----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:44:50 24/12/2012 
-- Design Name: 
-- Module Name:    DDS_control - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 

----------------------------------------------------------------------------------
-- LIBRARY
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

----------------------------------------------------------------------------------

entity DDS_control is
	 Generic ( dds_data_length : natural;
				  dds_bus_width : natural
				);
	 Port ( CLK : 		  in   STD_LOGIC;		-- 20 MHz clock
			  RST : 		  in   STD_LOGIC;
           ENABLE :    in   STD_LOGIC;		-- enable (start) direct digital synthesizer
           DATA_IN :   in   STD_LOGIC_VECTOR(dds_data_length-1 downto 0);		-- data in (frequency setting)
			  RST_DDS :   out  STD_LOGIC;
			  W_CLK_DDS : out  STD_LOGIC;
			  FQ_UD_DDS : out  STD_LOGIC;		-- reset, word load clock and frequency update pins of external DDS chip
			  DATA_OUT :  out  STD_LOGIC_VECTOR(dds_bus_width-1 downto 0);			-- data out (to external DDS chip)
           READY : 	  out  STD_LOGIC		-- ready "message" back to NQR_ML505_top
			 );
end DDS_control;

architecture Behavioral of DDS_control is


----------------------------------------------------------------------------------
-- SIGNALS declaration
----------------------------------------------------------------------------------

	signal state_Reg : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');		-- signal for finite state machine



begin


	process (CLK) begin
		if rising_edge(CLK) then
			if (ENABLE = '0' or RST = '1') then
				RST_DDS <= '0';
				W_CLK_DDS <= '0';
				FQ_UD_DDS <= '0';
				DATA_OUT <= (others => '0');
				READY <= '0';
				state_Reg <= (others => '0');
			else
	
				case state_Reg is

					when "0000" =>  RST_DDS <= '1';		-- reset external DDS chip
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= (others => '0');
										 READY <= '0';
										 state_Reg <= "0001";
													
					when "0001" =>  RST_DDS <= '0';
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= DATA_IN(dds_bus_width*5-1 downto dds_bus_width*4);
										 READY <= '0';
										 state_Reg <= "0010";

					when "0010" =>  RST_DDS <= '0';		-- send word 0
										 W_CLK_DDS <= '1';
										 FQ_UD_DDS <= '0';
										 READY <= '0';
										 state_Reg <= "0011";
									  
					when "0011" =>  RST_DDS <= '0';
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= DATA_IN(dds_bus_width*4-1 downto dds_bus_width*3);
										 READY <= '0';
										 state_Reg <= "0100";	

					when "0100" =>  RST_DDS <= '0';		-- send word 1
										 W_CLK_DDS <= '1';
										 FQ_UD_DDS <= '0';
										 READY <= '0';
										 state_Reg <= "0101";
										
					when "0101" =>  RST_DDS <= '0';
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= DATA_IN(dds_bus_width*3-1 downto dds_bus_width*2);
										 READY <= '0';
										 state_Reg <= "0110";	

					when "0110" =>  RST_DDS <= '0';		-- send word 2
										 W_CLK_DDS <= '1';
										 FQ_UD_DDS <= '0';
										 READY <= '0';
										 state_Reg <= "0111";
										
					when "0111" =>  RST_DDS <= '0';
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= DATA_IN(dds_bus_width*2-1 downto dds_bus_width);
										 READY <= '0';
										 state_Reg <= "1000";	

					when "1000" =>  RST_DDS <= '0';		-- send word 3
										 W_CLK_DDS <= '1';
										 FQ_UD_DDS <= '0';
										 READY <= '0';
										 state_Reg <= "1001";
										 
					when "1001" =>  RST_DDS <= '0';
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 DATA_OUT <= DATA_IN(dds_bus_width-1 downto 0);
										 READY <= '0';
										 state_Reg <= "1010";	

					when "1010" =>  RST_DDS <= '0';		-- send word 4
										 W_CLK_DDS <= '1';
										 FQ_UD_DDS <= '0';
										 READY <= '0';
										 state_Reg <= "1011";
										 
					when "1011" =>  RST_DDS <= '0';		-- send update frequency signal
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '1';
										 READY <= '0';
										 state_Reg <= "1100";
										 
					when "1100" =>  RST_DDS <= '0';		-- send READY "message" back to NQR_ML505_top
										 W_CLK_DDS <= '0';
										 FQ_UD_DDS <= '0';
										 READY <= '1';
										 state_Reg <= "1100";
										
					when others =>  state_Reg <= (others => '0');
									
				end case;
		
			end if;
		end if;
	end process;



end Behavioral;

