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.
$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
$fatal
is also an elaboration task added in IEEE Std 1800-2009 in section 20.10. See IEEE Std 1800-2012 § 20.11 Elaboration system tasks. It can be used inside an generate block. The follow should work if the simulator is *09+ complaint.
...
`else
//inferred generate block
if (0) $fatal(1,"MACRO_0 or MACRO_1 must be set for compilation");
`endif
I tried it out on edaplaygrond but it looks like ModelSim10.1d does not support it. In the mean time, like others have suggested, you can do the following:
...
`else
CAUSE_ELAB_ERR fatal("MACRO_0 or MACRO_1 must be set for compilation");
`endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With