模拟器和架构之间的信号门控差异

问题描述 投票:0回答:1

我有一个模拟,我在时钟边沿后更改信号并将其连接到 D 触发器。

  • 我预计 D 触发器的输出会在下一个时钟结束时发生变化,但在某些模拟器中它会与输入同时变化。
  • 如果我在更改信号之前添加 #0 语句,它似乎适用于所有模拟器。
  • 如果我将触发器从外部模块移至内部
    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
simulation system-verilog
1个回答
0
投票

您需要使用非阻塞赋值 (

<=
) 在 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
© www.soinside.com 2019 - 2024. All rights reserved.