目录
引言
知识储备
时钟创建
时钟偏差
时钟延迟
转换时间
输入路径约束
输出路径延迟
组合逻辑路径约束
时间预算
寄存器输出
总结
实际操作
设计文件
check_design
reset_design
时序约束
check_timing
compile
report_constraint -all_violators
remove_design -hierarchy
TCL脚本文件
dcprocheck
source ../script/MY_TOP.tcl
查看时序报告
引言
本篇继续学习 DC的基本使用。本篇主要学习 DC 需要的时序约束。
前文链接:
Design Compiler工具学习笔记(1)
Design Compiler工具学习笔记(2)
知识储备
时钟创建
时钟偏差
时钟延迟
转换时间
输入路径约束
输出路径延迟
组合逻辑路径约束
指定输入延迟、输出延迟,以及时钟周期,可以得到中间组合逻辑 F 的延迟不超过
时钟周期-输入延迟-输出延迟
纯组合逻辑,需要创建虚拟时钟,
时间预算
寄存器输出
总结
实际操作
写了一个很简单的设计文件:
设计文件
顶层:
// ================== TOP module ======================================= // Date:2022-11-20 // By:Xu Y. B. // Description: // use I_CNT_CTRL_A signal's posedge to control the counter in the time // domain B to count . // ===================================================================== module TOP ( // time domain A 100MHz input I_CNT_CTRL_A, // input signal that needs to be synchronized // time domain B 50MHz input I_CLK_B, // clock B 50MHz input I_RSTN_B, // synchronous reset active low // output output reg [3:0]O_SYNC_DATA_B // output counter ); // internal signals wire W_SYNC_CTRL_B; // I_CNT_CTRL_A synchronize to time domain B reg R_W_SYNC_CTRL_B_R1; // W_SYNC_CTRL_B register one clock wire W_SYNC_CTRL_B_PDG; // posedge of W_SYNC_CTRL_B // module logic always @ (posedge I_CLK_B) begin:register if(~I_RSTN_B) begin R_W_SYNC_CTRL_B_R1 <= 0; end else begin R_W_SYNC_CTRL_B_R1 <= W_SYNC_CTRL_B; end end assign W_SYNC_CTRL_B_PDG = W_SYNC_CTRL_B & (~R_W_SYNC_CTRL_B_R1); // count always @ (posedge I_CLK_B) begin:count_B if(~I_RSTN_B) begin O_SYNC_DATA_B <= 4'd0; end else begin if(W_SYNC_CTRL_B_PDG) begin O_SYNC_DATA_B <= 3'd0; end else if(&O_SYNC_DATA_B) begin O_SYNC_DATA_B <= O_SYNC_DATA_B; end else begin O_SYNC_DATA_B <= O_SYNC_DATA_B + 1; end end end // module instantiate sync_2 INST_sync_2 (.I_CLK(I_CLK_B), .I_RSTN(I_RSTN_B), .I_DATA(I_CNT_CTRL_A), .O_SYNC_DATA(W_SYNC_CTRL_B)); endmodule
sync_2:
// ================== single-bit signal two stages synchronizer ================= // Date:2022-11-20 // By:Xu Y. B. // ============================================================================== module sync_2 ( input I_CLK, // clock input I_RSTN, // synchronous reset active low input I_DATA, // input signal that needs to be synchronized output O_SYNC_DATA // output signal that has been synchronized ); reg [1:0] R_SYNC; always @ (posedge I_CLK) begin:sync if(~I_RSTN) begin R_SYNC <= 2'b00; end else begin R_SYNC[0] <= I_DATA; R_SYNC[1] <= R_SYNC[0]; end end assign O_SYNC_DATA = R_SYNC[1]; endmodule
首先按照上篇文章的流程读取设计文件,并且做库的链接。
然后进行后续操作:
check_design
返回 1 表示正确可用。
reset_design
返回 1 ,表示正确操作。目的是将涉及置于初始状态,去除一切约束。
时序约束
此处的约束种类比较多,后面会在 tcl 脚本里面详细阐述。
check_timing
主要用来检查时序约束的完整性。
compile
此步骤完成设计的编译即网表映射。
report_constraint -all_violators
查看时序违规
remove_design -hierarchy
将设计全部移除。
TCL脚本文件
# |=========================================================== # | 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 TOP analyze -format verilog [list TOP.v sync_2.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 # |=========================================================== set CLK_NAME I_CLK_B set CLK_PERIOD 20 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] # |=========================================================== # |STEP 5: define reset # |=========================================================== set RST_NAME I_RSTN_B set_ideal_network [get_ports $RST_NAME] set_dont_touch_network [get_ports $RST_NAME] set_drive 0 [get_ports $RST_NAME] # |=========================================================== # |STEP 6: set input delay using timing budget # |Assume a weak cell to drive the input pins # |=========================================================== set LIB_NAME typical set WIRE_LOAD_MODULE smic18_wl10 set DRIVE_CELL INVX1 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_input_delay -min 0 -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/INVX8/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
dcprocheck
检查 tcl 脚本有无语法问题。
故意打错一个命令:
出现了未定义程序的警告需要重视。
source ../script/MY_TOP.tcl
执行脚本,注意路径。