为什么不遵守 icarus verilog 指定时间?
why are icarus verilog specify times not respected?
我对“指定”的理解是它控制从输入到输出的传播延迟。
所以..
我希望下面的代码显示 'o' 在 118 处发生变化 - 即 'b' 发生变化时 108 之后的 10 个时间单位
但 'b' 更改合并到 115,即更改后的 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
我是不是误会了'specify'?
见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 的定时模型,并希望定时准确,因为我想生成发布的定时暗示的稳定毛刺。
我应该为此创建一个单独的问题吗?
指定路径延迟有两种形式; 并行 连接a=>o
和完全 连接a*>o
。 并连接等同于写a[0] => o[0]
和a[1] => o[1]
。 a[0] => o[1]
没有路径,b[0]=>o[1]
.
也一样
在您的测试用例中,您正在更改 a[0]
和 b[0]
,但是 o[1]
正在更改,因为没有路径,所以延迟为 0。此外,LRM 第 30.7 节说
Two consecutive scheduled transitions closer together in time than the
module path delay are deemed a pulse. By default, pulses on a module
path output are rejected.
这就是 o
直接从 0
到 2
的原因。您需要使用 Full 连接。
顺便说一句,我无法在 EDAPlayground 上使用 Icarus Verilog 来匹配您的结果,或者在将 =>
更改为 *>
时给我正确的结果,但所有其他模拟器都可以。
更新
您的选项 1 过滤输入故障。如果 a
或 b
的毛刺少于 10 个时间单位,则这些毛刺将被过滤掉。您的选项 2 通过所有输出毛刺,甚至 0 个延迟毛刺。如果你想要真实的脉冲滤波,你必须使用 specify
路径延迟和 $PATHPULSE
并且显然 iverilog 没有正确实现。
我对“指定”的理解是它控制从输入到输出的传播延迟。
所以..
我希望下面的代码显示 'o' 在 118 处发生变化 - 即 'b' 发生变化时 108 之后的 10 个时间单位 但 'b' 更改合并到 115,即更改后的 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
我是不是误会了'specify'?
见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 的定时模型,并希望定时准确,因为我想生成发布的定时暗示的稳定毛刺。
我应该为此创建一个单独的问题吗?
指定路径延迟有两种形式; 并行 连接a=>o
和完全 连接a*>o
。 并连接等同于写a[0] => o[0]
和a[1] => o[1]
。 a[0] => o[1]
没有路径,b[0]=>o[1]
.
在您的测试用例中,您正在更改 a[0]
和 b[0]
,但是 o[1]
正在更改,因为没有路径,所以延迟为 0。此外,LRM 第 30.7 节说
Two consecutive scheduled transitions closer together in time than the module path delay are deemed a pulse. By default, pulses on a module path output are rejected.
这就是 o
直接从 0
到 2
的原因。您需要使用 Full 连接。
顺便说一句,我无法在 EDAPlayground 上使用 Icarus Verilog 来匹配您的结果,或者在将 =>
更改为 *>
时给我正确的结果,但所有其他模拟器都可以。
更新
您的选项 1 过滤输入故障。如果 a
或 b
的毛刺少于 10 个时间单位,则这些毛刺将被过滤掉。您的选项 2 通过所有输出毛刺,甚至 0 个延迟毛刺。如果你想要真实的脉冲滤波,你必须使用 specify
路径延迟和 $PATHPULSE
并且显然 iverilog 没有正确实现。