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

Subversion Repositories ethernet_tri_mode

[/] [ethernet_tri_mode/] [trunk/] [rtl/] [verilog/] [eth_miim.v] - Blame information for rev 7

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

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

powered by: WebSVN 2.1.0

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