Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / fnx / vlib / CCCXactor / vera / CCCXactor.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: CCCXactor.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 <vera_defines.vrh>
36#include "report_macros.vri"
37#include "cReport.vrh"
38#include "CCCXactor.port.vri"
39#include "CCCXactorDefines.vri"
40//#include "CCCXactorTransaction.vrh"
41//#include "CCCXactorPacketCollection.vrh"
42
43
44//------------------------------------------------------------------------------
45// Class Definition
46//
47//
48//
49//------------------------------------------------------------------------------
50
51class CCCXactor {
52
53 local CCCXactorRingDataIn ring_in_port;
54 local CCCXactorRingDataOut ring_out_port;
55 local ReportClass Report;
56 local integer drive_mbx,rcv_mbx,availTransID;
57 local event TransactionComplete;
58 local string XactorName;
59
60 //----------------------------------------------------------------------------
61 // Note that ring_in must be PHOLD in users interface definition.
62 //----------------------------------------------------------------------------
63
64 //--------------------------
65 // Constructor
66 //--------------------------
67
68 task new( CCCXactorRingDataIn ring_in_bind,
69 CCCXactorRingDataOut ring_out_bind,
70 ReportClass rpt,
71 integer BaseTransID );
72
73 //--------------------------
74 // ExecuteTrans Task
75 //--------------------------
76
77 task ExecuteTrans( CCCXactorTransaction ring_trans, integer timeout, integer min_timeout );
78
79 //--------------------------
80 // Drive Task
81 // - non blocking
82 //--------------------------
83
84 task Drive( CCCXactorTransaction ring_trans );
85
86
87 //--------------------------
88 // Expect Task
89 // - blocking
90 // - until satified
91 // - timeout
92 // - unexepected tran
93 //--------------------------
94
95 task Expect( CCCXactorTransaction ring_trans, integer timeout, integer min_timeout );
96
97 //--------------------------
98 // Driver Task
99 //--------------------------
100
101 protected task Driver();
102
103 //--------------------------
104 // Sampler Task
105 //--------------------------
106
107 protected task Sampler();
108}
109
110////////////////////////////////////////////////////////////////////////////////
111
112 //***************************************************************
113 // Constructor
114 //
115 // - Pass in bind to input port
116 // - Pass in bind to output port
117 // - Pass in reference to report
118 // - Pass in intial Trans ID
119 //
120 //***************************************************************
121
122
123task CCCXactor::new( CCCXactorRingDataIn ring_in_bind,
124 CCCXactorRingDataOut ring_out_bind,
125 ReportClass rpt,
126 integer BaseTransID )
127{
128
129 //------------------------------------
130 // Assign the Passed in Varibles
131 //------------------------------------
132 ring_in_port = ring_in_bind;
133 ring_out_port = ring_out_bind;
134 Report = rpt;
135 XactorName = "CCC_XACTOR";
136 availTransID = BaseTransID;
137
138
139#ifdef N2_FC
140 ring_in_port.$ring_data_in = {32{1'bz}};
141#endif
142
143 //------------------------------------
144 // Alloc the Mailbox Space
145 //------------------------------------
146
147 drive_mbx = alloc( MAILBOX, 0, 1 );
148 rcv_mbx = alloc( MAILBOX, 0, 1 );
149
150 if (drive_mbx == 0 || rcv_mbx == 0)
151 error ("%0s: Cannot alloc mailbox\n", XactorName);
152
153 //------------------------------------
154 // Call Driver and Sampler Tasks
155 //------------------------------------
156
157 Driver();
158 Sampler();
159}
160
161
162 //***************************************************************
163 // Execute Transaction Task
164 //
165 // - Pass in a CCC Transaction
166 // - Pass in a Timeout value
167 //
168 //***************************************************************
169
170
171
172task CCCXactor::ExecuteTrans( CCCXactorTransaction ring_trans,
173 integer timeout,
174 integer min_timeout )
175{
176#ifndef N2_FC
177 CCCXactorTransaction blank_data_trans;
178
179 //-----------------------------------
180 // Choose between Read and Write
181 //-----------------------------------
182
183 case (ring_trans.wr_rd_cmd) {
184
185 CCC_XACTOR_RD_CMD:
186 {
187
188 //------------------------------
189 // Copy Packet to New
190 //------------------------------
191
192 blank_data_trans = new;
193 blank_data_trans.error = ring_trans.error;
194 blank_data_trans.wr_rd_cmd = ring_trans.wr_rd_cmd;
195 blank_data_trans.address = ring_trans.address;
196 blank_data_trans.src_bus_id = ring_trans.src_bus_id;
197
198 blank_data_trans.RingXactionID.SetContextID( ring_trans.RingXactionID.GetContextID() );
199 blank_data_trans.RingXactionID.SetStrategyID( ring_trans.RingXactionID.GetStrategyID() );
200 blank_data_trans.RingXactionID.SetTransID( ring_trans.RingXactionID.GetTransID() );
201
202 //-------------------------------
203 // Call the Drive and Expect
204 //-------------------------------
205
206 fork
207 {
208 Expect( ring_trans, timeout, min_timeout);
209 }
210 {
211 Drive( blank_data_trans );
212 }
213 join all
214 }
215
216
217 CCC_XACTOR_WR_CMD:
218 {
219 fork {
220 Expect( ring_trans, timeout, min_timeout);
221 }
222 {
223 Drive( ring_trans );
224 }
225 join all
226 }
227
228 default:
229 QuickReport(Report, RTYP_TEST_ERROR,
230 "%s: executing transaction with invalid wr/rd cmd (%0b)",
231 XactorName, ring_trans.wr_rd_cmd );
232 }
233#endif
234}
235
236
237
238//***************************************************************
239// Drive Task
240//
241// - Pass in a CCC Transaction
242//
243//***************************************************************
244
245task CCCXactor::Drive( CCCXactorTransaction ring_trans )
246{
247#ifndef N2_FC
248 bit [ 31:0 ] ring_drive_data = 0;
249
250 CCCXactorPacketCollection drive_pkts = new;
251
252 //----------------------------------------------------
253 // Assign a transaction ID to the transaction
254 //----------------------------------------------------
255
256 ring_trans.RingXactionID.SetTransID( availTransID++ );
257
258 //--------------------------------
259 //Form Command Phase of Packet
260 //--------------------------------
261
262 ring_drive_data[CCC_RING_FIELD_CMD] = {1'b0, 1'b1, ring_trans.wr_rd_cmd};
263 ring_drive_data[CCC_RING_FIELD_SRC_BUS_ID] = ring_trans.src_bus_id;
264 ring_drive_data[CCC_RING_FIELD_ADDR] = ring_trans.address;
265
266 drive_pkts.ring_pkt_collection[0] = ring_drive_data;
267
268 //--------------------------------
269 //Form Data Phase 0 of Packet
270 //--------------------------------
271
272 ring_drive_data[CCC_TRANS_FIELD_DATA_0] = ring_trans.csr_data[63:32];
273
274 drive_pkts.ring_pkt_collection[1] = ring_drive_data;
275
276 //--------------------------------
277 //Form Data Phase 1 of Packet
278 //--------------------------------
279
280 ring_drive_data[CCC_TRANS_FIELD_DATA_1] = ring_trans.csr_data[31:0];
281
282 drive_pkts.ring_pkt_collection[2] = ring_drive_data;
283
284
285 //--------------------------------
286 // Put Into Mail Box
287 //--------------------------------
288
289 mailbox_put( drive_mbx, drive_pkts );
290#endif
291}
292
293
294//***************************************************************
295// Expect Task
296//
297// - Pass in a CCC Transaction
298// - Pass in a Time Out Value
299//
300//***************************************************************
301
302
303task CCCXactor::Expect( CCCXactorTransaction ring_trans,
304 integer timeout,
305 integer min_timeout)
306{
307#ifndef N2_FC
308 bit [31:0 ] ring_expect_data = 0;
309
310 CCCXactorPacketCollection expected_pkts = new;
311
312 bit satisfied_min_timeout = 1'b0;
313 bit satisfied_expect = 1'b0;
314 string tmp;
315
316 //--------------------------------
317 //Form Command Phase of Packet
318 //--------------------------------
319
320 ring_expect_data[CCC_RING_FIELD_CMD] = {1'b1, ring_trans.error, ring_trans.wr_rd_cmd};
321 ring_expect_data[CCC_RING_FIELD_SRC_BUS_ID] = ring_trans.src_bus_id;
322 ring_expect_data[CCC_RING_FIELD_ADDR] = ring_trans.address;
323
324 expected_pkts.ring_pkt_collection[0] = ring_expect_data;
325
326 //--------------------------------
327 //Form Data Phase 0 of Packet
328 //--------------------------------
329
330 if (ring_trans.wr_rd_cmd == CCC_XACTOR_RD_CMD) {
331 ring_expect_data[CCC_TRANS_FIELD_DATA_0] = ring_trans.csr_data[63:32];
332 }
333
334 expected_pkts.ring_pkt_collection[1] = ring_expect_data;
335
336 //--------------------------------
337 //Form Data Phase 1 of Packet
338 //--------------------------------
339
340 if (ring_trans.wr_rd_cmd == CCC_XACTOR_RD_CMD) {
341 ring_expect_data[CCC_TRANS_FIELD_DATA_1] = ring_trans.csr_data[31:0];
342 }
343
344 expected_pkts.ring_pkt_collection[2] = ring_expect_data;
345
346
347 sprintf( tmp, "%s: expect launched:\n%s",
348 XactorName, ring_trans.toString() );
349 QuickReport(Report, RTYP_DEBUG_3, tmp );
350
351
352 //----------------------------------------------------------------------------
353 // Launch Expect
354 //
355 // - Fork off Time out and Actual Expect
356 //----------------------------------------------------------------------------
357
358 fork
359 { //@min_timeout satisfied_min_timeout = 1'b1;
360
361 repeat (min_timeout) {
362
363 @(posedge ring_out_port.$clk);
364 sprintf( tmp, "%s: One Clock for Min Timeout: the min time out value is %d\n the value of timeout is %d\n",
365 XactorName, min_timeout, timeout);
366 QuickReport(Report, RTYP_DEBUG_3, tmp );
367
368
369 }
370 satisfied_min_timeout = 1'b1;
371
372 sprintf( tmp, "%s: Satified Min Timeout\n",
373 XactorName);
374 QuickReport(Report, RTYP_DEBUG_3, tmp );
375
376 }
377 join none
378
379
380 fork
381 {
382 @timeout ring_in_port.$ring_data_in = void; // wait
383 }
384 {
385 CCCXactorPacketCollection rcvd_pkts = new;
386
387 bit xor_check;
388
389
390 //------------------------------------------
391 // Wait for somthing in the MailBox
392 //
393 // - Put it in rcvd_pkts
394 //------------------------------------------
395
396 mailbox_get( WAIT, rcv_mbx, rcvd_pkts );
397
398
399 //-----------------------------------------
400 // Check for any x values from DUT
401 //-----------------------------------------
402
403 xor_check = ^rcvd_pkts.ring_pkt_collection[0];
404
405 if (xor_check === 1'bx) {
406 sprintf( tmp, "%s: sampled x during Command Phase:\n Command Phase: %b\n Data 0 Phase: %b\n Data 1 Phase: %b\n",
407 XactorName,
408 rcvd_pkts.ring_pkt_collection[0],
409 rcvd_pkts.ring_pkt_collection[1],
410 rcvd_pkts.ring_pkt_collection[2]
411 );
412 QuickReport(Report, RTYP_CCC_XTR_SAMPLED_X_ERROR, tmp );
413 }
414
415
416 //-----------------------------------------
417 // Check for Data Compare
418 //-----------------------------------------
419
420 if (expected_pkts.ring_pkt_collection[0] != rcvd_pkts.ring_pkt_collection[0]) {
421
422 sprintf( tmp,
423 "%s: unexpected transaction: Command Phase mismatch\nexpected:\n%sreceived:\n%s",
424 XactorName, expected_pkts.toString(), rcvd_pkts.toString() );
425 QuickReport(Report, RTYP_TEST_ERROR, tmp );
426 }
427
428
429 if (ring_trans.wr_rd_cmd == CCC_XACTOR_RD_CMD) {
430 if (expected_pkts.ring_pkt_collection[1] !== 32'hx && expected_pkts.ring_pkt_collection[1] !== rcvd_pkts.ring_pkt_collection[1]) {
431 sprintf( tmp,
432 "%s: unexpected transaction: Data Phase 0 mismatch\nexpected:\n%sreceived:\n%s",
433 XactorName, expected_pkts.toString(), rcvd_pkts.toString() );
434 QuickReport(Report, RTYP_TEST_ERROR, tmp );
435 }
436
437 if (expected_pkts.ring_pkt_collection[2] !== 32'hx && expected_pkts.ring_pkt_collection[2] !== rcvd_pkts.ring_pkt_collection[2]) {
438 sprintf( tmp,
439 "%s: unexpected transaction: Data Phase 1 mismatch\nexpected:\n%sreceived:\n%s",
440 XactorName, expected_pkts.toString(), rcvd_pkts.toString() );
441 QuickReport(Report, RTYP_TEST_ERROR, tmp );
442 }
443 }
444
445 //-------------------------------------------
446 // Check Trans didn't come back to fast
447 //-------------------------------------------
448
449 if (satisfied_min_timeout) {
450 satisfied_expect = 1'b1;
451
452 //------------------------------------------------------------
453 // Put Data Sampled into Packet so it can be used if
454 // user wants to put x's in
455 //------------------------------------------------------------
456 if (ring_trans.wr_rd_cmd) { }
457 else {
458 ring_expect_data = rcvd_pkts.ring_pkt_collection[1];
459 ring_trans.csr_data[63:32] = ring_expect_data;
460
461 ring_expect_data = rcvd_pkts.ring_pkt_collection[2];
462 ring_trans.csr_data[31:0] = ring_expect_data;
463 }
464 }
465
466 }
467
468 join any
469 terminate;
470
471 if(satisfied_expect !== 1'b1 ) {
472
473
474 if(satisfied_min_timeout !== 1'b1) {
475
476 sprintf( tmp, "%s: expected transaction came back to quickly:\n%s",
477 XactorName, ring_trans.toString() );
478 QuickReport(Report, RTYP_TEST_ERROR, tmp );
479 trigger( ONE_BLAST, TransactionComplete );
480
481 }
482 else {
483 sprintf( tmp, "%s: expected transaction timed out:\n%s",
484 XactorName, ring_trans.toString() );
485 QuickReport(Report, RTYP_TEST_ERROR, tmp );
486 trigger( ONE_BLAST, TransactionComplete );
487 }
488
489
490 }
491 else {
492 sprintf( tmp, "%s: expect satisifed:\n%s",
493 XactorName, ring_trans.toString() );
494 QuickReport(Report, RTYP_DEBUG_3, tmp );
495 }
496#endif
497}
498
499//***************************************************************
500// Driver Task
501//
502// - Launched by the contructor
503// - Constantly monitors the drive mailbox
504// - if has a packet sends and waits for sync
505//
506//
507//***************************************************************
508
509task CCCXactor::Driver()
510{
511#ifndef N2_FC
512 fork {
513
514 CCCXactorPacketCollection drive_pkts;
515
516 bit [31:0] drive_data;
517
518 @( posedge ring_in_port.$clk );
519
520 ring_in_port.$ring_data_in = CCC_XACTOR_IDLE;
521
522 while( 1 ) {
523 mailbox_get( WAIT, drive_mbx, drive_pkts );
524
525 @( posedge ring_in_port.$clk );
526 drive_data = drive_pkts.ring_pkt_collection[ 0 ];
527 ring_in_port.$ring_data_in = drive_data;
528
529 @( posedge ring_in_port.$clk );
530 drive_data = drive_pkts.ring_pkt_collection[ 1 ];
531 ring_in_port.$ring_data_in = drive_data;
532
533 @( posedge ring_in_port.$clk );
534 drive_data = drive_pkts.ring_pkt_collection[ 2 ];
535 ring_in_port.$ring_data_in = drive_data;
536
537 @( posedge ring_in_port.$clk );
538
539 ring_in_port.$ring_data_in = CCC_XACTOR_IDLE;
540
541 // Keep driving IDLE and wait for event notifying transaction complete
542
543 sync( ANY, TransactionComplete );
544
545 }
546 }
547 join none
548#endif
549}
550
551
552//***************************************************************
553// Sampler Task
554//
555//
556//***************************************************************
557
558
559
560task CCCXactor::Sampler()
561{
562#ifndef N2_FC
563 CCCXactorPacketCollection rcvd_pkts;
564
565 fork {
566 bit [ 31:0 ] curr_rcvd_data;
567
568 integer curr_state = CCC_XACTOR_SAMPLE_IDLE;
569 integer seen_mapped_bit = 0;
570 string tmp;
571
572 //---------------------------------------------------------------
573 // state machine
574 // CCC_XACTOR_SAMPLE_IDLE
575 // --> CSR ring is idle
576 // CCC_XACTOR_SAMPLE_REC_1
577 // --> detected Command phase,
578 // CCC_XACTOR_SAMPLE_REC_2
579 // -->
580 //---------------------------------------------------------------
581
582 while( 1 ) {
583 curr_rcvd_data = ring_out_port.$ring_data_out;
584
585 case( curr_state ) {
586
587 //---------------------------------------------------------------
588 // IDLE STATE
589 //
590 // - Stay here until a response is seen
591 // - 4 possible could be seen
592 // - READ 100
593 // - WRITE 101
594 // - READ ERROR 110
595 // - WRITE ERROR 111
596 //
597 //
598 // - When see response packet load data into index [0]
599 // of collection
600 //---------------------------------------------------------------
601
602 CCC_XACTOR_SAMPLE_IDLE: {
603
604 if (curr_rcvd_data[CCC_RING_FIELD_CMD] !== 3'b000) {
605
606 if (curr_rcvd_data[CCC_RING_FIELD_CMD_MSB] === 1'b1) {
607
608 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from IDLE to REC_1",XactorName );
609
610 rcvd_pkts = new;
611 rcvd_pkts.ring_pkt_collection[0] = curr_rcvd_data;
612
613 curr_state = CCC_XACTOR_SAMPLE_REC_1;
614
615 }
616 else {
617 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from IDLE to INVAL_1",XactorName );
618 curr_state = CCC_XACTOR_SAMPLE_INVAL_1;
619 }
620
621 }
622 }
623
624 //---------------------------------------------------------------
625 // INAVLID 1 STATE
626 //
627 //
628 //---------------------------------------------------------------
629
630 CCC_XACTOR_SAMPLE_INVAL_1: {
631
632 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from INVAL_1 to INVAL_2",XactorName );
633
634 curr_state = CCC_XACTOR_SAMPLE_INVAL_2;
635 }
636
637 //---------------------------------------------------------------
638 // INAVLID 2 STATE
639 //
640 //
641 //---------------------------------------------------------------
642
643 CCC_XACTOR_SAMPLE_INVAL_2: {
644
645 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from INVAL_2 to IDLE",XactorName );
646
647 curr_state = CCC_XACTOR_SAMPLE_IDLE;
648 }
649
650 //---------------------------------------------------------------
651 // REC 1 STATE
652 //
653 //
654 // - Load data into index [1] of collection
655 //---------------------------------------------------------------
656
657 CCC_XACTOR_SAMPLE_REC_1: {
658
659 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from REC_1 to REC_2",XactorName );
660
661 rcvd_pkts.ring_pkt_collection[1] = curr_rcvd_data;
662
663 curr_state = CCC_XACTOR_SAMPLE_REC_2;
664 }
665
666 //---------------------------------------------------------------
667 // REC 2 STATE
668 //
669 //
670 // - Load data into index [2] of collection
671 //---------------------------------------------------------------
672
673 CCC_XACTOR_SAMPLE_REC_2: {
674
675 QuickReport(Report, RTYP_DEBUG_3, "%s: transitioning from REC_2 to IDLE",XactorName );
676
677 rcvd_pkts.ring_pkt_collection[2] = curr_rcvd_data;
678
679 curr_state = CCC_XACTOR_SAMPLE_IDLE;
680 mailbox_put( rcv_mbx, rcvd_pkts );
681 rcvd_pkts = null;
682 trigger( ONE_BLAST, TransactionComplete );
683 }
684
685 default:
686 QuickReport(Report, RTYP_TEST_ERROR,
687 "%s: invalid state reached in CCCXactor.Sampler()",
688 XactorName );
689 }
690 @( posedge ring_out_port.$clk );
691 }
692 }
693 join none
694#endif
695}