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

Subversion Repositories or1k

[/] [or1k/] [tags/] [first/] [orp/] [orp_soc/] [rtl/] [verilog/] [ethernet.old/] [eth_receivecontrol.v] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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