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