----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date: 19.10.2017 08:01:54
-- Design Name: 
-- Module Name: VGA_top - 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;

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

library ourTypes;
use ourTypes.types.all;

entity VGA_top is
    Port ( H125MHz : in STD_LOGIC;
           resetGeneral : in std_logic;
           led0 : out std_logic;
           vga_hs : out STD_LOGIC;
           vga_vs : out STD_LOGIC;
           vga_r : out STD_LOGIC_VECTOR (4 downto 0);
           vga_g : out STD_LOGIC_VECTOR (5 downto 0);
           vga_b : out STD_LOGIC_VECTOR (4 downto 0));
end VGA_top;

architecture Behavioral of VGA_top is

component clk_wiz_0
port
 (-- Clock in ports
  clk_in1           : in     std_logic;
  -- Clock out ports
  clk_out1          : out    std_logic
 );
end component;

ATTRIBUTE SYN_BLACK_BOX : BOOLEAN;
ATTRIBUTE SYN_BLACK_BOX OF clk_wiz_0 : COMPONENT IS TRUE;

ATTRIBUTE BLACK_BOX_PAD_PIN : STRING;
ATTRIBUTE BLACK_BOX_PAD_PIN OF clk_wiz_0 : COMPONENT IS "clk_in1,clk_out1";

component GeneSync is
    Port ( CLK   : in std_logic;
           HSYNC : out std_logic;
           VSYNC : out std_logic;
		   IMG   : out std_logic;
           X     : out std_logic_vector(9 downto 0);
           Y     : out std_logic_vector(8 downto 0));
end component;

component GeneRGB_V1  is
    Port ( 
	       X     : in unsigned(9 downto 0);
           Y     : in unsigned(8 downto 0);
           IMG   : in std_logic;
		   R     : out std_logic_vector(4 downto 0);
           G     : out std_logic_vector(5 downto 0);
           B     : out std_logic_vector(4 downto 0);
           snakePresent : in std_logic);
end component;

component Gene_Snake
generic ( addressSize : integer:=SNAKE_ADDRESS_SIZE);
Port ( X : in unsigned (9 downto 0);
       Y : in unsigned (8 downto 0);
       currentSnake : in pos;
       clk: in std_logic;
       updateOrder : in std_logic;
       reset: in std_logic;
       snakePresent : out std_logic;
       currentAddress : out unsigned(SNAKE_ADDRESS_SIZE-1 downto 0));
end component Gene_Snake;

component snakeRam
generic (length : integer:=1200; --30x40=1200, taille max du snake
        addressSize : integer:=11 --ln(1200)/ln(2)>10 on prend 11
);
Port ( address : in unsigned(addressSize-1 downto 0);
       data : inout pos;
       writeEnable : in STD_LOGIC;
       clk : in STD_LOGIC);
end component snakeRam;

component Diviseur
  generic (nbBits : integer:=8);
  Port (  clk_in : in STD_LOGIC;
          reset : in STD_LOGIC;
          max : in unsigned (nbBits-1 downto 0);
          clk_out : out STD_LOGIC);
end component Diviseur;

signal Xi          : std_logic_vector(9 downto 0);
signal Yi          : std_logic_vector(8 downto 0);
signal Xpxl        : unsigned(9 downto 0);
signal Ypxl        : unsigned(8 downto 0);
signal IMGi        : std_logic;  
signal pxl_clk     : std_logic;

signal clk_lente: std_logic;
signal valPosX: unsigned (9 downto 0);
signal valPosY: unsigned (8 downto 0);
signal valSnakePresent: std_logic;

signal displayRAMAddress : unsigned(SNAKE_ADDRESS_SIZE-1 downto 0);
signal displayRAMData : pos;

signal clk_latch : std_logic;

begin

Xpxl <= unsigned(Xi);
Ypxl <= unsigned(Yi);

U0 : clk_wiz_0
   port map ( 
   -- Clock in ports
   clk_in1 => H125MHz,
  -- Clock out ports  
   clk_out1 => pxl_clk              
 );
 
U1 : GeneSync 
    port map(
    CLK    => pxl_clk,
    HSYNC  => vga_hs,
    VSYNC  => vga_vs,
    IMG    => IMGi,
	X      => Xi,
    Y      => Yi);
	 
U2 : GeneRGB_V1  
    port map(
	X     => Xpxl,
    Y     => Ypxl,
    IMG   => IMGi,
    R     => vga_r,
    G     => vga_g,
    B     => vga_b,
    snakePresent => valSnakePresent);
    
U3 : Diviseur
    -- pxl_clock 25MHz, clk_lente ~60Hz, 1 coup sur clk_lente = 25e6/60 = 4.2e5 coups sur pxl_clk. ln(4.2e5)/ln(2)=18.6, donc on prend 19bits
    generic map (nbBits => 19)
    port map (
      clk_in => pxl_clk,
      reset => resetGeneral,
      max => to_unsigned(420000,19),
      clk_out => clk_lente
    );
    
U4 : Gene_Snake
    port map (
      X => Xpxl,
      Y => Ypxl,
      currentSnake => displayRamData,
      clk => H125Mhz,
      updateOrder => pxl_clk,
      reset => resetGeneral,
      snakePresent => valSnakePresent,
      currentAddress => displayRamAddress
    );
    
U5 : snakeRAM
    port map (
        address => displayRAMAddress,
        data => displayRAMdata,
        writeEnable => '0',
        clk => H125Mhz
    );

process(clk_lente,clk_latch)
begin
if(clk_lente'event and clk_lente = '1') then
    clk_latch <= clk_latch xor '1';
end if;
end process;
led0 <= clk_latch;
end Behavioral;
