-- 

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE ieee.std_logic_unsigned.all;


ENTITY phaseur IS
	PORT(
		r		: IN	std_logic_vector(7 downto 0);
		g		: IN	std_logic_vector(7 downto 0);
		b		: IN	std_logic_vector(7 downto 0);
		llc		: IN	STD_LOGIC;
		burst	: IN	STD_LOGIC;
		typeAB	: IN	STD_LOGIC;
		phase	: IN	STD_LOGIC_VECTOR(9 DOWNTO 0);
		field	: IN	std_logic_vector(2 downto 0);
		chromi	: OUT	STD_LOGIC_VECTOR(10 DOWNTO 0); -- signé 1024 = 100IRE
		lumi	: OUT	STD_LOGIC_VECTOR(10 DOWNTO 0); -- signé 1024 = 100IRE
		cvbs	: OUT	STD_LOGIC_VECTOR(11 DOWNTO 0) -- signé 1024 = 100IRE
	);
END phaseur;

ARCHITECTURE a OF phaseur IS

signal phase_u  : STD_LOGIC_VECTOR(9 DOWNTO 0);
signal phase_v  : STD_LOGIC_VECTOR(9 DOWNTO 0);
signal u_cos    : std_logic_vector(9 downto 0);
signal v_cos    : std_logic_vector(9 downto 0);
signal u_modul  : std_logic_vector(10 downto 0);
signal v_modul  : std_logic_vector(10 downto 0);
signal u_amplit : std_logic_vector(10 downto 0);
signal v_amplit : std_logic_vector(10 downto 0);
signal diff_u   : std_logic_vector(11 downto 0);
signal diff_v   : std_logic_vector(11 downto 0);
signal luminan  : std_logic_vector(9 downto 0);
signal colorb   : std_logic_vector(9 downto 0);

component cosinus
	PORT
	(
		clock		: IN STD_LOGIC ;
		address_a	: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
		address_b	: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
		q_a			: OUT STD_LOGIC_VECTOR (9 DOWNTO 0);
		q_b			: OUT STD_LOGIC_VECTOR (9 DOWNTO 0)
	);
end component;

component multiplier
	PORT
	(
		dataa		: IN STD_LOGIC_VECTOR (9 DOWNTO 0);
		datab		: IN STD_LOGIC_VECTOR (10 DOWNTO 0);
		result		: OUT STD_LOGIC_VECTOR (10 DOWNTO 0)
	);
end component;

BEGIN

	-- 0.01 0011 0010 * R + 0.10 0101 1000 * G + 0.00 0111 0100 * B
	luminan <= ("00"&R) + ("00000"&R(7 downto 3)) + ("000000"&R(7 downto 4)) + ("000000000"&R(7))
	+ ('0'&G&'0') + ("0000"&G(7 downto 2)) + ("000000"&G(7 downto 4)) + ("0000000"&G(7 downto 5))
	+ ("0000"&B(7 downto 2)) + ("00000"&B(7 downto 3)) + ("000000"&B(7 downto 4)) + ("00000000"&B(7 downto 6));

	lumi <= '0'&luminan;
	-- de 0 à 1009

	u_component_or_burst : process (phase, burst, typeAB) --line, field)
	begin
		if burst = '0' then
			-- U
			phase_u <= phase;
			
		-- le burst et V changent de phase entre 2 trames pour la meme ligne
		elsif typeAB = '0' then --(line = '0' and field(1) = '0') or (line = '1' and field(1) = '1') then
			-- Burst +135°
			phase_u <= phase + "0110000000";
		else
			-- Burst -135°
			phase_u <= phase - "0110000000";
		end if;
	end process;

	v_component : process (phase, typeAB) --line, field)
	begin
		-- le burst et V changent de phase entre 2 trames pour la meme ligne
		if typeAB = '0' then --(line = '0' and field(1) = '0') or (line = '1' and field(1) = '1') then
			-- V +90°
			phase_v <= phase + "0100000000";
		else
			-- V -90°
			phase_v <= phase - "0100000000";
		end if;
	end process;

	COS : cosinus PORT MAP (
		clock => llc,
		address_a => phase_u,
		address_b => phase_v,
		q_a	=> u_cos, -- sert aussi pour le burst
		q_b => v_cos
	);

	diff_u <= ("00"&B&"00") - ("00"&luminan(9 downto 0)); -- diff_u de 908 à -897 (sur +-2047)
	diff_v <= ("00"&R&"00") - ("00"&luminan(9 downto 0)); -- diff_v de 718 à -707 (sur +-2047)

	uv_generate : process (llc)
	begin
		if rising_edge(llc) then
			-- 0.1 * diff_u
			u_amplit <= diff_u(11 downto 1);
			-- de 454 à -449

			-- 0.111 * diff_v
			v_amplit <= diff_v(11 downto 1) + (diff_v(11)&diff_v(11 downto 2)) + (diff_v(11)&diff_v(11)&diff_v(11 downto 3));
			-- de 628 à -619
		end if;
	end process;

	colorb <= (u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9 downto 3)) + (u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9 downto 4)) + (u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9)&u_cos(9 downto 6)); -- 0.00 1101 0000 * u_cos
	-- min/max = 224

	UMUL : multiplier PORT MAP (
		dataa => u_cos,
		datab => u_amplit,
		result => u_modul -- maxi=454 mini=-449
	);
	VMUL : multiplier PORT MAP (
		dataa => v_cos,
		datab => v_amplit,
		result => v_modul -- maxi=618 mini=-619
	);

	chrominance : process (u_cos, v_cos, burst, colorb, u_modul, v_modul, luminan)
	begin
		if burst = '1' then
			chromi <= colorb(9)&colorb; -- le burst
			cvbs <= colorb(9)&colorb(9)&colorb;
		else
			chromi <= u_modul + v_modul; -- la vraie chrominance
			cvbs <= (u_modul(10)&u_modul(10 downto 0)) + (v_modul(10)&v_modul(10 downto 0)) + ("00"&luminan(9 downto 0));
		end if;
	end process;

END a;
