LIBRARY ieee, work;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
USE ieee.std_logic_unsigned.all;

ENTITY une_ligne IS
  
	GENERIC (
		taille_flux : natural := 16
	);
	PORT (
		clock		: in	std_logic;
		
		wren		: in	std_logic;
		pixel_num	: in	std_logic_vector(9 downto 0);

		data_sig	: IN	STD_LOGIC_VECTOR(taille_flux-1 DOWNTO 0);
		
		q_n		: out	STD_LOGIC_VECTOR(taille_flux-1 DOWNTO 0); -- q(addr)
		q_n1	: out	STD_LOGIC_VECTOR(taille_flux-1 DOWNTO 0); -- q(addr+1)
		q_n2	: out	STD_LOGIC_VECTOR(taille_flux-1 DOWNTO 0); -- q(addr+2)
		q_n3	: out	STD_LOGIC_VECTOR(taille_flux-1 DOWNTO 0)  -- q(addr+3)
	);

END une_ligne ;

ARCHITECTURE a OF une_ligne IS

component ram
	GENERIC (
		taille_flux : natural := 16
	);
	PORT
	(
		address		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		clock		: IN STD_LOGIC ;
		data		: IN STD_LOGIC_VECTOR (taille_flux-1 DOWNTO 0);
		wren		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (taille_flux-1 DOWNTO 0)
	);
end component;

signal address_A, address_B, address_C, address_D : STD_LOGIC_VECTOR (7 DOWNTO 0);
signal wren_A, wren_B, wren_C, wren_D: std_logic;
signal q_A, q_B, q_C, q_D : std_logic_vector(taille_flux-1 downto 0);

BEGIN

-- les buffers de lignes sont decoupes en 4, de facon a pouvoir recuperer 4 pixels de chaque ligne
	ram_addr_A : process (pixel_num, wren)
	begin
		case pixel_num(1 downto 0) is
			when "00" =>	address_A <= pixel_num(9 downto 2);
							wren_A <= wren;
			when "01" =>	address_A <= pixel_num(9 downto 2)+"00000001";
							wren_A <= '0';
			when "10" =>	address_A <= pixel_num(9 downto 2)+"00000001";
							wren_A <= '0';
			when others =>	address_A <= pixel_num(9 downto 2)+"00000001";
							wren_A <= '0';
		end case;
	end process;
	ram_addr_B : process (pixel_num, wren)
	begin
		case pixel_num(1 downto 0) is
			when "00" => address_B <= pixel_num(9 downto 2);
							wren_B <= '0';
			when "01" => address_B <= pixel_num(9 downto 2);
							wren_B <= wren;
			when "10" => address_B <= pixel_num(9 downto 2)+"00000001";
							wren_B <= '0';
			when others => address_B <= pixel_num(9 downto 2)+"00000001";
							wren_B <= '0';
		end case;
	end process;
	ram_addr_C : process (pixel_num, wren)
	begin
		case pixel_num(1 downto 0) is
			when "00" => address_C <= pixel_num(9 downto 2);
							wren_C <= '0';
			when "01" => address_C <= pixel_num(9 downto 2);
							wren_C <= '0';
			when "10" => address_C <= pixel_num(9 downto 2);
							wren_C <= wren;
			when others => address_C <= pixel_num(9 downto 2)+"00000001";
							wren_C <= '0';
		end case;
	end process;
	ram_addr_D : process (pixel_num, wren)
	begin
		case pixel_num(1 downto 0) is
			when "00" => address_D <= pixel_num(9 downto 2);
							wren_D <= '0';
			when "01" => address_D <= pixel_num(9 downto 2);
							wren_D <= '0';
			when "10" => address_D <= pixel_num(9 downto 2);
							wren_D <= '0';
			when others => address_D <= pixel_num(9 downto 2);
							wren_D <= wren;
		end case;
	end process;

  with pixel_num(1 downto 0) select
    q_n <=
    q_A when "00",
    q_B when "01",
    q_C when "10",
    q_D when others;

  with pixel_num(1 downto 0) select
    q_n1 <=
    q_B when "00",
    q_C when "01",
    q_D when "10",
    q_A when others;

  with pixel_num(1 downto 0) select
    q_n2 <=
    q_C when "00",
    q_D when "01",
    q_A when "10",
    q_B when others;

  with pixel_num(1 downto 0) select
    q_n3 <=
    q_D when "00",
    q_A when "01",
    q_B when "10",
    q_C when others;
	
ram_A : ram GENERIC MAP(
		taille_flux => taille_flux
	)
	PORT MAP (
		address	 => address_A,
		clock	 => clock,
		data	 => data_sig,
		wren	 => wren_A,
		q	 => q_A
	);
ram_B : ram GENERIC MAP(
		taille_flux => taille_flux
	)
	PORT MAP (
		address	 => address_B,
		clock	 => clock,
		data	 => data_sig,
		wren	 => wren_B,
		q	 => q_B
	);
ram_C : ram GENERIC MAP(
		taille_flux => taille_flux
	)
	PORT MAP (
		address	 => address_C,
		clock	 => clock,
		data	 => data_sig,
		wren	 => wren_C,
		q	 => q_C
	);
ram_D : ram GENERIC MAP(
		taille_flux => taille_flux
	)
	PORT MAP (
		address	 => address_D,
		clock	 => clock,
		data	 => data_sig,
		wren	 => wren_D,
		q	 => q_D
	);

END a;
