source: XOpenSparcT1/trunk/OC-Ethernet/eth_wishbone.v @ 6

Revision 6, 68.7 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

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