2-D dynamic array of parameters failed

Hi all,

I was trying to have some parameters in design. I put them in a 2-D dynamic array. But my code could not compile

parameter int STATE_ARRAY [2] [] = '{'{30, 100}, {24,155}};

The error message was: “Unsupported element datatype for array parameter”.

So, I tried different approaches to making the code run

  1. set it to a regular array, not a parameter one.
int STATE_ARRAY [2] [] = '{'{30, 100}, {24,155}};
  1. change it to a fixed size array.
parameter int STATE_ARRAY [2] [2] = '{'{30, 100}, {24,155}};
  1. Flatten it into 2 1D dynamic arrays.
parameter int STATE_ARRAY_1 [] = '{30, 100};
parameter int STATE_ARRAY_2 [] = '{24,155};

All of them work. Forget about why I’m so obsessed with the 2D dynamic array, can someone explain to me why instantiation of a 2D dynamic array of parameters does not compile, please? Thanks.

In reply to amy992:

Parameters are evaluated at elaboration time.The elaboration time flattens out the module/program hierarchy, propagates the appropriate parameter overrides and resolves hierarchical references to different modules.

So, a parameter must not be dynamically allocated array. It should be elaboration time constant variable or array. There should not be any overriding of parameter after elaboration time. Note that the elaboration time is not the simulation time-0.

In order to pass varying sizes of parameters, you can add the dimensions of parameter array as another parameters. For example, you can add the ROWS and COLS parameters which defined the number of elements in the STATE_ARRAY:

module mymod #(
parameter int ROWS = 2,
parameter int COLS = 2,
parameter int STATE_ARRAY [ROWS] [COLS] = '{'{30, 100}, {24,155}}) (/*some ports*/);
//...

module top();
  // Override the ROWS parameter
  mymod #(.ROWS(3), .COLS(2), .STATE_ARRAY('{'{30, 100}, {24,155}, {1,2}})) m();
endmodule

// Output:
ROWS= 3 COLS=2
STATE_ARRAY[0][0] = 30
STATE_ARRAY[0][1] = 100
STATE_ARRAY[1][0] = 24
STATE_ARRAY[1][1] = 155
STATE_ARRAY[2][0] = 1
STATE_ARRAY[2][1] = 2

module tio();
  mymod m();
endmodule

// Output:
ROWS= 2 COLS=2
STATE_ARRAY[0][0] = 30
STATE_ARRAY[0][1] = 100
STATE_ARRAY[1][0] = 24
STATE_ARRAY[1][1] = 155

This post can be useful about passing array of parameters to a module.

In reply to amy992:

Your code compiles fine on Questa. And parameters whose type are one dimensional dynamic arrays compile fine in all other implementations. Whenever you see an “unsupported” message, it means the tool recognizes valid syntax, but has not implementing it yet.

You can have parameters whose types are dynamic, but you will never be able to change the size of an array or construct a class variable.

In reply to dave_59:

In reply to amy992:
Your code compiles fine on Questa. And parameters whose type are one dimensional dynamic arrays compile fine in all other implementations. Whenever you see an “unsupported” message, it means the tool recognizes valid syntax, but has not implementing it yet.
You can have parameters whose types are dynamic, but you will never be able to change the size of an array or construct a class variable.

I was using NCVerilog, and apparently the version I was using doesn’t support it at this moment. I tried Questa, and it worked. Thanks.

In reply to sharvil111:

In reply to amy992:
Parameters are evaluated at elaboration time.The elaboration time flattens out the module/program hierarchy, propagates the appropriate parameter overrides and resolves hierarchical references to different modules.
So, a parameter must not be dynamically allocated array. It should be elaboration time constant variable or array. There should not be any overriding of parameter after elaboration time. Note that the elaboration time is not the simulation time-0.
In order to pass varying sizes of parameters, you can add the dimensions of parameter array as another parameters. For example, you can add the ROWS and COLS parameters which defined the number of elements in the STATE_ARRAY:

module mymod #(
parameter int ROWS = 2,
parameter int COLS = 2,
parameter int STATE_ARRAY [ROWS] [COLS] = '{'{30, 100}, {24,155}}) (/*some ports*/);
//...
module top();
// Override the ROWS parameter
mymod #(.ROWS(3), .COLS(2), .STATE_ARRAY('{'{30, 100}, {24,155}, {1,2}})) m();
endmodule
// Output:
ROWS= 3 COLS=2
STATE_ARRAY[0][0] = 30
STATE_ARRAY[0][1] = 100
STATE_ARRAY[1][0] = 24
STATE_ARRAY[1][1] = 155
STATE_ARRAY[2][0] = 1
STATE_ARRAY[2][1] = 2
module tio();
mymod m();
endmodule
// Output:
ROWS= 2 COLS=2
STATE_ARRAY[0][0] = 30
STATE_ARRAY[0][1] = 100
STATE_ARRAY[1][0] = 24
STATE_ARRAY[1][1] = 155

This post can be useful about passing array of parameters to a module.

Thanks. This helps me deepen my understanding of passing parameters.