library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity eth_rx is port ( clk : in std_logic; wr_en : out std_logic := '0'; wr_data : out std_logic_vector (63 downto 0) := (others => '0'); wr_done : out std_logic := '0'; wr_accept : in std_logic; xgmii_rxd : in std_logic_vector(63 downto 0); xgmii_rxc : in std_logic_vector(7 downto 0) ); end eth_rx; architecture arch of eth_rx is constant IDLE : std_logic_vector(7 downto 0) := x"07"; constant START : std_logic_vector(7 downto 0) := x"FB"; constant TERMINATE : std_logic_vector(7 downto 0) := x"FD"; constant ERR : std_logic_vector(7 downto 0) := x"FE"; type lanes_t is array (0 to 7) of std_logic_vector(7 downto 0); signal lanes_a : lanes_t; signal lanes_b : lanes_t; signal control_a : std_logic_vector(7 downto 0); signal control_b : std_logic_vector(7 downto 0); type state_t is (state_idle, state_a, state_b); signal state : state_t := state_idle; begin gen_a : for i in 0 to 7 generate lanes_a(i) <= xgmii_rxd(7+8*i downto 8*i); control_a(i) <= xgmii_rxc(i); end generate gen_a; lanes_b(4 to 7) <= lanes_a(0 to 3); control_b(7 downto 4) <= control_a(3 downto 0); process (clk) begin if rising_edge(clk) then wr_en <= '0'; wr_data <= (others => '0'); wr_done <= '0'; lanes_b(0 to 3) <= lanes_a(4 to 7); control_b(3 downto 0) <= control_a(7 downto 4); if state = state_idle and wr_accept = '1' then if control_a(0) = '1' and lanes_a(0) = START then state <= state_a; elsif control_b(0) = '1' and lanes_b(0) = START then state <= state_b; end if; elsif state = state_a then wr_en <= '1'; for i in 0 to 7 loop wr_data(63-8*i downto 56-8*i) <= lanes_a(i); if control_a(i) = '1' and (lanes_a(i) = TERMINATE or lanes_a(i) = ERR) then state <= state_idle; wr_done <= '1'; end if; end loop; elsif state = state_b then wr_en <= '1'; for i in 0 to 7 loop wr_data(63-8*i downto 56-8*i) <= lanes_b(i); if control_b(i) = '1' and (lanes_b(i) = TERMINATE or lanes_b(i) = ERR) then state <= state_idle; wr_done <= '1'; end if; end loop; end if; end if; end process; end arch;