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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [ethmac/] [eth_receivecontrol.v] - Blame information for rev 643

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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