Macro is a piece of code which enables text substitution everywhere the macro name is called. Systemverilog macro can also have argument like a function and it is actually very similar to macro in C which you may familiar with.
Systemverilog macro 101
Syntax
Rules to follow
Avoid using the macro name which is similar to any compiler directives.
No space after the backslash \ at the end of each line except for the last line of the macro.
No space between macro name and the open parentheses for macro argument (. (I actually had a painful experience with this rule).
Using macro argument
Only the ARG itself: replaced as normal
`` (double tick) + ARG : use the ARG to form a variable name, block name, signals, etc.
`” (a tick then double quotes): if ARG is put between these, the ARG will considered as a string, also `” will be parsed as doubled quotes “.
This argument can be used a with $psprintf() to form a string.
`\`” (a tick, a backslash, a tick then double quotes): to keep the escape sequence \” in the generated text.
You can run an example of these macros with argument here:
Local macro
There is no such thing as local macro, but we can define a macro right when we need to call it, then undef after use so we do not worry that it might be called by accident somewhere else.
Recommendation
If writing a function/task is possible, avoid writing macro =D.
Write all macros in one file, and include that file in your sv package. Since redefine macro is allowed, write macros everywhere in your codes make debugging these macros become painful.
Macro can call other macros or compiler directives, but be careful, should keep it simple.
When using argument, try to use default value (similar to default value in function/task).
Make sure your code run first, then turn it into a macro.
Debugging
Macro is annoying when it comes to debugging. When I need to write and debug a macro, I do this:
Open macro files in EDA tool, such as verdi, then hover the mouse over the macro to see the generated code.
Examples
Macro to create an assertion
Create a macro to define assertion with below requirements:
Assertion to compare SIGNAL value with EXP_VALUE.
Provide clock in CLK, enable/reset signal in ENA. ENA default is 0 (inactive).
Use EXT_ERROR_CMD to add additional statement when assertion fail, leave it blank if no use.
Macro for queue/array conversion
Note that these conversions below can be easily achieved by using Streaming operator .
My mistakes
Space between macro name and the open parentheses as below:
Using var i as index iterator inside macro, then call macro in another loop, which also use i as index iterator.
Finding more information
To have more understanding as well as more examples, you can check the IEEE Standard for SystemVerilog, chapter.22 Compilers directives.