diff options
Diffstat (limited to 'testsuite/gna/issue2185/avm_arbit.vhd')
-rw-r--r-- | testsuite/gna/issue2185/avm_arbit.vhd | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/testsuite/gna/issue2185/avm_arbit.vhd b/testsuite/gna/issue2185/avm_arbit.vhd new file mode 100644 index 000000000..d1516c669 --- /dev/null +++ b/testsuite/gna/issue2185/avm_arbit.vhd @@ -0,0 +1,156 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.numeric_std_unsigned.all; + +-- This arbitrates fairly between two Masters connected to a single Slave + +entity avm_arbit is + generic ( + G_ADDRESS_SIZE : integer; + G_DATA_SIZE : integer + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + -- Slave interface 0 (input) + s0_avm_write_i : in std_logic; + s0_avm_read_i : in std_logic; + s0_avm_address_i : in std_logic_vector(G_ADDRESS_SIZE-1 downto 0); + s0_avm_writedata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0); + s0_avm_byteenable_i : in std_logic_vector(G_DATA_SIZE/8-1 downto 0); + s0_avm_burstcount_i : in std_logic_vector(7 downto 0); + s0_avm_readdata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0); + s0_avm_readdatavalid_o : out std_logic; + s0_avm_waitrequest_o : out std_logic; + + -- Slave interface 1 (input) + s1_avm_write_i : in std_logic; + s1_avm_read_i : in std_logic; + s1_avm_address_i : in std_logic_vector(G_ADDRESS_SIZE-1 downto 0); + s1_avm_writedata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0); + s1_avm_byteenable_i : in std_logic_vector(G_DATA_SIZE/8-1 downto 0); + s1_avm_burstcount_i : in std_logic_vector(7 downto 0); + s1_avm_readdata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0); + s1_avm_readdatavalid_o : out std_logic; + s1_avm_waitrequest_o : out std_logic; + + -- Master interface (output) + m_avm_write_o : out std_logic; + m_avm_read_o : out std_logic; + m_avm_address_o : out std_logic_vector(G_ADDRESS_SIZE-1 downto 0); + m_avm_writedata_o : out std_logic_vector(G_DATA_SIZE-1 downto 0); + m_avm_byteenable_o : out std_logic_vector(G_DATA_SIZE/8-1 downto 0); + m_avm_burstcount_o : out std_logic_vector(7 downto 0); + m_avm_readdata_i : in std_logic_vector(G_DATA_SIZE-1 downto 0); + m_avm_readdatavalid_i : in std_logic; + m_avm_waitrequest_i : in std_logic + ); +end entity avm_arbit; + +architecture synthesis of avm_arbit is + + signal s0_active_req : std_logic; + signal s1_active_req : std_logic; + + signal s0_active_grant : std_logic := '0'; + signal s1_active_grant : std_logic := '0'; + signal active_grants : std_logic_vector(1 downto 0); + + signal last_grant : std_logic := '0'; + + signal burstcount : std_logic_vector(7 downto 0); + +begin + + s0_avm_waitrequest_o <= not s0_active_grant; + s1_avm_waitrequest_o <= not s1_active_grant; + + s0_active_req <= s0_avm_write_i or s0_avm_read_i; + s1_active_req <= s1_avm_write_i or s1_avm_read_i; + + p_burstcount : process (clk_i) + begin + if rising_edge(clk_i) then + if burstcount = X"00" then + if s0_avm_write_i and not s0_avm_waitrequest_o then + burstcount <= s0_avm_burstcount_i; + end if; + if s1_avm_write_i and not s1_avm_waitrequest_o then + burstcount <= s1_avm_burstcount_i; + end if; + else + if (s0_avm_write_i and not s0_avm_waitrequest_o) or + s0_avm_readdatavalid_o or + (s1_avm_write_i and not s1_avm_waitrequest_o) or + s1_avm_readdatavalid_o then + burstcount <= burstcount - 1; + end if; + end if; + + if rst_i = '1' then + burstcount <= X"00"; + end if; + end if; + end process p_burstcount; + + active_grants <= s0_active_grant & s1_active_grant; + + p_grant : process (clk_i) + begin + if rising_edge(clk_i) then + case active_grants is + when "00" => + if s0_active_req = '1' and last_grant = '1' then + s0_active_grant <= '1'; + last_grant <= '1'; + end if; + if s1_active_req = '1' and last_grant = '0' then + s1_active_grant <= '1'; + last_grant <= '0'; + end if; + + when "01" => + if burstcount = X"01" then + if (s1_avm_write_i and not s1_avm_waitrequest_o) or + s1_avm_readdatavalid_o then + s1_active_grant <= '0'; + end if; + end if; + when "10" => + if burstcount = X"01" then + if (s0_avm_write_i and not s0_avm_waitrequest_o) or + s0_avm_readdatavalid_o then + s0_active_grant <= '0'; + end if; + end if; + + when others => + report "S0 and S1 both active" + severity failure; + end case; + + if rst_i = '1' then + s0_active_grant <= '0'; + s1_active_grant <= '0'; + last_grant <= '0'; + end if; + end if; + end process p_grant; + + m_avm_write_o <= s0_avm_write_i when last_grant = '0' else s1_avm_write_i; + m_avm_read_o <= s0_avm_read_i when last_grant = '0' else s1_avm_read_i; + m_avm_address_o <= s0_avm_address_i when last_grant = '0' else s1_avm_address_i; + m_avm_writedata_o <= s0_avm_writedata_i when last_grant = '0' else s1_avm_writedata_i; + m_avm_byteenable_o <= s0_avm_byteenable_i when last_grant = '0' else s1_avm_byteenable_i; + m_avm_burstcount_o <= s0_avm_burstcount_i when last_grant = '0' else s1_avm_burstcount_i; + + s0_avm_readdata_o <= m_avm_readdata_i; + s0_avm_readdatavalid_o <= m_avm_readdatavalid_i when last_grant = '0' else '0'; + + s1_avm_readdata_o <= m_avm_readdata_i; + s1_avm_readdatavalid_o <= m_avm_readdatavalid_i when last_grant = '1' else '0'; + +end architecture synthesis; + |