blob: bcd395f96ef99de918a5b4551902799196f7e38d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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;
|