Ald*_*doT 2 verilog system-verilog
我刚刚发现 always@(*) 在涉及function
.
请参阅下面的简单示例代码。
http://www.edaplayground.com/x/J7M
module test;
reg a, b, c;
function reg my_func();
if (b==0) begin
$display("DEBUG 0 @%0t", $time);
return a;
end
else if (b==1) begin
$display("DEBUG 1 @%0t", $time);
return ~a;
end
else begin
$display("DEBUG 2 @%0t", $time);
return 0;
end
endfunction
always @(*) begin
//always_comb begin
c = my_func();
end
initial begin
a = 0; #10;
a = 1; #10;
a=0;
end
endmodule
Run Code Online (Sandbox Code Playgroud)
尝试在模拟always @(*)
和always_comb
模拟之间切换。如果我使用always @(*)
,则不会显示任何内容。但是,如果我使用always_comb
,它将显示如下预期结果:
DEBUG 2 @0
DEBUG 2 @0
DEBUG 2 @10
DEBUG 2 @20
Run Code Online (Sandbox Code Playgroud)
上面的代码只是简单的组合逻辑。为什么always @(*)
和always_comb
显示不同的结果?只是模拟问题吗?进一步的实验我注意到它可能与function
在 always 块中的使用有关。
always@(*)
块对所有变量的值变化很敏感,即由 always 块读取,或者我们可以说哪个位于 always 块内的右侧。
在您的示例中,始终块中没有使用任何变量,因此始终@(*)
块在这里不起作用。
根据 SV LRM,
always_comb 对函数内容的变化敏感,而 always @* 只对函数参数的变化敏感。
即,每当函数内的变量发生变化时, always_comb 将触发,但在您的情况下, always @(*) 只有在我们在函数中传递参数时才会触发。
所以你可以使用,
always @(*) begin
c = my_func(b);
end
Run Code Online (Sandbox Code Playgroud)
或者你可以使用,
always_comb begin
c = my_func();
end
Run Code Online (Sandbox Code Playgroud)
我已经修改了你的代码。请在下面的链接中找到它。
http://www.edaplayground.com/x/JiS