0

I have several verilog (not system-verilog) blocks where I want to generate them depending on other parameters. As an example:

module some_module (in, out)

realtime p = 3.5; // the parameter which I want to change

initial begin
if ('global_parameter == 1)
    p = 5.8;
if ('global_parameter == 2)
    p = 4.4;
end

core_module #(p) core (in, out);
endmodule

Here, "global_parameter" is defined in a header file but overridden at simulation time by using simulator parameters. And my core module uses "p" for delay value like in this example:

module core_module(in, out)

parameter p = 1;

always out <= #p in; // p should be constant

endmodule

Therefore, I'm hoping to have the core module with updated parameter "p". But this scenario is not simulate-able. Could you please recommend me a possible solid solution for this problem if possible?

Thank you

2
  • "not simulate-able" or not compiling? Commented Jun 3, 2015 at 20:14
  • Getting error during compiling, sorry for confusion Commented Jun 4, 2015 at 20:50

1 Answer 1

1

A parameter needs to be a parameter type throughout the design. You cannot pass a variable as a parameter.

You can use a generate block to control instantiation:

module core_module#(parameter realtime P=1)(input in, output out);
  always @(in) out <= #(P) in; // p should be constant
endmodule

module some_module (input in, output out);
  generate
    if (GLOBAL_PARAMETER == 1) begin : cfg_1
      core_module #(5.8) core (in, out);
    end
    else if (GLOBAL_PARAMETER == 2) begin : cfg_2
      core_module #(4.4) core (in, out);
    end
    else begin : cfg_dflt
      core_module #(3.5) core (in, out); // default
    end
  endgenerate
endmodule

You can also calculate the parameter in a single line:

module some_module (input in, output out);
  parameter P = (GLOBAL_PARAMETER == 1) ? 5.8 : (GLOBAL_PARAMETER == 2) ? 4.4 : 3.5;
  core_module #(P) core (in, out); // default
endmodule

Alternatively (since you can not synthesizing), you can have the delay value be a variable, then force the value through hierarchical reference. Example:

module core_module (input in, output out);
  realtime p = 1;
  always @(in) out <= #(p) in; // this p is a variable
endmodule

module some_module (input in, output out);
  realtime p = 3.5;
  core_module core (in, out);
  initial begin
    if (GLOBAL_PARAMETER == 1)
      p = 5.8;
    else if (GLOBAL_PARAMETER == 2)
      p = 4.4;
    force core.p = p; // force hierarchical variable assignment
  end
endmodule

Note: all example are compatible with IEEE Std 1364-2001 and IEEE Std 1364-2005, utilizing ANSI header style and generate blocks. These features do not exist in IEEE Std 1364-1995


I'm not aware of any clean Verilog only solutions. You can try embed code (such as Perl's EP3, Ruby's eRuby/ruby_it, Python's prepro, etc.) As I mention in another answer to a somewhat similar question, here. A challenge with embedded is the need to be pre-compiled/processed, making them more like `define then parameters.

If SystemVerilog is an option, you can do the following: (Refer to IEEE Std 1800-2012 § 6.20 Constants; example near the end of § 6.20.2)

module some_module (input in, output out);
  parameter realtime P [3] = '{3.5, 5.8, 4.4};
  core_module #(P[GLOBAL_PARAMETER]) core (in, out);
endmodule
Sign up to request clarification or add additional context in comments.

1 Comment

Ty for your answer Greg, I have already tried with generate blocks which seems to be good but too many blocks are generated in this way. Do you know if there can be any other alternative?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.