library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.float.all; use work.task.all; entity sine is port ( clk : in std_logic; reset : in std_logic; task_start : in std_logic; task_state : out work.task.State; step_size : in work.reg32.word; --Parameter, übergeben aus task_sine phase : in work.reg32.word; --Parameter, übergeben aus task_sine amplitude : in work.reg32.word; --Parameter, übergeben aus task_sine signal_write : out std_logic; signal_writedata : out std_logic_vector( 31 downto 0 ) ); end entity sine; architecture rtl of sine is signal current_task_state : work.task.State; signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; --own signals: signal data_valid : std_logic; signal busy : std_logic; signal angle : signed(31 downto 0); signal result_valid : std_logic; signal sine_value : signed(31 downto 0); signal output_value : signed(31 downto 0); signal output_flag : std_logic; --signal exp : signed(7 downto 0); --signal tmp : signed(7 downto 0); ---State machine ---------------------------------- TYPE State_type IS (A, B, C, D); -- Define the states SIGNAL State : State_Type; -- Create a signal that uses -- the different states begin u_float_sine : entity work.float_sine generic map ( ITERATIONS => 8 ) port map( clk => clk, reset => reset, data_valid => data_valid, angle => angle, busy => busy, result_valid => result_valid, sine => sine_value ); PROCESS (clk, reset) BEGIN If (reset = '1') THEN --RESET: State to A data_valid <= '0'; output_flag <= '0'; angle <= x"00000000";--x"1FFFFFFF"; State <= A; ELSIF rising_edge(clk) THEN -- if there is a rising edge of the -- clock, then do the stuff below -- The CASE statement checks the value of the State variable, -- and based on the value and any other control signals, changes -- to a new state. CASE State IS -- If the current state is A and P is set to 1, then the -- next state is B WHEN A => --set data_valid to 1 for one clock cycle IF index = 0 THEN angle <= signed(phase); ELSE --angle <= angle;--x"1FFFFFFF"; --debug: 1,5 --> should result in sin() = 1 END IF; IF data_valid ='0' AND current_task_state = TASK_RUNNING THEN data_valid <= '1'; State <= B; END IF; -- If the current state is B and P is set to 1, then the -- next state is C WHEN B => IF data_valid ='1' THEN data_valid <= '0'; State <= C; END IF; -- If the current state is C and P is set to 1, then the -- next state is D WHEN C => IF result_valid = '1' AND busy = '0' THEN --sine_value <= sine; output_flag <= '1'; data_valid <= '0'; angle <= angle + signed(step_size); --winkel neu zuweisen State <= D; END IF; -- If the current state is D and P is set to 1, then the -- next state is B. -- If the current state is D and P is set to 0, then the -- next state is A. WHEN D=> IF data_valid = '0' THEN output_flag <= '0'; State <= A; --ELSE --State <= A; END IF; --WHEN others => --State <= A; END CASE; END IF; END PROCESS; --end of state machine______________________________________ --do not change task_state_transitions : 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 -- changed from index = work.task.STREAM_LEN - 1 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_transitions; --end of no not change sync : process ( clk, reset , signal_writedata) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; elsif ( rising_edge( clk ) ) then current_task_state <= next_task_state; case next_task_state is when work.task.TASK_IDLE => index <= 0; signal_write <= '0'; when work.task.TASK_RUNNING => --output: IF output_flag = '1' THEN index <= index + 1; signal_write <= '1'; output_value <= sine_value; output_value(30 downto 23) <= sine_value(30 downto 23) + (signed(amplitude(30 downto 23)) - 127); --change from +2 to correct exponent --wenn 1: +0, wenn 2: +1, wenn 4:2, wenn 8: 3 = Bit ELSE signal_write <= '0'; END IF; --signal_writedata <= std_logic_vector(to_unsigned(2, signal_writedata'length)); --test when work.task.TASK_DONE => index <= 0; signal_write <= '0'; end case; end if; end process sync; task_state <= current_task_state; signal_writedata <= std_logic_vector(output_value);--x"40800000";--( others => '0' ); end architecture rtl;