Can we include final block in systemverilog macros

Hi

i need to include final block inside my macros.svh file, my macro looks like this:

`define FATAL_FINISH(ifdef_msg, msg, verbosity_l) \
   if(ifdef_msg) \
   if(VERBOSITY>=verbosity_l) \
   begin $fatal("%m: time- %0t", $time,msg); end \

but if i include final block inside this, this is giving compilation issue i.e , systemverilog final block cannot be called in this context.
i.e

`define FATAL_FINISH(ifdef_msg, msg, verbosity_l) \
   if(ifdef_msg) \
   if(VERBOSITY>=verbosity_l) \
   begin $fatal("%m: time- %0t", $time,msg);  final $finish end \ 

do we have any solution on this, i.e how to include final block inside my macro.

Thanks

In reply to Somu:

SystemVerilog macros don’t care about SystemVerilog syntax. Your code needs to make sense after the macro text gets expanded.

A final block is like the inverse of an initial block. It instantiates a block of procedural statements, but is not a statement in itself. A final block executes as the result of a call to $finish. You do not put $finish inside a final block.

There is no need for you to cal $finish because $fatal implicitly calls $finish.

In reply to dave_59:

I know fatal will call implicitly $finish, but in our design we have multiple final blocks which gets executed whenever tests ends, i.e when $finish gets called, but the problem is when fatal error occurred it will call implicitly call $finish, but then rest of the final block in other modules get triggered, actually I don’t want those prints coming from rest of the final blocks, that’s why I am keeping one more final block there I am explicitly calling $finish in order to avoid prints from other final block.

In reply to Somu:

That strategy will not work. First of all, as soon as you execute $fatal, that thread terminates immediately ( along with all other threads). No statement in the block executes after executing $fatal or $finish. Secondly, assuming you could develop the right macro, the order of execution of final blocks is unpredictable.

So you either have to live with the extra information printed out (I don’t know why you would even care if you are going have to go back and debug the test anyway), or set a global flag that each final block checks before printing out.

Of course, if you were using the UVM, you wouldn’t have to worry about any of this and the report_phase takes care of this for you.

In reply to dave_59:

Hi Dave,

Thanks for your valuable inputs, but how do i set a global flag that each final block will check before printing out. can you please write a snippet for that.

Thanks,
Somu

In reply to Somu:

package globals;

  bit skip_final_blocks = 0;

endpackage

// inside macro
 begin $fatal("%m: time- %0t", $time,msg); globals::skip_final_blocks = 1; end

// inside all final blocks
final begin
  if (globals::skip_final_blocks) $finish; // causes immediate exit
  ... 
end