Search code examples
verilogsystem-verilog

Why is $display not executing when I expect it to?


In my bench program, I have something like this (simplified):

// bench.sv
program tb (input clk, ...);
  initial begin
    ...
    repeat (100) begin
      main_module_interface.write_index <= bench.write_index;
      // drive additional inputs
      ...

      @(clk);

      $display("%t : BENCH", $realtime);

In my main module, I have a generate loop to create my index_reg modules

// main_module.sv
generate
  for (genvar ix = 0; ix < 32; ix++) begin
    index_reg #(.WIDTH(32), .INDEX(ix)) r (
      .clk,
      .ind(writeIFC.write_index),
      ...
    );
  end
endgenerate

Then in my index_reg module, I have added the following debug code:

// index_reg.sv
always @ (posedge clk) begin
  if (INDEX == 10) begin
    $display("I see the clock");
  end
end

I would expect to see this output:

I see the clock
10 : BENCH
I see the clock
20 : BENCH
I see the clock
30 : BENCH
I see the clock
40 : BENCH
I see the clock
50 : BENCH
etc.

But sometimes, the "I see the clock" only shows up every other time. So I see

10 : BENCH
I see the clock
20 : BENCH
30 : BENCH
I see the clock
40 : BENCH
50 : BENCH
etc.

I can't understand why that might happen. Can someone please point me in the right direction?


Solution

  • Without seeing more of the code, here is my best guess.

    @(clk);
    

    That code is triggered on every clk edge, both posedge and negedge.

    always @ (posedge clk) begin
    

    That code is only triggered on posedge of clk, which is every other time.

    That may be why you see BENCH twice as often as I see the clock.

    If that doesn't answer your question, provide a complete code example that anyone can compile and run.