-------EAGLE IN A RACK--------
-- Main File
-- Copyright Colin O'Flynn (c) 2004
-- see www.newae.com or e-mail me at coflynn@newae.com




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

use work.PS2_mouse.all;
use work.i2c_control.all;
use work.video_tracker.all;


--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;


entity video_board is
    Port ( 	  

--System connections
    CLK_IN     : in std_logic; ---50 MHz system clock

    nRESET_IN  : in std_logic; --Active low reset, this is connected to the Power On Reset
    						 --circuit and the front-panel reset button

    mouseOK_OUT : out std_logic; --LED that lights up when mouse is connected

    videoOK_OUT : out std_logic; --LED that lights up when video signal is OK, 
                                 --blinks when macrovision protected, and is off
                                 --when video not present

    systemOK_OUT : out std_logic; --LED that mights up when the System is A-OK
    trackOK_OUT :  out std_logic; --LED that lights up when the video track is good

--PS/2 Pointing Device (mouse, trackball)
    ps2_clk_inout  : inout std_logic;   --PS2 clock, OC
    ps2_data_inout : inout std_logic;   --PS2 data, OC

--Serial Port
    TX_out     : out std_logic;

--Video source selection connections
    VideoA     : inout std_logic; --select actual video source
    VideoB     : out std_logic; --select video blanking source
    VideoAmp   : out std_logic; --when low video amp is selected.

--Connections of TVP5145
    PCLK_in    : in std_logic; --line locked pixel clock
    PREF_in    : in std_logic; --line locked phase ref
    SCLK_in    : in std_logic; --line locked system clock at twice PCLK
    AVID_in    : in std_logic; --active video indicator
    FID_in     : in std_logic; --even/odd, 1 = odd
    PALI_in    : in std_logic; --PAL Line Indicator
    VSYNC_in   : in std_logic; --Vertical Sync
    HSYNC_in   : in std_logic; --Horizontal Sync

    UV_in		: in std_logic_vector (9 downto 0); --UV Input
    Y_in		: in std_logic_vector (9 downto 0); --Y Input
	
    SCL_inout  : inout std_logic; -- I2C Clock
    SDA_inout  : inout std_logic; -- I2C Data
    SAS_out    : out std_logic; --I2C Address Select

    TVP_Reset_out : out std_logic --inverted reset for TVP5145
    );

    attribute clkdv_divide: string; 

end video_board;

architecture structural of video_board is

                                                   
   --Reset signals (Reset = active high, nReset = active low), Reset_sig is used to create Reset and nReset 
   signal Reset, nReset, Reset_sig, nReset_sig    : std_logic;                                                                         
   
   --mouse controls
   signal x_mouse, y_mouse : std_logic_vector (9 downto 0);
   signal quadsize_vector  : std_logic_vector (7 downto 0);
   signal rightbut, leftbut: std_logic;

   --standard port pin signal buffer
   component IBUF port (i: in std_logic; o: out std_logic); 
   end component; 

   --global clock buffer
   component BUFG port (i: in std_logic; o: out std_logic); 
   end component; 

   --CLKDLL, for clock control
   component CLKDLL port (CLKIN: in std_logic; CLKFB: in std_logic; CLK0: out std_logic;
                          CLKDV: out std_logic; RST: in std_logic);
   end component;
   signal CLK0             : std_logic;
   signal CLK0_BUFG        : std_logic;

   --clock running at 1/8 the main clock speed
   signal SLOW_CLK         : std_logic;
   attribute clkdv_divide of clkdiv1 : label is "8.0";

   --used to create the blinking Video OK LED
   constant VIDEOOK_COUNTER_MAX : integer := 1562500;

   --Signals used to get the video OK light to do its stuff
   signal videook_counter : integer range 0 to VIDEOOK_COUNTER_MAX;
   signal video_macro    : std_logic;
   signal video_lock     : std_logic;


   --Buffers for clock signals that aren't on global clock pins
   signal PCLK             : std_logic;
   signal SCLK			  : std_logic;
   signal PREF			  : std_logic;
   signal HSYNC            : std_logic;
   signal AVID             : std_logic;
   signal VSYNC            : std_logic;
   signal FID              : std_logic;

   --Video source selectors
   signal VideoA_vert, VideoA_horiz : std_logic;
   signal VideoA_vertbox, VideoA_horizbox : std_logic;

   begin

   PCLK <= PCLK_in;
   SCLK <= SCLK_in;
   PREF <= PREF_in;

   --need to stop ISE from deciding that these signals are global clocks
   --and complaining when they aren't routed to global clock pins
   ibuf1: IBUF port map(i => VSYNC_IN, o => VSYNC);
   ibuf2: IBUF port map(i => HSYNC_IN, o => HSYNC); 

   --Create a low-frequency clock signal 
   clkdiv1: CLKDLL port map(CLKIN => CLK_IN, CLK0 => CLK0, CLKFB => CLK0_BUFG, RST => '0',
                           CLKDV => SLOW_CLK);  
   bufg3: BUFG port map(i => CLK0, o => CLK0_BUFG);


   process(nReset_in, SLOW_CLK)
   begin
   if (nReset_in = '0') then
   	Reset <= '1';
   elsif rising_edge(SLOW_CLK) then
   	Reset <= '0';
   end if;
   end process;

   --some things need active low reset
   nReset <= not Reset;
   
   --mapped to actual signal names in case a buffer ever needs to be inserted
   AVID <= AVID_in;
   FID <= FID_in;


   SystemOK_Out <= nReset;


   tvp_reset_out <= nRESET;

   --connect up the I2C init part that will initilize the TVP5145
   i2c_ctrl: controlchip port map (RESET_in => Reset, CLK_in => clk_in,
                  Lock_out => video_lock, Macro_out => video_macro,
                  SCL_inout => SCL_inout, SDA_inout => SDA_inout, SAS_out => SAS_out);

 --connect up the mouse controller 
ps2: mouse port map (clk_i => clk_in, rst_i => Reset, nrst_i => nReset, y_loc_o => y_mouse, 
                     x_loc_o => x_mouse, z_loc_o => quadsize_vector, mouseok_o => mouseok_out, 
				 slow_clk => slow_clk, 
				 rightbut_o => rightbut, leftbut_o => leftbut, 
                     ps2_clk_io => ps2_clk_inout, ps2_data_io => ps2_data_inout);

   --connect up the core video tracking algorithm
   track1: video_main port map (
    clk_IN => clk_in,
    slow_clk_IN => slow_clk,
    reset_IN => reset, 

    trackOK_OUT => trackOK_OUT, 

    x_mouse =>  x_mouse, 
    y_mouse =>  y_mouse,
    quadsize_vector	=> quadsize_vector,
    leftbut => leftbut,
    rightbut => rightbut,

    TX_out => TX_out, 

    VideoA => VideoA, 
    VideoB => VideoB,

    PCLK_in => PCLK,     
    PREF_in => PREF, 
    SCLK_in => SCLK, 
    AVID_in => AVID,
    FID_in => FID,
    PALI_in => PALI_in, 
    VSYNC_in => VSYNC, 
    HSYNC_in => HSYNC,

    UV_in	=> UV_in, 
    Y_in	=> Y_in
    );

    VideoAmp <= '0';

   --used to indicate what the status of the video signal is   
   process(slow_clk, video_macro, video_lock)
      begin
      if Rising_edge(slow_clk) then
         if (video_macro = '1') then
            videook_counter <= videook_counter + 1;
         elsif (video_lock = '1') then
            videook_counter <= VIDEOOK_COUNTER_MAX/2;
         else
            videook_counter <= 0;
         end if;
      end if;
   end process;

   process(videook_counter, slow_clk)
      begin
      if falling_edge(slow_clk) then
         if (videook_counter = VIDEOOK_COUNTER_MAX/2) then
            videook_out <= '1';
         elsif (videook_counter = 0) then
            videook_out <= '0';
         end if;
      end if;
   end process;

end structural;



	
