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

I think the question summarizes it pretty well what I want: passing the value of the variable to a macro in SystemVerilog.

For example, what I want: Let's say there are 4 signals named abc_X_def, and I want to initialize them all 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 I wrote has 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 is trying to find the abc_i_def signal, which is obviously erroneous. Just wondering if the actual value of the variable "i" can be passed to the macro.

+4
source share
2 answers

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 computed by the compiler.

So your preprocessor does not evaluate the for loop. He sees:

 `define `set_value(bit) abc_``bit``_def = 4'b0000 [some verilog] `set_value(i); [some verilog] 

So, ā€œiā€ is just i. It does not become a number until compilation.

Why don't you use the local parameters to generate, so local parameters are created in a loop during development when the for loop is expanded?

This is one of many places where macros are a problem. Generate the problem elsewhere (for example, when you want to manage port lists).


I dig into it a little more. Parameters and local parameters inside the generation are created by local parameters in the generation area. See Here: Verilog System Parameters in Block Generation . I had to get back to work before I could test it.

I would just use the code and populate the 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 
+3
source

Since you said that naming conventions got out of hand, you should consider using another tool to create verilog for you.

You may have the code generated by your preferred programming, then use the `include statement in your verilog file. Or you can go with a built-in route.

The concept is the same, just the difference in the built-in language and the tool used for conversion.

+1
source

Source: https://habr.com/ru/post/1494863/


All Articles