Search code examples
veriloghdluser-defined-typespreprocessor-directive

For loop in `define Macro


I searched on SO, and on web, no where found the ans. I have following code, where It success fully parsed `define and generate expected results, but if number of times calling of macro is large then, Can we using Looping Construct?.

`define myreg(name) \
   addr_``name    

`define para(i) \
  parameter `myreg(i) = i  

module register;

`para(1);
`para(2);
`para(3);
`para(4);

initial
begin
  $display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
  $display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
  #100 $finish;
end
endmodule

Simulation Result:

// # Loading work.register(fast)
// # run -all
// # ADDR1 =           1, ADDR2 =           2
// # ADDR3 =           3, ADDR4 =           4
// # ** Note: $finish    : reg.v(18)

Now, when I use for loop, like in below code,

`define myreg(name) \
   addr_``name    

`define para(i) \
  parameter `myreg(i) = i  

module register;

genvar i;
generate 
  for (i = 1; i<=4; i=i+1)
  begin
    `para(i);
  end
endgenerate

initial
begin
  $display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
  $display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
  #100 $finish;
end
endmodule

In that case, It shows an error while displaying or using it, Simulation Result:

// # vsim -lib work register -c -do "run -all; quit -f" -appendlog -l qverilog.log -vopt 
// # ** Note: (vsim-3813) Design is being optimized due to module recompilation...
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_1' in hierarchical name '/addr_1'.
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_2' in hierarchical name '/addr_2'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_3' in hierarchical name '/addr_3'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_4' in hierarchical name '/addr_4'.
// # Optimization failed
// # Error loading design

It is asked more times but proper solution is not given by any one, any help appreciated a lot.


Solution

  • The problem is actually much simpler than as sharvil111 explains.

    The directives `defines, `ifdefs and `includes all get handled by a preprocessor that produces a stream of text and is fed into a compiler. The preprocessor does not know anything about Verilog syntax and the compiler does not see any of those directives because they have been processed away.

    You can actually see this intermediate stream of text by adding the vlog -E <filename> option which writes the output of the preprocessor to

    There is no looping directive in Verilog/SystemVerilog. Some options for you are:

    • write the macros out by hand. Perhaps you can find some function in your text editor to help you do this
    • use some other macro preprocessor to generate your code. This can make debugging difficult as you have to manage two sets of source code files.
    • Restructure your code to use an array instead of having separately named parameters