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



entity rgmii_rx is
    Port ( rx_clk           : in  STD_LOGIC;
           rx_ctl           : in  STD_LOGIC_VECTOR(0 downto 0);
           rx_data          : in  STD_LOGIC_VECTOR (3 downto 0);
           link_10mb        : out STD_LOGIC;
           link_100mb       : out STD_LOGIC;
           link_1000mb      : out STD_LOGIC;
           link_full_duplex : out STD_LOGIC;
           data             : out STD_LOGIC_VECTOR (7 downto 0);
           data_valid       : out STD_LOGIC;
           data_enable      : out STD_LOGIC;
           data_error       : out STD_LOGIC);
end rgmii_rx;

architecture Behavioral of rgmii_rx is
	 
	component my_ddio_in IS
		PORT
		(
			datain		: IN STD_LOGIC_VECTOR (0 DOWNTO 0);
			inclock		: IN STD_LOGIC ;
			dataout_h	: OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
			dataout_l	: OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
		);
	end component my_ddio_in; 
	
	component tx_ddio_in IS
	PORT
	(
		datain		: IN STD_LOGIC_VECTOR (3 DOWNTO 0);
		inclock		: IN STD_LOGIC ;
		dataout_h		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
		dataout_l		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
	);
	end component tx_ddio_in;

    signal raw_ctl  : std_logic_vector(1 downto 0);
    signal raw_data : std_logic_vector(7 downto 0) := (others => '0');
	 signal a,b 	  : std_logic_vector(0 downto 0);
begin
	--tx_ctl in
	ddr_tx_ctl:	my_ddio_in
			port map
			(
				datain		=> rx_ctl,
				inclock		=> rx_clk,
				dataout_h	=> a,
				dataout_l	=> b
			);
	raw_ctl(1) <= a(0);
	raw_ctl(0) <= b(0);
	--data in
	ddr_rx_data : tx_ddio_in
	PORT MAP
	(
		datain		=> rx_data,
		inclock		=> rx_clk,
		dataout_h	=> raw_data(7 downto 4),
		dataout_l	=> raw_data(3 downto 0)
	);	

process(rx_clk) 
    begin
        if rising_edge(rx_clk) then
            data_valid <= raw_ctl(0);
            data_error <= raw_ctl(0) XOR raw_ctl(1);
            data       <= raw_data;
            -- check for inter-frame with matching upper and lower nibble
            if raw_ctl = "00"  and raw_data(3 downto 0) = raw_data(7 downto 4) then
                link_10mb        <= '0';
                link_100mb       <= '0';
                link_1000mb      <= '0';
                link_full_duplex <= '0';
                case raw_data(2 downto 0) is
                    when "001" => link_10mb   <= '1'; link_full_duplex <= raw_data(3);
                    when "011" => link_100mb  <= '1'; link_full_duplex <= raw_data(3);
                    when "101" => link_1000mb <= '1'; link_full_duplex <= raw_data(3);
                    when others => NULL;
                end case;
            end if; 
        end if;
    end process;
end Behavioral;