Sensitivity list of an always_comb block

Hi,

I am confused with behavior of the always_comb block.


module sample (input logic a, input logic b, output logic bn, output logic a_and_bn);
always_comb begin
  a_and_bn = a && bn;
  bn       = ~b;
end
endmodule

In simulation, the signal “a_and_bn” is not obtained as the and operation of signal “a” and signal “bn”.
The expecation is that the assigment “bn = ~b” will re-trigger the evaluation of the always_comb block.
To match the expectation, the code has to be re-written as


always_comb begin
  bn       = ~b;
  a_and_bn = a && bn;
end

Systemverilog LRM says " 9.2.2.2.1 Implicit always_comb sensitivities
The implicit sensitivity list of an always_comb includes the expansions of the longest static prefix of each variable or select expression that is read within the block or within any function called within the block with the following exceptions:
a) Any expansion of a variable declared within the block or within any function called within the block
b) Any expression that is also written within the block or within any function called within the block"

Signal “bn” is variable in the right hand side of the equation. Hence shouldn’t the always_comb block be re-evaluated with the new value of signal “bn”?

Thanks in advance!

Test bench is given for reference.


`timescale 1ns / 1ps

module tb_sample();
logic a; logic b; logic bn; logic a_and_bn;

initial begin
  $dumpfile("dump.vcd");
  $dumpvars(1, a, bn, a_and_bn);
  $dumpon;
  a = 0;
  b = 0;
  # 1000;
  a = 0;
  b = 1;
  # 1000;
  a = 1;
  b = 0;
  # 1000;
  a = 1;
  b = 1;
  # 1000;
  a = 0;
  b = 0;
  # 1000;
  a = 1;
  b = 1;
  # 1000;
  a = 0;
  b = 0;
  # 1000;
  $dumpflush;
  $stop;  
end

sample sample_i (
  .a        ( a         ), 
  .bn       ( bn        ),
  .b        ( b         ),
  .a_and_bn ( a_and_bn  )
);

endmodule

In reply to sts:

Since bn is written within the block, it is the exception and not put into the sensitivity list.

And even if they were put in the sensitivity list, always blocks do not ever “retrigger” themselves. They wait for a change in a signal, then execute the block, make any changes, then wait for another set of changes. The changes made inside the block have already happened.

In reply to dave_59:
AIUI: Systemverilog LRM says " 9.2.2.2.1 Implicit always_comb sensitivities
The implicit sensitivity list of an always_comb includes the expansions of the longest static prefix of each variable or select expression that is read within the block or within any function called within the block with the following exceptions:
“b) Any expression that is also written within the block or within any function called within the block”

excludes the signals / varaibles that are assigned in the within the always_comb from the implict sensitivity list.

I tried explicity mentioning signal “bn” in the sensitivity list using always @ (a, b, bn). That also behaves the same as always_comb. Thanks dave_59 for the explanation.