Equivalent of ##0 when there is not a default clocking block

A simple one that’s bugged me for a long time. Hopefully I’ve just been missing something all along.

When a default clocking block has been declared, we can use ##0 to move to the next clock edge if we’re not already at a clock edge.

How do I get the same functionality if there is no default clocking block and the ## notation is unavailable?

Thanks!

In reply to jjarmagost:
the LRM is clear:

If no default clocking has been specified for the current module, interface, checker, or program, then the compiler shall issue anerror.

You would have to essentially replicate the functionality of a clocking block by creating your own clocking event

event cb;
always @(posedge clk) -> cb;

task wait_cycle(int N);
 if (N == 0)
    wait (cb.triggered);
 else 
    repeat (N) @cb;
endtask

In reply to dave_59:

Thanks for your fast reply, Dave!

I don’t think my question was stated very clearly though. Sorry about that.

Please see the following example:


module no_default_clocking_block;

  // clock "a"

  logic   clk_a = '0;
  always #5ns clk_a = ~clk_a;

  clocking cb_a @(posedge clk_a);
  endclocking
  

  // clock "b"

  logic   clk_b = '0;
  always #2ns clk_b = ~clk_b;

  clocking cb_b @(posedge clk_b);
  endclocking

endmodule


As shown, I have two clocking blocks and neither one is declared as the default. How can I get the behavior that ##0 gives me when there is a default clocking block?

In other words, how do I say “if we’re at the clock edge do nothing, else go to next edge”?

Thanks!

In reply to jjarmagost:

That seems like an incredibly strange requirement, but you can do

event e_a;
always @(posedge clk) -> e_a;
event e_b;
always @(posedge clk) -> e_b;

task wait_for_next_clock;
  wait(e_a.trigered || e_b.trigered);
endtask