对 ref 参数的非阻塞赋值
Non-blocking assignment to ref parameter
我想了解 System Verilog 中的任务是如何工作的。我认为任务只是一种命名和参数化一些代码的方式,否则这些代码可能会出现在 begin
和 end
之间。但是,参数的工作方式并不明显。
假设我想从模块中提取非阻塞分配的实例。我可能会做类似下面的事情,从而达到同一任务的两个实例仅在参数上有所不同(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 参数是有道理的,因为这样就无需担心它们的生命周期。不太清楚为什么只允许对自动变量进行阻塞赋值。当有挂起的非阻塞分配时,似乎没有明显需要自动变量消失?
请问如何将非阻塞分配分解为任务?非常感谢。
问题是 task
无法对传递给它的变量的存储分类做出任何假设。为该任务生成的代码必须适用于任何类型的存储,因此通过 ref
必须接受悲观的限制集。
我想了解 System Verilog 中的任务是如何工作的。我认为任务只是一种命名和参数化一些代码的方式,否则这些代码可能会出现在 begin
和 end
之间。但是,参数的工作方式并不明显。
假设我想从模块中提取非阻塞分配的实例。我可能会做类似下面的事情,从而达到同一任务的两个实例仅在参数上有所不同(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 参数是有道理的,因为这样就无需担心它们的生命周期。不太清楚为什么只允许对自动变量进行阻塞赋值。当有挂起的非阻塞分配时,似乎没有明显需要自动变量消失?
请问如何将非阻塞分配分解为任务?非常感谢。
问题是 task
无法对传递给它的变量的存储分类做出任何假设。为该任务生成的代码必须适用于任何类型的存储,因此通过 ref
必须接受悲观的限制集。