为啥不遵守icarus verilog指定的时间?

Posted

技术标签:

【中文标题】为啥不遵守icarus verilog指定的时间?【英文标题】:why are icarus verilog specify times not respected?为什么不遵守icarus verilog指定的时间? 【发布时间】:2020-09-27 01:26:33 【问题描述】:

我对“指定”的理解是它控制了从输入到输出的传播延迟。

所以..

我希望下面的代码显示 'o' 在 118 处发生变化 - 即 108 后 10 个时间单位时 'b' 发生变化 而是在 115 处合并了“b”更改,即更改后的 10 个单位。

>A T=   0  a  0  b  0  o  x
>B T=   0  a  0  b  0  o  x
 O T=  10  a  0  b  0  o  0
>A T= 105  a  1  b  0  o  0
>B T= 108  a  1  b  1  o  0
 O T= 115  a  1  b  1  o  2

我预料到了……

>A T=   0  a  0  b  0  o  x
>B T=   0  a  0  b  0  o  x
 O T=  10  a  0  b  0  o  0
>A T= 105  a  1  b  0  o  0
>B T= 108  a  1  b  1  o  0
 O T= 115  a  1  b  1  o  1
 O T= 118  a  1  b  1  o  2

我是否误解了“指定”?

见https://www.edaplayground.com/x/eBUY

module check(a,b,o);
  output wire [1:0] o;
  input [1:0]  a,b;

specify
    ( a => o ) = 10;
    ( b => o ) = 10;
endspecify

  assign o = a + b;

  always @ (a)
    $display (">A T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);
  always @ (b)
    $display (">B T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);
  always @ (o)
    $display (" O T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);

endmodule

module test;

  wire [1:0] o;
  logic [1:0] a,b;

  check t1(.a,.b,.o);


  initial begin
    a = 0;
    b = 0;
  end
  initial begin
    #105 a = 1;
  end
  initial begin
    #108 b = 1; // I EXPECT o TO CHANGE AS 108+10 BUT IT CHANGES AT 115
  end

endmodule

=========

更新...

似乎按我预期的方式工作的两种选择 见下文和https://www.edaplayground.com/x/P7kB

module check(a,b,o);
  output reg [1:0] o;
  input [1:0]  a,b;

  // OPTION 1 - put the delays on the individual wires
  wire #10 a_delayed = a;
  wire #10 b_delayed = b;
  assign o = a_delayed + b_delayed;

  
  // OPTION 2
  // Use non-blocking with RHS delay as per https://www-inst.eecs.berkeley.edu/~cs152/fa06/handouts/CummingsHDLCON1999_BehavioralDelays_Rev1_1.pdf
  //  always @* 
  //    o <= #10 a + b;
  
  always @ (a)
    $display (">A T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);
  always @ (b)
    $display (">B T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);
  always @ (o)
    $display (" O T=%4t  a %2d  b %2d  o %2d ", $time, a, b, o);

endmodule

选项 1 和 2 产生相同的输出 ...

>A T=   0  a  0  b  0  o  x 
>B T=   0  a  0  b  0  o  x 
 O T=  10  a  0  b  0  o  0 
>A T= 105  a  1  b  0  o  0 
>B T= 108  a  1  b  1  o  0 
 O T= 115  a  1  b  1  o  1 
 O T= 118  a  1  b  1  o  2 

有没有更好的方法让单个输入到输出的传播延迟起作用?

顺便说一句,这个问题实际上是这个问题的动机更复杂的用例的一部分。 我正在创建一个 74HCT151 的定时模型,并希望定时准确,因为我想生成已发布的定时暗示的稳定故障。

我应该为此创建一个单独的问题吗?

【问题讨论】:

【参考方案1】:

指定路径延迟有两种形式; 并行连接a=&gt;o完整连接a*&gt;o并行连接与编写a[0] =&gt; o[0]a[1] =&gt; o[1] 相同。 a[0] =&gt; o[1] 没有路径,b[0]=&gt;o[1] 也是如此。

在您的测试用例中,您正在更改 a[0]b[0],但 o[1] 正在更改,因为没有路径,所以延迟为 0。此外,LRM 第 30.7 节说

两个连续的预定转换在时间上比 模块路径延迟被视为一个脉冲。默认情况下,模块上的脉冲 路径输出被拒绝。

这就是为什么o 直接从02。您需要使用完整连接。

顺便说一句,在将 =&gt; 更改为 *&gt; 时,我无法让 EDAPlayground 上的 Icarus Verilog 与您的结果匹配或给我正确的结果,但所有其他模拟器都可以工作。


更新

您的选项 1 过滤输入故障。如果 ab 的毛刺少于 10 个时间单位,则会被过滤掉。您的选项 2 通过所有输出毛刺,甚至 0 延迟毛刺。如果你想要真实的脉冲过滤,你必须使用specify 路径延迟和$PATHPULSE,显然iverilog 没有正确实现。

【讨论】:

您好,请尝试一下 - 我做了更改,但结果相同... edaplayground.com/x/eBUY 查看我的更新。 EDAPlaygroud 上的所有 4 个商业模拟器都正确实现了路径延迟。 iverilog 没有。 谢谢 dave_59 。不知道您所说的“0 脉冲延迟”是什么意思,但似乎我能对故障敏感的最好方法是使用第二种方法?如果你有耐心,那么你介意看看这个...***.com/questions/64092936/… - 这是我问题的原始上下文。

以上是关于为啥不遵守icarus verilog指定的时间?的主要内容,如果未能解决你的问题,请参考以下文章

在 Icarus Verilog 中调试组合逻辑循环

如何使用 Icarus Verilog 在 Verilog 中转换 VHDL 代码?

编译动态内存模块时 Icarus Verilog 崩溃

如何在icarus verilog中包含文件?

Icarus Verilog:多位数组解析错误

icarus verilog 中的多维数组端口支持