SystemVerilog: `define gotchas

It is very common to use macros using `define in Verilog and SystemVerilog. While this may be an easy way to define some commonly used values, there are some potential pitfalls.  Here are some examples to illustrate some things to watch out for when`defines.

Example 1: Here is an example where a macro is used to define the width of a bus.

`define BUS_WIDTH 16

module m ( input logic [`BUS_WIDTH-1:0] i, output logic [`BUS_WIDTH-1:0] o);
logic [`BUS_WIDTH-1:0] internal_bus;
// some code
endmodule

Example 2: This example uses more macros with expressions. See how the macro causes the expression to expand in an unexpected way!

`define BUS_WIDTH 16
`define MIN_LEVEL 5
`define MAX_LEVEL 10
`define RANGE `MAX_LEVEL - `MIN_LEVEL

module m ( input logic [`BUS_WIDTH-1:0] i, output logic [`BUS_WIDTH-1:0] o);
logic [`BUS_WIDTH-1:0] internal_bus;
const int twice_range = `RANGE * 2; // Danger!!
// The RHS results in 10 - 5 * 2 = 0 (probably not intended!!)
endmodule

Since the macro RANGE is processed by the preprocessor and not evaluated, it is replaced with the expression 10 – 5, because the preprocessor does simple string substitution. This results in the RSH to be evaluated as shown in the comment.

Example 3: This example shows a safe way to create expressions with macros, using parentheses.

`define BUS_WIDTH 16
`define MIN_LEVEL 5
`define MAX_LEVEL 10
`define RANGE (`MAX_LEVEL - `MIN_LEVEL) // using parentheses

module m ( input logic [`BUS_WIDTH-1:0] i, output logic [`BUS_WIDTH-1:0] o);
logic [`BUS_WIDTH-1:0] internal_bus;
const int twice_range = `RANGE * 2; // Safe!
// The RHS results in (10 - 5) * 2 = 10 (probably what was expected)
endmodule

In this example, the macro is still processed by the preprocessor, and it replaces RANGE with (10 – 5) including the parentheses as defined in the macro. The parentheses makes this usage safe.

So any expressions in macros must be enclosed by parentheses to make them safe.

Author: editor

Leave a Reply

Your email address will not be published. Required fields are marked *