Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / siu / vera / monitors / siu_dmu_mon.vr
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: siu_dmu_mon.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#include "siu_dmu_packet.vrh"
39#include "siu_monitor.vrh"
40
41class siu_dmu_monitor {
42 dmumon_port monitor;
43
44 siu_dmu_packet snd_packet;
45 siu_dmu_packet rec_packet;
46 integer snd_mbox, rec_mbox;
47
48 StandardDisplay dbg;
49 string myname;
50
51 task new (dmumon_port monitor, integer snd_mbox, integer rec_mbox, StandardDisplay dbg);
52
53 task monitor_send ();
54 task monitor_recv ();
55
56 function integer get_send_pkt(Cycle_Mode mode, integer cycle);
57 function integer check_send(Cycle_Mode mode);
58 function integer get_recv_pkt(Cycle_Mode mode, integer cycle);
59 function integer check_recv(Cycle_Mode mode);
60}
61
62task siu_dmu_monitor::new(dmumon_port monitor, integer snd_mbox, integer rec_mbox, StandardDisplay dbg)
63{
64 this.monitor = monitor;
65
66 snd_packet = new(RDD, 0, 0, 0, 1, 1);
67 rec_packet = new(RDD, 0, 0, 0, 1, 1);
68
69 this.snd_mbox = snd_mbox;
70 this.rec_mbox = rec_mbox;
71 this.dbg = dbg;
72 myname = "siu-dmu";
73
74 dbg.dispmon(myname, MON_NORMAL, psprintf ("monitor ready !"));
75
76 fork { monitor_send(); } join none
77 fork { monitor_recv(); } join none
78}
79
80task siu_dmu_monitor::monitor_send()
81{
82siu_dmu_packet packet;
83integer i, data_cycles;
84integer fail, result, temp;
85string t,p,q;
86
87 while (1)
88 {
89 @(posedge monitor.$clk);
90 if (monitor.$sreq === 1'b1)
91 {
92 data_cycles = 0;
93 fail = 0;
94 temp = 0;
95
96 // header
97 result = get_send_pkt(HEADER_C, 1);
98 fail = check_send(HEADER_C);
99
100 case (snd_packet.type) {
101 RDD: { t="R"; p="N"; }
102 WRI: { t="W";
103 p=(snd_packet.posted) ? "P" : "N"; }
104 WRM: { t="M"; p="P"; }
105 INT: { t="I"; p="N"; }
106 PIORTN: { t="P"; p="N"; }
107 }
108 q = (snd_packet.bypass) ? "bypass" : "order";
109 dbg.dispmon (myname, MON_NORMAL, psprintf ("snd [%s%s,%4x,%10x] %s ", t, p, snd_packet.id, snd_packet.pa, q));
110
111 // data
112 if (monitor.$sdatareq === 1'b1)
113 {
114 data_cycles = 4;
115 if (monitor.$datareq16 === 1'b1) data_cycles = 1;
116 }
117 for (i=0; i<data_cycles; i++)
118 {
119 @(posedge monitor.$clk);
120 result = get_send_pkt(DATA_C, i);
121 temp = check_send(DATA_C);
122 fail += temp;
123 }
124
125 packet = new(RDD, 0, 0, 0, 1, 1);
126 packet = snd_packet.object_copy();
127
128 if (fail != 0)
129 dbg.dispmon(myname, MON_ERR, psprintf ("dmu -> siu pkt=%x protocol fail!", snd_packet.id));
130 else
131 mailbox_put(snd_mbox, packet);
132 }
133 }
134}
135
136task siu_dmu_monitor::monitor_recv()
137{
138integer i, result, fail, temp, data_cycles;
139
140 while (1)
141 {
142 @(posedge monitor.$clk);
143 if (monitor.$rreq === 1'b1)
144 {
145 data_cycles = 0;
146 fail = 0;
147 temp = 0;
148
149 result = get_recv_pkt(HEADER_C, 1);
150 fail = check_recv(HEADER_C);
151
152 dbg.dispmon(myname, MON_NORMAL, psprintf ("siu -> dmu pkt=%x ", rec_packet.id));
153
154 // data
155 /*if (monitor.$rdatareq === 1'b1)*/ data_cycles = 4;
156 for (i=0; i<data_cycles; i++)
157 {
158 @(posedge monitor.$clk);
159 result = get_recv_pkt(DATA_C, i);
160 temp = check_recv(DATA_C);
161 fail += temp;
162 }
163
164 if (fail != 0)
165 dbg.dispmon(myname, MON_ERR, psprintf ("siu -> dmu pkt=%x protocol fail!", snd_packet.id));
166 else
167 mailbox_put(rec_mbox, rec_packet);
168 }
169 }
170}
171
172function integer siu_dmu_monitor::get_send_pkt(Cycle_Mode mode, integer cycle)
173{
174 if (mode == HEADER_C)
175 {
176 // bypass
177 snd_packet.bypass = monitor.$bypass;
178 // take header
179 snd_packet.posted = monitor.$sdata[126];
180 snd_packet.target = monitor.$sdata[123];
181 snd_packet.id = monitor.$sdata[79:64];
182 snd_packet.pa = monitor.$sdata[39:0];
183 snd_packet.tout = monitor.$sdata[82];
184 snd_packet.ue = monitor.$sdata[81];
185 snd_packet.uce = monitor.$sdata[80];
186 // type
187 if (monitor.$sdata[123] === 1'b1)
188 {
189 if (monitor.$sdatareq === 1'b0)
190 snd_packet.type = RDD;
191 else
192 if (monitor.$sdatareq === 1'b1)
193 {
194 if (monitor.$sdata[124] === 1'b1)
195 snd_packet.type = WRM;
196 else
197 snd_packet.type = WRI;
198 }
199 } else
200 {
201 if (monitor.$sdata[127] === 1'b1)
202 snd_packet.type = PIORTN;
203 else
204 snd_packet.type = INT;
205 }
206 }
207 if (mode == DATA_C)
208 {
209 snd_packet.data[cycle*2] = monitor.$sdata[63:0];
210 snd_packet.be[cycle*2] = monitor.$sdata[3:0];
211 snd_packet.data[cycle*2+1] = monitor.$sdata[127:64];
212 snd_packet.be[cycle*2+1] = monitor.$sdata[7:4];
213 }
214}
215
216function integer siu_dmu_monitor::check_send(Cycle_Mode mode)
217{
218 integer fail = 0;
219
220 if (mode == HEADER_C)
221 {
222 // to L2, RDD, WRI and WRM
223 if (monitor.$sdata[123] === 1'b1)
224 {
225 if (monitor.$sdata[122] !== 1'b0 || monitor.$sdata[127] !== 1'b0)
226 {
227 fail++;
228 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid DMA header"));
229 }
230 if (monitor.$sdatareq === 1'b0 && monitor.$datareq16 === 1'b0)
231 {
232 if (monitor.$sdata[126:125] !== 2'b01 )
233 {
234 fail++;
235 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid RDD header"));
236 }
237 }
238 else
239 if (monitor.$sdatareq === 1'b1)
240 {
241 if (monitor.$sdata[125:123] !== 3'b011 && monitor.$sdata[125:123] !== 3'b001 )
242 {
243 fail++;
244 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid WRI/WRM header"));
245 }
246 }
247 }
248 // to NCU PIORTN and INT
249 if (monitor.$sdata[122] === 1'b1)
250 {
251 if (monitor.$sdata[123] !== 1'b0)
252 {
253 fail++;
254 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid non-DMA header"));
255 }
256 if (monitor.$sdata[127] === 1'b1)
257 {
258 if (monitor.$sdata[126:125] !== 2'b01 )
259 {
260 fail++;
261 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid PIORTN header"));
262 }
263 }
264 else
265 {
266 if (monitor.$sdata[126:124] !== 3'b000 )
267 {
268 fail++;
269 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid INT header"));
270 }
271 }
272 }
273
274 // comment out and change later
275 /*
276 if (monitor.$sdata[121:83] !== 39'b0 || monitor.$sdata[63:40] !== 24'b0)
277 {
278 fail++;
279 dbg.dispmon(myname, MON_NORMAL, psprintf ("header error, reserved bits not zero"));
280 }
281 */
282 }
283 if (mode == DATA_C)
284 {
285 if (monitor.$sreq === 1'b1 || monitor.$sdatareq === 1'b1 || monitor.$datareq16 === 1'b1)
286 {
287 fail++;
288 dbg.dispmon(myname, MON_NORMAL, psprintf ("req error, active in data cycles"));
289 }
290 }
291
292 check_send = fail;
293}
294
295function integer siu_dmu_monitor::get_recv_pkt(Cycle_Mode mode, integer cycle)
296{
297 if (mode == HEADER_C)
298 {
299 // take header
300 rec_packet.posted = monitor.$rdata[126];
301 rec_packet.id = monitor.$rdata[79:64];
302 rec_packet.pa = monitor.$rdata[39:0];
303 rec_packet.tout = monitor.$rdata[82];
304 rec_packet.ue = monitor.$rdata[81];
305 rec_packet.uce = monitor.$rdata[80];
306 // type, changed somePerson as only RDD type is valid
307 /*if (monitor.$rdatareq === 1'b0)
308 rec_packet.type = WRI;
309 else
310 if (monitor.$rdatareq === 1'b1)*/
311 rec_packet.type = RDD;
312 }
313 if (mode == DATA_C)
314 {
315 rec_packet.data[cycle*2] = monitor.$rdata[63:0];
316 rec_packet.data[cycle*2+1] = monitor.$rdata[127:64];
317 }
318}
319
320function integer siu_dmu_monitor::check_recv(Cycle_Mode mode)
321{
322 integer fail = 0;
323
324 if (mode == HEADER_C)
325 {
326 /*if (monitor.$rdatareq === 1'b0)
327 {
328 if (monitor.$rdata[127:122] !== 6'b100010)
329 {
330 fail++;
331 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid WRI ack header"));
332 }
333 }
334 if (monitor.$rdatareq === 1'b1)
335 {*/
336 if (monitor.$rdata[127:122] !== 6'b101010)
337 {
338 fail++;
339 dbg.dispmon(myname, MON_NORMAL, psprintf ("invalid RDD rtn header"));
340 }
341 //}
342
343 if (monitor.$rdata[121:83] !== 39'b0 || monitor.$rdata[63:62] !== 2'b0 || monitor.$rdata[55:40] !== 16'b0)
344 {
345 fail++;
346 dbg.dispmon(myname, MON_NORMAL, psprintf ("header error, reserved bits not zero"));
347 }
348 }
349 if (mode == DATA_C)
350 {
351 if (monitor.$rreq === 1) // || monitor.$rdatareq === 1)
352 {
353 // Fu: 7/20/04 need document in the spec.
354 //fail++;
355 dbg.dispmon(myname, MON_WARN, psprintf ("req error, active in data cycles"));
356 }
357 }
358
359 check_recv = fail;
360}