OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [ethmac/] [eth_receivecontrol.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////////
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
 
80
module 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
 
87
parameter Tp = 1;
88
 
89
 
90
input       MTxClk;
91
input       MRxClk;
92
input       TxReset;
93
input       RxReset;
94
input [7:0] RxData;
95
input       RxValid;
96
input       RxStartFrm;
97
input       RxEndFrm;
98
input       RxFlow;
99
input       ReceiveEnd;
100
input [47:0]MAC;
101
input       DlyCrcEn;
102
input       TxDoneIn;
103
input       TxAbortIn;
104
input       TxStartFrmOut;
105
input       ReceivedLengthOK;
106
input       ReceivedPacketGood;
107
input       TxUsedDataOutDetected;
108
input       RxStatusWriteLatched_sync2;
109
input       r_PassAll;
110
 
111
output      Pause;
112
output      ReceivedPauseFrm;
113
output      AddressOK;
114
output      SetPauseTimer;
115
 
116
 
117
reg         Pause;
118
reg         AddressOK;                // Multicast or unicast address detected
119
reg         TypeLengthOK;             // Type/Length field contains 0x8808
120
reg         DetectionWindow;          // Detection of the PAUSE frame is possible within this window
121
reg         OpCodeOK;                 // PAUSE opcode detected (0x0001)
122
reg  [2:0]  DlyCrcCnt;
123
reg  [4:0]  ByteCnt;
124
reg [15:0]  AssembledTimerValue;
125
reg [15:0]  LatchedTimerValue;
126
reg         ReceivedPauseFrm;
127
reg         ReceivedPauseFrmWAddr;
128
reg         PauseTimerEq0_sync1;
129
reg         PauseTimerEq0_sync2;
130
reg [15:0]  PauseTimer;
131
reg         Divider2;
132
reg  [5:0]  SlotTimer;
133
 
134
wire [47:0] ReservedMulticast;        // 0x0180C2000001
135
wire [15:0] TypeLength;               // 0x8808
136
wire        ResetByteCnt;             // 
137
wire        IncrementByteCnt;         // 
138
wire        ByteCntEq0;               // ByteCnt = 0
139
wire        ByteCntEq1;               // ByteCnt = 1
140
wire        ByteCntEq2;               // ByteCnt = 2
141
wire        ByteCntEq3;               // ByteCnt = 3
142
wire        ByteCntEq4;               // ByteCnt = 4
143
wire        ByteCntEq5;               // ByteCnt = 5
144
wire        ByteCntEq12;              // ByteCnt = 12
145
wire        ByteCntEq13;              // ByteCnt = 13
146
wire        ByteCntEq14;              // ByteCnt = 14
147
wire        ByteCntEq15;              // ByteCnt = 15
148
wire        ByteCntEq16;              // ByteCnt = 16
149
wire        ByteCntEq17;              // ByteCnt = 17
150
wire        ByteCntEq18;              // ByteCnt = 18
151
wire        DecrementPauseTimer;      // 
152
wire        PauseTimerEq0;            // 
153
wire        ResetSlotTimer;           // 
154
wire        IncrementSlotTimer;       // 
155
wire        SlotFinished;             // 
156
 
157
 
158
 
159
// Reserved multicast address and Type/Length for PAUSE control
160
assign ReservedMulticast = 48'h0180C2000001;
161
assign TypeLength = 16'h8808;
162
 
163
 
164
// Address Detection (Multicast or unicast)
165
always @ (posedge MRxClk or posedge RxReset)
166
begin
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;
190
end
191
 
192
 
193
 
194
// TypeLengthOK (Type/Length Control frame detected)
195
always @ (posedge MRxClk or posedge RxReset )
196
begin
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;
208
end
209
 
210
 
211
 
212
// Latch Control Frame Opcode
213
always @ (posedge MRxClk or posedge RxReset )
214
begin
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
228
end
229
 
230
 
231
// ReceivedPauseFrmWAddr (+Address Check)
232
always @ (posedge MRxClk or posedge RxReset )
233
begin
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;
242
end
243
 
244
 
245
 
246
// Assembling 16-bit timer value from two 8-bit data
247
always @ (posedge MRxClk or posedge RxReset )
248
begin
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
261
end
262
 
263
 
264
// Detection window (while PAUSE detection is possible)
265
always @ (posedge MRxClk or posedge RxReset )
266
begin
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;
275
end
276
 
277
 
278
 
279
// Latching Timer Value
280
always @ (posedge MRxClk or posedge RxReset )
281
begin
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;
290
end
291
 
292
 
293
 
294
// Delayed CEC counter
295
always @ (posedge MRxClk or posedge RxReset)
296
begin
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;
305
end
306
 
307
 
308
assign ResetByteCnt = RxEndFrm;
309
assign IncrementByteCnt = RxValid & DetectionWindow & ~ByteCntEq18 & (~DlyCrcEn | DlyCrcEn & DlyCrcCnt[2]);
310
 
311
 
312
// Byte counter
313
always @ (posedge MRxClk or posedge RxReset)
314
begin
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;
323
end
324
 
325
 
326
assign ByteCntEq0 = RxValid & ByteCnt[4:0] == 5'h0;
327
assign ByteCntEq1 = RxValid & ByteCnt[4:0] == 5'h1;
328
assign ByteCntEq2 = RxValid & ByteCnt[4:0] == 5'h2;
329
assign ByteCntEq3 = RxValid & ByteCnt[4:0] == 5'h3;
330
assign ByteCntEq4 = RxValid & ByteCnt[4:0] == 5'h4;
331
assign ByteCntEq5 = RxValid & ByteCnt[4:0] == 5'h5;
332
assign ByteCntEq12 = RxValid & ByteCnt[4:0] == 5'h0C;
333
assign ByteCntEq13 = RxValid & ByteCnt[4:0] == 5'h0D;
334
assign ByteCntEq14 = RxValid & ByteCnt[4:0] == 5'h0E;
335
assign ByteCntEq15 = RxValid & ByteCnt[4:0] == 5'h0F;
336
assign ByteCntEq16 = RxValid & ByteCnt[4:0] == 5'h10;
337
assign ByteCntEq17 = RxValid & ByteCnt[4:0] == 5'h11;
338
assign ByteCntEq18 = RxValid & ByteCnt[4:0] == 5'h12 & DetectionWindow;
339
 
340
 
341
assign SetPauseTimer = ReceiveEnd & ReceivedPauseFrmWAddr & ReceivedPacketGood & ReceivedLengthOK & RxFlow;
342
assign DecrementPauseTimer = SlotFinished & |PauseTimer;
343
 
344
 
345
// PauseTimer[15:0]
346
always @ (posedge MRxClk or posedge RxReset)
347
begin
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;
356
end
357
 
358
assign PauseTimerEq0 = ~(|PauseTimer[15:0]);
359
 
360
 
361
 
362
// Synchronization of the pause timer
363
always @ (posedge MTxClk or posedge TxReset)
364
begin
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
375
end
376
 
377
 
378
// Pause signal generation
379
always @ (posedge MTxClk or posedge TxReset)
380
begin
381
  if(TxReset)
382
    Pause <= #Tp 1'b0;
383
  else
384
  if((TxDoneIn | TxAbortIn | ~TxUsedDataOutDetected) & ~TxStartFrmOut)
385
    Pause <= #Tp RxFlow & ~PauseTimerEq0_sync2;
386
end
387
 
388
 
389
// Divider2 is used for incrementing the Slot timer every other clock
390
always @ (posedge MRxClk or posedge RxReset)
391
begin
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;
399
end
400
 
401
 
402
assign ResetSlotTimer = RxReset;
403
assign IncrementSlotTimer =  Pause & RxFlow & Divider2;
404
 
405
 
406
// SlotTimer
407
always @ (posedge MRxClk or posedge RxReset)
408
begin
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;
417
end
418
 
419
 
420
assign SlotFinished = &SlotTimer[5:0] & IncrementSlotTimer;  // Slot is 512 bits (64 bytes)
421
 
422
 
423
 
424
// Pause Frame received
425
always @ (posedge MRxClk or posedge RxReset)
426
begin
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;
435
end
436
 
437
 
438
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.