Vector 在VHDL中创建以其他向量的索引作为元素的向量

Vector 在VHDL中创建以其他向量的索引作为元素的向量,vector,indexing,vhdl,Vector,Indexing,Vhdl,我有一个像这样的标准逻辑向量作为输入:v1=“10001010”,我想创建另一个像这样的向量:v2=X“00000731”,其中X“7”、X“3”和X“1”表示第一个向量(v1)的索引,其中值为“1” v1(1)='1',v1(2)='0',v1(3)='1',等等 请帮我介绍一些可以创建v2的编码示例。类似于: variable base : natural := 0; .... v2 <= (others => '0'); for i in v1'right to v1'left

我有一个像这样的标准逻辑向量作为输入:v1=“10001010”,我想创建另一个像这样的向量:v2=X“00000731”,其中X“7”、X“3”和X“1”表示第一个向量(v1)的索引,其中值为“1”

v1(1)='1',v1(2)='0',v1(3)='1',等等

请帮我介绍一些可以创建v2的编码示例。

类似于:

variable base : natural := 0;
....
v2 <= (others => '0');
for i in v1'right to v1'left loop
  if v1(i) = '1' then
    v2(base+3 downto base) = to_unsigned(i,4);
    base := base + 4;
  end if;
end for;
变量基:自然:=0;
....
v2‘0’;
对于v1'右至v1'左循环中的i
如果v1(i)=“1”,则
v2(基数+3向下至基数)=至_无符号(i,4);
基数:=基数+4;
如果结束;
结束于;

v2可以通过此函数生成,v1作为标准逻辑向量(8-1向下至0):

该功能可在Altera Cyclone IV E中以~220 MHz的频率关闭定时 (EP4CE6E22A7)FPGA,当v1和v2上有触发器时

这是否是一个可接受的解决方案取决于您遇到的具体问题 我们正在努力解决这个问题

此外,并非您为v2选择的格式将导致v2= 当v1=“00000000”表示“00000001”时,为X“00000000”。这可能没问题,视情况而定
关于问题细节。

我们过去也遇到过类似的问题。我们找到的最佳解决方案是对v2使用移位寄存器:循环v1的元素,每当在v1中找到“1”时,就在循环索引中移位

这里有一个函数可以满足您的需要:

  type output_type is array (7 downto 0) of unsigned(2 downto 0);

  function find_ones(v1: std_logic_vector(7 downto 0)) return output_type is
    variable v2: output_type := (others => "000");
  begin
    for i in v1'range loop
      if v1(i) = '1' then
        v2 := v2(6 downto 0) & to_unsigned(i, 3);
      end if;
    end loop;
    return v2;
  end;  

  -- results:
  --   find_ones("00000000") --> "000_000_000_000_000_000_000_000"
  --   find_ones("11111111") --> "111_110_101_100_011_010_001_000"
  --   find_ones("10001010") --> "000_000_000_000_000_111_011_001"
由于此解决方案基于移位寄存器,因此很容易以时钟方式实现,如果需要,可以一次处理一个元素,甚至可以通过管道处理整个过程

  type output_type is array (7 downto 0) of unsigned(2 downto 0);

  function find_ones(v1: std_logic_vector(7 downto 0)) return output_type is
    variable v2: output_type := (others => "000");
  begin
    for i in v1'range loop
      if v1(i) = '1' then
        v2 := v2(6 downto 0) & to_unsigned(i, 3);
      end if;
    end loop;
    return v2;
  end;  

  -- results:
  --   find_ones("00000000") --> "000_000_000_000_000_000_000_000"
  --   find_ones("11111111") --> "111_110_101_100_011_010_001_000"
  --   find_ones("10001010") --> "000_000_000_000_000_111_011_001"