VHDL:是否可以同时移动数组元素?
VHDL: Is it possible to concurrently shift array elements?
出于学习目的,我想创建自己的插入排序实现。
正如您现在可能看到的那样,其中一个步骤需要将数组元素向右移动 1。这里的主要困难在于此操作的范围必须是动态的。
所以如果 sort_reg 是从 0 到 array_length 的数组,我需要实现 sort_reg(n)<=sort_reg(n-1), sort_reg(n-1)<=sort_reg(n-2) ... sort_reg(n-i+1)<=sort_reg(n-i); (n-m)>=i>=1,其中 m 范围的起始数组索引,将从范围(m 到 n-1)到(m+1 到 n)右移 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循环来写了。
EDIT:在每个迭代步骤中,if
语句可用于检查是否应实际移动元素。信号 n
和 m
的类型应为 unsigned
(首选),或范围为 0 到 SIZE-1 的 integer
。
编辑 2:示例更改为评论中指出的旋转。
-- 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;
这个怎么样;
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 中 &
用作串联运算符。它将两个 vector/arrays 连接在一起形成一个 vector/array.
以上示例仅移动 1 项。如果你想移动 M
,你可以使用这样的东西;
sort_reg <= sort_reg(M to sort_reg'high) & sort_reg(0 to M-1);
请注意,如果您想移动一个信号(而不是将其分配给其他信号),您应该按照 所述的过程进行。
出于学习目的,我想创建自己的插入排序实现。 正如您现在可能看到的那样,其中一个步骤需要将数组元素向右移动 1。这里的主要困难在于此操作的范围必须是动态的。
所以如果 sort_reg 是从 0 到 array_length 的数组,我需要实现 sort_reg(n)<=sort_reg(n-1), sort_reg(n-1)<=sort_reg(n-2) ... sort_reg(n-i+1)<=sort_reg(n-i); (n-m)>=i>=1,其中 m 范围的起始数组索引,将从范围(m 到 n-1)到(m+1 到 n)右移 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循环来写了。
EDIT:在每个迭代步骤中,if
语句可用于检查是否应实际移动元素。信号 n
和 m
的类型应为 unsigned
(首选),或范围为 0 到 SIZE-1 的 integer
。
编辑 2:示例更改为评论中指出的旋转。
-- 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;
这个怎么样;
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 中 &
用作串联运算符。它将两个 vector/arrays 连接在一起形成一个 vector/array.
以上示例仅移动 1 项。如果你想移动 M
,你可以使用这样的东西;
sort_reg <= sort_reg(M to sort_reg'high) & sort_reg(0 to M-1);
请注意,如果您想移动一个信号(而不是将其分配给其他信号),您应该按照