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