简体   繁体   English

VHDL中的气泡排序

[英]bubble sort in vhdl

Can anyone help me in writing VHDL code for bubble sort given an array of data as input? 在给定数据数组作为输入的情况下,谁能帮助我编写用于气泡排序的VHDL代码?

I have declared in_array as input which contains 15 array elements. 我已经声明in_array作为包含15个数组元素的输入。 i want to bubble sort them in descending order. 我想按降序对它们进行泡沫排序。

in_array is input array. in_array是输入数组。 sorted_array is out put array. sorted_array输出数组。 in_array_sig is signal of type in_array in_array_sig是in_array类型的信号

I am facing problem with statements inside process 我在流程中遇到陈述问题

Below is my code: 下面是我的代码:

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;

I am beginner in VHDL coding. 我是VHDL编码的初学者。 Kindly help me with this. 请帮助我。

The lack of a Minimal Complete and Verifiable example makes it hard to provide an answer about all the the things stopping your code from bubble sorting accurately. 缺少最小完成和可验证的示例,使得很难就阻止代码正确进行气泡排序的所有问题提供答案。 These can be described in the order you'd encounter them troubleshooting. 这些问题可以按照您进行故障排除的顺序进行描述。

  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;

Before starting note that the clock is gated with reset. 在开始之前,请注意时钟是通过复位控制的。 You could qualify assignments with reset making it an enable instead. 您可以通过重置来限定分配,而将其启用。

Problems 问题

The first thing we'd find producing an MCVe and a testbench is that the process never suspends. 我们发现产生MCVe和测试平台的第一件事是该过程永不暂停。 This is caused by the condition in the while loop depending on i and ia signal being updated within the process. 这是由于while循环中的条件所致,具体取决于在该过程中更新i和ia信号。 i shouldn't be a signal here (and alternatively you could use a for loop here). 我不应该在这里发出信号(或者您可以在这里使用for循环)。

This also points out that temp is a signal and suffers the same problem, you can't use the 'new' value of temp until the process has suspended and resumed. 这也指出temp是一个信号,并且会遇到相同的问题,在过程暂停和恢复之前,不能使用temp的“新”值。 Signals are scheduled for update, a signal assignment without a waveform element containing an after clause have an implicit after clause with zero delay. 信号被调度用于更新,没有包含after子句的波形元素的信号分配具有零延迟的隐式after子句。 Signal updates do no occur while any process scheduled to resume has yet to resume and subsequently suspend. 当计划恢复的任何进程尚未恢复并随后挂起时,不会发生信号更新。 This allows the semblance of concurrency for signals who's assignments are found in sequential statements (a concurrent statement has an equivalent process containing equivalent sequential statements). 这允许在顺序语句中发现分配给谁的信号的并发外观(并发语句具有包含等效顺序语句的等效过程)。 So neither i nor temp can update during execution of a processes sequence of statements and both want to be variables. 因此,i和temp都无法在执行过程中的语句序列期间进行更新,并且两者都希望成为变量。

We'd also get bitten using a signal for in_array_sig. 我们还会使用in_array_sig的信号来咬人。 As you increment i the previously indexed in_array_sig(i + 1) becomes the next loop iteration's in_array_sig(i). 随着i的增加,先前索引的in_array_sig(i + 1)成为下一个循环迭代的in_array_sig(i)。 Without an intervening process suspend and resume the original value is available. 无需干预过程即可暂停并恢复原始值。 in_array_sig wants to be a variable as well. in_array_sig也想成为变量。

If we were to fix all these we'd also likely note that i is not initialized (this would be taken care of in a for loop iteration scheme) and we might also find that we get a bound error in a line using an (i + 1) index for in_array_sig. 如果我们要修复所有这些问题,我们可能还会注意到i尚未初始化(这将在for循环迭代方案中解决),并且我们可能还会发现使用(i + 1)in_array_sig的索引。 It's not clear without the author of the question providing an MCVe whether the array size is 16 (numbered 0 to 15) or 17. If the former i = 15 + 1 would be out of the index range for the undisclosed array type for in_array, in_array_sig, and sorted_array. 如果问题的作者没有提供MCVe,则不清楚,数组大小是16(编号为0到15)还是17。如果前i = 15 +1超出了in_array未公开数组类型的索引范围, in_array_sig和sorted_array。

If we were to insure the index range is met noting that we only need 1 fewer tests and swaps than the number of elements in an array we'd find that what the process isn't a complete bubble sort. 如果要确保满足索引范围,请注意我们只需要比数组中的元素数量少1个测试和交换就可以发现该过程不是完整的冒泡排序。 We would see the largest binary value of in_array_sig end up as the right most element of sorted_array. 我们将看到in_array_sig的最大二进制值最终成为sorted_array的最右边的元素。 However the order of the remaining elements isn't guaranteed. 但是,不能保证其余元素的顺序。

To perform a complete bubble sort we need another loop nesting the first one. 为了执行完整的冒泡排序,我们需要另一个循环嵌套第一个循环。 Also the now 'inner' for loop can have a decreasing number of elements to traverse because each iteration leaves a largest remaining element rightmost until the order is assured to be complete. 而且,现在的“内部” for循环可以遍历的元素数量会减少,因为每次迭代都会在最右边保留最大的剩余元素,直到确保完成顺序为止。

Fixes 修正

Fixing the above would give us something that looks like this: 解决上述问题将使我们看起来像这样:

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;

Note the loop iteration schemes are described in terms of type bubble bounds, the outer is one shorter than the length and the inner is one shorter for each iteration. 请注意,循环迭代方案是根据类型气泡边界描述的,对于每次迭代,外部的长度比长度短一,内部的长度短一。 Also note the sorted_array assignment is moved into the process where the in_array_sig variable replacement var_array is visible. 还要注意,sorted_array分配已移到可见in_array_sig变量替换var_array的过程中。

Also of note is the use of the unsigned greater than operator. 还要注意的是,无符号大于运算符的使用。 The ">" for std_logic_vector allows meta-values and 'H' and 'L' values to distort relational comparison while the operator for unsigned is arithmetic. std_logic_vector的“>”允许元值以及“ H”和“ L”值扭曲关系比较,而无符号运算符是算术运算符。

Results 结果

Throw in package and entity declarations: 放入包和实体声明中:

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;

along with a testbench: 以及一个测试平台:

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;

and we get: 我们得到:

bubbleort_tb.png

something that works. 有用的东西。

The reset as enable has not been included in process BSORT in architecture and can be added in, inside the if statement with a clock edge condition. 复位为使能尚未包括在体系结构的进程BSORT中,可以在带有时钟边沿条件的if语句中添加。

And about here we get to Matthew Taylor's point in a comment about describing hardware. 关于这点,我们在关于描述硬件的评论中谈到了Matthew Taylor的观点。

Depending on the synthesis tool the process may or may not be realizable as hardware. 取决于综合工具,该过程可能实现也可能无法实现为硬件。 If not you'd need intermediary variables holding the array portions used in each successive iteration of the inner loop. 如果不是这样,则需要中间变量保存内部循环的每次连续迭代中使用的数组部分。

There's also the issue of how much you can do in a clock cycle. 还有一个问题,您在一个时钟周期内可以做什么。 Worst case there is a delay depth comprised of fifteen element comparisons and fifteen 2:2 selectors conditionally swapping element pairs. 最坏的情况是延迟深度由15个元素比较和15个2:2选择器有条件地交换元素对组成。

If you were to pick a clock speed that was incompatible with the synthesized delay you'd need to re-architect the implementation from a software loop emulation to something operating across successive clocks. 如果要选择与合成延迟不兼容的时钟速度,则需要重新设计实现,从软件循环仿真到跨连续时钟工作的实现。

That could be as simple as allowing more clock periods by using that enable to determine when the bubble sort is valid for loading into the sorted_array register. 通过使用该启用来确定何时冒泡排序有效地加载到sorted_array寄存器中,可以简单地允许提供更多的时钟周期。 It could be more complex also allowing different and better performing sorting methods or a modification to bubble sort to say detect no more swaps can be necessary. 它可能更加复杂,还允许使用不同且性能更好的排序方法,或者对冒泡排序进行修改以表明不再需要进行交换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM