
目录

本篇继续学习 DC的基本使用。本篇主要学习 DC 综合之后的效果分析,多同步时钟设计以及 DC 综合完成之后的各种输出文件。
前文链接:






















多周期约束时,对应的设计代码也需要修改。比如使能信号、数据有效信号需要延迟相应的时间。


















简单的设计文件:做一个9级延迟的寄存器链。源代码:
module MY_DESIGN ( input I_CLK_100M, input I_RSTN_100M, input I_DATA, input I_VAL, output O_DATA ); reg [9:0] R_I_DATA; genvar GV_I; generate for(GV_I = 0;GV_I < 10;GV_I = GV_I + 1) begin always @ (posedge I_CLK_100M) begin if(~I_RSTN_100M) begin R_I_DATA[GV_I] <= 0; end else if(GV_I == 0) begin R_I_DATA[GV_I] <= I_DATA & I_VAL; end else begin R_I_DATA[GV_I] <= R_I_DATA[GV_I-1]; end end end endgenerate assign O_DATA = R_I_DATA[9]; endmodule
- # |===========================================================
- # | Author : Xu Y. B.
- # | Date : 2022-11-21
- # | Description : tcl script for top design
- # |===========================================================
-
-
- # |===========================================================
- # |STEP 1: Read & elaborate the RTL design file list & check
- # |===========================================================
- set TOP_MODULE MY_DESIGN
- analyze -format verilog [list MY_DESIGN.v]
- elaborate $TOP_MODULE -architecture verilog
- current_design $TOP_MODULE
-
- if {[link] == 0} {
- echo "Your Link has errors !";
- exit;
- }
-
- if {[check_design] == 0} {
- echo "Your check design has errors !";
- exit;
- }
-
- # |===========================================================
- # |STEP 2: reset design
- # |===========================================================
- reset_design
-
-
- # |===========================================================
- # |STEP 3: Write unmapped ddc file
- # |===========================================================
- uniquify
- set uniquify_naming_style "%s_%d"
- write -f ddc -hierarchy -output ${UNMAPPED_PATH}/${TOP_MODULE}.ddc
-
-
- # |===========================================================
- # |STEP 4: define clocks
- # |===========================================================
- # -------------------------- CLK 100MHz ----------------------
- set CLK_NAME I_CLK_100M
- set CLK_PERIOD 10
- set CLK_SKEW [expr {$CLK_PERIOD*0.05}]
- set CLK_TRANS [expr {$CLK_PERIOD*0.01}]
- set CLK_SRC_LATENCY [expr {$CLK_PERIOD*0.1 }]
- set CLK_LATENCY [expr {$CLK_PERIOD*0.1 }]
-
- create_clock -period $CLK_PERIOD [get_ports $CLK_NAME]
- set_ideal_network [get_ports $CLK_NAME]
- set_dont_touch_network [get_ports $CLK_NAME]
- set_drive 0 [get_ports $CLK_NAME]
-
- set_clock_uncertainty -setup $CLK_SKEW [get_clocks $CLK_NAME]
- set_clock_transition -max $CLK_TRANS [get_clocks $CLK_NAME]
- set_clock_latency -source -max $CLK_SRC_LATENCY [get_clocks $CLK_NAME]
- set_clock_latency -max $CLK_LATENCY [get_clocks $CLK_NAME]
-
- # --------------------------- CLK 50MHz ----------------------
- # set CLK_NAME_2 I_CLK_50M
- # set CLK_PERIOD_2 20
- # set CLK_SKEW_2 [expr {$CLK_PERIOD_2*0.05}]
- # set CLK_TRANS_2 [expr {$CLK_PERIOD_2*0.01}]
- # set CLK_SRC_LATENCY_2 [expr {$CLK_PERIOD_2*0.1 }]
- # set CLK_LATENCY_2 [expr {$CLK_PERIOD_2*0.1 }]
-
- # create_clock -period $CLK_PERIOD_2 [get_ports $CLK_NAME_2]
- # set_ideal_network [get_ports $CLK_NAME_2]
- # set_dont_touch_network [get_ports $CLK_NAME_2]
- # set_drive 0 [get_ports $CLK_NAME_2]
-
- # set_clock_uncertainty -setup $CLK_SKEW_2 [get_clocks $CLK_NAME_2]
- # set_clock_transition -max $CLK_TRANS_2 [get_clocks $CLK_NAME_2]
- # set_clock_latency -source -max $CLK_SRC_LATENCY_2 [get_clocks $CLK_NAME_2]
- # set_clock_latency -max $CLK_LATENCY_2 [get_clocks $CLK_NAME_2]
-
-
- # |===========================================================
- # |STEP 5: define reset
- # |===========================================================
- # ------------------------- RST 1 ----------------------------
- set RST_NAME I_RSTN_100M
- set_ideal_network [get_ports $RST_NAME]
- set_dont_touch_network [get_ports $RST_NAME]
- set_drive 0 [get_ports $RST_NAME]
-
- # # ------------------------- RST 2 ----------------------------
- # set RST_NAME_2 I_RSTN_50M
- # set_ideal_network [get_ports $RST_NAME_2]
- # set_dont_touch_network [get_ports $RST_NAME_2]
- # set_drive 0 [get_ports $RST_NAME_2]
-
-
- # |===========================================================
- # |STEP 6: set input delay using timing budget
- # |Assume a weak cell to drive the input pins
- # |===========================================================
- set LIB_NAME typical
- set WIRE_LOAD_MODEL smic18_wl10
-
-
- set DRIVE_PIN Y
- set OPERATE_CONDITION typical
-
- set ALL_INPUT_EXCEPT_CLK [remove_from_collection [all_inputs] [get_ports "$CLK_NAME"]]
- set INPUT_DELAY [expr {$CLK_PERIOD*0.6}]
-
- set_input_delay $INPUT_DELAY -clock $CLK_NAME $ALL_INPUT_EXCEPT_CLK
- set_driving_cell -lib_cell ${DRIVE_CELL} -pin ${DRIVE_PIN} $ALL_INPUT_EXCEPT_CLK
-
-
-
- # |===========================================================
- # |STEP 7: set output delay
- # |===========================================================
- set OUTPUT_DELAY [expr {$CLK_PERIOD*0.6}]
- set MAX_LOAD [expr {[load_of $LIB_NAME/INVX4/A] * 10}]
-
- set_output_delay $OUTPUT_DELAY -clock $CLK_NAME [all_outputs]
- set_load [expr {$MAX_LOAD * 3}] [all_outputs]
- set_isolate_ports -type buffer [all_outputs]
-
-
- # |===========================================================
- # |STEP 8: set max delay for comb logic
- # |===========================================================
- # set_input_delay [expr $CLK_PERIOD * 0.1] -clock $CLK_NAME -add_delay [get_ports I_1]
- # set_output_delay [expr $CLK_PERIOD * 0.1] -clock $CLK_NAME -add_delay [get_ports O_1]
-
-
- # |===========================================================
- # |STEP 9: set operating condition & wire load model
- # |===========================================================
- set_operating_conditions -max $OPERATE_CONDITION \
- -max_library $LIB_NAME
-
- set auto_wire_load_selection false
- set_wire_load_mode top
- set_wire_load_model -name $WIRE_LOAD_MODEL \
- -library $LIB_NAME
-
-
- # |===========================================================
- # |STEP 10: set area constraint (Let DC try its best)
- # |===========================================================
- set_max_area 1000
-
-
- # |===========================================================
- # |STEP 11: set DRC constraint
- # |===========================================================
- # set MAX_CAPACITANCE [expr {[load_of $LIB_NAME/NAND4X2/Y] * 5}]
- # set_max_capacitance $MAX_CAPACITANCE $ALL_INPUT_EXCEPT_CLK
-
-
- # |===========================================================
- # |STEP 12: set group path
- # |Avoid getting stack on one path
- # |===========================================================
- group_path -name $CLK_NAME -weight 5 \
- -critical_range [expr {$CLK_PERIOD * 0.1}]
-
- group_path -name INPUTS -from [all_inputs] \
- -critical_range [expr {$CLK_PERIOD * 0.1}]
-
- group_path -name OUTPUTS -to [all_outputs] \
- -critical_range [expr {$CLK_PERIOD * 0.1}]
-
- group_path -name COMBS -from [all_inputs] \
- -to [all_outputs] \
- -critical_range [expr {$CLK_PERIOD * 0.1}]
- report_path_group
-
-
- # |===========================================================
- # |STEP 13: Elimate the multiple-port inter-connect &
- # | define name style
- # |===========================================================
- # set_app_var verilogout_no_tri true
- # set_app_var verilogout_show_unconnected_pins true
- # set_app_var bus_naming_style {%s[%d]}
- # simplify_constants -boundary_optimization
- # set_boundary_optimization [current_design] true
- # set_fix_multiple_port_nets -all -buffer_constants
-
-
- # |===========================================================
- # |STEP 14: timing exception define
- # |===========================================================
- # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
- # set ALL_CLKS [all_clocks]
- # foreach_in_collection CUR_CLK $ALL_CLKS
- # {
- # set OTHER_CLKS [remove_from_collection [all_clocks] $CUR_CLK]
- # set_false_path -from $CUR_CLK $OTHER_CLKS
- # }
-
- # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
- # set_false_path -from [get_clocks I_CLK_100M] -to [get_clocks I_CLK_100M]
-
- # set_disable_timing TOP/U1 -from a -to y
- # set_case_analysis 0 [get_ports sel_i]
-
- # set_multicycle_path -setup 6 -from FFA/CP -through ADD/out -to FFB/D
- # set_multicycle_path -hold 5 -from FFA/CP -through ADD/out -to FFB/D
- # set_multicycle_path -setup 2 -to FFB/D
- # set_multicycle_path -hold 1 -to FFB/D
-
-
-
- # |===========================================================
- # |STEP 15: compile flow
- # |===========================================================
- # ungroup -flatten -all
-
- # 1st-pass compile
- # compile -map_effort high -area_effort high
- # compile -map_effort high -area_effort high -boundary_optimization
- compile -map_effort high -area_effort high
-
- # simplify_constants -boundary_optimization
- # set_fix_multiple_port_nets -all -buffer_constants
-
- # compile -map_effort high -area_effort high -incremental_mapping -scan
-
- # 2nd-pass compile
- # compile -map_effort high -area_effort high -incremental_mapping -boundary_optimization
- # compile_ultra -incr
-
-
- # |===========================================================
- # |STEP 16: write post-process files
- # |===========================================================
- change_names -rules verilog -hierarchy
- remove-unconnected_ports [get_cells -hier *] -blast_buses
- # Write the mapped files
- write -f ddc -output $MAPPED_PATH/${TOP_MODULE}.ddc
- write -f verilog -hierarchy -output $MAPPED_PATH/${TOP_MODULE}.v
- write_sdc -version 1.7 $MAPPED_PATH/${TOP_MODULE}.sdc
- write_sdf -version 2.1 $MAPPED_PATH/${TOP_MODULE}.sdf
-
- # |===========================================================
- # |STEP 17: generate report files
- # |===========================================================
- # Get report file
- redirect -tee -file ${REPORT_PATH}/check_design.txt {check_design}
- redirect -tee -file ${REPORT_PATH}/check_timing.txt {check_timing}
- redirect -tee -file ${REPORT_PATH}/report_constraint.txt {report_constraint -all_violators}
- redirect -tee -file ${REPORT_PATH}/check_setup.txt {report_timing -delay_type max}
- redirect -tee -file ${REPORT_PATH}/check_hold.txt {report_timing -delay_type min}
- redirect -tee -file ${REPORT_PATH}/report_area.txt {report_area}
打开映射后的 .v 文件:
编译时可以加上 -scan 选项,观察寄存器映射的差别:

里面包含了单元的延迟信息。

里面包含了该设计的所有约束

可以分别打开进行分析,包括时间、面积等。此处就不一一展开。

至此 DC 的视频学习告一段落,了解了基本的使用技巧。但是功夫还需要磨练,多结合工程进行实践是必不可缺的环节。继续加油~~