--- /dev/null
+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;
--- /dev/null
+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;