【问题标题】:Unexpected behavior with force statement inside interface task界面任务中的 force 语句出现意外行为
【发布时间】:2019-04-02 02:46:41
【问题描述】:

当我在任务中使用武力时,我看到其他不相关信号的副作用受到影响。在下面的示例中,我尝试在模块“dut”中强制使用 2 个自变量“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.

【问题讨论】:

    标签: system-verilog


    【解决方案1】:

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

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

    现在,不幸的是,您不能只创建任务automatic 或只创建value automatic 来解决问题,因为force 需要一个静态表达式(即仅包含静态变量或常量的表达式)来工作。一种解决方案是为您想要的值创建一个静态占位符,将您的force 与您的任务输入value 断开连接;你可以用一个数组来做到这一点:

    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
    

    【讨论】:

    • 如果我们删除任务中值的“静态”限定符,该代码也可以工作。将其设为“静态”的原因是什么?
    • @SanjeevSingh 它在技术上是多余的,因为任务本身是static,因此所有局部变量也是如此(除非明确声明为automatic)。所以,因为force1static,所以values 也是。我只是将它包括在内,以更明确地提醒values 的行为方式:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-28
    • 2018-11-26
    • 1970-01-01
    相关资源
    最近更新 更多