Search code examples
arraysmatrixvhdl

Fill one row in 2D array outside the process (VHDL)


I have array:

type MATR is array(natural range 1 to N, natural range 1 to N) of natural;
signal m: MATR;

1) Is it possible to fill elements m(0, 1), m(0, 2) ... m(0, N) with some value outside of process? Something like:

m(1) <= (others => 2)

2) Is it possible assign 1D array(range 1 to N) to one row of 2D array (Also outside of process)?


Solution

  • Yes you can do this by writing a procedure like this one:

    procedure assign_row(signal slm : out T_SLM; slv : STD_LOGIC_VECTOR; constant RowIndex : NATURAL) is
      variable temp : STD_LOGIC_VECTOR(slm'high(2) downto slm'low(2));  -- Xilinx iSIM work-around, because 'range(2) evaluates to 'range(1); tested with ISE XST/iSim 14.2
    begin
      temp := slv;
      for i in temp'range loop
        slm(RowIndex, i)  <= temp(i);
      end loop;
    end procedure;
    

    Where T_SLM is my matrix type defined like this:

    -- STD_LOGIC_MATRIXs
    type T_SLM is array(NATURAL range <>, NATURAL range <>) of STD_LOGIC;
    -- ATTENTION:
    -- 1. you MUST initialize your matrix signal with 'Z' to get correct simulation results (iSim, vSim, ghdl/gtkwave)
    --    Example: signal myMatrix : T_SLM(3 downto 0, 7 downto 0) := (others => (others => 'Z'));
    -- 2. Xilinx iSIM work-around: DON'T use myMatrix'range(n) for n >= 2
    --    because: myMatrix'range(2) returns always myMatrix'range(1); tested with ISE/iSim 14.2
    -- USAGE NOTES:
    --  dimension 1 => rows     - e.g. Words
    --  dimension 2 => columns  - e.g. Bits/Bytes in a word
    

    So here is an example to use this procedure:

    architecture [...]
      signal myVector : STD_LOGIC_VECTOR(7 downto 0);
      signal myMatrix : T_SLM(3 downto 0, myVector'range) := (others => (others => 'Z'));
      [...]
    begin
      [...]
      assign_row(myMatrix, myVector, 0);
      assign_row(myMatrix, (myVector'range => '0'), 1);
      assign_row(myMatrix, x"4A", 2);
      [...]
    end;
    

    This code is tested with ISE XST and iSim (13.x, 14.x), vSim and GHDL. As ISE 13.x was the current release, Xilinx stated that the range-bug will not be fixed in ISE 14.x.

    If you need the other way around, here is my function get_row:

    -- get a matrix row
    function get_row(slm : T_SLM; RowIndex : NATURAL) return STD_LOGIC_VECTOR is
      variable slv : STD_LOGIC_VECTOR(slm'high(2) downto slm'low(2));       -- Xilinx iSim work-around, because 'range(2) = 'range(1); tested with ISE/iSim 14.2
    begin
      for i in slv'range loop
        slv(i)  := slm(RowIndex, i);
      end loop;
      return slv;
    end function;
    

    If you want to use NATURAL as the elementary type for the vectors and matrices, then exchange STD_LOGIC with NATURAL.