e4ce80e2acdee59b41e7493e35b81139b509b00d
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

1) LIBRARY IEEE;
2) USE IEEE.STD_LOGIC_1164.ALL;
3) USE IEEE.NUMERIC_STD.ALL;
4) 
5) ENTITY e_io_eth_rxframe IS
6)     PORT (
7)         rst:       IN  std_logic;
8)         clk:       IN  std_logic;
9)         i_data:    IN  std_logic_vector( 7 DOWNTO 0);
10)         i_data_en: IN  std_logic;
11)         i_done:    IN  std_logic;
12)         i_err:     IN  std_logic;
13)         i_mac:     IN  std_logic_vector(47 DOWNTO 0);
14)         o_data:    OUT std_logic_vector(31 DOWNTO 0);
15)         o_data_en: OUT std_logic;
16)         o_done:    OUT std_logic;
17)         o_err:     OUT std_logic
18)     );
19) END ENTITY e_io_eth_rxframe;
20) 
21) ARCHITECTURE a_io_eth_rxframe OF e_io_eth_rxframe IS
22) 
23)     TYPE t_state IS (st_idle, st_sync, st_mac, st_mac_uni, st_mac_brd, st_data);
24) 
25)     SUBTYPE t_mac_cnt  IS natural RANGE 0 TO 5;
26)     SUBTYPE t_data_cnt IS natural RANGE 0 TO 3;
27) 
28)     SIGNAL r_state:    t_state    := st_idle;
29)     SIGNAL n_state:    t_state;
30)     SIGNAL r_mac_cnt:  t_mac_cnt  := 0;
31)     SIGNAL n_mac_cnt:  t_mac_cnt;
32)     SIGNAL r_data_cnt: t_data_cnt := 0;
33)     SIGNAL n_data_cnt: t_data_cnt;
34) 
35)     SIGNAL r_out_data:    std_logic_vector(31 DOWNTO 0) := (OTHERS => '0');
36)     SIGNAL n_out_data:    std_logic_vector(31 DOWNTO 0);
37)     SIGNAL r_out_data_en: std_logic                     := '0';
38)     SIGNAL n_out_data_en: std_logic;
39)     SIGNAL r_out_done:    std_logic                     := '0';
40)     SIGNAL n_out_done:    std_logic;
41)     SIGNAL r_out_err:     std_logic                     := '0';
42)     SIGNAL n_out_err:     std_logic;
43) 
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

44)     SIGNAL s_crc_en:    std_logic;
45)     SIGNAL s_crc_start: std_logic;
46)     SIGNAL s_crc_data:  std_logic_vector( 7 DOWNTO 0);
47)     SIGNAL s_crc_crc:   std_logic_vector(31 DOWNTO 0);
48) 
49)     COMPONENT e_block_crc32 IS
50)         PORT (
51)             rst:     IN  std_logic;
52)             clk:     IN  std_logic;
53)             i_en:    IN  std_logic;
54)             i_start: IN  std_logic;
55)             i_data:  IN  std_logic_vector( 7 DOWNTO 0);
56)             o_crc:   OUT std_logic_vector(31 DOWNTO 0)
57)         );
58)     END COMPONENT e_block_crc32;
59) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

60) BEGIN
61) 
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

62)     crc32: e_block_crc32
63)         PORT MAP (
64)             rst     => rst,
65)             clk     => clk,
66)             i_en    => s_crc_en,
67)             i_start => s_crc_start,
68)             i_data  => s_crc_data,
69)             o_crc   => s_crc_crc
70)         );
71) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

72)     p_next: PROCESS(r_state, r_mac_cnt, r_data_cnt, r_out_data,
73)                     i_data, i_data_en, i_done, i_err, i_mac)
74)         VARIABLE v_mac:  std_logic_vector(7 DOWNTO 0);
75)         VARIABLE v_data: boolean;
76)     BEGIN
77)         n_state       <= r_state;
78)         n_mac_cnt     <= r_mac_cnt;
79)         n_data_cnt    <= r_data_cnt;
80)         n_out_data    <= r_out_data;
81)         n_out_data_en <= '0';
82)         n_out_done    <= '0';
83)         n_out_err     <= '0';
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

84)         s_crc_en    <= '0';
85)         s_crc_start <= '0';
86)         s_crc_data  <= (OTHERS => '0');
87)         -- next state
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

88)         v_data := false;
89)         CASE r_state IS
90)             WHEN st_idle =>
91)                 IF i_data_en = '1' AND i_data = X"55" THEN
92)                     n_state <= st_sync;
93)                 END IF;
94)             WHEN st_sync =>
95)                 IF i_data_en = '1' THEN
96)                     IF i_data = X"D5" THEN
97)                         n_state    <= st_mac;
98)                         n_mac_cnt  <= 0;
99)                         n_data_cnt <= 0;
100)                     ELSIF i_data /= X"55" THEN
101)                         n_state <= st_idle;
102)                     END IF;
103)                 ELSIF i_done = '1' OR i_err = '1' THEN
104)                     n_state <= st_idle;
105)                 END IF;
106)             WHEN st_mac =>
107)                 IF i_data_en = '1' THEN
108)                     v_mac := i_mac(7 + 8 * r_mac_cnt DOWNTO 8 * r_mac_cnt);
109)                     IF v_mac = X"FF" THEN
110)                         IF i_data = v_mac THEN
111)                             v_data := true;
112)                         ELSE
113)                             n_state   <= st_idle;
114)                             n_out_err <= '1';
115)                         END IF;
116)                     ELSE
117)                         IF i_data = v_mac THEN
118)                             v_data  := true;
119)                             n_state <= st_mac_uni;
120)                         ELSIF i_data = X"FF" THEN
121)                             v_data  := true;
122)                             n_state <= st_mac_brd;
123)                         ELSE
124)                             n_state   <= st_idle;
125)                             n_out_err <= '1';
126)                         END IF;
127)                     END IF;
128)                     IF r_mac_cnt < 5 THEN
129)                         n_mac_cnt <= r_mac_cnt + 1;
130)                     ELSE
131)                         n_state <= st_data;
132)                     END IF;
133)                 ELSIF i_done = '1' OR i_err = '1' THEN
134)                     n_state   <= st_idle;
135)                     n_out_err <= '1';
136)                 END IF;
137)             WHEN st_mac_uni =>
138)                 IF i_data_en = '1' THEN
139)                     v_mac := i_mac(7 + 8 * r_mac_cnt DOWNTO 8 * r_mac_cnt);
140)                     IF i_data = v_mac THEN
141)                         v_data  := true;
142)                     ELSE
143)                         n_state   <= st_idle;
144)                         n_out_err <= '1';
145)                     END IF;
146)                     IF r_mac_cnt < 5 THEN
147)                         n_mac_cnt <= r_mac_cnt + 1;
148)                     ELSE
149)                         n_state <= st_data;
150)                     END IF;
151)                 ELSIF i_done = '1' OR i_err = '1' THEN
152)                     n_state   <= st_idle;
153)                     n_out_err <= '1';
154)                 END IF;
155)             WHEN st_mac_brd =>
156)                 IF i_data_en = '1' THEN
157)                     IF i_data = X"FF" THEN
158)                         v_data  := true;
159)                     ELSE
160)                         n_state   <= st_idle;
161)                         n_out_err <= '1';
162)                     END IF;
163)                     IF r_mac_cnt < 5 THEN
164)                         n_mac_cnt <= r_mac_cnt + 1;
165)                     ELSE
166)                         n_state <= st_data;
167)                     END IF;
168)                 ELSIF i_done = '1' OR i_err = '1' THEN
169)                     n_state   <= st_idle;
170)                     n_out_err <= '1';
171)                 END IF;
172)             WHEN st_data =>
173)                 IF i_data_en = '1' THEN
174)                     v_data  := true;
175)                 ELSIF i_done = '1' THEN
176)                     n_state    <= st_idle;
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

177)                     -- check CRC: last 4 bytes = 4 byte delayed CRC value
178)                     IF r_out_data = s_crc_crc THEN
179)                         n_out_done <= '1';
180)                     ELSE
181)                         n_out_err <= '1';
182)                     END IF;
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

183)                 ELSIF i_err = '1' THEN
184)                     n_state   <= st_idle;
185)                     n_out_err <= '1';
186)                 END IF;
187)             WHEN OTHERS => NULL;
188)         END CASE;
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

189)         -- data output / CRC
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

190)         IF v_data THEN
191)             n_out_data(31 DOWNTO 24) <= i_data;
192)             n_out_data(23 DOWNTO  0) <= r_out_data(31 DOWNTO 8);
193)             IF r_data_cnt < 3 THEN
194)                 n_data_cnt <= r_data_cnt + 1;
195)             ELSE
196)                 n_data_cnt    <= 0;
197)                 n_out_data_en <= '1';
198)             END IF;
Stefan Schuermans implemented ethernet RX CRC...

Stefan Schuermans authored 12 years ago

199)             -- calculate CRC with 4 bytes delay,
200)             -- so CRC value is available when i_done = 1
201)             s_crc_en   <= '1';
202)             s_crc_data <= r_out_data(7 DOWNTO 0);
203)             IF r_mac_cnt = 4 THEN
204)                 s_crc_start <= '1';
205)             END IF;