System verilog 接口任务内force语句的意外行为

System verilog 接口任务内force语句的意外行为,system-verilog,System Verilog,当我在任务中使用武力时,我看到其他无关信号的副作用受到影响。在下面的示例中,我尝试在模块“dut”内强制两个自变量“a”和“b”。为此,我在接口“intf”中使用助手任务“force1”。但是,我发现更改“b”也会导致“a”发生更改,如输出中所示 EDA上的测试用例 问题在于value是一个静态变量。在Verilog中声明任务时,除非将任务指定为自动,否则任务中的所有变量都将是静态的,这意味着修改变量的每个任务调用对该任务的所有调用都是静态的(类似于在C中创建静态局部变量) 同样重要的是要注意,

当我在任务中使用武力时,我看到其他无关信号的副作用受到影响。在下面的示例中,我尝试在模块“dut”内强制两个自变量“a”和“b”。为此,我在接口“intf”中使用助手任务“force1”。但是,我发现更改“b”也会导致“a”发生更改,如输出中所示

EDA上的测试用例


问题在于
value
是一个静态变量。在Verilog中声明任务时,除非将任务指定为
自动
,否则任务中的所有变量都将是静态的,这意味着修改变量的每个任务调用对该任务的所有调用都是静态的(类似于在C中创建静态局部变量)

同样重要的是要注意,
force
过程赋值不仅仅解析RHS并将LHS设置为该值,而是强制将LHS设置为RHS上的表达式。因此,像
force A=B这样的赋值
时,code>将使
A
等于
B
,并且之后可能会随时更新
B
。将其与上述信息结合起来(
value
是静态的),您并没有使用
force
dut1.a
设置为
1
,而是将其设置为
value
。一旦
value
随下一次任务调用而更改,
dut1.a
也会更改以匹配它

现在,不幸的是,您不能仅使任务
自动
或仅使
自动
来解决问题,因为
强制
需要静态表达式(即仅静态变量或常量的表达式)才能工作。一种解决方案是为所需的值创建一个静态占位符,将
强制
与任务输入
断开;您可以使用阵列执行此操作:

task force1(bit sel, int value);
  static int values[1 << $bits(sel)]; // <- Make sure no matter the width of sel, there are enough places in the array, could just be values[2]
  values[sel] = value;
  if(sel == 0) begin
    $display("[%0t]:forcing a to %0d", $stime, value);
    force dut1.a = values[0];
  end
  else begin
    $display("[%0t]:forcing b to %0d", $stime, value);
    force dut1.b = values[1];
  end
endtask
任务组1(位选择,int值);

静态int值[1如果我们删除任务中值的“静态”限定符,代码也会起作用。将其设置为“静态”的原因是什么?@sanjeevsing由于任务本身是
静态的
,因此所有局部变量也是静态的(除非明确声明为
自动的
).因此,由于
force1
静态的,因此
值也是静态的。
我只是为了更明确地提醒大家
值的行为:)
[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.
task force1(bit sel, int value);
  static int values[1 << $bits(sel)]; // <- Make sure no matter the width of sel, there are enough places in the array, could just be values[2]
  values[sel] = value;
  if(sel == 0) begin
    $display("[%0t]:forcing a to %0d", $stime, value);
    force dut1.a = values[0];
  end
  else begin
    $display("[%0t]:forcing b to %0d", $stime, value);
    force dut1.b = values[1];
  end
endtask