diff options
Diffstat (limited to 'netfpga10g/hdl/eth.vhd')
-rw-r--r-- | netfpga10g/hdl/eth.vhd | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/netfpga10g/hdl/eth.vhd b/netfpga10g/hdl/eth.vhd new file mode 100644 index 0000000..8034ceb --- /dev/null +++ b/netfpga10g/hdl/eth.vhd @@ -0,0 +1,219 @@ + +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; |