----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 12/15/2021 02:06:27 PM
-- Design Name: 
-- Module Name: updateSnake - 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;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

library ourTypes;
use ourTypes.types.all;

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

entity updateSnake is
    generic ( dataSize : integer);
    Port (
        clk : in std_logic;
        reset : in std_logic;
        
        address : out unsigned(SNAKE_ADDRESS_SIZE-1 downto 0);
        data : out std_logic_vector(dataSize-1 downto 0);
        writeEnable : out std_logic;
        
        matAddress : out unsigned(SNAKE_ADDRESS_SIZE-1 downto 0);
        matData : out unsigned(SNAKE_ADDRESS_SIZE-1 downto 0);
        matWriteEnable : out std_logic
        );
end updateSnake;

architecture Behavioral of updateSnake is
signal index : unsigned(SNAKE_ADDRESS_SIZE-1 downto 0);
signal currentSnake : pos;
signal clearRam : std_logic;
begin
process(clk,reset,clearRam,index)
begin
    if(reset = '0') then
        index <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
        clearRam <= '1';
        writeEnable <= '1';
        matWriteEnable <= '1';
    elsif(clk'event and clk = '1') then
        if(clearRam = '1') then
            index <= index + 1;
            if(index = MAX_SNAKE-1) then
                index <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
                clearRam <= '0';
                writeEnable <= '0';
                matWriteEnable <= '0';
            end if;
        end if;
    end if;
    
    if(clearRam = '1') then
        if(index = 0) then
            currentSnake.X <= to_unsigned(8,10);
            currentSnake.Y <= to_unsigned(8,9);
            currentSnake.dirX <= to_signed(1,2);
            currentSnake.dirY <= to_signed(0,2);
            currentSnake.isDefined <= '1';
            
            matAddress <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
            matData <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
        elsif(index = 1) then
            currentSnake.X <= to_unsigned(24,10);
            currentSnake.Y <= to_unsigned(8,9);
            currentSnake.dirX <= to_signed(1,2);
            currentSnake.dirY <= to_signed(0,2);
            currentSnake.isDefined <= '1';
            
            matAddress <= to_unsigned(1,SNAKE_ADDRESS_SIZE);
            matData <= to_unsigned(1,SNAKE_ADDRESS_SIZE);
        else
            currentSnake.X <= to_unsigned(0,10);
            currentSnake.Y <= to_unsigned(0,9);
            currentSnake.dirX <= to_signed(0,2);
            currentSnake.dirY <= to_signed(0,2);
            currentSnake.isDefined <= '0';
            
            matAddress <= to_unsigned(10,SNAKE_ADDRESS_SIZE);
            matData <= to_unsigned(10,SNAKE_ADDRESS_SIZE);
        end if;
    else
        index <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
        writeEnable <= '0';
        matWriteEnable <= '0';
        matAddress <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
        matData <= to_unsigned(0,SNAKE_ADDRESS_SIZE);
        
        currentSnake.X <= to_unsigned(0,10);
        currentSnake.Y <= to_unsigned(0,9);
        currentSnake.dirX <= to_signed(0,2);
        currentSnake.dirY <= to_signed(0,2);
        currentSnake.isDefined <= '0';
    end if;
end process;

data <= to_stdlogicvector(currentSnake);
address <= index;
end Behavioral;
