parameters and `defines in verilog

Status
Not open for further replies.

harpv

Member level 4
Joined
May 30, 2012
Messages
73
Helped
19
Reputation
38
Reaction score
20
Trophy points
1,288
Activity points
1,838
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.
 

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
 

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.
 
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.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…