signal_processing_vorlage/hardware/system/hardware_task_control.vhd
Johannes Kutning 0d1b73e3e0 Initial commit
2023-10-31 07:47:27 +01:00

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;