Design Compiler工具学习笔记(4)
创始人
2024-04-12 10:43:15
0


目录

引言

知识储备

实际操作

设计源码

Vivado2018.3仿真

VCS2016仿真

Tcl脚本

约束脚本 MY_TOP.tcl

运行脚本 RUN.tcl



引言

本篇继续学习 DC的基本使用。本篇主要学习 DC 需要的环境约束。

前文链接:

Design Compiler工具学习笔记(1)

Design Compiler工具学习笔记(2)

Design Compiler工具学习笔记(3)



知识储备

 


  




 

 

实际操作

设计源码

此处做一个简单的运算模块,实现 (A+B)*C-D

其中,A、B、C、D的位宽可变

子模块源码:

// ================== calculate A & B  module ==========================  
// Date:2022-11-20
// By:Xu Y. B.
// Description:
// 				FNUC == 0 : A+B;
// 				FUNC == 1 : A-B;
// 				FUNC == 2 : A*B;
// =====================================================================  module CAL_FUNC_MDL #(// ======================= module parameters specify ===================  
parameter 			P_DATA_A_WIDTH 		=	8,
parameter 			P_DATA_B_WIDTH      =   4
)(
// ======================= module iuput ports specify ==================  
input 										I_CLK_100M,
input 										I_RSTN,
input 				[P_DATA_A_WIDTH-1:0]    I_DATA_A,
input 				[P_DATA_B_WIDTH-1:0]    I_DATA_B,
input 										I_DATA_A_VAL,
input 										I_DATA_B_VAL,
input 				[1:0]					I_FUNC,// ======================= module output ports specify =================  
output 				[P_DATA_A_WIDTH+P_DATA_B_WIDTH-1:0]	O_CAL_RES,
output										O_CAL_RES_VAL);// ======================= module local parameters =====================
localparam 			LP_ADD_SUB_RES_WIDTH =	MAX(P_DATA_B_WIDTH,P_DATA_A_WIDTH) + 1;
localparam			LP_MULT_RES_WIDTH	 =  P_DATA_A_WIDTH+P_DATA_B_WIDTH;// ======================= module internal signals =====================
reg 				[LP_ADD_SUB_RES_WIDTH-1:0]	R_ADD_SUB_RES;
reg 				[LP_MULT_RES_WIDTH-1:0]		R_MULT_RES;
reg 											R_CAL_RES_VAL;reg 				[1:0]						R_FUNC;// ======================= module logic ================================
always @ (posedge I_CLK_100M)
begin:cal if(~I_RSTN)beginR_ADD_SUB_RES <= {(LP_ADD_SUB_RES_WIDTH){1'b0}};R_MULT_RES 	  <= {(LP_MULT_RES_WIDTH){1'b0}};R_CAL_RES_VAL <= 1'b0;endelsebeginif(I_DATA_A_VAL & I_DATA_B_VAL)begincase (I_FUNC)0:beginR_ADD_SUB_RES <=  {{(LP_ADD_SUB_RES_WIDTH-P_DATA_A_WIDTH){I_DATA_A[P_DATA_A_WIDTH-1]}},I_DATA_A} + {{(LP_ADD_SUB_RES_WIDTH-P_DATA_B_WIDTH){I_DATA_B[P_DATA_B_WIDTH-1]}},I_DATA_B};R_MULT_RES 	  <= {(LP_MULT_RES_WIDTH){1'b0}};R_CAL_RES_VAL <= 1'b1;end1:beginR_ADD_SUB_RES <=  {{(LP_ADD_SUB_RES_WIDTH-P_DATA_A_WIDTH){I_DATA_A[P_DATA_A_WIDTH-1]}},I_DATA_A} - {{(LP_ADD_SUB_RES_WIDTH-P_DATA_B_WIDTH){I_DATA_B[P_DATA_B_WIDTH-1]}},I_DATA_B};R_MULT_RES 	  <= {(LP_MULT_RES_WIDTH){1'b0}};R_CAL_RES_VAL <= 1'b1;end2:beginR_ADD_SUB_RES <= {(LP_ADD_SUB_RES_WIDTH){1'b0}};R_MULT_RES 	  <= {{(P_DATA_B_WIDTH){I_DATA_A[P_DATA_A_WIDTH-1]}},I_DATA_A} * {{(P_DATA_A_WIDTH){I_DATA_B[P_DATA_B_WIDTH-1]}},I_DATA_B};R_CAL_RES_VAL <= 1'b1;enddefault : beginR_ADD_SUB_RES <=  {{(LP_ADD_SUB_RES_WIDTH-P_DATA_A_WIDTH){I_DATA_A[P_DATA_A_WIDTH-1]}},I_DATA_A} + {{(LP_ADD_SUB_RES_WIDTH-P_DATA_B_WIDTH){I_DATA_B[P_DATA_B_WIDTH-1]}},I_DATA_B};R_MULT_RES 	  <= {(LP_MULT_RES_WIDTH){1'b0}};R_CAL_RES_VAL <= 1'b1;endendcaseendelsebeginR_ADD_SUB_RES <= {(LP_ADD_SUB_RES_WIDTH){1'b0}};R_MULT_RES 	  <= {(LP_MULT_RES_WIDTH){1'b0}};R_CAL_RES_VAL <= 1'b0;			endend
endalways @ (posedge I_CLK_100M)
begin:beatif(~I_RSTN)beginR_FUNC <= 2'd0;endelsebeginR_FUNC <= I_FUNC;end
endassign O_CAL_RES_VAL = R_CAL_RES_VAL;
assign O_CAL_RES = (R_FUNC < 2) ? {{(LP_MULT_RES_WIDTH-LP_ADD_SUB_RES_WIDTH){R_ADD_SUB_RES[LP_ADD_SUB_RES_WIDTH-1]}},R_ADD_SUB_RES}: R_MULT_RES;// function define
function integer MAX;input integer A, B;beginif(A>=B)beginMAX = A;endelsebeginMAX = B;endend
endfunction
endmodule

顶层文件:

// ================== TOP  module ==========================  
// Date:2022-11-20
// By:Xu Y. B.
// Description:
// 				(A+B)*C-D
// =========================================================module TOP #(
// ======================= module parameters specify ===================  
parameter 		P_DATA_A_WIDTH				=	2,
parameter 		P_DATA_B_WIDTH  			=   4,
parameter 		P_DATA_C_WIDTH				=	5,
parameter 		P_DATA_D_WIDTH  			=   8
)(
// ======================= module iuput ports specify ================== input 										I_CLK_100M,    // clock
input 										I_RSTN,        // synchronous reset active lowinput 			[P_DATA_A_WIDTH-1:0]		I_DATA_A,
input 			[P_DATA_B_WIDTH-1:0]		I_DATA_B,
input 			[P_DATA_C_WIDTH-1:0]		I_DATA_C,
input 			[P_DATA_D_WIDTH-1:0]		I_DATA_D,input 										I_DATA_VAL,// ======================= module output ports specify =================
output	[MAX(MAX(P_DATA_A_WIDTH,P_DATA_B_WIDTH)+1+P_DATA_C_WIDTH,P_DATA_D_WIDTH):0] 				O_CAL_RES,
output 										O_CAL_RES_VAL );
// ======================= module local parameters =====================
localparam 		LP_ADD_RES_WIDTH	=	MAX(P_DATA_A_WIDTH,P_DATA_B_WIDTH)+1;
localparam 		LP_MULT_RES_WIDTH	=	LP_ADD_RES_WIDTH + P_DATA_C_WIDTH;
localparam 		LP_SUB_RES_WIDTH	=	MAX(LP_MULT_RES_WIDTH,P_DATA_D_WIDTH)+1;
// ======================= module internal signals =====================
wire 			[LP_ADD_RES_WIDTH-1:0]	W_ADD_RES;
wire 									W_ADD_RES_VAL;
wire 			[LP_MULT_RES_WIDTH-1:0] W_MULT_RES;
wire 									W_MULT_RES_VAL;
wire 			[LP_SUB_RES_WIDTH-1:0]	W_SUB_RES;
wire 									W_SUB_RES_VAL;reg 			[P_DATA_C_WIDTH-1:0] 	R_DATA_C;
reg 									R_DATA_C_VAL;reg 			[P_DATA_D_WIDTH-1:0]	R_DATA_D[1:0];
reg 			[1:0]					R_DATA_D_VAL;
// ======================= module logic ================================// instantiate module
// ADD
CAL_FUNC_MDL #(.P_DATA_A_WIDTH(P_DATA_A_WIDTH),.P_DATA_B_WIDTH(P_DATA_B_WIDTH)) INST_CAL_FUNC_MDL_ADD (.I_CLK_100M    (I_CLK_100M),.I_RSTN        (I_RSTN),.I_DATA_A      (I_DATA_A),.I_DATA_B      (I_DATA_B),.I_DATA_A_VAL  (I_DATA_VAL),.I_DATA_B_VAL  (I_DATA_VAL),.I_FUNC        (2'd0),.O_CAL_RES     (W_ADD_RES),.O_CAL_RES_VAL (W_ADD_RES_VAL));
// MULT
always @ (posedge I_CLK_100M)
begin:delay_cif(~I_RSTN)beginR_DATA_C_VAL <= 0;R_DATA_C <= 0;endelsebeginR_DATA_C <= I_DATA_C;R_DATA_C_VAL <= I_DATA_VAL;end
end
CAL_FUNC_MDL #(.P_DATA_A_WIDTH(LP_ADD_RES_WIDTH),.P_DATA_B_WIDTH(P_DATA_C_WIDTH)) INST_CAL_FUNC_MDL_MULT (.I_CLK_100M    (I_CLK_100M),.I_RSTN        (I_RSTN),.I_DATA_A      (W_ADD_RES),.I_DATA_B      (R_DATA_C),.I_DATA_A_VAL  (W_ADD_RES_VAL),.I_DATA_B_VAL  (R_DATA_C_VAL),.I_FUNC        (2'd2),.O_CAL_RES     (W_MULT_RES),.O_CAL_RES_VAL (W_MULT_RES_VAL));// SUB
always @ (posedge I_CLK_100M)
begin:delay_dif(~I_RSTN)beginR_DATA_D_VAL <= 2'b00;R_DATA_D[0] <= 0;R_DATA_D[1] <= 0;endelsebeginR_DATA_D_VAL[0] <= I_DATA_VAL;R_DATA_D_VAL[1] <= R_DATA_D_VAL[0];R_DATA_D[0] 	<= I_DATA_D;R_DATA_D[1]		<= R_DATA_D[0];end
end
CAL_FUNC_MDL #(.P_DATA_A_WIDTH(LP_MULT_RES_WIDTH),.P_DATA_B_WIDTH(P_DATA_D_WIDTH)) INST_CAL_FUNC_MDL_SUB (.I_CLK_100M    (I_CLK_100M),.I_RSTN        (I_RSTN),.I_DATA_A      (W_MULT_RES),.I_DATA_B      (R_DATA_D[1]),.I_DATA_A_VAL  (W_MULT_RES_VAL),.I_DATA_B_VAL  (R_DATA_D_VAL[1]),.I_FUNC        (2'd1),.O_CAL_RES     (W_SUB_RES),.O_CAL_RES_VAL (W_SUB_RES_VAL));assign O_CAL_RES = W_SUB_RES;
assign O_CAL_RES_VAL = W_SUB_RES_VAL;// function define
function integer MAX;input integer A, B;beginif(A>=B)beginMAX = A;endelsebeginMAX = B;endend
endfunctionendmodule

仿真文件:

// ================== calculate A & B  module TestBench=================
// Date:2022-11-20
// By:Xu Y. B.
// Description:
// 				FNUC == 0 : A+B;
// 				FUNC == 1 : A-B;
// 				FUNC == 2 : A*B;
// =====================================================================  module TB ();// ======================= module parameters specify ===================  
localparam 		P_DATA_A_WIDTH				=	2;
localparam 		P_DATA_B_WIDTH  			=   4;
localparam 		P_DATA_C_WIDTH				=	5;
localparam 		P_DATA_D_WIDTH  			=   8;// ======================= module iuput ports specify ================== reg 										I_CLK_100M;    // clock
reg 										I_RSTN;        // synchronous reset active lowreg 			[P_DATA_A_WIDTH-1:0]		I_DATA_A;
reg 			[P_DATA_B_WIDTH-1:0]		I_DATA_B;
reg 			[P_DATA_C_WIDTH-1:0]		I_DATA_C;
reg 			[P_DATA_D_WIDTH-1:0]		I_DATA_D;reg 										I_DATA_VAL;// ======================= module output ports specify =================
wire	[MAX(MAX(P_DATA_A_WIDTH,P_DATA_B_WIDTH)+1+P_DATA_C_WIDTH,P_DATA_D_WIDTH):0] 				    O_CAL_RES;
wire 										O_CAL_RES_VAL ;// ======================= generate clock ==============================
initial I_CLK_100M = 0;
always #5 I_CLK_100M = ~I_CLK_100M;initial
beginI_RSTN = 1'b0;I_DATA_A <= 0;I_DATA_B <= 0;I_DATA_C <= 0;I_DATA_D <= 0;I_DATA_VAL = 0;#20;I_RSTN = 1;#10;@(posedge I_CLK_100M)I_DATA_A = 2'd1;I_DATA_B = -4'd6;I_DATA_C = -5'd2;I_DATA_D = 8'd100;I_DATA_VAL <= 1;	@(posedge I_CLK_100M)I_DATA_VAL <= 0;I_DATA_A <= 0;I_DATA_B <= 0;I_DATA_C <= 0;I_DATA_D <= 0;#10;@(posedge I_CLK_100M)I_DATA_A = -2'd1;I_DATA_B = 4'd6;I_DATA_C = -5'd2;I_DATA_D = 8'd66;I_DATA_VAL <= 1;@(posedge I_CLK_100M)I_DATA_VAL <= 0;I_DATA_A <= 0;I_DATA_B <= 0;I_DATA_C <= 0;I_DATA_D <= 0;@(negedge O_CAL_RES_VAL)#50;$display("TB END",`__FILE__,`__LINE__);$finish;endinitial 
begin`ifdef VPD_TEST$vcdpluson();`endif
endTOP #(.P_DATA_A_WIDTH(P_DATA_A_WIDTH),.P_DATA_B_WIDTH(P_DATA_B_WIDTH),.P_DATA_C_WIDTH(P_DATA_C_WIDTH),.P_DATA_D_WIDTH(P_DATA_D_WIDTH)) INST_TOP (.I_CLK_100M     (I_CLK_100M),.I_RSTN         (I_RSTN),.I_DATA_A       (I_DATA_A),.I_DATA_B       (I_DATA_B),.I_DATA_C       (I_DATA_C),.I_DATA_D       (I_DATA_D),.I_DATA_VAL     (I_DATA_VAL),.O_CAL_RES      (O_CAL_RES),.O_CAL_RES_VAL  (O_CAL_RES_VAL));// function define
function integer MAX;input integer A, B;beginif(A>=B)beginMAX = A;endelsebeginMAX = B;endend
endfunctionendmodule

Vivado2018.3仿真

VCS2016仿真

刚好复习一下 前段时间学习的 VCS使用。不了解的可以看本专栏前面关于 VCS 的文章:

Synosys Toolicon-default.png?t=M85Bhttps://blog.csdn.net/qq_43045275/category_12082114.html?spm=1001.2014.3001.5482

Tcl脚本

仅供参考~~~

约束脚本 MY_TOP.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 CAL_FUNC_MDL.v]
elaborate      $TOP_MODULE     -architecture verilog
current_design $TOP_MODULEif {[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_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]# |===========================================================
# |STEP 5: define reset
# |===========================================================
set RST_NAME 					I_RSTN
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_MODEL 	smic18_wl10
set 		DRIVE_CELL 			INVX1
set 		DRIVE_PIN 			Y
set 		OPERATE_CONDITION   typicalset 		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_NAMEset 					 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			 0# |===========================================================
# |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 $CLK_NAME -to [all_outputs] 		\
# 						   -critical_range  [expr {$CLK_PERIOD * 0.1}] # group_path -name $CLK_NAME -from [all_inputs] 		\
# 						   -to [all_outputs] 		\
# 						   -critical_range  [expr {$CLK_PERIOD * 0.1}] 					   

运行脚本 RUN.tcl

# source MY_TOP.tcl and print the process to terminal & run.log
redirect -tee -file ${WORK_PATH}/run.log {source -echo -verbose MY_TOP.tcl}

运行约束脚本,并将信息存放于log文件中。

 

 

 



~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...