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 data_channel_control is port ( clk : in std_logic; reset : in std_logic; address : in std_logic_vector( 3 downto 0 ); read : in std_logic; readdata : out std_logic_vector( 31 downto 0 ); write : in std_logic; writedata : in std_logic_vector( 31 downto 0 ); sink_config : out std_logic; source_config : out std_logic; clear : out std_logic; empty : in std_logic; full : in std_logic; level : in std_logic_vector( 9 downto 0 ); sink_write : out std_logic; sink_writedata : out std_logic_vector( 31 downto 0 ); source_read : out std_logic; source_readdata : in std_logic_vector( 31 downto 0 ) ); end entity data_channel_control; architecture rtl of data_channel_control is type Registers is ( REG_CONFIG, REG_EMPTY, REG_FULL, REG_LEVEL, REG_SINK, REG_SOURCE, REG_CLEAR ); constant REG_CONFIG_POS : natural := Registers'pos( REG_CONFIG ); constant REG_EMPTY_POS : natural := Registers'pos( REG_EMPTY ); constant REG_FULL_POS : natural := Registers'pos( REG_FULL ); constant REG_LEVEL_POS : natural := Registers'pos( REG_LEVEL ); constant REG_SINK_POS : natural := Registers'pos( REG_SINK ); constant REG_SOURCE_POS : natural := Registers'pos( REG_SOURCE ); constant REG_CLEAR_POS : natural := Registers'pos( REG_CLEAR ); constant REG_COUNT : natural := registers'pos( registers'right ) + 1; constant REG_ACCESS_TYPES : work.reg32.AccessArray( 0 to REG_COUNT - 1 ) := ( READ_WRITE, READ_ONLY, READ_ONLY, READ_ONLY, WRITE_ONLY, READ_ONLY, WRITE_ONLY ); signal reg_index : integer range 0 to REG_COUNT - 1; -- Internal registers signal current_state : work.avalon_slave.State; signal next_state : work.avalon_slave.State; signal reg_data : RegArray( 0 to REG_COUNT - 1 ); signal fifo_read_req : std_logic; begin u_avalon_slave_transitions: entity work.avalon_slave_transitions generic map ( REG_COUNT => REG_COUNT, REG_ACCESS_TYPES => REG_ACCESS_TYPES ) port map ( address => address, read => read, write => write, current_state => current_state, next_state => next_state, reg_index => reg_index ); sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_state <= SLAVE_IDLE; reg_data( REG_CONFIG_POS ) <= ( others => '0' ); fifo_read_req <= '0'; clear <= '0'; elsif ( rising_edge( clk ) ) then current_state <= next_state; sink_write <= '0'; source_read <= '0'; clear <= '0'; case next_state is when SLAVE_IDLE => null; when SLAVE_READ => readdata <= ( others => '0' ); if ( reg_index = REG_CONFIG_POS ) then readdata( 1 downto 0 ) <= reg_data( reg_index )( 1 downto 0 ); elsif ( reg_index = REG_EMPTY_POS ) then readdata( 0 ) <= reg_data( reg_index )( 0 ); elsif ( reg_index = REG_FULL_POS ) then readdata( 0 ) <= reg_data( reg_index )( 0 ); elsif ( reg_index = REG_LEVEL_POS ) then readdata( 9 downto 0 ) <= reg_data( reg_index )( 9 downto 0 ); elsif ( reg_index = REG_SINK_POS ) then readdata <= reg_data( reg_index ); elsif ( reg_index = REG_SOURCE_POS ) then readdata <= source_readdata; source_read <= '1'; end if; when SLAVE_READ_DATA => null; when SLAVE_WRITE => if ( reg_index = REG_SINK_POS ) then sink_write <= '1'; sink_writedata <= writedata; elsif ( reg_index = REG_CLEAR_POS ) then clear <= '1'; else reg_data( reg_index ) <= writedata; end if; end case; reg_data( REG_EMPTY_POS )( 0 ) <= empty; reg_data( REG_FULL_POS )( 0 ) <= full; reg_data( REG_LEVEL_POS )( level'left downto level'right ) <= level; end if; end process sync; sink_config <= reg_data( REG_CONFIG_POS )( 0 ); source_config <= reg_data( REG_CONFIG_POS )( 1 ); end architecture rtl;