Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior difference between always_comb and always@(*)

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.

like image 646
AldoT Avatar asked Nov 16 '25 05:11

AldoT


2 Answers

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

like image 184
H.Modh Avatar answered Nov 18 '25 19:11

H.Modh


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.

like image 42
dave_59 Avatar answered Nov 18 '25 21:11

dave_59



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!