library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity scan is
    Port ( clk : in STD_LOGIC;
           start : in STD_LOGIC;
           t_finish : in STD_LOGIC;
           max_found : in STD_LOGIC;
           adder_enable : out STD_LOGIC;
           delay_enable : out STD_LOGIC;
           scan_finish : out STD_LOGIC;
           address_0 : out STD_LOGIC_VECTOR (8 downto 0);
	       address_1 : out STD_LOGIC_VECTOR (8 downto 0);
           address_2 : out STD_LOGIC_VECTOR (8 downto 0);
	       address_3 : out STD_LOGIC_VECTOR (8 downto 0);
	   
           control_ram : out STD_LOGIC;
           get_max : out STD_LOGIC;
           ram_address : out STD_LOGIC_VECTOR (9 downto 0));
end scan;

architecture behavior of scan is
  type STATES is (IDLE, DELAY, SUM, DEGREE);
  type CYCLES is array (0 to 119) of integer;--total angles 
  signal state : STATES := IDLE;
  signal cycle : integer := 300;--(2,4,6,0,6,4,2);--400
  --(399,297,158,0,158,297,399);--the max cycle number of delays for each DEGREE
begin
  process (clk) 
    variable i : integer := 0;
    variable j : integer := 0;
    variable k : integer := 0;
    variable r : integer := 0;
    variable maxr : integer := 0;
    variable P : integer := 0; 
    variable P_0 : integer := 1; 	
    variable P_1 : integer := 0; 
    variable P_2 : integer := 0;
    variable P_3 : integer := 0; 
	
  begin
    if (rising_edge(clk)) then
        case state is
          
          when IDLE =>
            get_max <= '0';
            control_ram <='0';
            scan_finish <= '0';
            delay_enable <='0';
            adder_enable <= '0';
            address_0 <= "000000001";
            address_1 <= "000000010";
            address_2 <= "000000011";
            address_3 <= "000000100";
            ram_address<= "0000000001";
            if (start = '1') then
              state <= DELAY;
            end if;
         
          when DELAY =>
          adder_enable <= '0';
          delay_enable <='1';
            scan_finish <= '0';
            if (start = '0') then
              state <= IDLE;
            else
              
              if (t_finish = '1') then
                if (i < cycle) then  --i smaller than the mux delay value
                  i := i + 1;
                else
                  i := 0;
                  state <= SUM;               
                end if;
              end if;
            end if;


          -- Sum
          when SUM =>              
          
          if (j < 120) and (max_found='0') then --may need adjustment,j = 3.2Mhz/27khz=118. ?? continue sum?
               
            if (start = '0') then
              state <= IDLE;
            else
              if (t_finish = '1') then
                adder_enable <= '1';--adders enable, adding amplitude for each angle after delay(align the phase for 4 micors)
                j := j + 1; 
              end if;             
            end if;

                state <= SUM; 
              else
                state <= DEGREE;
                control_ram <='1';  --store the sum value, and then find the muximum value of sum
                j := 0;        
                adder_enable <= '0';     
              end if;
          -- Move to next DEGREE 
          when DEGREE =>
            control_ram <='0';
            scan_finish <= '1';
            if (start = '0') then
              state <= IDLE;
            else
                if (k<10) then
                k:=k+1;
                else
                  k:=0;
                  if (P < 119) then  --7 angles
                    --r := r+1;--r=0,p=0 
                    P := P + 1;
                    P_0 := P_0 + 4;   --5,6,7,8  
                    state <= DELAY;        
                  else
                    P := 0;  
                    state <=IDLE;
                  end if;
                  end if;
			  --P_0 := P + 24;
			  P_1 := P_0 + 1;--6
			  P_2 := P_1 + 1;--7
			  P_3 := P_2 + 1;--8
			  
              address_0  <= std_logic_vector(to_unsigned(P_0, 9));  --change to binary of 9 bits
			  address_1  <= std_logic_vector(to_unsigned(P_1, 9));
              address_2  <= std_logic_vector(to_unsigned(P_2, 9));
			  address_3  <= std_logic_vector(to_unsigned(P_3, 9));
              
            end if;   
                                                  
        end case;
    end if;
  end process;
end behavior;


