0
votes

I have the following code. Here I am trying to bubble sort the values of an array acoording to their index .

After bubblesorting in first set of for loops , i am using second set of for loops to get the original indeces of the values which are bubble sorted in an array.

library ieee;
use ieee.std_logic_1164.all;

package array_type is
    constant len: integer := 4;
    type sorted is array (0 to 15) of std_logic_vector(len-1 downto 0); 
end package;

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort is
port (
     clk:             in  std_logic;
     bit_array:        in  sorted;
     sorted_array:    out sorted 
);
end entity;

architecture behaviour of sort is
    use ieee.numeric_std.all;
begin

BSORT:
process (clk)
    variable temp:      std_logic_vector (len-1 downto 0);
    variable var_array:     sorted; 
    variable temp_array:     sorted;           
begin
    var_array := bit_array;
    if rising_edge(clk) then
        for j in sorted'LEFT to sorted'RIGHT - 1 loop 
            for i in sorted'LEFT to sorted'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;

        for i in sorted'LEFT to sorted'RIGHT loop 
            j_loop:for j in sorted'LEFT to sorted'RIGHT loop 
                if ( (var_array(i)) = (bit_array(j)) ) then
                    if not( (temp_array(0)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(1)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(2)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(3)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(4)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(5)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(6)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(7)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(8)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(9)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(10)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(11)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(12)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(13)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(14)= std_logic_vector(to_unsigned(j, len))) or
                            (temp_array(15)= std_logic_vector(to_unsigned(j, len))) ) then 
                        temp_array(i) := std_logic_vector(to_unsigned(j, len)); --conv_std_logic_vector(j,4);
                        exit j_loop;
                    end if;
                end if;
            end loop;
        end loop;
    sorted_array <= temp_array;
    end if;
end process;
end architecture behaviour;

and the test bench is as below:

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort_tb is
end entity;

architecture behav of sort_tb is
    use work.array_type.all;
    signal clk:             std_logic := '0';
    signal bit_array:        sorted;
    signal sorted_array:   sorted ;

    -- Clock period definitions
    constant clk_period : time := 10 ns; 

begin
DUT:
    entity work.sort(behaviour)
        port map (clk => clk,
            bit_array => bit_array,
            sorted_array => sorted_array
        );

    -- Clock process definitions( clock with 50% duty cycle is generated    here.
    clk_process :process
    begin
        clk <= '1';
        wait for clk_period/2;  --for 5 ns signal is '1'.
        clk <= '0';
        wait for clk_period/2;  --for next 5 ns signal is '0'.
    end process;

    process 
    begin
        bit_array <= (x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0") ;
        wait for 10 ns;
        bit_array <= (x"0", x"0", x"0", x"4", x"0", x"0", x"0", x"3", x"2", x"2", x"0", x"0", x"0", x"5", x"0", x"0") ;
        wait for 10 ns;
        bit_array <= (x"0", x"0", x"9", x"4", x"0", x"4", x"0", x"3", x"2", x"2", x"0", x"8", x"0", x"5", x"0", x"0") ;
        wait;
    end process;
end architecture;

wave

Here the problem is , the output sorted_array is not getting evaluated and updated every clock cycle as input bit_array changes. bit_array changes every clk cycle and clk is in sensitivity list of process, so sorted_array should get new values after evaluation each clk.

There are 2 for loops in the process. If i remove 2nd for loop and assign var_array to sorted_array(output), then sorted_array is evaluated according to new bit_array data and is updated every clock cycle which is correct. But the same is not happening if i include both the for loops.

I am new to VHDL , Need suggestion on this.

1
Wow, that's some integrated code. You must realize that this will likely not synthesize: exit is nice for simulations, but not for synthesis. Are you sure that long not( blahblah or blahblah or blahblah or ....) is correct?JHBonarius
exit statements are synthesis eligible, creating priority encoders (not needed here.) You're close to an MCVe but don't have a clear problem statement. What are the second set of loops supposed to do? Bubble sort works fine without them. They can't save hardware or make the hardware faster. Testing for any remaining work to be done is software optimization. For loops get unrolled (parallelized) in synthesis. You don't have an algorithm that saves hardware or fall through time. All those loops currently do is write the pattern you see to sorted_array.user1155120
@J.H.Bonarius and user1155120, After bubblesorting , i am using second set of for loops to get the original indeces of the values which are bubble sorted in an array.Santhosh Shetty Chowdary
But whatever the logic inside the process is , whole thing should be evaluated sequentially every clock cycle right ?Santhosh Shetty Chowdary
Sure it should happen in one clock in simulation. Changing the assignment to sorted_array from temp_array to from var_array gives the bubble sort. The second set of loops do not give you an index list from the original array by comparing to bit_array. The purpose of the second set of loops doesn't appear in your question and their function doesn't match your comment.user1155120

1 Answers

1
votes

... i am using second set of for loops to get the original indeces of the values which are bubble sorted in an array.

(Please update your question to reflect this).

Now that you're comment has clarified the purpose of the second set of loops the functionality can be introduce by another method.

Your contents addressable method with the second two loops is missing access to the original index of bit_array in the var_array.

The easiest way to to do this create a new array type that carries the original index along with the context of an array element using a record element type. (The idea shows up in CAM memory, the index is part of the data):

library ieee;
use ieee.std_logic_1164.all;

package array_type is
  constant len:         natural := 4;
  constant indx_size:    natural := len;
  type sorted is array (0 to 15) of std_logic_vector (len - 1 downto 0);
  type cam is record 
      contents: std_logic_vector (len - 1 downto 0);
      index:    std_logic_vector (indx_size - 1  downto 0);
  end record;
  type rsorted is array (0 to 15) of cam;
end package;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.array_type.all;

entity sort is
    port (
        clk:             in  std_logic;
        bit_array:       in  sorted;
        sorted_array:    out sorted
    );
end entity;

architecture behaviour of sort is
begin
BSORT:
    process (clk)
        variable temp:          cam;
        variable var_array:     rsorted;
        variable temp_array:    rsorted;
    begin
        -- var_array := bit_array;
        for i in bit_array'range loop
            var_array(i).contents := bit_array(i);
            var_array(i).index    := std_logic_vector(to_unsigned(i,indx_size));
        end loop;

        if rising_edge(clk) then
            for j in rsorted'LEFT to rsorted'RIGHT - 1 loop
                for i in rsorted'LEFT to rsorted'RIGHT - 1 - j loop
                    if var_array(i).contents < var_array(i + 1).contents then
                        temp := var_array(i);
                        var_array(i) := var_array(i + 1);
                        var_array(i + 1) := temp;
                    end if;
                end loop;
            end loop;
            -- for i in sorted'range loop            -- the sorted contents
            --     sorted_array(i) <= var_array(i).contents;
            -- end loop;
            -- or
            for i in sorted'range loop            -- the original indexes
                sorted_array(i) <= var_array(i).index;
            end loop;
        end if;
    end process;
end architecture behaviour;

library ieee;
use ieee.std_logic_1164.all;
use work.array_type.all;

entity sort_tb is
end entity;

architecture behav of sort_tb is
    use work.array_type.all;
    signal clk:            std_logic := '0';
    signal bit_array:      sorted;
    signal sorted_array:   sorted;
  -- Clock period definitions
    constant clk_period:   time := 10 ns;
begin
DUT:
    entity work.sort (behaviour)
        port map (
            clk          => clk,
            bit_array    => bit_array,
            sorted_array => sorted_array
        );
clk_process:
    process
    begin
        clk <= '1';
        wait for clk_period/2;
        clk <= '0';
        wait for clk_period/2;
    end process;

    process 
    begin
        bit_array <= ( x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0",
                       x"0", x"0", x"0", x"0", x"0", x"0", x"0", x"0" );
        wait for 10 ns;
        bit_array <= ( x"0", x"0", x"0", x"4", x"0", x"0", x"0", x"3",
                       x"2", x"2", x"0", x"0", x"0", x"5", x"0", x"0" );
        wait for 10 ns;
        bit_array <= ( x"0", x"0", x"9", x"4", x"0", x"4", x"0", x"3",
                       x"2", x"2", x"0", x"8", x"0", x"5", x"0", x"0" );
    wait;
    end process;
 end architecture;

You could conceivably output both the index list and the sorted contents in two different sorted arrays.

The above can do either by commenting out one output or the other.

And if you check the output waveform:

sorted_tb_index.png

Against the input array values you'd find it's correct.