RTL仿真中,由于对传输延时时间的模拟不够精确,对于某些信号的检测会与现实不符,下面演示会漏掉的一类信号。
RTL 代码功能:Clk 上升沿检测到 a==1 会使 b 翻转。
module my(
Clk,
Rst_n,
a,
b
);
input Clk;
input Rst_n;
input a;
output reg b;
always@(posedge Clk or negedge Rst_n) begin
if(!Rst_n)
b <= 0;
else if(a == 1)
b <= ~b;
end
endmodule
testbench
`timescale 1ns/1ns
`define Clk_period 20
module my_tb;
reg Clk, Rst_n, a;
wire b;
my my(
.Clk (Clk),
.Rst_n(Rst_n),
.a (a),
.b (b)
);
initial Clk = 1;
always#(`Clk_period/2) Clk = ~Clk;
initial begin
Rst_n = 0; a = 0;
#(`Clk_period*20+17);
Rst_n = 1;
#(`Clk_period*20+17);
@(posedge Clk);
a = 1;
#(`Clk_period);
a = 0;
@(negedge Clk);
a = 1;
#(`Clk_period + 1);
a = 0;
#123;
@(negedge Clk);
a = 1;
#(`Clk_period);
a = 0;
#200;
$stop;
end
endmodule
RTL仿真如下
可见,第一次 a=1 被完全漏掉了,没有检测到,第二次却被检测到,仅仅因为多延时了1ns。
第一次,Clk 的上升沿之后将 a 置 1,但是在下一个 Clk 上升沿,仍然会检测到 a 为 0,也就是 a=1 的时长小于一个时钟周期,恰巧藏进一个完整的时钟周期里面,而不会被检测到a==1。
第二次,Clk 的上升沿之后将 a 置 1,在下一个 Clk 上升沿,检测到 a 为 1,1ns 之后,a 被置为 0显然是这延长的 1ns 起了作用,这样的RTL仿真绝对不是我们想要的,接下来看看 后仿真。
a=1 第一次就被检测到了!
a=1 的时间没有延长,甚至时刻都与 RTL 仿真一致,但是这样的结果是我们所预期的
结论:RTL 仿真对于传输延时时间的模拟有一定的局限性,写 RTL 仿真代码的时候要注意这个问题,如果前方真不理想,不妨试试后仿真 或者 给信号加一些延时来模拟传输延时时间。 |