对ref参数的非阻塞赋值

时间:2017-08-29 16:24:18

标签: system-verilog

我想了解System Verilog中的任务是如何工作的。我认为任务只是一种命名和参数化一些代码的方式,否则这些代码可能会出现在beginend之间。但是,参数的工作方式并不明显。

假设我想从模块中分解出非阻塞分配的实例。我可能会执行以下操作,从而达到相同任务的两个实例在参数(ff_0和ff_1)中不同的程度。

module test_inlined;

bit clk;
int count = 0;   
logic [7:0] x, y, z;

task automatic ff_0;
   @(posedge clk);
   y <= x;
endtask

task automatic ff_1; // really same task as ff_0 to within variable renaming
   @(posedge clk);
   z <= y;
endtask   

always
  ff_0;

always
  ff_1;

always @(posedge clk)
  $strobe("%d: x=%d, y=%d, z=%d", count, x, y, z);

always
  #5 clk = !clk;

always @(posedge clk)
  begin
    x <= count;
    count ++;
    if (count > 20) $finish;    
  end   

endmodule

将相关的分配(也称为触发器)放入同一模块的两个实例中将是微不足道的,因此有意义的是,它也可以根据两个实例表达相同的功能。同样的任务。

以下不起作用,因为out应该是自动的,或者是Modelsim声称的。我不明白为什么会这样,因为它显然是对模块的静态成员的引用?

task automatic ff (ref logic [7:0] out, ref logic [7:0] inp, ref bit clk);
 @(posedge clk);
 out <= inp;
endtask   

module test_broken;

  bit clk;
  int count = 0;   
  logic [7:0] x, y, z;

  always
    ff(y, x, clk);

  always
    ff(z, y, clk);

  // .... same as before

endmodule

有意义的是,任务需要自动使用ref参数,因为这样就不必担心它们的生命周期了。不太清楚为什么只允许阻止对自动变量的赋值。当有未决的非阻塞分配时,有没有明显的需要自动变量消失?

如何将非阻止分配分解为任务?非常感谢提前。

1 个答案:

答案 0 :(得分:1)

问题是task不能假设传递给它的变量的存储分类。为任务生成的代码必须适用于任何类型的存储,因此通过ref必须采取悲观的限制集。