简体   繁体   中英

bubble sort in vhdl

Can anyone help me in writing VHDL code for bubble sort given an array of data as input?

I have declared in_array as input which contains 15 array elements. i want to bubble sort them in descending order.

in_array is input array. sorted_array is out put array. in_array_sig is signal of type 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. 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. This is caused by the condition in the while loop depending on i and ia signal being updated within the process. i shouldn't be a signal here (and alternatively you could use a for loop here).

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. Signals are scheduled for update, a signal assignment without a waveform element containing an after clause have an implicit after clause with zero delay. 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.

We'd also get bitten using a signal for 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). Without an intervening process suspend and resume the original value is available. in_array_sig wants to be a variable as well.

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. 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.

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. We would see the largest binary value of in_array_sig end up as the right most element of 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.

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.

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.

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.

And about here we get to Matthew Taylor's point in a comment about describing hardware.

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.

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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