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; phase : in work.reg32.word; amplitude : in work.reg32.word; 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; signal angle_calc : signed(31 downto 0); signal angle_busy : std_logic; signal angle_valid : std_logic; signal angle_result : signed(31 downto 0); signal START : std_logic; signal angle_amplitude : reg32.word; type angle_matrix is ARRAY(natural range<>) of signed; signal angle_lut : angle_matrix (31 downto 0) (31 downto 0); angle_lut(0) <= "0"; angle_lut(1) <= "138547331"; angle_lut(2) <= "277094662"; angle_lut(3) <= "415641993"; angle_lut(4) <= "554189324"; angle_lut(5) <= "692736655"; angle_lut(6) <= "831283986"; angle_lut(7) <= "969831317"; angle_lut(8) <= "1108378649"; angle_lut(9) <= "1246925980"; angle_lut(10) <= "1385473311"; angle_lut(11) <= "1524020642"; angle_lut(12) <= "1662567973"; angle_lut(13) <= "1801115304"; angle_lut(14) <= "1939662635"; angle_lut(15) <= "2078209966"; angle_lut(16) <= "2216757298"; angle_lut(17) <= "2355304629"; angle_lut(18) <= "2493851960"; angle_lut(19) <= "2632399291"; angle_lut(20) <= "2770946622"; angle_lut(21) <= "2909493953"; angle_lut(22) <= "3048041284"; angle_lut(23) <= "3186588615"; angle_lut(24) <= "3325135947"; angle_lut(25) <= "3463683278"; angle_lut(26) <= "3602230609"; angle_lut(27) <= "3740777940"; angle_lut(28) <= "3879325271"; angle_lut(29) <= "4017872602"; angle_lut(30) <= "4156419933"; angle_lut(31) <= "4294967265"; type AngleState is ( ANGLE_IDLE, ANGLE_SET_SIGNALS, ANGLE_RUNNING, ANGLE_DONE ); signal current_angle_state : AngleState; signal next_angle_state : AngleState; begin f1:ENTITY work.float_sine PORT MAP(CLK => CLK, RESET => RESET, data_valid => START, angle =>angle_calc, busy => angle_busy, result_valid => angle_valid, sine => angle_result); 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 - 1 ) 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_transitions; sync : process ( clk, reset ) 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; when work.task.TASK_RUNNING => if(current_angle_state = ANGLE_DONE) then index <= index + 1; end if; when work.task.TASK_DONE => index <= 0; end case; end if; end process sync; end process sync; task_state <= current_task_state; angle_state_transitions : process ( current_angle_state, angle_valid, current_angle_state) begin next_angle_state <= current_angle_state; case current_angle_state is when ANGLE_IDLE => if(current_angle_state = work.task.TASK_RUNNING) then next_angle_state <= ANGLE_SET_SIGNALS; end if; when ANGLE_SET_SIGNALS => next_angle_state <= ANGLE_RUNNING; when ANGLE_RUNNING => if(angle_valid = '1') then next_angle_state <= ANGLE_DONE; end if; when ANGLE_DONE => next_angle_state <= angle_IDLE; end case; end process angle_state_transitions; angle_calc : process (clk, reset) is begin if ( reset = '1' ) then current_angle_state <= ANGLE_IDLE; elsif ( rising_edge( clk ) ) then current_ANGLE_state <= next_angle_state; case next_angle_state is when ANGLE_IDLE => START <= '0'; signal_write <= '0'; when ANGLE_SET_SIGNALS => angle = i when ANGLE_RUNNING => START <= '1'; when ANGLE_DONE => START <= '0'; signal_write <= '1'; end case; end if; end process add; end architecture rtl;