I just found that always@(*) does not work as expected when it involve function.
Please see simple sample code below.
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
Try to switch between always @(*) and always_comb in simulation. If I use always @(*), nothing will display. But if I use always_comb, it will show expected result as follows:
DEBUG 2 @0
DEBUG 2 @0
DEBUG 2 @10
DEBUG 2 @20
The above code is just simple combinational logic.
Why always @(*) and always_comb show different result? Is it just simulation issue? Further experiment I noticed that it may have something to do with usage of function inside the always block.
The always @(*) block is sensitive to change of the values all the variables, that is read by always block or we can say which are at the right side inside the always block.
In your example, there are no any variables used inside always block, so this always @(*) block will not work here.
As per SV LRM,
always_comb is sensitive to changes within the contents of a function, whereas always @* is only sensitive to changes to the arguments of a function.
i.e., whenever the variables inside a function will change, the always_comb will trigger, but in your case, always @(*) will only trigger if we pass an argument in the function.
So either you can use,
always @(*) begin
c = my_func(b);
end
or you can use,
always_comb begin
c = my_func();
end
I have modified your code. Please find it in below link.
http://www.edaplayground.com/x/JiS
always @(*) was added by Verilog IEEE 1364-2001 standard and replaced by always_comb in the SystemVerilog IEEE 1800-2005 standard. always @(*) should no longer be used because it does not correctly simulate hardware in all cases. In addition to the difference you note with functions, it does not handle constant logic correctly.
parameter C = 0;
reg A,B;
always @(*) A = B && C;
A remains unknown until there is a change on B. Whereas using always_comb will immediately set A to 0 because execution at time 0 is guaranteed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With