【问题标题】:VHDL: Is it possible to concurrently shift array elements?VHDL:是否可以同时移动数组元素?
【发布时间】:2015-11-26 19:37:53
【问题描述】:

出于学习目的,我想创建自己的插入排序实现。 正如您现在可能看到的,其中一个步骤需要将数组元素向右移动 1。这里的主要困难是此操作的范围必须是动态的。

所以如果 sort_reg 是从 0 到 array_length 的数组,我需要实现 sort_reg(n)=i>=1,其中 m 范围的起始数组索引,从范围 (m 到 n-1) 到 (m+1 到 n) 将右移 1。

问题是是否有可能一步完成,然后怎么做?

【问题讨论】:

  • 请说明哪个范围必须是动态的,nm 或两者兼而有之?
  • 是的,我可能不够清楚,两者都需要是动态的。 m 是被移动成员的目标索引。这就是插入排序的工作原理:找到小于当前位置 m 的第一个成员 n 并在 m (n>m )。对于从 mn-1 的鱼群范围,必须将其移动到 m+1n。还忘了提到必须在 Xilinx Vivado 下为 Zynq 设备合成
  • 知道了。我扩展了我的例子。它与 Quartus-II 合成,但我无法检查它是否适用于 Vivado。

标签: arrays vhdl insertion-sort


【解决方案1】:

是的,一步即可。您必须将元素存储在寄存器中,然后在同一上升沿为所有数组元素分配新值。

让我们用两个std_logic 类型的信号a 和b 做一个简单的例子。然后这个过程会在clock的上升沿交换两个元素:

process(clock)
begin
  if rising_edge(clock) then
    a <= b;
    b <= a;
  end if;
end process;

这是可行的,因为信号会在处理完成后获得新的值。因此,在分配b 时,分配了a 的旧值(在时钟上升沿之前)。

让我们继续您的示例。 你没有指定一个特定的数组,所以我拿这个:

type array_type is array(0 to SIZE-1) of std_logic_vector(7 downto 0);
signal sort_reg : array_type;

然后可以使用 for 循环编写该过程。 编辑:在每个迭代步骤中,if 语句可用于检查元素是否应实际移动。信号nm 应该是unsigned 类型(首选),或integer 类型,范围为0 到SIZE-1。 编辑 2:示例更改为 cmets 中所示的旋转。

-- value to insert in case of rotation
value_to_insert <= sort_reg(to_integer(n)); -- to_integer required if type of 'n' is unsigned

process(clock)
begin
  if rising_edge(clock) then
    -- This loop is unrolled by the synthesis tool.
    for i in SIZE-1 downto 1 loop
      -- shift elements [n-1:m] to [n:m+1]
      if (i <= n) and (i >= m+1) then
        sort_reg(i) <= sort_reg(i-1);
      end if;

      -- insert new value
      if i = m then
        sort_reg(i) <= value_to_insert;
      end if;
    end loop;

    -- insert into position zero
    if m = 0 then
      sort_reg(0) <= value_to_insert;
    end if;
  end if;
end process;

【讨论】:

  • 不应该是if (i&lt;=n) and (i&gt;=m+1) 吗?
  • 我现在意识到,我可能可以通过解释我想旋转数组的动态范围来简化任务描述。 (其中移位是子操作)我实现了一个用于测试的模块,该模块将整数数组 m ,n 作为输入,并使用您建议的方法将范围 m 旋转到 n 。我模拟了 Vivado,看起来还不错谢谢!
  • @AndreyPro 你是对的,但这个if 条件仅适用于 cmets 中指定的范围。我现在已经接受了这个。但是,您最初的问题仍然使用另一个移位范围,即将元素 n-1 向下移动到 n-m 一个位置。请编辑您的问题以避免混淆。
  • 哦,我明白了。我在 2 种不同的意义上使用了 m 并使每个人都感到困惑:-/。对此感到抱歉。我会澄清
【解决方案2】:

这个怎么样;

sort_reg <= sort_reg(1 to sort_reg'high) & sort_reg(0);

我假设sort_reg 是一个定义为的信号;

signal sort_reg : some_array_type(0 to N);

在这种情况下,sort_reg'high 是一个等于 N 的属性。

在 vhdl 中,&amp; 用作连接运算符。它将两个向量/数组连接在一起形成一个向量/数组。

以上示例仅移动 1 个项目。如果你想通过M移动,你可以使用这样的东西;

sort_reg <= sort_reg(M to sort_reg'high) & sort_reg(0 to M-1);

请注意,如果您想转换一个信号(而不是将其分配给不同的信号),您应该按照Martin 所述的流程进行。

【讨论】:

  • 移位 1 没问题。我将在 FSM 中使用它,所以我可能会像 sort_reg_next(i-1) 那样分配它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
相关资源
最近更新 更多