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

Subversion Repositories sgmii

[/] [sgmii/] [trunk/] [build/] [OpenCore_MAC/] [eth_miim.v] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jefflieu
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  eth_miim.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  2006/01/19 14:07:53  maverickist
45
// verification is complete.
46
//
47
// Revision 1.1.1.1  2005/12/13 01:51:44  Administrator
48
// no message
49
//
50
// Revision 1.4  2005/08/16 12:07:57  Administrator
51
// no message
52
//
53
// Revision 1.3  2005/05/19 07:04:29  Administrator
54
// no message
55
//
56
// Revision 1.2  2005/04/27 15:58:46  Administrator
57
// no message
58
//
59
// Revision 1.1.1.1  2004/12/15 06:38:54  Administrator
60
// no message
61
//
62
// Revision 1.5  2003/05/16 10:08:27  mohor
63
// Busy was set 2 cycles too late. Reported by Dennis Scott.
64
//
65
// Revision 1.4  2002/08/14 18:32:10  mohor
66
// - Busy signal was not set on time when scan status operation was performed
67
// and clock was divided with more than 2.
68
// - Nvalid remains valid two more clocks (was previously cleared too soon).
69
//
70
// Revision 1.3  2002/01/23 10:28:16  mohor
71
// Link in the header changed.
72
//
73
// Revision 1.2  2001/10/19 08:43:51  mohor
74
// eth_timescale.v changed to timescale.v This is done because of the
75
// simulation of the few cores in a one joined project.
76
//
77
// Revision 1.1  2001/08/06 14:44:29  mohor
78
// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex).
79
// Include files fixed to contain no path.
80
// File names and module names changed ta have a eth_ prologue in the name.
81
// File eth_timescale.v is used to define timescale
82
// All pin names on the top module are changed to contain _I, _O or _OE at the end.
83
// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O
84
// and Mdo_OE. The bidirectional signal must be created on the top level. This
85
// is done due to the ASIC tools.
86
//
87
// Revision 1.2  2001/08/02 09:25:31  mohor
88
// Unconnected signals are now connected.
89
//
90
// Revision 1.1  2001/07/30 21:23:42  mohor
91
// Directory structure changed. Files checked and joind together.
92
//
93
// Revision 1.3  2001/06/01 22:28:56  mohor
94
// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated.
95
//
96
//
97
 
98
`timescale 1ns/10ps
99
 
100
 
101
module eth_miim
102
(
103
  Clk,
104
  Reset,
105
  Divider,
106
  NoPre,
107
  CtrlData,
108
  Rgad,
109
  Fiad,
110
  WCtrlData,
111
  RStat,
112
  ScanStat,
113
  Mdo,
114
  MdoEn,
115
  Mdi,
116
  Mdc,
117
  Busy,
118
  Prsd,
119
  LinkFail,
120
  Nvalid,
121
  WCtrlDataStart,
122
  RStatStart,
123
  UpdateMIIRX_DATAReg
124
);
125
 
126
 
127
 
128
input         Clk;                // Host Clock
129
input         Reset;              // General Reset
130
input   [7:0] Divider;            // Divider for the host clock
131
input  [15:0] CtrlData;           // Control Data (to be written to the PHY reg.)
132
input   [4:0] Rgad;               // Register Address (within the PHY)
133
input   [4:0] Fiad;               // PHY Address
134
input         NoPre;              // No Preamble (no 32-bit preamble)
135
input         WCtrlData;          // Write Control Data operation
136
input         RStat;              // Read Status operation
137
input         ScanStat;           // Scan Status operation
138
output        Mdo;                // MII Management Data Output
139
output        MdoEn;              // MII Management Data Output Enable
140
input         Mdi;
141
 
142
output        Mdc;                // MII Management Data Clock
143
 
144
output        Busy;               // Busy Signal
145
output        LinkFail;           // Link Integrity Signal
146
output        Nvalid;             // Invalid Status (qualifier for the valid scan result)
147
 
148
output [15:0] Prsd;               // Read Status Data (data read from the PHY)
149
 
150
output        WCtrlDataStart;     // This signals resets the WCTRLDATA bit in the MIIM Command register
151
output        RStatStart;         // This signal resets the RSTAT BIT in the MIIM Command register
152
output        UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data
153
 
154
parameter Tp = 1;
155
 
156
 
157
reg           Nvalid;
158
reg           EndBusy_d;          // Pre-end Busy signal
159
reg           EndBusy;            // End Busy signal (stops the operation in progress)
160
 
161
reg           WCtrlData_q1;       // Write Control Data operation delayed 1 Clk cycle
162
reg           WCtrlData_q2;       // Write Control Data operation delayed 2 Clk cycles
163
reg           WCtrlData_q3;       // Write Control Data operation delayed 3 Clk cycles
164
reg           WCtrlDataStart;     // Start Write Control Data Command (positive edge detected)
165
reg           WCtrlDataStart_q;
166
reg           WCtrlDataStart_q1;  // Start Write Control Data Command delayed 1 Mdc cycle
167
reg           WCtrlDataStart_q2;  // Start Write Control Data Command delayed 2 Mdc cycles
168
 
169
reg           RStat_q1;           // Read Status operation delayed 1 Clk cycle
170
reg           RStat_q2;           // Read Status operation delayed 2 Clk cycles
171
reg           RStat_q3;           // Read Status operation delayed 3 Clk cycles
172
reg           RStatStart;         // Start Read Status Command (positive edge detected)
173
reg           RStatStart_q1;      // Start Read Status Command delayed 1 Mdc cycle
174
reg           RStatStart_q2;      // Start Read Status Command delayed 2 Mdc cycles
175
 
176
reg           ScanStat_q1;        // Scan Status operation delayed 1 cycle
177
reg           ScanStat_q2;        // Scan Status operation delayed 2 cycles
178
reg           SyncStatMdcEn;      // Scan Status operation delayed at least cycles and synchronized to MdcEn
179
 
180
wire          WriteDataOp;        // Write Data Operation (positive edge detected)
181
wire          ReadStatusOp;       // Read Status Operation (positive edge detected)
182
wire          ScanStatusOp;       // Scan Status Operation (positive edge detected)
183
wire          StartOp;            // Start Operation (start of any of the preceding operations)
184
wire          EndOp;              // End of Operation
185
 
186
reg           InProgress;         // Operation in progress
187
reg           InProgress_q1;      // Operation in progress delayed 1 Mdc cycle
188
reg           InProgress_q2;      // Operation in progress delayed 2 Mdc cycles
189
reg           InProgress_q3;      // Operation in progress delayed 3 Mdc cycles
190
 
191
reg           WriteOp;            // Write Operation Latch (When asserted, write operation is in progress)
192
reg     [6:0] BitCounter;         // Bit Counter
193
 
194
 
195
wire          MdcFrame;           // Frame window for limiting the Mdc
196
wire    [3:0] ByteSelect;         // Byte Select defines which byte (preamble, data, operation, etc.) is loaded and shifted through the shift register.
197
wire          MdcEn;              // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc rises.
198
wire          ShiftedBit;         // This bit is output of the shift register and is connected to the Mdo signal
199
 
200
 
201
wire          LatchByte1_d2;
202
wire          LatchByte0_d2;
203
reg           LatchByte1_d;
204
reg           LatchByte0_d;
205
reg     [1:0] LatchByte;          // Latch Byte selects which part of Read Status Data is updated from the shift register
206
 
207
reg           UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data
208
 
209
 
210
 
211
/*
212
assign  Mdi=Mdio;
213
assign  Mdio=MdoEn?Mdo:1'bz;
214
*/
215
 
216
 
217
 
218
// Generation of the EndBusy signal. It is used for ending the MII Management operation.
219
always @ (posedge Clk or posedge Reset)
220
begin
221
  if(Reset)
222
    begin
223
      EndBusy_d <= #Tp 1'b0;
224
      EndBusy <= #Tp 1'b0;
225
    end
226
  else
227
    begin
228
      EndBusy_d <= #Tp ~InProgress_q2 & InProgress_q3;
229
      EndBusy   <= #Tp EndBusy_d;
230
    end
231
end
232
 
233
 
234
// Update MII RX_DATA register
235
always @ (posedge Clk or posedge Reset)
236
begin
237
  if(Reset)
238
    UpdateMIIRX_DATAReg <= #Tp 0;
239
  else
240
  if(EndBusy & ~WCtrlDataStart_q)
241
    UpdateMIIRX_DATAReg <= #Tp 1;
242
  else
243
    UpdateMIIRX_DATAReg <= #Tp 0;
244
end
245
 
246
 
247
 
248
// Generation of the delayed signals used for positive edge triggering.
249
always @ (posedge Clk or posedge Reset)
250
begin
251
  if(Reset)
252
    begin
253
      WCtrlData_q1 <= #Tp 1'b0;
254
      WCtrlData_q2 <= #Tp 1'b0;
255
      WCtrlData_q3 <= #Tp 1'b0;
256
 
257
      RStat_q1 <= #Tp 1'b0;
258
      RStat_q2 <= #Tp 1'b0;
259
      RStat_q3 <= #Tp 1'b0;
260
 
261
      ScanStat_q1  <= #Tp 1'b0;
262
      ScanStat_q2  <= #Tp 1'b0;
263
      SyncStatMdcEn <= #Tp 1'b0;
264
    end
265
  else
266
    begin
267
      WCtrlData_q1 <= #Tp WCtrlData;
268
      WCtrlData_q2 <= #Tp WCtrlData_q1;
269
      WCtrlData_q3 <= #Tp WCtrlData_q2;
270
 
271
      RStat_q1 <= #Tp RStat;
272
      RStat_q2 <= #Tp RStat_q1;
273
      RStat_q3 <= #Tp RStat_q2;
274
 
275
      ScanStat_q1  <= #Tp ScanStat;
276
      ScanStat_q2  <= #Tp ScanStat_q1;
277
      if(MdcEn)
278
        SyncStatMdcEn  <= #Tp ScanStat_q2;
279
    end
280
end
281
 
282
 
283
// Generation of the Start Commands (Write Control Data or Read Status)
284
always @ (posedge Clk or posedge Reset)
285
begin
286
  if(Reset)
287
    begin
288
      WCtrlDataStart <= #Tp 1'b0;
289
      WCtrlDataStart_q <= #Tp 1'b0;
290
      RStatStart <= #Tp 1'b0;
291
    end
292
  else
293
    begin
294
      if(EndBusy)
295
        begin
296
          WCtrlDataStart <= #Tp 1'b0;
297
          RStatStart <= #Tp 1'b0;
298
        end
299
      else
300
        begin
301
          if(WCtrlData_q2 & ~WCtrlData_q3)
302
            WCtrlDataStart <= #Tp 1'b1;
303
          if(RStat_q2 & ~RStat_q3)
304
            RStatStart <= #Tp 1'b1;
305
          WCtrlDataStart_q <= #Tp WCtrlDataStart;
306
        end
307
    end
308
end
309
 
310
 
311
// Generation of the Nvalid signal (indicates when the status is invalid)
312
always @ (posedge Clk or posedge Reset)
313
begin
314
  if(Reset)
315
    Nvalid <= #Tp 1'b0;
316
  else
317
    begin
318
      if(~InProgress_q2 & InProgress_q3)
319
        begin
320
          Nvalid <= #Tp 1'b0;
321
        end
322
      else
323
        begin
324
          if(ScanStat_q2  & ~SyncStatMdcEn)
325
            Nvalid <= #Tp 1'b1;
326
        end
327
    end
328
end
329
 
330
// Signals used for the generation of the Operation signals (positive edge)
331
always @ (posedge Clk or posedge Reset)
332
begin
333
  if(Reset)
334
    begin
335
      WCtrlDataStart_q1 <= #Tp 1'b0;
336
      WCtrlDataStart_q2 <= #Tp 1'b0;
337
 
338
      RStatStart_q1 <= #Tp 1'b0;
339
      RStatStart_q2 <= #Tp 1'b0;
340
 
341
      InProgress_q1 <= #Tp 1'b0;
342
      InProgress_q2 <= #Tp 1'b0;
343
      InProgress_q3 <= #Tp 1'b0;
344
 
345
          LatchByte0_d <= #Tp 1'b0;
346
          LatchByte1_d <= #Tp 1'b0;
347
 
348
          LatchByte <= #Tp 2'b00;
349
    end
350
  else
351
    begin
352
      if(MdcEn)
353
        begin
354
          WCtrlDataStart_q1 <= #Tp WCtrlDataStart;
355
          WCtrlDataStart_q2 <= #Tp WCtrlDataStart_q1;
356
 
357
          RStatStart_q1 <= #Tp RStatStart;
358
          RStatStart_q2 <= #Tp RStatStart_q1;
359
 
360
          LatchByte[0] <= #Tp LatchByte0_d;
361
          LatchByte[1] <= #Tp LatchByte1_d;
362
 
363
          LatchByte0_d <= #Tp LatchByte0_d2;
364
          LatchByte1_d <= #Tp LatchByte1_d2;
365
 
366
          InProgress_q1 <= #Tp InProgress;
367
          InProgress_q2 <= #Tp InProgress_q1;
368
          InProgress_q3 <= #Tp InProgress_q2;
369
        end
370
    end
371
end
372
 
373
 
374
// Generation of the Operation signals
375
assign WriteDataOp  = WCtrlDataStart_q1 & ~WCtrlDataStart_q2;
376
assign ReadStatusOp = RStatStart_q1     & ~RStatStart_q2;
377
assign ScanStatusOp = SyncStatMdcEn     & ~InProgress & ~InProgress_q1 & ~InProgress_q2;
378
assign StartOp      = WriteDataOp | ReadStatusOp | ScanStatusOp;
379
 
380
// Busy
381
reg             Busy;
382
always @ (posedge Clk or posedge Reset)
383
        if (Reset)
384
                Busy    <=0;
385
        else if(WCtrlData | WCtrlDataStart | RStat | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid)
386
                Busy    <=1;
387
        else
388
                Busy    <=0;
389
 
390
//assign Busy = WCtrlData | WCtrlDataStart | RStat | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid;
391
 
392
 
393
// Generation of the InProgress signal (indicates when an operation is in progress)
394
// Generation of the WriteOp signal (indicates when a write is in progress)
395
always @ (posedge Clk or posedge Reset)
396
begin
397
  if(Reset)
398
    begin
399
      InProgress <= #Tp 1'b0;
400
      WriteOp <= #Tp 1'b0;
401
    end
402
  else
403
    begin
404
      if(MdcEn)
405
        begin
406
          if(StartOp)
407
            begin
408
              if(~InProgress)
409
                WriteOp <= #Tp WriteDataOp;
410
              InProgress <= #Tp 1'b1;
411
            end
412
          else
413
            begin
414
              if(EndOp)
415
                begin
416
                  InProgress <= #Tp 1'b0;
417
                  WriteOp <= #Tp 1'b0;
418
                end
419
            end
420
        end
421
    end
422
end
423
 
424
 
425
 
426
// Bit Counter counts from 0 to 63 (from 32 to 63 when NoPre is asserted)
427
always @ (posedge Clk or posedge Reset)
428
begin
429
  if(Reset)
430
    BitCounter[6:0] <= #Tp 7'h0;
431
  else
432
    begin
433
      if(MdcEn)
434
        begin
435
          if(InProgress)
436
            begin
437
              if(NoPre & ( BitCounter == 7'h0 ))
438
                BitCounter[6:0] <= #Tp 7'h21;
439
              else
440
                BitCounter[6:0] <= #Tp BitCounter[6:0] + 1'b1;
441
            end
442
          else
443
            BitCounter[6:0] <= #Tp 7'h0;
444
        end
445
    end
446
end
447
 
448
 
449
// Operation ends when the Bit Counter reaches 63
450
assign EndOp = BitCounter==63;
451
 
452
assign ByteSelect[0] = InProgress & ((NoPre & (BitCounter == 7'h0)) | (~NoPre & (BitCounter == 7'h20)));
453
assign ByteSelect[1] = InProgress & (BitCounter == 7'h28);
454
assign ByteSelect[2] = InProgress & WriteOp & (BitCounter == 7'h30);
455
assign ByteSelect[3] = InProgress & WriteOp & (BitCounter == 7'h38);
456
 
457
 
458
// Latch Byte selects which part of Read Status Data is updated from the shift register
459
assign LatchByte1_d2 = InProgress & ~WriteOp & BitCounter == 7'h37;
460
assign LatchByte0_d2 = InProgress & ~WriteOp & BitCounter == 7'h3F;
461
 
462
 
463
// Connecting the Clock Generator Module
464
eth_clockgen clkgen(.Clk(Clk), .Reset(Reset), .Divider(Divider[7:0]), .MdcEn(MdcEn), .MdcEn_n(MdcEn_n), .Mdc(Mdc)
465
                   );
466
 
467
// Connecting the Shift Register Module
468
eth_shiftreg shftrg(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .Mdi(Mdi), .Fiad(Fiad), .Rgad(Rgad),
469
                    .CtrlData(CtrlData), .WriteOp(WriteOp), .ByteSelect(ByteSelect), .LatchByte(LatchByte),
470
                    .ShiftedBit(ShiftedBit), .Prsd(Prsd), .LinkFail(LinkFail)
471
                   );
472
 
473
// Connecting the Output Control Module
474
eth_outputcontrol outctrl(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .InProgress(InProgress),
475
                          .ShiftedBit(ShiftedBit), .BitCounter(BitCounter), .WriteOp(WriteOp), .NoPre(NoPre),
476
                          .Mdo(Mdo), .MdoEn(MdoEn)
477
                         );
478
 
479
endmodule

powered by: WebSVN 2.1.0

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