library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.avalon_slave.all; entity avalon_slave_transitions is generic ( REG_COUNT : natural; REG_ACCESS_TYPES : work.reg32.AccessArray ); port ( address : in std_logic_vector( 3 downto 0 ); read : in std_logic; write : in std_logic; current_state : in work.avalon_slave.State; next_state : out work.avalon_slave.State; reg_index : out integer range 0 to REG_COUNT - 1 ); end entity avalon_slave_transitions; architecture rtl of avalon_slave_transitions is signal is_access : boolean; signal is_read : boolean; signal is_write : boolean; signal address_index : integer range 0 to 2 ** address'high - 1; signal is_valid_reg_index : boolean; signal access_type : work.reg32.AccessType; signal is_valid_access : boolean; signal is_valid_access_type : boolean; signal index : integer range 0 to REG_COUNT - 1; begin c_is_access: is_access <= ( read or write ) = '1'; c_is_read: is_read <= read = '1'; c_is_write: is_write <= write = '1' and not is_read; c_address_index: address_index <= to_integer( unsigned( address ) ); c_is_valid_reg_index: is_valid_reg_index <= address_index <= ( REG_COUNT - 1 ); c_index: index <= address_index when is_valid_reg_index else 0; c_reg_index: reg_index <= index; c_access_type: access_type <= REG_ACCESS_TYPES( index ); c_is_valid_access_type: is_valid_access_type <= true when ( is_read and work.reg32.allows_read( access_type ) ) or ( is_write and work.reg32.allows_write( access_type ) ) else false; c_is_valid_access: is_valid_access <= is_access and is_valid_reg_index and is_valid_access_type; transition : process( all ) is begin case current_state is when SLAVE_IDLE => if ( is_valid_access and is_read ) then next_state <= SLAVE_READ; elsif ( is_valid_access and is_write ) then next_state <= SLAVE_WRITE; else next_state <= SLAVE_IDLE; end if; when SLAVE_READ => next_state <= SLAVE_READ_DATA; when SLAVE_READ_DATA => if ( is_valid_access and is_read ) then next_state <= SLAVE_READ; elsif ( is_valid_access and is_write ) then next_state <= SLAVE_WRITE; else next_state <= SLAVE_IDLE; end if; when SLAVE_WRITE => next_state <= SLAVE_IDLE; end case; end process transition; end architecture rtl;