Skip to content

Commit 495a099

Browse files
authored
Merge pull request #6 from smunaut/sta
STA for scan chain
2 parents 748631d + de1ff06 commit 495a099

File tree

3 files changed

+79
-10
lines changed

3 files changed

+79
-10
lines changed

src/base.sdc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Create a clock for the scan chain @ 200 MHz
2+
create_clock -name clk_scan_in -period 5 [get_ports {clk_in}]
3+
create_generated_clock -name clk_scan_out -source clk_in -combinational [get_ports {clk_out}]
4+
5+
# Scan chain input 0.5 ns setup time, 0.5 ns hold time
6+
set_input_delay -min 0.5 -clock [get_clocks clk_scan_in] [get_ports {data_in}]
7+
set_input_delay -max 0.5 -clock [get_clocks clk_scan_in] [get_ports {data_in}]
8+
9+
# Scan chain output 1.5 ns setup time, 1.5 ns hold time
10+
set_output_delay -min -1.5 -clock [get_clocks clk_scan_out] [get_ports {data_out}]
11+
set_output_delay -max 1.5 -clock [get_clocks clk_scan_out] [get_ports {data_out}]
12+
13+
# Misc
14+
set_max_fanout $::env(SYNTH_MAX_FANOUT) [current_design]
15+
16+
if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL)] } {
17+
set ::env(SYNTH_CLK_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL)
18+
}
19+
20+
if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL_PIN)] } {
21+
set ::env(SYNTH_CLK_DRIVING_CELL_PIN) $::env(SYNTH_DRIVING_CELL_PIN)
22+
}
23+
24+
set_driving_cell -lib_cell $::env(SYNTH_DRIVING_CELL) -pin $::env(SYNTH_DRIVING_CELL_PIN) [get_ports {data_in scan_select_in latch_enable_in}]
25+
set_driving_cell -lib_cell $::env(SYNTH_CLK_DRIVING_CELL) -pin $::env(SYNTH_CLK_DRIVING_CELL_PIN) [get_ports {clk_in}]
26+
27+
set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
28+
puts "\[INFO\]: Setting load to: $cap_load"
29+
set_load $cap_load [all_outputs]
30+
31+
puts "\[INFO\]: Setting clock uncertainity to: $::env(SYNTH_CLOCK_UNCERTAINITY)"
32+
set_clock_uncertainty $::env(SYNTH_CLOCK_UNCERTAINITY) [get_clocks {clk_sys clk_scan_in clk_scan_out}]
33+
34+
puts "\[INFO\]: Setting clock transition to: $::env(SYNTH_CLOCK_TRANSITION)"
35+
set_clock_transition $::env(SYNTH_CLOCK_TRANSITION) [get_clocks {clk_sys clk_scan_in clk_scan_out}]
36+
37+
puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 100}] %"
38+
set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
39+
set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]

template/config.tcl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@ set ::env(DECAP_CELL) "\
3232
sky130_ef_sc_hd__decap_12"
3333

3434
# clock
35-
set ::env(CLOCK_PERIOD) "100"
36-
set ::env(CLOCK_PORT) "clk"
35+
set ::env(CLOCK_PERIOD) "10"
36+
set ::env(CLOCK_PORT) ""
37+
38+
set ::env(BASE_SDC_FILE) $::env(DESIGN_DIR)/base.sdc
39+
40+
set ::env(SYNTH_CLOCK_UNCERTAINITY) 0.20
41+
set ::env(SYNTH_CLOCK_TRANSITION) 0.15
3742

3843
# don't use power rings or met5
3944
set ::env(DESIGN_IS_CORE) 0

template/scan_wrapper.v

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,29 @@ module scan_wrapper_USER_MODULE_ID (
1919
output wire scan_select_out,
2020
output wire latch_enable_out
2121
);
22-
23-
assign scan_select_out = scan_select_in;
24-
assign latch_enable_out = latch_enable_in;
25-
assign clk_out = clk_in;
26-
wire clk = clk_in;
22+
23+
// input buffers
24+
// Looking at results from multiple projects the bufferring is a bit
25+
// inconsistent. So instead, we ensure at least clk buf
26+
wire clk;
27+
28+
sky130_fd_sc_hd__clkbuf_2 input_buf_clk (
29+
.A (clk_in),
30+
.X (clk),
31+
.VPWR (1'b1),
32+
.VGND (1'b0)
33+
);
34+
35+
// output buffers
36+
// Same as for input, to try and be more consistent, we make our own
37+
wire data_out_i;
38+
39+
sky130_fd_sc_hd__buf_4 output_buffers[3:0] (
40+
.A ({clk, data_out_i, scan_select_in, latch_enable_in }),
41+
.X ({clk_out, data_out, scan_select_out, latch_enable_out }),
42+
.VPWR (1'b1),
43+
.VGND (1'b0)
44+
);
2745

2846
/*
2947
`ifdef COCOTB
@@ -45,9 +63,16 @@ module scan_wrapper_USER_MODULE_ID (
4563

4664
// scan chain - link all the flops, with data coming from data_in
4765
assign scan_data_in = {scan_data_out[NUM_IOS-2:0], data_in};
48-
49-
// end of the chain is the last scan flop's out
50-
assign data_out = scan_data_out[NUM_IOS-1];
66+
67+
// end of the chain is a negedge FF to increase hold margin between blocks
68+
sky130_fd_sc_hd__dfrtn_1 out_flop (
69+
.RESET_B (1'b1),
70+
.CLK_N (clk),
71+
.D (scan_data_out[NUM_IOS-1]),
72+
.Q (data_out_i),
73+
.VPWR (1'b1),
74+
.VGND (1'b0)
75+
);
5176

5277
// scan flops have a mux on their inputs to choose either data from the user module or the previous flop's output
5378
// https://antmicro-skywater-pdk-docs.readthedocs.io/en/test-submodules-in-rtd/contents/libraries/sky130_fd_sc_ls/cells/sdfxtp/README.html

0 commit comments

Comments
 (0)