Creating a generic array whose elements have increasing width in VHDL

后端 未结 2 1060
情深已故
情深已故 2020-12-21 12:37

Is it possible to create an array whose elements have increasing width. For example lets say X is an array that has 10 elements;

X(0) is std_logic_vector(3 downto 0)

2条回答
  •  [愿得一人]
    2020-12-21 12:48

    There is no solution to solve your question, as you requested, but additionally to Morten's answer I'll try to provide another work around solutions.

    I'll use your example: X is an array of 10 elements each with increasing length from 4 to 13.

    My solution puts all the vectors into one 1-dimensional vector and eases the access to the bits with functions. The following lines try to present how the bits are organized.

    --bit 84              bit 19      bit 13       bit 8       bit 4       bit 0
    [X(9)(12..0)]...[X(4)(7..0)][X(3)(6..0)][X(2)(5..0)][X(1)(4..0)][X(0)(3..0)]
    

    Step-by-Step:

    1. Create a vector of INTEGERs(T_INTVEC) or more constrained a vector of NATURALs (T_NATVEC).

      type T_NATVEC is array (NATURAL range <>) of NATURAL;
      
    2. Create a instance of this type and fill it with your array lengths.

      constant MY_BITS : T_NATVEC := (
        0 => 4,
        1 => 5,
        [...]
        9 => 13
      );
      

      Or use a function to calculate it:

      function generateVectorLengths return T_NATVEC is
        constant Count        : NATURAL              := 10;
        constant Startlength  : NATURAL              := 4;
        variable Result : T_NATVEC(0 to Count - 1);
      begin
        for i in 0 to Count - 1 loop
          Result(i) := StartLength + i;
        end loop;
        return Result;
      end function;
      
      constant MY_BITS : T_NATVEC := generateVectorLengths;
      
    3. Create some helper function to:

      • sum all vector lengths

        function isum(vec : T_NATVEC) return NATURAL is
          variable Result : NATURAL := 0;
        begin
          for i in vec'range loop
            Result := Result + vec(i);
          end loop;
          return Result;
        end function;
        
      • get the upper bound of an embedded vector

        function low(VectorBits : T_POSVEC; index : NATURAL) return NATURAL is
          variable pos : NATURAL := 0;
        begin
          for i in VectorBits'low to index - 1 loop
            pos := pos + VectorBits(i);
          end loop;
          return pos;
        end function;
        
      • get the lower bound of an embedded vector

        function high(VectorBits : T_POSVEC; index : NATURAL) return NATURAL is
          variable pos : NATURAL := 0;
        begin
          for i in lenvec'low to index loop
            pos := pos + VectorBits(i);
          end loop;
          return pos - 1;
        end function;
        
      • get an entire embedded vector

        function getSubvector(vector : STD_LOGIC_VECTOR; VectorBits : T_POSVEC; index : NATURAL) return STD_LOGIC_VECTOR is
        begin
          return vector(high(VectorBit, index) downto low(VectorBit, index));
        end function;
        
      • assign a sub vector to the big vector

         procedure assignSubVector(signal slm : out T_SLM; slv : STD_LOGIC_VECTOR; constant VectorBits : T_POSVEC; constant index : NATURAL) is
         begin
            for i in slv'range loop
              slm(high(VectorBit, index) downto low(VectorBit, index)) <= slv;
            end loop;
         end procedure;
        
    4. So now you can use this functions to create an 1-dimensional vector like this:

      signal Vector_1 : STD_LOGIC_VECTOR(isum(MY_BITS) - 1 downto 0)  := (others => 'Z');
      -- initialize this vector with 'Z'; this is needed for simulation!
      
    5. And you can use this vector with high and low function or with the forlast helper function (see function getSubvector).

      signal Vector_X3 : STD_LOGIC_VECTOR(MY_BITS(3) - 1 downto 0);
      ...
      Vector_X3 <= getSubvector(My_Vector, MY_BITS, 3);
      
    6. Finally, you can use assignSubVector to assign vectors to the big one:

      signal Vector_X4 : STD_LOGIC_VECTOR(MY_BITS(4) - 1 downto 0);
      ...
      assignSubvector(My_Vector, Vector_X4, MY_BITS, 4);
      

    If you find these bit moving and twisting function for vectors and matrixes interesting, here is the complete file :).

提交回复
热议问题