Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / classes / siu_ncu_mondo_checker.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: siu_ncu_mondo_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 <vera_defines.vrh>
36#include <VeraListProgram.vrh>
37#include <ListMacros.vrh>
38//#include <globals.vri>
39
40#define STD_DISP gDbg
41
42#include "top_defines.vrh"
43#include "siu_ncu_mondo.if.vrh"
44#include "siu_ncu_mondo_ports_binds.vrh"
45#include <std_display_defines.vri>
46#include <std_display_class.vrh>
47/////////////////////////////////////////////////////////////////////////////////
48class mondoPacket
49{
50 bit req;
51 bit [31:0] header;
52 bit [127:0] data;
53 bit [5:0] thread;
54
55 bit [5:0] mondo_id;
56 bit ack;
57 bit nack;
58
59 task new(
60 (bit req = 1'bx),
61 (bit [31:0] header = 128'hx),
62 (bit [127:0] data = 32'hx),
63 (bit [5:0] thread = 6'bx),
64 (bit [5:0] mondo_id = 6'hx),
65 (bit ack = 1'bx),
66 (bit nack = 1'bx)
67 );
68
69 function bit checkMondo(mondoPacket mondoAckNack);
70 task print_pkt(mondoPacket Pkt);
71}
72
73////////////////////////////////////////////////////////////////////////////
74
75task mondoPacket::new(
76 (bit req = 1'bx),
77 (bit [31:0] header = 128'hx),
78 (bit [127:0] data = 32'hx),
79 (bit [5:0] thread = 6'bx),
80 (bit [5:0] mondo_id = 6'hx),
81 (bit ack = 1'bx),
82 (bit nack = 1'bx))
83
84{
85 this.req = 1'bx;
86 this.header = 32'hx;
87 this.data = 127'hx;
88 this.thread = 6'bx;
89 this.mondo_id = 6'hx;
90 this.ack = 1'bx;
91 this.nack = 1'bx;
92}
93
94////////////////////////////////////////////////////////////////////////////
95// compare mondo req and ack
96function bit mondoPacket::checkMondo(mondoPacket mondoAckNack)
97{
98 if((mondoAckNack.ack) || (mondoAckNack.nack))
99 {
100 if(this.mondo_id == mondoAckNack.mondo_id)
101 {
102 checkMondo = 1;
103 }
104 else
105 {
106 checkMondo = 0;
107 }
108 }
109}
110
111///////////////////////////////////////////////////////////////////
112extern StandardDisplay gDbg;
113MakeVeraList(mondoPacket)
114
115class siu_ncu_mondo_checker
116{
117 integer mondo_queue_sem;
118 mondo_ncu_port mondo_port;
119 VeraList_mondoPacket mondo_pkt_queue;
120
121 task new(mondo_ncu_port portvar);
122 task collectMondoReq();
123 task collectMondoAck();
124 task collectMondoNack();
125 task dumpExpects();
126 task checkMondoAckNack(mondoPacket Pkt);
127}
128
129task siu_ncu_mondo_checker::new(mondo_ncu_port portvar)
130{
131 integer i;
132
133 mondo_port = portvar;
134 mondo_pkt_queue = new();
135 mondo_queue_sem = alloc(SEMAPHORE, 0, 1, 1);
136 fork
137 {
138 collectMondoReq();
139 }
140 {
141 collectMondoAck();
142 }
143 {
144 collectMondoNack();
145 }
146 join none
147}
148
149task siu_ncu_mondo_checker::collectMondoReq()
150{
151 mondoPacket reqPkt;
152 mondoPacket pendReqPkt;
153 bit [31:0] header;
154 bit [128:0] data;
155 integer size,i;
156
157 while (1)
158 {
159 @(posedge mondo_port.$req);
160 @(posedge mondo_port.$grant);
161 @(posedge mondo_port.$clk);
162 header[31:0] = mondo_port.$data;
163 reqPkt = new();
164 reqPkt.req = header[15:15];
165 reqPkt.header = header;
166 reqPkt.mondo_id = {header[14:11], header[2:1]};
167 @(posedge mondo_port.$clk);
168 data[127:96] = mondo_port.$data;
169 @(posedge mondo_port.$clk);
170 data[95:64] = mondo_port.$data;
171 fork
172 {
173 @(posedge mondo_port.$clk);
174 data[63:32] = mondo_port.$data;
175 @(posedge mondo_port.$clk);
176 data[31:0] = mondo_port.$data;
177 reqPkt.data = data;
178 reqPkt.thread = data[11:6];
179 semaphore_get(WAIT, mondo_queue_sem, 1);
180
181 PR_NORMAL ("siu_ncu_mondo_checker", MON_NORMAL, psprintf("Received Mondo Interrupt : Header %8h : Data %32h : mondo_id %2h",reqPkt.header, reqPkt.data, reqPkt.mondo_id));
182
183 size = mondo_pkt_queue.size();
184 if(size > 4)
185 {
186 PR_ERROR ("siu_ncu_mondo_checker", MON_ERROR, psprintf("Already 4 Mondo Interrupts are pending : Unexpecvted Mondo Interrupt with mondo id : %2h",pendReqPkt.mondo_id));
187 }
188
189 for(i = 0; i < size; i++)
190 {
191 pendReqPkt = mondo_pkt_queue.front();
192 mondo_pkt_queue.pop_front();
193 if(pendReqPkt.mondo_id == reqPkt.mondo_id)
194 {
195 PR_ERROR ("siu_ncu_mondo_checker", MON_ERROR, psprintf("Mondo Interrupt with mondo id : %2h already pending",pendReqPkt.mondo_id));
196 }
197 mondo_pkt_queue.push_back(pendReqPkt);
198 }
199 mondo_pkt_queue.push_back(reqPkt);
200 semaphore_put(mondo_queue_sem, 1);
201 }
202 join none
203 }
204}
205
206
207task siu_ncu_mondo_checker::collectMondoAck()
208{
209 mondoPacket ackPkt;
210
211 while (1)
212 {
213 @(posedge mondo_port.$clk);
214 if(mondo_port.$ack == 1'b1)
215 {
216 ackPkt = new();
217 ackPkt.ack = 1'b1;
218 ackPkt.mondo_id = mondo_port.$mondo_id;
219 checkMondoAckNack(ackPkt);
220 }
221 }
222}
223
224task siu_ncu_mondo_checker::collectMondoNack()
225{
226 mondoPacket nackPkt;
227
228 while (1)
229 {
230 @(posedge mondo_port.$clk);
231 if(mondo_port.$nack == 1'b1)
232 {
233 nackPkt = new();
234 nackPkt.nack = 1'b1;
235 nackPkt.mondo_id = mondo_port.$mondo_id;
236 checkMondoAckNack(nackPkt);
237 }
238 }
239}
240
241///////////////////////////////////////////////////////////////////////
242task siu_ncu_mondo_checker::checkMondoAckNack(mondoPacket Pkt)
243{
244 mondoPacket reqPkt;
245 integer size,i;
246 bit found = 0;
247
248 size = mondo_pkt_queue.size();
249
250
251 reqPkt = mondo_pkt_queue.front();
252 if(reqPkt.checkMondo(Pkt))
253 {
254 mondo_pkt_queue.pop_front();
255 found = 1;
256 if(Pkt.ack)
257 {
258 PR_NORMAL("siu_ncu_mondo_checker", MON_NORMAL, psprintf ("Received Ack for mondo Id : %2h \n", Pkt.mondo_id));
259 }
260 else if(Pkt.nack)
261 {
262 PR_NORMAL("siu_ncu_mondo_checker", MON_NORMAL, psprintf ("Received Nack for mondo Id : %2h \n", Pkt.mondo_id));
263 }
264 }
265 else
266 {
267 dumpExpects();
268 if(Pkt.ack)
269 {
270 PR_ERROR ("siu_ncu_mondo_checker", MON_ERROR, psprintf ("Received unexpected mondo Ack with mondo Id : %2h \n", Pkt.mondo_id));
271 }
272 else if(Pkt.nack)
273 {
274 PR_ERROR ("siu_ncu_mondo_checker", MON_ERROR, psprintf ("Received unexpected mondo Nack with mondo Id : %2h \n", Pkt.mondo_id));
275 }
276 }
277 semaphore_put(mondo_queue_sem, 1);
278}
279
280
281///////////////////////////////////////////////////////////////////////
282task siu_ncu_mondo_checker::dumpExpects()
283{
284 mondoPacket reqPkt;
285 integer size,i;
286
287 printf ("------ Dumping Expects for Mondo requests from SIU to NCU ------ \n");
288
289 for(i = 0; i < size; i++)
290 {
291 reqPkt = mondo_pkt_queue.front();
292 mondo_pkt_queue.pop_front();
293 printf (" %d : Mondo Id %2h : Header %8h : Data %32h \n", i, reqPkt.mondo_id, reqPkt.header, reqPkt.data);
294 }
295
296 printf("------------------------------------------------------------------ \n");
297}
298