Search code examples
macroscompilationverilogsystem-veriloghdl

Prevent systemverilog compilation if certain macro isn't set


I am writing a systemverilog module and I need to make sure that a certain macro is set to allow compilation to proceed.

I have tried the below, but it simply gives the syntax error "unexpected SYSTEM_IDENTIFIER" $fatal.

I know that does technically stop the compilation, but does anyone know of a more graceful solution?

* Correction, if the syntax in the `else branch is not correct, none of the branches will compile successfully.

`ifdef MACRO_0
// Some code
`elsif MACRO_1
// Some other code
`else
$fatal("MACRO_0 or MACRO_1 must be set for compilation");
`endif

As per recommendation, adding the below information to the question:

The code is in a module but not inside an initial or always statement. I am hoping to find a solution that will allow me to terminate the compilation i.e. elaboration of hdl. I am designing for FPGA implementation and I need to make sure that no other user of this code can reach the synthesis phase of a design flow without setting one of these macros.


Solution

  • $fatal is a run-time system call, not a compile-time fatal as mentioned by toolic. I don't think you can stop the compile unless you have a compile error. In your sample code you are getting close to what you want by hiding part of the code, but the compile does not terminate and you don't print the right message.

    I am not aware of any standard Verilog/SystemVerilog construct for printing a customized message during the compile time. GCC for example, has #error for this purpose. However, some synthesis tools, like Synopsis Design Compiler do print the output of $display messages during elaboration time. The $display still needs to be inside an always block. If you also deliberately place an elaboration error when MACRO0 and MACRO1 are not defined, you may be able to terminate the synthesis.

    For example, in the following, a dummy module is instantiated without defining its body:

    `ifdef MACRO_0
    // Some code
    `elsif MACRO_1
    // Some other code
    `else
     logic a;
     always $display("MACRO_0 or MACRO_1 must be set for compilation");
     DEFINE_MACRO0_OR_MACRO1 dummy (.in(a));
    `endif
    

    this will generate the following elaboration message:

    $display output: MACRO_0 or MACRO_1 must be set for compilation
    ...
    Information: Building the design 'DEFINE_MACRO0_OR_MACRO1'. (HDL-193)
    Warning: Cannot find the design 'DEFINE_MACRO0_OR_MACRO1' in the library 'WORK'. (LBR-1)
    Warning: Unable to resolve reference 'DEFINE_MACRO0_OR_MACRO1' in 'TEST'. (LINK-5)
    0