c906a48b0ededd4b309f78a0e70d657e561dad0a
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 RX bus...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

108)     COMPONENT e_io_eth_rxframe IS
109)         PORT (
110)             rst:       IN  std_logic;
111)             clk:       IN  std_logic;
112)             i_data:    IN  std_logic_vector( 7 DOWNTO 0);
113)             i_data_en: IN  std_logic;
114)             i_done:    IN  std_logic;
115)             i_err:     IN  std_logic;
116)             i_mac:     IN  std_logic_vector(47 DOWNTO 0);
117)             o_data:    OUT std_logic_vector(31 DOWNTO 0);
118)             o_data_en: OUT std_logic;
119)             o_done:    OUT std_logic;
120)             o_err:     OUT std_logic
121)         );
122)     END COMPONENT e_io_eth_rxframe;
123) 
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

124)     COMPONENT e_block_fifo IS
125)         GENERIC (
126)             addr_width: natural;
127)             data_width: natural
128)         );
129)         PORT (
130)             rst:       IN  std_logic;
131)             clk:       IN  std_logic;
132)             o_wr_rdy:  OUT std_logic;
133)             i_wr_data: IN  std_logic_vector(data_width - 1 DOWNTO 0);
134)             i_wr_en:   IN  std_logic;
135)             o_rd_rdy:  OUT std_logic;
136)             o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
137)             i_rd_en:   IN  std_logic
138)         );
139)     END COMPONENT e_block_fifo;
140) 
141) BEGIN
142) 
143)     reset: e_io_eth_rst
144)         PORT MAP (
145)             rst        => rst,
146)             clk        => clk,
147)             pin_o_nrst => pin_o_nrst
148)         );
149) 
150)     rxif: e_io_eth_rxif
151)         PORT MAP (
152)             rst          => rst,
153)             clk          => clk,
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

154)             o_data       => s_rxif_data,
155)             o_data_en    => s_rxif_data_en,
156)             o_done       => s_rxif_done,
157)             o_err        => s_rxif_err,
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

158)             pin_i_rx_clk => pin_i_rx_clk,
159)             pin_i_rxd    => pin_i_rxd,
160)             pin_i_rx_dv  => pin_i_rx_dv,
161)             pin_i_crs    => pin_i_crs,
162)             pin_i_col    => pin_i_col
163)         );
164) 
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

165)     rxframe: e_io_eth_rxframe
166)         PORT MAP (
167)             rst       => rst,
168)             clk       => clk,
169)             i_data    => s_rxif_data,
170)             i_data_en => s_rxif_data_en,
171)             i_done    => s_rxif_done,
172)             i_err     => s_rxif_err,
173)             i_mac     => X"070605040302",
174)             o_data    => s_rxframe_data,
175)             o_data_en => s_rxframe_data_en,
176)             o_done    => s_rxframe_done,
177)             o_err     => s_rxframe_err
178)         );
179) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

180)     p_rx_next: PROCESS(r_rx_start, r_rx_cur, r_rx_size, r_rx_end,
181)                        r_rx_new_start, r_rx_new_end, r_rx_new_en,
182)                        s_rxframe_data, s_rxframe_data_en,
183)                        s_rxframe_done, s_rxframe_err,
184)                        s_wrbuf_wr_rdy)
185)         VARIABLE v_abort:  boolean; -- abort current packet reception
186)         VARIABLE v_ignore: boolean; -- ignore rest of packet
187)         VARIABLE v_store:  boolean; -- store packet data
188)         VARIABLE v_finish: boolean; -- finish reception of packet
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

190)         n_rx_start      <= r_rx_start;
191)         n_rx_cur        <= r_rx_cur;
192)         n_rx_size       <= r_rx_size;
193)         n_rx_end        <= r_rx_end;
194)         s_wrbuf_wr_data <= (OTHERS => '0');
195)         s_wrbuf_wr_en   <= '0';
196)         s_rx_new        <= '0';
197) 
198)         -- determine which action to perform
199)         v_abort  := false;
200)         v_ignore := false;
201)         v_store  := false;
202)         v_finish := false;
203)         -- incoming data
204)         IF s_rxframe_data_en = '1' THEN
205)             IF r_rx_start = r_rx_end THEN
206)                 v_ignore := true; -- buffer not available -> ignore rest of packet
207)             ELSIF r_rx_cur = r_rx_end THEN
208)                 v_ignore := true; -- buffer full -> ignore rest of packet
209)             ELSIF s_wrbuf_wr_rdy = '0' THEN
210)                 v_ignore := true; -- bus master write buffer full -> ignore rest of packet
211)             ELSE
212)                 v_store := true; -- store data
213)             END IF;
214)         -- packet complete
Stefan Schuermans implemented ethernet RX fra...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

216)             IF r_rx_start = r_rx_end THEN
217)                 v_abort := true; -- buffer not available -> abort
218)             ELSIF r_rx_cur = r_rx_end THEN
219)                 v_abort := true; -- buffer full -> abort
220)             ELSIF s_wrbuf_wr_rdy = '0' THEN
221)                 v_abort := true; -- bus master write buffer full -> abort
222)             ELSIF r_rx_size = X"00000000" THEN
223)                 v_abort := true; -- empty packet -> abort
224)             ELSE
225)                 v_finish := true; -- finish packet recpetion
226)             END IF;
227)         -- error
228)         ELSIF s_rxframe_err = '1' THEN
229)             v_abort := true; -- abort
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

230)         END IF;
231) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

232)         -- perform action selected above
233)         -- abort current packet
234)         IF v_abort THEN
235)             n_rx_cur  <= std_logic_vector(unsigned(r_rx_start) + X"00000004");
236)             n_rx_size <= X"00000000";
237)         -- ignore rest of packet
238)         --   count size to ensure it is not zero
239)         ELSIF v_ignore THEN
240)             n_rx_cur  <= r_rx_end;
241)             n_rx_size <= std_logic_vector(unsigned(r_rx_size) + X"00000004");
242)         -- store data to current address and advance in buffer
243)         ELSIF v_store THEN
244)             s_wrbuf_wr_data <= r_rx_cur & s_rxframe_data;
245)             s_wrbuf_wr_en   <= '1';
246)             n_rx_cur  <= std_logic_vector(unsigned(r_rx_cur) + X"00000004");
247)             n_rx_size <= std_logic_vector(unsigned(r_rx_size) + X"00000004");
248)         -- store size to start and restart after packet
249)         ELSIF v_finish THEN
250)             s_wrbuf_wr_data <= r_rx_start & r_rx_size;
251)             s_wrbuf_wr_en   <= '1';
252)             n_rx_start <= r_rx_cur;
253)             n_rx_cur   <= std_logic_vector(unsigned(r_rx_cur) + X"00000004");
254)             n_rx_size  <= X"00000000";
255)         END IF;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

256) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

257)         -- use new buffer
258)         --   if no action, no data yet and new_en set
259)         IF NOT v_abort AND NOT v_ignore AND NOT v_store AND NOT v_finish AND
260)            r_rx_size = X"00000000" AND r_rx_new_en = '1' THEN
261)             -- terminate old buffer by writing size 0 (if old buffer was available)
262)             IF r_rx_start /= r_rx_end THEN
263)                 s_wrbuf_wr_data <= r_rx_start & X"00000000";
264)                 s_wrbuf_wr_en   <= '1';
265)             END IF;
266)             -- take over new_start and new_end
267)             n_rx_start <= r_rx_new_start;
268)             n_rx_cur   <= std_logic_vector(unsigned(r_rx_new_start) + X"00000004");
269)             n_rx_size  <= X"00000000";
270)             n_rx_end   <= r_rx_new_end;
271)             -- signal overtake of new buffer to process p_write
272)             s_rx_new   <= '1';
273)         END IF;
274)     END PROCESS p_rx_next;
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

275) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

277)     BEGIN
278)         IF rst = '1' THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

279)             r_rx_start     <= X"00000000";
280)             r_rx_cur       <= X"00000004";
281)             r_rx_size      <= X"00000000";
282)             r_rx_end       <= X"00000000";
283)             r_rx_new_start <= X"00000000";
284)             r_rx_new_end   <= X"00000000";
285)             r_rx_new_en    <= '0';
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

287)             r_rx_start     <= n_rx_start;
288)             r_rx_cur       <= n_rx_cur;
289)             r_rx_size      <= n_rx_size;
290)             r_rx_end       <= n_rx_end;
291)             r_rx_new_start <= n_rx_new_start;
292)             r_rx_new_end   <= n_rx_new_end;
293)             r_rx_new_en    <= n_rx_new_en;
Stefan Schuermans fix reading (1 cycle latenc...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

296) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

297)     -- register interface write
298)     p_write: PROCESS(r_rx_new_start, r_rx_new_end, r_rx_new_en,
299)                      s_rx_new,
300)                      i_addr, i_wr_data, i_wr_en)
301)     BEGIN
302)         n_rx_new_start <= r_rx_new_start;
303)         n_rx_new_end   <= r_rx_new_end;
304)         n_rx_new_en    <= r_rx_new_en;
305)         IF s_rx_new = '1' THEN
306)             n_rx_new_en <= '0'; -- new buffer has been overtaken, reset new_en
307)         END IF;
308)         IF i_wr_en = "1111" THEN
309)             CASE i_addr IS
310)                 WHEN "100" => n_rx_new_start <= i_wr_data;
311)                 WHEN "101" => n_rx_new_end   <= i_wr_data;
312)                 WHEN "110" => n_rx_new_en    <= i_wr_data(0);
313)                 WHEN OTHERS => NULL;
314)             END CASE;
315)         END IF;
316)     END PROCESS p_write;
Stefan Schuermans begin of ethernet RX implem...

Stefan Schuermans authored 12 years ago

317) 
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

320)     BEGIN
321)         IF rst = '1' THEN
Stefan Schuermans implemented ethernet RX bus...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

324)             o_rd_data <= (OTHERS => '0');
325)             CASE i_addr IS
326)                 WHEN "000" => o_rd_data    <= r_rx_start;
327)                 WHEN "001" => o_rd_data    <= r_rx_cur;
328)                 WHEN "010" => o_rd_data    <= r_rx_size;
329)                 WHEN "011" => o_rd_data    <= r_rx_end;
330)                 WHEN "100" => o_rd_data    <= r_rx_new_start;
331)                 WHEN "101" => o_rd_data    <= r_rx_new_end;
332)                 WHEN "110" => o_rd_data(0) <= r_rx_new_en;
333)                 WHEN OTHERS => NULL;
334)             END CASE;
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

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

Stefan Schuermans authored 12 years ago

336)     END PROCESS p_read;
337) 
338)     -- bus master write buffer
339)     --   as the core has lower bus priority than ethernet,
340)     --   the core will never access memory or ethernet registers
341)     --   when data is in this buffer
342)     wrbuf: e_block_fifo
343)         GENERIC MAP (
344)             addr_width => 2,
345)             data_width => 64
346)         )
347)         PORT MAP (
348)             rst       => rst,
349)             clk       => clk,
350)             o_wr_rdy  => s_wrbuf_wr_rdy,
351)             i_wr_data => s_wrbuf_wr_data,
352)             i_wr_en   => s_wrbuf_wr_en,
353)             o_rd_rdy  => s_wrbuf_rd_rdy,
354)             o_rd_data => s_wrbuf_rd_data,
355)             i_rd_en   => s_wrbuf_rd_en
356)         );
357) 
358)     pin_o_txd   <= "0000";
359)     pin_o_tx_en <= '0';
360) 
361)     -- bus master write
362)     p_bm_wr: PROCESS(s_wrbuf_rd_rdy, s_wrbuf_rd_data, i_bm_grant)
363)     BEGIN
364)         s_wrbuf_rd_en <= '0';
365)         o_bm_req      <= '0';
366)         o_bm_addr     <= (OTHERS => '0');
367)         o_bm_rd_en    <= (OTHERS => '0');
368)         o_bm_wr_data  <= (OTHERS => '0');
369)         o_bm_wr_en    <= (OTHERS => '0');
370)         -- process write requests from write buffer
371)         IF s_wrbuf_rd_rdy = '1' THEN
372)             s_wrbuf_rd_en <= i_bm_grant;
373)             o_bm_req      <= '1';
374)             o_bm_addr     <= s_wrbuf_rd_data(63 DOWNTO 32);
375)             o_bm_wr_data  <= s_wrbuf_rd_data(31 DOWNTO  0);
376)             o_bm_wr_en    <= "1111";
377)         END IF;        
378)     END PROCESS p_bm_wr;
Stefan Schuermans implemented multi-master fe...

Stefan Schuermans authored 12 years ago

379)