library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.task.all; entity add is port ( clk : in std_logic; reset : in std_logic; task_start : in std_logic; task_state : out work.task.State; signal_a_read : out std_logic; signal_a_readdata : in std_logic_vector( 31 downto 0 ); signal_b_read : out std_logic; signal_b_readdata : in std_logic_vector( 31 downto 0 ); signal_write : out std_logic; signal_writedata : out std_logic_vector( 31 downto 0 ) ); end entity add; architecture rtl of add is type AddState is (z0_ADD_IDLE, z1_ADD_READ_FIFO, z2_ADD_CALC, z3_ADD_STORE_RESULT); signal current_task_state : work.task.State; signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; -- Interne Signale für die Verbindung zur float_add Komponente signal internal_start : std_logic; signal internal_done : std_logic; signal internal_sum : std_logic_vector(31 downto 0); -- Signal für den internen Additions-Status signal current_calc_state : AddState; begin u_float_add : entity work.float_add port map( clk => clk, reset => reset, start => internal_start, done => internal_done, A => signal_a_readdata, B => signal_b_readdata, sum => internal_sum ); task_state_transition : process (current_task_state, task_start, index ) is begin next_task_state <= current_task_state; case current_task_state is when work.task.TASK_IDLE => if (task_start = '1') then next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => if (index = work.task.STREAM_LEN) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => if (task_start = '1') then next_task_state <= work.task.TASK_RUNNING; end if; end case; end process task_state_transition; sync : process (clk, reset) is begin if (reset = '1') then current_task_state <= work.task.TASK_IDLE; index <= 0; -- Reset current_calc_state <= z1_ADD_READ_FIFO; internal_start <= '0'; signal_a_read <= '0'; signal_b_read <= '0'; signal_write <= '0'; elsif (rising_edge(clk)) then current_task_state <= next_task_state; -- defaults für Steuersignale signal_a_read <= '0'; signal_b_read <= '0'; signal_write <= '0'; internal_start <= '0'; case next_task_state is when work.task.TASK_IDLE => index <= 0; --signal_write <= '0'; current_calc_state <= z1_ADD_READ_FIFO; -- Reset für nächsten Lauf when work.task.TASK_RUNNING => --index <= index + 1; --signal_write <= '1'; --signal_writedata <= (others => '0'); -- Sub State Machine case current_calc_state is when z1_ADD_READ_FIFO => -- Daten aus den FIFOs anfordern if (index < work.task.STREAM_LEN) then current_calc_state <= z2_ADD_CALC; end if; when z2_ADD_CALC => internal_start <= '1'; -- Warten bis float_add 'done' meldet if (internal_done = '1') then internal_start <= '0'; -- Trigger wegnehmen current_calc_state <= z3_ADD_STORE_RESULT; else -- Bleibe hier und warte current_calc_state <= z2_ADD_CALC; end if; when z3_ADD_STORE_RESULT => -- Ergebnis schreiben signal_write <= '1'; signal_writedata <= internal_sum; -- nicht in Schritt z1_ADD_READ_FIFO!! signal_a_read <= '1'; signal_b_read <= '1'; -- Index erhöhen index <= index + 1; -- Zurück zum Lesen für das nächste Paar current_calc_state <= z1_ADD_READ_FIFO; when others => current_calc_state <= z1_ADD_READ_FIFO; end case; when work.task.TASK_DONE => index <= 0; signal_write <= '0'; end case; end if; end process sync; task_state <= current_task_state; end architecture rtl;