2

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?

Chris Fernandez
  • 1,316
  • 14
  • 32

1 Answers1

4

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

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