1

I know that in Verilog a matrix can not be passed to the ports, so i am wondering how could i turn matrix into array.

Consider the code:

input [7:0] matrix1 [0:3][0:3];

The code is valid in systemverilog, but not in Verilog 2005 standard.

Anyone got any ideas how to do this? I need it to be synthesizable.

  • 1
    Are you sure your synthesis tool can't handle system verilog syntax? Mine does and I have used 2D arrays in silicon (that worked and is being sold to customers). You might just need to add the `-sv` switch when you read the design into the synthesis tool. – nguthrie Sep 24 '18 at 17:58
  • @nguthrie What tool do you use? – Aleksandar Kostovic Sep 24 '18 at 17:59
  • Cadence Genus. Since verilog 2005 is 13 years old I would hope that by this time many other tools would support some of the SV syntax, but I don't know for sure since I just use this one. – nguthrie Sep 24 '18 at 18:04
  • @nguthrie i also find the support of systemverilog (outside of verification) to be quite surprising - in a bad way. I will use systemverilog for the sake of simplicity. Altho i am super interested to see answers on how it can be done in verilog. – Aleksandar Kostovic Sep 24 '18 at 18:11

1 Answers1

1

You got choices.

Break it up into a smaller ports:

module top();
// ...
example dut(
  .matrix1_0_0(matrix1[0][0]),
  .matrix1_0_1(matrix1[0][1]),
  // ...
  .matrix1_3_2(matrix1[3][2]),
  .matrix1_3_3(matrix1[3][3]),
  // ... other ports ...
);
//  ...
endmodule

module example(
  input [7:0] matrix1_0_0,
  input [7:0] matrix1_0_1,
  // ...
  input [7:0] matrix1_3_2,
  input [7:0] matrix1_3_3,
  // ... other ports ...
  );
wire [7:0] matrix1 [0:3][0:3];
assign matrix1[0][0] = matrix1_0_0;
// ...
assign matrix1[3][3] = matrix1_3_3;
// ... other logic
endmodule

Merge into a single bus then split it back to a matrix using +: or -: (see part-select addressing):

module top();
// ...
integer i,j;
reg [8*4*4-1:0] matrix1_bus;
always @* begin
  for(i = 0; i<4; i=i+1) begin
    for(j = 0; j<4; j=j+1) begin
      matrix1_bus[ 8*( 4*i + j) +: 8] = matrix1[i][j];
    end
  end
end
example dut(
  .matrix1_bus(matrix1_bus),
  // ... other ports ...
);
//  ...
endmodule

module example(
  input [8*4*4-1:0] matrix1_bus,
  // ... other ports ...
  );
integer i,j;
reg [7:0] matrix1 [0:3][0:3];
always @* begin
  for(i = 0; i<4; i=i+1) begin
    for(j = 0; j<4; j=j+1) begin
      matrix1[i][j] = matrix1_bus[ 8*( 4*i + j) +: 8];
    end
  end
end
// ... other logic
endmodule

Or mix/match combination of two approaches.

For a small matrix it doesn't matter which approaches you use. For a very larger matrix, then the specific synthesizer tool, version, and synthesis constraints may start becoming factors on which strategy to use.

Greg
  • 18,111
  • 5
  • 46
  • 68