]> git.zerfleddert.de Git - raggedstone/blame - ethernet/source/ethernet/eth_miim.v
clock
[raggedstone] / ethernet / source / ethernet / eth_miim.v
CommitLineData
40a1f26c 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
92module 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
119input Clk; // Host Clock
120input Reset; // General Reset
121input [7:0] Divider; // Divider for the host clock
122input [15:0] CtrlData; // Control Data (to be written to the PHY reg.)
123input [4:0] Rgad; // Register Address (within the PHY)
124input [4:0] Fiad; // PHY Address
125input NoPre; // No Preamble (no 32-bit preamble)
126input WCtrlData; // Write Control Data operation
127input RStat; // Read Status operation
128input ScanStat; // Scan Status operation
129input Mdi; // MII Management Data In
130
131output Mdc; // MII Management Data Clock
132output Mdo; // MII Management Data Output
133output MdoEn; // MII Management Data Output Enable
134output Busy; // Busy Signal
135output LinkFail; // Link Integrity Signal
136output Nvalid; // Invalid Status (qualifier for the valid scan result)
137
138output [15:0] Prsd; // Read Status Data (data read from the PHY)
139
140output WCtrlDataStart; // This signals resets the WCTRLDATA bit in the MIIM Command register
141output RStatStart; // This signal resets the RSTAT BIT in the MIIM Command register
142output UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data
143
144parameter Tp = 1;
145
146
147reg Nvalid;
148reg EndBusy_d; // Pre-end Busy signal
149reg EndBusy; // End Busy signal (stops the operation in progress)
150
151reg WCtrlData_q1; // Write Control Data operation delayed 1 Clk cycle
152reg WCtrlData_q2; // Write Control Data operation delayed 2 Clk cycles
153reg WCtrlData_q3; // Write Control Data operation delayed 3 Clk cycles
154reg WCtrlDataStart; // Start Write Control Data Command (positive edge detected)
155reg WCtrlDataStart_q;
156reg WCtrlDataStart_q1; // Start Write Control Data Command delayed 1 Mdc cycle
157reg WCtrlDataStart_q2; // Start Write Control Data Command delayed 2 Mdc cycles
158
159reg RStat_q1; // Read Status operation delayed 1 Clk cycle
160reg RStat_q2; // Read Status operation delayed 2 Clk cycles
161reg RStat_q3; // Read Status operation delayed 3 Clk cycles
162reg RStatStart; // Start Read Status Command (positive edge detected)
163reg RStatStart_q1; // Start Read Status Command delayed 1 Mdc cycle
164reg RStatStart_q2; // Start Read Status Command delayed 2 Mdc cycles
165
166reg ScanStat_q1; // Scan Status operation delayed 1 cycle
167reg ScanStat_q2; // Scan Status operation delayed 2 cycles
168reg SyncStatMdcEn; // Scan Status operation delayed at least cycles and synchronized to MdcEn
169
170wire WriteDataOp; // Write Data Operation (positive edge detected)
171wire ReadStatusOp; // Read Status Operation (positive edge detected)
172wire ScanStatusOp; // Scan Status Operation (positive edge detected)
173wire StartOp; // Start Operation (start of any of the preceding operations)
174wire EndOp; // End of Operation
175
176reg InProgress; // Operation in progress
177reg InProgress_q1; // Operation in progress delayed 1 Mdc cycle
178reg InProgress_q2; // Operation in progress delayed 2 Mdc cycles
179reg InProgress_q3; // Operation in progress delayed 3 Mdc cycles
180
181reg WriteOp; // Write Operation Latch (When asserted, write operation is in progress)
182reg [6:0] BitCounter; // Bit Counter
183
184
185wire [3:0] ByteSelect; // Byte Select defines which byte (preamble, data, operation, etc.) is loaded and shifted through the shift register.
186wire MdcEn; // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc rises.
187wire ShiftedBit; // This bit is output of the shift register and is connected to the Mdo signal
188wire MdcEn_n;
189
190wire LatchByte1_d2;
191wire LatchByte0_d2;
192reg LatchByte1_d;
193reg LatchByte0_d;
194reg [1:0] LatchByte; // Latch Byte selects which part of Read Status Data is updated from the shift register
195
196reg 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.
203always @ (posedge Clk or posedge Reset)
204begin
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
215end
216
217
218// Update MII RX_DATA register
219always @ (posedge Clk or posedge Reset)
220begin
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;
228end
229
230
231
232// Generation of the delayed signals used for positive edge triggering.
233always @ (posedge Clk or posedge Reset)
234begin
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
264end
265
266
267// Generation of the Start Commands (Write Control Data or Read Status)
268always @ (posedge Clk or posedge Reset)
269begin
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
292end
293
294
295// Generation of the Nvalid signal (indicates when the status is invalid)
296always @ (posedge Clk or posedge Reset)
297begin
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
312end
313
314// Signals used for the generation of the Operation signals (positive edge)
315always @ (posedge Clk or posedge Reset)
316begin
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
355end
356
357
358// Generation of the Operation signals
359assign WriteDataOp = WCtrlDataStart_q1 & ~WCtrlDataStart_q2;
360assign ReadStatusOp = RStatStart_q1 & ~RStatStart_q2;
361assign ScanStatusOp = SyncStatMdcEn & ~InProgress & ~InProgress_q1 & ~InProgress_q2;
362assign StartOp = WriteDataOp | ReadStatusOp | ScanStatusOp;
363
364// Busy
365assign 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)
370always @ (posedge Clk or posedge Reset)
371begin
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
397end
398
399
400
401// Bit Counter counts from 0 to 63 (from 32 to 63 when NoPre is asserted)
402always @ (posedge Clk or posedge Reset)
403begin
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
421end
422
423
424// Operation ends when the Bit Counter reaches 63
425assign EndOp = BitCounter==63;
426
427assign ByteSelect[0] = InProgress & ((NoPre & (BitCounter == 7'h0)) | (~NoPre & (BitCounter == 7'h20)));
428assign ByteSelect[1] = InProgress & (BitCounter == 7'h28);
429assign ByteSelect[2] = InProgress & WriteOp & (BitCounter == 7'h30);
430assign 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
434assign LatchByte1_d2 = InProgress & ~WriteOp & BitCounter == 7'h37;
435assign LatchByte0_d2 = InProgress & ~WriteOp & BitCounter == 7'h3F;
436
437
438// Connecting the Clock Generator Module
439eth_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
443eth_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
449eth_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
454endmodule
Impressum, Datenschutz