2
\$\begingroup\$

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?

\$\endgroup\$
3
\$\begingroup\$

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

\$\endgroup\$
  • 2
    \$\begingroup\$ 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 \$\endgroup\$ – CapnJJ Feb 19 at 17:17
  • 2
    \$\begingroup\$ @CapnJJ Should've added an example of the invocation. Will do that :) \$\endgroup\$ – awjlogan Feb 19 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.