The text I am reading (Stuart Sutherland's text on SystemVerilog for Simulation and Synthesis) gives the following snippet which apparently should be used in order to avoid including the same package multiple times in the same compilation:
I am a bit confused about the preprocessor statement:
`define DEFINITIONS_PKG_ALREADY_COMPILED
as, from other languages, I was expecting to see something more like:
`define DEFINITIONS_PKG_ALREADY_COMPILED 1
in order to actually "set" the flag. Is this an error in the text or just a shortcut based on the preprocessing inferring a true flag here?
2 Answers 2
It is not an error in the text. SystemVerilog allows you to simply use a macro name without setting it to a value. The macro will not have a specific value; you should just consider it as being "true" when checking it with conditional macros like `ifdef
.
Consider the following code:
module tb;
`define FOO
`ifdef FOO
initial $display("FOO is defined");
`else
initial $display("FOO is not defined");
`endif
endmodule
If you run it as-is, you get the output:
FOO is defined
If you delete the `define
line, you get the output:
FOO is not defined
Refer to IEEE Std 1800-2017, section 22.6 `ifdef, `else, `elsif, `endif , `ifndef
for other code examples.
Unfortunately, the Std does not explicitly state that the macro_text
can be omitted (aside from the code examples).
-
\$\begingroup\$ Thanks very much! After following the links in your bio I just signed up for EDA Playground to check this out (very helpful, thank you!) and can see that this is true. I poked around the LRM you mentioned (Section 22-5 specifically) but still can't see exactly where this behavior for `define is explained. I guess it's a default that omitting the "macro_text" field here just gives us a 1? \$\endgroup\$EE18– EE182024年01月19日 15:39:39 +00:00Commented Jan 19, 2024 at 15:39
-
\$\begingroup\$ @EE18: You're welcome. Yes, the playground is so helpful. I updated my answer to address your other points. \$\endgroup\$toolic– toolic2024年01月19日 15:48:03 +00:00Commented Jan 19, 2024 at 15:48
-
\$\begingroup\$ Thought I was missing something so thank you for confirming the standard doesn't explicitly confirm this usage :) thanks once again for all your help here! \$\endgroup\$EE18– EE182024年01月19日 15:52:55 +00:00Commented Jan 19, 2024 at 15:52
-
\$\begingroup\$ @EE18: It took a bit of staring myself! \$\endgroup\$toolic– toolic2024年01月19日 15:55:11 +00:00Commented Jan 19, 2024 at 15:55
-
\$\begingroup\$ FWIW, C behaves the same way -- after
#define X
, code between#ifdef X
and#endif
is compiled. Defining the value to1
is customary because it also allows#if X
to work. \$\endgroup\$Simon Richter– Simon Richter2024年01月19日 15:56:47 +00:00Commented Jan 19, 2024 at 15:56
The current 1800-2017 section 22.6 specifies `ifdef
to work based on the existence of macro definition
When an
`ifdef
is encountered, the`ifdef
text_macro_identifier is tested to see whether it is defined as a text macro name using`define
within the SystemVerilog source description.
It does not look at the value of the definition, just its existence. The 1800-2023 LRM has an enhancement to create a Boolean expression of a combination of existences , like
`ifdef (example_def0 && example_def1)
but that still does not look at the contents of the definitions, just their existence.
The LRM says that a newline character not preceded by a backslash shall end the macro text. There's nothing that says the macros text must contain at least one character. Perhaps it should call that "empty" text as it does for macro arguments.
BTW, these compiler guards around packages aren't necessary like they are in C/C++ if you have properly set up your compilation scripts. They are useful around other `define
files which are global to the compilation unit.
-
\$\begingroup\$ You read my mind (see my concurrent comment above!) and certainly made it a lot clearer to me, thank you so much. I've already accepted the other answer but really appreciate this as well :) \$\endgroup\$EE18– EE182024年01月19日 16:14:58 +00:00Commented Jan 19, 2024 at 16:14
-
\$\begingroup\$ @ee18 it is possible to change your accepted answer to the one that answers your question most succinctly, or at least give it an upvote \$\endgroup\$dave_59– dave_592024年01月19日 16:18:14 +00:00Commented Jan 19, 2024 at 16:18
-
\$\begingroup\$ @dave_59 have all the major vendors implemented
ifdef (example_def0 && example_def1)
? 1800-2023 LRM is not officially released yet, it is an "Approved Draft" right now. \$\endgroup\$Greg– Greg2024年01月19日 23:45:15 +00:00Commented Jan 19, 2024 at 23:45 -
\$\begingroup\$ @Greg, I don't know the answer to your first question. The official public release of 1800-2023 is scheduled for mid-March 2024 \$\endgroup\$dave_59– dave_592024年01月20日 00:59:52 +00:00Commented Jan 20, 2024 at 0:59