How to pass a variable value to a macro in SystemVerilog?

macros, system-verilog

Solution

The preprocessor directives are evaluated by the preprocessor and modify the code that is presented to the compiler.

The for loop is a verilog construct that is evaluated by the compiler.

So your preprocessor is not evaluating the for loop. It sees:

`define `set_value(bit) abc_``bit``_def = 4'b0000

[some verilog]
   `set_value(i);
[some verilog]

So 'i' is just i. It doesn't become a number until compilation.

Why don't you use local params with generate, so the local params are created in a loop at elaboration as the for loop is unrolled?

This is one of the many places that macros are a problem. Generate is a problem in other places (like when you want to control port lists).

I dug into this a bit more. Parameters and local parameters inside a generate are created a localparams in the scope of the generate. See here: System Verilog parameters in generate block. I had to get back to work before I could test it.

I would just use code and populate an array. This compiles in VCS:

module veritest  
    #(  
    parameter   MAX_X = 5,  
                MAX_Y = 3,  
                MAX_Z = 2  
    )  
    (); // empty port list  

logic [4:0] abc_def[1:MAX_X][1:MAX_Y][1:MAX_Z];  

always @*  
begin  
for (integer z=1; z<(MAX_X+1);z=z+1)  
   for (integer y=1; y<(MAX_Y+1);y=y+1)  
       for (integer x=1; x<(MAX_X+1);x=x+1)  
       begin  
            abc_def[x][y][z] = 4'b0000;  
       end  
end  
endmodule  

Problem

I think the question sums it up pretty well as to what I want: passing the value of a variable to a macro in SystemVerilog. For example, what I want: Say, there are 4 signals by the name of abc_X_def and I want to initialize all of them to 0. So, without macros: ``` abc_0_def = 4'b0000; abc_1_def = 4'b0000; abc_2_def = 4'b0000; abc_3_def = 4'b0000; ``` Now, the code that I have written is having a problem: ``` `define set_value(bit) abc_``bit``_def = 4'b0000 for (int i = 0; i < 4; i++) begin `set_value(i); end ``` The error is that it's trying to find the signal abc_i_def which is obviously wrong. Just wondering if it's possible to pass the actual value of the variable 'i' to the macro.

Original source