source: XOpenSparcT1/trunk/OC-Ethernet/eth_miim.v @ 6

Revision 6, 15.6 KB checked in by pntsvt00, 14 years ago (diff)

versione iniziale opensparc

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