FPGA后仿真时,相比于功能仿真增加了门延时和布线延时,相对于门级仿真增加了布线延时,因此后仿真相比于功能仿真具有不同的特点。
下面所示的代码在功能仿真时是正确的的,但在后仿真时,似乎是有问题的。功能很简单,当delay为高电平时,a与b相加,将结果赋值给out;当delay为低电平时,a与b相乘,将结果赋值给out。
RTL源代码:
`timescale 1ns / 1ps
module Top(clk,rst,in,out,delay);
input clk,rst,in;
output reg[3:0] out;
output reg delay;
reg [1:0] a,b;
always @(posedge clk or negedge rst)
if (!rst)
begin
delay<=0;
a<=0;
b<=0;
end
else
begin
delay<=in;
a<=a+1;
b<=b+1;
end
always @ ( *)
if(delay==1)
out<=a+b;
else
out<=a*b;
endmodule
testbench代码:
`timescale 1ns / 1ps
module tb;
reg clk,rst,in;
wire delay;
wire[3:0] out;
initial
begin
clk<=0;
rst<=0;
in <=0;
#100 rst<=1;
@(posedge clk)
#1 in<=0;
@(posedge clk)
#1 in<=1;
@(posedge clk)
#1 in<=0;
@(posedge clk)
#1 in<=1;
@(posedge clk)
#1 in<=0;
@(posedge clk)
#1 in<=1;
end
always #5 clk=~clk;
Top inst(.clk(clk),.rst(rst),.in(in),.out(out),.delay(delay) );
endmodule
在时序仿真时,我们不能只关心端口的clk与其他信号如in、delay等的时序关系。原因分析如下:
端口的clk在经过vivado的综合与实现后,vivado将clk部署到全局时钟网络(BUFG),这会引入时钟偏斜。如下图1所示,clk经过IBUF会引入时钟偏斜,再经过BUFG进一步引入时钟偏斜。
图1 时钟偏斜
vivado综合后的IBUF网表如下:
IBUF clk_IBUF_inst
(.I(clk),
.O(clk_IBUF));
与IBUF对应的标准延时文件描述如下:
(CELL
(CELLTYPE "IBUF")
(INSTANCE clk_IBUF_inst)
(DELAY
(PATHPULSE (50.0))
(ABSOLUTE
(IOPATH I O (639.2:764.8:764.8) (639.2:764.8:764.8))
)
)
)
通过分析IBUF的输入与输出,可以看出clk与clk_IBUF相位偏斜为764.8ns,通过查看时序仿真波形可以看出clk与clk_IBUF相差764.8ns。
同样,输入信号经过不同的门,也会引入延时,例如输入信号in,在经过IBUF后,会引入延时,IBUF网表如下所示(clk与in都是通过IBUF,但是两者延时不一样):
IBUF in_IBUF_inst
(.I(in),
.O(in_IBUF));
IBUF的标准延时文件如下所示:
(CELL
(CELLTYPE "IBUF")
(INSTANCE in_IBUF_inst)
(DELAY
(PATHPULSE (50.0))
(ABSOLUTE
(IOPATH I O (613.0:738.4:738.4) (613.0:738.4:738.4))
)
)
)
综上所述,在进行时序仿真时,如果输入的时钟、信号经过不同的门或布线延时,不能只看原始的时钟和信号的时序关系。如研究clk与in之间的相位关系如下图所示:
clk与in都经过不同的门和布线延时,单纯比较clk 与in 的相位关系,无法判断delay触发器是否满足建立与保持时间的关系,所以必须查看clk_IBUF_BUFG与in_IBUF的时间是否满足建立与保持关系。