- UID
- 1023229
- 来自
- 中国
|
FPGA设计技巧之如何保证RTL设计与综合后网表的一致性?
在超大规模数字集成电路的设计中,我们使用逻辑综合工具来完成从RTL设计到门级网表的转化。我们希望它综合出的门级网表与我们的RTL设计在逻辑和时序上完全一致。但是某些书写风格和设计思路却会造成两者不一致的情况,降低我们的工作效率。本文列举了三种RTL设计与综合后网表不一致的情况,并给出了解决方法.我们以Design Compiler为例,来说明设计RTL时应该注意的问题。在仿真和调试时,我们使用了NC-Verilog和Debussy。
1.不完整的敏感量列表在下面的例子中,有一个always语句,它描述了一个或门,其中它的敏感量列表包含IN1和IN2。/////////////////////////////////////////////////////////////////////////////module OR_GATE_A (OUT_A, IN1, IN2);output OUT_A;input IN1, IN2;reg OUT_A;always @(IN1 or IN2)OUT_A = IN1 | IN2;endmodule/////////////////////////////////////////////////////////////////////////////再看下面的例子,敏感量列表只包含IN1。/////////////////////////////////////////////////////////////////////////////module OR_GATE_B (OUT_B, IN1, IN2);output OUT_B;input IN1, IN2;reg OUT_B;always @(IN1)OUT_B = IN1 | IN2;endmodule/////////////////////////////////////////////////////////////////////////////这两个例子有什么不同呢?我们看下面的波形:[[wysiwyg_imageupload:238:]] 对比两个module的输出,可以看出:它们的输入相同,但是输出在22时刻却不同,这是因为OR_GATE_B的敏感量列表只包含IN1,导致在22时刻虽然IN2发生了变化,却不能触发OUT_B重新求值。我们看逻辑综合后的情况。这两个module的逻辑综合的结果完全相同,均包含完整的敏感量列表。因此,对于OR_GATE_B,它会有RTL设计与综合后的网表不一致的问题。避免这种问题的方法有二:
- 使用数据流的描述方法描述组合逻辑;
- 若用always语句描述组合逻辑,必须检查敏感量列表是否完整;
显然,采用第一种方法更简单一些。
2.时序延迟(timing delay)我们在进行建模时,常常含有时间延迟。而时间延迟是不可综合的对象,因此,如果建模时不注意时间延迟的"必要的准确性",便会造成时序上的不一致,进而造成逻辑结果上的不一致。我们看下面的例子。例子:一个二级延迟线////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////module mis_timing (A ,DATA_RDY,VE_CLK,VE_RSTJ,OUT,OUT_RDY);parameter A_WIDTH = 3;input [A_WIDTH-1:0]A;input DATA_RDY;input VE_RSTJ;input VE_CLK;output OUT;output OUT_RDY;reg OUT_RDY;reg DATA_RDY_DLY1;reg DATA_RDY_DLY2;reg [A_WIDTH-1:0]OUT ;parameter UDLY = 1;//---time for one clock cycleparameter CLOCK_CYCLE=6.5 ;always@(posedge VE_CLK or negedge VE_RSTJ) //the data addrif (!VE_RSTJ)OUT <= #UDLY 'd0 ;else OUT <= #(UDLY+CLOCK_CYCLE) A;//---- output ready ------------------always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)OUT_RDY <= #UDLY 'd0 ;else OUT_RDY <= #(UDLY+CLOCK_CYCLE) DATA_RDY;endmodule////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////在这个行为级描述中,我们使用了一个超过一个时钟周期的延迟。我们使用下面的仿真文件进行仿真://///////////////////////////////////////////////////////////////////////////////////////////////////module ts;parameter A_WIDTH = 3;reg [A_WIDTH-1:0]A;reg DATA_RDY;reg VE_CLK;reg VE_RSTJ;mis_timing mis_timing(.A (A ),.DATA_RDY(DATA_RDY ),.VE_CLK (VE_CLK ),.VE_RSTJ (VE_RSTJ ),.OUT ( ),.OUT_RDY ( ));//----------- input data----------------------initial begin#2 A=0;#10 A=0; DATA_RDY=0;#6 A=3'h5; DATA_RDY=1;#6.5 A=3'h5; DATA_RDY=0;end//-------------clock and RST signal -------------initial begin#1 VE_CLK=1'b0;forever #3.2 VE_CLK= ~VE_CLK;endinitial begin#1 VE_RSTJ =1'b1;#10 VE_RSTJ =1'b0;#7 VE_RSTJ =1'b1;end//---------- waveform dump---------------initial begin$fsdbDumpfile("delay_line.fsdb");$fsdbDumpvars(0,ts );end//-------------finish-----------------------------initial begin#100 $finish;endendmodule////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////我们看它的波形效果:[[wysiwyg_imageupload:239:]] 使用逻辑综合工具后,得到门级网表文件如下:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////module mis_timing ( A, DATA_RDY, VE_CLK, VE_RSTJ, OUT, OUT_RDY, TEST_SI, TEST_SO, test_se );input [2:0] A;output [2:0] OUT;input DATA_RDY, VE_CLK, VE_RSTJ, TEST_SI, test_se;output OUT_RDY, TEST_SO;wire n7, n8, n9;BUFX8 I3 ( .A(n7), .Y(OUT[1]) );BUFX8 I4 ( .A(n8), .Y(OUT[0]) );BUFX8 I5 ( .A(TEST_SO), .Y(OUT[2]) );BUFX8 I6 ( .A(n9), .Y(OUT_RDY) );SDFFRHQX2 OUT_RDY_reg ( .SI(TEST_SI), .SE(test_se), .D(DATA_RDY), .CK(VE_CLK), .RN(VE_RSTJ), .Q(n9) );SDFFRHQX2 \OUT_reg[0] ( .SI(n9), .SE(test_se), .D(A[0]), .CK(VE_CLK),.RN(VE_RSTJ), .Q(n8) );SDFFRHQX2 \OUT_reg[1] ( .SI(n8), .SE(test_se), .D(A[1]), .CK(VE_CLK),.RN(VE_RSTJ), .Q(n7) );SDFFRHQX2 \OUT_reg[2] ( .SI(n7), .SE(test_se), .D(A[2]), .CK(VE_CLK),.RN(VE_RSTJ), .Q(TEST_SO) );endmodule//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////研究这个网表文件,我们发现从输入到输出只有一级延迟,显然这与RTL设计不符,因此产生了不匹配。注:我们在逻辑综合时加上了扫描链,所以有TEST_SI, TEST_SO, test_se这三个信号。我们看综合后的仿真波形:[[wysiwyg_imageupload:240:]] 比较两个波形,可以直观的看出这种不匹配现象。为了避免这种情况的发生,我们必须改正原来的RTL设计。//改正RTL//////////////////////////////////////////////////////////////////////////////////////////////////////////module mis_timing (A ,DATA_RDY,VE_CLK,VE_RSTJ,OUT,OUT_RDY);parameter A_WIDTH = 3;input [A_WIDTH-1:0]A;input DATA_RDY;input VE_RSTJ;input VE_CLK;output OUT;output OUT_RDY;reg OUT_RDY;reg DATA_RDY_DLY1;reg [A_WIDTH-1:0]OUT ;parameter UDLY = 1;//---time for one clock cycleparameter CLOCK_CYCLE=6.5 ;always@(posedge VE_CLK or negedge VE_RSTJ) //the data addrif (!VE_RSTJ)OUT <= #UDLY 'd0 ;else if (DATA_RDY )OUT <= #(UDLY) A;//---- output ready ------------------always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)DATA_RDY_DLY1 <= #UDLY 'd0 ;else DATA_RDY_DLY1 <= #UDLY DATA_RDY;always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)OUT_RDY <= #UDLY 'd0 ;else OUT_RDY <= #UDLY DATA_RDY_DLY1 ;endmodule////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////我们总结避免这种不匹配的方法:除非一个逻辑运算在一个时钟周期内无法完成(或者你要仿真一条延迟太长的连线),在设计可综合的RTL代码时,一般不要用超过一个周期的时间延迟。
3.多周期路径(multi-cycle path)引起的问题在含有时钟的电路中,某些较复杂的组合逻辑运算无法在一个周期内完成,而是需要多个周期来完成,我们称这条逻辑路径为多周期路径(Multi-cycle Path)。我们看下面的例子:我们来实现一个17/6的无符号整数除法,被除数为A,除数为B;DATA_RDY为一个脉冲信号,当它为高时对应的A,B为有效值。我们设计RTL code如下:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////module multi_cycle (A ,B ,DATA_RDY,VE_CLK,VE_RSTJ,OUT,OUT_RDY);parameter A_WIDTH = 17;parameter B_WIDTH = 6;input [A_WIDTH-1:0]A;input [B_WIDTH-1:0]B;input DATA_RDY;input VE_RSTJ;input VE_CLK;output OUT;output OUT_RDY;reg OUT_RDY;reg [A_WIDTH-1:0]OUT ;parameter UDLY = 1;wire [(A_WIDTH-1):0] DATA_TMP= A / B ;always@(posedge VE_CLK or negedge VE_RSTJ) if (!VE_RSTJ)OUT = #UDLY 'd0 ;else if (DATA_RDY)OUT = #UDLY DATA_TMP;//---- output ready ------------------always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)OUT_RDY <= #UDLY 'd0 ;else OUT_RDY <= #UDLY DATA_RDY ;endmodule////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////我们用以下的仿真文件来完成仿真:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////module ts;parameter A_WIDTH = 17;parameter B_WIDTH = 6;reg [A_WIDTH-1:0]A;reg [B_WIDTH-1:0]B;reg DATA_RDY;reg RDY_DLY;reg VE_CLK;reg VE_RSTJ;multi_cycle multi_cycle(.A (A ),.B (B ),.DATA_RDY(DATA_RDY ),.VE_CLK (VE_CLK ),.VE_RSTJ (VE_RSTJ ),.OUT ( ),.OUT_RDY ( ));//----------- input data----------------------initialbegin#2 A=0; B=0;#10 A=0; B=0; DATA_RDY=0;#6 A=17'h15505; B=7'h55; DATA_RDY=1;#6.5 A=17'h15505; B=7'h55; DATA_RDY=0;end//-------------clock and RST signal -------------initial begin#1 VE_CLK=1'b0;forever #3.2 VE_CLK= ~VE_CLK;endinitial begin#1 VE_RSTJ =1'b1;#10 VE_RSTJ =1'b0;#7 VE_RSTJ =1'b1;end//------- waveform dump: I use debussy as debug tool----initial begin$fsdbDumpfile("multi_cycle.fsdb");$fsdbDumpvars(0,ts );end//-------------finish-----------------------------initial begin#100 $finish;endendmodule////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////我们看它的波形:[[wysiwyg_imageupload:241:]] //逻辑综合我们来完成它的逻辑综合:使用的单元库为UMC的UMC018AG_AASW。逻辑综合时,我们设定时钟周期为6.5ns;逻辑综合完成后,得到时序报告文件,下面是它的一部分:****************************************Report : timing-path full-delay max-max_paths 3Design : multi_cycleVersion: 2002.05Date : Wed Dec 29 16:15:22 2004****************************************Operating Conditions: slow Library: UMC018AG_AASWWire Load Model Mode: topStartpoint: B[2] (input port clocked by VE_CLK)Endpoint: OUT_reg[0] (rising edge-triggered flip-flop clocked by VE_CLK)Path Group: VE_CLKPath Type: maxDes/Clust/Port Wire Load Model Library------------------------------------------------multi_cycle UMC18_Conservative UMC018AG_AASWPoint Incr Path--------------------------------------------------------------------------clock VE_CLK (rise edge) 0.00 0.00clock network delay (ideal) 0.00 0.00input external delay 1.00 1.00 rB[2] (in) 0.05 1.05 rdiv_30/b[2] (multi_cycle_DW_div_uns_17_6_1_test_1) 0.00 1.05 rdiv_30/U228/Y (BUFX20) 0.17 1.22 r......OUT_reg[0]/D (SDFFRXL) 0.00 13.24 fdata arrival time 13.24clock VE_CLK (rise edge) 7.00 7.00clock network delay (ideal) 0.00 7.00clock uncertainty -0.50 6.50OUT_reg[0]/CK (SDFFRXL) 0.00 6.50 rlibrary setup time -0.41 6.09data required time 6.09--------------------------------------------------------------------------data required time 6.09data arrival time -13.24--------------------------------------------------------------------------slack (VIOLATED) -7.15可以看出,这个除法在13ns内才能完成,在这里时钟周期为6.4ns,因此这个除法含有多周期路径。这个路径需要的周期数为3个。我们来分析这条多周期路径造成的后果:也就是下属语句:else if (DATA_RDY)OUT = #UDLY DATA_TMP;因为DATA_TMP的计算需要3个时钟周期,所以我们如果在DATA_RDY有效时对DATA_TMP采样,只能得到它的中间值,这自然是一个错误的值。为避免不匹配我们需要延迟两个周期后对DATA_TMP采样。//改写RTL code因此我们的文件改写为:////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////module multi_cycle (A ,B ,DATA_RDY,VE_CLK,VE_RSTJ,OUT,OUT_RDY);parameter A_WIDTH = 17;parameter B_WIDTH = 6;input [A_WIDTH-1:0]A;input [B_WIDTH-1:0]B;input DATA_RDY;input VE_RSTJ;input VE_CLK;output OUT;output OUT_RDY;reg OUT_RDY;reg DATA_RDY_DLY1;reg DATA_RDY_DLY2;reg [A_WIDTH-1:0]OUT ;parameter UDLY = 1;wire [(A_WIDTH-1):0] SUM_TMP= A / B ;always@(posedge VE_CLK or negedge VE_RSTJ) //the data addrif (!VE_RSTJ)OUT <= #UDLY 'd0 ;else if (DATA_RDY_DLY2)OUT <= #UDLY SUM_TMP;//---- output ready ------------------always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)DATA_RDY_DLY1 <= #UDLY 'd0 ;else DATA_RDY_DLY1 <= #UDLY DATA_RDY;always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)DATA_RDY_DLY2 <= #UDLY 'd0 ;else DATA_RDY_DLY2 <= #UDLY DATA_RDY_DLY1;always@(posedge VE_CLK or negedge VE_RSTJ)if (!VE_RSTJ)OUT_RDY <= #UDLY 'd0 ;else OUT_RDY <= #UDLY DATA_RDY_DLY2 ;endmodule//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////重新综合---得到逻辑网表文件(.net)和延迟文件(.sdf)///综合后的仿真波形:[[wysiwyg_imageupload:242:]] //总结:避免此种不匹配的方法:当我们的RTL设计中含有运算复杂,延迟较大的路径时,我们应该根据我们的时钟和使用的单元库,评估它会不会是多周期路径。如果是多周期路径,要看看它是否会造成逻辑和时序错误,然后对RTL代码做必要的修改。
4.总结在进行RTL设计时,为了保证RTL设计与综合后网表的一致,应注意:
- 结合所选用的逻辑综合工具的特点,使用合适的书写方式;
- 了解所使用的标准库单元的速度;
- 明确硬件电路时钟的频率,并估计一些复杂运算在一个周期内能否完成;
5.参考文献1)Don Mills, Clifford E. Cummings, RTL Coding Styles That Yield Simulation and Synthesis Mismatches,SNUG1999。2)Samir Palnitkar, VERILOG HDL, A Guide to DIGITAL Design and Synthesis, Sunsoft Press作者:王振国科广新(北京)信息技术公司 |
|