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 22

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

powered by: WebSVN 2.1.0

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