From: Tobias Weber Date: Sun, 11 Feb 2018 09:11:50 +0000 (+0800) Subject: basic round robin arbiter to replace priority type multiplexing of fifos. X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=1355b6499a3c20527ac2e7fca7daf33e2299e318;p=trb3.git basic round robin arbiter to replace priority type multiplexing of fifos. --- diff --git a/mupix/Mupix8/sources/Arbiter.vhd b/mupix/Mupix8/sources/Arbiter.vhd new file mode 100644 index 0000000..5ec3b6b --- /dev/null +++ b/mupix/Mupix8/sources/Arbiter.vhd @@ -0,0 +1,150 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity PriorityArbiter is + generic( + g_num_channels : integer := 4 + ); + port( + requests : in std_logic_vector(g_num_channels - 1 downto 0); -- requests to arbiter + grants : out std_logic_vector(g_num_channels - 1 downto 0) -- grants from arbiter + ); +end entity PriorityArbiter; + +architecture rtl of PriorityArbiter is + + signal temp : unsigned(g_num_channels - 1 downto 0); + +begin + + temp <= unsigned(not requests); + grants <= requests and std_logic_vector(temp + 1); + +end architecture rtl; + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity HotBitMask is -- mask of all bits less significant than one hot bit + generic( + g_num_channels : integer := 4 + ); + port( + bitvector : in std_logic_vector(g_num_channels - 1 downto 0); -- input bit vector + mask : out std_logic_vector(g_num_channels - 1 downto 0) -- output bit mask + ); +end entity HotBitMask; + +architecture rtl of HotBitMask is + + signal temp : unsigned(g_num_channels - 1 downto 0); + signal mask_i : std_logic_vector(g_num_channels - 1 downto 0); + constant allzero : std_logic_vector(g_num_channels - 1 downto 0) := (others => '0'); + +begin + + temp <= unsigned(bitvector) - 1; + + invert_proc : process(bitvector, temp) is + begin + --mask_i <= + if bitvector = allzero then + mask_i <= bitvector xor std_logic_vector(temp); + else + mask_i <= not (bitvector xor std_logic_vector(temp)); + end if; + end process invert_proc; + + mask <= mask_i or bitvector; + +end architecture rtl; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity RoundRobinArbiter is + generic( + g_num_channels : integer := 4 + ); + port( + clk : in std_logic; + requests : in std_logic_vector(g_num_channels - 1 downto 0); + grant : out std_logic_vector(g_num_channels - 1 downto 0) + ); +end entity RoundRobinArbiter; + + +architecture rtl of RoundRobinArbiter is + + component PriorityArbiter + generic(g_num_channels : integer := 4); + port( + requests : in std_logic_vector(g_num_channels - 1 downto 0); + grants : out std_logic_vector(g_num_channels - 1 downto 0) + ); + end component PriorityArbiter; + + component HotBitMask + generic(g_num_channels : integer := 4); + port( + bitvector : in std_logic_vector(g_num_channels - 1 downto 0); + mask : out std_logic_vector(g_num_channels - 1 downto 0) + ); + end component HotBitMask; + + constant c_zeros : std_logic_vector(g_num_channels - 1 downto 0) := (others => '0'); + signal grant_raw : std_logic_vector(g_num_channels - 1 downto 0); + signal grant_i : std_logic_vector(g_num_channels - 1 downto 0) := (others => '0'); + signal mask : std_logic_vector(g_num_channels - 1 downto 0); + signal requests_masked : std_logic_vector(g_num_channels - 1 downto 0); + signal grant_masked : std_logic_vector(g_num_channels - 1 downto 0); + +begin + + priority_arbiter1 : entity work.PriorityArbiter + generic map( + g_num_channels => g_num_channels + ) + port map( + requests => requests, + grants => grant_raw + ); + + hotbit1 : entity work.HotBitMask + generic map( + g_num_channels => g_num_channels + ) + port map( + bitvector => grant_i, + mask => mask + ); + + requests_masked <= requests and mask; + + priority_arbiter2 : component PriorityArbiter + generic map( + g_num_channels => g_num_channels + ) + port map( + requests => requests_masked, + grants => grant_masked + ); + + grant_proc : process (clk) is + begin + if rising_edge(clk) then + if grant_masked = c_zeros then + grant_i <= grant_raw; + else + grant_i <= grant_masked; + end if; + end if; + end process grant_proc; + + grant <= grant_i; + +end architecture rtl; diff --git a/mupix/Mupix8/tb/ArbiterTest.vhd b/mupix/Mupix8/tb/ArbiterTest.vhd new file mode 100644 index 0000000..6e6b880 --- /dev/null +++ b/mupix/Mupix8/tb/ArbiterTest.vhd @@ -0,0 +1,144 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity ArbiterTest is +end entity ArbiterTest; + +architecture sim of ArbiterTest is + + component PriorityArbiter is + generic ( + g_num_channels : integer); + port ( + requests : in std_logic_vector(g_num_channels - 1 downto 0); + grants : out std_logic_vector(g_num_channels - 1 downto 0)); + end component PriorityArbiter; + + signal requests : std_logic_vector(4 downto 0); + signal grants : std_logic_vector(4 downto 0); + +begin + + PriorityArbiter_1: entity work.PriorityArbiter + generic map ( + g_num_channels => 5) + port map ( + requests => requests, + grants => grants); + + + stim : process + begin + wait for 50 ns; + requests <= (others => '0'); + wait for 50 ns; + requests <= "01101"; + wait for 50 ns; + requests <= "01100"; + end process stim; + +end architecture sim; + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity HotBitMaskTest is +end entity HotBitMaskTest; + +architecture sim of HotBitMaskTest is + + component HotBitMask is + generic ( + g_num_channels : integer); + port ( + bitvector : in std_logic_vector(g_num_channels - 1 downto 0); + mask : out std_logic_vector(g_num_channels - 1 downto 0)); + end component HotBitMask; + + signal bitvector : std_logic_vector(4 downto 0); + signal mask : std_logic_vector(4 downto 0); + +begin + + HotBitMask_1: entity work.HotBitMask + generic map ( + g_num_channels => 5) + port map ( + bitvector => bitvector, + mask => mask); + + + stim : process + begin + wait for 50 ns; + bitvector <= "00001"; + wait for 50 ns; + bitvector <= "00100"; + wait for 50 ns; + bitvector <= "01000"; + wait for 50 ns; + bitvector <= (others => '0'); + end process stim; + +end architecture sim; + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity RoundRobinArbiterTest is +end entity RoundRobinArbiterTest; + +architecture sim of RoundRobinArbiterTest is + + component RoundRobinArbiter is + generic ( + g_num_channels : integer); + port ( + clk : in std_logic; + requests : in std_logic_vector(g_num_channels - 1 downto 0); + grant : out std_logic_vector(g_num_channels - 1 downto 0)); + end component RoundRobinArbiter; + + constant clk_period : time := 20 ns; + signal clk : std_logic; + signal requests : std_logic_vector(4 downto 0); + signal grant : std_logic_vector(4 downto 0); + +begin + + RoundRobinArbiter_1: entity work.RoundRobinArbiter + generic map ( + g_num_channels => 5) + port map ( + clk => clk, + requests => requests, + grant => grant); + + clk_gen : process + begin + clk <= '1'; + wait for clk_period/2; + clk <= '0'; + wait for clk_period/2; + end process clk_gen; + + stim : process + begin + requests <= "01101"; + wait for 2*clk_period; + requests <= "01100"; + wait for 2*clk_period; + requests <= "01001"; + wait for 2*clk_period; + requests <= "10001"; + wait for 2*clk_period; + requests <= "00001"; + wait; + end process stim; + +end architecture sim;