首页 文章

创建一个通用数组,其元素的宽度在VHDL中增加

提问于
浏览
2

是否可以创建一个元素的宽度增加的数组 . 例如,假设X是一个包含10个元素的数组;

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

2 回答

  • 2

    不,VHDL数组中的所有元素都是相同的,因此如果元素是 std_logic_vector ,则具有相同的宽度(长度) .

    但是在综合中,如果你声明具有最大所需长度的元素,然后只是不使用某些元素的高位,那么任何合适的综合工具都会减少实现中的实际大小 .

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

  • 3

    根据您的要求,没有解决方案可以解决您的问题,但除了Morten的回答之外,我还会尝试提供另一种解决方案 .

    我将使用您的示例:X是一个包含10个元素的数组,每个元素的长度从4增加到13 .

    我的解决方案将所有向量放入一个1维向量中,并简化了对具有函数的位的访问 . 以下几行尝试介绍这些位的组织方式 .

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

    • 创建INTEGER(T_INTVEC)的向量或更多约束NATURALs(T_NATVEC)的向量 .
    type T_NATVEC is array (NATURAL range <>) of NATURAL;
    
    • 创建此类型的实例并使用数组长度填充它 .
    constant MY_BITS : T_NATVEC := (
      0 => 4,
      1 => 5,
      [...]
      9 => 13
    );
    

    或者使用函数来计算它:

    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;
    
    • 创建一些辅助函数:

    • 求和所有矢量长度

    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;
    
    • 获取嵌入向量的上限
    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;
    
    • 获取嵌入向量的下限
    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;
    
    • 获取整个嵌入向量
    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;
    
    • 将子矢量分配给大矢量
    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;
    
    • 所以现在你可以使用这个函数创建一个这样的1维向量:
    signal Vector_1 : STD_LOGIC_VECTOR(isum(MY_BITS) - 1 downto 0)  := (others => 'Z');
    -- initialize this vector with 'Z'; this is needed for simulation!
    
    • 您可以使用具有高和低功能的向量或使用forlast辅助函数(请参阅函数 getSubvector ) .
    signal Vector_X3 : STD_LOGIC_VECTOR(MY_BITS(3) - 1 downto 0);
    ...
    Vector_X3 <= getSubvector(My_Vector, MY_BITS, 3);
    
    • 最后,您可以使用 assignSubVector 将向量分配给大的向量:
    signal Vector_X4 : STD_LOGIC_VECTOR(MY_BITS(4) - 1 downto 0);
    ...
    assignSubvector(My_Vector, Vector_X4, MY_BITS, 4);
    

    如果你发现有趣的向量和矩阵的这些位移动和扭曲函数,这里是complete file :) .

相关问题