我有一个模拟,我在时钟边沿后更改信号并将其连接到 D 触发器。
always_ff
语句,它似乎适用于所有模拟器。这里发生了什么?
代码-testbench.sv
module testbench;
logic clk;
logic strb;
logic rdy_out_sv;
UUT2 uut2_instance (
.clk(clk),
.strb_in(strb),
.rdy_out(rdy_out_sv)
);
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, testbench);
end
initial
begin
clk = 0;
forever #(2.5) clk=~clk;
end
initial
begin
strb = 0;
@(posedge clk);
//#0;
for (int i=0; i<100; i++)
begin
strb = 1;
@(posedge clk);
//#0;
strb = 0;
@(posedge clk);
//#0;
end
$finish;
end
endmodule
和 UUT2.sv
module UUT2(
input logic clk,
input logic strb_in,
output logic rdy_out
);
always_ff @(posedge clk)
begin
rdy_out = strb_in;
end
endmodule
这是一个模拟:https://edaplayground.com/x/KmSs 它与 Aldec 和 Mentor 一起产生正确的结果
但是 Cadence 和 Synopsys(以及 Vivado)似乎是错误的,直到我取消注释
#0;
语句:
此外,如果我将 UUT2 移动到测试台内,它似乎对于所有模拟器都是正确的 - https://edaplayground.com/x/P8Fw
module testbench;
logic clk;
logic strb;
logic rdy_out_sv;
always_ff @(posedge clk)
begin
rdy_out_sv = strb;
end
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, testbench);
end
initial
begin
clk = 0;
forever #(2.5) clk=~clk;
end
initial
begin
strb = 0;
@(posedge clk);
//#0;
for (int i=0; i<100; i++)
begin
strb = 1;
@(posedge clk);
//#0;
strb = 0;
@(posedge clk);
//#0;
end
$finish;
end
endmodule
您需要使用非阻塞赋值 (
<=
) 在 Verilog 中对顺序逻辑进行建模。将其用于 rdy_out
中的 UUT2
信号并驱动来自测试台的 strb_in
输入。
module testbench;
logic clk;
logic strb;
logic rdy_out_sv;
UUT2 uut2_instance (
.clk(clk),
.strb_in(strb),
.rdy_out(rdy_out_sv)
);
initial begin
$dumpfile("dump.vcd");
$dumpvars(0, testbench);
end
initial
begin
clk = 0;
forever #(2.5) clk=~clk;
end
initial
begin
strb = 0;
@(posedge clk);
for (int i=0; i<100; i++)
begin
strb <= 1;
@(posedge clk);
strb <= 0;
@(posedge clk);
end
$finish;
end
endmodule
module UUT2(
input logic clk,
input logic strb_in,
output logic rdy_out
);
always_ff @(posedge clk)
begin
rdy_out <= strb_in;
end
endmodule