]> git.zerfleddert.de Git - raggedstone/blame - ethernet/source/ethernet/eth_wishbone.v
add shit
[raggedstone] / ethernet / source / ethernet / eth_wishbone.v
CommitLineData
40a1f26c 1//////////////////////////////////////////////////////////////////////
2//// ////
3//// eth_wishbone.v ////
4//// ////
5//// This file is part of the Ethernet IP core project ////
6//// http://www.opencores.org/projects/ethmac/ ////
7//// ////
8//// Author(s): ////
9//// - Igor Mohor (igorM@opencores.org) ////
10//// ////
11//// All additional information is available in the Readme.txt ////
12//// file. ////
13//// ////
14//////////////////////////////////////////////////////////////////////
15//// ////
16//// Copyright (C) 2001, 2002 Authors ////
17//// ////
18//// This source file may be used and distributed without ////
19//// restriction provided that this copyright statement is not ////
20//// removed from the file and that any derivative work contains ////
21//// the original copyright notice and the associated disclaimer. ////
22//// ////
23//// This source file is free software; you can redistribute it ////
24//// and/or modify it under the terms of the GNU Lesser General ////
25//// Public License as published by the Free Software Foundation; ////
26//// either version 2.1 of the License, or (at your option) any ////
27//// later version. ////
28//// ////
29//// This source is distributed in the hope that it will be ////
30//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
31//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
32//// PURPOSE. See the GNU Lesser General Public License for more ////
33//// details. ////
34//// ////
35//// You should have received a copy of the GNU Lesser General ////
36//// Public License along with this source; if not, download it ////
37//// from http://www.opencores.org/lgpl.shtml ////
38//// ////
39//////////////////////////////////////////////////////////////////////
40//
41// CVS Revision History
42//
43// $Log: eth_wishbone.v,v $
44// Revision 1.1 2007-03-20 17:50:56 sithglan
45// add shit
46//
47// Revision 1.58 2005/03/21 20:07:18 igorm
48// Some small fixes + some troubles fixed.
49//
50// Revision 1.57 2005/02/21 11:35:33 igorm
51// Defer indication fixed.
52//
53// Revision 1.56 2004/04/30 10:30:00 igorm
54// Accidently deleted line put back.
55//
56// Revision 1.55 2004/04/26 15:26:23 igorm
57// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the
58// previous update of the core.
59// - TxBDAddress is set to 0 after the TX is enabled in the MODER register.
60// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER
61// register. (thanks to Mathias and Torbjorn)
62// - Multicast reception was fixed. Thanks to Ulrich Gries
63//
64// Revision 1.54 2003/11/12 18:24:59 tadejm
65// WISHBONE slave changed and tested from only 32-bit accesss to byte access.
66//
67// Revision 1.53 2003/10/17 07:46:17 markom
68// mbist signals updated according to newest convention
69//
70// Revision 1.52 2003/01/30 14:51:31 mohor
71// Reset has priority in some flipflops.
72//
73// Revision 1.51 2003/01/30 13:36:22 mohor
74// A new bug (entered with previous update) fixed. When abort occured sometimes
75// data transmission was blocked.
76//
77// Revision 1.50 2003/01/22 13:49:26 tadejm
78// When control packets were received, they were ignored in some cases.
79//
80// Revision 1.49 2003/01/21 12:09:40 mohor
81// When receiving normal data frame and RxFlow control was switched on, RXB
82// interrupt was not set.
83//
84// Revision 1.48 2003/01/20 12:05:26 mohor
85// When in full duplex, transmit was sometimes blocked. Fixed.
86//
87// Revision 1.47 2002/11/22 13:26:21 mohor
88// Registers RxStatusWrite_rck and RxStatusWriteLatched were not used
89// anywhere. Removed.
90//
91// Revision 1.46 2002/11/22 01:57:06 mohor
92// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort
93// synchronized.
94//
95// Revision 1.45 2002/11/19 17:33:34 mohor
96// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying
97// that a frame was received because of the promiscous mode.
98//
99// Revision 1.44 2002/11/13 22:21:40 tadejm
100// RxError is not generated when small frame reception is enabled and small
101// frames are received.
102//
103// Revision 1.43 2002/10/18 20:53:34 mohor
104// case changed to casex.
105//
106// Revision 1.42 2002/10/18 17:04:20 tadejm
107// Changed BIST scan signals.
108//
109// Revision 1.41 2002/10/18 15:42:09 tadejm
110// Igor added WB burst support and repaired BUG when handling TX under-run and retry.
111//
112// Revision 1.40 2002/10/14 16:07:02 mohor
113// TxStatus is written after last access to the TX fifo is finished (in case of abort
114// or retry). TxDone is fixed.
115//
116// Revision 1.39 2002/10/11 15:35:20 mohor
117// txfifo_cnt and rxfifo_cnt counters width is defined in the eth_define.v file,
118// TxDone and TxRetry are generated after the current WISHBONE access is
119// finished.
120//
121// Revision 1.38 2002/10/10 16:29:30 mohor
122// BIST added.
123//
124// Revision 1.37 2002/09/11 14:18:46 mohor
125// Sometimes both RxB_IRQ and RxE_IRQ were activated. Bug fixed.
126//
127// Revision 1.36 2002/09/10 13:48:46 mohor
128// Reception is possible after RxPointer is read and not after BD is read. For
129// that reason RxBDReady is changed to RxReady.
130// Busy_IRQ interrupt connected. When there is no RxBD ready and frame
131// comes, interrupt is generated.
132//
133// Revision 1.35 2002/09/10 10:35:23 mohor
134// Ethernet debug registers removed.
135//
136// Revision 1.34 2002/09/08 16:31:49 mohor
137// Async reset for WB_ACK_O removed (when core was in reset, it was
138// impossible to access BDs).
139// RxPointers and TxPointers names changed to be more descriptive.
140// TxUnderRun synchronized.
141//
142// Revision 1.33 2002/09/04 18:47:57 mohor
143// Debug registers reg1, 2, 3, 4 connected. Synchronization of many signals
144// changed (bugs fixed). Access to un-alligned buffers fixed. RxAbort signal
145// was not used OK.
146//
147// Revision 1.32 2002/08/14 19:31:48 mohor
148// Register TX_BD_NUM is changed so it contains value of the Tx buffer descriptors. No
149// need to multiply or devide any more.
150//
151// Revision 1.31 2002/07/25 18:29:01 mohor
152// WriteRxDataToMemory signal changed so end of frame (when last word is
153// written to fifo) is changed.
154//
155// Revision 1.30 2002/07/23 15:28:31 mohor
156// Ram , used for BDs changed from generic_spram to eth_spram_256x32.
157//
158// Revision 1.29 2002/07/20 00:41:32 mohor
159// ShiftEnded synchronization changed.
160//
161// Revision 1.28 2002/07/18 16:11:46 mohor
162// RxBDAddress takes `ETH_TX_BD_NUM_DEF value after reset.
163//
164// Revision 1.27 2002/07/11 02:53:20 mohor
165// RxPointer bug fixed.
166//
167// Revision 1.26 2002/07/10 13:12:38 mohor
168// Previous bug wasn't succesfully removed. Now fixed.
169//
170// Revision 1.25 2002/07/09 23:53:24 mohor
171// Master state machine had a bug when switching from master write to
172// master read.
173//
174// Revision 1.24 2002/07/09 20:44:41 mohor
175// m_wb_cyc_o signal released after every single transfer.
176//
177// Revision 1.23 2002/05/03 10:15:50 mohor
178// Outputs registered. Reset changed for eth_wishbone module.
179//
180// Revision 1.22 2002/04/24 08:52:19 mohor
181// Compiler directives added. Tx and Rx fifo size incremented. A "late collision"
182// bug fixed.
183//
184// Revision 1.21 2002/03/29 16:18:11 lampret
185// Small typo fixed.
186//
187// Revision 1.20 2002/03/25 16:19:12 mohor
188// Any address can be used for Tx and Rx BD pointers. Address does not need
189// to be aligned.
190//
191// Revision 1.19 2002/03/19 12:51:50 mohor
192// Comments in Slovene language removed.
193//
194// Revision 1.18 2002/03/19 12:46:52 mohor
195// casex changed with case, fifo reset changed.
196//
197// Revision 1.17 2002/03/09 16:08:45 mohor
198// rx_fifo was not always cleared ok. Fixed.
199//
200// Revision 1.16 2002/03/09 13:51:20 mohor
201// Status was not latched correctly sometimes. Fixed.
202//
203// Revision 1.15 2002/03/08 06:56:46 mohor
204// Big Endian problem when sending frames fixed.
205//
206// Revision 1.14 2002/03/02 19:12:40 mohor
207// Byte ordering changed (Big Endian used). casex changed with case because
208// Xilinx Foundation had problems. Tested in HW. It WORKS.
209//
210// Revision 1.13 2002/02/26 16:59:55 mohor
211// Small fixes for external/internal DMA missmatches.
212//
213// Revision 1.12 2002/02/26 16:22:07 mohor
214// Interrupts changed
215//
216// Revision 1.11 2002/02/15 17:07:39 mohor
217// Status was not written correctly when frames were discarted because of
218// address mismatch.
219//
220// Revision 1.10 2002/02/15 12:17:39 mohor
221// RxStartFrm cleared when abort or retry comes.
222//
223// Revision 1.9 2002/02/15 11:59:10 mohor
224// Changes that were lost when updating from 1.5 to 1.8 fixed.
225//
226// Revision 1.8 2002/02/14 20:54:33 billditt
227// Addition of new module eth_addrcheck.v
228//
229// Revision 1.7 2002/02/12 17:03:47 mohor
230// RxOverRun added to statuses.
231//
232// Revision 1.6 2002/02/11 09:18:22 mohor
233// Tx status is written back to the BD.
234//
235// Revision 1.5 2002/02/08 16:21:54 mohor
236// Rx status is written back to the BD.
237//
238// Revision 1.4 2002/02/06 14:10:21 mohor
239// non-DMA host interface added. Select the right configutation in eth_defines.
240//
241// Revision 1.3 2002/02/05 16:44:39 mohor
242// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200
243// MHz. Statuses, overrun, control frame transmission and reception still need
244// to be fixed.
245//
246// Revision 1.2 2002/02/01 12:46:51 mohor
247// Tx part finished. TxStatus needs to be fixed. Pause request needs to be
248// added.
249//
250// Revision 1.1 2002/01/23 10:47:59 mohor
251// Initial version. Equals to eth_wishbonedma.v at this moment.
252//
253//
254//
255
256`include "eth_defines.v"
257`include "timescale.v"
258
259
260module eth_wishbone
261 (
262
263 // WISHBONE common
264 WB_CLK_I, WB_DAT_I, WB_DAT_O,
265
266 // WISHBONE slave
267 WB_ADR_I, WB_WE_I, WB_ACK_O,
268 BDCs,
269
270 Reset,
271
272 // WISHBONE master
273 m_wb_adr_o, m_wb_sel_o, m_wb_we_o,
274 m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o,
275 m_wb_stb_o, m_wb_ack_i, m_wb_err_i,
276
277`ifdef ETH_WISHBONE_B3
278 m_wb_cti_o, m_wb_bte_o,
279`endif
280
281 //TX
282 MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData,
283 TxRetry, TxAbort, TxUnderRun, TxDone, PerPacketCrcEn,
284 PerPacketPad,
285
286 //RX
287 MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort, RxStatusWriteLatched_sync2,
288
289 // Register
290 r_TxEn, r_RxEn, r_TxBDNum, r_RxFlow, r_PassAll,
291
292 // Interrupts
293 TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ,
294
295 // Rx Status
296 InvalidSymbol, LatchedCrcError, RxLateCollision, ShortFrame, DribbleNibble,
297 ReceivedPacketTooBig, RxLength, LoadRxStatus, ReceivedPacketGood, AddressMiss,
298 ReceivedPauseFrm,
299
300 // Tx Status
301 RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, RstDeferLatched, CarrierSenseLost
302
303 // Bist
304`ifdef ETH_BIST
305 ,
306 // debug chain signals
307 mbist_si_i, // bist scan serial in
308 mbist_so_o, // bist scan serial out
309 mbist_ctrl_i // bist chain shift control
310`endif
311
312
313
314 );
315
316
317parameter Tp = 1;
318
319
320// WISHBONE common
321input WB_CLK_I; // WISHBONE clock
322input [31:0] WB_DAT_I; // WISHBONE data input
323output [31:0] WB_DAT_O; // WISHBONE data output
324
325// WISHBONE slave
326input [9:2] WB_ADR_I; // WISHBONE address input
327input WB_WE_I; // WISHBONE write enable input
328input [3:0] BDCs; // Buffer descriptors are selected
329output WB_ACK_O; // WISHBONE acknowledge output
330
331// WISHBONE master
332output [29:0] m_wb_adr_o; //
333output [3:0] m_wb_sel_o; //
334output m_wb_we_o; //
335output [31:0] m_wb_dat_o; //
336output m_wb_cyc_o; //
337output m_wb_stb_o; //
338input [31:0] m_wb_dat_i; //
339input m_wb_ack_i; //
340input m_wb_err_i; //
341
342`ifdef ETH_WISHBONE_B3
343output [2:0] m_wb_cti_o; // Cycle Type Identifier
344output [1:0] m_wb_bte_o; // Burst Type Extension
345reg [2:0] m_wb_cti_o; // Cycle Type Identifier
346`endif
347
348input Reset; // Reset signal
349
350// Rx Status signals
351input InvalidSymbol; // Invalid symbol was received during reception in 100 Mbps mode
352input LatchedCrcError; // CRC error
353input RxLateCollision; // Late collision occured while receiving frame
354input ShortFrame; // Frame shorter then the minimum size (r_MinFL) was received while small packets are enabled (r_RecSmall)
355input DribbleNibble; // Extra nibble received
356input ReceivedPacketTooBig;// Received packet is bigger than r_MaxFL
357input [15:0] RxLength; // Length of the incoming frame
358input LoadRxStatus; // Rx status was loaded
359input ReceivedPacketGood;// Received packet's length and CRC are good
360input AddressMiss; // When a packet is received AddressMiss status is written to the Rx BD
361input r_RxFlow;
362input r_PassAll;
363input ReceivedPauseFrm;
364
365// Tx Status signals
366input [3:0] RetryCntLatched; // Latched Retry Counter
367input RetryLimit; // Retry limit reached (Retry Max value + 1 attempts were made)
368input LateCollLatched; // Late collision occured
369input DeferLatched; // Defer indication (Frame was defered before sucessfully sent)
370output RstDeferLatched;
371input CarrierSenseLost; // Carrier Sense was lost during the frame transmission
372
373// Tx
374input MTxClk; // Transmit clock (from PHY)
375input TxUsedData; // Transmit packet used data
376input TxRetry; // Transmit packet retry
377input TxAbort; // Transmit packet abort
378input TxDone; // Transmission ended
379output TxStartFrm; // Transmit packet start frame
380output TxEndFrm; // Transmit packet end frame
381output [7:0] TxData; // Transmit packet data byte
382output TxUnderRun; // Transmit packet under-run
383output PerPacketCrcEn; // Per packet crc enable
384output PerPacketPad; // Per packet pading
385
386// Rx
387input MRxClk; // Receive clock (from PHY)
388input [7:0] RxData; // Received data byte (from PHY)
389input RxValid; //
390input RxStartFrm; //
391input RxEndFrm; //
392input RxAbort; // This signal is set when address doesn't match.
393output RxStatusWriteLatched_sync2;
394
395//Register
396input r_TxEn; // Transmit enable
397input r_RxEn; // Receive enable
398input [7:0] r_TxBDNum; // Receive buffer descriptor number
399
400// Interrupts
401output TxB_IRQ;
402output TxE_IRQ;
403output RxB_IRQ;
404output RxE_IRQ;
405output Busy_IRQ;
406
407
408// Bist
409`ifdef ETH_BIST
410input mbist_si_i; // bist scan serial in
411output mbist_so_o; // bist scan serial out
412input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control
413`endif
414
415reg TxB_IRQ;
416reg TxE_IRQ;
417reg RxB_IRQ;
418reg RxE_IRQ;
419
420reg TxStartFrm;
421reg TxEndFrm;
422reg [7:0] TxData;
423
424reg TxUnderRun;
425reg TxUnderRun_wb;
426
427reg TxBDRead;
428wire TxStatusWrite;
429
430reg [1:0] TxValidBytesLatched;
431
432reg [15:0] TxLength;
433reg [15:0] LatchedTxLength;
434reg [14:11] TxStatus;
435
436reg [14:13] RxStatus;
437
438reg TxStartFrm_wb;
439reg TxRetry_wb;
440reg TxAbort_wb;
441reg TxDone_wb;
442
443reg TxDone_wb_q;
444reg TxAbort_wb_q;
445reg TxRetry_wb_q;
446reg TxRetryPacket;
447reg TxRetryPacket_NotCleared;
448reg TxDonePacket;
449reg TxDonePacket_NotCleared;
450reg TxAbortPacket;
451reg TxAbortPacket_NotCleared;
452reg RxBDReady;
453reg RxReady;
454reg TxBDReady;
455
456reg RxBDRead;
457
458reg [31:0] TxDataLatched;
459reg [1:0] TxByteCnt;
460reg LastWord;
461reg ReadTxDataFromFifo_tck;
462
463reg BlockingTxStatusWrite;
464reg BlockingTxBDRead;
465
466reg Flop;
467
468reg [7:1] TxBDAddress;
469reg [7:1] RxBDAddress;
470
471reg TxRetrySync1;
472reg TxAbortSync1;
473reg TxDoneSync1;
474
475reg TxAbort_q;
476reg TxRetry_q;
477reg TxUsedData_q;
478
479reg [31:0] RxDataLatched2;
480
481reg [31:8] RxDataLatched1; // Big Endian Byte Ordering
482
483reg [1:0] RxValidBytes;
484reg [1:0] RxByteCnt;
485reg LastByteIn;
486reg ShiftWillEnd;
487
488reg WriteRxDataToFifo;
489reg [15:0] LatchedRxLength;
490reg RxAbortLatched;
491
492reg ShiftEnded;
493reg RxOverrun;
494
495reg [3:0] BDWrite; // BD Write Enable for access from WISHBONE side
496reg BDRead; // BD Read access from WISHBONE side
497wire [31:0] RxBDDataIn; // Rx BD data in
498wire [31:0] TxBDDataIn; // Tx BD data in
499
500reg TxEndFrm_wb;
501
502wire TxRetryPulse;
503wire TxDonePulse;
504wire TxAbortPulse;
505
506wire StartRxBDRead;
507
508wire StartTxBDRead;
509
510wire TxIRQEn;
511wire WrapTxStatusBit;
512
513wire RxIRQEn;
514wire WrapRxStatusBit;
515
516wire [1:0] TxValidBytes;
517
518wire [7:1] TempTxBDAddress;
519wire [7:1] TempRxBDAddress;
520
521wire RxStatusWrite;
522wire RxBufferFull;
523wire RxBufferAlmostEmpty;
524wire RxBufferEmpty;
525
526reg WB_ACK_O;
527
528wire [8:0] RxStatusIn;
529reg [8:0] RxStatusInLatched;
530
531reg WbEn, WbEn_q;
532reg RxEn, RxEn_q;
533reg TxEn, TxEn_q;
534reg r_TxEn_q;
535reg r_RxEn_q;
536
537wire ram_ce;
538wire [3:0] ram_we;
539wire ram_oe;
540reg [7:0] ram_addr;
541reg [31:0] ram_di;
542wire [31:0] ram_do;
543
544wire StartTxPointerRead;
545reg TxPointerRead;
546reg TxEn_needed;
547reg RxEn_needed;
548
549wire StartRxPointerRead;
550reg RxPointerRead;
551
552`ifdef ETH_WISHBONE_B3
553assign m_wb_bte_o = 2'b00; // Linear burst
554`endif
555
556assign m_wb_stb_o = m_wb_cyc_o;
557
558always @ (posedge WB_CLK_I)
559begin
560 WB_ACK_O <=#Tp (|BDWrite) & WbEn & WbEn_q | BDRead & WbEn & ~WbEn_q;
561end
562
563assign WB_DAT_O = ram_do;
564
565// Generic synchronous single-port RAM interface
566eth_spram_256x32 bd_ram (
567 .clk(WB_CLK_I), .rst(Reset), .ce(ram_ce), .we(ram_we), .oe(ram_oe), .addr(ram_addr), .di(ram_di), .do(ram_do)
568`ifdef ETH_BIST
569 ,
570 .mbist_si_i (mbist_si_i),
571 .mbist_so_o (mbist_so_o),
572 .mbist_ctrl_i (mbist_ctrl_i)
573`endif
574);
575
576assign ram_ce = 1'b1;
577assign ram_we = (BDWrite & {4{(WbEn & WbEn_q)}}) | {4{(TxStatusWrite | RxStatusWrite)}};
578assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead);
579
580
581always @ (posedge WB_CLK_I or posedge Reset)
582begin
583 if(Reset)
584 TxEn_needed <=#Tp 1'b0;
585 else
586 if(~TxBDReady & r_TxEn & WbEn & ~WbEn_q)
587 TxEn_needed <=#Tp 1'b1;
588 else
589 if(TxPointerRead & TxEn & TxEn_q)
590 TxEn_needed <=#Tp 1'b0;
591end
592
593// Enabling access to the RAM for three devices.
594always @ (posedge WB_CLK_I or posedge Reset)
595begin
596 if(Reset)
597 begin
598 WbEn <=#Tp 1'b1;
599 RxEn <=#Tp 1'b0;
600 TxEn <=#Tp 1'b0;
601 ram_addr <=#Tp 8'h0;
602 ram_di <=#Tp 32'h0;
603 BDRead <=#Tp 1'b0;
604 BDWrite <=#Tp 1'b0;
605 end
606 else
607 begin
608 // Switching between three stages depends on enable signals
609 case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed}) // synopsys parallel_case
610 5'b100_10, 5'b100_11 :
611 begin
612 WbEn <=#Tp 1'b0;
613 RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled
614 TxEn <=#Tp 1'b0;
615 ram_addr <=#Tp {RxBDAddress, RxPointerRead};
616 ram_di <=#Tp RxBDDataIn;
617 end
618 5'b100_01 :
619 begin
620 WbEn <=#Tp 1'b0;
621 RxEn <=#Tp 1'b0;
622 TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled
623 ram_addr <=#Tp {TxBDAddress, TxPointerRead};
624 ram_di <=#Tp TxBDDataIn;
625 end
626 5'b010_00, 5'b010_10 :
627 begin
628 WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled
629 RxEn <=#Tp 1'b0;
630 TxEn <=#Tp 1'b0;
631 ram_addr <=#Tp WB_ADR_I[9:2];
632 ram_di <=#Tp WB_DAT_I;
633 BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};
634 BDRead <=#Tp (|BDCs) & ~WB_WE_I;
635 end
636 5'b010_01, 5'b010_11 :
637 begin
638 WbEn <=#Tp 1'b0;
639 RxEn <=#Tp 1'b0;
640 TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled
641 ram_addr <=#Tp {TxBDAddress, TxPointerRead};
642 ram_di <=#Tp TxBDDataIn;
643 end
644 5'b001_00, 5'b001_01, 5'b001_10, 5'b001_11 :
645 begin
646 WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage)
647 RxEn <=#Tp 1'b0;
648 TxEn <=#Tp 1'b0;
649 ram_addr <=#Tp WB_ADR_I[9:2];
650 ram_di <=#Tp WB_DAT_I;
651 BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};
652 BDRead <=#Tp (|BDCs) & ~WB_WE_I;
653 end
654 5'b100_00 :
655 begin
656 WbEn <=#Tp 1'b0; // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit
657 end
658 5'b000_00 :
659 begin
660 WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage.
661 RxEn <=#Tp 1'b0;
662 TxEn <=#Tp 1'b0;
663 ram_addr <=#Tp WB_ADR_I[9:2];
664 ram_di <=#Tp WB_DAT_I;
665 BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}};
666 BDRead <=#Tp (|BDCs) & ~WB_WE_I;
667 end
668 endcase
669 end
670end
671
672
673// Delayed stage signals
674always @ (posedge WB_CLK_I or posedge Reset)
675begin
676 if(Reset)
677 begin
678 WbEn_q <=#Tp 1'b0;
679 RxEn_q <=#Tp 1'b0;
680 TxEn_q <=#Tp 1'b0;
681 r_TxEn_q <=#Tp 1'b0;
682 r_RxEn_q <=#Tp 1'b0;
683 end
684 else
685 begin
686 WbEn_q <=#Tp WbEn;
687 RxEn_q <=#Tp RxEn;
688 TxEn_q <=#Tp TxEn;
689 r_TxEn_q <=#Tp r_TxEn;
690 r_RxEn_q <=#Tp r_RxEn;
691 end
692end
693
694// Changes for tx occur every second clock. Flop is used for this manner.
695always @ (posedge MTxClk or posedge Reset)
696begin
697 if(Reset)
698 Flop <=#Tp 1'b0;
699 else
700 if(TxDone | TxAbort | TxRetry_q)
701 Flop <=#Tp 1'b0;
702 else
703 if(TxUsedData)
704 Flop <=#Tp ~Flop;
705end
706
707wire ResetTxBDReady;
708assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;
709
710// Latching READY status of the Tx buffer descriptor
711always @ (posedge WB_CLK_I or posedge Reset)
712begin
713 if(Reset)
714 TxBDReady <=#Tp 1'b0;
715 else
716 if(TxEn & TxEn_q & TxBDRead)
717 TxBDReady <=#Tp ram_do[15] & (ram_do[31:16] > 4); // TxBDReady is sampled only once at the beginning.
718 else // Only packets larger then 4 bytes are transmitted.
719 if(ResetTxBDReady)
720 TxBDReady <=#Tp 1'b0;
721end
722
723
724// Reading the Tx buffer descriptor
725assign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) & ~BlockingTxBDRead & ~TxBDReady;
726
727always @ (posedge WB_CLK_I or posedge Reset)
728begin
729 if(Reset)
730 TxBDRead <=#Tp 1'b1;
731 else
732 if(StartTxBDRead)
733 TxBDRead <=#Tp 1'b1;
734 else
735 if(TxBDReady)
736 TxBDRead <=#Tp 1'b0;
737end
738
739
740// Reading Tx BD pointer
741assign StartTxPointerRead = TxBDRead & TxBDReady;
742
743// Reading Tx BD Pointer
744always @ (posedge WB_CLK_I or posedge Reset)
745begin
746 if(Reset)
747 TxPointerRead <=#Tp 1'b0;
748 else
749 if(StartTxPointerRead)
750 TxPointerRead <=#Tp 1'b1;
751 else
752 if(TxEn_q)
753 TxPointerRead <=#Tp 1'b0;
754end
755
756
757// Writing status back to the Tx buffer descriptor
758assign TxStatusWrite = (TxDonePacket_NotCleared | TxAbortPacket_NotCleared) & TxEn & TxEn_q & ~BlockingTxStatusWrite;
759
760
761
762// Status writing must occur only once. Meanwhile it is blocked.
763always @ (posedge WB_CLK_I or posedge Reset)
764begin
765 if(Reset)
766 BlockingTxStatusWrite <=#Tp 1'b0;
767 else
768 if(~TxDone_wb & ~TxAbort_wb)
769 BlockingTxStatusWrite <=#Tp 1'b0;
770 else
771 if(TxStatusWrite)
772 BlockingTxStatusWrite <=#Tp 1'b1;
773end
774
775
776reg BlockingTxStatusWrite_sync1;
777reg BlockingTxStatusWrite_sync2;
778reg BlockingTxStatusWrite_sync3;
779
780// Synchronizing BlockingTxStatusWrite to MTxClk
781always @ (posedge MTxClk or posedge Reset)
782begin
783 if(Reset)
784 BlockingTxStatusWrite_sync1 <=#Tp 1'b0;
785 else
786 BlockingTxStatusWrite_sync1 <=#Tp BlockingTxStatusWrite;
787end
788
789// Synchronizing BlockingTxStatusWrite to MTxClk
790always @ (posedge MTxClk or posedge Reset)
791begin
792 if(Reset)
793 BlockingTxStatusWrite_sync2 <=#Tp 1'b0;
794 else
795 BlockingTxStatusWrite_sync2 <=#Tp BlockingTxStatusWrite_sync1;
796end
797
798// Synchronizing BlockingTxStatusWrite to MTxClk
799always @ (posedge MTxClk or posedge Reset)
800begin
801 if(Reset)
802 BlockingTxStatusWrite_sync3 <=#Tp 1'b0;
803 else
804 BlockingTxStatusWrite_sync3 <=#Tp BlockingTxStatusWrite_sync2;
805end
806
807assign RstDeferLatched = BlockingTxStatusWrite_sync2 & ~BlockingTxStatusWrite_sync3;
808
809// TxBDRead state is activated only once.
810always @ (posedge WB_CLK_I or posedge Reset)
811begin
812 if(Reset)
813 BlockingTxBDRead <=#Tp 1'b0;
814 else
815 if(StartTxBDRead)
816 BlockingTxBDRead <=#Tp 1'b1;
817 else
818 if(~StartTxBDRead & ~TxBDReady)
819 BlockingTxBDRead <=#Tp 1'b0;
820end
821
822
823// Latching status from the tx buffer descriptor
824// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)
825always @ (posedge WB_CLK_I or posedge Reset)
826begin
827 if(Reset)
828 TxStatus <=#Tp 4'h0;
829 else
830 if(TxEn & TxEn_q & TxBDRead)
831 TxStatus <=#Tp ram_do[14:11];
832end
833
834reg ReadTxDataFromMemory;
835wire WriteRxDataToMemory;
836
837reg MasterWbTX;
838reg MasterWbRX;
839
840reg [29:0] m_wb_adr_o;
841reg m_wb_cyc_o;
842reg [3:0] m_wb_sel_o;
843reg m_wb_we_o;
844
845wire TxLengthEq0;
846wire TxLengthLt4;
847
848reg BlockingIncrementTxPointer;
849reg [31:2] TxPointerMSB;
850reg [1:0] TxPointerLSB;
851reg [1:0] TxPointerLSB_rst;
852reg [31:2] RxPointerMSB;
853reg [1:0] RxPointerLSB_rst;
854
855wire RxBurstAcc;
856wire RxWordAcc;
857wire RxHalfAcc;
858wire RxByteAcc;
859
860//Latching length from the buffer descriptor;
861always @ (posedge WB_CLK_I or posedge Reset)
862begin
863 if(Reset)
864 TxLength <=#Tp 16'h0;
865 else
866 if(TxEn & TxEn_q & TxBDRead)
867 TxLength <=#Tp ram_do[31:16];
868 else
869 if(MasterWbTX & m_wb_ack_i)
870 begin
871 if(TxLengthLt4)
872 TxLength <=#Tp 16'h0;
873 else
874 if(TxPointerLSB_rst==2'h0)
875 TxLength <=#Tp TxLength - 3'h4; // Length is subtracted at the data request
876 else
877 if(TxPointerLSB_rst==2'h1)
878 TxLength <=#Tp TxLength - 3'h3; // Length is subtracted at the data request
879 else
880 if(TxPointerLSB_rst==2'h2)
881 TxLength <=#Tp TxLength - 3'h2; // Length is subtracted at the data request
882 else
883 if(TxPointerLSB_rst==2'h3)
884 TxLength <=#Tp TxLength - 3'h1; // Length is subtracted at the data request
885 end
886end
887
888
889
890//Latching length from the buffer descriptor;
891always @ (posedge WB_CLK_I or posedge Reset)
892begin
893 if(Reset)
894 LatchedTxLength <=#Tp 16'h0;
895 else
896 if(TxEn & TxEn_q & TxBDRead)
897 LatchedTxLength <=#Tp ram_do[31:16];
898end
899
900assign TxLengthEq0 = TxLength == 0;
901assign TxLengthLt4 = TxLength < 4;
902
903reg cyc_cleared;
904reg IncrTxPointer;
905
906
907// Latching Tx buffer pointer from buffer descriptor. Only 30 MSB bits are latched
908// because TxPointerMSB is only used for word-aligned accesses.
909always @ (posedge WB_CLK_I or posedge Reset)
910begin
911 if(Reset)
912 TxPointerMSB <=#Tp 30'h0;
913 else
914 if(TxEn & TxEn_q & TxPointerRead)
915 TxPointerMSB <=#Tp ram_do[31:2];
916 else
917 if(IncrTxPointer & ~BlockingIncrementTxPointer)
918 TxPointerMSB <=#Tp TxPointerMSB + 1'b1; // TxPointer is word-aligned
919end
920
921
922// Latching 2 MSB bits of the buffer descriptor. Since word accesses are performed,
923// valid data does not necesserly start at byte 0 (could be byte 0, 1, 2 or 3). This
924// signals are used for proper selection of the start byte (TxData and TxByteCnt) are
925// set by this two bits.
926always @ (posedge WB_CLK_I or posedge Reset)
927begin
928 if(Reset)
929 TxPointerLSB[1:0] <=#Tp 0;
930 else
931 if(TxEn & TxEn_q & TxPointerRead)
932 TxPointerLSB[1:0] <=#Tp ram_do[1:0];
933end
934
935
936// Latching 2 MSB bits of the buffer descriptor.
937// After the read access, TxLength needs to be decremented for the number of the valid
938// bytes (1 to 4 bytes are valid in the first word). After the first read all bytes are
939// valid so this two bits are reset to zero.
940always @ (posedge WB_CLK_I or posedge Reset)
941begin
942 if(Reset)
943 TxPointerLSB_rst[1:0] <=#Tp 0;
944 else
945 if(TxEn & TxEn_q & TxPointerRead)
946 TxPointerLSB_rst[1:0] <=#Tp ram_do[1:0];
947 else
948 if(MasterWbTX & m_wb_ack_i) // After first access pointer is word alligned
949 TxPointerLSB_rst[1:0] <=#Tp 0;
950end
951
952
953reg [3:0] RxByteSel;
954wire MasterAccessFinished;
955
956
957always @ (posedge WB_CLK_I or posedge Reset)
958begin
959 if(Reset)
960 BlockingIncrementTxPointer <=#Tp 0;
961 else
962 if(MasterAccessFinished)
963 BlockingIncrementTxPointer <=#Tp 0;
964 else
965 if(IncrTxPointer)
966 BlockingIncrementTxPointer <=#Tp 1'b1;
967end
968
969
970wire TxBufferAlmostFull;
971wire TxBufferFull;
972wire TxBufferEmpty;
973wire TxBufferAlmostEmpty;
974wire SetReadTxDataFromMemory;
975
976reg BlockReadTxDataFromMemory;
977
978assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;
979
980always @ (posedge WB_CLK_I or posedge Reset)
981begin
982 if(Reset)
983 ReadTxDataFromMemory <=#Tp 1'b0;
984 else
985 if(TxLengthEq0 | TxAbortPulse | TxRetryPulse)
986 ReadTxDataFromMemory <=#Tp 1'b0;
987 else
988 if(SetReadTxDataFromMemory)
989 ReadTxDataFromMemory <=#Tp 1'b1;
990end
991
992reg tx_burst_en;
993reg rx_burst_en;
994
995wire ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~BlockReadTxDataFromMemory;
996wire tx_burst = ReadTxDataFromMemory_2 & tx_burst_en;
997
998wire [31:0] TxData_wb;
999wire ReadTxDataFromFifo_wb;
1000
1001always @ (posedge WB_CLK_I or posedge Reset)
1002begin
1003 if(Reset)
1004 BlockReadTxDataFromMemory <=#Tp 1'b0;
1005 else
1006 if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX & (~cyc_cleared) & (!(TxAbortPacket_NotCleared | TxRetryPacket_NotCleared)))
1007 BlockReadTxDataFromMemory <=#Tp 1'b1;
1008 else
1009 if(ReadTxDataFromFifo_wb | TxDonePacket | TxAbortPacket | TxRetryPacket)
1010 BlockReadTxDataFromMemory <=#Tp 1'b0;
1011end
1012
1013
1014assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
1015wire [`ETH_TX_FIFO_CNT_WIDTH-1:0] txfifo_cnt;
1016wire [`ETH_RX_FIFO_CNT_WIDTH-1:0] rxfifo_cnt;
1017reg [`ETH_BURST_CNT_WIDTH-1:0] tx_burst_cnt;
1018reg [`ETH_BURST_CNT_WIDTH-1:0] rx_burst_cnt;
1019
1020wire rx_burst;
1021wire enough_data_in_rxfifo_for_burst;
1022wire enough_data_in_rxfifo_for_burst_plus1;
1023
1024// Enabling master wishbone access to the memory for two devices TX and RX.
1025always @ (posedge WB_CLK_I or posedge Reset)
1026begin
1027 if(Reset)
1028 begin
1029 MasterWbTX <=#Tp 1'b0;
1030 MasterWbRX <=#Tp 1'b0;
1031 m_wb_adr_o <=#Tp 30'h0;
1032 m_wb_cyc_o <=#Tp 1'b0;
1033 m_wb_we_o <=#Tp 1'b0;
1034 m_wb_sel_o <=#Tp 4'h0;
1035 cyc_cleared<=#Tp 1'b0;
1036 tx_burst_cnt<=#Tp 0;
1037 rx_burst_cnt<=#Tp 0;
1038 IncrTxPointer<=#Tp 1'b0;
1039 tx_burst_en<=#Tp 1'b1;
1040 rx_burst_en<=#Tp 1'b0;
1041 `ifdef ETH_WISHBONE_B3
1042 m_wb_cti_o <=#Tp 3'b0;
1043 `endif
1044 end
1045 else
1046 begin
1047 // Switching between two stages depends on enable signals
1048 casex ({MasterWbTX, MasterWbRX, ReadTxDataFromMemory_2, WriteRxDataToMemory, MasterAccessFinished, cyc_cleared, tx_burst, rx_burst}) // synopsys parallel_case
1049 8'b00_10_00_10, // Idle and MRB needed
1050 8'b10_1x_10_1x, // MRB continues
1051 8'b10_10_01_10, // Clear (previously MR) and MRB needed
1052 8'b01_1x_01_1x : // Clear (previously MW) and MRB needed
1053 begin
1054 MasterWbTX <=#Tp 1'b1; // tx burst
1055 MasterWbRX <=#Tp 1'b0;
1056 m_wb_cyc_o <=#Tp 1'b1;
1057 m_wb_we_o <=#Tp 1'b0;
1058 m_wb_sel_o <=#Tp 4'hf;
1059 cyc_cleared<=#Tp 1'b0;
1060 IncrTxPointer<=#Tp 1'b1;
1061 tx_burst_cnt <=#Tp tx_burst_cnt+3'h1;
1062 if(tx_burst_cnt==0)
1063 m_wb_adr_o <=#Tp TxPointerMSB;
1064 else
1065 m_wb_adr_o <=#Tp m_wb_adr_o+1'b1;
1066
1067 if(tx_burst_cnt==(`ETH_BURST_LENGTH-1))
1068 begin
1069 tx_burst_en<=#Tp 1'b0;
1070 `ifdef ETH_WISHBONE_B3
1071 m_wb_cti_o <=#Tp 3'b111;
1072 `endif
1073 end
1074 else
1075 begin
1076 `ifdef ETH_WISHBONE_B3
1077 m_wb_cti_o <=#Tp 3'b010;
1078 `endif
1079 end
1080 end
1081 8'b00_x1_00_x1, // Idle and MWB needed
1082 8'b01_x1_10_x1, // MWB continues
1083 8'b01_01_01_01, // Clear (previously MW) and MWB needed
1084 8'b10_x1_01_x1 : // Clear (previously MR) and MWB needed
1085 begin
1086 MasterWbTX <=#Tp 1'b0; // rx burst
1087 MasterWbRX <=#Tp 1'b1;
1088 m_wb_cyc_o <=#Tp 1'b1;
1089 m_wb_we_o <=#Tp 1'b1;
1090 m_wb_sel_o <=#Tp RxByteSel;
1091 IncrTxPointer<=#Tp 1'b0;
1092 cyc_cleared<=#Tp 1'b0;
1093 rx_burst_cnt <=#Tp rx_burst_cnt+3'h1;
1094
1095 if(rx_burst_cnt==0)
1096 m_wb_adr_o <=#Tp RxPointerMSB;
1097 else
1098 m_wb_adr_o <=#Tp m_wb_adr_o+1'b1;
1099
1100 if(rx_burst_cnt==(`ETH_BURST_LENGTH-1))
1101 begin
1102 rx_burst_en<=#Tp 1'b0;
1103 `ifdef ETH_WISHBONE_B3
1104 m_wb_cti_o <=#Tp 3'b111;
1105 `endif
1106 end
1107 else
1108 begin
1109 `ifdef ETH_WISHBONE_B3
1110 m_wb_cti_o <=#Tp 3'b010;
1111 `endif
1112 end
1113 end
1114 8'b00_x1_00_x0 : // idle and MW is needed (data write to rx buffer)
1115 begin
1116 MasterWbTX <=#Tp 1'b0;
1117 MasterWbRX <=#Tp 1'b1;
1118 m_wb_adr_o <=#Tp RxPointerMSB;
1119 m_wb_cyc_o <=#Tp 1'b1;
1120 m_wb_we_o <=#Tp 1'b1;
1121 m_wb_sel_o <=#Tp RxByteSel;
1122 IncrTxPointer<=#Tp 1'b0;
1123 end
1124 8'b00_10_00_00 : // idle and MR is needed (data read from tx buffer)
1125 begin
1126 MasterWbTX <=#Tp 1'b1;
1127 MasterWbRX <=#Tp 1'b0;
1128 m_wb_adr_o <=#Tp TxPointerMSB;
1129 m_wb_cyc_o <=#Tp 1'b1;
1130 m_wb_we_o <=#Tp 1'b0;
1131 m_wb_sel_o <=#Tp 4'hf;
1132 IncrTxPointer<=#Tp 1'b1;
1133 end
1134 8'b10_10_01_00, // MR and MR is needed (data read from tx buffer)
1135 8'b01_1x_01_0x : // MW and MR is needed (data read from tx buffer)
1136 begin
1137 MasterWbTX <=#Tp 1'b1;
1138 MasterWbRX <=#Tp 1'b0;
1139 m_wb_adr_o <=#Tp TxPointerMSB;
1140 m_wb_cyc_o <=#Tp 1'b1;
1141 m_wb_we_o <=#Tp 1'b0;
1142 m_wb_sel_o <=#Tp 4'hf;
1143 cyc_cleared<=#Tp 1'b0;
1144 IncrTxPointer<=#Tp 1'b1;
1145 end
1146 8'b01_01_01_00, // MW and MW needed (data write to rx buffer)
1147 8'b10_x1_01_x0 : // MR and MW is needed (data write to rx buffer)
1148 begin
1149 MasterWbTX <=#Tp 1'b0;
1150 MasterWbRX <=#Tp 1'b1;
1151 m_wb_adr_o <=#Tp RxPointerMSB;
1152 m_wb_cyc_o <=#Tp 1'b1;
1153 m_wb_we_o <=#Tp 1'b1;
1154 m_wb_sel_o <=#Tp RxByteSel;
1155 cyc_cleared<=#Tp 1'b0;
1156 IncrTxPointer<=#Tp 1'b0;
1157 end
1158 8'b01_01_10_00, // MW and MW needed (cycle is cleared between previous and next access)
1159 8'b01_1x_10_x0, // MW and MW or MR or MRB needed (cycle is cleared between previous and next access)
1160 8'b10_10_10_00, // MR and MR needed (cycle is cleared between previous and next access)
1161 8'b10_x1_10_0x : // MR and MR or MW or MWB (cycle is cleared between previous and next access)
1162 begin
1163 m_wb_cyc_o <=#Tp 1'b0; // whatever and master read or write is needed. We need to clear m_wb_cyc_o before next access is started
1164 cyc_cleared<=#Tp 1'b1;
1165 IncrTxPointer<=#Tp 1'b0;
1166 tx_burst_cnt<=#Tp 0;
1167 tx_burst_en<=#Tp txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4));
1168 rx_burst_cnt<=#Tp 0;
1169 rx_burst_en<=#Tp MasterWbRX ? enough_data_in_rxfifo_for_burst_plus1 : enough_data_in_rxfifo_for_burst; // Counter is not decremented, yet, so plus1 is used.
1170 `ifdef ETH_WISHBONE_B3
1171 m_wb_cti_o <=#Tp 3'b0;
1172 `endif
1173 end
1174 8'bxx_00_10_00, // whatever and no master read or write is needed (ack or err comes finishing previous access)
1175 8'bxx_00_01_00 : // Between cyc_cleared request was cleared
1176 begin
1177 MasterWbTX <=#Tp 1'b0;
1178 MasterWbRX <=#Tp 1'b0;
1179 m_wb_cyc_o <=#Tp 1'b0;
1180 cyc_cleared<=#Tp 1'b0;
1181 IncrTxPointer<=#Tp 1'b0;
1182 rx_burst_cnt<=#Tp 0;
1183 rx_burst_en<=#Tp MasterWbRX ? enough_data_in_rxfifo_for_burst_plus1 : enough_data_in_rxfifo_for_burst; // Counter is not decremented, yet, so plus1 is used.
1184 `ifdef ETH_WISHBONE_B3
1185 m_wb_cti_o <=#Tp 3'b0;
1186 `endif
1187 end
1188 8'b00_00_00_00: // whatever and no master read or write is needed (ack or err comes finishing previous access)
1189 begin
1190 tx_burst_cnt<=#Tp 0;
1191 tx_burst_en<=#Tp txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4));
1192 end
1193 default: // Don't touch
1194 begin
1195 MasterWbTX <=#Tp MasterWbTX;
1196 MasterWbRX <=#Tp MasterWbRX;
1197 m_wb_cyc_o <=#Tp m_wb_cyc_o;
1198 m_wb_sel_o <=#Tp m_wb_sel_o;
1199 IncrTxPointer<=#Tp IncrTxPointer;
1200 end
1201 endcase
1202 end
1203end
1204
1205
1206wire TxFifoClear;
1207
1208assign TxFifoClear = (TxAbortPacket | TxRetryPacket);
1209
1210eth_fifo #(`ETH_TX_FIFO_DATA_WIDTH, `ETH_TX_FIFO_DEPTH, `ETH_TX_FIFO_CNT_WIDTH)
1211tx_fifo ( .data_in(m_wb_dat_i), .data_out(TxData_wb),
1212 .clk(WB_CLK_I), .reset(Reset),
1213 .write(MasterWbTX & m_wb_ack_i), .read(ReadTxDataFromFifo_wb & ~TxBufferEmpty),
1214 .clear(TxFifoClear), .full(TxBufferFull),
1215 .almost_full(TxBufferAlmostFull), .almost_empty(TxBufferAlmostEmpty),
1216 .empty(TxBufferEmpty), .cnt(txfifo_cnt)
1217 );
1218
1219
1220reg StartOccured;
1221reg TxStartFrm_sync1;
1222reg TxStartFrm_sync2;
1223reg TxStartFrm_syncb1;
1224reg TxStartFrm_syncb2;
1225
1226
1227
1228// Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
1229always @ (posedge WB_CLK_I or posedge Reset)
1230begin
1231 if(Reset)
1232 TxStartFrm_wb <=#Tp 1'b0;
1233 else
1234 if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
1235 TxStartFrm_wb <=#Tp 1'b1;
1236 else
1237 if(TxStartFrm_syncb2)
1238 TxStartFrm_wb <=#Tp 1'b0;
1239end
1240
1241// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
1242always @ (posedge WB_CLK_I or posedge Reset)
1243begin
1244 if(Reset)
1245 StartOccured <=#Tp 1'b0;
1246 else
1247 if(TxStartFrm_wb)
1248 StartOccured <=#Tp 1'b1;
1249 else
1250 if(ResetTxBDReady)
1251 StartOccured <=#Tp 1'b0;
1252end
1253
1254// Synchronizing TxStartFrm_wb to MTxClk
1255always @ (posedge MTxClk or posedge Reset)
1256begin
1257 if(Reset)
1258 TxStartFrm_sync1 <=#Tp 1'b0;
1259 else
1260 TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
1261end
1262
1263always @ (posedge MTxClk or posedge Reset)
1264begin
1265 if(Reset)
1266 TxStartFrm_sync2 <=#Tp 1'b0;
1267 else
1268 TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
1269end
1270
1271always @ (posedge WB_CLK_I or posedge Reset)
1272begin
1273 if(Reset)
1274 TxStartFrm_syncb1 <=#Tp 1'b0;
1275 else
1276 TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
1277end
1278
1279always @ (posedge WB_CLK_I or posedge Reset)
1280begin
1281 if(Reset)
1282 TxStartFrm_syncb2 <=#Tp 1'b0;
1283 else
1284 TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
1285end
1286
1287always @ (posedge MTxClk or posedge Reset)
1288begin
1289 if(Reset)
1290 TxStartFrm <=#Tp 1'b0;
1291 else
1292 if(TxStartFrm_sync2)
1293 TxStartFrm <=#Tp 1'b1;
1294 else
1295 if(TxUsedData_q | ~TxStartFrm_sync2 & (TxRetry & (~TxRetry_q) | TxAbort & (~TxAbort_q)))
1296 TxStartFrm <=#Tp 1'b0;
1297end
1298// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
1299
1300
1301// TxEndFrm_wb: indicator of the end of frame
1302always @ (posedge WB_CLK_I or posedge Reset)
1303begin
1304 if(Reset)
1305 TxEndFrm_wb <=#Tp 1'b0;
1306 else
1307 if(TxLengthEq0 & TxBufferAlmostEmpty & TxUsedData)
1308 TxEndFrm_wb <=#Tp 1'b1;
1309 else
1310 if(TxRetryPulse | TxDonePulse | TxAbortPulse)
1311 TxEndFrm_wb <=#Tp 1'b0;
1312end
1313
1314
1315// Marks which bytes are valid within the word.
1316assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
1317
1318reg LatchValidBytes;
1319reg LatchValidBytes_q;
1320
1321always @ (posedge WB_CLK_I or posedge Reset)
1322begin
1323 if(Reset)
1324 LatchValidBytes <=#Tp 1'b0;
1325 else
1326 if(TxLengthLt4 & TxBDReady)
1327 LatchValidBytes <=#Tp 1'b1;
1328 else
1329 LatchValidBytes <=#Tp 1'b0;
1330end
1331
1332always @ (posedge WB_CLK_I or posedge Reset)
1333begin
1334 if(Reset)
1335 LatchValidBytes_q <=#Tp 1'b0;
1336 else
1337 LatchValidBytes_q <=#Tp LatchValidBytes;
1338end
1339
1340
1341// Latching valid bytes
1342always @ (posedge WB_CLK_I or posedge Reset)
1343begin
1344 if(Reset)
1345 TxValidBytesLatched <=#Tp 2'h0;
1346 else
1347 if(LatchValidBytes & ~LatchValidBytes_q)
1348 TxValidBytesLatched <=#Tp TxValidBytes;
1349 else
1350 if(TxRetryPulse | TxDonePulse | TxAbortPulse)
1351 TxValidBytesLatched <=#Tp 2'h0;
1352end
1353
1354
1355assign TxIRQEn = TxStatus[14];
1356assign WrapTxStatusBit = TxStatus[13];
1357assign PerPacketPad = TxStatus[12];
1358assign PerPacketCrcEn = TxStatus[11];
1359
1360
1361assign RxIRQEn = RxStatus[14];
1362assign WrapRxStatusBit = RxStatus[13];
1363
1364
1365// Temporary Tx and Rx buffer descriptor address
1366assign TempTxBDAddress[7:1] = {7{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1'b1) ; // Tx BD increment or wrap (last BD)
1367assign TempRxBDAddress[7:1] = {7{ WrapRxStatusBit}} & (r_TxBDNum[6:0]) | // Using first Rx BD
1368 {7{~WrapRxStatusBit}} & (RxBDAddress + 1'b1) ; // Using next Rx BD (incremenrement address)
1369
1370
1371// Latching Tx buffer descriptor address
1372always @ (posedge WB_CLK_I or posedge Reset)
1373begin
1374 if(Reset)
1375 TxBDAddress <=#Tp 7'h0;
1376 else if (r_TxEn & (~r_TxEn_q))
1377 TxBDAddress <=#Tp 7'h0;
1378 else if (TxStatusWrite)
1379 TxBDAddress <=#Tp TempTxBDAddress;
1380end
1381
1382
1383// Latching Rx buffer descriptor address
1384always @ (posedge WB_CLK_I or posedge Reset)
1385begin
1386 if(Reset)
1387 RxBDAddress <=#Tp 7'h0;
1388 else if(r_RxEn & (~r_RxEn_q))
1389 RxBDAddress <=#Tp r_TxBDNum[6:0];
1390 else if(RxStatusWrite)
1391 RxBDAddress <=#Tp TempRxBDAddress;
1392end
1393
1394wire [8:0] TxStatusInLatched = {TxUnderRun, RetryCntLatched[3:0], RetryLimit, LateCollLatched, DeferLatched, CarrierSenseLost};
1395
1396assign RxBDDataIn = {LatchedRxLength, 1'b0, RxStatus, 4'h0, RxStatusInLatched};
1397assign TxBDDataIn = {LatchedTxLength, 1'b0, TxStatus, 2'h0, TxStatusInLatched};
1398
1399
1400// Signals used for various purposes
1401assign TxRetryPulse = TxRetry_wb & ~TxRetry_wb_q;
1402assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
1403assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
1404
1405
1406
1407// Generating delayed signals
1408always @ (posedge MTxClk or posedge Reset)
1409begin
1410 if(Reset)
1411 begin
1412 TxAbort_q <=#Tp 1'b0;
1413 TxRetry_q <=#Tp 1'b0;
1414 TxUsedData_q <=#Tp 1'b0;
1415 end
1416 else
1417 begin
1418 TxAbort_q <=#Tp TxAbort;
1419 TxRetry_q <=#Tp TxRetry;
1420 TxUsedData_q <=#Tp TxUsedData;
1421 end
1422end
1423
1424// Generating delayed signals
1425always @ (posedge WB_CLK_I or posedge Reset)
1426begin
1427 if(Reset)
1428 begin
1429 TxDone_wb_q <=#Tp 1'b0;
1430 TxAbort_wb_q <=#Tp 1'b0;
1431 TxRetry_wb_q <=#Tp 1'b0;
1432 end
1433 else
1434 begin
1435 TxDone_wb_q <=#Tp TxDone_wb;
1436 TxAbort_wb_q <=#Tp TxAbort_wb;
1437 TxRetry_wb_q <=#Tp TxRetry_wb;
1438 end
1439end
1440
1441
1442reg TxAbortPacketBlocked;
1443always @ (posedge WB_CLK_I or posedge Reset)
1444begin
1445 if(Reset)
1446 TxAbortPacket <=#Tp 1'b0;
1447 else
1448 if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
1449 TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
1450 TxAbortPacket <=#Tp 1'b1;
1451 else
1452 TxAbortPacket <=#Tp 1'b0;
1453end
1454
1455
1456always @ (posedge WB_CLK_I or posedge Reset)
1457begin
1458 if(Reset)
1459 TxAbortPacket_NotCleared <=#Tp 1'b0;
1460 else
1461 if(TxEn & TxEn_q & TxAbortPacket_NotCleared)
1462 TxAbortPacket_NotCleared <=#Tp 1'b0;
1463 else
1464 if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
1465 TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
1466 TxAbortPacket_NotCleared <=#Tp 1'b1;
1467end
1468
1469
1470always @ (posedge WB_CLK_I or posedge Reset)
1471begin
1472 if(Reset)
1473 TxAbortPacketBlocked <=#Tp 1'b0;
1474 else
1475 if(!TxAbort_wb & TxAbort_wb_q)
1476 TxAbortPacketBlocked <=#Tp 1'b0;
1477 else
1478 if(TxAbortPacket)
1479 TxAbortPacketBlocked <=#Tp 1'b1;
1480end
1481
1482
1483reg TxRetryPacketBlocked;
1484always @ (posedge WB_CLK_I or posedge Reset)
1485begin
1486 if(Reset)
1487 TxRetryPacket <=#Tp 1'b0;
1488 else
1489 if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
1490 TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
1491 TxRetryPacket <=#Tp 1'b1;
1492 else
1493 TxRetryPacket <=#Tp 1'b0;
1494end
1495
1496
1497always @ (posedge WB_CLK_I or posedge Reset)
1498begin
1499 if(Reset)
1500 TxRetryPacket_NotCleared <=#Tp 1'b0;
1501 else
1502 if(StartTxBDRead)
1503 TxRetryPacket_NotCleared <=#Tp 1'b0;
1504 else
1505 if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
1506 TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
1507 TxRetryPacket_NotCleared <=#Tp 1'b1;
1508end
1509
1510
1511always @ (posedge WB_CLK_I or posedge Reset)
1512begin
1513 if(Reset)
1514 TxRetryPacketBlocked <=#Tp 1'b0;
1515 else
1516 if(!TxRetry_wb & TxRetry_wb_q)
1517 TxRetryPacketBlocked <=#Tp 1'b0;
1518 else
1519 if(TxRetryPacket)
1520 TxRetryPacketBlocked <=#Tp 1'b1;
1521end
1522
1523
1524reg TxDonePacketBlocked;
1525always @ (posedge WB_CLK_I or posedge Reset)
1526begin
1527 if(Reset)
1528 TxDonePacket <=#Tp 1'b0;
1529 else
1530 if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxDonePacketBlocked |
1531 TxDone_wb & !MasterWbTX & !TxDonePacketBlocked)
1532 TxDonePacket <=#Tp 1'b1;
1533 else
1534 TxDonePacket <=#Tp 1'b0;
1535end
1536
1537
1538always @ (posedge WB_CLK_I or posedge Reset)
1539begin
1540 if(Reset)
1541 TxDonePacket_NotCleared <=#Tp 1'b0;
1542 else
1543 if(TxEn & TxEn_q & TxDonePacket_NotCleared)
1544 TxDonePacket_NotCleared <=#Tp 1'b0;
1545 else
1546 if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & (~TxDonePacketBlocked) |
1547 TxDone_wb & !MasterWbTX & (~TxDonePacketBlocked))
1548 TxDonePacket_NotCleared <=#Tp 1'b1;
1549end
1550
1551
1552always @ (posedge WB_CLK_I or posedge Reset)
1553begin
1554 if(Reset)
1555 TxDonePacketBlocked <=#Tp 1'b0;
1556 else
1557 if(!TxDone_wb & TxDone_wb_q)
1558 TxDonePacketBlocked <=#Tp 1'b0;
1559 else
1560 if(TxDonePacket)
1561 TxDonePacketBlocked <=#Tp 1'b1;
1562end
1563
1564
1565// Indication of the last word
1566always @ (posedge MTxClk or posedge Reset)
1567begin
1568 if(Reset)
1569 LastWord <=#Tp 1'b0;
1570 else
1571 if((TxEndFrm | TxAbort | TxRetry) & Flop)
1572 LastWord <=#Tp 1'b0;
1573 else
1574 if(TxUsedData & Flop & TxByteCnt == 2'h3)
1575 LastWord <=#Tp TxEndFrm_wb;
1576end
1577
1578
1579// Tx end frame generation
1580always @ (posedge MTxClk or posedge Reset)
1581begin
1582 if(Reset)
1583 TxEndFrm <=#Tp 1'b0;
1584 else
1585 if(Flop & TxEndFrm | TxAbort | TxRetry_q)
1586 TxEndFrm <=#Tp 1'b0;
1587 else
1588 if(Flop & LastWord)
1589 begin
1590 case (TxValidBytesLatched) // synopsys parallel_case
1591 1 : TxEndFrm <=#Tp TxByteCnt == 2'h0;
1592 2 : TxEndFrm <=#Tp TxByteCnt == 2'h1;
1593 3 : TxEndFrm <=#Tp TxByteCnt == 2'h2;
1594 0 : TxEndFrm <=#Tp TxByteCnt == 2'h3;
1595 default : TxEndFrm <=#Tp 1'b0;
1596 endcase
1597 end
1598end
1599
1600
1601// Tx data selection (latching)
1602always @ (posedge MTxClk or posedge Reset)
1603begin
1604 if(Reset)
1605 TxData <=#Tp 0;
1606 else
1607 if(TxStartFrm_sync2 & ~TxStartFrm)
1608 case(TxPointerLSB) // synopsys parallel_case
1609 2'h0 : TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering
1610 2'h1 : TxData <=#Tp TxData_wb[23:16]; // Big Endian Byte Ordering
1611 2'h2 : TxData <=#Tp TxData_wb[15:08]; // Big Endian Byte Ordering
1612 2'h3 : TxData <=#Tp TxData_wb[07:00]; // Big Endian Byte Ordering
1613 endcase
1614 else
1615 if(TxStartFrm & TxUsedData & TxPointerLSB==2'h3)
1616 TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering
1617 else
1618 if(TxUsedData & Flop)
1619 begin
1620 case(TxByteCnt) // synopsys parallel_case
1621 0 : TxData <=#Tp TxDataLatched[31:24]; // Big Endian Byte Ordering
1622 1 : TxData <=#Tp TxDataLatched[23:16];
1623 2 : TxData <=#Tp TxDataLatched[15:8];
1624 3 : TxData <=#Tp TxDataLatched[7:0];
1625 endcase
1626 end
1627end
1628
1629
1630// Latching tx data
1631always @ (posedge MTxClk or posedge Reset)
1632begin
1633 if(Reset)
1634 TxDataLatched[31:0] <=#Tp 32'h0;
1635 else
1636 if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0)
1637 TxDataLatched[31:0] <=#Tp TxData_wb[31:0];
1638end
1639
1640
1641// Tx under run
1642always @ (posedge WB_CLK_I or posedge Reset)
1643begin
1644 if(Reset)
1645 TxUnderRun_wb <=#Tp 1'b0;
1646 else
1647 if(TxAbortPulse)
1648 TxUnderRun_wb <=#Tp 1'b0;
1649 else
1650 if(TxBufferEmpty & ReadTxDataFromFifo_wb)
1651 TxUnderRun_wb <=#Tp 1'b1;
1652end
1653
1654
1655reg TxUnderRun_sync1;
1656
1657// Tx under run
1658always @ (posedge MTxClk or posedge Reset)
1659begin
1660 if(Reset)
1661 TxUnderRun_sync1 <=#Tp 1'b0;
1662 else
1663 if(TxUnderRun_wb)
1664 TxUnderRun_sync1 <=#Tp 1'b1;
1665 else
1666 if(BlockingTxStatusWrite_sync2)
1667 TxUnderRun_sync1 <=#Tp 1'b0;
1668end
1669
1670// Tx under run
1671always @ (posedge MTxClk or posedge Reset)
1672begin
1673 if(Reset)
1674 TxUnderRun <=#Tp 1'b0;
1675 else
1676 if(BlockingTxStatusWrite_sync2)
1677 TxUnderRun <=#Tp 1'b0;
1678 else
1679 if(TxUnderRun_sync1)
1680 TxUnderRun <=#Tp 1'b1;
1681end
1682
1683
1684// Tx Byte counter
1685always @ (posedge MTxClk or posedge Reset)
1686begin
1687 if(Reset)
1688 TxByteCnt <=#Tp 2'h0;
1689 else
1690 if(TxAbort_q | TxRetry_q)
1691 TxByteCnt <=#Tp 2'h0;
1692 else
1693 if(TxStartFrm & ~TxUsedData)
1694 case(TxPointerLSB) // synopsys parallel_case
1695 2'h0 : TxByteCnt <=#Tp 2'h1;
1696 2'h1 : TxByteCnt <=#Tp 2'h2;
1697 2'h2 : TxByteCnt <=#Tp 2'h3;
1698 2'h3 : TxByteCnt <=#Tp 2'h0;
1699 endcase
1700 else
1701 if(TxUsedData & Flop)
1702 TxByteCnt <=#Tp TxByteCnt + 1'b1;
1703end
1704
1705
1706// Start: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
1707reg ReadTxDataFromFifo_sync1;
1708reg ReadTxDataFromFifo_sync2;
1709reg ReadTxDataFromFifo_sync3;
1710reg ReadTxDataFromFifo_syncb1;
1711reg ReadTxDataFromFifo_syncb2;
1712reg ReadTxDataFromFifo_syncb3;
1713
1714
1715always @ (posedge MTxClk or posedge Reset)
1716begin
1717 if(Reset)
1718 ReadTxDataFromFifo_tck <=#Tp 1'b0;
1719 else
1720 if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0)
1721 ReadTxDataFromFifo_tck <=#Tp 1'b1;
1722 else
1723 if(ReadTxDataFromFifo_syncb2 & ~ReadTxDataFromFifo_syncb3)
1724 ReadTxDataFromFifo_tck <=#Tp 1'b0;
1725end
1726
1727// Synchronizing TxStartFrm_wb to MTxClk
1728always @ (posedge WB_CLK_I or posedge Reset)
1729begin
1730 if(Reset)
1731 ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
1732 else
1733 ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
1734end
1735
1736always @ (posedge WB_CLK_I or posedge Reset)
1737begin
1738 if(Reset)
1739 ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
1740 else
1741 ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
1742end
1743
1744always @ (posedge MTxClk or posedge Reset)
1745begin
1746 if(Reset)
1747 ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
1748 else
1749 ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
1750end
1751
1752always @ (posedge MTxClk or posedge Reset)
1753begin
1754 if(Reset)
1755 ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
1756 else
1757 ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
1758end
1759
1760always @ (posedge MTxClk or posedge Reset)
1761begin
1762 if(Reset)
1763 ReadTxDataFromFifo_syncb3 <=#Tp 1'b0;
1764 else
1765 ReadTxDataFromFifo_syncb3 <=#Tp ReadTxDataFromFifo_syncb2;
1766end
1767
1768always @ (posedge WB_CLK_I or posedge Reset)
1769begin
1770 if(Reset)
1771 ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
1772 else
1773 ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
1774end
1775
1776assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
1777// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
1778
1779
1780// Synchronizing TxRetry signal (synchronized to WISHBONE clock)
1781always @ (posedge WB_CLK_I or posedge Reset)
1782begin
1783 if(Reset)
1784 TxRetrySync1 <=#Tp 1'b0;
1785 else
1786 TxRetrySync1 <=#Tp TxRetry;
1787end
1788
1789always @ (posedge WB_CLK_I or posedge Reset)
1790begin
1791 if(Reset)
1792 TxRetry_wb <=#Tp 1'b0;
1793 else
1794 TxRetry_wb <=#Tp TxRetrySync1;
1795end
1796
1797
1798// Synchronized TxDone_wb signal (synchronized to WISHBONE clock)
1799always @ (posedge WB_CLK_I or posedge Reset)
1800begin
1801 if(Reset)
1802 TxDoneSync1 <=#Tp 1'b0;
1803 else
1804 TxDoneSync1 <=#Tp TxDone;
1805end
1806
1807always @ (posedge WB_CLK_I or posedge Reset)
1808begin
1809 if(Reset)
1810 TxDone_wb <=#Tp 1'b0;
1811 else
1812 TxDone_wb <=#Tp TxDoneSync1;
1813end
1814
1815// Synchronizing TxAbort signal (synchronized to WISHBONE clock)
1816always @ (posedge WB_CLK_I or posedge Reset)
1817begin
1818 if(Reset)
1819 TxAbortSync1 <=#Tp 1'b0;
1820 else
1821 TxAbortSync1 <=#Tp TxAbort;
1822end
1823
1824always @ (posedge WB_CLK_I or posedge Reset)
1825begin
1826 if(Reset)
1827 TxAbort_wb <=#Tp 1'b0;
1828 else
1829 TxAbort_wb <=#Tp TxAbortSync1;
1830end
1831
1832
1833reg RxAbortSync1;
1834reg RxAbortSync2;
1835reg RxAbortSync3;
1836reg RxAbortSync4;
1837reg RxAbortSyncb1;
1838reg RxAbortSyncb2;
1839
1840assign StartRxBDRead = RxStatusWrite | RxAbortSync3 & ~RxAbortSync4 | r_RxEn & ~r_RxEn_q;
1841
1842// Reading the Rx buffer descriptor
1843always @ (posedge WB_CLK_I or posedge Reset)
1844begin
1845 if(Reset)
1846 RxBDRead <=#Tp 1'b0;
1847 else
1848 if(StartRxBDRead & ~RxReady)
1849 RxBDRead <=#Tp 1'b1;
1850 else
1851 if(RxBDReady)
1852 RxBDRead <=#Tp 1'b0;
1853end
1854
1855
1856// Reading of the next receive buffer descriptor starts after reception status is
1857// written to the previous one.
1858
1859// Latching READY status of the Rx buffer descriptor
1860always @ (posedge WB_CLK_I or posedge Reset)
1861begin
1862 if(Reset)
1863 RxBDReady <=#Tp 1'b0;
1864 else
1865 if(RxPointerRead)
1866 RxBDReady <=#Tp 1'b0;
1867 else
1868 if(RxEn & RxEn_q & RxBDRead)
1869 RxBDReady <=#Tp ram_do[15]; // RxBDReady is sampled only once at the beginning
1870end
1871
1872// Latching Rx buffer descriptor status
1873// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active)
1874always @ (posedge WB_CLK_I or posedge Reset)
1875begin
1876 if(Reset)
1877 RxStatus <=#Tp 2'h0;
1878 else
1879 if(RxEn & RxEn_q & RxBDRead)
1880 RxStatus <=#Tp ram_do[14:13];
1881end
1882
1883
1884// RxReady generation
1885always @ (posedge WB_CLK_I or posedge Reset)
1886begin
1887 if(Reset)
1888 RxReady <=#Tp 1'b0;
1889 else
1890 if(ShiftEnded | RxAbortSync2 & ~RxAbortSync3 | ~r_RxEn & r_RxEn_q)
1891 RxReady <=#Tp 1'b0;
1892 else
1893 if(RxEn & RxEn_q & RxPointerRead)
1894 RxReady <=#Tp 1'b1;
1895end
1896
1897
1898// Reading Rx BD pointer
1899
1900
1901assign StartRxPointerRead = RxBDRead & RxBDReady;
1902
1903// Reading Tx BD Pointer
1904always @ (posedge WB_CLK_I or posedge Reset)
1905begin
1906 if(Reset)
1907 RxPointerRead <=#Tp 1'b0;
1908 else
1909 if(StartRxPointerRead)
1910 RxPointerRead <=#Tp 1'b1;
1911 else
1912 if(RxEn & RxEn_q)
1913 RxPointerRead <=#Tp 1'b0;
1914end
1915
1916
1917//Latching Rx buffer pointer from buffer descriptor;
1918always @ (posedge WB_CLK_I or posedge Reset)
1919begin
1920 if(Reset)
1921 RxPointerMSB <=#Tp 30'h0;
1922 else
1923 if(RxEn & RxEn_q & RxPointerRead)
1924 RxPointerMSB <=#Tp ram_do[31:2];
1925 else
1926 if(MasterWbRX & m_wb_ack_i)
1927 RxPointerMSB <=#Tp RxPointerMSB + 1'b1; // Word access (always word access. m_wb_sel_o are used for selecting bytes)
1928end
1929
1930
1931//Latching last addresses from buffer descriptor (used as byte-half-word indicator);
1932always @ (posedge WB_CLK_I or posedge Reset)
1933begin
1934 if(Reset)
1935 RxPointerLSB_rst[1:0] <=#Tp 0;
1936 else
1937 if(MasterWbRX & m_wb_ack_i) // After first write all RxByteSel are active
1938 RxPointerLSB_rst[1:0] <=#Tp 0;
1939 else
1940 if(RxEn & RxEn_q & RxPointerRead)
1941 RxPointerLSB_rst[1:0] <=#Tp ram_do[1:0];
1942end
1943
1944
1945always @ (RxPointerLSB_rst)
1946begin
1947 case(RxPointerLSB_rst[1:0]) // synopsys parallel_case
1948 2'h0 : RxByteSel[3:0] = 4'hf;
1949 2'h1 : RxByteSel[3:0] = 4'h7;
1950 2'h2 : RxByteSel[3:0] = 4'h3;
1951 2'h3 : RxByteSel[3:0] = 4'h1;
1952 endcase
1953end
1954
1955
1956always @ (posedge WB_CLK_I or posedge Reset)
1957begin
1958 if(Reset)
1959 RxEn_needed <=#Tp 1'b0;
1960 else
1961 if(~RxReady & r_RxEn & WbEn & ~WbEn_q)
1962 RxEn_needed <=#Tp 1'b1;
1963 else
1964 if(RxPointerRead & RxEn & RxEn_q)
1965 RxEn_needed <=#Tp 1'b0;
1966end
1967
1968
1969// Reception status is written back to the buffer descriptor after the end of frame is detected.
1970assign RxStatusWrite = ShiftEnded & RxEn & RxEn_q;
1971
1972reg RxEnableWindow;
1973
1974// Indicating that last byte is being reveived
1975always @ (posedge MRxClk or posedge Reset)
1976begin
1977 if(Reset)
1978 LastByteIn <=#Tp 1'b0;
1979 else
1980 if(ShiftWillEnd & (&RxByteCnt) | RxAbort)
1981 LastByteIn <=#Tp 1'b0;
1982 else
1983 if(RxValid & RxReady & RxEndFrm & ~(&RxByteCnt) & RxEnableWindow)
1984 LastByteIn <=#Tp 1'b1;
1985end
1986
1987reg ShiftEnded_rck;
1988reg ShiftEndedSync1;
1989reg ShiftEndedSync2;
1990reg ShiftEndedSync3;
1991reg ShiftEndedSync_c1;
1992reg ShiftEndedSync_c2;
1993
1994wire StartShiftWillEnd;
1995assign StartShiftWillEnd = LastByteIn | RxValid & RxEndFrm & (&RxByteCnt) & RxEnableWindow;
1996
1997// Indicating that data reception will end
1998always @ (posedge MRxClk or posedge Reset)
1999begin
2000 if(Reset)
2001 ShiftWillEnd <=#Tp 1'b0;
2002 else
2003 if(ShiftEnded_rck | RxAbort)
2004 ShiftWillEnd <=#Tp 1'b0;
2005 else
2006 if(StartShiftWillEnd)
2007 ShiftWillEnd <=#Tp 1'b1;
2008end
2009
2010
2011
2012// Receive byte counter
2013always @ (posedge MRxClk or posedge Reset)
2014begin
2015 if(Reset)
2016 RxByteCnt <=#Tp 2'h0;
2017 else
2018 if(ShiftEnded_rck | RxAbort)
2019 RxByteCnt <=#Tp 2'h0;
2020 else
2021 if(RxValid & RxStartFrm & RxReady)
2022 case(RxPointerLSB_rst) // synopsys parallel_case
2023 2'h0 : RxByteCnt <=#Tp 2'h1;
2024 2'h1 : RxByteCnt <=#Tp 2'h2;
2025 2'h2 : RxByteCnt <=#Tp 2'h3;
2026 2'h3 : RxByteCnt <=#Tp 2'h0;
2027 endcase
2028 else
2029 if(RxValid & RxEnableWindow & RxReady | LastByteIn)
2030 RxByteCnt <=#Tp RxByteCnt + 1'b1;
2031end
2032
2033
2034// Indicates how many bytes are valid within the last word
2035always @ (posedge MRxClk or posedge Reset)
2036begin
2037 if(Reset)
2038 RxValidBytes <=#Tp 2'h1;
2039 else
2040 if(RxValid & RxStartFrm)
2041 case(RxPointerLSB_rst) // synopsys parallel_case
2042 2'h0 : RxValidBytes <=#Tp 2'h1;
2043 2'h1 : RxValidBytes <=#Tp 2'h2;
2044 2'h2 : RxValidBytes <=#Tp 2'h3;
2045 2'h3 : RxValidBytes <=#Tp 2'h0;
2046 endcase
2047 else
2048 if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
2049 RxValidBytes <=#Tp RxValidBytes + 1'b1;
2050end
2051
2052
2053always @ (posedge MRxClk or posedge Reset)
2054begin
2055 if(Reset)
2056 RxDataLatched1 <=#Tp 24'h0;
2057 else
2058 if(RxValid & RxReady & ~LastByteIn)
2059 if(RxStartFrm)
2060 begin
2061 case(RxPointerLSB_rst) // synopsys parallel_case
2062 2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering
2063 2'h1: RxDataLatched1[23:16] <=#Tp RxData;
2064 2'h2: RxDataLatched1[15:8] <=#Tp RxData;
2065 2'h3: RxDataLatched1 <=#Tp RxDataLatched1;
2066 endcase
2067 end
2068 else if (RxEnableWindow)
2069 begin
2070 case(RxByteCnt) // synopsys parallel_case
2071 2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering
2072 2'h1: RxDataLatched1[23:16] <=#Tp RxData;
2073 2'h2: RxDataLatched1[15:8] <=#Tp RxData;
2074 2'h3: RxDataLatched1 <=#Tp RxDataLatched1;
2075 endcase
2076 end
2077end
2078
2079wire SetWriteRxDataToFifo;
2080
2081// Assembling data that will be written to the rx_fifo
2082always @ (posedge MRxClk or posedge Reset)
2083begin
2084 if(Reset)
2085 RxDataLatched2 <=#Tp 32'h0;
2086 else
2087 if(SetWriteRxDataToFifo & ~ShiftWillEnd)
2088 RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering
2089 else
2090 if(SetWriteRxDataToFifo & ShiftWillEnd)
2091 case(RxValidBytes) // synopsys parallel_case
2092 0 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering
2093 1 : RxDataLatched2 <=#Tp {RxDataLatched1[31:24], 24'h0};
2094 2 : RxDataLatched2 <=#Tp {RxDataLatched1[31:16], 16'h0};
2095 3 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], 8'h0};
2096 endcase
2097end
2098
2099
2100reg WriteRxDataToFifoSync1;
2101reg WriteRxDataToFifoSync2;
2102reg WriteRxDataToFifoSync3;
2103
2104
2105// Indicating start of the reception process
2106assign SetWriteRxDataToFifo = (RxValid & RxReady & ~RxStartFrm & RxEnableWindow & (&RxByteCnt)) |
2107 (RxValid & RxReady & RxStartFrm & (&RxPointerLSB_rst)) |
2108 (ShiftWillEnd & LastByteIn & (&RxByteCnt));
2109
2110always @ (posedge MRxClk or posedge Reset)
2111begin
2112 if(Reset)
2113 WriteRxDataToFifo <=#Tp 1'b0;
2114 else
2115 if(SetWriteRxDataToFifo & ~RxAbort)
2116 WriteRxDataToFifo <=#Tp 1'b1;
2117 else
2118 if(WriteRxDataToFifoSync2 | RxAbort)
2119 WriteRxDataToFifo <=#Tp 1'b0;
2120end
2121
2122
2123
2124always @ (posedge WB_CLK_I or posedge Reset)
2125begin
2126 if(Reset)
2127 WriteRxDataToFifoSync1 <=#Tp 1'b0;
2128 else
2129 if(WriteRxDataToFifo)
2130 WriteRxDataToFifoSync1 <=#Tp 1'b1;
2131 else
2132 WriteRxDataToFifoSync1 <=#Tp 1'b0;
2133end
2134
2135always @ (posedge WB_CLK_I or posedge Reset)
2136begin
2137 if(Reset)
2138 WriteRxDataToFifoSync2 <=#Tp 1'b0;
2139 else
2140 WriteRxDataToFifoSync2 <=#Tp WriteRxDataToFifoSync1;
2141end
2142
2143always @ (posedge WB_CLK_I or posedge Reset)
2144begin
2145 if(Reset)
2146 WriteRxDataToFifoSync3 <=#Tp 1'b0;
2147 else
2148 WriteRxDataToFifoSync3 <=#Tp WriteRxDataToFifoSync2;
2149end
2150
2151wire WriteRxDataToFifo_wb;
2152assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync2 & ~WriteRxDataToFifoSync3;
2153
2154
2155reg LatchedRxStartFrm;
2156reg SyncRxStartFrm;
2157reg SyncRxStartFrm_q;
2158reg SyncRxStartFrm_q2;
2159wire RxFifoReset;
2160
2161always @ (posedge MRxClk or posedge Reset)
2162begin
2163 if(Reset)
2164 LatchedRxStartFrm <=#Tp 0;
2165 else
2166 if(RxStartFrm & ~SyncRxStartFrm_q)
2167 LatchedRxStartFrm <=#Tp 1;
2168 else
2169 if(SyncRxStartFrm_q)
2170 LatchedRxStartFrm <=#Tp 0;
2171end
2172
2173
2174always @ (posedge WB_CLK_I or posedge Reset)
2175begin
2176 if(Reset)
2177 SyncRxStartFrm <=#Tp 0;
2178 else
2179 if(LatchedRxStartFrm)
2180 SyncRxStartFrm <=#Tp 1;
2181 else
2182 SyncRxStartFrm <=#Tp 0;
2183end
2184
2185
2186always @ (posedge WB_CLK_I or posedge Reset)
2187begin
2188 if(Reset)
2189 SyncRxStartFrm_q <=#Tp 0;
2190 else
2191 SyncRxStartFrm_q <=#Tp SyncRxStartFrm;
2192end
2193
2194always @ (posedge WB_CLK_I or posedge Reset)
2195begin
2196 if(Reset)
2197 SyncRxStartFrm_q2 <=#Tp 0;
2198 else
2199 SyncRxStartFrm_q2 <=#Tp SyncRxStartFrm_q;
2200end
2201
2202
2203assign RxFifoReset = SyncRxStartFrm_q & ~SyncRxStartFrm_q2;
2204
2205
2206eth_fifo #(`ETH_RX_FIFO_DATA_WIDTH, `ETH_RX_FIFO_DEPTH, `ETH_RX_FIFO_CNT_WIDTH)
2207rx_fifo (.data_in(RxDataLatched2), .data_out(m_wb_dat_o),
2208 .clk(WB_CLK_I), .reset(Reset),
2209 .write(WriteRxDataToFifo_wb & ~RxBufferFull), .read(MasterWbRX & m_wb_ack_i),
2210 .clear(RxFifoReset), .full(RxBufferFull),
2211 .almost_full(), .almost_empty(RxBufferAlmostEmpty),
2212 .empty(RxBufferEmpty), .cnt(rxfifo_cnt)
2213 );
2214
2215assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=`ETH_BURST_LENGTH;
2216assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>`ETH_BURST_LENGTH;
2217assign WriteRxDataToMemory = ~RxBufferEmpty;
2218assign rx_burst = rx_burst_en & WriteRxDataToMemory;
2219
2220
2221// Generation of the end-of-frame signal
2222always @ (posedge MRxClk or posedge Reset)
2223begin
2224 if(Reset)
2225 ShiftEnded_rck <=#Tp 1'b0;
2226 else
2227 if(~RxAbort & SetWriteRxDataToFifo & StartShiftWillEnd)
2228 ShiftEnded_rck <=#Tp 1'b1;
2229 else
2230 if(RxAbort | ShiftEndedSync_c1 & ShiftEndedSync_c2)
2231 ShiftEnded_rck <=#Tp 1'b0;
2232end
2233
2234always @ (posedge WB_CLK_I or posedge Reset)
2235begin
2236 if(Reset)
2237 ShiftEndedSync1 <=#Tp 1'b0;
2238 else
2239 ShiftEndedSync1 <=#Tp ShiftEnded_rck;
2240end
2241
2242always @ (posedge WB_CLK_I or posedge Reset)
2243begin
2244 if(Reset)
2245 ShiftEndedSync2 <=#Tp 1'b0;
2246 else
2247 ShiftEndedSync2 <=#Tp ShiftEndedSync1;
2248end
2249
2250always @ (posedge WB_CLK_I or posedge Reset)
2251begin
2252 if(Reset)
2253 ShiftEndedSync3 <=#Tp 1'b0;
2254 else
2255 if(ShiftEndedSync1 & ~ShiftEndedSync2)
2256 ShiftEndedSync3 <=#Tp 1'b1;
2257 else
2258 if(ShiftEnded)
2259 ShiftEndedSync3 <=#Tp 1'b0;
2260end
2261
2262// Generation of the end-of-frame signal
2263always @ (posedge WB_CLK_I or posedge Reset)
2264begin
2265 if(Reset)
2266 ShiftEnded <=#Tp 1'b0;
2267 else
2268 if(ShiftEndedSync3 & MasterWbRX & m_wb_ack_i & RxBufferAlmostEmpty & ~ShiftEnded)
2269 ShiftEnded <=#Tp 1'b1;
2270 else
2271 if(RxStatusWrite)
2272 ShiftEnded <=#Tp 1'b0;
2273end
2274
2275always @ (posedge MRxClk or posedge Reset)
2276begin
2277 if(Reset)
2278 ShiftEndedSync_c1 <=#Tp 1'b0;
2279 else
2280 ShiftEndedSync_c1 <=#Tp ShiftEndedSync2;
2281end
2282
2283always @ (posedge MRxClk or posedge Reset)
2284begin
2285 if(Reset)
2286 ShiftEndedSync_c2 <=#Tp 1'b0;
2287 else
2288 ShiftEndedSync_c2 <=#Tp ShiftEndedSync_c1;
2289end
2290
2291// Generation of the end-of-frame signal
2292always @ (posedge MRxClk or posedge Reset)
2293begin
2294 if(Reset)
2295 RxEnableWindow <=#Tp 1'b0;
2296 else
2297 if(RxStartFrm)
2298 RxEnableWindow <=#Tp 1'b1;
2299 else
2300 if(RxEndFrm | RxAbort)
2301 RxEnableWindow <=#Tp 1'b0;
2302end
2303
2304
2305always @ (posedge WB_CLK_I or posedge Reset)
2306begin
2307 if(Reset)
2308 RxAbortSync1 <=#Tp 1'b0;
2309 else
2310 RxAbortSync1 <=#Tp RxAbortLatched;
2311end
2312
2313always @ (posedge WB_CLK_I or posedge Reset)
2314begin
2315 if(Reset)
2316 RxAbortSync2 <=#Tp 1'b0;
2317 else
2318 RxAbortSync2 <=#Tp RxAbortSync1;
2319end
2320
2321always @ (posedge WB_CLK_I or posedge Reset)
2322begin
2323 if(Reset)
2324 RxAbortSync3 <=#Tp 1'b0;
2325 else
2326 RxAbortSync3 <=#Tp RxAbortSync2;
2327end
2328
2329always @ (posedge WB_CLK_I or posedge Reset)
2330begin
2331 if(Reset)
2332 RxAbortSync4 <=#Tp 1'b0;
2333 else
2334 RxAbortSync4 <=#Tp RxAbortSync3;
2335end
2336
2337always @ (posedge MRxClk or posedge Reset)
2338begin
2339 if(Reset)
2340 RxAbortSyncb1 <=#Tp 1'b0;
2341 else
2342 RxAbortSyncb1 <=#Tp RxAbortSync2;
2343end
2344
2345always @ (posedge MRxClk or posedge Reset)
2346begin
2347 if(Reset)
2348 RxAbortSyncb2 <=#Tp 1'b0;
2349 else
2350 RxAbortSyncb2 <=#Tp RxAbortSyncb1;
2351end
2352
2353
2354always @ (posedge MRxClk or posedge Reset)
2355begin
2356 if(Reset)
2357 RxAbortLatched <=#Tp 1'b0;
2358 else
2359 if(RxAbortSyncb2)
2360 RxAbortLatched <=#Tp 1'b0;
2361 else
2362 if(RxAbort)
2363 RxAbortLatched <=#Tp 1'b1;
2364end
2365
2366
2367always @ (posedge MRxClk or posedge Reset)
2368begin
2369 if(Reset)
2370 LatchedRxLength[15:0] <=#Tp 16'h0;
2371 else
2372 if(LoadRxStatus)
2373 LatchedRxLength[15:0] <=#Tp RxLength[15:0];
2374end
2375
2376
2377assign RxStatusIn = {ReceivedPauseFrm, AddressMiss, RxOverrun, InvalidSymbol, DribbleNibble, ReceivedPacketTooBig, ShortFrame, LatchedCrcError, RxLateCollision};
2378
2379always @ (posedge MRxClk or posedge Reset)
2380begin
2381 if(Reset)
2382 RxStatusInLatched <=#Tp 'h0;
2383 else
2384 if(LoadRxStatus)
2385 RxStatusInLatched <=#Tp RxStatusIn;
2386end
2387
2388
2389// Rx overrun
2390always @ (posedge WB_CLK_I or posedge Reset)
2391begin
2392 if(Reset)
2393 RxOverrun <=#Tp 1'b0;
2394 else
2395 if(RxStatusWrite)
2396 RxOverrun <=#Tp 1'b0;
2397 else
2398 if(RxBufferFull & WriteRxDataToFifo_wb)
2399 RxOverrun <=#Tp 1'b1;
2400end
2401
2402
2403
2404wire TxError;
2405assign TxError = TxUnderRun | RetryLimit | LateCollLatched | CarrierSenseLost;
2406
2407wire RxError;
2408
2409// ShortFrame (RxStatusInLatched[2]) can not set an error because short frames
2410// are aborted when signal r_RecSmall is set to 0 in MODER register.
2411// AddressMiss is identifying that a frame was received because of the promiscous
2412// mode and is not an error
2413assign RxError = (|RxStatusInLatched[6:3]) | (|RxStatusInLatched[1:0]);
2414
2415
2416
2417reg RxStatusWriteLatched;
2418reg RxStatusWriteLatched_sync1;
2419reg RxStatusWriteLatched_sync2;
2420reg RxStatusWriteLatched_syncb1;
2421reg RxStatusWriteLatched_syncb2;
2422
2423
2424// Latching and synchronizing RxStatusWrite signal. This signal is used for clearing the ReceivedPauseFrm signal
2425always @ (posedge WB_CLK_I or posedge Reset)
2426begin
2427 if(Reset)
2428 RxStatusWriteLatched <=#Tp 1'b0;
2429 else
2430 if(RxStatusWriteLatched_syncb2)
2431 RxStatusWriteLatched <=#Tp 1'b0;
2432 else
2433 if(RxStatusWrite)
2434 RxStatusWriteLatched <=#Tp 1'b1;
2435end
2436
2437
2438always @ (posedge MRxClk or posedge Reset)
2439begin
2440 if(Reset)
2441 begin
2442 RxStatusWriteLatched_sync1 <=#Tp 1'b0;
2443 RxStatusWriteLatched_sync2 <=#Tp 1'b0;
2444 end
2445 else
2446 begin
2447 RxStatusWriteLatched_sync1 <=#Tp RxStatusWriteLatched;
2448 RxStatusWriteLatched_sync2 <=#Tp RxStatusWriteLatched_sync1;
2449 end
2450end
2451
2452
2453always @ (posedge WB_CLK_I or posedge Reset)
2454begin
2455 if(Reset)
2456 begin
2457 RxStatusWriteLatched_syncb1 <=#Tp 1'b0;
2458 RxStatusWriteLatched_syncb2 <=#Tp 1'b0;
2459 end
2460 else
2461 begin
2462 RxStatusWriteLatched_syncb1 <=#Tp RxStatusWriteLatched_sync2;
2463 RxStatusWriteLatched_syncb2 <=#Tp RxStatusWriteLatched_syncb1;
2464 end
2465end
2466
2467
2468
2469// Tx Done Interrupt
2470always @ (posedge WB_CLK_I or posedge Reset)
2471begin
2472 if(Reset)
2473 TxB_IRQ <=#Tp 1'b0;
2474 else
2475 if(TxStatusWrite & TxIRQEn)
2476 TxB_IRQ <=#Tp ~TxError;
2477 else
2478 TxB_IRQ <=#Tp 1'b0;
2479end
2480
2481
2482// Tx Error Interrupt
2483always @ (posedge WB_CLK_I or posedge Reset)
2484begin
2485 if(Reset)
2486 TxE_IRQ <=#Tp 1'b0;
2487 else
2488 if(TxStatusWrite & TxIRQEn)
2489 TxE_IRQ <=#Tp TxError;
2490 else
2491 TxE_IRQ <=#Tp 1'b0;
2492end
2493
2494
2495// Rx Done Interrupt
2496always @ (posedge WB_CLK_I or posedge Reset)
2497begin
2498 if(Reset)
2499 RxB_IRQ <=#Tp 1'b0;
2500 else
2501 if(RxStatusWrite & RxIRQEn & ReceivedPacketGood & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow)))
2502 RxB_IRQ <=#Tp (~RxError);
2503 else
2504 RxB_IRQ <=#Tp 1'b0;
2505end
2506
2507
2508// Rx Error Interrupt
2509always @ (posedge WB_CLK_I or posedge Reset)
2510begin
2511 if(Reset)
2512 RxE_IRQ <=#Tp 1'b0;
2513 else
2514 if(RxStatusWrite & RxIRQEn & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow)))
2515 RxE_IRQ <=#Tp RxError;
2516 else
2517 RxE_IRQ <=#Tp 1'b0;
2518end
2519
2520
2521// Busy Interrupt
2522
2523reg Busy_IRQ_rck;
2524reg Busy_IRQ_sync1;
2525reg Busy_IRQ_sync2;
2526reg Busy_IRQ_sync3;
2527reg Busy_IRQ_syncb1;
2528reg Busy_IRQ_syncb2;
2529
2530
2531always @ (posedge MRxClk or posedge Reset)
2532begin
2533 if(Reset)
2534 Busy_IRQ_rck <=#Tp 1'b0;
2535 else
2536 if(RxValid & RxStartFrm & ~RxReady)
2537 Busy_IRQ_rck <=#Tp 1'b1;
2538 else
2539 if(Busy_IRQ_syncb2)
2540 Busy_IRQ_rck <=#Tp 1'b0;
2541end
2542
2543always @ (posedge WB_CLK_I)
2544begin
2545 Busy_IRQ_sync1 <=#Tp Busy_IRQ_rck;
2546 Busy_IRQ_sync2 <=#Tp Busy_IRQ_sync1;
2547 Busy_IRQ_sync3 <=#Tp Busy_IRQ_sync2;
2548end
2549
2550always @ (posedge MRxClk)
2551begin
2552 Busy_IRQ_syncb1 <=#Tp Busy_IRQ_sync2;
2553 Busy_IRQ_syncb2 <=#Tp Busy_IRQ_syncb1;
2554end
2555
2556assign Busy_IRQ = Busy_IRQ_sync2 & ~Busy_IRQ_sync3;
2557
2558
2559
2560
2561
2562endmodule
Impressum, Datenschutz