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

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

versione iniziale opensparc

Line 
1//////////////////////////////////////////////////////////////////////
2////                                                              ////
3////  eth_receivecontrol.v                                        ////
4////                                                              ////
5////  This file is part of the Ethernet IP core project           ////
6////  http://www.opencores.org/projects/ethmac/                   ////
7////                                                              ////
8////  Author(s):                                                  ////
9////      - Igor Mohor (igorM@opencores.org)                      ////
10////                                                              ////
11////  All additional information is avaliable in the Readme.txt   ////
12////  file.                                                       ////
13////                                                              ////
14//////////////////////////////////////////////////////////////////////
15////                                                              ////
16//// Copyright (C) 2001 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.4  2002/11/22 01:57:06  mohor
45// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort
46// synchronized.
47//
48// Revision 1.3  2002/01/23 10:28:16  mohor
49// Link in the header changed.
50//
51// Revision 1.2  2001/10/19 08:43:51  mohor
52// eth_timescale.v changed to timescale.v This is done because of the
53// simulation of the few cores in a one joined project.
54//
55// Revision 1.1  2001/08/06 14:44:29  mohor
56// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
57// Include files fixed to contain no path.
58// File names and module names changed ta have a eth_ prologue in the name.
59// File eth_timescale.v is used to define timescale
60// All pin names on the top module are changed to contain _I, _O or _OE at the end.
61// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
62// and Mdo_OE. The bidirectional signal must be created on the top level. This
63// is done due to the ASIC tools.
64//
65// Revision 1.1  2001/07/30 21:23:42  mohor
66// Directory structure changed. Files checked and joind together.
67//
68// Revision 1.1  2001/07/03 12:51:54  mohor
69// Initial release of the MAC Control module.
70//
71//
72//
73//
74//
75
76
77`include "timescale.v"
78
79
80module eth_receivecontrol (MTxClk, MRxClk, TxReset, RxReset, RxData, RxValid, RxStartFrm, 
81                           RxEndFrm, RxFlow, ReceiveEnd, MAC, DlyCrcEn, TxDoneIn, 
82                           TxAbortIn, TxStartFrmOut, ReceivedLengthOK, ReceivedPacketGood, 
83                           TxUsedDataOutDetected, Pause, ReceivedPauseFrm, AddressOK, 
84                           RxStatusWriteLatched_sync2, r_PassAll, SetPauseTimer
85                          );
86
87parameter Tp = 1;
88
89
90input       MTxClk;
91input       MRxClk;
92input       TxReset; 
93input       RxReset; 
94input [7:0] RxData;
95input       RxValid;
96input       RxStartFrm;
97input       RxEndFrm;
98input       RxFlow;
99input       ReceiveEnd;
100input [47:0]MAC;
101input       DlyCrcEn;
102input       TxDoneIn;
103input       TxAbortIn;
104input       TxStartFrmOut;
105input       ReceivedLengthOK;
106input       ReceivedPacketGood;
107input       TxUsedDataOutDetected;
108input       RxStatusWriteLatched_sync2;
109input       r_PassAll;
110
111output      Pause;
112output      ReceivedPauseFrm;
113output      AddressOK;
114output      SetPauseTimer;
115
116
117reg         Pause;
118reg         AddressOK;                // Multicast or unicast address detected
119reg         TypeLengthOK;             // Type/Length field contains 0x8808
120reg         DetectionWindow;          // Detection of the PAUSE frame is possible within this window
121reg         OpCodeOK;                 // PAUSE opcode detected (0x0001)
122reg  [2:0]  DlyCrcCnt;
123reg  [4:0]  ByteCnt;
124reg [15:0]  AssembledTimerValue;
125reg [15:0]  LatchedTimerValue;
126reg         ReceivedPauseFrm;
127reg         ReceivedPauseFrmWAddr;
128reg         PauseTimerEq0_sync1;
129reg         PauseTimerEq0_sync2;
130reg [15:0]  PauseTimer;
131reg         Divider2;
132reg  [5:0]  SlotTimer;
133
134wire [47:0] ReservedMulticast;        // 0x0180C2000001
135wire [15:0] TypeLength;               // 0x8808
136wire        ResetByteCnt;             //
137wire        IncrementByteCnt;         //
138wire        ByteCntEq0;               // ByteCnt = 0
139wire        ByteCntEq1;               // ByteCnt = 1
140wire        ByteCntEq2;               // ByteCnt = 2
141wire        ByteCntEq3;               // ByteCnt = 3
142wire        ByteCntEq4;               // ByteCnt = 4
143wire        ByteCntEq5;               // ByteCnt = 5
144wire        ByteCntEq12;              // ByteCnt = 12
145wire        ByteCntEq13;              // ByteCnt = 13
146wire        ByteCntEq14;              // ByteCnt = 14
147wire        ByteCntEq15;              // ByteCnt = 15
148wire        ByteCntEq16;              // ByteCnt = 16
149wire        ByteCntEq17;              // ByteCnt = 17
150wire        ByteCntEq18;              // ByteCnt = 18
151wire        DecrementPauseTimer;      //
152wire        PauseTimerEq0;            //
153wire        ResetSlotTimer;           //
154wire        IncrementSlotTimer;       //
155wire        SlotFinished;             //
156
157
158
159// Reserved multicast address and Type/Length for PAUSE control
160assign ReservedMulticast = 48'h0180C2000001;
161assign TypeLength = 16'h8808;
162
163
164// Address Detection (Multicast or unicast)
165always @ (posedge MRxClk or posedge RxReset)
166begin
167  if(RxReset)
168    AddressOK <= #Tp 1'b0;
169  else
170  if(DetectionWindow & ByteCntEq0)
171    AddressOK <= #Tp  RxData[7:0] == ReservedMulticast[47:40] | RxData[7:0] == MAC[47:40];
172  else
173  if(DetectionWindow & ByteCntEq1)
174    AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[39:32] | RxData[7:0] == MAC[39:32]) & AddressOK;
175  else
176  if(DetectionWindow & ByteCntEq2)
177    AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[31:24] | RxData[7:0] == MAC[31:24]) & AddressOK;
178  else
179  if(DetectionWindow & ByteCntEq3)
180    AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[23:16] | RxData[7:0] == MAC[23:16]) & AddressOK;
181  else
182  if(DetectionWindow & ByteCntEq4)
183    AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[15:8]  | RxData[7:0] == MAC[15:8])  & AddressOK;
184  else
185  if(DetectionWindow & ByteCntEq5)
186    AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[7:0]   | RxData[7:0] == MAC[7:0])   & AddressOK;
187  else
188  if(ReceiveEnd)
189    AddressOK <= #Tp 1'b0;
190end
191
192
193
194// TypeLengthOK (Type/Length Control frame detected)
195always @ (posedge MRxClk or posedge RxReset )
196begin
197  if(RxReset)
198    TypeLengthOK <= #Tp 1'b0;
199  else
200  if(DetectionWindow & ByteCntEq12)
201    TypeLengthOK <= #Tp ByteCntEq12 & (RxData[7:0] == TypeLength[15:8]);
202  else
203  if(DetectionWindow & ByteCntEq13)
204    TypeLengthOK <= #Tp ByteCntEq13 & (RxData[7:0] == TypeLength[7:0]) & TypeLengthOK;
205  else
206  if(ReceiveEnd)
207    TypeLengthOK <= #Tp 1'b0;
208end
209
210
211
212// Latch Control Frame Opcode
213always @ (posedge MRxClk or posedge RxReset )
214begin
215  if(RxReset)
216    OpCodeOK <= #Tp 1'b0;
217  else
218  if(ByteCntEq16)
219    OpCodeOK <= #Tp 1'b0;
220  else
221    begin
222      if(DetectionWindow & ByteCntEq14)
223        OpCodeOK <= #Tp ByteCntEq14 & RxData[7:0] == 8'h00;
224   
225      if(DetectionWindow & ByteCntEq15)
226        OpCodeOK <= #Tp ByteCntEq15 & RxData[7:0] == 8'h01 & OpCodeOK;
227    end
228end
229
230
231// ReceivedPauseFrmWAddr (+Address Check)
232always @ (posedge MRxClk or posedge RxReset )
233begin
234  if(RxReset)
235    ReceivedPauseFrmWAddr <= #Tp 1'b0;
236  else
237  if(ReceiveEnd)
238    ReceivedPauseFrmWAddr <= #Tp 1'b0;
239  else
240  if(ByteCntEq16 & TypeLengthOK & OpCodeOK & AddressOK)
241    ReceivedPauseFrmWAddr <= #Tp 1'b1;       
242end
243
244
245
246// Assembling 16-bit timer value from two 8-bit data
247always @ (posedge MRxClk or posedge RxReset )
248begin
249  if(RxReset)
250    AssembledTimerValue[15:0] <= #Tp 16'h0;
251  else
252  if(RxStartFrm)
253    AssembledTimerValue[15:0] <= #Tp 16'h0;
254  else
255    begin
256      if(DetectionWindow & ByteCntEq16)
257        AssembledTimerValue[15:8] <= #Tp RxData[7:0];
258      if(DetectionWindow & ByteCntEq17)
259        AssembledTimerValue[7:0] <= #Tp RxData[7:0];
260    end
261end
262
263
264// Detection window (while PAUSE detection is possible)
265always @ (posedge MRxClk or posedge RxReset )
266begin
267  if(RxReset)
268    DetectionWindow <= #Tp 1'b1;
269  else
270  if(ByteCntEq18)
271    DetectionWindow <= #Tp 1'b0;
272  else
273  if(ReceiveEnd)
274    DetectionWindow <= #Tp 1'b1;
275end
276
277
278
279// Latching Timer Value
280always @ (posedge MRxClk or posedge RxReset )
281begin
282  if(RxReset)
283    LatchedTimerValue[15:0] <= #Tp 16'h0;
284  else
285  if(DetectionWindow &  ReceivedPauseFrmWAddr &  ByteCntEq18)
286    LatchedTimerValue[15:0] <= #Tp AssembledTimerValue[15:0];
287  else
288  if(ReceiveEnd)
289    LatchedTimerValue[15:0] <= #Tp 16'h0;
290end
291
292
293
294// Delayed CEC counter
295always @ (posedge MRxClk or posedge RxReset)
296begin
297  if(RxReset)
298    DlyCrcCnt <= #Tp 3'h0;
299  else
300  if(RxValid & RxEndFrm)
301    DlyCrcCnt <= #Tp 3'h0;
302  else
303  if(RxValid & ~RxEndFrm & ~DlyCrcCnt[2])
304    DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1;
305end
306
307             
308assign ResetByteCnt = RxEndFrm;
309assign IncrementByteCnt = RxValid & DetectionWindow & ~ByteCntEq18 & (~DlyCrcEn | DlyCrcEn & DlyCrcCnt[2]);
310
311
312// Byte counter
313always @ (posedge MRxClk or posedge RxReset)
314begin
315  if(RxReset)
316    ByteCnt[4:0] <= #Tp 5'h0;
317  else
318  if(ResetByteCnt)
319    ByteCnt[4:0] <= #Tp 5'h0;
320  else
321  if(IncrementByteCnt)
322    ByteCnt[4:0] <= #Tp ByteCnt[4:0] + 1'b1;
323end
324
325
326assign ByteCntEq0 = RxValid & ByteCnt[4:0] == 5'h0;
327assign ByteCntEq1 = RxValid & ByteCnt[4:0] == 5'h1;
328assign ByteCntEq2 = RxValid & ByteCnt[4:0] == 5'h2;
329assign ByteCntEq3 = RxValid & ByteCnt[4:0] == 5'h3;
330assign ByteCntEq4 = RxValid & ByteCnt[4:0] == 5'h4;
331assign ByteCntEq5 = RxValid & ByteCnt[4:0] == 5'h5;
332assign ByteCntEq12 = RxValid & ByteCnt[4:0] == 5'h0C;
333assign ByteCntEq13 = RxValid & ByteCnt[4:0] == 5'h0D;
334assign ByteCntEq14 = RxValid & ByteCnt[4:0] == 5'h0E;
335assign ByteCntEq15 = RxValid & ByteCnt[4:0] == 5'h0F;
336assign ByteCntEq16 = RxValid & ByteCnt[4:0] == 5'h10;
337assign ByteCntEq17 = RxValid & ByteCnt[4:0] == 5'h11;
338assign ByteCntEq18 = RxValid & ByteCnt[4:0] == 5'h12 & DetectionWindow;
339
340
341assign SetPauseTimer = ReceiveEnd & ReceivedPauseFrmWAddr & ReceivedPacketGood & ReceivedLengthOK & RxFlow;
342assign DecrementPauseTimer = SlotFinished & |PauseTimer;
343
344
345// PauseTimer[15:0]
346always @ (posedge MRxClk or posedge RxReset)
347begin
348  if(RxReset)
349    PauseTimer[15:0] <= #Tp 16'h0;
350  else
351  if(SetPauseTimer)
352    PauseTimer[15:0] <= #Tp LatchedTimerValue[15:0];
353  else
354  if(DecrementPauseTimer)
355    PauseTimer[15:0] <= #Tp PauseTimer[15:0] - 1'b1;
356end
357
358assign PauseTimerEq0 = ~(|PauseTimer[15:0]);
359
360
361
362// Synchronization of the pause timer
363always @ (posedge MTxClk or posedge TxReset)
364begin
365  if(TxReset)
366    begin
367      PauseTimerEq0_sync1 <= #Tp 1'b1;
368      PauseTimerEq0_sync2 <= #Tp 1'b1;
369    end
370  else
371    begin
372      PauseTimerEq0_sync1 <= #Tp PauseTimerEq0;
373      PauseTimerEq0_sync2 <= #Tp PauseTimerEq0_sync1;
374    end
375end
376
377
378// Pause signal generation
379always @ (posedge MTxClk or posedge TxReset)
380begin
381  if(TxReset)
382    Pause <= #Tp 1'b0;
383  else
384  if((TxDoneIn | TxAbortIn | ~TxUsedDataOutDetected) & ~TxStartFrmOut)
385    Pause <= #Tp RxFlow & ~PauseTimerEq0_sync2;
386end
387
388
389// Divider2 is used for incrementing the Slot timer every other clock
390always @ (posedge MRxClk or posedge RxReset)
391begin
392  if(RxReset)
393    Divider2 <= #Tp 1'b0;
394  else
395  if(|PauseTimer[15:0] & RxFlow)
396    Divider2 <= #Tp ~Divider2;
397  else
398    Divider2 <= #Tp 1'b0;
399end
400
401
402assign ResetSlotTimer = RxReset;
403assign IncrementSlotTimer =  Pause & RxFlow & Divider2;
404
405
406// SlotTimer
407always @ (posedge MRxClk or posedge RxReset)
408begin
409  if(RxReset)
410    SlotTimer[5:0] <= #Tp 6'h0;
411  else
412  if(ResetSlotTimer)
413    SlotTimer[5:0] <= #Tp 6'h0;
414  else
415  if(IncrementSlotTimer)
416    SlotTimer[5:0] <= #Tp SlotTimer[5:0] + 1'b1;
417end
418
419
420assign SlotFinished = &SlotTimer[5:0] & IncrementSlotTimer;  // Slot is 512 bits (64 bytes)
421
422
423
424// Pause Frame received
425always @ (posedge MRxClk or posedge RxReset)
426begin
427  if(RxReset)
428    ReceivedPauseFrm <=#Tp 1'b0;
429  else
430  if(RxStatusWriteLatched_sync2 & r_PassAll | ReceivedPauseFrm & (~r_PassAll))
431    ReceivedPauseFrm <=#Tp 1'b0;
432  else
433  if(ByteCntEq16 & TypeLengthOK & OpCodeOK)
434    ReceivedPauseFrm <=#Tp 1'b1;       
435end
436
437
438endmodule
Note: See TracBrowser for help on using the repository browser.