Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / verilog / niu / mdio_mmd_model / mdio_mmd_model.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: mdio_mmd_model.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35`include "mdio_model_defines.vh"
36module mdio_mmd_model (reset, mdc, mdio_in, mdio_out, mdio_en);
37input reset;
38input mdc;
39input mdio_in;
40output mdio_out;
41output mdio_en;
42
43wire mdio_en_id_match_pre;
44wire mdio_en_id_match_post;
45wire mdio_en = mdio_en_id_match_post;
46wire mdio_out;
47reg mdio_d;
48
49integer bit_cnt;
50integer bit_cnt_preamble;
51integer bit_cnt_read;
52reg [3:0] state;
53reg [3:0] next_state;
54
55reg [1:0] st;
56reg [1:0] op;
57reg [4:0] prtad;
58reg [4:0] phyad;
59reg [4:0] devad;
60reg [4:0] regad;
61reg [15:0] addr;
62reg [1:0] ta;
63reg [15:0] data;
64reg write_en_22;
65reg write_en_45;
66reg [15:0] read_data;
67
68// storage
69reg [15:0] memory [65535:0]; // supports upto 64K registers
70// debug
71wire [15:0] memory0 = memory[0];
72wire [15:0] memory1 = memory[1];
73wire [15:0] memory2 = memory[2];
74wire [15:0] memory3 = memory[3];
75wire [15:0] memory4 = memory[4];
76wire [15:0] memory5 = memory[5];
77wire [15:0] memory6 = memory[6];
78wire [15:0] memory7 = memory[7];
79wire [15:0] memory8 = memory[8];
80wire [15:0] memory9 = memory[9];
81wire [15:0] memory100 = memory[100];
82wire [15:0] memory200 = memory[200];
83
84parameter MY_PRT_ID = `MDIO_MMD_MODEL_PRT_ID;
85parameter MY_PHY_ID = `MDIO_MMD_MODEL_PHY_ID;
86parameter MY_DEV_ID = `MDIO_MMD_MODEL_DEV_ID;
87
88parameter
89 IDLE = 0,
90 PREAMBLE= 1,
91 ST = 2,
92 OP = 3,
93 PRTAD = 4,
94 PHYAD = 5,
95 DEVAD = 6,
96 REGAD = 7,
97 TA = 8,
98 ADDR = 9,
99 DATA_RD = 10,
100 DATA_RDP= 11,
101 DATA_WR = 12;
102
103assign mdio_out = ((next_state == DATA_RD | next_state == DATA_RDP) &&
104 (bit_cnt_read == 17) && (op[1] == 1'b1)) ?
105 1'bz : ((next_state == DATA_RD | next_state == DATA_RDP) &&
106 (bit_cnt_read == 16) && (op[1] == 1'b1)) ?
107 1'b0 : ((next_state == DATA_RD | next_state == DATA_RDP |
108 state == DATA_RD | state == DATA_RDP) &&
109 (op[1] == 1'b1)) ?
110 read_data[bit_cnt_read] : 1'bz;
111
112assign mdio_en_id_match_pre = ((next_state == DATA_RD | next_state == DATA_RDP) &&
113 (bit_cnt_read == 17) && (op[1] == 1'b1)) ?
114 1'b1 : ((next_state == DATA_RD | next_state == DATA_RDP) &&
115 (bit_cnt_read == 16) && (op[1] == 1'b1)) ?
116 1'b1 : ((next_state == DATA_RD | next_state == DATA_RDP |
117 state == DATA_RD | state == DATA_RDP) &&
118 (op[1] == 1'b1)) ?
119 1'b1 : 1'b0;
120
121assign mdio_en_id_match_post = ((st == 2'b01) && (phyad[4:0] == MY_PHY_ID)) ? // Claus22
122 mdio_en_id_match_pre :
123 ((st == 2'b00) && (prtad[4:0] == MY_PRT_ID) && (devad[4:0] == MY_DEV_ID)) ?
124 mdio_en_id_match_pre : 1'b0;
125// combinational logic
126always @(reset or state or mdio_in or bit_cnt or st or op or bit_cnt_read or bit_cnt_preamble)
127begin
128 case (state)
129 IDLE :
130 if(reset)
131 next_state = IDLE;
132 else if(mdio_in === 1'b1)
133 next_state = PREAMBLE;
134 else
135 next_state = IDLE;
136 PREAMBLE :
137 if((mdio_in === 1'b0) && (bit_cnt_preamble < 31))
138 next_state = IDLE;
139 else if((mdio_in == 1'b0) && (bit_cnt_preamble >= 31))
140 next_state = ST;
141 else
142 next_state = PREAMBLE;
143 ST :
144 if((bit_cnt == 0) && ((st == 2'b11) | (st == 2'b10))) begin
145 $display("<%0d> MDIO_DEBUG: ERROR: Invalid MDIO transaction st:%h , state:%h, next_state:%h %m",
146 $time, st, state, next_state);
147 next_state = IDLE;
148 end
149 else if(bit_cnt == 0)
150 next_state = OP;
151 else
152 next_state = ST;
153 OP :
154 if((bit_cnt == 0) && (st == 2'b01))
155 next_state = PHYAD;
156 else if((bit_cnt == 0) && (st == 2'b00))
157 next_state = PRTAD;
158 else
159 next_state = OP;
160 PHYAD : // Claus22 Specific
161 if(bit_cnt == 0)
162 next_state = REGAD;
163 else
164 next_state = PHYAD;
165 PRTAD : // Claus45 specific
166 if(bit_cnt == 0)
167 next_state = DEVAD;
168 else
169 next_state = PRTAD;
170 DEVAD : // Claus45 specific
171 if((bit_cnt == 0) && (op == 2'b00))
172 next_state = TA;
173 else if((bit_cnt == 0) && (op == 2'b01))
174 next_state = TA;
175 else if((bit_cnt == 0) && (op == 2'b11))
176 next_state = DATA_RD;
177 else if((bit_cnt == 0) && (op == 2'b10) && (st == 2'b01)) // Claus22 specific
178 next_state = DATA_RD;
179 else if((bit_cnt == 0) && (op == 2'b10) && (st == 2'b00)) // Claus45 specific
180 next_state = DATA_RDP;
181 else
182 next_state = DEVAD;
183 REGAD :
184 if((bit_cnt == 0) && (op == 2'b00))
185 next_state = TA;
186 else if((bit_cnt == 0) && (op == 2'b01))
187 next_state = TA;
188 else if((bit_cnt == 0) && (op == 2'b11))
189 next_state = DATA_RD;
190 else if((bit_cnt == 0) && (op == 2'b10) && (st == 2'b01)) // Claus22 specific
191 next_state = DATA_RD;
192 else if((bit_cnt == 0) && (op == 2'b10) && (st == 2'b00)) // Claus45 specific
193 next_state = DATA_RDP;
194 else
195 next_state = REGAD;
196 TA :
197 if((bit_cnt == 0) && (op == 2'b00))
198 next_state = ADDR;
199 else if((bit_cnt == 0) && (op == 2'b01))
200 next_state = DATA_WR;
201 else
202 next_state = TA;
203 ADDR :
204 if(bit_cnt == 0)
205 next_state = IDLE;
206 else
207 next_state = ADDR;
208 DATA_WR :
209 if(bit_cnt == 0)
210 next_state = IDLE;
211 else
212 next_state = DATA_WR;
213 DATA_RD :
214 if(bit_cnt_read == 0)
215 next_state = IDLE;
216 else
217 next_state = DATA_RD;
218 DATA_RDP :
219 if(bit_cnt_read == 0)
220 next_state = IDLE;
221 else
222 next_state = DATA_RDP;
223 default :
224 next_state = IDLE;
225 endcase
226end
227
228always @(posedge mdc)
229begin
230 if(reset) begin
231 state <= #1 4'h0;
232 bit_cnt <= #1 7'd31;
233 mdio_d <= #1 1'bz;
234 write_en_22 <= #1 1'b0;
235 write_en_45 <= #1 1'b0;
236 bit_cnt_read <= #1 7'd0;
237 end
238 else begin
239 state <= #1 next_state;
240 mdio_d <= #1 mdio_in;
241 end
242
243 // default
244 write_en_22 <= #1 1'b0;
245 write_en_45 <= #1 1'b0;
246 bit_cnt_read <= #1 bit_cnt_read - 1;
247
248 // bit_cnt update
249 if(state == IDLE) begin
250 bit_cnt <= #1 31;
251 bit_cnt_preamble <= #1 0;
252 end
253 else if(state == PREAMBLE) begin
254 bit_cnt_preamble <= #1 bit_cnt_preamble + 1;
255 bit_cnt <= #1 1;
256 end
257 else if((state == ST) && (bit_cnt == 0))
258 bit_cnt <= #1 1;
259 else if((state == OP) && (bit_cnt == 0))
260 bit_cnt <= #1 4;
261 else if((state == PHYAD) && (bit_cnt == 0))
262 bit_cnt <= #1 4;
263 else if((state == PRTAD) && (bit_cnt == 0))
264 bit_cnt <= #1 4;
265 else if((state == DEVAD) && (bit_cnt == 0))
266 bit_cnt <= #1 1;
267 else if((state == REGAD) && (bit_cnt == 0))
268 bit_cnt <= #1 1;
269 else if((state == TA) && (bit_cnt == 0))
270 bit_cnt <= #1 15;
271 else if((state == ADDR) && (bit_cnt == 0))
272 bit_cnt <= #1 31;
273 else if((state == DATA_WR) && (bit_cnt == 0))
274 bit_cnt <= #1 31;
275 else if((state == DATA_RD) && (bit_cnt == 0))
276 bit_cnt <= #1 31;
277 else if((state == DATA_RDP) && (bit_cnt == 0))
278 bit_cnt <= #1 31;
279 else
280 bit_cnt <= #1 bit_cnt - 1;
281
282 // bit_cnt_read
283 if((state == DEVAD) && (bit_cnt == 1))
284 bit_cnt_read <= #1 17;
285 if((state == REGAD) && (bit_cnt == 1))
286 bit_cnt_read <= #1 17;
287
288 // st
289 if(state == IDLE)
290 st <= #1 0;
291 else if(state == ST)
292 st[bit_cnt] <= #1 mdio_d;
293
294 // op
295 if(state == IDLE)
296 op <= #1 0;
297 else if(state == OP)
298 op[bit_cnt] <= #1 mdio_d;
299
300 // prtad
301 if(state == IDLE)
302 prtad <= #1 0;
303 else if(state == PRTAD)
304 prtad[bit_cnt]<= #1 mdio_d;
305
306 // phyad
307 if(state == IDLE)
308 phyad <= #1 0;
309 else if(state == PHYAD)
310 phyad[bit_cnt]<= #1 mdio_d;
311
312 // devad
313 if(state == IDLE)
314 devad <= #1 0;
315 else if(state == DEVAD) begin
316 devad[bit_cnt]<= #1 mdio_d;
317 read_data <= #1 memory[addr];
318 end
319
320 // regad
321 if(state == IDLE)
322 regad <= #1 0;
323 else if(state == REGAD) begin
324 regad[bit_cnt]<= #1 mdio_d;
325 read_data <= #1 memory[{regad[4:1], mdio_d}];
326 end
327
328 // ta
329 if(state == IDLE)
330 ta <= #1 0;
331 else if(state == TA)
332 ta[bit_cnt] <= #1 mdio_d;
333
334 // addr
335 if(state == ADDR)
336 addr[bit_cnt] <= #1 mdio_d;
337
338 // data
339 if(state == IDLE)
340 data <= #1 0;
341 if(state == DATA_WR)
342 data[bit_cnt] <= #1 mdio_d;
343
344
345 // Write
346 if((state == DATA_WR) && (st == 2'b01) && (bit_cnt == 0)) // Claus22
347 if(phyad[4:0] == MY_PHY_ID)
348 write_en_22 <= #1 1'b1;
349
350 // Write
351 if((state == DATA_WR) && (st == 2'b00) && (bit_cnt == 0)) // Claus45
352 if((prtad[4:0] == MY_PRT_ID) && (devad[4:0] == MY_DEV_ID)) begin
353 write_en_45 <= #1 1'b1;
354 regad <= #1 addr;
355 end
356
357 if(write_en_22 == 1'b1) begin
358 memory[regad] <= #1 data;
359 $display("<%0d> MDIO_DEBUG: Write addr:%h data:%h Claus22 %m", $time, regad, data);
360 end
361
362 if(write_en_45 == 1'b1) begin
363 memory[addr] <= #1 data;
364 $display("<%0d> MDIO_DEBUG: Write addr:%h data:%h Claus45 %m", $time, addr, data);
365 end
366
367 // Read
368 if((state == DATA_RD) && (st == 2'b01)) begin // Claus22
369 if(phyad[4:0] == MY_PHY_ID) begin
370 if(bit_cnt == 0)
371 $display("<%0d> MDIO_DEBUG: Read addr:%h data:%h Claus22 %m", $time, regad, memory[regad]);
372 end
373 end
374
375 // Read
376 if((state == DATA_RD) && (st == 2'b00)) begin // Claus45
377 if((prtad[4:0] == MY_PRT_ID) && (devad[4:0] == MY_DEV_ID)) begin
378 if(bit_cnt == 0)
379 $display("<%0d> MDIO_DEBUG: Read addr:%h data:%h Claus45 %m", $time, addr, memory[addr]);
380 end
381 end
382
383 // Read post-read-increment-address
384 if((state == DATA_RDP) && (st == 2'b00)) begin // Claus45
385 if((prtad[4:0] == MY_PRT_ID) && (devad[4:0] == MY_DEV_ID)) begin
386 addr <= #1 addr + 1;
387 if(bit_cnt == 0)
388 $display("<%0d> MDIO_DEBUG: Read addr:%h data:%h %m", $time, addr, memory[addr]);
389 end
390 end
391end // always
392
393
394`ifdef AXIS
395`else // AXIS
396// logic to test poll mode in MIF
397// Provides facilities to modify mmd memory content
398reg [15:0] modify_mmd_memory_address;
399reg [15:0] modify_mmd_memory_data;
400reg [15:0] modify_mmd_memory_time;
401reg modify_mmd_memory_enable;
402integer ret_code;
403initial
404begin
405 modify_mmd_memory_address = 16'hFFFF;
406 modify_mmd_memory_data = 16'h0;
407 modify_mmd_memory_time = 16'h0;
408 modify_mmd_memory_enable = 1'b0;
409
410 if ($test$plusargs("MODIFY_MMD_MEMORY_ADDRESS="))
411 modify_mmd_memory_enable = 1'b1;
412
413 if ($test$plusargs("MODIFY_MMD_MEMORY_ADDRESS="))
414 ret_code = $value$plusargs("MODIFY_MMD_MEMORY_ADDRESS=%h", modify_mmd_memory_address);
415 if ($test$plusargs("MODIFY_MMD_MEMORY_DATA="))
416 ret_code = $value$plusargs("MODIFY_MMD_MEMORY_DATA=%h", modify_mmd_memory_data);
417 if ($test$plusargs("MODIFY_MMD_MEMORY_TIME="))
418 ret_code = $value$plusargs("MODIFY_MMD_MEMORY_TIME=%d", modify_mmd_memory_time);
419
420 // corrupt
421 if(modify_mmd_memory_enable) begin
422 $display("<%0d> MDIO_DEBUG: modify mmd memory at time:%0d mdc cycles addr:%h data:%h %m",
423 $time, modify_mmd_memory_time, modify_mmd_memory_address, modify_mmd_memory_data);
424 repeat(modify_mmd_memory_time) @(posedge mdc);
425 $display("<%0d> MDIO_DEBUG: modify mmd memory now time:%0d mdc cycles addr:%h data:%h %m",
426 $time, modify_mmd_memory_time, modify_mmd_memory_address, modify_mmd_memory_data);
427 memory[modify_mmd_memory_address] = modify_mmd_memory_data;
428 end
429
430end
431
432reg force_mmd_mdio_bus_enable;
433reg force_mmd_mdio_bus_value;
434reg [31:0] force_mmd_mdio_bus_time;
435
436initial
437begin
438 if ($test$plusargs("FORCE_MMD_MDIO_BUS_ENABLE"))
439 force_mmd_mdio_bus_enable = 1'b1;
440 else
441 force_mmd_mdio_bus_enable = 1'b0;
442
443 if ($test$plusargs("FORCE_MMD_MDIO_BUS_VALUE="))
444 ret_code = $value$plusargs("FORCE_MMD_MDIO_BUS_VALUE=%d", force_mmd_mdio_bus_value);
445
446 if ($test$plusargs("FORCE_MMD_MDIO_BUS_TIME="))
447 ret_code = $value$plusargs("FORCE_MMD_MDIO_BUS_TIME=%d", force_mmd_mdio_bus_time);
448
449 if(force_mmd_mdio_bus_enable) begin
450 $display("<%0d> MDIO_DEBUG: force mmd mdio at time:%0d mdc cycles %m",
451 $time, force_mmd_mdio_bus_time);
452 repeat(force_mmd_mdio_bus_time) @(posedge mdc);
453 force mdio_out = force_mmd_mdio_bus_value;
454 force mdio_en = force_mmd_mdio_bus_value;
455 force mdio_in = force_mmd_mdio_bus_value;
456 $display("<%0d> MDIO_DEBUG: force mmd mdio now time:%0d mdc cycles %m",
457 $time, force_mmd_mdio_bus_time);
458 end
459end
460`endif // AXIS
461
462endmodule
463