signal_processing/hardware/system/avalon_slave_transitions.vhd

90 lines
2.7 KiB
VHDL
Raw Normal View History

2023-10-31 06:47:27 +00:00
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;