138 lines
4.1 KiB
VHDL
138 lines
4.1 KiB
VHDL
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;
|
|
|