library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ntsc2vga is

port (
	clk25	: in std_logic;
	clk27	: in std_logic;
	clk50	: in std_logic;
	reset	: in std_logic;
	
	-- signals from TV decoder
	td_data : in std_logic_vector(7 downto 0);
	td_hs	: in std_logic;
	td_vs	: in std_logic;
	
	-- signals to VGA
	VGA_CLK,                         -- Clock
    VGA_HS,                          -- H_SYNC
    VGA_VS,                          -- V_SYNC
    VGA_BLANK,                       -- BLANK
    VGA_SYNC : out std_logic;        -- SYNC
    VGA_R,                           -- Red[9:0]
    VGA_G,                           -- Green[9:0]
    VGA_B : out unsigned(9 downto 0); -- Blue[9:0]

	hcount: out unsigned(15 downto 0);
	vcount: out unsigned(15 downto 0)
    
);
end ntsc2vga;

architecture rtl of ntsc2vga is
	
	component vid_interface
		port (
			clk27:	in std_logic;
			reset:	in std_logic;

			-- output from video interface
			data_out:	out std_logic_vector(29 downto 0);
			data_valid: out std_logic;						
			page:	out std_logic;
			hs, vs: out std_logic;
			blank : out std_logic;
			write_addr: out unsigned(15 downto 0);
			v_count: out unsigned(15 downto 0);

			-- input from the ADV7181 decoder
			td_data:	in std_logic_vector(7 downto 0);
			td_hs:	in std_logic;
			td_vs:	in std_logic
		);
	end component;
	
	component TV_to_VGA is
		port (
			OSC_27 : in std_logic;   
			RESET : in std_logic;
			TD_VS : in std_logic;
			TD_HS : in std_logic;
			HSx2 : in std_logic;
			VGA_BLANK : out std_logic;   			
			VGA_SYNC : out std_logic;
			VGA_HS : out std_logic;
			VGA_VS : out std_logic
		);
	end component;
	
	component line_buffer
		  port (
			reset	  : in std_logic;
			wclk	  : in std_logic;
			rclk	  : in std_logic;
			write_enable  : in std_logic;
			rgb	  : in std_logic_vector(29 downto 0);
			write_address : in unsigned(15 downto 0);
			read_data	  : out std_logic_vector(29 downto 0);
			read_address  : in unsigned(15 downto 0);
			-- page = 0: write to line1, read from line2
			-- page = 1: write to line2, read from line1
			page          : in std_logic
			);
	end component;
	
	component vga_controller
		port (    
			reset : in std_logic;
			clk   : in std_logic;                    -- Should be 25.125 MHz  
			rgb : in std_logic_vector(29 downto 0); 
			hs_in : in std_logic;
			vs_in : in std_logic;
			sync_in : in std_logic;
			blank_in : in std_logic;
			line_sel : out std_logic;
			buffer_read_addr : out unsigned(15 downto 0);
			VGA_CLK,                         -- Clock
			VGA_HS,                          -- H_SYNC
			VGA_VS,                          -- V_SYNC
			VGA_BLANK,                       -- BLANK
			VGA_SYNC : out std_logic;        -- SYNC
			VGA_R,                           -- Red[9:0]
			VGA_G,                           -- Green[9:0]
			VGA_B : out unsigned(9 downto 0) -- Blue[9:0]
		);
	end component;
	
	signal yuv_sig	: std_logic_vector(15 downto 0);
	
	signal vid_out : std_logic_vector(29 downto 0);
	signal page_sig : std_logic;
	signal write_en : std_logic;
	signal w_addr : unsigned(15 downto 0);
	signal v_count_sig : unsigned(15 downto 0);
	signal buff_out : std_logic_vector(29 downto 0);
	signal read_addr : unsigned(15 downto 0);
	signal hs_sig : std_logic;
	signal vs_sig : std_logic;
	signal sync_sig : std_logic;
	signal blank_sig : std_logic;
	signal line_sig : std_logic;
	
	-- new signals
	signal Y_sig : std_logic_vector(7 downto 0);
	signal Cb_sig : std_logic_vector(7 downto 0);
	signal Cr_sig : std_logic_vector(7 downto 0);
	
	signal R_sig : std_logic_vector(9 downto 0);
	signal G_sig : std_logic_vector(9 downto 0);
	signal B_sig : std_logic_vector(9 downto 0);
	
	signal hs2_sig : std_logic;
	signal hs_block : std_logic;
	signal vs_block : std_logic;
	signal blank_block : std_logic;
	signal sync_block : std_logic;
		
begin 
	
	vid1: vid_interface
	port map(
			clk27 => clk27,
			reset => reset,
			data_out => vid_out,
			page => page_sig,
			write_addr => w_addr,
			v_count => v_count_sig,
			data_valid => write_en,
			hs => hs2_sig,
			vs => vs_block,
			blank => VGA_BLANK,
			td_data => td_data,
			td_hs => td_hs,
			td_vs => td_vs
	);
	
	tv1: TV_to_VGA
	port map(
			OSC_27 => clk27,
			RESET => reset,
			TD_VS => td_vs,
			TD_HS => td_hs,
			HSx2 => hs2_sig,
			VGA_BLANK => blank_sig,
			VGA_SYNC => sync_sig,
			VGA_HS => hs_sig,
			VGA_VS => vs_sig
	);
	vga1: vga_controller
	port map(
			reset => reset,
			clk => clk27,
			rgb => buff_out,
			buffer_read_addr => read_addr,
			hs_in => hs_sig,
			vs_in => vs_sig,
			sync_in => sync_sig,
			blank_in => blank_sig,
			line_sel => line_sig,
			VGA_CLK => VGA_CLK,                        
			VGA_HS => VGA_HS,                          
			VGA_VS => VGA_VS,                          
			VGA_BLANK => blank_block,                       
			VGA_SYNC => VGA_SYNC,
			VGA_R => VGA_R,                           
			VGA_G => VGA_G,                           
			VGA_B => VGA_B
	);			
	
	buffer1: line_buffer
	port map(
			reset => reset,
			wclk => clk27,
			rclk => clk50,
			write_enable => '1',
			rgb => vid_out,
			write_address => w_addr,
			read_data => buff_out,
			read_address => read_addr,
			page => page_sig
	);	
	
	hcount <= w_addr;
	vcount <= v_count_sig;
	
end rtl;


