1 //////////////////////////////////////////////////////////////////////
3 //// eth_wishbone.v ////
5 //// This file is part of the Ethernet IP core project ////
6 //// http://www.opencores.org/projects/ethmac/ ////
9 //// - Igor Mohor (igorM@opencores.org) ////
11 //// All additional information is available in the Readme.txt ////
14 //////////////////////////////////////////////////////////////////////
16 //// Copyright (C) 2001, 2002 Authors ////
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. ////
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. ////
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 ////
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 ////
39 //////////////////////////////////////////////////////////////////////
41 // CVS Revision History
43 // $Log: eth_wishbone.v,v $
44 // Revision 1.1 2007-03-20 17:50:56 sithglan
47 // Revision 1.58 2005/03/21 20:07:18 igorm
48 // Some small fixes + some troubles fixed.
50 // Revision 1.57 2005/02/21 11:35:33 igorm
51 // Defer indication fixed.
53 // Revision 1.56 2004/04/30 10:30:00 igorm
54 // Accidently deleted line put back.
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
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.
67 // Revision 1.53 2003/10/17 07:46:17 markom
68 // mbist signals updated according to newest convention
70 // Revision 1.52 2003/01/30 14:51:31 mohor
71 // Reset has priority in some flipflops.
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.
77 // Revision 1.50 2003/01/22 13:49:26 tadejm
78 // When control packets were received, they were ignored in some cases.
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.
84 // Revision 1.48 2003/01/20 12:05:26 mohor
85 // When in full duplex, transmit was sometimes blocked. Fixed.
87 // Revision 1.47 2002/11/22 13:26:21 mohor
88 // Registers RxStatusWrite_rck and RxStatusWriteLatched were not used
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
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.
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.
103 // Revision 1.43 2002/10/18 20:53:34 mohor
104 // case changed to casex.
106 // Revision 1.42 2002/10/18 17:04:20 tadejm
107 // Changed BIST scan signals.
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.
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.
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
121 // Revision 1.38 2002/10/10 16:29:30 mohor
124 // Revision 1.37 2002/09/11 14:18:46 mohor
125 // Sometimes both RxB_IRQ and RxE_IRQ were activated. Bug fixed.
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.
133 // Revision 1.35 2002/09/10 10:35:23 mohor
134 // Ethernet debug registers removed.
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.
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
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.
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.
155 // Revision 1.30 2002/07/23 15:28:31 mohor
156 // Ram , used for BDs changed from generic_spram to eth_spram_256x32.
158 // Revision 1.29 2002/07/20 00:41:32 mohor
159 // ShiftEnded synchronization changed.
161 // Revision 1.28 2002/07/18 16:11:46 mohor
162 // RxBDAddress takes `ETH_TX_BD_NUM_DEF value after reset.
164 // Revision 1.27 2002/07/11 02:53:20 mohor
165 // RxPointer bug fixed.
167 // Revision 1.26 2002/07/10 13:12:38 mohor
168 // Previous bug wasn't succesfully removed. Now fixed.
170 // Revision 1.25 2002/07/09 23:53:24 mohor
171 // Master state machine had a bug when switching from master write to
174 // Revision 1.24 2002/07/09 20:44:41 mohor
175 // m_wb_cyc_o signal released after every single transfer.
177 // Revision 1.23 2002/05/03 10:15:50 mohor
178 // Outputs registered. Reset changed for eth_wishbone module.
180 // Revision 1.22 2002/04/24 08:52:19 mohor
181 // Compiler directives added. Tx and Rx fifo size incremented. A "late collision"
184 // Revision 1.21 2002/03/29 16:18:11 lampret
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
191 // Revision 1.19 2002/03/19 12:51:50 mohor
192 // Comments in Slovene language removed.
194 // Revision 1.18 2002/03/19 12:46:52 mohor
195 // casex changed with case, fifo reset changed.
197 // Revision 1.17 2002/03/09 16:08:45 mohor
198 // rx_fifo was not always cleared ok. Fixed.
200 // Revision 1.16 2002/03/09 13:51:20 mohor
201 // Status was not latched correctly sometimes. Fixed.
203 // Revision 1.15 2002/03/08 06:56:46 mohor
204 // Big Endian problem when sending frames fixed.
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.
210 // Revision 1.13 2002/02/26 16:59:55 mohor
211 // Small fixes for external/internal DMA missmatches.
213 // Revision 1.12 2002/02/26 16:22:07 mohor
214 // Interrupts changed
216 // Revision 1.11 2002/02/15 17:07:39 mohor
217 // Status was not written correctly when frames were discarted because of
220 // Revision 1.10 2002/02/15 12:17:39 mohor
221 // RxStartFrm cleared when abort or retry comes.
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.
226 // Revision 1.8 2002/02/14 20:54:33 billditt
227 // Addition of new module eth_addrcheck.v
229 // Revision 1.7 2002/02/12 17:03:47 mohor
230 // RxOverRun added to statuses.
232 // Revision 1.6 2002/02/11 09:18:22 mohor
233 // Tx status is written back to the BD.
235 // Revision 1.5 2002/02/08 16:21:54 mohor
236 // Rx status is written back to the BD.
238 // Revision 1.4 2002/02/06 14:10:21 mohor
239 // non-DMA host interface added. Select the right configutation in eth_defines.
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
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
250 // Revision 1.1 2002/01/23 10:47:59 mohor
251 // Initial version. Equals to eth_wishbonedma.v at this moment.
256 `include "eth_defines.v"
257 `include "timescale.v"
264 WB_CLK_I, WB_DAT_I, WB_DAT_O,
267 WB_ADR_I, WB_WE_I, WB_ACK_O,
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,
277 `ifdef ETH_WISHBONE_B3
278 m_wb_cti_o, m_wb_bte_o,
282 MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData,
283 TxRetry, TxAbort, TxUnderRun, TxDone, PerPacketCrcEn,
287 MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort, RxStatusWriteLatched_sync2,
290 r_TxEn, r_RxEn, r_TxBDNum, r_RxFlow, r_PassAll,
293 TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ,
296 InvalidSymbol, LatchedCrcError, RxLateCollision, ShortFrame, DribbleNibble,
297 ReceivedPacketTooBig, RxLength, LoadRxStatus, ReceivedPacketGood, AddressMiss,
301 RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, RstDeferLatched, CarrierSenseLost
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
321 input WB_CLK_I; // WISHBONE clock
322 input [31:0] WB_DAT_I; // WISHBONE data input
323 output [31:0] WB_DAT_O; // WISHBONE data output
326 input [9:2] WB_ADR_I; // WISHBONE address input
327 input WB_WE_I; // WISHBONE write enable input
328 input [3:0] BDCs; // Buffer descriptors are selected
329 output WB_ACK_O; // WISHBONE acknowledge output
332 output [29:0] m_wb_adr_o; //
333 output [3:0] m_wb_sel_o; //
335 output [31:0] m_wb_dat_o; //
336 output m_wb_cyc_o; //
337 output m_wb_stb_o; //
338 input [31:0] m_wb_dat_i; //
342 `ifdef ETH_WISHBONE_B3
343 output [2:0] m_wb_cti_o; // Cycle Type Identifier
344 output [1:0] m_wb_bte_o; // Burst Type Extension
345 reg [2:0] m_wb_cti_o; // Cycle Type Identifier
348 input Reset; // Reset signal
351 input InvalidSymbol; // Invalid symbol was received during reception in 100 Mbps mode
352 input LatchedCrcError; // CRC error
353 input RxLateCollision; // Late collision occured while receiving frame
354 input ShortFrame; // Frame shorter then the minimum size (r_MinFL) was received while small packets are enabled (r_RecSmall)
355 input DribbleNibble; // Extra nibble received
356 input ReceivedPacketTooBig;// Received packet is bigger than r_MaxFL
357 input [15:0] RxLength; // Length of the incoming frame
358 input LoadRxStatus; // Rx status was loaded
359 input ReceivedPacketGood;// Received packet's length and CRC are good
360 input AddressMiss; // When a packet is received AddressMiss status is written to the Rx BD
363 input ReceivedPauseFrm;
366 input [3:0] RetryCntLatched; // Latched Retry Counter
367 input RetryLimit; // Retry limit reached (Retry Max value + 1 attempts were made)
368 input LateCollLatched; // Late collision occured
369 input DeferLatched; // Defer indication (Frame was defered before sucessfully sent)
370 output RstDeferLatched;
371 input CarrierSenseLost; // Carrier Sense was lost during the frame transmission
374 input MTxClk; // Transmit clock (from PHY)
375 input TxUsedData; // Transmit packet used data
376 input TxRetry; // Transmit packet retry
377 input TxAbort; // Transmit packet abort
378 input TxDone; // Transmission ended
379 output TxStartFrm; // Transmit packet start frame
380 output TxEndFrm; // Transmit packet end frame
381 output [7:0] TxData; // Transmit packet data byte
382 output TxUnderRun; // Transmit packet under-run
383 output PerPacketCrcEn; // Per packet crc enable
384 output PerPacketPad; // Per packet pading
387 input MRxClk; // Receive clock (from PHY)
388 input [7:0] RxData; // Received data byte (from PHY)
392 input RxAbort; // This signal is set when address doesn't match.
393 output RxStatusWriteLatched_sync2;
396 input r_TxEn; // Transmit enable
397 input r_RxEn; // Receive enable
398 input [7:0] r_TxBDNum; // Receive buffer descriptor number
410 input mbist_si_i; // bist scan serial in
411 output mbist_so_o; // bist scan serial out
412 input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control
430 reg [1:0] TxValidBytesLatched;
433 reg [15:0] LatchedTxLength;
434 reg [14:11] TxStatus;
436 reg [14:13] RxStatus;
447 reg TxRetryPacket_NotCleared;
449 reg TxDonePacket_NotCleared;
451 reg TxAbortPacket_NotCleared;
458 reg [31:0] TxDataLatched;
461 reg ReadTxDataFromFifo_tck;
463 reg BlockingTxStatusWrite;
464 reg BlockingTxBDRead;
468 reg [7:1] TxBDAddress;
469 reg [7:1] RxBDAddress;
479 reg [31:0] RxDataLatched2;
481 reg [31:8] RxDataLatched1; // Big Endian Byte Ordering
483 reg [1:0] RxValidBytes;
488 reg WriteRxDataToFifo;
489 reg [15:0] LatchedRxLength;
495 reg [3:0] BDWrite; // BD Write Enable for access from WISHBONE side
496 reg BDRead; // BD Read access from WISHBONE side
497 wire [31:0] RxBDDataIn; // Rx BD data in
498 wire [31:0] TxBDDataIn; // Tx BD data in
511 wire WrapTxStatusBit;
514 wire WrapRxStatusBit;
516 wire [1:0] TxValidBytes;
518 wire [7:1] TempTxBDAddress;
519 wire [7:1] TempRxBDAddress;
523 wire RxBufferAlmostEmpty;
528 wire [8:0] RxStatusIn;
529 reg [8:0] RxStatusInLatched;
544 wire StartTxPointerRead;
549 wire StartRxPointerRead;
552 `ifdef ETH_WISHBONE_B3
553 assign m_wb_bte_o = 2'b00; // Linear burst
556 assign m_wb_stb_o = m_wb_cyc_o;
558 always @ (posedge WB_CLK_I)
560 WB_ACK_O <=#Tp (|BDWrite) & WbEn & WbEn_q | BDRead & WbEn & ~WbEn_q;
563 assign WB_DAT_O = ram_do;
565 // Generic synchronous single-port RAM interface
566 eth_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)
570 .mbist_si_i (mbist_si_i),
571 .mbist_so_o (mbist_so_o),
572 .mbist_ctrl_i (mbist_ctrl_i)
576 assign ram_ce = 1'b1;
577 assign ram_we = (BDWrite & {4{(WbEn & WbEn_q)}}) | {4{(TxStatusWrite | RxStatusWrite)}};
578 assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead);
581 always @ (posedge WB_CLK_I or posedge Reset)
584 TxEn_needed <=#Tp 1'b0;
586 if(~TxBDReady & r_TxEn & WbEn & ~WbEn_q)
587 TxEn_needed <=#Tp 1'b1;
589 if(TxPointerRead & TxEn & TxEn_q)
590 TxEn_needed <=#Tp 1'b0;
593 // Enabling access to the RAM for three devices.
594 always @ (posedge WB_CLK_I or posedge Reset)
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 :
613 RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled
615 ram_addr <=#Tp {RxBDAddress, RxPointerRead};
616 ram_di <=#Tp RxBDDataIn;
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;
626 5'b010_00, 5'b010_10 :
628 WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled
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;
636 5'b010_01, 5'b010_11 :
640 TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled
641 ram_addr <=#Tp {TxBDAddress, TxPointerRead};
642 ram_di <=#Tp TxBDDataIn;
644 5'b001_00, 5'b001_01, 5'b001_10, 5'b001_11 :
646 WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage)
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;
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
660 WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage.
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;
673 // Delayed stage signals
674 always @ (posedge WB_CLK_I or posedge Reset)
689 r_TxEn_q <=#Tp r_TxEn;
690 r_RxEn_q <=#Tp r_RxEn;
694 // Changes for tx occur every second clock. Flop is used for this manner.
695 always @ (posedge MTxClk or posedge Reset)
700 if(TxDone | TxAbort | TxRetry_q)
708 assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;
710 // Latching READY status of the Tx buffer descriptor
711 always @ (posedge WB_CLK_I or posedge Reset)
714 TxBDReady <=#Tp 1'b0;
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.
720 TxBDReady <=#Tp 1'b0;
724 // Reading the Tx buffer descriptor
725 assign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) & ~BlockingTxBDRead & ~TxBDReady;
727 always @ (posedge WB_CLK_I or posedge Reset)
740 // Reading Tx BD pointer
741 assign StartTxPointerRead = TxBDRead & TxBDReady;
743 // Reading Tx BD Pointer
744 always @ (posedge WB_CLK_I or posedge Reset)
747 TxPointerRead <=#Tp 1'b0;
749 if(StartTxPointerRead)
750 TxPointerRead <=#Tp 1'b1;
753 TxPointerRead <=#Tp 1'b0;
757 // Writing status back to the Tx buffer descriptor
758 assign TxStatusWrite = (TxDonePacket_NotCleared | TxAbortPacket_NotCleared) & TxEn & TxEn_q & ~BlockingTxStatusWrite;
762 // Status writing must occur only once. Meanwhile it is blocked.
763 always @ (posedge WB_CLK_I or posedge Reset)
766 BlockingTxStatusWrite <=#Tp 1'b0;
768 if(~TxDone_wb & ~TxAbort_wb)
769 BlockingTxStatusWrite <=#Tp 1'b0;
772 BlockingTxStatusWrite <=#Tp 1'b1;
776 reg BlockingTxStatusWrite_sync1;
777 reg BlockingTxStatusWrite_sync2;
778 reg BlockingTxStatusWrite_sync3;
780 // Synchronizing BlockingTxStatusWrite to MTxClk
781 always @ (posedge MTxClk or posedge Reset)
784 BlockingTxStatusWrite_sync1 <=#Tp 1'b0;
786 BlockingTxStatusWrite_sync1 <=#Tp BlockingTxStatusWrite;
789 // Synchronizing BlockingTxStatusWrite to MTxClk
790 always @ (posedge MTxClk or posedge Reset)
793 BlockingTxStatusWrite_sync2 <=#Tp 1'b0;
795 BlockingTxStatusWrite_sync2 <=#Tp BlockingTxStatusWrite_sync1;
798 // Synchronizing BlockingTxStatusWrite to MTxClk
799 always @ (posedge MTxClk or posedge Reset)
802 BlockingTxStatusWrite_sync3 <=#Tp 1'b0;
804 BlockingTxStatusWrite_sync3 <=#Tp BlockingTxStatusWrite_sync2;
807 assign RstDeferLatched = BlockingTxStatusWrite_sync2 & ~BlockingTxStatusWrite_sync3;
809 // TxBDRead state is activated only once.
810 always @ (posedge WB_CLK_I or posedge Reset)
813 BlockingTxBDRead <=#Tp 1'b0;
816 BlockingTxBDRead <=#Tp 1'b1;
818 if(~StartTxBDRead & ~TxBDReady)
819 BlockingTxBDRead <=#Tp 1'b0;
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)
825 always @ (posedge WB_CLK_I or posedge Reset)
830 if(TxEn & TxEn_q & TxBDRead)
831 TxStatus <=#Tp ram_do[14:11];
834 reg ReadTxDataFromMemory;
835 wire WriteRxDataToMemory;
840 reg [29:0] m_wb_adr_o;
842 reg [3:0] m_wb_sel_o;
848 reg BlockingIncrementTxPointer;
849 reg [31:2] TxPointerMSB;
850 reg [1:0] TxPointerLSB;
851 reg [1:0] TxPointerLSB_rst;
852 reg [31:2] RxPointerMSB;
853 reg [1:0] RxPointerLSB_rst;
860 //Latching length from the buffer descriptor;
861 always @ (posedge WB_CLK_I or posedge Reset)
864 TxLength <=#Tp 16'h0;
866 if(TxEn & TxEn_q & TxBDRead)
867 TxLength <=#Tp ram_do[31:16];
869 if(MasterWbTX & m_wb_ack_i)
872 TxLength <=#Tp 16'h0;
874 if(TxPointerLSB_rst==2'h0)
875 TxLength <=#Tp TxLength - 3'h4; // Length is subtracted at the data request
877 if(TxPointerLSB_rst==2'h1)
878 TxLength <=#Tp TxLength - 3'h3; // Length is subtracted at the data request
880 if(TxPointerLSB_rst==2'h2)
881 TxLength <=#Tp TxLength - 3'h2; // Length is subtracted at the data request
883 if(TxPointerLSB_rst==2'h3)
884 TxLength <=#Tp TxLength - 3'h1; // Length is subtracted at the data request
890 //Latching length from the buffer descriptor;
891 always @ (posedge WB_CLK_I or posedge Reset)
894 LatchedTxLength <=#Tp 16'h0;
896 if(TxEn & TxEn_q & TxBDRead)
897 LatchedTxLength <=#Tp ram_do[31:16];
900 assign TxLengthEq0 = TxLength == 0;
901 assign TxLengthLt4 = TxLength < 4;
907 // Latching Tx buffer pointer from buffer descriptor. Only 30 MSB bits are latched
908 // because TxPointerMSB is only used for word-aligned accesses.
909 always @ (posedge WB_CLK_I or posedge Reset)
912 TxPointerMSB <=#Tp 30'h0;
914 if(TxEn & TxEn_q & TxPointerRead)
915 TxPointerMSB <=#Tp ram_do[31:2];
917 if(IncrTxPointer & ~BlockingIncrementTxPointer)
918 TxPointerMSB <=#Tp TxPointerMSB + 1'b1; // TxPointer is word-aligned
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.
926 always @ (posedge WB_CLK_I or posedge Reset)
929 TxPointerLSB[1:0] <=#Tp 0;
931 if(TxEn & TxEn_q & TxPointerRead)
932 TxPointerLSB[1:0] <=#Tp ram_do[1:0];
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.
940 always @ (posedge WB_CLK_I or posedge Reset)
943 TxPointerLSB_rst[1:0] <=#Tp 0;
945 if(TxEn & TxEn_q & TxPointerRead)
946 TxPointerLSB_rst[1:0] <=#Tp ram_do[1:0];
948 if(MasterWbTX & m_wb_ack_i) // After first access pointer is word alligned
949 TxPointerLSB_rst[1:0] <=#Tp 0;
954 wire MasterAccessFinished;
957 always @ (posedge WB_CLK_I or posedge Reset)
960 BlockingIncrementTxPointer <=#Tp 0;
962 if(MasterAccessFinished)
963 BlockingIncrementTxPointer <=#Tp 0;
966 BlockingIncrementTxPointer <=#Tp 1'b1;
970 wire TxBufferAlmostFull;
973 wire TxBufferAlmostEmpty;
974 wire SetReadTxDataFromMemory;
976 reg BlockReadTxDataFromMemory;
978 assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;
980 always @ (posedge WB_CLK_I or posedge Reset)
983 ReadTxDataFromMemory <=#Tp 1'b0;
985 if(TxLengthEq0 | TxAbortPulse | TxRetryPulse)
986 ReadTxDataFromMemory <=#Tp 1'b0;
988 if(SetReadTxDataFromMemory)
989 ReadTxDataFromMemory <=#Tp 1'b1;
995 wire ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~BlockReadTxDataFromMemory;
996 wire tx_burst = ReadTxDataFromMemory_2 & tx_burst_en;
998 wire [31:0] TxData_wb;
999 wire ReadTxDataFromFifo_wb;
1001 always @ (posedge WB_CLK_I or posedge Reset)
1004 BlockReadTxDataFromMemory <=#Tp 1'b0;
1006 if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX & (~cyc_cleared) & (!(TxAbortPacket_NotCleared | TxRetryPacket_NotCleared)))
1007 BlockReadTxDataFromMemory <=#Tp 1'b1;
1009 if(ReadTxDataFromFifo_wb | TxDonePacket | TxAbortPacket | TxRetryPacket)
1010 BlockReadTxDataFromMemory <=#Tp 1'b0;
1014 assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
1015 wire [`ETH_TX_FIFO_CNT_WIDTH-1:0] txfifo_cnt;
1016 wire [`ETH_RX_FIFO_CNT_WIDTH-1:0] rxfifo_cnt;
1017 reg [`ETH_BURST_CNT_WIDTH-1:0] tx_burst_cnt;
1018 reg [`ETH_BURST_CNT_WIDTH-1:0] rx_burst_cnt;
1021 wire enough_data_in_rxfifo_for_burst;
1022 wire enough_data_in_rxfifo_for_burst_plus1;
1024 // Enabling master wishbone access to the memory for two devices TX and RX.
1025 always @ (posedge WB_CLK_I or posedge Reset)
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;
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
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;
1063 m_wb_adr_o <=#Tp TxPointerMSB;
1065 m_wb_adr_o <=#Tp m_wb_adr_o+1'b1;
1067 if(tx_burst_cnt==(`ETH_BURST_LENGTH-1))
1069 tx_burst_en<=#Tp 1'b0;
1070 `ifdef ETH_WISHBONE_B3
1071 m_wb_cti_o <=#Tp 3'b111;
1076 `ifdef ETH_WISHBONE_B3
1077 m_wb_cti_o <=#Tp 3'b010;
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
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;
1096 m_wb_adr_o <=#Tp RxPointerMSB;
1098 m_wb_adr_o <=#Tp m_wb_adr_o+1'b1;
1100 if(rx_burst_cnt==(`ETH_BURST_LENGTH-1))
1102 rx_burst_en<=#Tp 1'b0;
1103 `ifdef ETH_WISHBONE_B3
1104 m_wb_cti_o <=#Tp 3'b111;
1109 `ifdef ETH_WISHBONE_B3
1110 m_wb_cti_o <=#Tp 3'b010;
1114 8'b00_x1_00_x0 : // idle and MW is needed (data write to rx buffer)
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;
1124 8'b00_10_00_00 : // idle and MR is needed (data read from tx buffer)
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;
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)
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;
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)
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;
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)
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;
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
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;
1188 8'b00_00_00_00: // whatever and no master read or write is needed (ack or err comes finishing previous access)
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));
1193 default: // Don't touch
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;
1208 assign TxFifoClear = (TxAbortPacket | TxRetryPacket);
1210 eth_fifo #(`ETH_TX_FIFO_DATA_WIDTH, `ETH_TX_FIFO_DEPTH, `ETH_TX_FIFO_CNT_WIDTH)
1211 tx_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)
1221 reg TxStartFrm_sync1;
1222 reg TxStartFrm_sync2;
1223 reg TxStartFrm_syncb1;
1224 reg TxStartFrm_syncb2;
1228 // Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
1229 always @ (posedge WB_CLK_I or posedge Reset)
1232 TxStartFrm_wb <=#Tp 1'b0;
1234 if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
1235 TxStartFrm_wb <=#Tp 1'b1;
1237 if(TxStartFrm_syncb2)
1238 TxStartFrm_wb <=#Tp 1'b0;
1241 // StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
1242 always @ (posedge WB_CLK_I or posedge Reset)
1245 StartOccured <=#Tp 1'b0;
1248 StartOccured <=#Tp 1'b1;
1251 StartOccured <=#Tp 1'b0;
1254 // Synchronizing TxStartFrm_wb to MTxClk
1255 always @ (posedge MTxClk or posedge Reset)
1258 TxStartFrm_sync1 <=#Tp 1'b0;
1260 TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
1263 always @ (posedge MTxClk or posedge Reset)
1266 TxStartFrm_sync2 <=#Tp 1'b0;
1268 TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
1271 always @ (posedge WB_CLK_I or posedge Reset)
1274 TxStartFrm_syncb1 <=#Tp 1'b0;
1276 TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
1279 always @ (posedge WB_CLK_I or posedge Reset)
1282 TxStartFrm_syncb2 <=#Tp 1'b0;
1284 TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
1287 always @ (posedge MTxClk or posedge Reset)
1290 TxStartFrm <=#Tp 1'b0;
1292 if(TxStartFrm_sync2)
1293 TxStartFrm <=#Tp 1'b1;
1295 if(TxUsedData_q | ~TxStartFrm_sync2 & (TxRetry & (~TxRetry_q) | TxAbort & (~TxAbort_q)))
1296 TxStartFrm <=#Tp 1'b0;
1298 // End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
1301 // TxEndFrm_wb: indicator of the end of frame
1302 always @ (posedge WB_CLK_I or posedge Reset)
1305 TxEndFrm_wb <=#Tp 1'b0;
1307 if(TxLengthEq0 & TxBufferAlmostEmpty & TxUsedData)
1308 TxEndFrm_wb <=#Tp 1'b1;
1310 if(TxRetryPulse | TxDonePulse | TxAbortPulse)
1311 TxEndFrm_wb <=#Tp 1'b0;
1315 // Marks which bytes are valid within the word.
1316 assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
1318 reg LatchValidBytes;
1319 reg LatchValidBytes_q;
1321 always @ (posedge WB_CLK_I or posedge Reset)
1324 LatchValidBytes <=#Tp 1'b0;
1326 if(TxLengthLt4 & TxBDReady)
1327 LatchValidBytes <=#Tp 1'b1;
1329 LatchValidBytes <=#Tp 1'b0;
1332 always @ (posedge WB_CLK_I or posedge Reset)
1335 LatchValidBytes_q <=#Tp 1'b0;
1337 LatchValidBytes_q <=#Tp LatchValidBytes;
1341 // Latching valid bytes
1342 always @ (posedge WB_CLK_I or posedge Reset)
1345 TxValidBytesLatched <=#Tp 2'h0;
1347 if(LatchValidBytes & ~LatchValidBytes_q)
1348 TxValidBytesLatched <=#Tp TxValidBytes;
1350 if(TxRetryPulse | TxDonePulse | TxAbortPulse)
1351 TxValidBytesLatched <=#Tp 2'h0;
1355 assign TxIRQEn = TxStatus[14];
1356 assign WrapTxStatusBit = TxStatus[13];
1357 assign PerPacketPad = TxStatus[12];
1358 assign PerPacketCrcEn = TxStatus[11];
1361 assign RxIRQEn = RxStatus[14];
1362 assign WrapRxStatusBit = RxStatus[13];
1365 // Temporary Tx and Rx buffer descriptor address
1366 assign TempTxBDAddress[7:1] = {7{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1'b1) ; // Tx BD increment or wrap (last BD)
1367 assign 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)
1371 // Latching Tx buffer descriptor address
1372 always @ (posedge WB_CLK_I or posedge 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;
1383 // Latching Rx buffer descriptor address
1384 always @ (posedge WB_CLK_I or posedge 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;
1394 wire [8:0] TxStatusInLatched = {TxUnderRun, RetryCntLatched[3:0], RetryLimit, LateCollLatched, DeferLatched, CarrierSenseLost};
1396 assign RxBDDataIn = {LatchedRxLength, 1'b0, RxStatus, 4'h0, RxStatusInLatched};
1397 assign TxBDDataIn = {LatchedTxLength, 1'b0, TxStatus, 2'h0, TxStatusInLatched};
1400 // Signals used for various purposes
1401 assign TxRetryPulse = TxRetry_wb & ~TxRetry_wb_q;
1402 assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
1403 assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
1407 // Generating delayed signals
1408 always @ (posedge MTxClk or posedge Reset)
1412 TxAbort_q <=#Tp 1'b0;
1413 TxRetry_q <=#Tp 1'b0;
1414 TxUsedData_q <=#Tp 1'b0;
1418 TxAbort_q <=#Tp TxAbort;
1419 TxRetry_q <=#Tp TxRetry;
1420 TxUsedData_q <=#Tp TxUsedData;
1424 // Generating delayed signals
1425 always @ (posedge WB_CLK_I or posedge Reset)
1429 TxDone_wb_q <=#Tp 1'b0;
1430 TxAbort_wb_q <=#Tp 1'b0;
1431 TxRetry_wb_q <=#Tp 1'b0;
1435 TxDone_wb_q <=#Tp TxDone_wb;
1436 TxAbort_wb_q <=#Tp TxAbort_wb;
1437 TxRetry_wb_q <=#Tp TxRetry_wb;
1442 reg TxAbortPacketBlocked;
1443 always @ (posedge WB_CLK_I or posedge Reset)
1446 TxAbortPacket <=#Tp 1'b0;
1448 if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
1449 TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
1450 TxAbortPacket <=#Tp 1'b1;
1452 TxAbortPacket <=#Tp 1'b0;
1456 always @ (posedge WB_CLK_I or posedge Reset)
1459 TxAbortPacket_NotCleared <=#Tp 1'b0;
1461 if(TxEn & TxEn_q & TxAbortPacket_NotCleared)
1462 TxAbortPacket_NotCleared <=#Tp 1'b0;
1464 if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) |
1465 TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked))
1466 TxAbortPacket_NotCleared <=#Tp 1'b1;
1470 always @ (posedge WB_CLK_I or posedge Reset)
1473 TxAbortPacketBlocked <=#Tp 1'b0;
1475 if(!TxAbort_wb & TxAbort_wb_q)
1476 TxAbortPacketBlocked <=#Tp 1'b0;
1479 TxAbortPacketBlocked <=#Tp 1'b1;
1483 reg TxRetryPacketBlocked;
1484 always @ (posedge WB_CLK_I or posedge Reset)
1487 TxRetryPacket <=#Tp 1'b0;
1489 if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
1490 TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
1491 TxRetryPacket <=#Tp 1'b1;
1493 TxRetryPacket <=#Tp 1'b0;
1497 always @ (posedge WB_CLK_I or posedge Reset)
1500 TxRetryPacket_NotCleared <=#Tp 1'b0;
1503 TxRetryPacket_NotCleared <=#Tp 1'b0;
1505 if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked |
1506 TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked)
1507 TxRetryPacket_NotCleared <=#Tp 1'b1;
1511 always @ (posedge WB_CLK_I or posedge Reset)
1514 TxRetryPacketBlocked <=#Tp 1'b0;
1516 if(!TxRetry_wb & TxRetry_wb_q)
1517 TxRetryPacketBlocked <=#Tp 1'b0;
1520 TxRetryPacketBlocked <=#Tp 1'b1;
1524 reg TxDonePacketBlocked;
1525 always @ (posedge WB_CLK_I or posedge Reset)
1528 TxDonePacket <=#Tp 1'b0;
1530 if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxDonePacketBlocked |
1531 TxDone_wb & !MasterWbTX & !TxDonePacketBlocked)
1532 TxDonePacket <=#Tp 1'b1;
1534 TxDonePacket <=#Tp 1'b0;
1538 always @ (posedge WB_CLK_I or posedge Reset)
1541 TxDonePacket_NotCleared <=#Tp 1'b0;
1543 if(TxEn & TxEn_q & TxDonePacket_NotCleared)
1544 TxDonePacket_NotCleared <=#Tp 1'b0;
1546 if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & (~TxDonePacketBlocked) |
1547 TxDone_wb & !MasterWbTX & (~TxDonePacketBlocked))
1548 TxDonePacket_NotCleared <=#Tp 1'b1;
1552 always @ (posedge WB_CLK_I or posedge Reset)
1555 TxDonePacketBlocked <=#Tp 1'b0;
1557 if(!TxDone_wb & TxDone_wb_q)
1558 TxDonePacketBlocked <=#Tp 1'b0;
1561 TxDonePacketBlocked <=#Tp 1'b1;
1565 // Indication of the last word
1566 always @ (posedge MTxClk or posedge Reset)
1569 LastWord <=#Tp 1'b0;
1571 if((TxEndFrm | TxAbort | TxRetry) & Flop)
1572 LastWord <=#Tp 1'b0;
1574 if(TxUsedData & Flop & TxByteCnt == 2'h3)
1575 LastWord <=#Tp TxEndFrm_wb;
1579 // Tx end frame generation
1580 always @ (posedge MTxClk or posedge Reset)
1583 TxEndFrm <=#Tp 1'b0;
1585 if(Flop & TxEndFrm | TxAbort | TxRetry_q)
1586 TxEndFrm <=#Tp 1'b0;
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;
1601 // Tx data selection (latching)
1602 always @ (posedge MTxClk or posedge Reset)
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
1615 if(TxStartFrm & TxUsedData & TxPointerLSB==2'h3)
1616 TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering
1618 if(TxUsedData & Flop)
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];
1631 always @ (posedge MTxClk or posedge Reset)
1634 TxDataLatched[31:0] <=#Tp 32'h0;
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];
1642 always @ (posedge WB_CLK_I or posedge Reset)
1645 TxUnderRun_wb <=#Tp 1'b0;
1648 TxUnderRun_wb <=#Tp 1'b0;
1650 if(TxBufferEmpty & ReadTxDataFromFifo_wb)
1651 TxUnderRun_wb <=#Tp 1'b1;
1655 reg TxUnderRun_sync1;
1658 always @ (posedge MTxClk or posedge Reset)
1661 TxUnderRun_sync1 <=#Tp 1'b0;
1664 TxUnderRun_sync1 <=#Tp 1'b1;
1666 if(BlockingTxStatusWrite_sync2)
1667 TxUnderRun_sync1 <=#Tp 1'b0;
1671 always @ (posedge MTxClk or posedge Reset)
1674 TxUnderRun <=#Tp 1'b0;
1676 if(BlockingTxStatusWrite_sync2)
1677 TxUnderRun <=#Tp 1'b0;
1679 if(TxUnderRun_sync1)
1680 TxUnderRun <=#Tp 1'b1;
1685 always @ (posedge MTxClk or posedge Reset)
1688 TxByteCnt <=#Tp 2'h0;
1690 if(TxAbort_q | TxRetry_q)
1691 TxByteCnt <=#Tp 2'h0;
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;
1701 if(TxUsedData & Flop)
1702 TxByteCnt <=#Tp TxByteCnt + 1'b1;
1706 // Start: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
1707 reg ReadTxDataFromFifo_sync1;
1708 reg ReadTxDataFromFifo_sync2;
1709 reg ReadTxDataFromFifo_sync3;
1710 reg ReadTxDataFromFifo_syncb1;
1711 reg ReadTxDataFromFifo_syncb2;
1712 reg ReadTxDataFromFifo_syncb3;
1715 always @ (posedge MTxClk or posedge Reset)
1718 ReadTxDataFromFifo_tck <=#Tp 1'b0;
1720 if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0)
1721 ReadTxDataFromFifo_tck <=#Tp 1'b1;
1723 if(ReadTxDataFromFifo_syncb2 & ~ReadTxDataFromFifo_syncb3)
1724 ReadTxDataFromFifo_tck <=#Tp 1'b0;
1727 // Synchronizing TxStartFrm_wb to MTxClk
1728 always @ (posedge WB_CLK_I or posedge Reset)
1731 ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
1733 ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
1736 always @ (posedge WB_CLK_I or posedge Reset)
1739 ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
1741 ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
1744 always @ (posedge MTxClk or posedge Reset)
1747 ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
1749 ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
1752 always @ (posedge MTxClk or posedge Reset)
1755 ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
1757 ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
1760 always @ (posedge MTxClk or posedge Reset)
1763 ReadTxDataFromFifo_syncb3 <=#Tp 1'b0;
1765 ReadTxDataFromFifo_syncb3 <=#Tp ReadTxDataFromFifo_syncb2;
1768 always @ (posedge WB_CLK_I or posedge Reset)
1771 ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
1773 ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
1776 assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
1777 // End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
1780 // Synchronizing TxRetry signal (synchronized to WISHBONE clock)
1781 always @ (posedge WB_CLK_I or posedge Reset)
1784 TxRetrySync1 <=#Tp 1'b0;
1786 TxRetrySync1 <=#Tp TxRetry;
1789 always @ (posedge WB_CLK_I or posedge Reset)
1792 TxRetry_wb <=#Tp 1'b0;
1794 TxRetry_wb <=#Tp TxRetrySync1;
1798 // Synchronized TxDone_wb signal (synchronized to WISHBONE clock)
1799 always @ (posedge WB_CLK_I or posedge Reset)
1802 TxDoneSync1 <=#Tp 1'b0;
1804 TxDoneSync1 <=#Tp TxDone;
1807 always @ (posedge WB_CLK_I or posedge Reset)
1810 TxDone_wb <=#Tp 1'b0;
1812 TxDone_wb <=#Tp TxDoneSync1;
1815 // Synchronizing TxAbort signal (synchronized to WISHBONE clock)
1816 always @ (posedge WB_CLK_I or posedge Reset)
1819 TxAbortSync1 <=#Tp 1'b0;
1821 TxAbortSync1 <=#Tp TxAbort;
1824 always @ (posedge WB_CLK_I or posedge Reset)
1827 TxAbort_wb <=#Tp 1'b0;
1829 TxAbort_wb <=#Tp TxAbortSync1;
1840 assign StartRxBDRead = RxStatusWrite | RxAbortSync3 & ~RxAbortSync4 | r_RxEn & ~r_RxEn_q;
1842 // Reading the Rx buffer descriptor
1843 always @ (posedge WB_CLK_I or posedge Reset)
1846 RxBDRead <=#Tp 1'b0;
1848 if(StartRxBDRead & ~RxReady)
1849 RxBDRead <=#Tp 1'b1;
1852 RxBDRead <=#Tp 1'b0;
1856 // Reading of the next receive buffer descriptor starts after reception status is
1857 // written to the previous one.
1859 // Latching READY status of the Rx buffer descriptor
1860 always @ (posedge WB_CLK_I or posedge Reset)
1863 RxBDReady <=#Tp 1'b0;
1866 RxBDReady <=#Tp 1'b0;
1868 if(RxEn & RxEn_q & RxBDRead)
1869 RxBDReady <=#Tp ram_do[15]; // RxBDReady is sampled only once at the beginning
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)
1874 always @ (posedge WB_CLK_I or posedge Reset)
1877 RxStatus <=#Tp 2'h0;
1879 if(RxEn & RxEn_q & RxBDRead)
1880 RxStatus <=#Tp ram_do[14:13];
1884 // RxReady generation
1885 always @ (posedge WB_CLK_I or posedge Reset)
1890 if(ShiftEnded | RxAbortSync2 & ~RxAbortSync3 | ~r_RxEn & r_RxEn_q)
1893 if(RxEn & RxEn_q & RxPointerRead)
1898 // Reading Rx BD pointer
1901 assign StartRxPointerRead = RxBDRead & RxBDReady;
1903 // Reading Tx BD Pointer
1904 always @ (posedge WB_CLK_I or posedge Reset)
1907 RxPointerRead <=#Tp 1'b0;
1909 if(StartRxPointerRead)
1910 RxPointerRead <=#Tp 1'b1;
1913 RxPointerRead <=#Tp 1'b0;
1917 //Latching Rx buffer pointer from buffer descriptor;
1918 always @ (posedge WB_CLK_I or posedge Reset)
1921 RxPointerMSB <=#Tp 30'h0;
1923 if(RxEn & RxEn_q & RxPointerRead)
1924 RxPointerMSB <=#Tp ram_do[31:2];
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)
1931 //Latching last addresses from buffer descriptor (used as byte-half-word indicator);
1932 always @ (posedge WB_CLK_I or posedge Reset)
1935 RxPointerLSB_rst[1:0] <=#Tp 0;
1937 if(MasterWbRX & m_wb_ack_i) // After first write all RxByteSel are active
1938 RxPointerLSB_rst[1:0] <=#Tp 0;
1940 if(RxEn & RxEn_q & RxPointerRead)
1941 RxPointerLSB_rst[1:0] <=#Tp ram_do[1:0];
1945 always @ (RxPointerLSB_rst)
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;
1956 always @ (posedge WB_CLK_I or posedge Reset)
1959 RxEn_needed <=#Tp 1'b0;
1961 if(~RxReady & r_RxEn & WbEn & ~WbEn_q)
1962 RxEn_needed <=#Tp 1'b1;
1964 if(RxPointerRead & RxEn & RxEn_q)
1965 RxEn_needed <=#Tp 1'b0;
1969 // Reception status is written back to the buffer descriptor after the end of frame is detected.
1970 assign RxStatusWrite = ShiftEnded & RxEn & RxEn_q;
1974 // Indicating that last byte is being reveived
1975 always @ (posedge MRxClk or posedge Reset)
1978 LastByteIn <=#Tp 1'b0;
1980 if(ShiftWillEnd & (&RxByteCnt) | RxAbort)
1981 LastByteIn <=#Tp 1'b0;
1983 if(RxValid & RxReady & RxEndFrm & ~(&RxByteCnt) & RxEnableWindow)
1984 LastByteIn <=#Tp 1'b1;
1988 reg ShiftEndedSync1;
1989 reg ShiftEndedSync2;
1990 reg ShiftEndedSync3;
1991 reg ShiftEndedSync_c1;
1992 reg ShiftEndedSync_c2;
1994 wire StartShiftWillEnd;
1995 assign StartShiftWillEnd = LastByteIn | RxValid & RxEndFrm & (&RxByteCnt) & RxEnableWindow;
1997 // Indicating that data reception will end
1998 always @ (posedge MRxClk or posedge Reset)
2001 ShiftWillEnd <=#Tp 1'b0;
2003 if(ShiftEnded_rck | RxAbort)
2004 ShiftWillEnd <=#Tp 1'b0;
2006 if(StartShiftWillEnd)
2007 ShiftWillEnd <=#Tp 1'b1;
2012 // Receive byte counter
2013 always @ (posedge MRxClk or posedge Reset)
2016 RxByteCnt <=#Tp 2'h0;
2018 if(ShiftEnded_rck | RxAbort)
2019 RxByteCnt <=#Tp 2'h0;
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;
2029 if(RxValid & RxEnableWindow & RxReady | LastByteIn)
2030 RxByteCnt <=#Tp RxByteCnt + 1'b1;
2034 // Indicates how many bytes are valid within the last word
2035 always @ (posedge MRxClk or posedge Reset)
2038 RxValidBytes <=#Tp 2'h1;
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;
2048 if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
2049 RxValidBytes <=#Tp RxValidBytes + 1'b1;
2053 always @ (posedge MRxClk or posedge Reset)
2056 RxDataLatched1 <=#Tp 24'h0;
2058 if(RxValid & RxReady & ~LastByteIn)
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;
2068 else if (RxEnableWindow)
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;
2079 wire SetWriteRxDataToFifo;
2081 // Assembling data that will be written to the rx_fifo
2082 always @ (posedge MRxClk or posedge Reset)
2085 RxDataLatched2 <=#Tp 32'h0;
2087 if(SetWriteRxDataToFifo & ~ShiftWillEnd)
2088 RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering
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};
2100 reg WriteRxDataToFifoSync1;
2101 reg WriteRxDataToFifoSync2;
2102 reg WriteRxDataToFifoSync3;
2105 // Indicating start of the reception process
2106 assign SetWriteRxDataToFifo = (RxValid & RxReady & ~RxStartFrm & RxEnableWindow & (&RxByteCnt)) |
2107 (RxValid & RxReady & RxStartFrm & (&RxPointerLSB_rst)) |
2108 (ShiftWillEnd & LastByteIn & (&RxByteCnt));
2110 always @ (posedge MRxClk or posedge Reset)
2113 WriteRxDataToFifo <=#Tp 1'b0;
2115 if(SetWriteRxDataToFifo & ~RxAbort)
2116 WriteRxDataToFifo <=#Tp 1'b1;
2118 if(WriteRxDataToFifoSync2 | RxAbort)
2119 WriteRxDataToFifo <=#Tp 1'b0;
2124 always @ (posedge WB_CLK_I or posedge Reset)
2127 WriteRxDataToFifoSync1 <=#Tp 1'b0;
2129 if(WriteRxDataToFifo)
2130 WriteRxDataToFifoSync1 <=#Tp 1'b1;
2132 WriteRxDataToFifoSync1 <=#Tp 1'b0;
2135 always @ (posedge WB_CLK_I or posedge Reset)
2138 WriteRxDataToFifoSync2 <=#Tp 1'b0;
2140 WriteRxDataToFifoSync2 <=#Tp WriteRxDataToFifoSync1;
2143 always @ (posedge WB_CLK_I or posedge Reset)
2146 WriteRxDataToFifoSync3 <=#Tp 1'b0;
2148 WriteRxDataToFifoSync3 <=#Tp WriteRxDataToFifoSync2;
2151 wire WriteRxDataToFifo_wb;
2152 assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync2 & ~WriteRxDataToFifoSync3;
2155 reg LatchedRxStartFrm;
2157 reg SyncRxStartFrm_q;
2158 reg SyncRxStartFrm_q2;
2161 always @ (posedge MRxClk or posedge Reset)
2164 LatchedRxStartFrm <=#Tp 0;
2166 if(RxStartFrm & ~SyncRxStartFrm_q)
2167 LatchedRxStartFrm <=#Tp 1;
2169 if(SyncRxStartFrm_q)
2170 LatchedRxStartFrm <=#Tp 0;
2174 always @ (posedge WB_CLK_I or posedge Reset)
2177 SyncRxStartFrm <=#Tp 0;
2179 if(LatchedRxStartFrm)
2180 SyncRxStartFrm <=#Tp 1;
2182 SyncRxStartFrm <=#Tp 0;
2186 always @ (posedge WB_CLK_I or posedge Reset)
2189 SyncRxStartFrm_q <=#Tp 0;
2191 SyncRxStartFrm_q <=#Tp SyncRxStartFrm;
2194 always @ (posedge WB_CLK_I or posedge Reset)
2197 SyncRxStartFrm_q2 <=#Tp 0;
2199 SyncRxStartFrm_q2 <=#Tp SyncRxStartFrm_q;
2203 assign RxFifoReset = SyncRxStartFrm_q & ~SyncRxStartFrm_q2;
2206 eth_fifo #(`ETH_RX_FIFO_DATA_WIDTH, `ETH_RX_FIFO_DEPTH, `ETH_RX_FIFO_CNT_WIDTH)
2207 rx_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)
2215 assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=`ETH_BURST_LENGTH;
2216 assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>`ETH_BURST_LENGTH;
2217 assign WriteRxDataToMemory = ~RxBufferEmpty;
2218 assign rx_burst = rx_burst_en & WriteRxDataToMemory;
2221 // Generation of the end-of-frame signal
2222 always @ (posedge MRxClk or posedge Reset)
2225 ShiftEnded_rck <=#Tp 1'b0;
2227 if(~RxAbort & SetWriteRxDataToFifo & StartShiftWillEnd)
2228 ShiftEnded_rck <=#Tp 1'b1;
2230 if(RxAbort | ShiftEndedSync_c1 & ShiftEndedSync_c2)
2231 ShiftEnded_rck <=#Tp 1'b0;
2234 always @ (posedge WB_CLK_I or posedge Reset)
2237 ShiftEndedSync1 <=#Tp 1'b0;
2239 ShiftEndedSync1 <=#Tp ShiftEnded_rck;
2242 always @ (posedge WB_CLK_I or posedge Reset)
2245 ShiftEndedSync2 <=#Tp 1'b0;
2247 ShiftEndedSync2 <=#Tp ShiftEndedSync1;
2250 always @ (posedge WB_CLK_I or posedge Reset)
2253 ShiftEndedSync3 <=#Tp 1'b0;
2255 if(ShiftEndedSync1 & ~ShiftEndedSync2)
2256 ShiftEndedSync3 <=#Tp 1'b1;
2259 ShiftEndedSync3 <=#Tp 1'b0;
2262 // Generation of the end-of-frame signal
2263 always @ (posedge WB_CLK_I or posedge Reset)
2266 ShiftEnded <=#Tp 1'b0;
2268 if(ShiftEndedSync3 & MasterWbRX & m_wb_ack_i & RxBufferAlmostEmpty & ~ShiftEnded)
2269 ShiftEnded <=#Tp 1'b1;
2272 ShiftEnded <=#Tp 1'b0;
2275 always @ (posedge MRxClk or posedge Reset)
2278 ShiftEndedSync_c1 <=#Tp 1'b0;
2280 ShiftEndedSync_c1 <=#Tp ShiftEndedSync2;
2283 always @ (posedge MRxClk or posedge Reset)
2286 ShiftEndedSync_c2 <=#Tp 1'b0;
2288 ShiftEndedSync_c2 <=#Tp ShiftEndedSync_c1;
2291 // Generation of the end-of-frame signal
2292 always @ (posedge MRxClk or posedge Reset)
2295 RxEnableWindow <=#Tp 1'b0;
2298 RxEnableWindow <=#Tp 1'b1;
2300 if(RxEndFrm | RxAbort)
2301 RxEnableWindow <=#Tp 1'b0;
2305 always @ (posedge WB_CLK_I or posedge Reset)
2308 RxAbortSync1 <=#Tp 1'b0;
2310 RxAbortSync1 <=#Tp RxAbortLatched;
2313 always @ (posedge WB_CLK_I or posedge Reset)
2316 RxAbortSync2 <=#Tp 1'b0;
2318 RxAbortSync2 <=#Tp RxAbortSync1;
2321 always @ (posedge WB_CLK_I or posedge Reset)
2324 RxAbortSync3 <=#Tp 1'b0;
2326 RxAbortSync3 <=#Tp RxAbortSync2;
2329 always @ (posedge WB_CLK_I or posedge Reset)
2332 RxAbortSync4 <=#Tp 1'b0;
2334 RxAbortSync4 <=#Tp RxAbortSync3;
2337 always @ (posedge MRxClk or posedge Reset)
2340 RxAbortSyncb1 <=#Tp 1'b0;
2342 RxAbortSyncb1 <=#Tp RxAbortSync2;
2345 always @ (posedge MRxClk or posedge Reset)
2348 RxAbortSyncb2 <=#Tp 1'b0;
2350 RxAbortSyncb2 <=#Tp RxAbortSyncb1;
2354 always @ (posedge MRxClk or posedge Reset)
2357 RxAbortLatched <=#Tp 1'b0;
2360 RxAbortLatched <=#Tp 1'b0;
2363 RxAbortLatched <=#Tp 1'b1;
2367 always @ (posedge MRxClk or posedge Reset)
2370 LatchedRxLength[15:0] <=#Tp 16'h0;
2373 LatchedRxLength[15:0] <=#Tp RxLength[15:0];
2377 assign RxStatusIn = {ReceivedPauseFrm, AddressMiss, RxOverrun, InvalidSymbol, DribbleNibble, ReceivedPacketTooBig, ShortFrame, LatchedCrcError, RxLateCollision};
2379 always @ (posedge MRxClk or posedge Reset)
2382 RxStatusInLatched <=#Tp 'h0;
2385 RxStatusInLatched <=#Tp RxStatusIn;
2390 always @ (posedge WB_CLK_I or posedge Reset)
2393 RxOverrun <=#Tp 1'b0;
2396 RxOverrun <=#Tp 1'b0;
2398 if(RxBufferFull & WriteRxDataToFifo_wb)
2399 RxOverrun <=#Tp 1'b1;
2405 assign TxError = TxUnderRun | RetryLimit | LateCollLatched | CarrierSenseLost;
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
2413 assign RxError = (|RxStatusInLatched[6:3]) | (|RxStatusInLatched[1:0]);
2417 reg RxStatusWriteLatched;
2418 reg RxStatusWriteLatched_sync1;
2419 reg RxStatusWriteLatched_sync2;
2420 reg RxStatusWriteLatched_syncb1;
2421 reg RxStatusWriteLatched_syncb2;
2424 // Latching and synchronizing RxStatusWrite signal. This signal is used for clearing the ReceivedPauseFrm signal
2425 always @ (posedge WB_CLK_I or posedge Reset)
2428 RxStatusWriteLatched <=#Tp 1'b0;
2430 if(RxStatusWriteLatched_syncb2)
2431 RxStatusWriteLatched <=#Tp 1'b0;
2434 RxStatusWriteLatched <=#Tp 1'b1;
2438 always @ (posedge MRxClk or posedge Reset)
2442 RxStatusWriteLatched_sync1 <=#Tp 1'b0;
2443 RxStatusWriteLatched_sync2 <=#Tp 1'b0;
2447 RxStatusWriteLatched_sync1 <=#Tp RxStatusWriteLatched;
2448 RxStatusWriteLatched_sync2 <=#Tp RxStatusWriteLatched_sync1;
2453 always @ (posedge WB_CLK_I or posedge Reset)
2457 RxStatusWriteLatched_syncb1 <=#Tp 1'b0;
2458 RxStatusWriteLatched_syncb2 <=#Tp 1'b0;
2462 RxStatusWriteLatched_syncb1 <=#Tp RxStatusWriteLatched_sync2;
2463 RxStatusWriteLatched_syncb2 <=#Tp RxStatusWriteLatched_syncb1;
2469 // Tx Done Interrupt
2470 always @ (posedge WB_CLK_I or posedge Reset)
2475 if(TxStatusWrite & TxIRQEn)
2476 TxB_IRQ <=#Tp ~TxError;
2482 // Tx Error Interrupt
2483 always @ (posedge WB_CLK_I or posedge Reset)
2488 if(TxStatusWrite & TxIRQEn)
2489 TxE_IRQ <=#Tp TxError;
2495 // Rx Done Interrupt
2496 always @ (posedge WB_CLK_I or posedge Reset)
2501 if(RxStatusWrite & RxIRQEn & ReceivedPacketGood & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow)))
2502 RxB_IRQ <=#Tp (~RxError);
2508 // Rx Error Interrupt
2509 always @ (posedge WB_CLK_I or posedge Reset)
2514 if(RxStatusWrite & RxIRQEn & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow)))
2515 RxE_IRQ <=#Tp RxError;
2527 reg Busy_IRQ_syncb1;
2528 reg Busy_IRQ_syncb2;
2531 always @ (posedge MRxClk or posedge Reset)
2534 Busy_IRQ_rck <=#Tp 1'b0;
2536 if(RxValid & RxStartFrm & ~RxReady)
2537 Busy_IRQ_rck <=#Tp 1'b1;
2540 Busy_IRQ_rck <=#Tp 1'b0;
2543 always @ (posedge WB_CLK_I)
2545 Busy_IRQ_sync1 <=#Tp Busy_IRQ_rck;
2546 Busy_IRQ_sync2 <=#Tp Busy_IRQ_sync1;
2547 Busy_IRQ_sync3 <=#Tp Busy_IRQ_sync2;
2550 always @ (posedge MRxClk)
2552 Busy_IRQ_syncb1 <=#Tp Busy_IRQ_sync2;
2553 Busy_IRQ_syncb2 <=#Tp Busy_IRQ_syncb1;
2556 assign Busy_IRQ = Busy_IRQ_sync2 & ~Busy_IRQ_sync3;