summaryrefslogtreecommitdiff
path: root/netfpga10g/hdl/eth.vhd
diff options
context:
space:
mode:
authorAlexander D'hoore <dhoore.alexander@gmail.com>2017-12-15 15:37:58 +0100
committerDimitri Staessens <dimitri.staessens@ugent.be>2017-12-15 15:37:58 +0100
commitd1a1059d748955ed93a8e87c437c7eae1258293c (patch)
tree9137bc921db74bb3797b8b0f05e7a69022412522 /netfpga10g/hdl/eth.vhd
parent8f258e469b1acea8e3ccf1485779e1db0bf5f772 (diff)
downloadraptor-d1a1059d748955ed93a8e87c437c7eae1258293c.tar.gz
raptor-d1a1059d748955ed93a8e87c437c7eae1258293c.zip
Add the linux device driver and netfpga files
This adds the device driver and netfpga files from the master thesis (in Dutch) "Implementatie van de Recursive Internet Architecture op een FPGA platform" by Alexander D'hoore.
Diffstat (limited to 'netfpga10g/hdl/eth.vhd')
-rw-r--r--netfpga10g/hdl/eth.vhd219
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;