64053dc72092c01ad62f68ba4796202971aa93f5
Stefan Schuermans begin of ethernet RX implem...

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 IS
6)     PORT (
7)         rst:          IN  std_logic;
8)         clk:          IN  std_logic;
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

9)         i_addr:       IN  std_logic_vector( 2 DOWNTO 0);
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

10)         o_rd_data:    OUT std_logic_vector(31 DOWNTO 0);
Stefan Schuermans add read_enable signal to d...

Stefan Schuermans authored 12 years ago

11)         i_rd_en:      IN  std_logic_vector( 3 DOWNTO 0);
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

12)         i_wr_data:    IN  std_logic_vector(31 DOWNTO 0);
13)         i_wr_en:      IN  std_logic_vector( 3 DOWNTO 0);
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

14)         o_bm_req:     OUT std_logic;
15)         i_bm_grant:   IN  std_logic;
16)         o_bm_addr:    OUT std_logic_vector(31 DOWNTO 0);
17)         i_bm_rd_data: IN  std_logic_vector(31 DOWNTO 0);
18)         o_bm_rd_en:   OUT std_logic_vector( 3 DOWNTO 0);
19)         o_bm_wr_data: OUT std_logic_vector(31 DOWNTO 0);
20)         o_bm_wr_en:   OUT std_logic_vector( 3 DOWNTO 0);
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

21)         pin_o_nrst:   OUT std_logic;
22)         pin_i_rx_clk: IN  std_logic;
23)         pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
24)         pin_i_rx_dv:  IN  std_logic;
25)         pin_i_crs:    IN  std_logic;
26)         pin_i_col:    IN  std_logic;
27)         pin_i_tx_clk: IN  std_logic;
28)         pin_o_txd:    OUT std_logic_vector(3 DOWNTO 0);
29)         pin_o_tx_en:  OUT std_logic
30)     );
31) END ENTITY e_io_eth;
32) 
33) ARCHITECTURE a_io_eth OF e_io_eth IS
34) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

35)     SIGNAL s_rxif_data:    std_logic_vector(7 DOWNTO 0);
36)     SIGNAL s_rxif_data_en: std_logic;
37)     SIGNAL s_rxif_done:    std_logic;
38)     SIGNAL s_rxif_err:     std_logic;
39) 
40)     SIGNAL s_rxframe_data:    std_logic_vector(31 DOWNTO 0);
41)     SIGNAL s_rxframe_data_en: std_logic;
42)     SIGNAL s_rxframe_done:    std_logic;
43)     SIGNAL s_rxframe_err:     std_logic;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

44) 
Stefan Schuermans implemented ethernet TX int...

Stefan Schuermans authored 12 years ago

45)     SIGNAL s_rx_new: std_logic;
46) 
47)     SIGNAL s_txif_data:     std_logic_vector(7 DOWNTO 0);
48)     SIGNAL s_txif_data_en:  std_logic;
49)     SIGNAL s_txif_data_ack: std_logic;
50) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

51)     -- RX buffer registers
52)     --   start: current buffer begin
53)     --   cur: address of next data write
54)     --   size: size of data received
55)     --   end: address just behind buffer
56)     --   data is written to buffer like this: <size><data 0>...<data size-1>
57)     --      size is written last
58)     --      next packet begins directly afterwards
59)     --   all addresses/sizes are word-aligned
60)     SIGNAL r_rx_start: std_logic_vector(31 DOWNTO 0) := X"00000000";
61)     SIGNAL n_rx_start: std_logic_vector(31 DOWNTO 0);
62)     SIGNAL r_rx_cur:   std_logic_vector(31 DOWNTO 0) := X"00000004";
63)     SIGNAL n_rx_cur:   std_logic_vector(31 DOWNTO 0);
64)     SIGNAL r_rx_size:  std_logic_vector(31 DOWNTO 0) := X"00000000";
65)     SIGNAL n_rx_size:  std_logic_vector(31 DOWNTO 0);
66)     SIGNAL r_rx_end:   std_logic_vector(31 DOWNTO 0) := X"00000000";
67)     SIGNAL n_rx_end:   std_logic_vector(31 DOWNTO 0);
68) 
69)     -- RX new buffer registers
70)     --     new_start: begin of new buffer
71)     --     new_end: address just behind new buffer
72)     --     new_en: if a new buffer is available
73)     --   all addresses are word-aligned
74)     SIGNAL r_rx_new_start: std_logic_vector(31 DOWNTO 0) := X"00000000";
75)     SIGNAL n_rx_new_start: std_logic_vector(31 DOWNTO 0);
76)     SIGNAL r_rx_new_end:   std_logic_vector(31 DOWNTO 0) := X"00000000";
77)     SIGNAL n_rx_new_end:   std_logic_vector(31 DOWNTO 0);
78)     SIGNAL r_rx_new_en:    std_logic                     := '0';
79)     SIGNAL n_rx_new_en:    std_logic;
80) 
81)     SIGNAL s_wrbuf_wr_rdy:  std_logic;
82)     SIGNAL s_wrbuf_wr_data: std_logic_vector(63 DOWNTO 0);
83)     SIGNAL s_wrbuf_wr_en:   std_logic;
84)     SIGNAL s_wrbuf_rd_rdy:  std_logic;
85)     SIGNAL s_wrbuf_rd_data: std_logic_vector(63 DOWNTO 0);
86)     SIGNAL s_wrbuf_rd_en:   std_logic;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

87) 
88)     COMPONENT e_io_eth_rst IS
89)         PORT (
90)             rst:        IN  std_logic;
91)             clk:        IN  std_logic;
92)             pin_o_nrst: OUT std_logic
93)         );
94)     END COMPONENT e_io_eth_rst;
95) 
96)     COMPONENT e_io_eth_rxif IS
97)         PORT (
98)             rst:          IN  std_logic;
99)             clk:          IN  std_logic;
100)             o_data:       OUT std_logic_vector(7 DOWNTO 0);
101)             o_data_en:    OUT std_logic;
102)             o_done:       OUT std_logic;
103)             o_err:        OUT std_logic;
104)             pin_i_rx_clk: IN  std_logic;
105)             pin_i_rxd:    IN  std_logic_vector(4 DOWNTO 0);
106)             pin_i_rx_dv:  IN  std_logic;
107)             pin_i_crs:    IN  std_logic;
108)             pin_i_col:    IN  std_logic
109)         );
110)     END COMPONENT e_io_eth_rxif;
111) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

112)     COMPONENT e_io_eth_rxframe IS
113)         PORT (
114)             rst:       IN  std_logic;
115)             clk:       IN  std_logic;
116)             i_data:    IN  std_logic_vector( 7 DOWNTO 0);
117)             i_data_en: IN  std_logic;
118)             i_done:    IN  std_logic;
119)             i_err:     IN  std_logic;
120)             i_mac:     IN  std_logic_vector(47 DOWNTO 0);
121)             o_data:    OUT std_logic_vector(31 DOWNTO 0);
122)             o_data_en: OUT std_logic;
123)             o_done:    OUT std_logic;
124)             o_err:     OUT std_logic
125)         );
126)     END COMPONENT e_io_eth_rxframe;
127) 
Stefan Schuermans implemented ethernet TX int...

Stefan Schuermans authored 12 years ago

128)     COMPONENT e_io_eth_txif IS
129)         PORT (
130)             rst:          IN  std_logic;
131)             clk:          IN  std_logic;
132)             i_data:       IN  std_logic_vector(7 DOWNTO 0);
133)             i_data_en:    IN  std_logic;
134)             o_data_ack:   OUT std_logic;
135)             pin_i_tx_clk: IN  std_logic;
136)             pin_o_txd:    OUT std_logic_vector(3 DOWNTO 0);
137)             pin_o_tx_en:  OUT std_logic
138)         );
139)     END COMPONENT e_io_eth_txif;
140) 
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

141)     COMPONENT e_block_fifo IS
142)         GENERIC (
143)             addr_width: natural;
144)             data_width: natural
145)         );
146)         PORT (
147)             rst:       IN  std_logic;
148)             clk:       IN  std_logic;
149)             o_wr_rdy:  OUT std_logic;
150)             i_wr_data: IN  std_logic_vector(data_width - 1 DOWNTO 0);
151)             i_wr_en:   IN  std_logic;
152)             o_rd_rdy:  OUT std_logic;
153)             o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
154)             i_rd_en:   IN  std_logic
155)         );
156)     END COMPONENT e_block_fifo;
157) 
158) BEGIN
159) 
160)     reset: e_io_eth_rst
161)         PORT MAP (
162)             rst        => rst,
163)             clk        => clk,
164)             pin_o_nrst => pin_o_nrst
165)         );
166) 
167)     rxif: e_io_eth_rxif
168)         PORT MAP (
169)             rst          => rst,
170)             clk          => clk,
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

171)             o_data       => s_rxif_data,
172)             o_data_en    => s_rxif_data_en,
173)             o_done       => s_rxif_done,
174)             o_err        => s_rxif_err,
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

175)             pin_i_rx_clk => pin_i_rx_clk,
176)             pin_i_rxd    => pin_i_rxd,
177)             pin_i_rx_dv  => pin_i_rx_dv,
178)             pin_i_crs    => pin_i_crs,
179)             pin_i_col    => pin_i_col
180)         );
181) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

182)     rxframe: e_io_eth_rxframe
183)         PORT MAP (
184)             rst       => rst,
185)             clk       => clk,
186)             i_data    => s_rxif_data,
187)             i_data_en => s_rxif_data_en,
188)             i_done    => s_rxif_done,
189)             i_err     => s_rxif_err,
190)             i_mac     => X"070605040302",
191)             o_data    => s_rxframe_data,
192)             o_data_en => s_rxframe_data_en,
193)             o_done    => s_rxframe_done,
194)             o_err     => s_rxframe_err
195)         );
196) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

197)     p_rx_next: PROCESS(r_rx_start, r_rx_cur, r_rx_size, r_rx_end,
198)                        r_rx_new_start, r_rx_new_end, r_rx_new_en,
199)                        s_rxframe_data, s_rxframe_data_en,
200)                        s_rxframe_done, s_rxframe_err,
201)                        s_wrbuf_wr_rdy)
202)         VARIABLE v_abort:  boolean; -- abort current packet reception
203)         VARIABLE v_ignore: boolean; -- ignore rest of packet
204)         VARIABLE v_store:  boolean; -- store packet data
205)         VARIABLE v_finish: boolean; -- finish reception of packet
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

206)     BEGIN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

207)         n_rx_start      <= r_rx_start;
208)         n_rx_cur        <= r_rx_cur;
209)         n_rx_size       <= r_rx_size;
210)         n_rx_end        <= r_rx_end;
211)         s_wrbuf_wr_data <= (OTHERS => '0');
212)         s_wrbuf_wr_en   <= '0';
213)         s_rx_new        <= '0';
214) 
215)         -- determine which action to perform
216)         v_abort  := false;
217)         v_ignore := false;
218)         v_store  := false;
219)         v_finish := false;
220)         -- incoming data
221)         IF s_rxframe_data_en = '1' THEN
222)             IF r_rx_start = r_rx_end THEN
223)                 v_ignore := true; -- buffer not available -> ignore rest of packet
224)             ELSIF r_rx_cur = r_rx_end THEN
225)                 v_ignore := true; -- buffer full -> ignore rest of packet
226)             ELSIF s_wrbuf_wr_rdy = '0' THEN
227)                 v_ignore := true; -- bus master write buffer full -> ignore rest of packet
228)             ELSE
229)                 v_store := true; -- store data
230)             END IF;
231)         -- packet complete
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

232)         ELSIF s_rxframe_done = '1' THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

233)             IF r_rx_start = r_rx_end THEN
234)                 v_abort := true; -- buffer not available -> abort
235)             ELSIF r_rx_cur = r_rx_end THEN
236)                 v_abort := true; -- buffer full -> abort
237)             ELSIF s_wrbuf_wr_rdy = '0' THEN
238)                 v_abort := true; -- bus master write buffer full -> abort
239)             ELSIF r_rx_size = X"00000000" THEN
240)                 v_abort := true; -- empty packet -> abort
241)             ELSE
242)                 v_finish := true; -- finish packet recpetion
243)             END IF;
244)         -- error
245)         ELSIF s_rxframe_err = '1' THEN
246)             v_abort := true; -- abort
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

247)         END IF;
248) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

249)         -- perform action selected above
250)         -- abort current packet
251)         IF v_abort THEN
252)             n_rx_cur  <= std_logic_vector(unsigned(r_rx_start) + X"00000004");
253)             n_rx_size <= X"00000000";
254)         -- ignore rest of packet
255)         --   count size to ensure it is not zero
256)         ELSIF v_ignore THEN
257)             n_rx_cur  <= r_rx_end;
258)             n_rx_size <= std_logic_vector(unsigned(r_rx_size) + X"00000004");
259)         -- store data to current address and advance in buffer
260)         ELSIF v_store THEN
261)             s_wrbuf_wr_data <= r_rx_cur & s_rxframe_data;
262)             s_wrbuf_wr_en   <= '1';
263)             n_rx_cur  <= std_logic_vector(unsigned(r_rx_cur) + X"00000004");
264)             n_rx_size <= std_logic_vector(unsigned(r_rx_size) + X"00000004");
265)         -- store size to start and restart after packet
266)         ELSIF v_finish THEN
267)             s_wrbuf_wr_data <= r_rx_start & r_rx_size;
268)             s_wrbuf_wr_en   <= '1';
269)             n_rx_start <= r_rx_cur;
270)             n_rx_cur   <= std_logic_vector(unsigned(r_rx_cur) + X"00000004");
271)             n_rx_size  <= X"00000000";
272)         END IF;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

273) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

274)         -- use new buffer
275)         --   if no action, no data yet and new_en set
276)         IF NOT v_abort AND NOT v_ignore AND NOT v_store AND NOT v_finish AND
277)            r_rx_size = X"00000000" AND r_rx_new_en = '1' THEN
278)             -- terminate old buffer by writing size 0 (if old buffer was available)
279)             IF r_rx_start /= r_rx_end THEN
280)                 s_wrbuf_wr_data <= r_rx_start & X"00000000";
281)                 s_wrbuf_wr_en   <= '1';
282)             END IF;
283)             -- take over new_start and new_end
284)             n_rx_start <= r_rx_new_start;
285)             n_rx_cur   <= std_logic_vector(unsigned(r_rx_new_start) + X"00000004");
286)             n_rx_size  <= X"00000000";
287)             n_rx_end   <= r_rx_new_end;
288)             -- signal overtake of new buffer to process p_write
289)             s_rx_new   <= '1';
290)         END IF;
291)     END PROCESS p_rx_next;
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

292) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

293)     p_rx_sync: PROCESS(rst, clk)
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

294)     BEGIN
295)         IF rst = '1' THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

296)             r_rx_start     <= X"00000000";
297)             r_rx_cur       <= X"00000004";
298)             r_rx_size      <= X"00000000";
299)             r_rx_end       <= X"00000000";
300)             r_rx_new_start <= X"00000000";
301)             r_rx_new_end   <= X"00000000";
302)             r_rx_new_en    <= '0';
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

303)         ELSIF rising_edge(clk) THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

304)             r_rx_start     <= n_rx_start;
305)             r_rx_cur       <= n_rx_cur;
306)             r_rx_size      <= n_rx_size;
307)             r_rx_end       <= n_rx_end;
308)             r_rx_new_start <= n_rx_new_start;
309)             r_rx_new_end   <= n_rx_new_end;
310)             r_rx_new_en    <= n_rx_new_en;
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

311)         END IF;
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

312)     END PROCESS p_rx_sync;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

313) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

314)     -- register interface write
315)     p_write: PROCESS(r_rx_new_start, r_rx_new_end, r_rx_new_en,
316)                      s_rx_new,
317)                      i_addr, i_wr_data, i_wr_en)
318)     BEGIN
319)         n_rx_new_start <= r_rx_new_start;
320)         n_rx_new_end   <= r_rx_new_end;
321)         n_rx_new_en    <= r_rx_new_en;
322)         IF s_rx_new = '1' THEN
323)             n_rx_new_en <= '0'; -- new buffer has been overtaken, reset new_en
324)         END IF;
325)         IF i_wr_en = "1111" THEN
326)             CASE i_addr IS
327)                 WHEN "100" => n_rx_new_start <= i_wr_data;
328)                 WHEN "101" => n_rx_new_end   <= i_wr_data;
329)                 WHEN "110" => n_rx_new_en    <= i_wr_data(0);
330)                 WHEN OTHERS => NULL;
331)             END CASE;
332)         END IF;
333)     END PROCESS p_write;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

334) 
Stefan Schuermans implemented ethernet TX int...

Stefan Schuermans authored 12 years ago

335)     txif: e_io_eth_txif
336)         PORT MAP (
337)             rst          => rst,
338)             clk          => clk,
339)             i_data       => s_txif_data,
340)             i_data_en    => s_txif_data_en,
341)             o_data_ack   => s_txif_data_ack,
342)             pin_i_tx_clk => pin_i_tx_clk,
343)             pin_o_txd    => pin_o_txd,
344)             pin_o_tx_en  => pin_o_tx_en
345)         );
346) 
347)     -- TODO
348)     s_txif_data    <= X"00";
349)     s_txif_data_en <= '0';
350) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

351)     -- register interface read
352)     p_read: PROCESS(rst, clk)
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

353)     BEGIN
354)         IF rst = '1' THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

355)             o_rd_data <= (OTHERS => '0');
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

356)         ELSIF rising_edge(clk) THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

357)             o_rd_data <= (OTHERS => '0');
358)             CASE i_addr IS
359)                 WHEN "000" => o_rd_data    <= r_rx_start;
360)                 WHEN "001" => o_rd_data    <= r_rx_cur;
361)                 WHEN "010" => o_rd_data    <= r_rx_size;
362)                 WHEN "011" => o_rd_data    <= r_rx_end;
363)                 WHEN "100" => o_rd_data    <= r_rx_new_start;
364)                 WHEN "101" => o_rd_data    <= r_rx_new_end;
365)                 WHEN "110" => o_rd_data(0) <= r_rx_new_en;
366)                 WHEN OTHERS => NULL;
367)             END CASE;
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

368)         END IF;
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

369)     END PROCESS p_read;
370) 
371)     -- bus master write buffer
372)     --   as the core has lower bus priority than ethernet,
373)     --   the core will never access memory or ethernet registers
374)     --   when data is in this buffer
375)     wrbuf: e_block_fifo
376)         GENERIC MAP (
377)             addr_width => 2,
378)             data_width => 64
379)         )
380)         PORT MAP (
381)             rst       => rst,
382)             clk       => clk,
383)             o_wr_rdy  => s_wrbuf_wr_rdy,
384)             i_wr_data => s_wrbuf_wr_data,
385)             i_wr_en   => s_wrbuf_wr_en,
386)             o_rd_rdy  => s_wrbuf_rd_rdy,
387)             o_rd_data => s_wrbuf_rd_data,
388)             i_rd_en   => s_wrbuf_rd_en
389)         );
390) 
391)     pin_o_txd   <= "0000";
392)     pin_o_tx_en <= '0';
393) 
394)     -- bus master write
395)     p_bm_wr: PROCESS(s_wrbuf_rd_rdy, s_wrbuf_rd_data, i_bm_grant)
396)     BEGIN
397)         s_wrbuf_rd_en <= '0';
398)         o_bm_req      <= '0';
399)         o_bm_addr     <= (OTHERS => '0');
400)         o_bm_rd_en    <= (OTHERS => '0');
401)         o_bm_wr_data  <= (OTHERS => '0');
402)         o_bm_wr_en    <= (OTHERS => '0');
403)         -- process write requests from write buffer
404)         IF s_wrbuf_rd_rdy = '1' THEN
405)             s_wrbuf_rd_en <= i_bm_grant;
406)             o_bm_req      <= '1';
407)             o_bm_addr     <= s_wrbuf_rd_data(63 DOWNTO 32);
408)             o_bm_wr_data  <= s_wrbuf_rd_data(31 DOWNTO  0);
409)             o_bm_wr_en    <= "1111";
410)         END IF;        
411)     END PROCESS p_bm_wr;
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

412)