在给定一组数据作为输入的情况下,任何人都可以帮我编写用于冒泡排序的VHDL代码吗?
我已将in_array声明为包含15个数组元素的输入。我想按降序对它们进行冒泡排序。
in_array
是输入数组。
sorted_array
已输出数组。
in_array_sig
是in_array类型的信号
我在进程内部的语句面临问题
以下是我的代码:
architecture behav of Bubblesort is
signal in_array_sig : bubble;
signal temp : std_logic_vector(3 downto 0);
signal i : integer := 0;
begin
in_array_sig <= in_array;
proc1 : process(clk, reset)
begin
if reset = '0' then
if (clk'event and clk = '1') then
while (i <= 15) loop
if (in_array_sig(i) < in_array_sig(i + 1)) then
temp <= in_array_sig(i);
in_array_sig(i) <= in_array_sig(i + 1);
in_array_sig(i + 1) <= temp;
end if;
i <= i + 1;
end loop;
end if;
end if;
end process;
sorted_array <= in_array_sig;
end behav;
我是VHDL编码的初学者。请帮助我。
答案 0 :(得分:1)
缺少Minimal Complete and Verifiable example使得很难提供关于所有阻止代码准确排除代码的事情的答案。这些可以按照您遇到的故障排除顺序进行描述。
proc1 : process(clk, reset)
begin
if reset = '0' then
if (clk'event and clk = '1') then
while (i <= 15) loop
if (in_array_sig(i) < in_array_sig(i + 1)) then
temp <= in_array_sig(i);
in_array_sig(i) <= in_array_sig(i + 1);
in_array_sig(i + 1) <= temp;
end if;
i <= i + 1;
end loop;
end if;
end if;
end process;
开始注意时钟是通过复位门控的。您可以通过重置来限定分配,使其成为启用。
<强>问题强>
我们发现生产MCVe和测试平台的第一件事是该过程永远不会中止。这是由while循环中的条件引起的,这取决于i和i在过程中更新的信号。我不应该在这里成为一个信号(或者你可以在这里使用for循环)。
这也指出temp是一个信号并且遇到同样的问题,你不能使用&#39; new&#39; temp的值,直到进程暂停和恢复为止。信号被安排更新,没有包含after子句的波形元素的信号分配具有带零延迟的隐式后子句。在计划恢复的任何进程尚未恢复并随后暂停时,不会发生信号更新。这允许在顺序语句中找到分配信号的并发性(并发语句具有包含等效顺序语句的等效过程)。因此,i和temp都不能在执行语句的进程序列期间更新,并且两者都想成为变量。
我们也会使用in_array_sig的信号进行咬合。当你递增i时,先前索引的in_array_sig(i + 1)变成下一个循环迭代&lt; arayray_sig(i)。没有干预过程暂停和恢复原始值是可用的。 in_array_sig也想成为一个变量。
如果我们要修复所有这些,我们也可能会注意到我没有初始化(这将在for循环迭代方案中处理),我们也可能会发现我们得到了一个绑定错误使用in_array_sig的(i + 1)索引的行。如果没有提供MCVe的问题的作者,不清楚阵列大小是16(编号为0到15)还是17,如果前者i = 15 + 1将超出未公开数组的索引范围,则不清楚输入in_array,in_array_sig和sorted_array。
如果我们确保满足索引范围,并指出我们只需要比阵列中元素数量少1个测试和交换,我们就会发现该过程不是完整的冒泡排序。我们会看到in_array_sig的最大二进制值最终是sorted_array的最右边元素。但是,其余元素的顺序并不保证。
要执行完整的冒泡排序,我们需要另一个循环嵌套第一个循环。也是现在的内心&#39; for循环可以减少要遍历的元素数量,因为每次迭代都会留下最大的剩余元素,直到确保订单完成为止。
修正
修复上述内容会给我们看起来像这样:
architecture foo of bubblesort is
use ieee.numeric_std.all;
begin
BSORT:
process (clk)
variable temp: std_logic_vector (3 downto 0);
variable var_array: bubble;
begin
var_array := in_array;
if rising_edge(clk) then
for j in bubble'LEFT to bubble'RIGHT - 1 loop
for i in bubble'LEFT to bubble'RIGHT - 1 - j loop
if unsigned(var_array(i)) > unsigned(var_array(i + 1)) then
temp := var_array(i);
var_array(i) := var_array(i + 1);
var_array(i + 1) := temp;
end if;
end loop;
end loop;
sorted_array <= var_array;
end if;
end process;
end architecture foo;
注意循环迭代方案是根据类型气泡边界来描述的,外部是一个比长度短的内部,而内部是一个更短的每次迭代。另请注意,sorted_array赋值将移动到in_array_sig变量替换var_array可见的进程中。
另外值得注意的是使用unsigned大于运算符。 &#34;&gt;&#34;对于std_logic_vector,允许元值和&#39; H&#39;和&#39; L&#39;用于扭曲关系比较的值,而无符号运算符是算术运算。
<强>结果
抛出包和实体声明:
library ieee;
use ieee.std_logic_1164.all;
package array_type is
type bubble is array (0 to 15) of std_logic_vector(3 downto 0);
end package;
library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;
entity bubblesort is
port (
signal clk: in std_logic;
signal reset: in std_logic;
signal in_array: in bubble;
signal sorted_array: out bubble
);
end entity;
以及测试平台:
library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;
entity bubblesort_tb is
end entity;
architecture fum of bubblesort_tb is
signal clk: std_logic := '0';
signal reset: std_logic := '0';
signal in_array: bubble :=
(x"F", x"E", x"D", x"C", x"B", x"A", x"9", x"8",
x"7", x"6", x"5", x"4", x"3", x"2", x"1", x"0");
signal sorted_array: bubble;
begin
DUT:
entity work.bubblesort(foo)
port map (
clk => clk,
reset => reset,
in_array => in_array,
sorted_array => sorted_array
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if now > 30 ns then
wait;
end if;
end process;
end architecture;
我们得到:
有效的东西。
作为启用的复位未包含在架构中的过程BSORT中,并且可以在具有时钟边沿条件的if语句中添加。
关于这里,我们在关于描述硬件的评论中得到了马修泰勒的观点。
根据综合工具,该过程可能会或可能不会被视为硬件。如果不是,您需要中间变量来保存内循环的每次连续迭代中使用的数组部分。
还有一个问题是你在一个时钟周期中可以做多少。最坏的情况是延迟深度由十五个元素比较和十五个2:2选择器组成,有条件地交换元素对。
如果您要选择与合成延迟不兼容的时钟速度,则需要重新设计从软件循环仿真到连续时钟操作的实现。
这可以简单到允许更多时钟周期,通过使用该启用来确定冒泡排序何时有效加载到sorted_array寄存器。它可能更复杂,也允许不同的和更好的执行排序方法或修改冒泡排序,以便检测不再需要交换。