0

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

v1(1) = '1'、v1(2) = '0'、v1(3) = '1' 等。

请帮助我提供一些可以创建 v2 的编码示例。

4

3 回答 3

0

我们过去也遇到过类似的问题。我们找到的最佳解决方案是对 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"

由于此解决方案基于移位寄存器,因此很容易以时钟方式实现并根据需要一次处理一个元素,甚至可以流水线化整个过程。

于 2013-09-05T21:10:07.747 回答
0

就像是:

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;
于 2013-09-04T14:09:12.520 回答
0

可以使用此函数生成 v2,其中 v1 为 std_logic_vector(8 - 1 downto 0):

library ieee;
use ieee.numeric_std.all;
...
function v1_to_v2(v1 : std_logic_vector) return std_logic_vector is
  variable v2_v   : std_logic_vector(4 * v1'length - 1 downto 0);
  variable ones_v : natural;
begin
  ones_v := 0;
  v2_v := (others => '0');
  for idx in 0 to v1'left loop
    if v1(idx) = '1' then
      v2_v(4 * ones_v + 3 downto 4 * ones_v) := std_logic_vector(to_unsigned(idx, 4));
      ones_v := ones_v + 1;
    end if;
  end loop;
  return v2_v;
end function;

当 v1 和 v2 上有触发器时,该函数可以在 Altera Cyclone IV E (EP4CE6E22A7) FPGA 中关闭约 220 MHz 的时序。

这是否是一个可接受的解决方案取决于您尝试解决的详细问题。

此外,当 v1 =“00000000”时,您为 v2 选择的格式不会像“00000001”一样导致 v2 = X“00000000”。这可能没问题,具体取决于问题的详细信息。

于 2013-09-04T14:09:46.220 回答