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