library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.task.all; use work.avalon_slave.all; entity hardware_task_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 ); task_start : out std_logic; task_state : in work.task.State; task_config : out work.reg32.RegArray( 0 to 2 ) ); end entity hardware_task_control; architecture rtl of hardware_task_control is type Registers is ( REG_START, REG_STATE, REG_CYCLE_COUNT, REG_CONFIG_0, REG_CONFIG_1, REG_CONFIG_2 ); constant REG_START_POS : natural := Registers'pos( REG_START ); constant REG_STATE_POS : natural := Registers'pos( REG_STATE ); constant REG_CYCLE_COUNT_POS : natural := Registers'pos( REG_CYCLE_COUNT ); constant REG_CONFIG_0_POS : natural := Registers'pos( REG_CONFIG_0 ); constant REG_CONFIG_1_POS : natural := Registers'pos( REG_CONFIG_1 ); constant REG_CONFIG_2_POS : natural := Registers'pos( REG_CONFIG_2 ); constant REG_COUNT : natural := registers'pos( registers'right ) + 1; constant REG_ACCESS_TYPES : work.reg32.AccessArray( 0 to REG_COUNT - 1 ) := ( WRITE_ONLY, READ_ONLY, READ_ONLY, READ_WRITE, READ_WRITE, READ_WRITE ); -- Internal control and data signals 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 task_running : 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( Registers'pos( REG_CYCLE_COUNT ) ) <= ( others => '0' ); reg_data( Registers'pos( REG_CONFIG_0 ) ) <= ( others => '0' ); elsif ( rising_edge( clk ) ) then current_state <= next_state; task_start <= '0'; if ( task_state = work.task.TASK_DONE ) then task_running <= '0'; end if; case next_state is when SLAVE_IDLE => null; when SLAVE_READ => readdata <= ( others => '0' ); if ( reg_index = REG_STATE_POS ) then readdata <= to_std_logic_vector( task_state, work.reg32.word'length ); elsif ( reg_index = REG_CYCLE_COUNT_POS ) then readdata <= reg_data( REG_CYCLE_COUNT_POS ); else readdata <= reg_data( reg_index ); end if; when SLAVE_READ_DATA => null; when SLAVE_WRITE => if ( reg_index = REG_START_POS ) then task_start <= '1'; reg_data( REG_CYCLE_COUNT_POS ) <= ( others => '0' ); task_running <= '1'; else reg_data( reg_index ) <= writedata; end if; end case; if ( task_running = '1' ) then reg_data( REG_CYCLE_COUNT_POS ) <= std_logic_vector( unsigned( reg_data( REG_CYCLE_COUNT_POS ) ) + 1 ); end if; end if; end process sync; task_config <= reg_data( REG_CONFIG_0_POS to REG_CONFIG_2_POS ); end architecture rtl;