Search code examples
veriloghdl

Input matrix in verilog


I want to input a n*m (n and m are defined) matrix in verilog (where each element is of 32 bit length), but the compiler gives an error. Is there any direct way to do so? I don't want to write n*m separate input elements.

This is what I tried: input reg [31:0] matrix [0:9][0:12]

Anything wrong here?


Solution

  • Verilog doesn't support passing multi-dimensional arrays through ports. The feature was added in SystemVerilog.

    In EDAplayground, ModelSim runs with SystemVerilog enabled. Even if you remove the -sv command option SystemVerilog will still be enabled because the testbench and design have .sv file extensions. SystemVerilog Can be disabled in ModelSim with the -vlog01compat compile option. Adding this options to Morgan's Example will generate the following error: (or run here)

    ** Warning: (vlog-2644) Conflicting semantics, "-vlog01compat" switch disables SystemVerilog support.
    -- Compiling module dut
    ** Error: design.sv(4): 'Port' must not be declared to be an array: matrix.
    -- Compiling module tb
    ** Error: testbench.sv(6): (vlog-2110) Illegal reference to memory "data".
    ** Error: testbench.sv(6): (vlog-2110) Illegal reference to memory "data".
    ** Warning: testbench.sv(18): (vlog-2644) Conflicting semantics, "-vlog01compat" switch disables SystemVerilog support.

    To pass the matrix you need to enable SystemVerilog or pack the matrix into a 1-Dimenion array.

    • To enable SystemVerilog, it is recommenced you change your file extension from .v to .sv, Modern simulator will enable SystemVerilog on only this files. Alternatively you could enable the compiler option (most tools it is -sv) to force enable SystemVerilog on all Verilog files. The main problem with force enabling is a Verilog variable name may no conflict with a SystemVerilog keyword.
    • To translate the matrix to a simple array:

      parameter DWIDTH=32, XWIDTH=10, YWIDTH=13;
      reg [DWIDTH-1:0] matrix [0:XWIDTH-1][0:YWIDTH-1];
      reg [DWIDTH*XWIDTH*YWIDTH-1:0] flat;
      integer x,y;
      always @* begin
         for (x=0; x<XWIDTH; x=x+1)
           for (y=0; y<YWIDTH; y=y+1)
             flat[(x*XWIDTH+y)*DWIDTH +: DWIDTH] = matrix[x][y];
      end
      
      reg [DWIDTH-1:0] matrix_rebuild [0:XWIDTH-1][0:YWIDTH-1];
      integer xr,yr;
      always @* begin
         for (xr=0; xr<XWIDTH; xr=xr+1)
           for (yr=0; yr<YWIDTH; yr=yr+1)
             matrix_rebuild[xr][yr] = flat[(xr*XWIDTH+yr)*DWIDTH +: DWIDTH];
      end