----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:   
-- Design Name: 
-- Module Name:    inc_xifen - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all


entity inc_xifen is
    Port ( clk : in  STD_LOGIC;
           reset : in  STD_LOGIC;
			  start : in std_logic;
			  sin_adc: in std_logic_vector(11 downto 0);
			  cos_adc: in std_logic_vector(11 downto 0);
			  comm_voltage :in std_logic_vector(11 downto 0);			-- chu chang ce shi fu zhi 
			  dividend : out std_logic_vector(20 downto 0);				-- shift 8bits
			  dividsor : out std_logic_vector(11 downto 0);
--			  inc_lut_addr: out std_logic_vector(7 downto 0);	
			  inc_interpolation_lut: in std_logic_vector(10 downto 0);	
			  inc_interpolation_result: out std_logic_vector(10 downto 0);	
			  
--			  ttl_lut: out std_logic_vector(10 downto 0);	
			  inc_data_ready: in std_LOGIC;
			  divider_clk_en : out std_LOGIC;
--			  ttl_lut: in  std_logic_vector(1 downto 0);
--			  ttl_ab: out  std_logic_vector(1 downto 0)
			  inc_interpolation_done : out std_LOGIC
				);


end inc_xifen;

architecture Behavioral of inc_xifen is
type state is (idle,st0,st1,st2,st3,st4,st5,st6,st7);

-------------------reg-------------------
signal S_state_reg : state :=idle;
signal S_sin_adc_reg : unsigned(11 downto 0):=(others=>'0');
signal S_cos_adc_reg : unsigned(11 downto 0):=(others=>'0');
signal S_comm_voltage_reg : unsigned(11 downto 0):=(others=>'0');
signal S_dividend_reg : unsigned(20 downto 0):=(others=>'0');
signal S_dividsor_reg : unsigned(11 downto 0):=(others=>'1');
--signal S_inc_lut_addr_reg : unsigned(7 downto 0):=(others=>'0');
signal S_counter_reg : unsigned(4 downto 0):=(others=>'0');
signal S_inc_interpolation_lut_reg : unsigned(7 downto 0):=(others=>'0');
signal S_inc_interpolation_result_reg : unsigned(7 downto 0):=(others=>'0');
signal S_xiangxian_reg : std_logic_vector(2 downto 0):=(others=>'0');
signal S_divider_clk_en_reg: std_logic:='0';
signal S_ttl_ab_reg : std_logic_vector(1 downto 0):=(others=>'0');
signal S_inc_interpolation_done_reg: std_logic:='0';

-------------------reg-------------------


-------------------next-------------------
signal S_state_next : state :=idle;
signal S_sin_adc_next : unsigned(11 downto 0):=(others=>'0');
signal S_cos_adc_next : unsigned(11 downto 0):=(others=>'0');
signal S_comm_voltage_next : unsigned(11 downto 0):=(others=>'0');
signal S_dividend_next : unsigned(20 downto 0):=(others=>'0');
signal S_dividsor_next : unsigned(11 downto 0):=(others=>'1');
--signal S_inc_lut_addr_next : unsigned(7 downto 0):=(others=>'0');
signal S_counter_next : unsigned(4 downto 0):=(others=>'0');
signal S_inc_interpolation_lut_next : unsigned(7 downto 0):=(others=>'0');
signal S_inc_interpolation_result_next : unsigned(7 downto 0):=(others=>'0');
signal S_xiangxian_next : std_logic_vector(2 downto 0):=(others=>'0');
signal S_divider_clk_en_next: std_logic:='0';
signal S_ttl_ab_next : std_logic_vector(1 downto 0):=(others=>'0');
signal S_inc_interpolation_done_next: std_logic:='0';
-------------------reg-------------------



begin
p_reg1: process(clk,reset)
begin
	if reset='0' then
		S_state_reg<=idle;
		S_sin_adc_reg <=(others=>'0');
		S_cos_adc_reg <=(others=>'0');
		S_comm_voltage_reg <=(others=>'0');
		S_dividend_reg <=(others=>'0');
		S_dividsor_reg <=(others=>'0');
--		S_inc_lut_addr_reg <=(others=>'0');
		S_inc_interpolation_lut_reg <=(others=>'0');
		S_counter_reg<=(others=>'0');	
		S_divider_clk_en_reg<='0';
		S_ttl_ab_reg<="00";
		S_inc_interpolation_done_reg<='0';
	elsif rising_edge(clk)then

		S_state_reg<=S_state_next;
		S_sin_adc_reg <=S_sin_adc_next;
		S_cos_adc_reg <=S_cos_adc_next;
		S_comm_voltage_reg <=S_comm_voltage_next;
		S_dividend_reg <=S_dividend_next;
		S_dividsor_reg <=S_dividsor_next;
--		S_inc_lut_addr_reg <=S_inc_lut_addr_next;
		S_inc_interpolation_lut_reg <=S_inc_interpolation_lut_next;
		S_counter_reg<=S_counter_next;
		S_xiangxian_reg<=S_xiangxian_next;
		S_divider_clk_en_reg<=S_divider_clk_en_next;
		S_ttl_ab_reg<=S_ttl_ab_next;
		S_inc_interpolation_result_reg<=S_inc_interpolation_result_next;
		S_inc_interpolation_done_reg<=S_inc_interpolation_done_next;
	end if;


end process p_reg1;



p_reg2: process(S_state_reg,S_sin_adc_reg,S_cos_adc_reg,S_comm_voltage_reg,S_dividend_reg,S_dividsor_reg,
S_counter_reg,inc_data_ready,S_xiangxian_reg,S_divider_clk_en_reg,
S_inc_interpolation_lut_reg,S_inc_interpolation_result_reg
)
begin
	 S_state_next<=S_state_reg;
	 S_sin_adc_next<=S_sin_adc_reg;
	 S_cos_adc_next<=S_cos_adc_reg;
	 S_comm_voltage_next<=S_comm_voltage_reg;
	 S_dividend_next<=S_dividend_reg;
	 S_dividsor_next<=S_dividsor_reg;
--	 S_inc_lut_addr_next<=S_inc_lut_addr_reg;
	 S_counter_next<=S_counter_reg;
	 S_xiangxian_next<=S_xiangxian_reg;
	 S_inc_interpolation_lut_next<=S_inc_interpolation_lut_reg;
	 S_divider_clk_en_next<=S_divider_clk_en_reg;
	 S_ttl_ab_next<=S_ttl_ab_reg;
	 S_inc_interpolation_result_next<=S_inc_interpolation_result_reg;
	 S_inc_interpolation_done_next<='0';
	 if  Start='0' then
		S_state_next<=idle;
		S_divider_clk_en_next<='0';
		S_inc_interpolation_done_reg<='0';
	 end if;
	case S_state_reg is
		when idle =>
			if Start='1' then
				S_comm_voltage_next<=unsigned(comm_voltage);
				S_state_next<=st0;				
			end if;
		when st0 =>
			if inc_data_ready ='1' then
				S_sin_adc_next<=unsigned(sin_adc);
				S_cos_adc_next<=unsigned(cos_adc);
				S_state_next<=st1;
			end if;
		when st1 =>
			if S_sin_adc_reg>S_comm_voltage_reg then
				S_sin_adc_next<=S_sin_adc_reg - S_comm_voltage_reg;
				S_xiangxian_next(0)<='0';
			else
				S_sin_adc_next<=S_comm_voltage_reg -S_sin_adc_reg ;
				S_xiangxian_next(0)<='1';
			end if;
			
			if S_cos_adc_reg>S_comm_voltage_reg then
				S_cos_adc_next<=S_cos_adc_reg - S_comm_voltage_reg;
				S_xiangxian_next(1)<='0';
			else
				S_cos_adc_next<=S_comm_voltage_reg -S_cos_adc_reg ;
				S_xiangxian_next(1)<='1';
			
			end if;			
			S_state_next<=st2;

		when st2=>
			if S_sin_adc_reg>S_cos_adc_reg then
				S_xiangxian_next(2)<='1';
				S_dividend_next<=S_cos_adc_reg&"00000000" ;
				S_dividsor_next<=S_sin_adc_reg;
			else	
				S_xiangxian_next(2)<='0';
				S_dividend_next<=S_sin_adc_reg&"00000000" ;
				S_dividsor_next<=S_cos_adc_reg;				
				
			end if;
			S_state_next<=st3;
			
		when st3 =>
			if S_xiangxian_next(2)='1' then

				S_dividend_next<=S_dividend_reg - S_cos_adc_reg ;

			else	

				S_dividend_next<=S_dividend_reg - S_sin_adc_reg ;			
				
			end if;
			S_state_next<=st4;
		
		
		
		when st4 =>
			if S_xiangxian_next(2)='1' then

				S_dividend_next<=S_dividend_reg + S_sin_adc_reg(11 downto 1) ;

			else	

				S_dividend_next<=S_dividend_reg + S_cos_adc_reg(11 downto 1) ;			
				
			end if;
			S_divider_clk_en_next<='1';
			S_counter_next<=(others=>'0');
			S_state_next<=st5;		
		
		when st5 =>
			if S_counter_reg=7 then				--
				S_counter_next<=(others=>'0');
--				S_ttl_ab_next<=ttl_ab;
				S_inc_interpolation_lut_next<=unsigned(inc_interpolation_lut);
				S_divider_clk_en_next<='0';
				S_state_next<=st6;
			else	
				S_counter_next<=S_counter_reg + 1;
			end if;
		when st6 =>
			case S_xiangxian_reg is 
				when "000" =>  		-- |sin|<|cos|  cos>0  sin>0    qu jian 1
					null;
				
				when "001"=>			--|sin|<|cos|   cos>0  sin<0  qu jian 8
					S_inc_interpolation_result_next<="11111010000" - S_inc_interpolation_lut_reg;
				
				when "010" =>			--|sin|<|cos|   cos<0  sin>0  qu jian 4
					S_inc_interpolation_result_next<="01111101000" - S_inc_interpolation_lut_reg;
				
				when "011"=>			--|sin|<|cos|   cos<0  sin<0  qu jian 5
					S_inc_interpolation_result_next<="01111101000" + S_inc_interpolation_lut_reg;

				when "100" =>			--|sin|>|cos|   cos>0  sin>0  qu jian 2
					S_inc_interpolation_result_next<="00111110100" - S_inc_interpolation_lut_reg;
				
				when "101"=>			--|sin|>|cos|   cos>0  sin<0  qu jian 7
					S_inc_interpolation_result_next<="10111011100" + S_inc_interpolation_lut_reg;
				
				when "110" =>			--|sin|>|cos|   cos<0  sin>0  qu jian 3
					S_inc_interpolation_result_next<="00111110100" + S_inc_interpolation_lut_reg;
				
				when "111"=>			--|sin|>|cos|   cos<0  sin<0  qu jian 6

					S_inc_interpolation_result_next<="10111011100" - S_inc_interpolation_lut_reg;
				
				when others =>
					null;
			end case;
			S_inc_interpolation_done_next<='1';
			S_state_next<=st0;		
		when others =>
			null;
	end case;
end process p_reg2;


dividend<=std_logic_vector(S_dividend_reg);
dividsor<=std_logic_vector(S_dividsor_reg);
--inc_lut_addr<=S_inc_lut_addr_reg;
divider_clk_en<=S_divider_clk_en_reg;
--ttl_ab<=S_ttl_ab_reg;
inc_interpolation_result<=std_logic_vector(S_inc_interpolation_result_reg);
inc_interpolation_done<=S_inc_interpolation_done_reg;
end Behavioral;
