From 439e9f2e5767794e087088f5da0a5835ee1cc970 Mon Sep 17 00:00:00 2001 From: Benjamin Krill Date: Tue, 17 Sep 2013 12:52:29 +0200 Subject: [PATCH] vhdl: add rrarbiter module --- vhdl/rrarbiter.vhd | 56 ++++++++++++++ vhdl/rrarbiter_tb.vhd | 174 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 vhdl/rrarbiter.vhd create mode 100644 vhdl/rrarbiter_tb.vhd diff --git a/vhdl/rrarbiter.vhd b/vhdl/rrarbiter.vhd new file mode 100644 index 0000000..f927c8c --- /dev/null +++ b/vhdl/rrarbiter.vhd @@ -0,0 +1,56 @@ +-- --------------------------------------------------------------------------- +-- (2009) Benjamin Krill +-- +-- "THE BEER-WARE LICENSE" (Revision 42): +-- ben@codiert.org wrote this file. As long as you retain this notice you can +-- do whatever you want with this stuff. If we meet some day, and you think +-- this stuff is worth it, you can buy me a beer in return Benjamin Krill +-- --------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity rrarbiter is + generic ( CNT : integer := 7 ); + port ( + clk : in std_logic; + rst_n : in std_logic; + + req : in std_logic_vector(CNT-1 downto 0); + ack : in std_logic; + grant : out std_logic_vector(CNT-1 downto 0) + ); +end; + +architecture rrarbiter of rrarbiter is + signal grant_q : std_logic_vector(CNT-1 downto 0); + signal pre_req : std_logic_vector(CNT-1 downto 0); + signal sel_gnt : std_logic_vector(CNT-1 downto 0); + signal isol_lsb : std_logic_vector(CNT-1 downto 0); + signal mask_pre : std_logic_vector(CNT-1 downto 0); + signal win : std_logic_vector(CNT-1 downto 0); +begin + grant <= grant_q; + mask_pre <= req and not (std_logic_vector(unsigned(pre_req) - 1) or pre_req); -- Mask off previous winners + sel_gnt <= mask_pre and std_logic_vector(unsigned(not(mask_pre)) + 1); -- Select new winner + isol_lsb <= req and std_logic_vector(unsigned(not(req)) + 1); -- Isolate least significant set bit. + win <= sel_gnt when mask_pre /= (CNT-1 downto 0 => '0') else isol_lsb; + + process (clk, rst_n) + begin + if rst_n = '0' then + pre_req <= (others => '0'); + grant_q <= (others => '0'); + elsif rising_edge(clk) then + grant_q <= grant_q; + pre_req <= pre_req; + if grant_q = (CNT-1 downto 0 => '0') or ack = '1' then + if win /= (CNT-1 downto 0 => '0') then + pre_req <= win; + end if; + grant_q <= win; + end if; + end if; + end process; + +end rrarbiter; diff --git a/vhdl/rrarbiter_tb.vhd b/vhdl/rrarbiter_tb.vhd new file mode 100644 index 0000000..ec4a641 --- /dev/null +++ b/vhdl/rrarbiter_tb.vhd @@ -0,0 +1,174 @@ +-- --------------------------------------------------------------------------- +-- (2009) Benjamin Krill +-- +-- "THE BEER-WARE LICENSE" (Revision 42): +-- ben@codiert.org wrote this file. As long as you retain this notice you can +-- do whatever you want with this stuff. If we meet some day, and you think +-- this stuff is worth it, you can buy me a beer in return Benjamin Krill +-- --------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_Logic_unsigned.all; +use IEEE.numeric_std.all; + +entity rrarbiter_tb is +end rrarbiter_tb; + +architecture rtl of rrarbiter_tb is + constant CLK_PERIOD : time := 36 ns; + + signal clk : std_logic; + signal rst : std_logic; + signal rst_n : std_logic; + + signal req : std_logic_vector(6 downto 0); + signal grant : std_logic_vector(6 downto 0); + signal ack : std_logic; +begin + rst <= transport '1', '0' after ( 4 * CLK_PERIOD); + rst_n <= not rst; + + clock: process + begin + clk <= '1', '0' after CLK_PERIOD/2; + wait for Clk_PERIOD; + end process; + + beh: process + begin + req <= "0000000"; + wait for 10*CLK_PERIOD; + req <= "0000011"; + wait for 5*CLK_PERIOD; + req <= "0000000"; + wait for 5*CLK_PERIOD; + req <= "0001111"; + wait for 5*CLK_PERIOD; + req <= "0001110"; + wait for 20*CLK_PERIOD; + req <= "0000000"; + wait for 20*CLK_PERIOD; + wait; + end process beh; + + beh0: process + begin + ack <= '0'; + wait for 10*CLK_PERIOD; + wait for 6*CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for 8*CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for 5*CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for 2*CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + ack <= '1'; + wait for CLK_PERIOD; + ack <= '0'; + wait for CLK_PERIOD; + wait for 20*CLK_PERIOD; + wait; + end process beh0; + + DUT: entity work.rrarbiter_reg + port map ( + clk => clk, + rst_n => rst_n, + + ack => ack, + req => req, + grant => grant + ); + +end rtl; + +configuration rrarbiter_tb_rtl_cfg of rrarbiter_tb is + for rtl + end for; +end rrarbiter_tb_rtl_cfg;