创建一个泛型数组,其元素在VHDL中增加宽度

时间:2021-09-22 15:42:54

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是一个有10个元素的数组;

X(0) is std_logic_vector(3 downto 0)
X(1) is std_logic_vector(4 downto 0)
...
X(9) is std_logic_vector(12 downto 0)

X(0)为std_logic_vector(3向下至0)X(1)为std_logic_vector(4向下至0)…X(9)为std_logic_vector(12向下至0)

2 个解决方案

#1


3  

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.

正如你所要求的那样,没有解决问题的办法,但在Morten的回答中,我会试着提供另一个解决方案。

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

我将使用您的示例:X是10个元素的数组,每个元素的长度从4到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).

    创建一个整数向量(T_INTVEC),或者更严格地约束一个自然数向量(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).

    你可以用这个向量来表示高函数和低函数,或者用forlast助手函数(参见函数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:

    最后,可以使用assignSubVector将向量分配给大向量:

    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 :).

如果你觉得这些矢量和矩阵的位移动和扭曲函数有趣,这里有完整的文件:)。

#2


2  

No, all elements in an VHDL array are the same, thus will have same width (length) if the elements are std_logic_vector.

不,VHDL数组中的所有元素都是相同的,因此如果元素是std_logic_vector,那么它们的宽度(长度)也是相同的。

But in synthesis, if you declare the elements with maximum required length, and then simply don't use the upper bits on some of the elements, then any decent synthesis tool will reduce the actual size in the implementation.

但是在合成中,如果您声明了所需的最大长度的元素,然后简单地不使用某些元素的上位,那么任何合适的合成工具都会减少实现中的实际大小。

If your question is related to simulation only, then you can declare an array of access types (pointers) to std_logic_vector, and the std_logic_vectors pointed to can then have different length.

如果您的问题仅与模拟相关,那么您可以向std_logic_vector声明一个访问类型(指针)数组,然后指向的std_logic_vectors的长度就会不同。

#1


3  

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.

正如你所要求的那样,没有解决问题的办法,但在Morten的回答中,我会试着提供另一个解决方案。

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

我将使用您的示例:X是10个元素的数组,每个元素的长度从4到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).

    创建一个整数向量(T_INTVEC),或者更严格地约束一个自然数向量(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).

    你可以用这个向量来表示高函数和低函数,或者用forlast助手函数(参见函数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:

    最后,可以使用assignSubVector将向量分配给大向量:

    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 :).

如果你觉得这些矢量和矩阵的位移动和扭曲函数有趣,这里有完整的文件:)。

#2


2  

No, all elements in an VHDL array are the same, thus will have same width (length) if the elements are std_logic_vector.

不,VHDL数组中的所有元素都是相同的,因此如果元素是std_logic_vector,那么它们的宽度(长度)也是相同的。

But in synthesis, if you declare the elements with maximum required length, and then simply don't use the upper bits on some of the elements, then any decent synthesis tool will reduce the actual size in the implementation.

但是在合成中,如果您声明了所需的最大长度的元素,然后简单地不使用某些元素的上位,那么任何合适的合成工具都会减少实现中的实际大小。

If your question is related to simulation only, then you can declare an array of access types (pointers) to std_logic_vector, and the std_logic_vectors pointed to can then have different length.

如果您的问题仅与模拟相关,那么您可以向std_logic_vector声明一个访问类型(指针)数组,然后指向的std_logic_vectors的长度就会不同。