diff --git a/info.yaml b/info.yaml new file mode 100644 index 0000000..6ffcb41 --- /dev/null +++ b/info.yaml @@ -0,0 +1,38 @@ +--- +# TinyTapeout project information +# +# As everyone will have access to all designs, try to make it easy for someone new to your design to know what +# it does and how to operate it. +# +# This will be automatically collected and used to make a datasheet for the chip. +project: + author: "" # Your name + title: "" # Project title + description: "" # Short description of what your project does + how_it_works: "" # Longer description of how the project works + how_to_test: "" # Instructions on how someone could test your project, include things like what buttons do what and how to set the clock if needed + external_hw: "" # Describe any external hardware needed + doc_link: "" # URL to longer form documentation, eg the README.md in your repository + clock_hz: 0 # Clock frequency in Hz (if required) + language: "wokwi" # other examples include Verilog, Amaranth, VHDL, etc + wokwi_id: 0 # the wokwi ID + picture: "" # relative path to a picture in your repository + inputs: # a description of what the inputs do + - clock + - reset + - none + - none + - none + - none + - none + - none + outputs: + - segment a # a description of what the outputs do + - segment b + - segment c + - segment d + - segment e + - segment f + - segment g + - none + diff --git a/src/base.sdc b/src/base.sdc new file mode 100644 index 0000000..eadeece --- /dev/null +++ b/src/base.sdc @@ -0,0 +1,39 @@ +# Create a clock for the scan chain @ 200 MHz +create_clock -name clk_scan_in -period 5 [get_ports {clk_in}] +create_generated_clock -name clk_scan_out -source clk_in -combinational [get_ports {clk_out}] + +# Scan chain input 0.5 ns setup time, 0.5 ns hold time +set_input_delay -min 0.5 -clock [get_clocks clk_scan_in] [get_ports {data_in}] +set_input_delay -max 0.5 -clock [get_clocks clk_scan_in] [get_ports {data_in}] + +# Scan chain output 1.5 ns setup time, 1.5 ns hold time +set_output_delay -min -1.5 -clock [get_clocks clk_scan_out] [get_ports {data_out}] +set_output_delay -max 1.5 -clock [get_clocks clk_scan_out] [get_ports {data_out}] + +# Misc +set_max_fanout $::env(SYNTH_MAX_FANOUT) [current_design] + +if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL)] } { + set ::env(SYNTH_CLK_DRIVING_CELL) $::env(SYNTH_DRIVING_CELL) +} + +if { ![info exists ::env(SYNTH_CLK_DRIVING_CELL_PIN)] } { + set ::env(SYNTH_CLK_DRIVING_CELL_PIN) $::env(SYNTH_DRIVING_CELL_PIN) +} + +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}] +set_driving_cell -lib_cell $::env(SYNTH_CLK_DRIVING_CELL) -pin $::env(SYNTH_CLK_DRIVING_CELL_PIN) [get_ports {clk_in}] + +set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0] +puts "\[INFO\]: Setting load to: $cap_load" +set_load $cap_load [all_outputs] + +puts "\[INFO\]: Setting clock uncertainity to: $::env(SYNTH_CLOCK_UNCERTAINITY)" +set_clock_uncertainty $::env(SYNTH_CLOCK_UNCERTAINITY) [get_clocks {clk_sys clk_scan_in clk_scan_out}] + +puts "\[INFO\]: Setting clock transition to: $::env(SYNTH_CLOCK_TRANSITION)" +set_clock_transition $::env(SYNTH_CLOCK_TRANSITION) [get_clocks {clk_sys clk_scan_in clk_scan_out}] + +puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 100}] %" +set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}] +set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}] diff --git a/template/config.tcl b/template/config.tcl index 049038c..3c2cbea 100644 --- a/template/config.tcl +++ b/template/config.tcl @@ -19,7 +19,7 @@ set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/*.v] # absolute die size set ::env(FP_SIZING) absolute -set ::env(DIE_AREA) "0 0 100 100" +set ::env(DIE_AREA) "0 0 105 105" set ::env(FP_CORE_UTIL) 45 set ::env(PL_BASIC_PLACEMENT) {1} @@ -32,8 +32,13 @@ set ::env(DECAP_CELL) "\ sky130_ef_sc_hd__decap_12" # clock -set ::env(CLOCK_PERIOD) "100" -set ::env(CLOCK_PORT) "clk" +set ::env(CLOCK_PERIOD) "10" +set ::env(CLOCK_PORT) "" + +set ::env(BASE_SDC_FILE) $::env(DESIGN_DIR)/base.sdc + +set ::env(SYNTH_CLOCK_UNCERTAINITY) 0.20 +set ::env(SYNTH_CLOCK_TRANSITION) 0.15 # don't use power rings or met5 set ::env(DESIGN_IS_CORE) 0 diff --git a/template/scan_wrapper.v b/template/scan_wrapper.v index b24114b..428c5c1 100644 --- a/template/scan_wrapper.v +++ b/template/scan_wrapper.v @@ -19,11 +19,29 @@ module scan_wrapper_USER_MODULE_ID ( output wire scan_select_out, output wire latch_enable_out ); - - assign scan_select_out = scan_select_in; - assign latch_enable_out = latch_enable_in; - assign clk_out = clk_in; - wire clk = clk_in; + + // input buffers + // Looking at results from multiple projects the bufferring is a bit + // inconsistent. So instead, we ensure at least clk buf + wire clk; + + sky130_fd_sc_hd__clkbuf_2 input_buf_clk ( + .A (clk_in), + .X (clk), + .VPWR (1'b1), + .VGND (1'b0) + ); + + // output buffers + // Same as for input, to try and be more consistent, we make our own + wire data_out_i; + + sky130_fd_sc_hd__buf_4 output_buffers[3:0] ( + .A ({clk, data_out_i, scan_select_in, latch_enable_in }), + .X ({clk_out, data_out, scan_select_out, latch_enable_out }), + .VPWR (1'b1), + .VGND (1'b0) + ); /* `ifdef COCOTB @@ -45,9 +63,16 @@ module scan_wrapper_USER_MODULE_ID ( // scan chain - link all the flops, with data coming from data_in assign scan_data_in = {scan_data_out[NUM_IOS-2:0], data_in}; - - // end of the chain is the last scan flop's out - assign data_out = scan_data_out[NUM_IOS-1]; + + // end of the chain is a negedge FF to increase hold margin between blocks + sky130_fd_sc_hd__dfrtn_1 out_flop ( + .RESET_B (1'b1), + .CLK_N (clk), + .D (scan_data_out[NUM_IOS-1]), + .Q (data_out_i), + .VPWR (1'b1), + .VGND (1'b0) + ); // scan flops have a mux on their inputs to choose either data from the user module or the previous flop's output // https://antmicro-skywater-pdk-docs.readthedocs.io/en/test-submodules-in-rtd/contents/libraries/sky130_fd_sc_ls/cells/sdfxtp/README.html