# How do I calculate constant values across several modules at compile time in Verilog?

I have a Verilog module that uses three instances of the same low-level module, called 'pole'. The instances are identical, except for a constant offset value, which is provided by the top level. There are other constant values within 'pole' as well.

Here's a rough pseudo-code concept: (please forgive any syntax typos, I'm just trying to illustrate the idea)

module toplevel{
localparam offset0 = 0;
localparam offset120 = 120;
localparam offset240 = 240;

pole myPole0(offset0, variable);
pole myPole120(offset120, variable);
pole myPole240(offset240, variable);
}

module pole{
input offset;
input variable;

localparam x = 1;
localparam y = 2;
localparam z = 3;
localparam transitionConst = x + y + z + offset;
reg transitionPoint = transitionConst + variable;
}


'variable' is dynamically updated during operation, but is consistent across each instance of pole. 'offset' is statically set at compile time, but there is a different offset value for each pole.

I want to calculate the total of the constant values (transitionConst) for reg transitionPoint at compile time. How do I do this?

I tried using a localparam as shown above, but this gives me compilation errors at the 'pole' level because offset is not a constant. Obviously, I know that I will be providing offset as a different constant for each instance of pole, but the compiler doesn't know that. Is there an easy way to add constants across multiple modules at compile time?

## 1 Answer

With variable as an input, the compiler can't assign a constant value to transitionConst, as you've discovered.

You should declare your module like this, and then override the OFFSET parameter as a parameter to each invocation of the module. localparam variables may not be overriden, but parameter can be as shown. You can also supply a default value to the parameter, so you don't need to override it if it's not necessary. I chose variable to be 32 bits wide, but that's arbitrary*.

module pole #(parameter OFFSET = 0) (input logic [31:0] variable);
localparam x = 1;
localparam y = 1;
localparam z = 1;

localparam transitionConst = x + y + z + OFFSET;
reg [31:0] transitionPoint = transitionConst + variable;
endmodule : pole


You can then invoke this in your top module like this:

module toplevel();
localparam offset0 = 0;
localparam offset120 = 120;
localparam offset240 = 240;

logic [31:0] variable;

pole mypole0(.variable(variable));  // no need to use offset0
pole #(.OFFSET(offset120)) mypole120(.variable(variable));
pole #(.OFFSET(offset240)) mypole240(.variable(variable));
endmodule : toplevel


*: As declared, the localparams will be 32 bits wide

• Not my favorite site, but it does illustrate the concept of how to use parameters fairly well (searched: "verilog parameters"). asic-world.com/verilog/para_modules1.html – CapnJJ Feb 19 at 17:17
• @CapnJJ Should've added an example of the invocation. Will do that :) – awjlogan Feb 19 at 17:18