Arrays 在VHDL中创建元素宽度不断增加的通用数组

Arrays 在VHDL中创建元素宽度不断增加的通用数组,arrays,generics,vhdl,Arrays,Generics,Vhdl,是否可以创建元素宽度不断增加的数组。例如,假设X是一个包含10个元素的数组 X(0)是标准逻辑向量(3到0) X(1)是标准逻辑向量(4到0) … X(9)是标准逻辑向量(12到0)否,VHDL数组中的所有元素都是相同的,因此如果元素是标准逻辑向量,则具有相同的宽度(长度) 但是在合成中,如果您声明具有所需最大长度的元素,然后简单地不在某些元素上使用高位,那么任何合适的合成工具都会减少实现中的实际大小 如果您的问题仅与模拟相关,那么您可以声明一组访问类型(指针)到std\u logic\u ve

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

X(0)是标准逻辑向量(3到0)
X(1)是标准逻辑向量(4到0)


X(9)是标准逻辑向量(12到0)

否,VHDL数组中的所有元素都是相同的,因此如果元素是
标准逻辑向量
,则具有相同的宽度(长度)

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


如果您的问题仅与模拟相关,那么您可以声明一组访问类型(指针)到
std\u logic\u vector
,然后指向的
std\u logic\u vector
可以具有不同的长度。

按照您的要求,没有解决问题的方法,但除了Morten的回答之外,我将尝试提供另一种解决方案

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

我的解决方案将所有向量放入一个一维向量中,并通过函数简化对位的访问。以下几行试图展示位是如何组织的

--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)]
一步一步:

  • 创建一个整数向量(T_INTVEC)或一个更受约束的自然向量(T_NATVEC)

    或者使用函数计算它:

    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;
      
    • 获取嵌入向量的下界

      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;
      
    • 得到一个完整的嵌入向量

      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;
      
    • 您可以将此向量与high和low函数或forlast helper函数一起使用(请参见函数
      getSubvector


    • 如果你觉得这些向量和矩阵的位移动和扭曲函数很有趣,这里是:)。

      是的,我知道这个选项。但我不喜欢“你从未使用过我为你修剪的信号”类型的警告。我的意思是,如果有一个解决方案可以用过程或类似的东西来实现它。过程/函数对你没有帮助-最终,你需要一个信号/任何东西来分配你的数据,并且没有办法拥有一个二维数组,其中一个维度在数组中变化。很好的框架,但是,一个人必须携带相当多的额外重量。您的解决方案会导致合成出现问题吗?还有更多:)我们正在github上开发一个版本。这些功能在模拟、合成以及不同的工具链(quartus、xst、vivado、questasim、ghdl)中都经过了全面测试。所有功能都只是接线说明。是的,你有一个很好的通用软件包。这就是我的意思。但我将实现一些由1或2个函数组成的特殊形式。