I'm currently doing some verification in systemverilog and my team is currently using some macros to display messages in the transcript.

here's one of the macros I have:

`define MSG_ERR(TEXT) begin $write("** Error: %9.3f%2s %16s ", `GET_TIME, `GET_UNITS, c_MODULE); $error($sformatf TEXT); end 

so it's basically calling some system functions.

My question is: Is there any advantage to use macros instead of functions ?

Thanks in advance

2 Answers

Macros in verilog are just text substitution mechanism, similar to c/c++ macros. As such, macros can be "instantiated" in any part of the code, provided that its contents will be legal there.

In addition, as in c/c++ verilog macros have some capabilities of merging and stringizing its arguments, building variable names, strings and other.

There are a few disadvantages of the macros:

  1. they cannot be scoped. All macros exist in the global (compilation unit) scope and are affected by the order of compilation.

  2. there is absolutely no compiler checking for macro definitions available (except for arguments). Sometimes it is very difficult to figure out a compilation message related to macros, in particular to nested macros.

  3. some debugging tools have trouble debugging code inside macro definitions.

functions on the other hand provide you with more control over the contents and allow compiler doing a better job with checking. Debugging tools will also be happy.

You can define a function within a scope (module, package, ...), efficiently encapsulating it into a name space.

But,

  1. you can only use the function in places where it can be used.

  2. you cannot do any text-substitution tricks with the function arguments and in many cases one needs to write more code to instantiate a function.

My suggestion is to use functions (or tasks) as much as possible. In some cases you can use modules. Go macros only if there is no way to use a function/task/module or if you follow some methodology, based on macros.

In Verilog, there was no global space to put definitions except for the macro space. So that's what people used. Since SystemVerilog introduced the global package space, there is no longer an advantage.