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

entity vid_interface is 

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 vid_interface;

architecture vid_arch of vid_interface is

	component itu_r656_decoder is
		port (
			CLOCK : in std_logic;   
			TD_D : in std_logic_vector(7 downto 0);    
			TD_HS,  
			TD_VS : in std_logic;   
			
			blank : out std_logic;
			Y,      
			Cb,     
			Cr : out std_logic_vector(7 downto 0);    
			HSx2 : out std_logic;
			VSx1 : out std_logic 
		);
	end component;

	component YCbCr2RGB is
		port (
			Red, 
			Green,
			Blue : out std_logic_vector(9 downto 0);
			iY,
			iCb,
			iCr : in std_logic_vector(7 downto 0);			
			iRESET : in std_logic;
			iCLK : in std_logic
		);
	end component;
	
	signal h_counter: unsigned(15 downto 0);
	signal v_counter: unsigned(15 downto 0);
	
	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 vs_sig : std_logic;
	signal blank_sig : std_logic;

begin

	itu: itu_r656_decoder 
	port map(
			CLOCK => clk27,
			TD_D => TD_DATA,
			TD_HS => TD_HS,
			TD_VS => TD_VS,			
			blank => blank_sig,
			Y => Y_sig,
			Cb => Cb_sig,
			Cr => Cr_sig,
			HSx2 => hs2_sig,
			VSx1 => vs_sig
	);
	
	YCbCr2RGB01: YCbCr2RGB 
	port map(
			Red => R_sig,
			Green => G_sig,
			Blue => B_sig,
			iY => Y_sig,
			iCb => Cb_sig,
			iCr => Cr_sig,
			iRESET => reset,
			iCLK => clk27
	);	
	
	GetData: process (clk27)
	begin
		if rising_edge(clk27) then
			if reset = '1' then
				data_out <= (others => '0');
				h_counter <= (others => '0');
				v_counter <= (others => '0');	
			else
				data_out <= R_sig & G_sig & B_sig;
				data_valid <= '1';
				h_counter <= h_counter + 1;
				if td_hs = '0' then
					h_counter <= x"0000";
					v_counter <= v_counter + 1;
				end if;
				if td_vs = '0' then
					v_counter <= x"0000";
				end if;								
			end if;
		end if;
	end process GetData;
	
	blank <= blank_sig;
	hs <= hs2_sig;
	vs <= vs_sig;
	page <= v_counter(0);
	write_addr <= h_counter;
	v_count <= v_counter;
	
end vid_arch;

					