Parameterized Macro Definition

What is a macro ?

A macro is a literal name used in a program that is substituted by some value before the program is compiled. Macros are useful as an alias without using program resources. They are not variables, so you can not assign a value to a macro from within a program. Almost all modern languages, including Verilog, support macro definition.

Macros in Verilog

Macros in Verilog are specified by using `define compiler directive. Here is an example:

`define MY_DELAY  2
r1 = #`MY_DELAY 1'b1;

What is Parameterized Macro Definition ?

Parameterized macro definition (PMD) is something new in Verilog LRM2.0, although it has been there in other languages like C from the beginning. In a PMD, the definition of a macro contains zero or more parameters. An example of a PMD is shown below.

`define MAX(p,q) (p)>(q)?(p):(q)
r1 = #`MAX(setup_delay, rise_delay) 1'b1;
After preprocessing, the actual program that is passed to the compiler looks like:
r1 = #((setup_delay)>(rise_delay)?(setup_delay):(rise_delay)) 1'b1;
Note that the substitutions are literal. And, in the macro definition each term must be parenthesized.

My simulator does not support Parameterized Macro Definition. What can I do?

First off, do not worry. You are not alone. Most of the simulators do not support this. The sole purpose of this page is to provide you with a freeware which converts this new construct to one which a regular simulator can understand.

I wrote this preprocessor program as a part of a global conversion program between LRM2.0 to LRM1.0. This was presented in International Verilog Conference (IVC) in 1996. However, this program is a stripped off version of the main program without error checking etc.While the original program was written in C, to make it easier to install, I have used standard UNIX/C utility programs, such as nawk and m4. Install GNU gawk and m4 if you do not have these utilities.

How to download ?

Here is the all important file. This is a shell script. Save it as pmd.csh (or any other name) in a separate directory.
nawk ' \
# Detect multiline comments
/\/\*/ { ml_comment = 1 }
/\*\// { ml_comment = 0 }
# Create a new verilog file 
# without the macro definition
# and an m4 definition file

      if (($1 == "`define") && (ml_comment == 0) && (match($2,"[(]"))) {
         # find out the macro name
         paren_start = match($2, "[(]")
         macro_name = substr($2, 1, paren_start-1)
         # argument list
         arg_list = substr($2, paren_start+1, length($2)-1-paren_start)
         # remove white spaces from the argument list
         gsub("\t","", arg_list)
         gsub(" ","", arg_list)
         # store all the parameters in an array
         n_arg = split(arg_list, arg_array, ",")
         # now print the m4 definition

         printf "define("macro_name"," > "_m4"
         #find out the position of $3
         start_defn = index($0, $3)
         defn = substr($0, start_defn, length($0)-1-paren_start)
         for (i=1; i<=n_arg; i++) {
            initial_val = "\("arg_array[i]"\)"
            final_val = "\$"i
            gsub(initial_val, final_val, defn)
         print defn")" > "_m4"
         macro_name_array[j++] = macro_name;
      else { 
         for (k=0;k<j;k++) gsub("\`"macro_name_array[k],macro_name_array[k])
         print $0
}' $1 > _v

m4 _m4 _v

How to run it ?

%pmd.csh test1.v

There are two temporary files created by the program. They are called _m4 and _v. So do not use these two file names. The output appears on the standard output.

The program can easily be modified to have more than one Verilog file in the command line: 

%pmd test1.v test2.v ...


Here is a sample Verilog program that uses PMD. 

/* This is an example of parameterized macro definition. 
   This file goes to the input of the preprocesor.  */

`define MIN(a,b) (a)<(b)?(a):(b)
`define SQR(m) (m)*(m)

module myModule ;
integer s, s1, s2, bo ;

initial begin
   s1 = 1 ;
   s2 = 2 ;
   s = `MIN(s2,s1) ; // This is a comment
   bo = `SQR(s2);
   s = `MIN(s2,s1) + SQR(s2);
   s = `SQR(`MIN(s2,s1)) ;

 Here is the output of the  preprocessor:

/* This is an example of parameterized macro definition. 
   This file goes to the input of the preprocesor.  */

module myModule ;
integer s, s1, s2, bo ;

initial begin
   s1 = 1 ;
   s2 = 2 ;
   s = (s2)<(s1)?(s2):(s1) ; // This is a comment
   bo = (s2)*(s2);
   s = (s2)<(s1)?(s2):(s1) + (s2)*(s2);
   s = ((s2)<(s1)?(s2):(s1))*((s2)<(s1)?(s2):(s1)) ;

Note that the PMD definitions do not appear in the output. Share/Save/Bookmark

Verification Management
Join Verification Management Group

Book of the Month

From Our Press