当我在任务中使用武力时,我看到其他无关信号的副作用也受到影响。在下面的示例中,我尝试在模块“ dut”内强制使用两个自变量“ a”和“ b”。为此,我在接口“ intf”内部使用了辅助任务“ force1”。但是我发现更改'b'也会导致'a'更改,如输出所示。
edaplayground上的测试用例。 https://www.edaplayground.com/x/23LM
module dut(intf i1);
logic a;
logic b;
endmodule
interface intf;
task force1(bit sel, int value);
if(sel == 0) begin
$display("[%0t]:forcing a to %0d", $stime, value);
force dut1.a = value;
end
else begin
$display("[%0t]:forcing b to %0d", $stime, value);
force dut1.b = value;
end
endtask
endinterface
module test();
intf intf1();
dut dut1(intf1);
always@(dut1.a) begin
$display("[%0t]:Changing value of a=%0d", $stime, dut1.a);
end
always@(dut1.b) begin
$display("[%0t]:Changing value of b=%0d", $stime, dut1.b);
end
initial begin
intf1.force1(.sel(0), .value(1));// Change value of a to 1
#10;
intf1.force1(.sel(1), .value(0));// Change value of b to 0
#10;
$finish;
end
endmodule
[0]:forcing a to 1
[0]:Changing value of a=1
[10]:forcing b to 0
[10]:Changing value of a=0 ----------> WHY DID THIS CHANGE?
[10]:Changing value of b=0
I expected the output 'a' not to change to 0.
答案 0 :(得分:2)
问题在于value
是静态变量。当您在Verilog中声明任务时,除非您将任务指定为automatic
,否则任务中的所有变量都将是静态的,这意味着对任务的每次修改变量的调用都会对该任务的所有调用执行(就像在C中创建静态局部变量一样。
还需要注意的是,force
过程分配不仅会解析RHS并将LHS设置为该值,而是会强制将LHS设置为RHS上的表达式。因此,像force A = B;
这样的赋值将使A
等于B
在应用force
时以及之后B
可能被更新的任何时间。将其与上面的信息放在一起(value
是静态的),您无法将dut1.a
的{{1}}设置为1
,而将其设置为force
。 value
在您下次调用任务时发生更改后,value
也会随之更改以匹配它。
现在,不幸的是,由于dut1.a
需要静态表达式(即表达式),因此您不能仅仅执行任务automatic
或仅仅使value
automatic
来解决问题只能使用静态变量或常量)。一种解决方案是为所需的值创建一个静态占位符,以使force
与任务输入force
断开连接;您可以使用数组来做到这一点:
value