逻辑值变化事件
Event on logic value change
我通常使用 @
运算符来等待特定信号的任何逻辑值变化。例如,要等待信号 a
的任何变化,我通常会这样做
wire a;
//...
@(a); // wait any value change 0->1 or 1->0, or x->1 etc
但现在我意识到上面的代码并不总是按预期工作,尤其是当我们引入信号强度时,如下代码所示:
module test;
wire a;
logic sweak1 = 0;
logic spull1 = 0;
assign (weak0,weak1) a = sweak1 ? 1'b1 : 1'bz;
assign (pull0,pull1) a = spull1 ? 1'b1 : 1'bz;
task wait_a_change();
@(a);
endtask
initial forever begin
$display("Value: a = %b %v @%0t", a, a, $time);
wait_a_change();
end
initial begin
sweak1 = 1;
#10; spull1 = 1;
#10; spull1 = 0;
#10; spull1 = 1;
#10;
end
endmodule
即使 a
的逻辑值没有改变,事件 @(a)
也会触发。
所以我克服这个问题的第一个解决方案是:
task wait_a_change();
if (a) @(negedge a);
else @(posedge a);
endtask
该解决方案需要额外检查(也需要行)。
有没有更好的解决办法?
尝试@(!a)
。通过布尔表达式,它失去了力量。您唯一松动的是 x->z 转换。 (您的解决方案也不会捕捉到)。如果你需要,你最好更好地解释你想要完成的事情,而在哪些地方可能需要采取完全不同的方法。
如果你想获得 4 状态值 (1/0/X/Z) 你可以做 @(posedge a, negedge a)
或 @(posedge a or negedge a)
。我已经看到至少一个模拟器有一个错误,将这些错误视为 @(a)
。如果你的模拟器支持IEEE1800-2009(SystemVerilog 2009)或更高版本,你可以使用@(edge a)
。如果一切都失败了,你总是可以用另一条线对值进行采样。
wire a_val = a; // <-- 4-state value w/o preserving the strength
task wait_a_change();
@(a_val);
endtask
我通常使用 @
运算符来等待特定信号的任何逻辑值变化。例如,要等待信号 a
的任何变化,我通常会这样做
wire a;
//...
@(a); // wait any value change 0->1 or 1->0, or x->1 etc
但现在我意识到上面的代码并不总是按预期工作,尤其是当我们引入信号强度时,如下代码所示:
module test;
wire a;
logic sweak1 = 0;
logic spull1 = 0;
assign (weak0,weak1) a = sweak1 ? 1'b1 : 1'bz;
assign (pull0,pull1) a = spull1 ? 1'b1 : 1'bz;
task wait_a_change();
@(a);
endtask
initial forever begin
$display("Value: a = %b %v @%0t", a, a, $time);
wait_a_change();
end
initial begin
sweak1 = 1;
#10; spull1 = 1;
#10; spull1 = 0;
#10; spull1 = 1;
#10;
end
endmodule
即使 a
的逻辑值没有改变,事件 @(a)
也会触发。
所以我克服这个问题的第一个解决方案是:
task wait_a_change();
if (a) @(negedge a);
else @(posedge a);
endtask
该解决方案需要额外检查(也需要行)。 有没有更好的解决办法?
尝试@(!a)
。通过布尔表达式,它失去了力量。您唯一松动的是 x->z 转换。 (您的解决方案也不会捕捉到)。如果你需要,你最好更好地解释你想要完成的事情,而在哪些地方可能需要采取完全不同的方法。
如果你想获得 4 状态值 (1/0/X/Z) 你可以做 @(posedge a, negedge a)
或 @(posedge a or negedge a)
。我已经看到至少一个模拟器有一个错误,将这些错误视为 @(a)
。如果你的模拟器支持IEEE1800-2009(SystemVerilog 2009)或更高版本,你可以使用@(edge a)
。如果一切都失败了,你总是可以用另一条线对值进行采样。
wire a_val = a; // <-- 4-state value w/o preserving the strength
task wait_a_change();
@(a_val);
endtask