接口任务内部使用force语句发生意外行为

时间:2019-04-01 15:37:26

标签: system-verilog

当我在任务中使用武力时,我看到其他无关信号的副作用也受到影响。在下面的示例中,我尝试在模块“ 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.

1 个答案:

答案 0 :(得分:2)

问题在于value是静态变量。当您在Verilog中声明任务时,除非您将任务指定为automatic,否则任务中的所有变量都将是静态的,这意味着对任务的每次修改变量的调用都会对该任务的所有调用执行(就像在C中创建静态局部变量一样。

还需要注意的是,force过程分配不仅会解析RHS并将LHS设置为该值,而是会强制将LHS设置为RHS上的表达式。因此,像force A = B;这样的赋值将使A等于B在应用force时以及之后B可能被更新的任何时间。将其与上面的信息放在一起(value是静态的),您无法将dut1.a的{​​{1}}设置为1,而将其设置为forcevalue在您下次调用任务时发生更改后,value也会随之更改以匹配它。

现在,不幸的是,由于dut1.a需要静态表达式(即表达式),因此您不能仅仅执行任务automatic或仅仅使value automatic来解决问题只能使用静态变量或常量)。一种解决方案是为所需的值创建一个静态占位符,以使force与任务输入force断开连接;您可以使用数组来做到这一点:

value