--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+-- rule 1: an empty cell will only claim an element if the above cell is not empty
+-- rule 2: an occupied cell will only a claim incoming element if the element
+-- is less than the stored element and the occupied cell above is not pushing
+-- out its element
+-- rule 3: if the above cell kicks out its element, then the current cell must claim
+-- the aboves cell element independent of its state
+-- rule 4: if an occupied cell accepts an element it must kick out its current element
+
+entity SortingCell is
+ generic (
+ g_datawidth : natural := 8);
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ enable_in : in std_logic;
+ data_in : in std_logic_vector(g_datawidth - 1 downto 0);
+ pushing_out : out std_logic;
+ data_out : out std_logic_vector(g_datawidth - 1 downto 0);
+ cell_empty_out : out std_logic;
+ above_cell_empty_in : in std_logic;
+ above_cell_pushing_in : in std_logic;
+ above_cell_data_in : in std_logic_vector(g_datawidth - 1 downto 0));
+end entity SortingCell;
+
+architecture behavorial of SortingCell is
+
+ signal empty_i : std_logic := '1';
+ signal pushing_i : std_logic := '0';
+ signal accept_i : std_logic := '0';
+ signal data_i : std_logic_vector(g_datawidth - 1 downto 0) := (others => '1');
+
+begin -- architecture behavorial
+
+
+ accept_and_push_proc: process(clk) is
+ begin
+ if rising_edge(clk) then
+ pushing_i <= '0';
+ accept_i <= '0';
+ if enable_in = '1' then
+ if empty_i = '1' then
+ if above_cell_empty_in = '0' then
+ accept_i <= '1';
+ end if;
+ else
+ if unsigned(data_in) < unsigned(data_i) then
+ accept_i <= '1';
+ pushing_i <= '1';
+ end if;
+ end if;
+ end if;
+ end if;
+ end process accept_and_push_proc;
+
+
+
+ data_proc: process(clk) is
+ begin
+ if falling_edge(clk) then
+ if reset = '1' then
+ data_i <= (others => '1');
+ empty_i <= '1';
+ else
+ if enable_in = '1' then
+ if above_cell_pushing_in = '1' then
+ data_i <= above_cell_data_in;
+ empty_i <= '0';
+ elsif accept_i = '1' then
+ data_i <= data_in;
+ empty_i <= '0';
+ else
+ data_i <= data_i;
+ empty_i <= empty_i;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process data_proc;
+
+ cell_empty_out <= empty_i;
+ pushing_out <= pushing_i or above_cell_pushing_in;
+ data_out <= data_i;
+
+end architecture behavorial;
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+entity SortingNetwork is
+ generic (
+ g_datawidth : natural := 8;
+ g_sortingcells : natural := 32);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ enable : in std_logic;
+ data_in : in std_logic_vector(g_datawidth - 1 downto 0);
+ data_out : out std_logic_vector(g_datawidth*g_sortingcells - 1 downto 0));
+end entity SortingNetwork;
+
+
+architecture behavorial of SortingNetwork is
+
+ component SortingCell is
+ generic (
+ g_datawidth : natural);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ enable_in : in std_logic;
+ data_in : in std_logic_vector(g_datawidth - 1 downto 0);
+ pushing_out : out std_logic;
+ data_out : out std_logic_vector(g_datawidth - 1 downto 0);
+ cell_empty_out : out std_logic;
+ above_cell_empty_in : in std_logic;
+ above_cell_pushing_in : in std_logic;
+ above_cell_data_in : in std_logic_vector(g_datawidth - 1 downto 0));
+ end component SortingCell;
+
+ signal dummy_data : std_logic_vector(g_datawidth - 1 downto 0) := (others => '0');
+ signal pushing_i : std_logic_vector(g_sortingcells - 1 downto 0);
+ signal cell_empty_i : std_logic_vector(g_sortingcells - 1 downto 0);
+ signal data_i : std_logic_vector(g_sortingcells*g_datawidth - 1 downto 0);
+
+begin -- architecture behavorial
+
+ gen_cells : for j in g_sortingcells - 2 downto 0 generate
+ SortingCell: entity work.SortingCell
+ generic map (
+ g_datawidth => g_datawidth)
+ port map (
+ clk => clk,
+ reset => reset,
+ enable_in => enable,
+ data_in => data_in,
+ pushing_out => pushing_i(j),
+ data_out => data_i((j + 1)*g_datawidth - 1 downto j*g_datawidth),
+ cell_empty_out => cell_empty_i(j),
+ above_cell_empty_in => cell_empty_i(j + 1),
+ above_cell_pushing_in => pushing_i(j + 1),
+ above_cell_data_in => data_i((j + 2)*g_datawidth - 1 downto (j + 1)*g_datawidth));
+ end generate gen_cells;
+
+ SortingCell_1 : entity work.SortingCell -- highest sorting cell
+ generic map (
+ g_datawidth => g_datawidth)
+ port map (
+ clk => clk,
+ reset => reset,
+ enable_in => enable,
+ data_in => data_in,
+ pushing_out => pushing_i(g_sortingcells - 1),
+ data_out => data_i(g_sortingcells*g_datawidth - 1 downto (g_sortingcells - 1)*g_datawidth),
+ cell_empty_out => cell_empty_i(g_sortingcells - 1),
+ above_cell_empty_in => '0',
+ above_cell_pushing_in => '0',
+ above_cell_data_in => dummy_data);
+
+ data_out <= data_i;
+
+end architecture behavorial;