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

Subversion Repositories ethmac

[/] [ethmac/] [tags/] [rel_14/] [rtl/] [verilog/] [eth_receivecontrol.v] - Blame information for rev 338

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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