Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / siu / vera / monitors / siu_order_checker.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: siu_order_checker.vr
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 "siumon.if.vrh"
36#include "siumon_ports_binds.vrh"
37#include "std_display_class.vrh"
38
39// added these #ifndefs for excluding code for NIU
40#ifndef FC_NO_NIU_T2
41#include "siu_niu_packet.vrh"
42#endif
43
44#include "siu_dmu_packet.vrh"
45#include "siu_ncu_packet.vrh"
46#include "siu_l2_packet.vrh"
47#include "siu_monitor.vrh"
48#include "siu_jtag_packet.vrh"
49
50//extern bit siu_RDDord_pass_niuord_diffbank;
51//extern bit siu_RDDord_not_pass_niuord_samebank;
52//extern bit siu_WRIord_not_pass_niuord;
53//extern bit siu_niubyp_pass_niubyp_diffbank;
54//extern bit siu_niubyp_not_pass_niubyp_samebank;
55//extern bit siu_niubyp_pass_niuord_diffbank;
56//extern bit siu_RDDbyp_pass_RDDord_samebank;
57//extern bit siu_WRIbyp_not_pass_niuord_samebank;
58
59// added this
60#ifndef FC_NO_NIU_T2
61ExternVeraList(siu_niu_packet);
62#endif
63ExternVeraList(siu_dmu_packet);
64
65class siu_order_checker {
66
67 // FIFO
68// added this
69#ifndef FC_NO_NIU_T2
70 VeraList_siu_niu_packet niu_fifo;
71 VeraListIterator_siu_niu_packet niu_fifo_ptr;
72#endif
73 VeraList_siu_dmu_packet dmu_ordered_list, dmu_bypass_list;
74 VeraListIterator_siu_dmu_packet dmu_ordered_ptr, dmu_bypass_ptr;
75
76 // mailbox id
77// added this
78#ifndef FC_NO_NIU_T2
79 integer niu_snd_mbox;
80 integer niu_rec_mbox;
81#endif
82 integer dmu_snd_mbox;
83 integer dmu_rec_mbox;
84 integer ncu_rec_mbox;
85 integer l2_snd_mbox[];
86 integer l2_rec_mbox[];
87
88// added this
89#ifndef FC_NO_NIU_T2
90 public bit siu_RDDord_pass_niuord_diffbank = 0;
91 public bit siu_RDDord_not_pass_niuord_samebank = 0;
92 public bit siu_WRIord_not_pass_niuord = 0;
93 public bit siu_niubyp_pass_niubyp_diffbank = 0;
94 public bit siu_niubyp_not_pass_niubyp_samebank = 0;
95 public bit siu_niubyp_pass_niuord_diffbank = 0;
96 public bit siu_RDDbyp_pass_RDDord_samebank = 0;
97 public bit siu_WRIbyp_not_pass_niuord_samebank = 0;
98#endif
99
100 local integer wrm_in_progress;
101 local bit checker_disabled;
102 local bit ibl2_checker_proceed[8];
103 local bit obl2_checker_proceed[8];
104
105 siu_jtag_packet pending_jtag;
106
107 StandardDisplay dbg;
108 string myname;
109
110 task new (
111// added this
112#ifndef FC_NO_NIU_T2
113 integer niu_snd_mbox,
114 integer niu_rec_mbox,
115#endif
116 integer dmu_snd_mbox,
117 integer dmu_rec_mbox,
118 integer ncu_rec_mbox,
119 integer l2_snd_mbox_0,
120 integer l2_rec_mbox_0,
121 integer l2_snd_mbox_1,
122 integer l2_rec_mbox_1,
123 integer l2_snd_mbox_2,
124 integer l2_rec_mbox_2,
125 integer l2_snd_mbox_3,
126 integer l2_rec_mbox_3,
127 integer l2_snd_mbox_4,
128 integer l2_rec_mbox_4,
129 integer l2_snd_mbox_5,
130 integer l2_rec_mbox_5,
131 integer l2_snd_mbox_6,
132 integer l2_rec_mbox_6,
133 integer l2_snd_mbox_7,
134 integer l2_rec_mbox_7,
135 StandardDisplay dbg);
136
137// added this
138#ifndef FC_NO_NIU_T2
139 task check_niu_snd();
140 task check_niu_rec();
141#endif
142 task check_dmu_snd();
143 task check_dmu_rec();
144 task check_l2_snd(integer i);
145 task check_l2_rec(integer i);
146 task check_ncu_rec();
147
148 local function integer check_inbound_l2_order(Siu_L2_Packet packet, integer i);
149 local function integer check_outbound_l2_order(Siu_L2_Packet packet, integer i);
150 local function integer check_inbound_ncu_order(siu_ncu_packet packet);
151 local function integer check_outbound_order(siu_basic_packet packet);
152
153// added this
154#ifndef FC_NO_NIU_T2
155 local function integer check_niu_order_rules(Siu_Packet_Type btype, bit[39:0] bpa, bit bbypass,
156 Siu_Packet_Type ttype, bit[39:0] tpa, bit tbypass);
157#endif
158 local function integer check_dmu_order_rules(Siu_Packet_Type btype, bit[39:0] bpa, Siu_Packet_Type ttype, bit[39:0] tpa);
159}
160
161task siu_order_checker::new(
162// added this
163#ifndef FC_NO_NIU_T2
164 integer niu_snd_mbox,
165 integer niu_rec_mbox,
166#endif
167 integer dmu_snd_mbox,
168 integer dmu_rec_mbox,
169 integer ncu_rec_mbox,
170 integer l2_snd_mbox_0,
171 integer l2_rec_mbox_0,
172 integer l2_snd_mbox_1,
173 integer l2_rec_mbox_1,
174 integer l2_snd_mbox_2,
175 integer l2_rec_mbox_2,
176 integer l2_snd_mbox_3,
177 integer l2_rec_mbox_3,
178 integer l2_snd_mbox_4,
179 integer l2_rec_mbox_4,
180 integer l2_snd_mbox_5,
181 integer l2_rec_mbox_5,
182 integer l2_snd_mbox_6,
183 integer l2_rec_mbox_6,
184 integer l2_snd_mbox_7,
185 integer l2_rec_mbox_7,
186 StandardDisplay dbg)
187{
188 integer i;
189
190 this.dbg = dbg;
191 myname = "siu-ord-chk";
192
193// added this
194#ifndef FC_NO_NIU_T2
195 this.niu_snd_mbox = niu_snd_mbox;
196 this.niu_rec_mbox = niu_rec_mbox;
197#endif
198 this.dmu_snd_mbox = dmu_snd_mbox;
199 this.dmu_rec_mbox = dmu_rec_mbox;
200 this.ncu_rec_mbox = ncu_rec_mbox;
201 this.l2_snd_mbox[0] = l2_snd_mbox_0;
202 this.l2_rec_mbox[0] = l2_rec_mbox_0;
203 this.l2_snd_mbox[1] = l2_snd_mbox_1;
204 this.l2_rec_mbox[1] = l2_rec_mbox_1;
205 this.l2_snd_mbox[2] = l2_snd_mbox_2;
206 this.l2_rec_mbox[2] = l2_rec_mbox_2;
207 this.l2_snd_mbox[3] = l2_snd_mbox_3;
208 this.l2_rec_mbox[3] = l2_rec_mbox_3;
209 this.l2_snd_mbox[4] = l2_snd_mbox_4;
210 this.l2_rec_mbox[4] = l2_rec_mbox_4;
211 this.l2_snd_mbox[5] = l2_snd_mbox_5;
212 this.l2_rec_mbox[5] = l2_rec_mbox_5;
213 this.l2_snd_mbox[6] = l2_snd_mbox_6;
214 this.l2_rec_mbox[6] = l2_rec_mbox_6;
215 this.l2_snd_mbox[7] = l2_snd_mbox_7;
216 this.l2_rec_mbox[7] = l2_rec_mbox_7;
217
218 wrm_in_progress = 0;
219 checker_disabled = 0;
220 if ( get_plus_arg(CHECK, "siu_order_chk_off") ) {
221 checker_disabled = 1;
222 dbg.dispmon(myname, MON_NORMAL, psprintf ("siu order checker off!"));
223 }
224 else
225 dbg.dispmon(myname, MON_NORMAL, psprintf ("siu order checker ready!"));
226
227// added this
228#ifndef FC_NO_NIU_T2
229 niu_fifo = new();
230#endif
231 dmu_ordered_list = new();
232 dmu_bypass_list = new();
233 pending_jtag = new(JRD,0,0);
234 for (i=0; i<8; i++)
235 {
236 ibl2_checker_proceed[i] = 1;
237 obl2_checker_proceed[i] = 1;
238 }
239
240
241// added this
242#ifndef FC_NO_NIU_T2
243 fork { check_niu_snd(); } join none
244 fork { check_niu_rec(); } join none
245#endif
246 fork { check_dmu_snd(); } join none
247 fork { check_dmu_rec(); } join none
248 fork { check_ncu_rec(); } join none
249 fork { check_l2_snd(0); } join none
250 fork { check_l2_snd(1); } join none
251 fork { check_l2_snd(2); } join none
252 fork { check_l2_snd(3); } join none
253 fork { check_l2_snd(4); } join none
254 fork { check_l2_snd(5); } join none
255 fork { check_l2_snd(6); } join none
256 fork { check_l2_snd(7); } join none
257 fork { check_l2_rec(0); } join none
258 fork { check_l2_rec(1); } join none
259 fork { check_l2_rec(2); } join none
260 fork { check_l2_rec(3); } join none
261 fork { check_l2_rec(4); } join none
262 fork { check_l2_rec(5); } join none
263 fork { check_l2_rec(6); } join none
264 fork { check_l2_rec(7); } join none
265}
266
267
268// added this
269#ifndef FC_NO_NIU_T2
270task siu_order_checker::check_niu_snd()
271{
272 siu_niu_packet niu_pkt, tmp_pkt;
273 integer mb_var;
274
275 while (1)
276 {
277 mb_var = mailbox_get(WAIT, niu_snd_mbox, tmp_pkt);
278 niu_pkt = tmp_pkt.object_copy();
279 niu_fifo.push_back(niu_pkt);
280 }
281}
282
283task siu_order_checker::check_niu_rec()
284{
285 siu_niu_packet niu_pkt;
286 integer mb_var;
287 integer fail = 0;
288
289 while (!fail)
290 {
291 mb_var = mailbox_get(WAIT, niu_rec_mbox, niu_pkt);
292
293 // check outbound ordering rule
294 fail = check_outbound_order(niu_pkt);
295 }
296}
297#endif
298
299
300task siu_order_checker::check_dmu_snd()
301{
302 siu_dmu_packet dmu_pkt;
303 integer mb_var;
304
305 while (1)
306 {
307 mb_var = mailbox_get(WAIT, dmu_snd_mbox, dmu_pkt);
308 if (dmu_pkt.bypass)
309 dmu_bypass_list.push_back(dmu_pkt);
310 else
311 dmu_ordered_list.push_back(dmu_pkt);
312 }
313}
314
315task siu_order_checker::check_dmu_rec()
316{
317 siu_dmu_packet dmu_pkt;
318 integer mb_var;
319 integer fail = 0;
320
321 while (!fail)
322 {
323 mb_var = mailbox_get(WAIT, dmu_rec_mbox, dmu_pkt);
324
325 // check outbound ordering rule
326 fail = check_outbound_order(dmu_pkt);
327 }
328}
329
330task siu_order_checker::check_ncu_rec()
331{
332 siu_ncu_packet ncu_pkt;
333 integer mb_var;
334 integer fail = 0;
335
336 while (!fail)
337 {
338 mb_var = mailbox_get(WAIT, ncu_rec_mbox, ncu_pkt);
339
340 // check inbound ordering
341 fail = check_inbound_ncu_order(ncu_pkt);
342 }
343}
344
345task siu_order_checker::check_l2_rec(integer i)
346{
347 Siu_L2_Packet l2_pkt;
348 integer mb_var;
349 integer fail;
350
351 while (ibl2_checker_proceed[i] && obl2_checker_proceed[i])
352 {
353 mb_var = mailbox_get(WAIT, this.l2_rec_mbox[i], l2_pkt);
354
355 fail = check_inbound_l2_order(l2_pkt, i);
356 }
357}
358
359task siu_order_checker::check_l2_snd(integer i)
360{
361 Siu_L2_Packet l2_pkt;
362 integer mb_var;
363 integer fail;
364
365 while (ibl2_checker_proceed[i] && obl2_checker_proceed[i])
366 {
367 mb_var = mailbox_get(WAIT, this.l2_snd_mbox[i], l2_pkt);
368
369 fail = check_outbound_l2_order(l2_pkt, i);
370 }
371}
372
373function integer siu_order_checker::check_outbound_l2_order(Siu_L2_Packet l2_pkt, integer i)
374{
375 integer fail = 0;
376 integer found = 0;
377
378 if (checker_disabled) {
379 check_outbound_l2_order = 1;
380 return;
381 }
382
383 if (l2_pkt.type == JRD || l2_pkt.type == JWR)
384 {
385 if (pending_jtag.valid == 0)
386 dbg.dispmon (myname, MON_ERR, psprintf ("l2 send jtag packet but no pending jtag packet pa=%x", l2_pkt.pa));
387 else
388 {
389 fail = (pending_jtag.type != l2_pkt.type) ? 1 : 0;
390 pending_jtag.valid = 0;
391 }
392 }
393
394 check_outbound_l2_order = fail;
395 obl2_checker_proceed[i] = ~fail;
396}
397
398function integer siu_order_checker::check_inbound_l2_order(Siu_L2_Packet l2_pkt, integer i)
399{
400// added this
401#ifndef FC_NO_NIU_T2
402 siu_niu_packet niu_pkt;
403#endif
404 siu_dmu_packet dmu_pkt;
405 integer fail = 0;
406 integer found = 0;
407
408 if (checker_disabled) {
409 check_inbound_l2_order = 1;
410 return;
411 }
412
413 if (l2_pkt.type == JRD || l2_pkt.type == JWR)
414 {
415 if (pending_jtag.valid == 1)
416 dbg.dispmon (myname, MON_ERR, psprintf (" more than one jtag packet, pending jtag packet pa=%x", pending_jtag.pa));
417 else
418 {
419 pending_jtag.type = l2_pkt.type;
420 pending_jtag.pa = l2_pkt.pa;
421 pending_jtag.data = l2_pkt.data[0];
422 pending_jtag.valid = 1;
423 }
424 }
425 else
426 if (l2_pkt.source == 1) // dmu
427 {
428 dbg.dispmon (myname, MON_NORMAL, psprintf ("chk dmu pkt[%x] pa=%x", l2_pkt.id, l2_pkt.pa));
429 dmu_ordered_ptr = dmu_ordered_list.start();
430
431 if (dmu_ordered_list.size() == 0)
432 {
433 // check wrm
434 if (l2_pkt.type == WRM && wrm_in_progress)
435 fail = 0;
436 else
437 {
438 fail = 1;
439 dbg.dispmon (myname, MON_ERR, psprintf ("l2 receive dmu pkt[%x] but dmu list is empty!", l2_pkt.id));
440 }
441 }
442 while (!found && dmu_ordered_ptr != null && !fail)
443 {
444 dmu_pkt = dmu_ordered_ptr.data();
445
446 // check for wrm
447 if (wrm_in_progress)
448 {
449 if (l2_pkt.type == WRM)
450 found = 1;
451 else
452 wrm_in_progress = 0;
453 }
454
455 // if I found the packet, then no problem
456 if (!found)
457 {
458 if ((dmu_pkt.id === l2_pkt.id) || (dmu_pkt.type == WRM && l2_pkt.type == WRM))
459 {
460 wrm_in_progress = (l2_pkt.type == WRM) ? 1 : 0;
461 found = 1;
462 dbg.dispmon (myname, MON_NORMAL, psprintf ("dmu order chkP pkt[%x]", dmu_pkt.id));
463 dmu_ordered_ptr = dmu_ordered_list.erase(dmu_ordered_ptr);
464 }
465 else // I shall check can my pkt pass this packet in the list
466 {
467 dbg.dispmon (myname, MON_NORMAL, psprintf ("chk rules for bypassing pkt[%x] pa=%x bp=%1d", dmu_pkt.id, dmu_pkt.pa, dmu_pkt.bypass));
468
469 fail = check_dmu_order_rules(l2_pkt.type, l2_pkt.pa, dmu_pkt.type, dmu_pkt.pa);
470 dmu_ordered_ptr.next();
471 }
472 }
473 }
474
475 if (found)
476 {
477 // compare packet
478 }
479 }
480
481// added this
482#ifndef FC_NO_NIU_T2
483 else // niu
484 {
485 dbg.dispmon (myname, MON_NORMAL, psprintf ("chk niu pkt[%x] pa=%x", l2_pkt.id, l2_pkt.pa));
486 niu_fifo_ptr = niu_fifo.start();
487
488 while (!found && niu_fifo_ptr != null && !fail)
489 {
490 niu_pkt = niu_fifo_ptr.data();
491
492 // if I found the packet, then no problem
493 if (niu_pkt.id === l2_pkt.id)
494 {
495 found = 1;
496 dbg.dispmon (myname, MON_NORMAL, psprintf ("niu order chkP pkt[%x]", niu_pkt.id));
497 niu_fifo_ptr = niu_fifo.erase(niu_fifo_ptr);
498 }
499 else // I shall check can my pkt pass this packet in the list
500 {
501 dbg.dispmon (myname, MON_NORMAL, psprintf ("chk rules for bypassing pkt[%x] pa=%x bp=%1d", niu_pkt.id, niu_pkt.pa, niu_pkt.bypass));
502
503 fail = check_niu_order_rules(l2_pkt.type, l2_pkt.pa, l2_pkt.bypass, niu_pkt.type, niu_pkt.pa, niu_pkt.bypass);
504 niu_fifo_ptr.next();
505 }
506 }
507
508 if (found)
509 {
510 // compare packet
511 }
512 }
513#endif
514 //if (!fail) dbg.dispmon (myname, MON_NORMAL, psprintf ("order chkP pkt[%x]", l2_pkt.id));
515
516 check_inbound_l2_order = fail;
517 ibl2_checker_proceed[i] = ~fail;
518}
519
520function integer siu_order_checker::check_inbound_ncu_order(siu_ncu_packet ncu_pkt)
521{
522}
523
524function integer siu_order_checker::check_outbound_order(siu_basic_packet packet)
525{
526}
527
528// added this
529#ifndef FC_NO_NIU_T2
530function integer siu_order_checker::check_niu_order_rules(Siu_Packet_Type btype, bit[39:0] bpa, bit bbypass, Siu_Packet_Type ttype, bit[39:0] tpa, bit tbypass)
531{
532 integer fail = 1;
533
534 if (bbypass == 0)
535 {
536 // ord RDD pkt can bypass other order WRI pkt, if the addr is different
537 // ord RDD pkt can bypass other order RDD pkt, if the addr is different
538 if (btype == RDD && tbypass == 0)
539 {
540 if (bpa[38:6] !== tpa[38:6])
541 {
542 fail = 0;
543 dbg.dispmon (myname, MON_INFO, psprintf ("RDD order pkt can bypass order pkt in different bank %x:%x", bpa, tpa));
544 siu_RDDord_pass_niuord_diffbank = 1;
545 }
546 else {
547 dbg.dispmon (myname, MON_NORMAL, psprintf ("RDD order pkt cannot bypass order pkt in same bank %x:%x", bpa, tpa));
548 siu_RDDord_not_pass_niuord_samebank = 1;
549 }
550 }
551 else {
552 dbg.dispmon (myname, MON_NORMAL, psprintf ("WRI order pkt cannot bypass"));
553 siu_WRIord_not_pass_niuord = 1;
554 }
555 }
556 else
557 {
558 // bp pkt can bypass other bp pkt, if other are for different banks
559 // bp pkt can bypass order pkt, if no address dependency
560 // bp RDD pkt can bypass order RDD pkt, with the same address
561 if (tbypass == 1)
562 {
563 if (bpa[38:6] !== tpa[38:6])
564 {
565 fail = 0;
566 dbg.dispmon (myname, MON_INFO, psprintf ("bypass pkt can bypass bypass pkt in different bank %x:%x", bpa, tpa));
567 siu_niubyp_pass_niubyp_diffbank = 1;
568 }
569 else {
570 dbg.dispmon (myname, MON_NORMAL, psprintf ("bypass pkt cannot bypass bypass pkt in same bank "));
571 siu_niubyp_not_pass_niubyp_samebank = 1;
572 }
573 }
574 else
575 {
576 if (bpa[38:6] !== tpa[38:6])
577 {
578 fail = 0;
579 dbg.dispmon (myname, MON_INFO, psprintf ("bypass pkt can bypass order pkt in different bank %x:%x", bpa, tpa));
580 siu_niubyp_pass_niuord_diffbank = 1;
581 }
582 else
583 {
584 if (btype == RDD && ttype == RDD)
585 {
586 fail = 0;
587 dbg.dispmon (myname, MON_INFO, psprintf ("bypass RDD pkt can bypass order RDD pkt in same bank %x:%x", bpa, tpa));
588 siu_RDDbyp_pass_RDDord_samebank = 1;
589 }
590 else {
591 dbg.dispmon (myname, MON_NORMAL, psprintf ("WRI bypass pkt cannot bypass order pkt in same bank "));
592 siu_WRIbyp_not_pass_niuord_samebank = 1;
593 }
594 }
595 }
596 }
597
598 check_niu_order_rules = fail;
599}
600#endif
601
602// For N2, dmu only use order queue for DMA and Mondo interrupt, so we do not check the bypass queue
603function integer siu_order_checker::check_dmu_order_rules(Siu_Packet_Type btype, bit[39:0] bpa, Siu_Packet_Type ttype, bit[39:0] tpa)
604{
605 integer fail = 1;
606
607 // RDD pkt can bypass other order WRI pkt, if the addr is different
608 // RDD pkt can bypass other order RDD pkt, if the addr is different
609 if (btype == RDD)
610 {
611 if (bpa[38:6] !== tpa[38:6])
612 {
613 fail = 0;
614 dbg.dispmon (myname, MON_INFO, psprintf ("RDD order pkt can bypass order pkt in different bank %x:%x", bpa, tpa));
615 //RDDord_pass_niuord_diffbank = 1;
616 }
617 else {
618 dbg.dispmon (myname, MON_NORMAL, psprintf ("RDD order pkt cannot bypass order pkt in same bank %x:%x", bpa, tpa));
619 //RDDord_not_pass_niuord_samebank = 1;
620 }
621 }
622 else {
623 dbg.dispmon (myname, MON_NORMAL, psprintf ("WRI order pkt cannot bypass"));
624 //WRIord_not_pass_niuord = 1;
625 }
626
627 check_dmu_order_rules = fail;
628}