Commit | Line | Data |
---|---|---|
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 | ||
41 | class 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 | ||
62 | task 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 | ||
80 | task siu_dmu_monitor::monitor_send() | |
81 | { | |
82 | siu_dmu_packet packet; | |
83 | integer i, data_cycles; | |
84 | integer fail, result, temp; | |
85 | string 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 | ||
136 | task siu_dmu_monitor::monitor_recv() | |
137 | { | |
138 | integer 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 | ||
172 | function 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 | ||
216 | function 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 | ||
295 | function 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 | ||
320 | function 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 | } |