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 -------------------------------------------------------------------------- -- Task-FSM -------------------------------------------------------------------------- signal current_task_state : work.task.State; signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN-1; -------------------------------------------------------------------------- -- task_start → rising edge detection -------------------------------------------------------------------------- signal task_start_d : std_logic := '0'; signal task_start_re : std_logic := '0'; -------------------------------------------------------------------------- -- float_add IP-Core -------------------------------------------------------------------------- signal fa_start : std_logic := '0'; signal fa_done : std_logic := '0'; signal fa_sum : std_logic_vector(31 downto 0); signal a_value : std_logic_vector(31 downto 0); signal b_value : std_logic_vector(31 downto 0); -------------------------------------------------------------------------- -- Calc-FSM -------------------------------------------------------------------------- type calc_state_t is ( C_IDLE, C_READ_A, C_READ_B, C_START_ADD, C_WAIT_ADD, C_WRITE_RESULT ); signal calc_state : calc_state_t := C_IDLE; begin -------------------------------------------------------------------------- task_state <= current_task_state; -------------------------------------------------------------------------- -- float_add Instanz -------------------------------------------------------------------------- u_float_add : entity work.float_add port map ( A => a_value, B => b_value, clk => clk, reset => reset, start => fa_start, done => fa_done, sum => fa_sum ); -------------------------------------------------------------------------- -- Task-FSM Übergänge -------------------------------------------------------------------------- task_state_transitions : process(current_task_state, task_start_re, index, calc_state) begin next_task_state <= current_task_state; case current_task_state is when work.task.TASK_IDLE => if task_start_re = '1' then next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => if (index = work.task.STREAM_LEN - 1) and (calc_state = C_WRITE_RESULT) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => if task_start_re = '1' then next_task_state <= work.task.TASK_RUNNING; end if; end case; end process; -------------------------------------------------------------------------- -- Sync-Prozess -------------------------------------------------------------------------- sync : process(clk, reset) begin if reset = '1' then current_task_state <= work.task.TASK_IDLE; index <= 0; task_start_d <= '0'; task_start_re <= '0'; calc_state <= C_IDLE; fa_start <= '0'; signal_a_read <= '0'; signal_b_read <= '0'; signal_write <= '0'; signal_writedata <= (others => '0'); a_value <= (others => '0'); b_value <= (others => '0'); elsif rising_edge(clk) then ------------------------------------------------------------------ -- rising edge detect ------------------------------------------------------------------ task_start_re <= task_start and not task_start_d; task_start_d <= task_start; ------------------------------------------------------------------ -- default values ------------------------------------------------------------------ fa_start <= '0'; signal_a_read <= '0'; signal_b_read <= '0'; signal_write <= '0'; ------------------------------------------------------------------ -- task-FSM state update ------------------------------------------------------------------ current_task_state <= next_task_state; ------------------------------------------------------------------ -- index update ------------------------------------------------------------------ case next_task_state is when work.task.TASK_IDLE => index <= 0; when work.task.TASK_RUNNING => if calc_state = C_WRITE_RESULT then if index < work.task.STREAM_LEN - 1 then index <= index + 1; end if; end if; when work.task.TASK_DONE => index <= 0; end case; ------------------------------------------------------------------ -- Calc-FSM ------------------------------------------------------------------ case calc_state is when C_IDLE => if current_task_state = work.task.TASK_RUNNING and index = 0 then calc_state <= C_READ_A; end if; ------------------------------------------------------------------ -- READ A in the *same cycle*: request + latch ------------------------------------------------------------------ when C_READ_A => signal_a_read <= '1'; a_value <= signal_a_readdata; calc_state <= C_READ_B; ------------------------------------------------------------------ -- READ B similarly ------------------------------------------------------------------ when C_READ_B => signal_b_read <= '1'; b_value <= signal_b_readdata; calc_state <= C_START_ADD; ------------------------------------------------------------------ when C_START_ADD => fa_start <= '1'; calc_state <= C_WAIT_ADD; when C_WAIT_ADD => fa_start <= '1'; if fa_done = '1' then calc_state <= C_WRITE_RESULT; end if; ------------------------------------------------------------------ when C_WRITE_RESULT => signal_write <= '1'; signal_writedata <= fa_sum; if index = work.task.STREAM_LEN - 1 then calc_state <= C_IDLE; else calc_state <= C_READ_A; end if; end case; end if; end process; end architecture rtl;