library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity eth is generic ( BITS : integer := 14; REVERSE_LANES : std_logic := '0' ); port ( clk : in std_logic; reset : in std_logic; clk156_out : out std_logic; read : out std_logic; rd_data : in std_logic_vector(63 downto 0); rd_empty : in std_logic; rd_count : in std_logic_vector(BITS downto 0); write : out std_logic; wr_data : out std_logic_vector(63 downto 0); wr_full : in std_logic; wr_count : in std_logic_vector(BITS downto 0); xaui_clk_p : in std_logic; xaui_clk_n : in std_logic; xaui_dclk : in std_logic; xaui_tx_l0_p : out std_logic; xaui_tx_l0_n : out std_logic; xaui_tx_l1_p : out std_logic; xaui_tx_l1_n : out std_logic; xaui_tx_l2_p : out std_logic; xaui_tx_l2_n : out std_logic; xaui_tx_l3_p : out std_logic; xaui_tx_l3_n : out std_logic; xaui_rx_l0_p : in std_logic; xaui_rx_l0_n : in std_logic; xaui_rx_l1_p : in std_logic; xaui_rx_l1_n : in std_logic; xaui_rx_l2_p : in std_logic; xaui_rx_l2_n : in std_logic; xaui_rx_l3_p : in std_logic; xaui_rx_l3_n : in std_logic ); end eth; architecture arch of eth is type state_t is (state_idle, state_length, state_data, state_end); signal xgmii_txd : std_logic_vector(63 downto 0); signal xgmii_txc : std_logic_vector(7 downto 0); signal xgmii_rxd : std_logic_vector(63 downto 0); signal xgmii_rxc : std_logic_vector(7 downto 0); signal clk156 : std_logic; signal rx_data : std_logic_vector(63 downto 0); signal rx_start : std_logic; signal rx_end : std_logic; signal rx_rem : integer range 0 to 7; signal tx_data : std_logic_vector(63 downto 0); signal tx_start : std_logic; signal tx_end : std_logic; signal tx_rem : integer range 0 to 7; begin clk156_out <= clk156; -- sending process (clk, reset) variable state : state_t; variable length : unsigned(BITS downto 0); begin if reset = '1' then state := state_idle; read <= '0'; tx_data <= (others => '0'); tx_start <= '0'; tx_end <= '0'; tx_rem <= 0; elsif rising_edge(clk) then read <= '0'; tx_data <= (others => '0'); tx_start <= '0'; tx_end <= '0'; tx_rem <= 0; if state = state_idle then if rd_empty = '0' then length := unsigned(rd_data(BITS downto 0)) + 1; if length <= unsigned(rd_count) then state := state_data; read <= '1'; tx_start <= '1'; end if; end if; elsif state = state_data then tx_data <= rd_data; length := length - 1; if length > 0 then read <= '1'; else state := state_end; end if; elsif state = state_end then state := state_idle; tx_end <= '1'; tx_rem <= 0; end if; end if; end process; -- receiving process (clk, reset) variable state : state_t; variable length : unsigned(BITS downto 0); begin if reset = '1' then state := state_idle; write <= '0'; wr_data <= (others => '0'); elsif rising_edge(clk) then write <= '0'; wr_data <= (others => '0'); if state = state_idle then if rx_start = '1' and rx_end = '0' then state := state_length; end if; elsif state = state_length then state := state_idle; if rx_end = '0' and unsigned(rx_data) <= 511 and 16384 - unsigned(wr_count) >= 512 then state := state_data; length := unsigned(rx_data(BITS downto 0)) + 1; end if; end if; if state = state_data then write <= '1'; wr_data <= rx_data; length := length - 1; if length = 0 then state := state_idle; end if; end if; end if; end process; xaui : entity work.xaui_top generic map ( REVERSE_LANES => REVERSE_LANES ) port map ( dclk => xaui_dclk, reset => reset, xgmii_txd => xgmii_txd, xgmii_txc => xgmii_txc, xgmii_rxd => xgmii_rxd, xgmii_rxc => xgmii_rxc, clk156_out => clk156, refclk_p => xaui_clk_p, refclk_n => xaui_clk_n, xaui_tx_l0_p => xaui_tx_l0_p, xaui_tx_l0_n => xaui_tx_l0_n, xaui_tx_l1_p => xaui_tx_l1_p, xaui_tx_l1_n => xaui_tx_l1_n, xaui_tx_l2_p => xaui_tx_l2_p, xaui_tx_l2_n => xaui_tx_l2_n, xaui_tx_l3_p => xaui_tx_l3_p, xaui_tx_l3_n => xaui_tx_l3_n, xaui_rx_l0_p => xaui_rx_l0_p, xaui_rx_l0_n => xaui_rx_l0_n, xaui_rx_l1_p => xaui_rx_l1_p, xaui_rx_l1_n => xaui_rx_l1_n, xaui_rx_l2_p => xaui_rx_l2_p, xaui_rx_l2_n => xaui_rx_l2_n, xaui_rx_l3_p => xaui_rx_l3_p, xaui_rx_l3_n => xaui_rx_l3_n ); rx_eth : entity work.rx_eth port map ( clk => clk, reset => reset, xgmii_rxd => xgmii_rxd, xgmii_rxc => xgmii_rxc, rx_data => rx_data, rx_start => rx_start, rx_end => rx_end, rx_rem => rx_rem ); tx_eth : entity work.tx_eth port map ( clk => clk, reset => reset, xgmii_txd => xgmii_txd, xgmii_txc => xgmii_txc, tx_data => tx_data, tx_start => tx_start, tx_end => tx_end, tx_rem => tx_rem ); end arch;