Can I pass parameters down

I have a parameter passed into an interface. Within this interface I am doing a bind whilst passing that parameter in.

I get an error:

Error-[NCEI] Non-constant expression in parameter
bind_if.sv, 78
my_module, "param_path"
  The use of a non-constant expression to override a parameter value is 
  illegal.
  Please replace the offending expression by an elaboration-time constant.

The interface is:

interface mytop_bind_if import ...::*; 
#(
    string        param_path = "", ...
...
  bind my_module.bla.bla.bla my_bind_if
    #(
        .param_path(param_path),
...
endinterface

The my_bind_if looks like:

interface my_bind_if import ...::*; 
  #(
    string                  param_path                        ,


Can you please help me out?

In reply to ralphkak:

What is the definition of the bold .param_path(param_path)? As the error message says, it can only be a parameter, not a variable.

In reply to dave_59:

Hi Dave, as specified above, it is a string. Changing the string to parameter also yields the same error.

interface my_bind_if import …::*;
#(
string param_path ,

In reply to ralphkak:

It would help to provide a Short, Self Contained, Correct (Compilable), Example This works for me

interface bind_if #(string PATH) ();
   initial $display("%m %s",PATH);
endinterface
module target;
   parameter string path = "mypath";
   
endmodule : target

module top;
   target t();
   bind target:t bind_if #(.PATH(path)) bt();
endmodule : top

In reply to dave_59:

Dave, I know this is a bit old post, but Google popped it up, so I think others may run into this one as well.

What I have pulled out of the spec is that the bind does not “exist” in the scope of the code that you write it in, but is “bound” or “placed” in the scope of the bind_target_instance. Thus, when it goes to “find” the parameter, it will not see it. That was what the OP was running into.

It is like the statement is in 2 parts, the one that controls the bind “where” (type/instance etc) and the part for “what” (module/interface/program/checker) including identifier, parameters, and arguments.

Actually about to try this concept out to get around this error. Please do comment if my understanding seems correct.

In reply to DavidEllis:

Correct.

In reply to dave_59:

Dave, I have a coverage module using the parameter to declare the signals, the compilation failed by “The use of a non-constant expression to override a parameter value is illegal”. There are a few modules in our env using the parameter the way in your above example and have no issue, so not sure if the failure is due to the parameter used in the signal declaration. How to fix the error?

Here is the simplified code.


module module_cov #(int ENTRIES, int NUM) (
  input logic [ENTRIES-1:0] rd_q,
  input logic [ENTRIES-1:0] rd_buf [NUM-1:0]
  );
endmodule

module module_rtl #(parameter ENTRIES = 8, parameter NUM = 2) (
  input logic [ENTRIES-1:0] read_q,
  input logic [ENTRIES-1:0] read_buf [NUM-1:0]
  ); 
endmodule : module_rtl

module top;
  ...
  
  bind 'RTL_PATH module_cov #(.ENTRIES('RTL_PATH.ENTRIES), .NUM('RTL_PATH.NUM)) module_cov_inst (
    .rd_q   ('RTL_PATH.read_q),
    .rd_buf ('RTL_PATH.read_buf)
  );
endmodule : top

In reply to ella_sun:
bind:
‘literally places all code after the path, just before the endmodule line in the RTL’

Thus it has full access to the parameters, and ports, of the module that it is placed inside.

 bind 'RTL_PATH module_cov #(.ENTRIES(ENTRIES), .NUM(NUM)) module_cov_inst (
    .rd_q   (read_q),
    .rd_buf (read_buf)
  );

So see if that helps any.

Oh, and don’t use `define for any kind of ‘this is my path’. How are you going to do that for multiple instances of the same module? (In other words, it does not extend into the future when you will want to do something like this for a UVM RAL register path etc.
See the %m in this thread for some clues on how to get the path (You will have to edit it to remove that tail end for the bind’ed module instance – so use

 string path;
 path=$sformtf("%m");
  .....

and then use the factory (set_config) to pass into your verification class world…

In reply to DavidEllis:

Thanks David. The following code in EDA Playgroud works fine, but got same errors from our env with the similar changes:

Error-[NCEI] Non-constant expression in parameter
[path of bind file]
[RTL module name] [parameter name]
The use of a non-constant expression to override a parameter value is
illegal.
Please replace the offending expression by an elaboration-time constant.


module module_cov #(int ENTRIES, int NUM) (
  input logic [ENTRIES-1:0] rd_q,
  input logic [ENTRIES-1:0] rd_buf [NUM-1:0]
  );
  always_comb
    $display("In module_cov");
endmodule
 
module module_rtl #(parameter ENTRIES = 8, parameter NUM = 2) (
  input logic [ENTRIES-1:0] read_q,
  input logic [ENTRIES-1:0] read_buf [NUM-1:0]
  );
  always_comb
    $display("In module_rtl");
endmodule : module_rtl
 
module top;
  bind module_rtl module_cov #(.ENTRIES(ENTRIES), .NUM(NUM)) module_cov_inst ( // got errors pointing to this line in our env
    .rd_q   (read_q),
    .rd_buf (read_buf)
  );
  always_comb
    $display("In module_top");
endmodule : top

In reply to ella_sun:

Since it seems you are unable to show us the exact code in your environment, I suggest you remove all parameter overrides in your bind statement and try to recompile by adding one of them at a time. Perhaps you have a typo, or something else you have not considered.

In reply to dave_59:

There are a few configurations in our environment, some configurations can have different values of the parameters. In the initial coverage coding, all signals were declared using hard coded the largest values among all configurations. One configuration which using the largest values passed the compilation, but others failed.

E.g.


module module_cov (
  input logic [31:0] rd_q,         // hard coded
  input logic [31:0] rd_buf [1:0]  // hard coded
  );
  always_comb
    $display("In module_cov");
endmodule
 
module module_rtl #(parameter ENTRIES = 8, parameter NUM = 2) (
  input logic [ENTRIES-1:0] read_q,
  input logic [ENTRIES-1:0] read_buf [NUM-1:0]
  );
  always_comb
    $display("In module_rtl");
endmodule : module_rtl
 
module top;
  bind module_rtl module_cov module_cov_inst
    .rd_q   (read_q),
    .rd_buf (read_buf)
  );
  always_comb
    $display("In module_top");
endmodule : top

In a small configuration, the compilation failed by 3 types of error:

  1. Error-[PCWM-L] Port connection width mismatch
    The following 28-bit expression is connected to 32-bit port
    “rd_q” of module “module_cov”, instance
    “module_cov_inst”.
    Expression:
    module_rtl.read_q
    The expression is from module module_rtl, instance module_rtl

  2. Error-[NYI] Not Yet Implemented
    Feature is not yet supported: Incompatible packed dimensions of unpacked
    array elements in port expressions
    Source info:
    (* ATTR_PARTCOMP_BIND_APPLIED = “1” *)

    Expression:
    module_rtl.read_buf
    Port : logic [31:0] rd_buf [1:0]

  3. Error-[PCTM] Port connection type mismatch
    The following expression is illegally connected to port “rd_buf” of
    module “module_cov”, instance
    “module_cov_inst”. The type of the port does not match that
    of the port connect.
    Expression:
    module_rtl.read_buf
    Port : logic [31:0] rd_buf [1:0]
    Declared at:
    “… printed the file path …”

When thinking to add waivers in our env, the compilation failed by 2 errors:

Error-[BMII] Bad message id
Message id ‘NYI’ specified after ‘-error’, ignored.

Error-[BMII] Bad message id
Message id ‘PCTM’ specified after ‘-error’, ignored.

If the errors can’t be waived, will have to find a solution to fix the bind issue.