Reputation: 97
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;
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.
Upvotes: 0
Views: 1231
Reputation:
... 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:
Against the input array values you'd find it's correct.
Upvotes: 1