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

和自甴很熟 提交于 2019-12-20 01:09:50

问题


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.


回答1:


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  



回答2:


Since you said the naming conventions is out of your control, you should consider using another tool to generate the verilog for you.

You can have the code generated by your preferred programming then use an `include statement in your verilog file. Or you can go with an embedded route.

  • Perl had EP3 : http://search.cpan.org/~gspivey/Text-EP3-Verilog-1.00/Verilog.pm
  • Ruby has eRuby : http://www.tutorialspoint.com/ruby/eruby.htm
  • I'm sure something like it exists for other languages to. Such as Python, Tcl, JavaScript, etc.

Concept is the same, just a difference in embedded language and tool used for conversion.



来源:https://stackoverflow.com/questions/18007162/how-to-pass-a-variable-value-to-a-macro-in-systemverilog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!