From d1a1059d748955ed93a8e87c437c7eae1258293c Mon Sep 17 00:00:00 2001 From: Alexander D'hoore Date: Fri, 15 Dec 2017 15:37:58 +0100 Subject: 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. --- netfpga10g/hdl/rx_eth.vhd | 168 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 netfpga10g/hdl/rx_eth.vhd (limited to 'netfpga10g/hdl/rx_eth.vhd') diff --git a/netfpga10g/hdl/rx_eth.vhd b/netfpga10g/hdl/rx_eth.vhd new file mode 100644 index 0000000..fe6e65e --- /dev/null +++ b/netfpga10g/hdl/rx_eth.vhd @@ -0,0 +1,168 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity rx_eth is port ( + clk : in std_logic; + reset : in std_logic; + + xgmii_rxd : in std_logic_vector(63 downto 0); + xgmii_rxc : in std_logic_vector(7 downto 0); + + rx_data : out std_logic_vector(63 downto 0); + rx_start : out std_logic; + rx_end : out std_logic; + rx_rem : out integer range 0 to 7; + + start_count_out : out std_logic_vector(31 downto 0); + end_count_out : out std_logic_vector(31 downto 0) +); +end rx_eth; + +architecture arch of rx_eth 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"; + + constant PREAMBLE : std_logic_vector(7 downto 0) := "01010101"; + constant SFD : std_logic_vector(7 downto 0) := "11010101"; + + 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); + + signal use_a : std_logic; + + signal start_count : unsigned(31 downto 0); + signal end_count : unsigned(31 downto 0); +begin + start_count_out <= std_logic_vector(start_count); + end_count_out <= std_logic_vector(end_count); + + rx_lanes_gen : for i in 0 to 7 generate + lanes_a(i) <= xgmii_rxd(7+8*i downto 8*i); + end generate rx_lanes_gen; + + control_a <= xgmii_rxc; + lanes_b(4) <= lanes_a(0); + lanes_b(5) <= lanes_a(1); + lanes_b(6) <= lanes_a(2); + lanes_b(7) <= lanes_a(3); + control_b(4) <= control_a(0); + control_b(5) <= control_a(1); + control_b(6) <= control_a(2); + control_b(7) <= control_a(3); + + rx_logic : process (clk, reset) begin + if reset = '1' then + rx_data <= (others => '0'); + rx_start <= '0'; + rx_end <= '0'; + rx_rem <= 0; + start_count <= (others => '0'); + end_count <= (others => '0'); + lanes_b(0) <= (others => '0'); + lanes_b(1) <= (others => '0'); + lanes_b(2) <= (others => '0'); + lanes_b(3) <= (others => '0'); + control_b(3 downto 0) <= (others => '0'); + use_a <= '1'; + + elsif rising_edge(clk) then + rx_start <= '0'; + rx_end <= '0'; + rx_rem <= 0; + + lanes_b(0) <= lanes_a(4); + lanes_b(1) <= lanes_a(5); + lanes_b(2) <= lanes_a(6); + lanes_b(3) <= lanes_a(7); + control_b(3 downto 0) <= control_a(7 downto 4); + + for i in 0 to 7 loop + if use_a = '1' then + rx_data(63-8*i downto 56-8*i) <= lanes_a(i); + else + rx_data(63-8*i downto 56-8*i) <= lanes_b(i); + end if; + end loop; + + if control_a(0) = '1' and lanes_a(0) = START then + rx_start <= '1'; + use_a <= '1'; + elsif control_b(0) = '1' and lanes_b(0) = START then + rx_start <= '1'; + use_a <= '0'; + start_count <= start_count + 1; + end if; + + if use_a = '1' then + if control_a(0) = '1' and (lanes_a(0) = TERMINATE or lanes_a(0) = ERR) then + rx_end <= '1'; + rx_rem <= 0; + elsif control_a(1) = '1' and (lanes_a(1) = TERMINATE or lanes_a(1) = ERR) then + rx_end <= '1'; + rx_rem <= 1; + elsif control_a(2) = '1' and (lanes_a(2) = TERMINATE or lanes_a(2) = ERR) then + rx_end <= '1'; + rx_rem <= 2; + elsif control_a(3) = '1' and (lanes_a(3) = TERMINATE or lanes_a(3) = ERR) then + rx_end <= '1'; + rx_rem <= 3; + elsif control_a(4) = '1' and (lanes_a(4) = TERMINATE or lanes_a(4) = ERR) then + rx_end <= '1'; + rx_rem <= 4; + elsif control_a(5) = '1' and (lanes_a(5) = TERMINATE or lanes_a(5) = ERR) then + rx_end <= '1'; + rx_rem <= 5; + elsif control_a(6) = '1' and (lanes_a(6) = TERMINATE or lanes_a(6) = ERR) then + rx_end <= '1'; + rx_rem <= 6; + elsif control_a(7) = '1' and (lanes_a(7) = TERMINATE or lanes_a(7) = ERR) then + rx_end <= '1'; + rx_rem <= 7; + end if; + else + if control_b(0) = '1' and (lanes_b(0) = TERMINATE or lanes_b(0) = ERR) then + rx_end <= '1'; + rx_rem <= 0; + end_count <= end_count + 1; + elsif control_b(1) = '1' and (lanes_b(1) = TERMINATE or lanes_b(1) = ERR) then + rx_end <= '1'; + rx_rem <= 1; + end_count <= end_count + 1; + elsif control_b(2) = '1' and (lanes_b(2) = TERMINATE or lanes_b(2) = ERR) then + rx_end <= '1'; + rx_rem <= 2; + end_count <= end_count + 1; + elsif control_b(3) = '1' and (lanes_b(3) = TERMINATE or lanes_b(3) = ERR) then + rx_end <= '1'; + rx_rem <= 3; + end_count <= end_count + 1; + elsif control_b(4) = '1' and (lanes_b(4) = TERMINATE or lanes_b(4) = ERR) then + rx_end <= '1'; + rx_rem <= 4; + end_count <= end_count + 1; + elsif control_b(5) = '1' and (lanes_b(5) = TERMINATE or lanes_b(5) = ERR) then + rx_end <= '1'; + rx_rem <= 5; + end_count <= end_count + 1; + elsif control_b(6) = '1' and (lanes_b(6) = TERMINATE or lanes_b(6) = ERR) then + rx_end <= '1'; + rx_rem <= 6; + end_count <= end_count + 1; + elsif control_b(7) = '1' and (lanes_b(7) = TERMINATE or lanes_b(7) = ERR) then + rx_end <= '1'; + rx_rem <= 7; + end_count <= end_count + 1; + end if; + end if; + end if; + end process; +end arch; + -- cgit v1.2.3