Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / ccxDevices / ccxDevSpcBFM.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ccxDevSpcBFM.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
37// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
38// To use this class, you must have in your bench a files called globals.vri
39// that has all global extern declerations in it.
40#include <globals.vri>
41
42#include <ccxDevicesDefines.vri>
43#include <std_display_defines.vri>
44
45#include <std_display_class.vrh>
46#include <basePktClass.vrh>
47#include <cpxPktClass.vrh>
48#include <pcxPktClass.vrh>
49#include <baseParamsClass.vrh>
50#include <sparcParams.vrh>
51#include <ccxDevBaseBFM.vrh>
52
53
54#define CLASSNAME CcxDevSpcBFM
55#define CLASSNAMEQ "CcxDevSpcBFM"
56
57class CLASSNAME extends CcxDevBaseBFM {
58
59 // methods
60 task new(integer instatnce, reg passiveIn=0, reg flagUnexpected=0, reg ccxOnly=0);
61 // virtual in base
62 task recv(BasePkt pktHndl);
63 task cancelRecv(BasePkt pktHndl);
64 task sendIntr(reg [5:0] tid,
65 reg [1:0] type,
66 reg [5:0] vect);
67 local task slave();
68}
69
70
71 task CLASSNAME::new (integer instatnce, reg passiveIn=0,
72 reg flagUnexpected=0, reg ccxOnly=0) {
73
74 super.new(instatnce,passiveIn,CLASSNAMEQ);
75 super.flagUnexpected = flagUnexpected;
76 ccxOnly = ccxOnly; // only testing ccx
77 srandom(gSeed,this);
78
79 if (!passiveIn) {
80 // Initialize Outputs
81 gPcxPort[myPort].$req = 0;
82 gPcxPort[myPort].$atmo = 0;
83 gPcxPort[myPort].$datao = 0;
84 }
85
86
87// fork {
88// monitor();
89// } join none
90
91
92 fork {
93 @(posedge gPcxPort[myPort].$clk);
94 gPcxPort[myPort].$gnt == 0;
95 gCpxPort[myPort].$datai == 0;
96 } join none
97
98
99 // as a slave, we listen to one of two crossbars
100 fork slave();
101 join none
102
103 // service mailboxes, send packets
104 fork super.serviceSends2(PP_PCX);
105 join none
106
107 }
108
109
110
111// use to receive an expected packet.
112// mainly for CCX testing.
113//
114// user passes in a packet who's fields are set to match the
115// packet that should show up at this port. When it does, the
116// caller is notified (toggle a var in the passed in packet) and
117// the passed in packet will be populated with what showed up at the
118// destinatin port. Unexpected (not registered via a call to this task)
119// packets will cause failure (if enabled).
120task CLASSNAME::recv(BasePkt pktHndl) {
121
122 //CpxPkt cpxPkt;
123
124 // assign/cast pktHndl to be of PcxPkt type rather than base
125 //cast_assign(cpxPkt,pktHndl);
126
127 // load signature hash. key is "signature" and data is handle.
128 expectedSig[pktHndl.signature] = pktHndl;
129
130}
131
132// Mainly for CCX testing. Call when a pkt should no longer arrive.
133// For CCX, a pkt should never intentionally get dropped so this may not get used.
134task CLASSNAME::cancelRecv(BasePkt pktHndl) {
135
136 //CpxPkt cpxPkt;
137
138 // assign/cast pktHndl to be of PcxPkt type rather than base
139 //cast_assign(cpxPkt,pktHndl);
140
141 // clear signature hash.
142 //void = assoc_index(DELETE,expectedSig,pcxPkt.getVector());
143 void = assoc_index(DELETE,expectedSig,pktHndl.signature);
144
145}
146
147
148
149 // Wait for data from CPX, we are a SPC
150 task CLASSNAME::slave() {
151
152 CpxPkt pktHndl;
153 ccxPort portVar = gCpxPort[myPort];
154 integer second = 0;
155 reg [145:0] tmpVec;
156
157// if (!passive) {
158
159 while (1) {
160 if (portVar.$datai[145] == 0) @(posedge portVar.$datai[145]);
161 pktHndl = new();
162 pktHndl.loadPkt(portVar.$datai, myPort);
163 pktHndl.ccxSourced = 1;
164
165 // anyone waiting for this packet?
166 // was it expected?
167 tmpVec = pktHndl.makeSignature();
168 if (assoc_index(CHECK, expectedSig, tmpVec)) {
169 expectedSig[tmpVec].loadPkt(pktHndl.getVector(), myPort);
170 expectedSig[tmpVec].arrivalTime = get_cycle();
171 expectedSig[tmpVec].pktArrived = ~expectedSig[tmpVec].pktArrived;
172 } else if (flagUnexpected) {
173 pktHndl.print(myPort);
174 PR_ERROR(CLASSNAMEQ, MON_ERROR,
175 psprintf ("Unexpected packet on port %0d, vector=%h",myPort,pktHndl.getVector()));
176 }
177
178 // do something
179 @(negedge portVar.$clk);
180 }
181
182 // while (1) {
183 // @(negedge portVar.$clk);
184 // if (portVar.$datai[145] == 1) {
185 // pktHndl = new();
186 // pktHndl.loadPkt(portVar.$datai, myPort);
187 // pktHndl.ccxSourced = 1;
188 // //if (gParam.ccxPktPrint[PP_CPX] || gParam.ccxPktPrint[PP_SPC]) pktHndl.print(myPort);
189 // }
190 // }
191
192
193
194 // while (1) {
195 // @(posedge portVar.$datai[145]);
196 // pktHndl = new();
197 // pktHndl.loadPkt(portVar.$datai, myPort);
198 // if (gParam.ccxPktPrint[PP_CPX] || gParam.ccxPktPrint[PP_SPC]) pktHndl[second].print(myPort);
199 //
200 // // deal with 2 ifill return pkts
201 // if (pktHndl[second].rtntyp == CPX_IFILL &&
202 // pktHndl[second].wayf4b == 0) {
203 // second++;
204 // @(negedge portVar.$clk);
205 // pktHndl[second] = new();
206 // pktHndl[second].loadPkt(portVar.$datai, myPort);
207 // if (gParam.ccxPktPrint[PP_CPX] || gParam.ccxPktPrint[PP_SPC]) pktHndl[second].print(myPort);
208 // }
209 //
210 // @(negedge portVar.$datai[145]);
211 // second = 0;
212 //
213 // // print?
214 // //printf("\n%0d CcxDevSpcBFM::slavePcx got packet!\n", get_cycle());
215 //
216 // //pktHndl.printPkt();
217 //
218 // // anyone waiting for this packet?
219 // // was it expected? review
220 //
221 // } // while
222
223// }
224 }
225
226
227
228
229// // monitor real devices initiations when we are passive on the bus.
230// task CLASSNAME::monitor() {
231//
232// ccxPort portVar = gPcxPort[myPort];
233// ccxPort portVarC = gCpxPort[myPort];
234// CpxPkt pktHndlC;
235// reg [9:0] atm,req;
236// integer i;
237//
238// if (gParam.ccxPktPrint[PP_PCX] ||
239// gParam.ccxPktPrint[PP_SPC] ||
240// gParam.ccxPktPrint[PP_TRG] ||
241// gParam.ccxPktPrintMask[myPort]) {
242//
243// while (get_cycle() < 3) @(posedge CLOCK);
244//
245// pktHndlC = new();
246//
247// // monitor SPC out going requests.
248// if (gParam.ccxPktPrint[PP_PCX] ||
249// gParam.ccxPktPrint[PP_SPC] ||
250// gParam.ccxPktPrintMask[myPort]) {
251// fork
252// {
253// // monitor SPC out going requests.
254// // need to detect req changing back to zero here.
255// while (1) {
256//
257// if (!portVar.$req) {
258// @(portVar.$req);
259// req = portVar.$req;
260// if (portVar.$atmo) {
261// i = 2;
262// atm = portVar.$atmo;
263// } else {
264// i = 1;
265// atm = 0;
266// }
267// }
268//
269// repeat (i) {
270// // need to fork off to handle streaming/ back to back packets
271// {
272// PcxPkt pktHndl = new(); // keep in block
273// fork {
274// pktHndl.atm_wire = atm;
275// pktHndl.req_wire = req;
276// @(negedge portVar.$clk);
277// pktHndl.loadPkt(portVar.$datao, myPort);
278// // if (gParam.ccxPktPrint[PP_PCX] ||
279// // gParam.ccxPktPrint[PP_SPC] ||
280// // gParam.ccxPktPrintMask[myPort])
281// pktHndl.print(myPort);
282// } join none
283// }
284// @(negedge portVar.$clk);
285// }// rep
286// } // while
287// } join none
288// }
289//
290// fork
291// {
292// // monitor SPC incomming packets/responses
293// if (gParam.ccxPktPrint[PP_CPX] ||
294// gParam.ccxPktPrint[PP_SPC] ||
295// gParam.ccxPktPrint[PP_TRG] ||
296// gParam.ccxPktPrintMask[myPort]) {
297//
298// while (1) {
299// if (portVarC.$datai[145] == 0) @(posedge portVarC.$datai[145]);
300// pktHndlC.loadPkt(portVarC.$datai, myPort);
301// // if (gParam.ccxPktPrint[PP_PCX] ||
302// // gParam.ccxPktPrint[PP_SPC] ||
303// // gParam.ccxPktPrint[PP_TRG] ||
304// // gParam.ccxPktPrintMask[myPort])
305// pktHndlC.print(myPort);
306// @(negedge portVar.$clk);
307// }
308// }
309//
310// // while (1) {
311// // @(negedge portVarC.$clk);
312// // if (portVarC.$datai[145] == 1) {
313// // pktHndlC.loadPkt(portVarC.$datai, myPort);
314// // if (gParam.ccxPktPrint[PP_PCX] ||
315// // gParam.ccxPktPrint[PP_SPC] ||
316// // gParam.ccxPktPrintMask[myPort]) pktHndlC.print(myPort);
317// // }
318// // }
319// } join none
320//
321// } // if
322// }
323//
324
325 // Create/config Interrupt Pkt. this is really a store packet to a certain
326 // I/O adddress at the NCU. The NCU then does an interrupt to the target.
327 task CLASSNAME::sendIntr(reg [5:0] tid,
328 reg [1:0] type,
329 reg [5:0] vect)
330 {
331 PcxPkt reqPkt;
332
333 reqPkt = new();
334 reqPkt.createIntr(tid,type,vect);
335 reqPkt.sendPorts = 1 << myPort;
336 reqPkt.targetPorts = 1 << tid[5:3];
337 reqPkt.send(1);
338 }
339