# parameters and defines in verilog

Status
Not open for further replies.

#### harpv

##### Member level 4
I’ve been trying to run a simulation for the following sample code.

Requirement: Based on parameters generate a define which will be used further in the design.

Observation : I can make this work if the defines are not used in the port definitions and only in the Behavioral code.

Code Verilog - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module #( parameter PARAM_A_PRESENT = 0) dummy (
ifdef A_present
input A,
endif
input B,

output C,
output D
);

generate begin
if(PARAM_A_PRESENT == 1) begin
define A_present
end
end
endgenerate

/* ---- Behavioral code -------- */
always @ (*) begin

ifdef A_present
assign wire_lgi = A;
\$display("This works! ");
endif

end
/* -------------------------------   */
endmodule

Below is the TB where I've instantiated the module and passed the parameter.

Code Verilog - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module tb;

define A_PRESENT 1

dummy #(.PARAM_A_PRESENT(A_PRESENT)) dut (
.A(A),
.B(B),
.C(C),
.D(D)
);

/* Signal declaration */
/* test stimulus */

endmodule

I have a feeling this could be something the language doesn't really support. But I would like to understand what exactly is happening here.

I know the parameter comes into picture only during the elaboration phase. So since the define was not there in the compile phase it wouldn't have created the port for the dut. But in that case how would have the code worked? Still confused about this.

Any help is appreciated.

Thanks.

#### FvM

##### Super Moderator
Staff member
I don't believe that this works. define statement are read by a preprocessor which is unaware of generate statements.
Code:
generate begin
if(PARAM_A_PRESENT == 1) begin
define A_present
end
end
endgenerate

#### dave_59

##### Advanced Member level 3
But in that case how would have the code worked? Still confused about this.

<on soap-box>
There is a big problem with engineers when they say something "works", not just in hardware engineering, but in all aspects of engineering. True verification requires an understanding of the range of possible situations and their limits.

You only created one simple testcase where PARAM_A_PRESENT was set to 1, and only one instance of the dummy module. But the idea you are trying to explore is reusing the same code for different varying situations.

How could you have possible tested this theory with only one variation?

Had you tried define A_PRESENT 0 in your testbench, or had two instances of dummy with different parameter overrides, you would have discovered that the define A_PRESENT inside the generate happens unconditionally regardless of what the generate condition evaluates to.
<off soap-box>

The reason for this is that Verilog macros are pre-processed and expanded into text before any other Verilog syntax parsing. You can effectively think of macro processing as a separate tool that executes before being fed into the Verilog compiler. That means there is only one text declaration of a module. Then the Verilog parsing begins. And there is another step called elaboration. This is where the parameter overrides of each instance create unique definitions of module executing the generate blocks within them. Verilog has severe limits on what can be parameterized on an instance by instance basis and, unfortunately, changing the number of ports is one of those restrictions.

What you can do is make a port an array and change the size of the array as a parameter. This can work if the ports you want to add are all the same type. SystemVerilog adds the ability to parameterize types, which can be structures, and also has an interface construct that effectively puts the port declarations into a separate entity.

Points: 2

Points: 2

### harpv

Points: 2

##### Super Moderator
Staff member
The reason for this is that Verilog macros are pre-processed and expanded into text before any other Verilog syntax parsing. You can effectively think of macro processing as a separate tool that executes before being fed into the Verilog compiler. That means there is only one text declaration of a module. Then the Verilog parsing begins. And there is another step called elaboration. This is where the parameter overrides of each instance create unique definitions of module executing the generate blocks within them. Verilog has severe limits on what can be parameterized on an instance by instance basis and, unfortunately, changing the number of ports is one of those restrictions.
Eloquently stated, I avoided answering as my explanation would have probably left the OP even more confused. ;-)

What you can do is make a port an array and change the size of the array as a parameter. This can work if the ports you want to add are all the same type.
You aren't referring to a 2D array in the port are you? Last I checked the last Verilog-only standard 2005 didn't support 2D arrays in ports. i.e. input [15:0] some_input_name [0:NUM_INPUTS-1];. I'm not fully versed on SV so I can't say if it's supported there, I just know the tools I use definitely don't support it (I check when new versions of the tools appear).

Status
Not open for further replies.