5

I want to create this generic wrapper for a bunch of modules I am writing. The wrapper should provide the ability to connect these modules to different type of NoCs without having to change the behavior of the inner modules.

I thought that one way to do this would be the following. Considering a very simple module to wrap:

module add #(                                                                                                                       
             parameter COLUMN_WIDTH     = 32                                                                                        
             )

   (
    //data in                                                                                                                       
    input logic [COLUMN_WIDTH-1:0]  col_1,
    input logic [COLUMN_WIDTH-1:0]  col_2,
    //data out                                                                                                                      
    output logic [COLUMN_WIDTH-1:0] col_o

    );

   assign col_o = col_1 + col_2;

endmodule

The wrapper should be the following:

module wrapper #(                                                                                                                   
                 parameter COLUMN_WIDTH     = 32,                                                                                   
                 parameter WRAPPED_MODULE   = add                                                                                   
             )
   (
    //data in                                                                                                                       
    input logic [COLUMN_WIDTH-1:0]  col_1,
    input logic [COLUMN_WIDTH-1:0]  col_2,
    //data out                                                                                                                      
    output logic [COLUMN_WIDTH-1:0] col_o,
    /* std signals */
    input logic                     clk,
    input logic                     reset_i // reset everything                                                                     
    );

   logic [COLUMN_WIDTH-1:0]         max_result;

   WRAPPED_MODULE #(.COLUMN_WDITH(COLUMN_WIDTH),
                    ) a(
                        .*
                        );

   always @(posedge clk) begin
      if (reset_i)
        max_result <= 0;
      else
        max_result <= (col_o > max_result) ? col_o : max_result;
   end

endmodule

The error I get is the following:

Error-[IND] Identifier not declared
wrapper.sv, 4
  Identifier 'add' has not been declared yet. If this error is not expected, 
  please check if you have set `default_nettype to none.

Which makes sense since a parameter is not the same as a macro. A complete design should possibly instantiate a bunch of wrapped modules and I don't want to duplicate code by creating a wrapper for each inner module. How can I do that?

igon
  • 3,016
  • 1
  • 22
  • 37

2 Answers2

5

A parameter cannot be a module name. It can be a data_type, implicit data_type, or type

IEEE Std 1800-2012 § A.2.1.1 Module parameter declarations:

parameter_declaration ::=
    parameter data_type_or_implicit list_of_param_assignments
  | parameter type list_of_type_assignments

A workaround is to use a generate block and compare the value of the parameter.

module wrapper #(
    parameter        COLUMN_WIDTH     = 32,
    parameter string WRAPPED_MODULE   = "add"
  )
  (
    // ...
  );
  // ...
  generate
    if (WRAPPED_MODULE=="add") begin
      add #(.COLUMN_WDITH(COLUMN_WIDTH) ) a( .* );
    end
    else begin
     // ...
    end
  endgenerate
  // ...
endmodule
Greg
  • 18,111
  • 5
  • 46
  • 68
  • Nice workaround! Would that be synthesizable though? – igon Apr 10 '15 at 21:48
  • Should be. You will need to try it, not all synthesizers are the same. If it doesn't like `string` you might want to try with your own `enum` or just index it. – Greg Apr 10 '15 at 21:51
  • I tried something like this and can confirm that Cadence RTL compiler does NOT like the string parameter. I changed to an enum and all is well. – nguthrie Jun 30 '15 at 14:47
0

If you're using Vivado and SystemVerilog (only tested on 2017.4, likely would work on later versions too), I've been able to use something like parameter type WRAPPED_MODULE = add and it will synthesize as well.

dworvos
  • 166
  • 1
  • 4