Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / verilog / debug / debug.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: debug.v
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 ============================================
35module debug0;
36
37reg [7:0] parkedState;
38reg [7:0] parkTrans;
39reg [7:0] stepDone; // these tids have stepped
40reg [7:0] stepAllowed; // these tids will be stepping/active
41reg [7:0] stepActive;
42reg [7:0] virtualPark; // tid is "virtually parked"
43reg [7:0] watchStepFlush;
44reg [7:0] watchStepMMU;
45//reg [7:0] spuActive;
46reg doMode;
47reg ssMode;
48reg enabled;
49reg wasEnabled;
50reg noCmtCheck;
51integer stepWaitTime;
52integer redirectWait;
53integer parkWait;
54integer tmp;
55//integer spuTimeout;
56integer stepCount;
57//reg [63:0] threadEnable;
58integer flushCount0;
59integer flushCount1;
60integer flushCount2;
61integer flushCount3;
62integer flushCount4;
63integer flushCount5;
64integer flushCount6;
65integer flushCount7;
66integer redirectCount0;
67integer redirectCount1;
68integer redirectCount2;
69integer redirectCount3;
70integer redirectCount4;
71integer redirectCount5;
72integer redirectCount6;
73integer redirectCount7;
74integer pipelineCount0;
75integer pipelineCount1;
76integer pipelineCount2;
77integer pipelineCount3;
78integer pipelineCount4;
79integer pipelineCount5;
80integer pipelineCount6;
81integer pipelineCount7;
82integer junk;
83reg [1:0] cmtValid0;
84reg [1:0] cmtValid1;
85integer cmtCount0;
86integer cmtCount1;
87integer lastActiveVal;
88integer cmtCountT0;
89integer cmtCountT1;
90integer cmtCountT2;
91integer cmtCountT3;
92integer count0;
93integer count1;
94integer count2;
95integer count3;
96integer count4;
97integer count5;
98integer count6;
99integer count7;
100
101initial begin
102 parkedState = 8'hff;
103 parkTrans = 8'h0;
104 doMode = 0;
105 ssMode = 0;
106 stepDone = 0; // when stepDone = ~parked, all threads have steped
107 stepAllowed = 0;
108 stepActive = 0;
109 virtualPark = 0;
110 watchStepFlush = 0;
111 watchStepMMU = 0;
112 enabled = 0; // start out 0!
113 wasEnabled = 0;
114 noCmtCheck = 0;
115 stepCount = 0;
116// threadEnable = 0;
117 flushCount0 = 0;
118 flushCount1 = 0;
119 flushCount2 = 0;
120 flushCount3 = 0;
121 flushCount4 = 0;
122 flushCount5 = 0;
123 flushCount6 = 0;
124 flushCount7 = 0;
125 redirectCount0 = 0;
126 redirectCount1 = 0;
127 redirectCount2 = 0;
128 redirectCount3 = 0;
129 redirectCount4 = 0;
130 redirectCount5 = 0;
131 redirectCount6 = 0;
132 redirectCount7 = 0;
133 cmtValid0 = 0;
134 cmtValid1 = 0;
135 //spuActive = 0;
136 cmtCount0 = 0;
137 cmtCount1 = 0;
138 lastActiveVal = 0;
139 cmtCountT0 = 0;
140 cmtCountT1 = 0;
141 cmtCountT2 = 0;
142 cmtCountT3 = 0;
143 // tunable paramaters
144`ifdef SPC_BENCH
145 stepWaitTime = 1000; // From ss_start to ss_done, unless SPU
146 redirectWait = 30; // From core_running_status to redirect
147 parkWait = 600; // How long until core_running_status gets asserted/deasserted
148 //spuTimeout = 10000000; // How long until we give up on waiting for possible SPU activity
149`else
150 stepWaitTime = 2000; // From ss_start to ss_done, unless SPU
151 redirectWait = 60; // From core_running_status to redirect
152 //spuTimeout = 15000000; // How long until we give up on waiting for possible SPU activity
153 // How long until core_running_status gets asserted/deasserted
154 #2
155 parkWait = `PARGS.th_timeout-100;
156`endif
157end
158
159initial begin
160 //while (`TOP.core_cycle_cnt !== 5) #10;
161 @(negedge `TOP.in_reset);
162`ifdef FC_BENCH
163`ifdef FLUSH_RESET
164 @(posedge `TOP.flush_reset_complete);
165`endif
166`endif
167 @(posedge `SPC0.l2clk);
168 if (! $test$plusargs("noDebugChecks")) enabled = 1;
169 if (enabled) `PR_ALWAYS ("dbg_chk", `ALWAYS, "Core 0 Debug Logic Checker debug.v is alive and enabled.");
170 else `PR_ALWAYS ("dbg_chk", `ALWAYS, "!!!Core 0 Debug Logic Checker NOT enabled!!!");
171 if ($test$plusargs("noCmtCheck")) noCmtCheck = 1;
172 if (noCmtCheck) `PR_ALWAYS ("dbg_chk", `ALWAYS, "!!!Core 0 Debug Logic Commit Checker NOT enabled!!!");
173 if ($value$plusargs("stepWaitTime=%d", tmp)) stepWaitTime = tmp;
174 if ($value$plusargs("redirectWait=%d", tmp)) redirectWait = tmp;
175 if ($value$plusargs("parkWait=%d", tmp)) parkWait = tmp;
176 //if ($value$plusargs("spuTimeout=%d", tmp)) spuTimeout = tmp;
177 //if (enabled) `PR_ALWAYS ("dbg_chk", `ALWAYS, "Using stepWaitTime/redirectWait/parkWait/spuTimeout = %0d/%0d/%0d/%0d",stepWaitTime,redirectWait,parkWait,spuTimeout);
178 //threadEnable = `PARGS.finish_mask;
179 //if (enabled) `PR_ALWAYS ("dbg_chk", `ALWAYS, "Assuming active threads are (%h)", threadEnable);
180end
181
182
183
184// look for some reset change
185always @(`TOP.flush_reset_complete) begin
186 `PR_ALWAYS ("debugChecker", `ALWAYS, "flush_reset_complete changed to %0d. checker enabled=%0d",`TOP.flush_reset_complete,enabled);
187 // going into some kind of reset
188 if (enabled && !`TOP.flush_reset_complete) begin
189 wasEnabled = 1;
190 enabled = 0;
191 end
192 disable parkingCheck0;
193 disable parkedCheck0;
194 disable unparkCheck0;
195 disable watchStep0;
196 disable parkingCheck1;
197 disable parkedCheck1;
198 disable unparkCheck1;
199 disable watchStep1;
200 disable parkingCheck2;
201 disable parkedCheck2;
202 disable unparkCheck2;
203 disable watchStep2;
204 disable parkingCheck3;
205 disable parkedCheck3;
206 disable unparkCheck3;
207 disable watchStep3;
208 disable parkingCheck4;
209 disable parkedCheck4;
210 disable unparkCheck4;
211 disable watchStep4;
212 disable parkingCheck5;
213 disable parkedCheck5;
214 disable unparkCheck5;
215 disable watchStep5;
216 disable parkingCheck6;
217 disable parkedCheck6;
218 disable unparkCheck6;
219 disable watchStep6;
220 disable parkingCheck7;
221 disable parkedCheck7;
222 disable unparkCheck7;
223 disable watchStep7;
224 disable DOMODE;
225 disable SSMODE;
226 parkedState = 8'hff;
227 cmtValid0 = 0;
228 cmtValid1 = 0;
229 // coming out of reset
230 if (wasEnabled && `TOP.flush_reset_complete) begin
231 parkTrans = 8'b0;
232 enabled = 1;
233 wasEnabled = 0;
234 cmtValid0 = 0;
235 cmtValid1 = 0;
236`ifdef FC_BENCH
237`ifdef FLUSH_RESET
238 if (`TOP.flush_reset_complete !== 1) @(posedge `TOP.flush_reset_complete);
239`endif
240`endif
241 end
242 `PR_ALWAYS ("debugChecker", `ALWAYS, "flush_reset_complete/rst_wmr_protect transition complete. checker enabled=%0d",enabled);
243end
244
245//////////////////////////////////////////////////////////////////
246// THREAD 0
247//////////////////////////////////////////////////////////////////
248
249
250// got park request. transition into parking. parking check.
251always @(negedge `SPC0.tlu.tcu_core_running[0]) begin: GOTPARK0
252 `PR_DEBUG("dbg_chk", `DEBUG, "TID 0 calling parkingCheck");
253 if (enabled) parkingCheck0();
254end
255
256// got unpark request. transition into running. unparking check.
257always @(posedge `SPC0.tlu.tcu_core_running[0]) begin: UNPARKCHECK0
258 if (enabled && !ssMode) begin
259 `PR_DEBUG("dbg_chk", `DEBUG, "TID 0 calling unparkCheck.");
260 unparkCheck0();
261 end
262end
263
264// while parked check
265always @(posedge parkedState[0] or posedge virtualPark[0]) begin: PARKCHECK0
266 `PR_DEBUG("dbg_chk", `DEBUG, "TID 0 calling parkedCheck");
267 if (enabled) parkedCheck0();
268end
269
270// check for unexpected running transition
271 always @(`SPC0.tlu.tlu_core_running_status[0]) begin: UNEXPECTED0
272 if (!parkTrans[0] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
273 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[0]);
274end
275
276
277
278////////////// tasks for tid 0 ////////////////////
279
280// check the entering into parked state
281task parkingCheck0;
282
283begin
284
285
286 `PR_DEBUG("dbg_chk", `DEBUG, "TID 0 got park request!");
287
288 if (parkTrans[0] == 1) begin
289 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
290 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
291 disable parkingCheck0;
292 end
293
294 parkTrans[0] = 1;
295
296 // wait before checking signals
297 repeat (2) @(negedge `SPC0.l2clk);
298
299 // need to see at least one assertion of flush
300 // if (`SPC0.tlu_flush_ifu[0] !== 1)
301 // @(posedge `SPC0.tlu_flush_ifu[0]); // has glitches
302 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[0] !== 1)
303 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[0]);
304
305 // need to see all of these go idle
306 while (`SPC0.pku_quiesce[0] == 0 ||
307 `SPC0.ftu_ifu_quiesce[0] == 0 ||
308 `SPC0.lsu_stb_empty[0] == 0)
309 @(negedge `SPC0.l2clk);
310
311// // need to see all of these go idle
312// while (`SPC0.pku_quiesce[0] == 0 ||
313// `SPC0.ftu_ifu_quiesce[0] == 0 ||
314// `SPC0.lsu_stb_empty[0] == 0 ||
315// `SPC0.tlu.fls0.idl_request == 0)
316// @(negedge `SPC0.l2clk);
317
318 parkedState[0] <= 1;
319 parkTrans[0] <= 0;
320 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 0);
321 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 0 has parked!");
322
323end
324endtask
325
326
327// in parked state.
328// also called between single steps.
329task parkedCheck0;
330reg notified;
331begin //{
332
333 notified = 0;
334 // loop while not transitioning out of park if not SS mode.
335 // loop while in SS virtualPark if SS mode.
336 while ((parkTrans[0] == 0 && ssMode == 0) ||
337 (virtualPark[0] == 1 && ssMode == 1 &&
338 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
339 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 0 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[0],virtualPark[0],`TOP.cpu.tcu_ss_request[0]);
340
341 @(negedge `SPC0.l2clk);
342
343 // if in SS mode and core_running goes to zero for that thread, the thread
344 // will self step once and flush in order to change to a parked state
345 // (core_running_status=0). This looks like an un-asked for step so it
346 // has to be detected and ignored. Try stalling here during it.
347 while (`SPC0.tlu.tcu_core_running[0] == 0 &&
348 `SPC0.tlu.tlu_core_running_status[0] == 1)
349 @(negedge `SPC0.l2clk);
350
351 // watch for instructions sneaking in
352 // dec_inst_valid_m[1:0], one bit per group
353 if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 0 && `SPC0.tlu.tlu_retry[0] == 1)
354 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 had tlu_trap_pc_0_valid activity while parked/between steps!");
355
356 if (`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 0)
357 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 had dec_inst_valid_m activity while parked/between steps!");
358
359
360 end //} while
361
362 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 0 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[0],virtualPark[0],`TOP.cpu.tcu_ss_request[0]);
363
364end //}
365endtask
366
367
368// leaving parked state
369task unparkCheck0;
370integer count;
371begin
372
373 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 0 got unpark request!");
374
375 if (parkTrans[0] == 1) begin
376 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
377 disable unparkCheck0;
378 end
379
380 parkTrans[0] = 1;
381
382 // must see `SPC0.tlu.core_running_status[0] w/in count clocks
383 count0 = 0;
384
385 while (`SPC0.tlu.tlu_core_running_status[0] == 0) begin
386 @(negedge `SPC0.l2clk);
387 if (count0 > parkWait) begin // <--- may need to adjust
388 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count0);
389 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
390 end
391 count0 = count0 + 1;
392 end
393
394 if (!doMode && !ssMode) begin
395 // need to see re-direct w/in "redirectWait" more clocks
396 count0 = 0;
397
398 // if this is true, the redirect and the assertion of core_running_status
399 // happened at once so while loop can be skipped.
400 while (! (`SPC0.tlu_trap_pc_0_valid &&
401 `SPC0.tlu_trap_0_tid[1:0] == 0)) begin
402 @(negedge `SPC0.l2clk);
403 if (count0 > redirectWait) begin // <--- may need to adjust
404 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 0 did not redirect within %d clocks after core_running_status assert!", redirectWait);
405 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
406 end
407 count0 = count0 + 1;
408 end
409 end
410
411 parkedState[0] <= 0;
412 parkTrans[0] <= 0;
413 count0 <= 0;
414
415end
416endtask
417
418
419// watch this tid step correctly. Should step 1 instruction
420// and then "virtual park".
421// for SS and DO modes.
422task watchStep0;
423begin
424
425 watchStepFlush[0] = 0; // set if we got a flush
426 watchStepMMU[0] = 0; // set if we got a mmu reload
427 stepDone[0] = 0;
428 stepActive[0] = 1;
429
430 if (flushCount0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount0,redirectCount0);
431
432
433 fork
434 // timeout fork
435 begin : FORK10_0
436 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
437 `PR_ERROR ("dbg_chk", `ERROR, "watchStep0: TID 0 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
438 end
439
440// // look for SPU going active
441// begin : FORK11_0
442// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)))
443// @(negedge `SPC0.l2clk);
444// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 see SPU active!");
445// spuActive[0] = 1;
446// end
447
448 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
449 // this task gets called w/o knowing in advance if there will be one more
450 // assertion of tlu_trap_pc_0/1_valid or not.
451 begin : FORK8_0
452 if (ssMode) begin
453 @(posedge `SPC0.spc_ss_complete);
454 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount0, redirectCount0);
455 stepDone[0] = 1;
456 stepActive[0] = 0;
457 disable watchStep0; // return
458 end
459 end
460
461 // valid PC / retry
462 begin : FORK9_0
463 // start step. tid wakes up/redirects and does "one instruction"
464 while (!(`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 0 && `SPC0.tlu.tlu_retry[0] == 1)) begin
465 // might see `SPC0.tlu.mmu_reload_done[0] here if previous
466 // redirect was due to a MMU miss. If so, decrement flush count because
467 // the previous flush on prev pc_valid "does not count" and there can be
468 // any number of them w/ no way to predict quantity.
469 if (`SPC0.tlu.mmu_reload_done[0] && ssMode) begin
470 flushCount0 = flushCount0-1;
471 redirectCount0 = redirectCount0-1;
472 watchStepMMU[0] = 1;
473 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount0, redirectCount0);
474 end
475 @(negedge `SPC0.l2clk);
476 end
477
478 redirectCount0 = redirectCount0+1;
479 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount0);
480 disable FORK8_0; // kill sync on spc_ss_complete
481
482 @(negedge `SPC0.pku_quiesce[0]);
483 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
484
485 while (!(`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 0)) @(negedge `SPC0.l2clk);
486
487 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 valid step starting!");
488 disable FORK10_0; // kill timeout
489 //disable FORK11_0;
490 // if (!`SPC0.spu_tlu_cwq_busy &&
491// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
492// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)) spuActive[0] = 0;
493 end
494 join
495
496
497
498 // finish step
499 fork
500 // timeout fork
501 begin : FORK4_0
502 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
503
504 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
505 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
506 // since it can assert after the step has started.
507 `PR_ERROR ("dbg_chk", `ERROR, "watchStep0: TID 0 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
508 end
509
510 // look for SPU going active
511// begin : FORK12_0
512// while (!(`SPC0.spu_tlu_cwq_busy ||
513// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
514// @(negedge `SPC0.l2clk);
515// spuActive[0] = 1;
516// end
517
518
519 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
520 // and end this task if seen. tlu_flush_ifu assertion always means
521 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
522 begin : FORK6_0
523 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
524 while (`SPC0.tlu_flush_ifu[0] == 0)
525 @(negedge `SPC0.l2clk);
526
527// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
528// if (`SPC0.tlu.fls0.ptrap_flush[0] == 1) begin
529// `PR_ERROR ("dbg_chk", `ERROR, "watchStep0: TID 0 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
530// end
531//
532
533 if ((ssMode && `SPC0.tlu.fls0.ptrap_flush[0] == 0) || doMode) begin
534 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 have tlu_flush_ifu (flushCount=%0d)!",flushCount0);
535 watchStepFlush[0] = 1;
536 flushCount0 = flushCount0+1;
537 stepActive[0] = 0;
538 disable watchStep0; // return
539 end
540 end
541
542
543 // are we done fork, DO mode quiesce
544 begin : FORK5_0
545 if (doMode) begin
546 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 watching for quiesce (only matters fo DO mode)!");
547 while (`SPC0.pku_quiesce[0] == 0 ||
548 `SPC0.ftu_ifu_quiesce[0] == 0 ||
549 `SPC0.lsu_stb_empty[0] == 0) @(negedge `SPC0.l2clk);
550
551 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 have quiesce (only matters for DO mode)!");
552 if (doMode) begin
553 disable FORK4_0; // TO
554 disable FORK6_0; // flush check
555 //disable FORK12_0;
556// @(negedge `SPC0.l2clk);
557// if (!`SPC0.spu_tlu_cwq_busy &&
558// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
559// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)) spuActive[0] = 0;
560 end
561 end
562 end
563
564
565 // are we done fork, SS mode only
566 begin : FORK7_0
567 // wait for SS complete
568 if (ssMode) begin
569 @(posedge `SPC0.spc_ss_complete);
570 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount0,redirectCount0);
571 stepDone[0] = 1;
572
573// while (ssMode && !`SPC0.spc_ss_complete) begin
574// // detect a second inst valid w/o a flush between
575// if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 0 && `SPC0.tlu.tlu_retry[0] == 1) begin
576// // delay error so flush thread can kill this in the "got flush" case
577// @(negedge `SPC0.l2clk);
578// `PR_ERROR ("dbg_chk", `ERROR, "watchStep0: TID 0 had another inst start before SS done was asserted!");
579// end
580// @(negedge `SPC0.l2clk);
581// end // while
582
583 if (`SPC0.pku_quiesce[0] == 0 ||
584 `SPC0.ftu_ifu_quiesce[0] == 0 ||
585 `SPC0.lsu_stb_empty[0] == 0)
586 `PR_ERROR ("dbg_chk", `ERROR, "watchStep0: TID 0 was not quiesce at ss_complete assertion!");
587
588 disable FORK4_0; // TO
589 disable FORK6_0; // flush check
590 //disable FORK12_0;
591// @(negedge `SPC0.l2clk);
592// if (!`SPC0.spu_tlu_cwq_busy &&
593// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
594// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)) spuActive[0] = 0;
595 end
596 end
597
598 join
599
600
601 if (flushCount0 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 watchStep end!");
602 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep0: TID 0 repeated watchStep end!");
603
604 stepActive[0] = 0;
605
606end
607endtask
608
609
610
611// check that thread does DO mode correctly
612task watchDOsteps0;
613begin
614
615 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0: TID 0 watchDOsteps starting!");
616
617 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps0;
618
619 // now wait for a thread to start. TCU internal signal.
620 if (`SPC0.tlu.tlu_core_running_status[0] == 0)
621 @(posedge `SPC0.tlu.tlu_core_running_status[0]);
622
623 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0 TID 0 unparked and running in DO mode!");
624
625 // loop on step checking. DO mode is self stepping
626 while (doMode) begin : watchDOsteps0loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
627
628 stepDone[0] = 0;
629 watchStepFlush[0] = 0;
630 watchStepMMU[0] = 0;
631
632 // are we starting to park in middle of DO mode (or end)?
633 // wait here until unparked again
634 if (parkTrans[0]) begin
635 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0 TID 0 getting parked, will delay");
636 @(negedge parkTrans[0]);
637 if (!doMode) disable watchDOsteps0loop; // no longer in DO mode, bail
638 // wait to be unparked or !doMode
639 if (parkedState[0]) begin
640 @(negedge doMode or negedge parkedState[0]);
641 if (!doMode) disable watchDOsteps0loop; // no longer in DO mode, bail
642 end
643 end
644
645
646 // an unparked thread does one instruction to completion before thread starts
647 // the next instruction.
648 fork
649 // timeout fork
650 begin : FORKDO10
651 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
652 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps0: DO mode, TID 0 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
653 end
654
655 // look for SPU going active
656// begin : FORKDO20
657// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)))
658// @(negedge `SPC0.l2clk);
659// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps0: DO mode, TID 0 sees SPU busy!");
660// spuActive[0] = 1;
661// end
662
663 // watch step
664 begin
665 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0: TID 0 calling watchStep0 in DO mode!");
666 watchStep0; // returns when step is done or flushed
667 if (watchStepFlush[0])
668 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 0 in DO mode had flush!");
669 if (watchStepMMU[0])
670 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 0 in DO mode had mmu reload!");
671 // calling flush as a done in DO mode
672 disable FORKDO10; // TO
673 //disable FORKDO20; // SPU going active
674 end
675
676 join
677
678 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0: TID 0 DO mode watchDOsteps step done!");
679 stepDone[0] = 1;
680 flushCount0 = 0;
681// if (!`SPC0.spu_tlu_cwq_busy &&
682// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
683// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)) spuActive[0] = 0;
684
685 @(negedge `SPC0.l2clk);
686 end // while
687
688 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps0: TID 0 DO mode watchDOsteps task ending!");
689end
690endtask
691
692
693
694
695////////////////////////// end tid 0 ///////////////////////////////////////
696
697
698//////////////////////////////////////////////////////////////////
699// THREAD 1
700//////////////////////////////////////////////////////////////////
701
702
703// got park request. transition into parking. parking check.
704always @(negedge `SPC0.tlu.tcu_core_running[1]) begin: GOTPARK1
705 `PR_DEBUG("dbg_chk", `DEBUG, "TID 1 calling parkingCheck");
706 if (enabled) parkingCheck1();
707end
708
709// got unpark request. transition into running. unparking check.
710always @(posedge `SPC0.tlu.tcu_core_running[1]) begin: UNPARKCHECK1
711 if (enabled && !ssMode) begin
712 `PR_DEBUG("dbg_chk", `DEBUG, "TID 1 calling unparkCheck.");
713 unparkCheck1();
714 end
715end
716
717// while parked check
718always @(posedge parkedState[1] or posedge virtualPark[1]) begin: PARKCHECK1
719 `PR_DEBUG("dbg_chk", `DEBUG, "TID 1 calling parkedCheck");
720 if (enabled) parkedCheck1();
721end
722
723// check for unexpected running transition
724 always @(`SPC0.tlu.tlu_core_running_status[1]) begin: UNEXPECTED1
725 if (!parkTrans[1] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
726 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[1]);
727end
728
729
730
731////////////// tasks for tid 1 ////////////////////
732
733// check the entering into parked state
734task parkingCheck1;
735
736begin
737
738
739 `PR_DEBUG("dbg_chk", `DEBUG, "TID 1 got park request!");
740
741 if (parkTrans[1] == 1) begin
742 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
743 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
744 disable parkingCheck1;
745 end
746
747 parkTrans[1] = 1;
748
749 // wait before checking signals
750 repeat (2) @(negedge `SPC0.l2clk);
751
752 // need to see at least one assertion of flush
753 // if (`SPC0.tlu_flush_ifu[1] !== 1)
754 // @(posedge `SPC0.tlu_flush_ifu[1]); // has glitches
755 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[1] !== 1)
756 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[1]);
757
758 // need to see all of these go idle
759 while (`SPC0.pku_quiesce[1] == 0 ||
760 `SPC0.ftu_ifu_quiesce[1] == 0 ||
761 `SPC0.lsu_stb_empty[1] == 0)
762 @(negedge `SPC0.l2clk);
763
764// // need to see all of these go idle
765// while (`SPC0.pku_quiesce[1] == 0 ||
766// `SPC0.ftu_ifu_quiesce[1] == 0 ||
767// `SPC0.lsu_stb_empty[1] == 0 ||
768// `SPC0.tlu.fls0.idl_request == 0)
769// @(negedge `SPC0.l2clk);
770
771 parkedState[1] <= 1;
772 parkTrans[1] <= 0;
773 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 1);
774 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 1 has parked!");
775
776end
777endtask
778
779
780// in parked state.
781// also called between single steps.
782task parkedCheck1;
783reg notified;
784begin //{
785
786 notified = 0;
787 // loop while not transitioning out of park if not SS mode.
788 // loop while in SS virtualPark if SS mode.
789 while ((parkTrans[1] == 0 && ssMode == 0) ||
790 (virtualPark[1] == 1 && ssMode == 1 &&
791 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
792 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 1 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[1],virtualPark[1],`TOP.cpu.tcu_ss_request[0]);
793
794 @(negedge `SPC0.l2clk);
795
796 // if in SS mode and core_running goes to zero for that thread, the thread
797 // will self step once and flush in order to change to a parked state
798 // (core_running_status=0). This looks like an un-asked for step so it
799 // has to be detected and ignored. Try stalling here during it.
800 while (`SPC0.tlu.tcu_core_running[1] == 0 &&
801 `SPC0.tlu.tlu_core_running_status[1] == 1)
802 @(negedge `SPC0.l2clk);
803
804 // watch for instructions sneaking in
805 // dec_inst_valid_m[1:0], one bit per group
806 if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 1 && `SPC0.tlu.tlu_retry[0] == 1)
807 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 had tlu_trap_pc_0_valid activity while parked/between steps!");
808
809 if (`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 1)
810 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 had dec_inst_valid_m activity while parked/between steps!");
811
812
813 end //} while
814
815 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 1 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[1],virtualPark[1],`TOP.cpu.tcu_ss_request[0]);
816
817end //}
818endtask
819
820
821// leaving parked state
822task unparkCheck1;
823integer count;
824begin
825
826 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 1 got unpark request!");
827
828 if (parkTrans[1] == 1) begin
829 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
830 disable unparkCheck1;
831 end
832
833 parkTrans[1] = 1;
834
835 // must see `SPC0.tlu.core_running_status[1] w/in count clocks
836 count1 = 0;
837
838 while (`SPC0.tlu.tlu_core_running_status[1] == 0) begin
839 @(negedge `SPC0.l2clk);
840 if (count1 > parkWait) begin // <--- may need to adjust
841 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count1);
842 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
843 end
844 count1 = count1 + 1;
845 end
846
847 if (!doMode && !ssMode) begin
848 // need to see re-direct w/in "redirectWait" more clocks
849 count1 = 0;
850
851 // if this is true, the redirect and the assertion of core_running_status
852 // happened at once so while loop can be skipped.
853 while (! (`SPC0.tlu_trap_pc_0_valid &&
854 `SPC0.tlu_trap_0_tid[1:0] == 1)) begin
855 @(negedge `SPC0.l2clk);
856 if (count1 > redirectWait) begin // <--- may need to adjust
857 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 1 did not redirect within %d clocks after core_running_status assert!", redirectWait);
858 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
859 end
860 count1 = count1 + 1;
861 end
862 end
863
864 parkedState[1] <= 0;
865 parkTrans[1] <= 0;
866 count1 <= 0;
867
868end
869endtask
870
871
872// watch this tid step correctly. Should step 1 instruction
873// and then "virtual park".
874// for SS and DO modes.
875task watchStep1;
876begin
877
878 watchStepFlush[1] = 0; // set if we got a flush
879 watchStepMMU[1] = 0; // set if we got a mmu reload
880 stepDone[1] = 0;
881 stepActive[1] = 1;
882
883 if (flushCount1) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount1,redirectCount1);
884
885
886 fork
887 // timeout fork
888 begin : FORK10_1
889 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
890 `PR_ERROR ("dbg_chk", `ERROR, "watchStep1: TID 1 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
891 end
892
893// // look for SPU going active
894// begin : FORK11_1
895// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)))
896// @(negedge `SPC0.l2clk);
897// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 see SPU active!");
898// spuActive[1] = 1;
899// end
900
901 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
902 // this task gets called w/o knowing in advance if there will be one more
903 // assertion of tlu_trap_pc_0/1_valid or not.
904 begin : FORK8_1
905 if (ssMode) begin
906 @(posedge `SPC0.spc_ss_complete);
907 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount1, redirectCount1);
908 stepDone[1] = 1;
909 stepActive[1] = 0;
910 disable watchStep1; // return
911 end
912 end
913
914 // valid PC / retry
915 begin : FORK9_1
916 // start step. tid wakes up/redirects and does "one instruction"
917 while (!(`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 1 && `SPC0.tlu.tlu_retry[0] == 1)) begin
918 // might see `SPC0.tlu.mmu_reload_done[1] here if previous
919 // redirect was due to a MMU miss. If so, decrement flush count because
920 // the previous flush on prev pc_valid "does not count" and there can be
921 // any number of them w/ no way to predict quantity.
922 if (`SPC0.tlu.mmu_reload_done[1] && ssMode) begin
923 flushCount1 = flushCount1-1;
924 redirectCount1 = redirectCount1-1;
925 watchStepMMU[1] = 1;
926 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount1, redirectCount1);
927 end
928 @(negedge `SPC0.l2clk);
929 end
930
931 redirectCount1 = redirectCount1+1;
932 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount1);
933 disable FORK8_1; // kill sync on spc_ss_complete
934
935 @(negedge `SPC0.pku_quiesce[1]);
936 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
937
938 while (!(`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 1)) @(negedge `SPC0.l2clk);
939
940 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 valid step starting!");
941 disable FORK10_1; // kill timeout
942 //disable FORK11_1;
943 // if (!`SPC0.spu_tlu_cwq_busy &&
944// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
945// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)) spuActive[1] = 0;
946 end
947 join
948
949
950
951 // finish step
952 fork
953 // timeout fork
954 begin : FORK4_1
955 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
956
957 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
958 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
959 // since it can assert after the step has started.
960 `PR_ERROR ("dbg_chk", `ERROR, "watchStep1: TID 1 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
961 end
962
963 // look for SPU going active
964// begin : FORK12_1
965// while (!(`SPC0.spu_tlu_cwq_busy ||
966// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
967// @(negedge `SPC0.l2clk);
968// spuActive[1] = 1;
969// end
970
971
972 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
973 // and end this task if seen. tlu_flush_ifu assertion always means
974 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
975 begin : FORK6_1
976 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
977 while (`SPC0.tlu_flush_ifu[1] == 0)
978 @(negedge `SPC0.l2clk);
979
980// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
981// if (`SPC0.tlu.fls0.ptrap_flush[1] == 1) begin
982// `PR_ERROR ("dbg_chk", `ERROR, "watchStep1: TID 1 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
983// end
984//
985
986 if ((ssMode && `SPC0.tlu.fls0.ptrap_flush[1] == 0) || doMode) begin
987 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 have tlu_flush_ifu (flushCount=%0d)!",flushCount1);
988 watchStepFlush[1] = 1;
989 flushCount1 = flushCount1+1;
990 stepActive[1] = 0;
991 disable watchStep1; // return
992 end
993 end
994
995
996 // are we done fork, DO mode quiesce
997 begin : FORK5_1
998 if (doMode) begin
999 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 watching for quiesce (only matters fo DO mode)!");
1000 while (`SPC0.pku_quiesce[1] == 0 ||
1001 `SPC0.ftu_ifu_quiesce[1] == 0 ||
1002 `SPC0.lsu_stb_empty[1] == 0) @(negedge `SPC0.l2clk);
1003
1004 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 have quiesce (only matters for DO mode)!");
1005 if (doMode) begin
1006 disable FORK4_1; // TO
1007 disable FORK6_1; // flush check
1008 //disable FORK12_1;
1009// @(negedge `SPC0.l2clk);
1010// if (!`SPC0.spu_tlu_cwq_busy &&
1011// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1012// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)) spuActive[1] = 0;
1013 end
1014 end
1015 end
1016
1017
1018 // are we done fork, SS mode only
1019 begin : FORK7_1
1020 // wait for SS complete
1021 if (ssMode) begin
1022 @(posedge `SPC0.spc_ss_complete);
1023 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount1,redirectCount1);
1024 stepDone[1] = 1;
1025
1026// while (ssMode && !`SPC0.spc_ss_complete) begin
1027// // detect a second inst valid w/o a flush between
1028// if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 1 && `SPC0.tlu.tlu_retry[0] == 1) begin
1029// // delay error so flush thread can kill this in the "got flush" case
1030// @(negedge `SPC0.l2clk);
1031// `PR_ERROR ("dbg_chk", `ERROR, "watchStep1: TID 1 had another inst start before SS done was asserted!");
1032// end
1033// @(negedge `SPC0.l2clk);
1034// end // while
1035
1036 if (`SPC0.pku_quiesce[1] == 0 ||
1037 `SPC0.ftu_ifu_quiesce[1] == 0 ||
1038 `SPC0.lsu_stb_empty[1] == 0)
1039 `PR_ERROR ("dbg_chk", `ERROR, "watchStep1: TID 1 was not quiesce at ss_complete assertion!");
1040
1041 disable FORK4_1; // TO
1042 disable FORK6_1; // flush check
1043 //disable FORK12_1;
1044// @(negedge `SPC0.l2clk);
1045// if (!`SPC0.spu_tlu_cwq_busy &&
1046// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1047// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)) spuActive[1] = 0;
1048 end
1049 end
1050
1051 join
1052
1053
1054 if (flushCount1 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 watchStep end!");
1055 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep1: TID 1 repeated watchStep end!");
1056
1057 stepActive[1] = 0;
1058
1059end
1060endtask
1061
1062
1063
1064// check that thread does DO mode correctly
1065task watchDOsteps1;
1066begin
1067
1068 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1: TID 1 watchDOsteps starting!");
1069
1070 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps1;
1071
1072 // now wait for a thread to start. TCU internal signal.
1073 if (`SPC0.tlu.tlu_core_running_status[1] == 0)
1074 @(posedge `SPC0.tlu.tlu_core_running_status[1]);
1075
1076 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1 TID 1 unparked and running in DO mode!");
1077
1078 // loop on step checking. DO mode is self stepping
1079 while (doMode) begin : watchDOsteps1loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
1080
1081 stepDone[1] = 0;
1082 watchStepFlush[1] = 0;
1083 watchStepMMU[1] = 0;
1084
1085 // are we starting to park in middle of DO mode (or end)?
1086 // wait here until unparked again
1087 if (parkTrans[1]) begin
1088 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1 TID 1 getting parked, will delay");
1089 @(negedge parkTrans[1]);
1090 if (!doMode) disable watchDOsteps1loop; // no longer in DO mode, bail
1091 // wait to be unparked or !doMode
1092 if (parkedState[1]) begin
1093 @(negedge doMode or negedge parkedState[1]);
1094 if (!doMode) disable watchDOsteps1loop; // no longer in DO mode, bail
1095 end
1096 end
1097
1098
1099 // an unparked thread does one instruction to completion before thread starts
1100 // the next instruction.
1101 fork
1102 // timeout fork
1103 begin : FORKDO11
1104 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1105 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps1: DO mode, TID 1 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
1106 end
1107
1108 // look for SPU going active
1109// begin : FORKDO21
1110// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)))
1111// @(negedge `SPC0.l2clk);
1112// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps1: DO mode, TID 1 sees SPU busy!");
1113// spuActive[1] = 1;
1114// end
1115
1116 // watch step
1117 begin
1118 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1: TID 1 calling watchStep1 in DO mode!");
1119 watchStep1; // returns when step is done or flushed
1120 if (watchStepFlush[1])
1121 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 1 in DO mode had flush!");
1122 if (watchStepMMU[1])
1123 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 1 in DO mode had mmu reload!");
1124 // calling flush as a done in DO mode
1125 disable FORKDO11; // TO
1126 //disable FORKDO21; // SPU going active
1127 end
1128
1129 join
1130
1131 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1: TID 1 DO mode watchDOsteps step done!");
1132 stepDone[1] = 1;
1133 flushCount1 = 0;
1134// if (!`SPC0.spu_tlu_cwq_busy &&
1135// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1136// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)) spuActive[1] = 0;
1137
1138 @(negedge `SPC0.l2clk);
1139 end // while
1140
1141 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps1: TID 1 DO mode watchDOsteps task ending!");
1142end
1143endtask
1144
1145
1146
1147
1148////////////////////////// end tid 1 ///////////////////////////////////////
1149
1150
1151//////////////////////////////////////////////////////////////////
1152// THREAD 2
1153//////////////////////////////////////////////////////////////////
1154
1155
1156// got park request. transition into parking. parking check.
1157always @(negedge `SPC0.tlu.tcu_core_running[2]) begin: GOTPARK2
1158 `PR_DEBUG("dbg_chk", `DEBUG, "TID 2 calling parkingCheck");
1159 if (enabled) parkingCheck2();
1160end
1161
1162// got unpark request. transition into running. unparking check.
1163always @(posedge `SPC0.tlu.tcu_core_running[2]) begin: UNPARKCHECK2
1164 if (enabled && !ssMode) begin
1165 `PR_DEBUG("dbg_chk", `DEBUG, "TID 2 calling unparkCheck.");
1166 unparkCheck2();
1167 end
1168end
1169
1170// while parked check
1171always @(posedge parkedState[2] or posedge virtualPark[2]) begin: PARKCHECK2
1172 `PR_DEBUG("dbg_chk", `DEBUG, "TID 2 calling parkedCheck");
1173 if (enabled) parkedCheck2();
1174end
1175
1176// check for unexpected running transition
1177 always @(`SPC0.tlu.tlu_core_running_status[2]) begin: UNEXPECTED2
1178 if (!parkTrans[2] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
1179 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[2]);
1180end
1181
1182
1183
1184////////////// tasks for tid 2 ////////////////////
1185
1186// check the entering into parked state
1187task parkingCheck2;
1188
1189begin
1190
1191
1192 `PR_DEBUG("dbg_chk", `DEBUG, "TID 2 got park request!");
1193
1194 if (parkTrans[2] == 1) begin
1195 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
1196 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
1197 disable parkingCheck2;
1198 end
1199
1200 parkTrans[2] = 1;
1201
1202 // wait before checking signals
1203 repeat (2) @(negedge `SPC0.l2clk);
1204
1205 // need to see at least one assertion of flush
1206 // if (`SPC0.tlu_flush_ifu[2] !== 1)
1207 // @(posedge `SPC0.tlu_flush_ifu[2]); // has glitches
1208 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[2] !== 1)
1209 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[2]);
1210
1211 // need to see all of these go idle
1212 while (`SPC0.pku_quiesce[2] == 0 ||
1213 `SPC0.ftu_ifu_quiesce[2] == 0 ||
1214 `SPC0.lsu_stb_empty[2] == 0)
1215 @(negedge `SPC0.l2clk);
1216
1217// // need to see all of these go idle
1218// while (`SPC0.pku_quiesce[2] == 0 ||
1219// `SPC0.ftu_ifu_quiesce[2] == 0 ||
1220// `SPC0.lsu_stb_empty[2] == 0 ||
1221// `SPC0.tlu.fls0.idl_request == 0)
1222// @(negedge `SPC0.l2clk);
1223
1224 parkedState[2] <= 1;
1225 parkTrans[2] <= 0;
1226 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 2);
1227 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 2 has parked!");
1228
1229end
1230endtask
1231
1232
1233// in parked state.
1234// also called between single steps.
1235task parkedCheck2;
1236reg notified;
1237begin //{
1238
1239 notified = 0;
1240 // loop while not transitioning out of park if not SS mode.
1241 // loop while in SS virtualPark if SS mode.
1242 while ((parkTrans[2] == 0 && ssMode == 0) ||
1243 (virtualPark[2] == 1 && ssMode == 1 &&
1244 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
1245 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 2 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[2],virtualPark[2],`TOP.cpu.tcu_ss_request[0]);
1246
1247 @(negedge `SPC0.l2clk);
1248
1249 // if in SS mode and core_running goes to zero for that thread, the thread
1250 // will self step once and flush in order to change to a parked state
1251 // (core_running_status=0). This looks like an un-asked for step so it
1252 // has to be detected and ignored. Try stalling here during it.
1253 while (`SPC0.tlu.tcu_core_running[2] == 0 &&
1254 `SPC0.tlu.tlu_core_running_status[2] == 1)
1255 @(negedge `SPC0.l2clk);
1256
1257 // watch for instructions sneaking in
1258 // dec_inst_valid_m[1:0], one bit per group
1259 if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 2 && `SPC0.tlu.tlu_retry[0] == 1)
1260 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 had tlu_trap_pc_0_valid activity while parked/between steps!");
1261
1262 if (`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 2)
1263 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 had dec_inst_valid_m activity while parked/between steps!");
1264
1265
1266 end //} while
1267
1268 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 2 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[2],virtualPark[2],`TOP.cpu.tcu_ss_request[0]);
1269
1270end //}
1271endtask
1272
1273
1274// leaving parked state
1275task unparkCheck2;
1276integer count;
1277begin
1278
1279 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 2 got unpark request!");
1280
1281 if (parkTrans[2] == 1) begin
1282 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
1283 disable unparkCheck2;
1284 end
1285
1286 parkTrans[2] = 1;
1287
1288 // must see `SPC0.tlu.core_running_status[2] w/in count clocks
1289 count2 = 0;
1290
1291 while (`SPC0.tlu.tlu_core_running_status[2] == 0) begin
1292 @(negedge `SPC0.l2clk);
1293 if (count2 > parkWait) begin // <--- may need to adjust
1294 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count2);
1295 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
1296 end
1297 count2 = count2 + 1;
1298 end
1299
1300 if (!doMode && !ssMode) begin
1301 // need to see re-direct w/in "redirectWait" more clocks
1302 count2 = 0;
1303
1304 // if this is true, the redirect and the assertion of core_running_status
1305 // happened at once so while loop can be skipped.
1306 while (! (`SPC0.tlu_trap_pc_0_valid &&
1307 `SPC0.tlu_trap_0_tid[1:0] == 2)) begin
1308 @(negedge `SPC0.l2clk);
1309 if (count2 > redirectWait) begin // <--- may need to adjust
1310 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 2 did not redirect within %d clocks after core_running_status assert!", redirectWait);
1311 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
1312 end
1313 count2 = count2 + 1;
1314 end
1315 end
1316
1317 parkedState[2] <= 0;
1318 parkTrans[2] <= 0;
1319 count2 <= 0;
1320
1321end
1322endtask
1323
1324
1325// watch this tid step correctly. Should step 1 instruction
1326// and then "virtual park".
1327// for SS and DO modes.
1328task watchStep2;
1329begin
1330
1331 watchStepFlush[2] = 0; // set if we got a flush
1332 watchStepMMU[2] = 0; // set if we got a mmu reload
1333 stepDone[2] = 0;
1334 stepActive[2] = 1;
1335
1336 if (flushCount2) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount2,redirectCount2);
1337
1338
1339 fork
1340 // timeout fork
1341 begin : FORK10_2
1342 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1343 `PR_ERROR ("dbg_chk", `ERROR, "watchStep2: TID 2 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
1344 end
1345
1346// // look for SPU going active
1347// begin : FORK11_2
1348// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)))
1349// @(negedge `SPC0.l2clk);
1350// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 see SPU active!");
1351// spuActive[2] = 1;
1352// end
1353
1354 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
1355 // this task gets called w/o knowing in advance if there will be one more
1356 // assertion of tlu_trap_pc_0/1_valid or not.
1357 begin : FORK8_2
1358 if (ssMode) begin
1359 @(posedge `SPC0.spc_ss_complete);
1360 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount2, redirectCount2);
1361 stepDone[2] = 1;
1362 stepActive[2] = 0;
1363 disable watchStep2; // return
1364 end
1365 end
1366
1367 // valid PC / retry
1368 begin : FORK9_2
1369 // start step. tid wakes up/redirects and does "one instruction"
1370 while (!(`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 2 && `SPC0.tlu.tlu_retry[0] == 1)) begin
1371 // might see `SPC0.tlu.mmu_reload_done[2] here if previous
1372 // redirect was due to a MMU miss. If so, decrement flush count because
1373 // the previous flush on prev pc_valid "does not count" and there can be
1374 // any number of them w/ no way to predict quantity.
1375 if (`SPC0.tlu.mmu_reload_done[2] && ssMode) begin
1376 flushCount2 = flushCount2-1;
1377 redirectCount2 = redirectCount2-1;
1378 watchStepMMU[2] = 1;
1379 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount2, redirectCount2);
1380 end
1381 @(negedge `SPC0.l2clk);
1382 end
1383
1384 redirectCount2 = redirectCount2+1;
1385 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount2);
1386 disable FORK8_2; // kill sync on spc_ss_complete
1387
1388 @(negedge `SPC0.pku_quiesce[2]);
1389 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
1390
1391 while (!(`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 2)) @(negedge `SPC0.l2clk);
1392
1393 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 valid step starting!");
1394 disable FORK10_2; // kill timeout
1395 //disable FORK11_2;
1396 // if (!`SPC0.spu_tlu_cwq_busy &&
1397// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1398// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)) spuActive[2] = 0;
1399 end
1400 join
1401
1402
1403
1404 // finish step
1405 fork
1406 // timeout fork
1407 begin : FORK4_2
1408 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1409
1410 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
1411 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
1412 // since it can assert after the step has started.
1413 `PR_ERROR ("dbg_chk", `ERROR, "watchStep2: TID 2 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
1414 end
1415
1416 // look for SPU going active
1417// begin : FORK12_2
1418// while (!(`SPC0.spu_tlu_cwq_busy ||
1419// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
1420// @(negedge `SPC0.l2clk);
1421// spuActive[2] = 1;
1422// end
1423
1424
1425 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
1426 // and end this task if seen. tlu_flush_ifu assertion always means
1427 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
1428 begin : FORK6_2
1429 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
1430 while (`SPC0.tlu_flush_ifu[2] == 0)
1431 @(negedge `SPC0.l2clk);
1432
1433// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
1434// if (`SPC0.tlu.fls0.ptrap_flush[2] == 1) begin
1435// `PR_ERROR ("dbg_chk", `ERROR, "watchStep2: TID 2 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
1436// end
1437//
1438
1439 if ((ssMode && `SPC0.tlu.fls0.ptrap_flush[2] == 0) || doMode) begin
1440 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 have tlu_flush_ifu (flushCount=%0d)!",flushCount2);
1441 watchStepFlush[2] = 1;
1442 flushCount2 = flushCount2+1;
1443 stepActive[2] = 0;
1444 disable watchStep2; // return
1445 end
1446 end
1447
1448
1449 // are we done fork, DO mode quiesce
1450 begin : FORK5_2
1451 if (doMode) begin
1452 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 watching for quiesce (only matters fo DO mode)!");
1453 while (`SPC0.pku_quiesce[2] == 0 ||
1454 `SPC0.ftu_ifu_quiesce[2] == 0 ||
1455 `SPC0.lsu_stb_empty[2] == 0) @(negedge `SPC0.l2clk);
1456
1457 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 have quiesce (only matters for DO mode)!");
1458 if (doMode) begin
1459 disable FORK4_2; // TO
1460 disable FORK6_2; // flush check
1461 //disable FORK12_2;
1462// @(negedge `SPC0.l2clk);
1463// if (!`SPC0.spu_tlu_cwq_busy &&
1464// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1465// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)) spuActive[2] = 0;
1466 end
1467 end
1468 end
1469
1470
1471 // are we done fork, SS mode only
1472 begin : FORK7_2
1473 // wait for SS complete
1474 if (ssMode) begin
1475 @(posedge `SPC0.spc_ss_complete);
1476 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount2,redirectCount2);
1477 stepDone[2] = 1;
1478
1479// while (ssMode && !`SPC0.spc_ss_complete) begin
1480// // detect a second inst valid w/o a flush between
1481// if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 2 && `SPC0.tlu.tlu_retry[0] == 1) begin
1482// // delay error so flush thread can kill this in the "got flush" case
1483// @(negedge `SPC0.l2clk);
1484// `PR_ERROR ("dbg_chk", `ERROR, "watchStep2: TID 2 had another inst start before SS done was asserted!");
1485// end
1486// @(negedge `SPC0.l2clk);
1487// end // while
1488
1489 if (`SPC0.pku_quiesce[2] == 0 ||
1490 `SPC0.ftu_ifu_quiesce[2] == 0 ||
1491 `SPC0.lsu_stb_empty[2] == 0)
1492 `PR_ERROR ("dbg_chk", `ERROR, "watchStep2: TID 2 was not quiesce at ss_complete assertion!");
1493
1494 disable FORK4_2; // TO
1495 disable FORK6_2; // flush check
1496 //disable FORK12_2;
1497// @(negedge `SPC0.l2clk);
1498// if (!`SPC0.spu_tlu_cwq_busy &&
1499// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1500// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)) spuActive[2] = 0;
1501 end
1502 end
1503
1504 join
1505
1506
1507 if (flushCount2 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 watchStep end!");
1508 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep2: TID 2 repeated watchStep end!");
1509
1510 stepActive[2] = 0;
1511
1512end
1513endtask
1514
1515
1516
1517// check that thread does DO mode correctly
1518task watchDOsteps2;
1519begin
1520
1521 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2: TID 2 watchDOsteps starting!");
1522
1523 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps2;
1524
1525 // now wait for a thread to start. TCU internal signal.
1526 if (`SPC0.tlu.tlu_core_running_status[2] == 0)
1527 @(posedge `SPC0.tlu.tlu_core_running_status[2]);
1528
1529 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2 TID 2 unparked and running in DO mode!");
1530
1531 // loop on step checking. DO mode is self stepping
1532 while (doMode) begin : watchDOsteps2loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
1533
1534 stepDone[2] = 0;
1535 watchStepFlush[2] = 0;
1536 watchStepMMU[2] = 0;
1537
1538 // are we starting to park in middle of DO mode (or end)?
1539 // wait here until unparked again
1540 if (parkTrans[2]) begin
1541 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2 TID 2 getting parked, will delay");
1542 @(negedge parkTrans[2]);
1543 if (!doMode) disable watchDOsteps2loop; // no longer in DO mode, bail
1544 // wait to be unparked or !doMode
1545 if (parkedState[2]) begin
1546 @(negedge doMode or negedge parkedState[2]);
1547 if (!doMode) disable watchDOsteps2loop; // no longer in DO mode, bail
1548 end
1549 end
1550
1551
1552 // an unparked thread does one instruction to completion before thread starts
1553 // the next instruction.
1554 fork
1555 // timeout fork
1556 begin : FORKDO12
1557 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1558 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps2: DO mode, TID 2 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
1559 end
1560
1561 // look for SPU going active
1562// begin : FORKDO22
1563// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)))
1564// @(negedge `SPC0.l2clk);
1565// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps2: DO mode, TID 2 sees SPU busy!");
1566// spuActive[2] = 1;
1567// end
1568
1569 // watch step
1570 begin
1571 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2: TID 2 calling watchStep2 in DO mode!");
1572 watchStep2; // returns when step is done or flushed
1573 if (watchStepFlush[2])
1574 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 2 in DO mode had flush!");
1575 if (watchStepMMU[2])
1576 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 2 in DO mode had mmu reload!");
1577 // calling flush as a done in DO mode
1578 disable FORKDO12; // TO
1579 //disable FORKDO22; // SPU going active
1580 end
1581
1582 join
1583
1584 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2: TID 2 DO mode watchDOsteps step done!");
1585 stepDone[2] = 1;
1586 flushCount2 = 0;
1587// if (!`SPC0.spu_tlu_cwq_busy &&
1588// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1589// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)) spuActive[2] = 0;
1590
1591 @(negedge `SPC0.l2clk);
1592 end // while
1593
1594 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps2: TID 2 DO mode watchDOsteps task ending!");
1595end
1596endtask
1597
1598
1599
1600
1601////////////////////////// end tid 2 ///////////////////////////////////////
1602
1603
1604//////////////////////////////////////////////////////////////////
1605// THREAD 3
1606//////////////////////////////////////////////////////////////////
1607
1608
1609// got park request. transition into parking. parking check.
1610always @(negedge `SPC0.tlu.tcu_core_running[3]) begin: GOTPARK3
1611 `PR_DEBUG("dbg_chk", `DEBUG, "TID 3 calling parkingCheck");
1612 if (enabled) parkingCheck3();
1613end
1614
1615// got unpark request. transition into running. unparking check.
1616always @(posedge `SPC0.tlu.tcu_core_running[3]) begin: UNPARKCHECK3
1617 if (enabled && !ssMode) begin
1618 `PR_DEBUG("dbg_chk", `DEBUG, "TID 3 calling unparkCheck.");
1619 unparkCheck3();
1620 end
1621end
1622
1623// while parked check
1624always @(posedge parkedState[3] or posedge virtualPark[3]) begin: PARKCHECK3
1625 `PR_DEBUG("dbg_chk", `DEBUG, "TID 3 calling parkedCheck");
1626 if (enabled) parkedCheck3();
1627end
1628
1629// check for unexpected running transition
1630 always @(`SPC0.tlu.tlu_core_running_status[3]) begin: UNEXPECTED3
1631 if (!parkTrans[3] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
1632 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[3]);
1633end
1634
1635
1636
1637////////////// tasks for tid 3 ////////////////////
1638
1639// check the entering into parked state
1640task parkingCheck3;
1641
1642begin
1643
1644
1645 `PR_DEBUG("dbg_chk", `DEBUG, "TID 3 got park request!");
1646
1647 if (parkTrans[3] == 1) begin
1648 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
1649 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
1650 disable parkingCheck3;
1651 end
1652
1653 parkTrans[3] = 1;
1654
1655 // wait before checking signals
1656 repeat (2) @(negedge `SPC0.l2clk);
1657
1658 // need to see at least one assertion of flush
1659 // if (`SPC0.tlu_flush_ifu[3] !== 1)
1660 // @(posedge `SPC0.tlu_flush_ifu[3]); // has glitches
1661 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[3] !== 1)
1662 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[3]);
1663
1664 // need to see all of these go idle
1665 while (`SPC0.pku_quiesce[3] == 0 ||
1666 `SPC0.ftu_ifu_quiesce[3] == 0 ||
1667 `SPC0.lsu_stb_empty[3] == 0)
1668 @(negedge `SPC0.l2clk);
1669
1670// // need to see all of these go idle
1671// while (`SPC0.pku_quiesce[3] == 0 ||
1672// `SPC0.ftu_ifu_quiesce[3] == 0 ||
1673// `SPC0.lsu_stb_empty[3] == 0 ||
1674// `SPC0.tlu.fls0.idl_request == 0)
1675// @(negedge `SPC0.l2clk);
1676
1677 parkedState[3] <= 1;
1678 parkTrans[3] <= 0;
1679 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 3);
1680 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 3 has parked!");
1681
1682end
1683endtask
1684
1685
1686// in parked state.
1687// also called between single steps.
1688task parkedCheck3;
1689reg notified;
1690begin //{
1691
1692 notified = 0;
1693 // loop while not transitioning out of park if not SS mode.
1694 // loop while in SS virtualPark if SS mode.
1695 while ((parkTrans[3] == 0 && ssMode == 0) ||
1696 (virtualPark[3] == 1 && ssMode == 1 &&
1697 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
1698 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 3 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[3],virtualPark[3],`TOP.cpu.tcu_ss_request[0]);
1699
1700 @(negedge `SPC0.l2clk);
1701
1702 // if in SS mode and core_running goes to zero for that thread, the thread
1703 // will self step once and flush in order to change to a parked state
1704 // (core_running_status=0). This looks like an un-asked for step so it
1705 // has to be detected and ignored. Try stalling here during it.
1706 while (`SPC0.tlu.tcu_core_running[3] == 0 &&
1707 `SPC0.tlu.tlu_core_running_status[3] == 1)
1708 @(negedge `SPC0.l2clk);
1709
1710 // watch for instructions sneaking in
1711 // dec_inst_valid_m[1:0], one bit per group
1712 if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 3 && `SPC0.tlu.tlu_retry[0] == 1)
1713 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 had tlu_trap_pc_0_valid activity while parked/between steps!");
1714
1715 if (`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 3)
1716 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 had dec_inst_valid_m activity while parked/between steps!");
1717
1718
1719 end //} while
1720
1721 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 3 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[3],virtualPark[3],`TOP.cpu.tcu_ss_request[0]);
1722
1723end //}
1724endtask
1725
1726
1727// leaving parked state
1728task unparkCheck3;
1729integer count;
1730begin
1731
1732 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 3 got unpark request!");
1733
1734 if (parkTrans[3] == 1) begin
1735 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
1736 disable unparkCheck3;
1737 end
1738
1739 parkTrans[3] = 1;
1740
1741 // must see `SPC0.tlu.core_running_status[3] w/in count clocks
1742 count3 = 0;
1743
1744 while (`SPC0.tlu.tlu_core_running_status[3] == 0) begin
1745 @(negedge `SPC0.l2clk);
1746 if (count3 > parkWait) begin // <--- may need to adjust
1747 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count3);
1748 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
1749 end
1750 count3 = count3 + 1;
1751 end
1752
1753 if (!doMode && !ssMode) begin
1754 // need to see re-direct w/in "redirectWait" more clocks
1755 count3 = 0;
1756
1757 // if this is true, the redirect and the assertion of core_running_status
1758 // happened at once so while loop can be skipped.
1759 while (! (`SPC0.tlu_trap_pc_0_valid &&
1760 `SPC0.tlu_trap_0_tid[1:0] == 3)) begin
1761 @(negedge `SPC0.l2clk);
1762 if (count3 > redirectWait) begin // <--- may need to adjust
1763 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 3 did not redirect within %d clocks after core_running_status assert!", redirectWait);
1764 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
1765 end
1766 count3 = count3 + 1;
1767 end
1768 end
1769
1770 parkedState[3] <= 0;
1771 parkTrans[3] <= 0;
1772 count3 <= 0;
1773
1774end
1775endtask
1776
1777
1778// watch this tid step correctly. Should step 1 instruction
1779// and then "virtual park".
1780// for SS and DO modes.
1781task watchStep3;
1782begin
1783
1784 watchStepFlush[3] = 0; // set if we got a flush
1785 watchStepMMU[3] = 0; // set if we got a mmu reload
1786 stepDone[3] = 0;
1787 stepActive[3] = 1;
1788
1789 if (flushCount3) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount3,redirectCount3);
1790
1791
1792 fork
1793 // timeout fork
1794 begin : FORK10_3
1795 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1796 `PR_ERROR ("dbg_chk", `ERROR, "watchStep3: TID 3 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
1797 end
1798
1799// // look for SPU going active
1800// begin : FORK11_3
1801// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)))
1802// @(negedge `SPC0.l2clk);
1803// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 see SPU active!");
1804// spuActive[3] = 1;
1805// end
1806
1807 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
1808 // this task gets called w/o knowing in advance if there will be one more
1809 // assertion of tlu_trap_pc_0/1_valid or not.
1810 begin : FORK8_3
1811 if (ssMode) begin
1812 @(posedge `SPC0.spc_ss_complete);
1813 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount3, redirectCount3);
1814 stepDone[3] = 1;
1815 stepActive[3] = 0;
1816 disable watchStep3; // return
1817 end
1818 end
1819
1820 // valid PC / retry
1821 begin : FORK9_3
1822 // start step. tid wakes up/redirects and does "one instruction"
1823 while (!(`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 3 && `SPC0.tlu.tlu_retry[0] == 1)) begin
1824 // might see `SPC0.tlu.mmu_reload_done[3] here if previous
1825 // redirect was due to a MMU miss. If so, decrement flush count because
1826 // the previous flush on prev pc_valid "does not count" and there can be
1827 // any number of them w/ no way to predict quantity.
1828 if (`SPC0.tlu.mmu_reload_done[3] && ssMode) begin
1829 flushCount3 = flushCount3-1;
1830 redirectCount3 = redirectCount3-1;
1831 watchStepMMU[3] = 1;
1832 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount3, redirectCount3);
1833 end
1834 @(negedge `SPC0.l2clk);
1835 end
1836
1837 redirectCount3 = redirectCount3+1;
1838 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount3);
1839 disable FORK8_3; // kill sync on spc_ss_complete
1840
1841 @(negedge `SPC0.pku_quiesce[3]);
1842 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
1843
1844 while (!(`SPC0.dec_inst_valid_m[0] == 1 && `SPC0.dec_tid0_m[1:0] == 3)) @(negedge `SPC0.l2clk);
1845
1846 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 valid step starting!");
1847 disable FORK10_3; // kill timeout
1848 //disable FORK11_3;
1849 // if (!`SPC0.spu_tlu_cwq_busy &&
1850// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1851// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)) spuActive[3] = 0;
1852 end
1853 join
1854
1855
1856
1857 // finish step
1858 fork
1859 // timeout fork
1860 begin : FORK4_3
1861 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
1862
1863 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
1864 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
1865 // since it can assert after the step has started.
1866 `PR_ERROR ("dbg_chk", `ERROR, "watchStep3: TID 3 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
1867 end
1868
1869 // look for SPU going active
1870// begin : FORK12_3
1871// while (!(`SPC0.spu_tlu_cwq_busy ||
1872// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
1873// @(negedge `SPC0.l2clk);
1874// spuActive[3] = 1;
1875// end
1876
1877
1878 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
1879 // and end this task if seen. tlu_flush_ifu assertion always means
1880 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
1881 begin : FORK6_3
1882 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
1883 while (`SPC0.tlu_flush_ifu[3] == 0)
1884 @(negedge `SPC0.l2clk);
1885
1886// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
1887// if (`SPC0.tlu.fls0.ptrap_flush[3] == 1) begin
1888// `PR_ERROR ("dbg_chk", `ERROR, "watchStep3: TID 3 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
1889// end
1890//
1891
1892 if ((ssMode && `SPC0.tlu.fls0.ptrap_flush[3] == 0) || doMode) begin
1893 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 have tlu_flush_ifu (flushCount=%0d)!",flushCount3);
1894 watchStepFlush[3] = 1;
1895 flushCount3 = flushCount3+1;
1896 stepActive[3] = 0;
1897 disable watchStep3; // return
1898 end
1899 end
1900
1901
1902 // are we done fork, DO mode quiesce
1903 begin : FORK5_3
1904 if (doMode) begin
1905 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 watching for quiesce (only matters fo DO mode)!");
1906 while (`SPC0.pku_quiesce[3] == 0 ||
1907 `SPC0.ftu_ifu_quiesce[3] == 0 ||
1908 `SPC0.lsu_stb_empty[3] == 0) @(negedge `SPC0.l2clk);
1909
1910 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 have quiesce (only matters for DO mode)!");
1911 if (doMode) begin
1912 disable FORK4_3; // TO
1913 disable FORK6_3; // flush check
1914 //disable FORK12_3;
1915// @(negedge `SPC0.l2clk);
1916// if (!`SPC0.spu_tlu_cwq_busy &&
1917// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1918// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)) spuActive[3] = 0;
1919 end
1920 end
1921 end
1922
1923
1924 // are we done fork, SS mode only
1925 begin : FORK7_3
1926 // wait for SS complete
1927 if (ssMode) begin
1928 @(posedge `SPC0.spc_ss_complete);
1929 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount3,redirectCount3);
1930 stepDone[3] = 1;
1931
1932// while (ssMode && !`SPC0.spc_ss_complete) begin
1933// // detect a second inst valid w/o a flush between
1934// if (`SPC0.tlu_trap_pc_0_valid && `SPC0.tlu_trap_0_tid[1:0] == 3 && `SPC0.tlu.tlu_retry[0] == 1) begin
1935// // delay error so flush thread can kill this in the "got flush" case
1936// @(negedge `SPC0.l2clk);
1937// `PR_ERROR ("dbg_chk", `ERROR, "watchStep3: TID 3 had another inst start before SS done was asserted!");
1938// end
1939// @(negedge `SPC0.l2clk);
1940// end // while
1941
1942 if (`SPC0.pku_quiesce[3] == 0 ||
1943 `SPC0.ftu_ifu_quiesce[3] == 0 ||
1944 `SPC0.lsu_stb_empty[3] == 0)
1945 `PR_ERROR ("dbg_chk", `ERROR, "watchStep3: TID 3 was not quiesce at ss_complete assertion!");
1946
1947 disable FORK4_3; // TO
1948 disable FORK6_3; // flush check
1949 //disable FORK12_3;
1950// @(negedge `SPC0.l2clk);
1951// if (!`SPC0.spu_tlu_cwq_busy &&
1952// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
1953// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)) spuActive[3] = 0;
1954 end
1955 end
1956
1957 join
1958
1959
1960 if (flushCount3 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 watchStep end!");
1961 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep3: TID 3 repeated watchStep end!");
1962
1963 stepActive[3] = 0;
1964
1965end
1966endtask
1967
1968
1969
1970// check that thread does DO mode correctly
1971task watchDOsteps3;
1972begin
1973
1974 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3: TID 3 watchDOsteps starting!");
1975
1976 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps3;
1977
1978 // now wait for a thread to start. TCU internal signal.
1979 if (`SPC0.tlu.tlu_core_running_status[3] == 0)
1980 @(posedge `SPC0.tlu.tlu_core_running_status[3]);
1981
1982 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3 TID 3 unparked and running in DO mode!");
1983
1984 // loop on step checking. DO mode is self stepping
1985 while (doMode) begin : watchDOsteps3loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
1986
1987 stepDone[3] = 0;
1988 watchStepFlush[3] = 0;
1989 watchStepMMU[3] = 0;
1990
1991 // are we starting to park in middle of DO mode (or end)?
1992 // wait here until unparked again
1993 if (parkTrans[3]) begin
1994 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3 TID 3 getting parked, will delay");
1995 @(negedge parkTrans[3]);
1996 if (!doMode) disable watchDOsteps3loop; // no longer in DO mode, bail
1997 // wait to be unparked or !doMode
1998 if (parkedState[3]) begin
1999 @(negedge doMode or negedge parkedState[3]);
2000 if (!doMode) disable watchDOsteps3loop; // no longer in DO mode, bail
2001 end
2002 end
2003
2004
2005 // an unparked thread does one instruction to completion before thread starts
2006 // the next instruction.
2007 fork
2008 // timeout fork
2009 begin : FORKDO13
2010 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2011 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps3: DO mode, TID 3 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
2012 end
2013
2014 // look for SPU going active
2015// begin : FORKDO23
2016// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)))
2017// @(negedge `SPC0.l2clk);
2018// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps3: DO mode, TID 3 sees SPU busy!");
2019// spuActive[3] = 1;
2020// end
2021
2022 // watch step
2023 begin
2024 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3: TID 3 calling watchStep3 in DO mode!");
2025 watchStep3; // returns when step is done or flushed
2026 if (watchStepFlush[3])
2027 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 3 in DO mode had flush!");
2028 if (watchStepMMU[3])
2029 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 3 in DO mode had mmu reload!");
2030 // calling flush as a done in DO mode
2031 disable FORKDO13; // TO
2032 //disable FORKDO23; // SPU going active
2033 end
2034
2035 join
2036
2037 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3: TID 3 DO mode watchDOsteps step done!");
2038 stepDone[3] = 1;
2039 flushCount3 = 0;
2040// if (!`SPC0.spu_tlu_cwq_busy &&
2041// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2042// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)) spuActive[3] = 0;
2043
2044 @(negedge `SPC0.l2clk);
2045 end // while
2046
2047 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps3: TID 3 DO mode watchDOsteps task ending!");
2048end
2049endtask
2050
2051
2052
2053
2054////////////////////////// end tid 3 ///////////////////////////////////////
2055
2056
2057//////////////////////////////////////////////////////////////////
2058// THREAD 4
2059//////////////////////////////////////////////////////////////////
2060
2061
2062// got park request. transition into parking. parking check.
2063always @(negedge `SPC0.tlu.tcu_core_running[4]) begin: GOTPARK4
2064 `PR_DEBUG("dbg_chk", `DEBUG, "TID 4 calling parkingCheck");
2065 if (enabled) parkingCheck4();
2066end
2067
2068// got unpark request. transition into running. unparking check.
2069always @(posedge `SPC0.tlu.tcu_core_running[4]) begin: UNPARKCHECK4
2070 if (enabled && !ssMode) begin
2071 `PR_DEBUG("dbg_chk", `DEBUG, "TID 4 calling unparkCheck.");
2072 unparkCheck4();
2073 end
2074end
2075
2076// while parked check
2077always @(posedge parkedState[4] or posedge virtualPark[4]) begin: PARKCHECK4
2078 `PR_DEBUG("dbg_chk", `DEBUG, "TID 4 calling parkedCheck");
2079 if (enabled) parkedCheck4();
2080end
2081
2082// check for unexpected running transition
2083 always @(`SPC0.tlu.tlu_core_running_status[4]) begin: UNEXPECTED4
2084 if (!parkTrans[4] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
2085 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[4]);
2086end
2087
2088
2089
2090////////////// tasks for tid 4 ////////////////////
2091
2092// check the entering into parked state
2093task parkingCheck4;
2094
2095begin
2096
2097
2098 `PR_DEBUG("dbg_chk", `DEBUG, "TID 4 got park request!");
2099
2100 if (parkTrans[4] == 1) begin
2101 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
2102 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
2103 disable parkingCheck4;
2104 end
2105
2106 parkTrans[4] = 1;
2107
2108 // wait before checking signals
2109 repeat (2) @(negedge `SPC0.l2clk);
2110
2111 // need to see at least one assertion of flush
2112 // if (`SPC0.tlu_flush_ifu[4] !== 1)
2113 // @(posedge `SPC0.tlu_flush_ifu[4]); // has glitches
2114 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[4] !== 1)
2115 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[4]);
2116
2117 // need to see all of these go idle
2118 while (`SPC0.pku_quiesce[4] == 0 ||
2119 `SPC0.ftu_ifu_quiesce[4] == 0 ||
2120 `SPC0.lsu_stb_empty[4] == 0)
2121 @(negedge `SPC0.l2clk);
2122
2123// // need to see all of these go idle
2124// while (`SPC0.pku_quiesce[4] == 0 ||
2125// `SPC0.ftu_ifu_quiesce[4] == 0 ||
2126// `SPC0.lsu_stb_empty[4] == 0 ||
2127// `SPC0.tlu.fls1.idl_request == 0)
2128// @(negedge `SPC0.l2clk);
2129
2130 parkedState[4] <= 1;
2131 parkTrans[4] <= 0;
2132 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 4);
2133 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 4 has parked!");
2134
2135end
2136endtask
2137
2138
2139// in parked state.
2140// also called between single steps.
2141task parkedCheck4;
2142reg notified;
2143begin //{
2144
2145 notified = 0;
2146 // loop while not transitioning out of park if not SS mode.
2147 // loop while in SS virtualPark if SS mode.
2148 while ((parkTrans[4] == 0 && ssMode == 0) ||
2149 (virtualPark[4] == 1 && ssMode == 1 &&
2150 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
2151 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 4 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[4],virtualPark[4],`TOP.cpu.tcu_ss_request[0]);
2152
2153 @(negedge `SPC0.l2clk);
2154
2155 // if in SS mode and core_running goes to zero for that thread, the thread
2156 // will self step once and flush in order to change to a parked state
2157 // (core_running_status=0). This looks like an un-asked for step so it
2158 // has to be detected and ignored. Try stalling here during it.
2159 while (`SPC0.tlu.tcu_core_running[4] == 0 &&
2160 `SPC0.tlu.tlu_core_running_status[4] == 1)
2161 @(negedge `SPC0.l2clk);
2162
2163 // watch for instructions sneaking in
2164 // dec_inst_valid_m[1:0], one bit per group
2165 if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 4 && `SPC0.tlu.tlu_retry[1] == 1)
2166 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 had tlu_trap_pc_1_valid activity while parked/between steps!");
2167
2168 if (`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 0)
2169 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 had dec_inst_valid_m activity while parked/between steps!");
2170
2171
2172 end //} while
2173
2174 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 4 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[4],virtualPark[4],`TOP.cpu.tcu_ss_request[0]);
2175
2176end //}
2177endtask
2178
2179
2180// leaving parked state
2181task unparkCheck4;
2182integer count;
2183begin
2184
2185 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 4 got unpark request!");
2186
2187 if (parkTrans[4] == 1) begin
2188 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
2189 disable unparkCheck4;
2190 end
2191
2192 parkTrans[4] = 1;
2193
2194 // must see `SPC0.tlu.core_running_status[4] w/in count clocks
2195 count4 = 0;
2196
2197 while (`SPC0.tlu.tlu_core_running_status[4] == 0) begin
2198 @(negedge `SPC0.l2clk);
2199 if (count4 > parkWait) begin // <--- may need to adjust
2200 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count4);
2201 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
2202 end
2203 count4 = count4 + 1;
2204 end
2205
2206 if (!doMode && !ssMode) begin
2207 // need to see re-direct w/in "redirectWait" more clocks
2208 count4 = 0;
2209
2210 // if this is true, the redirect and the assertion of core_running_status
2211 // happened at once so while loop can be skipped.
2212 while (! (`SPC0.tlu_trap_pc_1_valid &&
2213 `SPC0.tlu_trap_1_tid[1:0] == 0)) begin
2214 @(negedge `SPC0.l2clk);
2215 if (count4 > redirectWait) begin // <--- may need to adjust
2216 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 4 did not redirect within %d clocks after core_running_status assert!", redirectWait);
2217 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
2218 end
2219 count4 = count4 + 1;
2220 end
2221 end
2222
2223 parkedState[4] <= 0;
2224 parkTrans[4] <= 0;
2225 count4 <= 0;
2226
2227end
2228endtask
2229
2230
2231// watch this tid step correctly. Should step 1 instruction
2232// and then "virtual park".
2233// for SS and DO modes.
2234task watchStep4;
2235begin
2236
2237 watchStepFlush[4] = 0; // set if we got a flush
2238 watchStepMMU[4] = 0; // set if we got a mmu reload
2239 stepDone[4] = 0;
2240 stepActive[4] = 1;
2241
2242 if (flushCount4) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount4,redirectCount4);
2243
2244
2245 fork
2246 // timeout fork
2247 begin : FORK10_4
2248 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2249 `PR_ERROR ("dbg_chk", `ERROR, "watchStep4: TID 4 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
2250 end
2251
2252// // look for SPU going active
2253// begin : FORK11_4
2254// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)))
2255// @(negedge `SPC0.l2clk);
2256// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 see SPU active!");
2257// spuActive[4] = 1;
2258// end
2259
2260 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
2261 // this task gets called w/o knowing in advance if there will be one more
2262 // assertion of tlu_trap_pc_0/1_valid or not.
2263 begin : FORK8_4
2264 if (ssMode) begin
2265 @(posedge `SPC0.spc_ss_complete);
2266 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount4, redirectCount4);
2267 stepDone[4] = 1;
2268 stepActive[4] = 0;
2269 disable watchStep4; // return
2270 end
2271 end
2272
2273 // valid PC / retry
2274 begin : FORK9_4
2275 // start step. tid wakes up/redirects and does "one instruction"
2276 while (!(`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 0 && `SPC0.tlu.tlu_retry[1] == 1)) begin
2277 // might see `SPC0.tlu.mmu_reload_done[4] here if previous
2278 // redirect was due to a MMU miss. If so, decrement flush count because
2279 // the previous flush on prev pc_valid "does not count" and there can be
2280 // any number of them w/ no way to predict quantity.
2281 if (`SPC0.tlu.mmu_reload_done[4] && ssMode) begin
2282 flushCount4 = flushCount4-1;
2283 redirectCount4 = redirectCount4-1;
2284 watchStepMMU[4] = 1;
2285 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount4, redirectCount4);
2286 end
2287 @(negedge `SPC0.l2clk);
2288 end
2289
2290 redirectCount4 = redirectCount4+1;
2291 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount4);
2292 disable FORK8_4; // kill sync on spc_ss_complete
2293
2294 @(negedge `SPC0.pku_quiesce[4]);
2295 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
2296
2297 while (!(`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 0)) @(negedge `SPC0.l2clk);
2298
2299 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 valid step starting!");
2300 disable FORK10_4; // kill timeout
2301 //disable FORK11_4;
2302 // if (!`SPC0.spu_tlu_cwq_busy &&
2303// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2304// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)) spuActive[4] = 0;
2305 end
2306 join
2307
2308
2309
2310 // finish step
2311 fork
2312 // timeout fork
2313 begin : FORK4_4
2314 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2315
2316 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
2317 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
2318 // since it can assert after the step has started.
2319 `PR_ERROR ("dbg_chk", `ERROR, "watchStep4: TID 4 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
2320 end
2321
2322 // look for SPU going active
2323// begin : FORK12_4
2324// while (!(`SPC0.spu_tlu_cwq_busy ||
2325// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
2326// @(negedge `SPC0.l2clk);
2327// spuActive[4] = 1;
2328// end
2329
2330
2331 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
2332 // and end this task if seen. tlu_flush_ifu assertion always means
2333 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
2334 begin : FORK6_4
2335 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
2336 while (`SPC0.tlu_flush_ifu[4] == 0)
2337 @(negedge `SPC0.l2clk);
2338
2339// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
2340// if (`SPC0.tlu.fls1.ptrap_flush[0] == 1) begin
2341// `PR_ERROR ("dbg_chk", `ERROR, "watchStep4: TID 4 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
2342// end
2343//
2344
2345 if ((ssMode && `SPC0.tlu.fls1.ptrap_flush[0] == 0) || doMode) begin
2346 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 have tlu_flush_ifu (flushCount=%0d)!",flushCount4);
2347 watchStepFlush[4] = 1;
2348 flushCount4 = flushCount4+1;
2349 stepActive[4] = 0;
2350 disable watchStep4; // return
2351 end
2352 end
2353
2354
2355 // are we done fork, DO mode quiesce
2356 begin : FORK5_4
2357 if (doMode) begin
2358 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 watching for quiesce (only matters fo DO mode)!");
2359 while (`SPC0.pku_quiesce[4] == 0 ||
2360 `SPC0.ftu_ifu_quiesce[4] == 0 ||
2361 `SPC0.lsu_stb_empty[4] == 0) @(negedge `SPC0.l2clk);
2362
2363 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 have quiesce (only matters for DO mode)!");
2364 if (doMode) begin
2365 disable FORK4_4; // TO
2366 disable FORK6_4; // flush check
2367 //disable FORK12_4;
2368// @(negedge `SPC0.l2clk);
2369// if (!`SPC0.spu_tlu_cwq_busy &&
2370// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2371// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)) spuActive[4] = 0;
2372 end
2373 end
2374 end
2375
2376
2377 // are we done fork, SS mode only
2378 begin : FORK7_4
2379 // wait for SS complete
2380 if (ssMode) begin
2381 @(posedge `SPC0.spc_ss_complete);
2382 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount4,redirectCount4);
2383 stepDone[4] = 1;
2384
2385// while (ssMode && !`SPC0.spc_ss_complete) begin
2386// // detect a second inst valid w/o a flush between
2387// if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 0 && `SPC0.tlu.tlu_retry[1] == 1) begin
2388// // delay error so flush thread can kill this in the "got flush" case
2389// @(negedge `SPC0.l2clk);
2390// `PR_ERROR ("dbg_chk", `ERROR, "watchStep4: TID 4 had another inst start before SS done was asserted!");
2391// end
2392// @(negedge `SPC0.l2clk);
2393// end // while
2394
2395 if (`SPC0.pku_quiesce[4] == 0 ||
2396 `SPC0.ftu_ifu_quiesce[4] == 0 ||
2397 `SPC0.lsu_stb_empty[4] == 0)
2398 `PR_ERROR ("dbg_chk", `ERROR, "watchStep4: TID 4 was not quiesce at ss_complete assertion!");
2399
2400 disable FORK4_4; // TO
2401 disable FORK6_4; // flush check
2402 //disable FORK12_4;
2403// @(negedge `SPC0.l2clk);
2404// if (!`SPC0.spu_tlu_cwq_busy &&
2405// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2406// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)) spuActive[4] = 0;
2407 end
2408 end
2409
2410 join
2411
2412
2413 if (flushCount4 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 watchStep end!");
2414 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep4: TID 4 repeated watchStep end!");
2415
2416 stepActive[4] = 0;
2417
2418end
2419endtask
2420
2421
2422
2423// check that thread does DO mode correctly
2424task watchDOsteps4;
2425begin
2426
2427 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4: TID 4 watchDOsteps starting!");
2428
2429 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps4;
2430
2431 // now wait for a thread to start. TCU internal signal.
2432 if (`SPC0.tlu.tlu_core_running_status[4] == 0)
2433 @(posedge `SPC0.tlu.tlu_core_running_status[4]);
2434
2435 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4 TID 4 unparked and running in DO mode!");
2436
2437 // loop on step checking. DO mode is self stepping
2438 while (doMode) begin : watchDOsteps4loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
2439
2440 stepDone[4] = 0;
2441 watchStepFlush[4] = 0;
2442 watchStepMMU[4] = 0;
2443
2444 // are we starting to park in middle of DO mode (or end)?
2445 // wait here until unparked again
2446 if (parkTrans[4]) begin
2447 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4 TID 4 getting parked, will delay");
2448 @(negedge parkTrans[4]);
2449 if (!doMode) disable watchDOsteps4loop; // no longer in DO mode, bail
2450 // wait to be unparked or !doMode
2451 if (parkedState[4]) begin
2452 @(negedge doMode or negedge parkedState[4]);
2453 if (!doMode) disable watchDOsteps4loop; // no longer in DO mode, bail
2454 end
2455 end
2456
2457
2458 // an unparked thread does one instruction to completion before thread starts
2459 // the next instruction.
2460 fork
2461 // timeout fork
2462 begin : FORKDO14
2463 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2464 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps4: DO mode, TID 4 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
2465 end
2466
2467 // look for SPU going active
2468// begin : FORKDO24
2469// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)))
2470// @(negedge `SPC0.l2clk);
2471// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps4: DO mode, TID 4 sees SPU busy!");
2472// spuActive[4] = 1;
2473// end
2474
2475 // watch step
2476 begin
2477 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4: TID 4 calling watchStep4 in DO mode!");
2478 watchStep4; // returns when step is done or flushed
2479 if (watchStepFlush[4])
2480 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 4 in DO mode had flush!");
2481 if (watchStepMMU[4])
2482 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 4 in DO mode had mmu reload!");
2483 // calling flush as a done in DO mode
2484 disable FORKDO14; // TO
2485 //disable FORKDO24; // SPU going active
2486 end
2487
2488 join
2489
2490 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4: TID 4 DO mode watchDOsteps step done!");
2491 stepDone[4] = 1;
2492 flushCount4 = 0;
2493// if (!`SPC0.spu_tlu_cwq_busy &&
2494// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2495// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)) spuActive[4] = 0;
2496
2497 @(negedge `SPC0.l2clk);
2498 end // while
2499
2500 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps4: TID 4 DO mode watchDOsteps task ending!");
2501end
2502endtask
2503
2504
2505
2506
2507////////////////////////// end tid 4 ///////////////////////////////////////
2508
2509
2510//////////////////////////////////////////////////////////////////
2511// THREAD 5
2512//////////////////////////////////////////////////////////////////
2513
2514
2515// got park request. transition into parking. parking check.
2516always @(negedge `SPC0.tlu.tcu_core_running[5]) begin: GOTPARK5
2517 `PR_DEBUG("dbg_chk", `DEBUG, "TID 5 calling parkingCheck");
2518 if (enabled) parkingCheck5();
2519end
2520
2521// got unpark request. transition into running. unparking check.
2522always @(posedge `SPC0.tlu.tcu_core_running[5]) begin: UNPARKCHECK5
2523 if (enabled && !ssMode) begin
2524 `PR_DEBUG("dbg_chk", `DEBUG, "TID 5 calling unparkCheck.");
2525 unparkCheck5();
2526 end
2527end
2528
2529// while parked check
2530always @(posedge parkedState[5] or posedge virtualPark[5]) begin: PARKCHECK5
2531 `PR_DEBUG("dbg_chk", `DEBUG, "TID 5 calling parkedCheck");
2532 if (enabled) parkedCheck5();
2533end
2534
2535// check for unexpected running transition
2536 always @(`SPC0.tlu.tlu_core_running_status[5]) begin: UNEXPECTED5
2537 if (!parkTrans[5] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
2538 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[5]);
2539end
2540
2541
2542
2543////////////// tasks for tid 5 ////////////////////
2544
2545// check the entering into parked state
2546task parkingCheck5;
2547
2548begin
2549
2550
2551 `PR_DEBUG("dbg_chk", `DEBUG, "TID 5 got park request!");
2552
2553 if (parkTrans[5] == 1) begin
2554 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
2555 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
2556 disable parkingCheck5;
2557 end
2558
2559 parkTrans[5] = 1;
2560
2561 // wait before checking signals
2562 repeat (2) @(negedge `SPC0.l2clk);
2563
2564 // need to see at least one assertion of flush
2565 // if (`SPC0.tlu_flush_ifu[5] !== 1)
2566 // @(posedge `SPC0.tlu_flush_ifu[5]); // has glitches
2567 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[5] !== 1)
2568 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[5]);
2569
2570 // need to see all of these go idle
2571 while (`SPC0.pku_quiesce[5] == 0 ||
2572 `SPC0.ftu_ifu_quiesce[5] == 0 ||
2573 `SPC0.lsu_stb_empty[5] == 0)
2574 @(negedge `SPC0.l2clk);
2575
2576// // need to see all of these go idle
2577// while (`SPC0.pku_quiesce[5] == 0 ||
2578// `SPC0.ftu_ifu_quiesce[5] == 0 ||
2579// `SPC0.lsu_stb_empty[5] == 0 ||
2580// `SPC0.tlu.fls1.idl_request == 0)
2581// @(negedge `SPC0.l2clk);
2582
2583 parkedState[5] <= 1;
2584 parkTrans[5] <= 0;
2585 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 5);
2586 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 5 has parked!");
2587
2588end
2589endtask
2590
2591
2592// in parked state.
2593// also called between single steps.
2594task parkedCheck5;
2595reg notified;
2596begin //{
2597
2598 notified = 0;
2599 // loop while not transitioning out of park if not SS mode.
2600 // loop while in SS virtualPark if SS mode.
2601 while ((parkTrans[5] == 0 && ssMode == 0) ||
2602 (virtualPark[5] == 1 && ssMode == 1 &&
2603 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
2604 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 5 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[5],virtualPark[5],`TOP.cpu.tcu_ss_request[0]);
2605
2606 @(negedge `SPC0.l2clk);
2607
2608 // if in SS mode and core_running goes to zero for that thread, the thread
2609 // will self step once and flush in order to change to a parked state
2610 // (core_running_status=0). This looks like an un-asked for step so it
2611 // has to be detected and ignored. Try stalling here during it.
2612 while (`SPC0.tlu.tcu_core_running[5] == 0 &&
2613 `SPC0.tlu.tlu_core_running_status[5] == 1)
2614 @(negedge `SPC0.l2clk);
2615
2616 // watch for instructions sneaking in
2617 // dec_inst_valid_m[1:0], one bit per group
2618 if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 5 && `SPC0.tlu.tlu_retry[1] == 1)
2619 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 had tlu_trap_pc_1_valid activity while parked/between steps!");
2620
2621 if (`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 1)
2622 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 had dec_inst_valid_m activity while parked/between steps!");
2623
2624
2625 end //} while
2626
2627 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 5 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[5],virtualPark[5],`TOP.cpu.tcu_ss_request[0]);
2628
2629end //}
2630endtask
2631
2632
2633// leaving parked state
2634task unparkCheck5;
2635integer count;
2636begin
2637
2638 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 5 got unpark request!");
2639
2640 if (parkTrans[5] == 1) begin
2641 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
2642 disable unparkCheck5;
2643 end
2644
2645 parkTrans[5] = 1;
2646
2647 // must see `SPC0.tlu.core_running_status[5] w/in count clocks
2648 count5 = 0;
2649
2650 while (`SPC0.tlu.tlu_core_running_status[5] == 0) begin
2651 @(negedge `SPC0.l2clk);
2652 if (count5 > parkWait) begin // <--- may need to adjust
2653 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count5);
2654 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
2655 end
2656 count5 = count5 + 1;
2657 end
2658
2659 if (!doMode && !ssMode) begin
2660 // need to see re-direct w/in "redirectWait" more clocks
2661 count5 = 0;
2662
2663 // if this is true, the redirect and the assertion of core_running_status
2664 // happened at once so while loop can be skipped.
2665 while (! (`SPC0.tlu_trap_pc_1_valid &&
2666 `SPC0.tlu_trap_1_tid[1:0] == 1)) begin
2667 @(negedge `SPC0.l2clk);
2668 if (count5 > redirectWait) begin // <--- may need to adjust
2669 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 5 did not redirect within %d clocks after core_running_status assert!", redirectWait);
2670 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
2671 end
2672 count5 = count5 + 1;
2673 end
2674 end
2675
2676 parkedState[5] <= 0;
2677 parkTrans[5] <= 0;
2678 count5 <= 0;
2679
2680end
2681endtask
2682
2683
2684// watch this tid step correctly. Should step 1 instruction
2685// and then "virtual park".
2686// for SS and DO modes.
2687task watchStep5;
2688begin
2689
2690 watchStepFlush[5] = 0; // set if we got a flush
2691 watchStepMMU[5] = 0; // set if we got a mmu reload
2692 stepDone[5] = 0;
2693 stepActive[5] = 1;
2694
2695 if (flushCount5) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount5,redirectCount5);
2696
2697
2698 fork
2699 // timeout fork
2700 begin : FORK10_5
2701 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2702 `PR_ERROR ("dbg_chk", `ERROR, "watchStep5: TID 5 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
2703 end
2704
2705// // look for SPU going active
2706// begin : FORK11_5
2707// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)))
2708// @(negedge `SPC0.l2clk);
2709// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 see SPU active!");
2710// spuActive[5] = 1;
2711// end
2712
2713 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
2714 // this task gets called w/o knowing in advance if there will be one more
2715 // assertion of tlu_trap_pc_0/1_valid or not.
2716 begin : FORK8_5
2717 if (ssMode) begin
2718 @(posedge `SPC0.spc_ss_complete);
2719 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount5, redirectCount5);
2720 stepDone[5] = 1;
2721 stepActive[5] = 0;
2722 disable watchStep5; // return
2723 end
2724 end
2725
2726 // valid PC / retry
2727 begin : FORK9_5
2728 // start step. tid wakes up/redirects and does "one instruction"
2729 while (!(`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 1 && `SPC0.tlu.tlu_retry[1] == 1)) begin
2730 // might see `SPC0.tlu.mmu_reload_done[5] here if previous
2731 // redirect was due to a MMU miss. If so, decrement flush count because
2732 // the previous flush on prev pc_valid "does not count" and there can be
2733 // any number of them w/ no way to predict quantity.
2734 if (`SPC0.tlu.mmu_reload_done[5] && ssMode) begin
2735 flushCount5 = flushCount5-1;
2736 redirectCount5 = redirectCount5-1;
2737 watchStepMMU[5] = 1;
2738 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount5, redirectCount5);
2739 end
2740 @(negedge `SPC0.l2clk);
2741 end
2742
2743 redirectCount5 = redirectCount5+1;
2744 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount5);
2745 disable FORK8_5; // kill sync on spc_ss_complete
2746
2747 @(negedge `SPC0.pku_quiesce[5]);
2748 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
2749
2750 while (!(`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 1)) @(negedge `SPC0.l2clk);
2751
2752 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 valid step starting!");
2753 disable FORK10_5; // kill timeout
2754 //disable FORK11_5;
2755 // if (!`SPC0.spu_tlu_cwq_busy &&
2756// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2757// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)) spuActive[5] = 0;
2758 end
2759 join
2760
2761
2762
2763 // finish step
2764 fork
2765 // timeout fork
2766 begin : FORK4_5
2767 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2768
2769 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
2770 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
2771 // since it can assert after the step has started.
2772 `PR_ERROR ("dbg_chk", `ERROR, "watchStep5: TID 5 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
2773 end
2774
2775 // look for SPU going active
2776// begin : FORK12_5
2777// while (!(`SPC0.spu_tlu_cwq_busy ||
2778// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
2779// @(negedge `SPC0.l2clk);
2780// spuActive[5] = 1;
2781// end
2782
2783
2784 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
2785 // and end this task if seen. tlu_flush_ifu assertion always means
2786 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
2787 begin : FORK6_5
2788 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
2789 while (`SPC0.tlu_flush_ifu[5] == 0)
2790 @(negedge `SPC0.l2clk);
2791
2792// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
2793// if (`SPC0.tlu.fls1.ptrap_flush[1] == 1) begin
2794// `PR_ERROR ("dbg_chk", `ERROR, "watchStep5: TID 5 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
2795// end
2796//
2797
2798 if ((ssMode && `SPC0.tlu.fls1.ptrap_flush[1] == 0) || doMode) begin
2799 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 have tlu_flush_ifu (flushCount=%0d)!",flushCount5);
2800 watchStepFlush[5] = 1;
2801 flushCount5 = flushCount5+1;
2802 stepActive[5] = 0;
2803 disable watchStep5; // return
2804 end
2805 end
2806
2807
2808 // are we done fork, DO mode quiesce
2809 begin : FORK5_5
2810 if (doMode) begin
2811 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 watching for quiesce (only matters fo DO mode)!");
2812 while (`SPC0.pku_quiesce[5] == 0 ||
2813 `SPC0.ftu_ifu_quiesce[5] == 0 ||
2814 `SPC0.lsu_stb_empty[5] == 0) @(negedge `SPC0.l2clk);
2815
2816 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 have quiesce (only matters for DO mode)!");
2817 if (doMode) begin
2818 disable FORK4_5; // TO
2819 disable FORK6_5; // flush check
2820 //disable FORK12_5;
2821// @(negedge `SPC0.l2clk);
2822// if (!`SPC0.spu_tlu_cwq_busy &&
2823// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2824// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)) spuActive[5] = 0;
2825 end
2826 end
2827 end
2828
2829
2830 // are we done fork, SS mode only
2831 begin : FORK7_5
2832 // wait for SS complete
2833 if (ssMode) begin
2834 @(posedge `SPC0.spc_ss_complete);
2835 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount5,redirectCount5);
2836 stepDone[5] = 1;
2837
2838// while (ssMode && !`SPC0.spc_ss_complete) begin
2839// // detect a second inst valid w/o a flush between
2840// if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 1 && `SPC0.tlu.tlu_retry[1] == 1) begin
2841// // delay error so flush thread can kill this in the "got flush" case
2842// @(negedge `SPC0.l2clk);
2843// `PR_ERROR ("dbg_chk", `ERROR, "watchStep5: TID 5 had another inst start before SS done was asserted!");
2844// end
2845// @(negedge `SPC0.l2clk);
2846// end // while
2847
2848 if (`SPC0.pku_quiesce[5] == 0 ||
2849 `SPC0.ftu_ifu_quiesce[5] == 0 ||
2850 `SPC0.lsu_stb_empty[5] == 0)
2851 `PR_ERROR ("dbg_chk", `ERROR, "watchStep5: TID 5 was not quiesce at ss_complete assertion!");
2852
2853 disable FORK4_5; // TO
2854 disable FORK6_5; // flush check
2855 //disable FORK12_5;
2856// @(negedge `SPC0.l2clk);
2857// if (!`SPC0.spu_tlu_cwq_busy &&
2858// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2859// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)) spuActive[5] = 0;
2860 end
2861 end
2862
2863 join
2864
2865
2866 if (flushCount5 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 watchStep end!");
2867 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep5: TID 5 repeated watchStep end!");
2868
2869 stepActive[5] = 0;
2870
2871end
2872endtask
2873
2874
2875
2876// check that thread does DO mode correctly
2877task watchDOsteps5;
2878begin
2879
2880 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5: TID 5 watchDOsteps starting!");
2881
2882 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps5;
2883
2884 // now wait for a thread to start. TCU internal signal.
2885 if (`SPC0.tlu.tlu_core_running_status[5] == 0)
2886 @(posedge `SPC0.tlu.tlu_core_running_status[5]);
2887
2888 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5 TID 5 unparked and running in DO mode!");
2889
2890 // loop on step checking. DO mode is self stepping
2891 while (doMode) begin : watchDOsteps5loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
2892
2893 stepDone[5] = 0;
2894 watchStepFlush[5] = 0;
2895 watchStepMMU[5] = 0;
2896
2897 // are we starting to park in middle of DO mode (or end)?
2898 // wait here until unparked again
2899 if (parkTrans[5]) begin
2900 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5 TID 5 getting parked, will delay");
2901 @(negedge parkTrans[5]);
2902 if (!doMode) disable watchDOsteps5loop; // no longer in DO mode, bail
2903 // wait to be unparked or !doMode
2904 if (parkedState[5]) begin
2905 @(negedge doMode or negedge parkedState[5]);
2906 if (!doMode) disable watchDOsteps5loop; // no longer in DO mode, bail
2907 end
2908 end
2909
2910
2911 // an unparked thread does one instruction to completion before thread starts
2912 // the next instruction.
2913 fork
2914 // timeout fork
2915 begin : FORKDO15
2916 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
2917 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps5: DO mode, TID 5 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
2918 end
2919
2920 // look for SPU going active
2921// begin : FORKDO25
2922// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)))
2923// @(negedge `SPC0.l2clk);
2924// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps5: DO mode, TID 5 sees SPU busy!");
2925// spuActive[5] = 1;
2926// end
2927
2928 // watch step
2929 begin
2930 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5: TID 5 calling watchStep5 in DO mode!");
2931 watchStep5; // returns when step is done or flushed
2932 if (watchStepFlush[5])
2933 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 5 in DO mode had flush!");
2934 if (watchStepMMU[5])
2935 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 5 in DO mode had mmu reload!");
2936 // calling flush as a done in DO mode
2937 disable FORKDO15; // TO
2938 //disable FORKDO25; // SPU going active
2939 end
2940
2941 join
2942
2943 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5: TID 5 DO mode watchDOsteps step done!");
2944 stepDone[5] = 1;
2945 flushCount5 = 0;
2946// if (!`SPC0.spu_tlu_cwq_busy &&
2947// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
2948// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)) spuActive[5] = 0;
2949
2950 @(negedge `SPC0.l2clk);
2951 end // while
2952
2953 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps5: TID 5 DO mode watchDOsteps task ending!");
2954end
2955endtask
2956
2957
2958
2959
2960////////////////////////// end tid 5 ///////////////////////////////////////
2961
2962
2963//////////////////////////////////////////////////////////////////
2964// THREAD 6
2965//////////////////////////////////////////////////////////////////
2966
2967
2968// got park request. transition into parking. parking check.
2969always @(negedge `SPC0.tlu.tcu_core_running[6]) begin: GOTPARK6
2970 `PR_DEBUG("dbg_chk", `DEBUG, "TID 6 calling parkingCheck");
2971 if (enabled) parkingCheck6();
2972end
2973
2974// got unpark request. transition into running. unparking check.
2975always @(posedge `SPC0.tlu.tcu_core_running[6]) begin: UNPARKCHECK6
2976 if (enabled && !ssMode) begin
2977 `PR_DEBUG("dbg_chk", `DEBUG, "TID 6 calling unparkCheck.");
2978 unparkCheck6();
2979 end
2980end
2981
2982// while parked check
2983always @(posedge parkedState[6] or posedge virtualPark[6]) begin: PARKCHECK6
2984 `PR_DEBUG("dbg_chk", `DEBUG, "TID 6 calling parkedCheck");
2985 if (enabled) parkedCheck6();
2986end
2987
2988// check for unexpected running transition
2989 always @(`SPC0.tlu.tlu_core_running_status[6]) begin: UNEXPECTED6
2990 if (!parkTrans[6] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
2991 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[6]);
2992end
2993
2994
2995
2996////////////// tasks for tid 6 ////////////////////
2997
2998// check the entering into parked state
2999task parkingCheck6;
3000
3001begin
3002
3003
3004 `PR_DEBUG("dbg_chk", `DEBUG, "TID 6 got park request!");
3005
3006 if (parkTrans[6] == 1) begin
3007 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
3008 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
3009 disable parkingCheck6;
3010 end
3011
3012 parkTrans[6] = 1;
3013
3014 // wait before checking signals
3015 repeat (2) @(negedge `SPC0.l2clk);
3016
3017 // need to see at least one assertion of flush
3018 // if (`SPC0.tlu_flush_ifu[6] !== 1)
3019 // @(posedge `SPC0.tlu_flush_ifu[6]); // has glitches
3020 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[6] !== 1)
3021 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[6]);
3022
3023 // need to see all of these go idle
3024 while (`SPC0.pku_quiesce[6] == 0 ||
3025 `SPC0.ftu_ifu_quiesce[6] == 0 ||
3026 `SPC0.lsu_stb_empty[6] == 0)
3027 @(negedge `SPC0.l2clk);
3028
3029// // need to see all of these go idle
3030// while (`SPC0.pku_quiesce[6] == 0 ||
3031// `SPC0.ftu_ifu_quiesce[6] == 0 ||
3032// `SPC0.lsu_stb_empty[6] == 0 ||
3033// `SPC0.tlu.fls1.idl_request == 0)
3034// @(negedge `SPC0.l2clk);
3035
3036 parkedState[6] <= 1;
3037 parkTrans[6] <= 0;
3038 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 6);
3039 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 6 has parked!");
3040
3041end
3042endtask
3043
3044
3045// in parked state.
3046// also called between single steps.
3047task parkedCheck6;
3048reg notified;
3049begin //{
3050
3051 notified = 0;
3052 // loop while not transitioning out of park if not SS mode.
3053 // loop while in SS virtualPark if SS mode.
3054 while ((parkTrans[6] == 0 && ssMode == 0) ||
3055 (virtualPark[6] == 1 && ssMode == 1 &&
3056 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
3057 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 6 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[6],virtualPark[6],`TOP.cpu.tcu_ss_request[0]);
3058
3059 @(negedge `SPC0.l2clk);
3060
3061 // if in SS mode and core_running goes to zero for that thread, the thread
3062 // will self step once and flush in order to change to a parked state
3063 // (core_running_status=0). This looks like an un-asked for step so it
3064 // has to be detected and ignored. Try stalling here during it.
3065 while (`SPC0.tlu.tcu_core_running[6] == 0 &&
3066 `SPC0.tlu.tlu_core_running_status[6] == 1)
3067 @(negedge `SPC0.l2clk);
3068
3069 // watch for instructions sneaking in
3070 // dec_inst_valid_m[1:0], one bit per group
3071 if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 6 && `SPC0.tlu.tlu_retry[1] == 1)
3072 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 had tlu_trap_pc_1_valid activity while parked/between steps!");
3073
3074 if (`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 2)
3075 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 had dec_inst_valid_m activity while parked/between steps!");
3076
3077
3078 end //} while
3079
3080 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 6 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[6],virtualPark[6],`TOP.cpu.tcu_ss_request[0]);
3081
3082end //}
3083endtask
3084
3085
3086// leaving parked state
3087task unparkCheck6;
3088integer count;
3089begin
3090
3091 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 6 got unpark request!");
3092
3093 if (parkTrans[6] == 1) begin
3094 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
3095 disable unparkCheck6;
3096 end
3097
3098 parkTrans[6] = 1;
3099
3100 // must see `SPC0.tlu.core_running_status[6] w/in count clocks
3101 count6 = 0;
3102
3103 while (`SPC0.tlu.tlu_core_running_status[6] == 0) begin
3104 @(negedge `SPC0.l2clk);
3105 if (count6 > parkWait) begin // <--- may need to adjust
3106 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count6);
3107 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
3108 end
3109 count6 = count6 + 1;
3110 end
3111
3112 if (!doMode && !ssMode) begin
3113 // need to see re-direct w/in "redirectWait" more clocks
3114 count6 = 0;
3115
3116 // if this is true, the redirect and the assertion of core_running_status
3117 // happened at once so while loop can be skipped.
3118 while (! (`SPC0.tlu_trap_pc_1_valid &&
3119 `SPC0.tlu_trap_1_tid[1:0] == 2)) begin
3120 @(negedge `SPC0.l2clk);
3121 if (count6 > redirectWait) begin // <--- may need to adjust
3122 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 6 did not redirect within %d clocks after core_running_status assert!", redirectWait);
3123 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
3124 end
3125 count6 = count6 + 1;
3126 end
3127 end
3128
3129 parkedState[6] <= 0;
3130 parkTrans[6] <= 0;
3131 count6 <= 0;
3132
3133end
3134endtask
3135
3136
3137// watch this tid step correctly. Should step 1 instruction
3138// and then "virtual park".
3139// for SS and DO modes.
3140task watchStep6;
3141begin
3142
3143 watchStepFlush[6] = 0; // set if we got a flush
3144 watchStepMMU[6] = 0; // set if we got a mmu reload
3145 stepDone[6] = 0;
3146 stepActive[6] = 1;
3147
3148 if (flushCount6) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount6,redirectCount6);
3149
3150
3151 fork
3152 // timeout fork
3153 begin : FORK10_6
3154 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3155 `PR_ERROR ("dbg_chk", `ERROR, "watchStep6: TID 6 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
3156 end
3157
3158// // look for SPU going active
3159// begin : FORK11_6
3160// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)))
3161// @(negedge `SPC0.l2clk);
3162// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 see SPU active!");
3163// spuActive[6] = 1;
3164// end
3165
3166 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
3167 // this task gets called w/o knowing in advance if there will be one more
3168 // assertion of tlu_trap_pc_0/1_valid or not.
3169 begin : FORK8_6
3170 if (ssMode) begin
3171 @(posedge `SPC0.spc_ss_complete);
3172 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount6, redirectCount6);
3173 stepDone[6] = 1;
3174 stepActive[6] = 0;
3175 disable watchStep6; // return
3176 end
3177 end
3178
3179 // valid PC / retry
3180 begin : FORK9_6
3181 // start step. tid wakes up/redirects and does "one instruction"
3182 while (!(`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 2 && `SPC0.tlu.tlu_retry[1] == 1)) begin
3183 // might see `SPC0.tlu.mmu_reload_done[6] here if previous
3184 // redirect was due to a MMU miss. If so, decrement flush count because
3185 // the previous flush on prev pc_valid "does not count" and there can be
3186 // any number of them w/ no way to predict quantity.
3187 if (`SPC0.tlu.mmu_reload_done[6] && ssMode) begin
3188 flushCount6 = flushCount6-1;
3189 redirectCount6 = redirectCount6-1;
3190 watchStepMMU[6] = 1;
3191 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount6, redirectCount6);
3192 end
3193 @(negedge `SPC0.l2clk);
3194 end
3195
3196 redirectCount6 = redirectCount6+1;
3197 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount6);
3198 disable FORK8_6; // kill sync on spc_ss_complete
3199
3200 @(negedge `SPC0.pku_quiesce[6]);
3201 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
3202
3203 while (!(`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 2)) @(negedge `SPC0.l2clk);
3204
3205 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 valid step starting!");
3206 disable FORK10_6; // kill timeout
3207 //disable FORK11_6;
3208 // if (!`SPC0.spu_tlu_cwq_busy &&
3209// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3210// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)) spuActive[6] = 0;
3211 end
3212 join
3213
3214
3215
3216 // finish step
3217 fork
3218 // timeout fork
3219 begin : FORK4_6
3220 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3221
3222 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
3223 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
3224 // since it can assert after the step has started.
3225 `PR_ERROR ("dbg_chk", `ERROR, "watchStep6: TID 6 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
3226 end
3227
3228 // look for SPU going active
3229// begin : FORK12_6
3230// while (!(`SPC0.spu_tlu_cwq_busy ||
3231// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
3232// @(negedge `SPC0.l2clk);
3233// spuActive[6] = 1;
3234// end
3235
3236
3237 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
3238 // and end this task if seen. tlu_flush_ifu assertion always means
3239 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
3240 begin : FORK6_6
3241 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
3242 while (`SPC0.tlu_flush_ifu[6] == 0)
3243 @(negedge `SPC0.l2clk);
3244
3245// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
3246// if (`SPC0.tlu.fls1.ptrap_flush[2] == 1) begin
3247// `PR_ERROR ("dbg_chk", `ERROR, "watchStep6: TID 6 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
3248// end
3249//
3250
3251 if ((ssMode && `SPC0.tlu.fls1.ptrap_flush[2] == 0) || doMode) begin
3252 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 have tlu_flush_ifu (flushCount=%0d)!",flushCount6);
3253 watchStepFlush[6] = 1;
3254 flushCount6 = flushCount6+1;
3255 stepActive[6] = 0;
3256 disable watchStep6; // return
3257 end
3258 end
3259
3260
3261 // are we done fork, DO mode quiesce
3262 begin : FORK5_6
3263 if (doMode) begin
3264 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 watching for quiesce (only matters fo DO mode)!");
3265 while (`SPC0.pku_quiesce[6] == 0 ||
3266 `SPC0.ftu_ifu_quiesce[6] == 0 ||
3267 `SPC0.lsu_stb_empty[6] == 0) @(negedge `SPC0.l2clk);
3268
3269 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 have quiesce (only matters for DO mode)!");
3270 if (doMode) begin
3271 disable FORK4_6; // TO
3272 disable FORK6_6; // flush check
3273 //disable FORK12_6;
3274// @(negedge `SPC0.l2clk);
3275// if (!`SPC0.spu_tlu_cwq_busy &&
3276// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3277// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)) spuActive[6] = 0;
3278 end
3279 end
3280 end
3281
3282
3283 // are we done fork, SS mode only
3284 begin : FORK7_6
3285 // wait for SS complete
3286 if (ssMode) begin
3287 @(posedge `SPC0.spc_ss_complete);
3288 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount6,redirectCount6);
3289 stepDone[6] = 1;
3290
3291// while (ssMode && !`SPC0.spc_ss_complete) begin
3292// // detect a second inst valid w/o a flush between
3293// if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 2 && `SPC0.tlu.tlu_retry[1] == 1) begin
3294// // delay error so flush thread can kill this in the "got flush" case
3295// @(negedge `SPC0.l2clk);
3296// `PR_ERROR ("dbg_chk", `ERROR, "watchStep6: TID 6 had another inst start before SS done was asserted!");
3297// end
3298// @(negedge `SPC0.l2clk);
3299// end // while
3300
3301 if (`SPC0.pku_quiesce[6] == 0 ||
3302 `SPC0.ftu_ifu_quiesce[6] == 0 ||
3303 `SPC0.lsu_stb_empty[6] == 0)
3304 `PR_ERROR ("dbg_chk", `ERROR, "watchStep6: TID 6 was not quiesce at ss_complete assertion!");
3305
3306 disable FORK4_6; // TO
3307 disable FORK6_6; // flush check
3308 //disable FORK12_6;
3309// @(negedge `SPC0.l2clk);
3310// if (!`SPC0.spu_tlu_cwq_busy &&
3311// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3312// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)) spuActive[6] = 0;
3313 end
3314 end
3315
3316 join
3317
3318
3319 if (flushCount6 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 watchStep end!");
3320 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep6: TID 6 repeated watchStep end!");
3321
3322 stepActive[6] = 0;
3323
3324end
3325endtask
3326
3327
3328
3329// check that thread does DO mode correctly
3330task watchDOsteps6;
3331begin
3332
3333 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6: TID 6 watchDOsteps starting!");
3334
3335 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps6;
3336
3337 // now wait for a thread to start. TCU internal signal.
3338 if (`SPC0.tlu.tlu_core_running_status[6] == 0)
3339 @(posedge `SPC0.tlu.tlu_core_running_status[6]);
3340
3341 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6 TID 6 unparked and running in DO mode!");
3342
3343 // loop on step checking. DO mode is self stepping
3344 while (doMode) begin : watchDOsteps6loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
3345
3346 stepDone[6] = 0;
3347 watchStepFlush[6] = 0;
3348 watchStepMMU[6] = 0;
3349
3350 // are we starting to park in middle of DO mode (or end)?
3351 // wait here until unparked again
3352 if (parkTrans[6]) begin
3353 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6 TID 6 getting parked, will delay");
3354 @(negedge parkTrans[6]);
3355 if (!doMode) disable watchDOsteps6loop; // no longer in DO mode, bail
3356 // wait to be unparked or !doMode
3357 if (parkedState[6]) begin
3358 @(negedge doMode or negedge parkedState[6]);
3359 if (!doMode) disable watchDOsteps6loop; // no longer in DO mode, bail
3360 end
3361 end
3362
3363
3364 // an unparked thread does one instruction to completion before thread starts
3365 // the next instruction.
3366 fork
3367 // timeout fork
3368 begin : FORKDO16
3369 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3370 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps6: DO mode, TID 6 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
3371 end
3372
3373 // look for SPU going active
3374// begin : FORKDO26
3375// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)))
3376// @(negedge `SPC0.l2clk);
3377// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps6: DO mode, TID 6 sees SPU busy!");
3378// spuActive[6] = 1;
3379// end
3380
3381 // watch step
3382 begin
3383 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6: TID 6 calling watchStep6 in DO mode!");
3384 watchStep6; // returns when step is done or flushed
3385 if (watchStepFlush[6])
3386 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 6 in DO mode had flush!");
3387 if (watchStepMMU[6])
3388 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 6 in DO mode had mmu reload!");
3389 // calling flush as a done in DO mode
3390 disable FORKDO16; // TO
3391 //disable FORKDO26; // SPU going active
3392 end
3393
3394 join
3395
3396 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6: TID 6 DO mode watchDOsteps step done!");
3397 stepDone[6] = 1;
3398 flushCount6 = 0;
3399// if (!`SPC0.spu_tlu_cwq_busy &&
3400// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3401// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)) spuActive[6] = 0;
3402
3403 @(negedge `SPC0.l2clk);
3404 end // while
3405
3406 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps6: TID 6 DO mode watchDOsteps task ending!");
3407end
3408endtask
3409
3410
3411
3412
3413////////////////////////// end tid 6 ///////////////////////////////////////
3414
3415
3416//////////////////////////////////////////////////////////////////
3417// THREAD 7
3418//////////////////////////////////////////////////////////////////
3419
3420
3421// got park request. transition into parking. parking check.
3422always @(negedge `SPC0.tlu.tcu_core_running[7]) begin: GOTPARK7
3423 `PR_DEBUG("dbg_chk", `DEBUG, "TID 7 calling parkingCheck");
3424 if (enabled) parkingCheck7();
3425end
3426
3427// got unpark request. transition into running. unparking check.
3428always @(posedge `SPC0.tlu.tcu_core_running[7]) begin: UNPARKCHECK7
3429 if (enabled && !ssMode) begin
3430 `PR_DEBUG("dbg_chk", `DEBUG, "TID 7 calling unparkCheck.");
3431 unparkCheck7();
3432 end
3433end
3434
3435// while parked check
3436always @(posedge parkedState[7] or posedge virtualPark[7]) begin: PARKCHECK7
3437 `PR_DEBUG("dbg_chk", `DEBUG, "TID 7 calling parkedCheck");
3438 if (enabled) parkedCheck7();
3439end
3440
3441// check for unexpected running transition
3442 always @(`SPC0.tlu.tlu_core_running_status[7]) begin: UNEXPECTED7
3443 if (!parkTrans[7] && enabled && ! doMode && ! ssMode) // review? to remove ! doMode
3444 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 spc_core_running_status changed w/o request to park/unpark (trans=%0d)!",parkTrans[7]);
3445end
3446
3447
3448
3449////////////// tasks for tid 7 ////////////////////
3450
3451// check the entering into parked state
3452task parkingCheck7;
3453
3454begin
3455
3456
3457 `PR_DEBUG("dbg_chk", `DEBUG, "TID 7 got park request!");
3458
3459 if (parkTrans[7] == 1) begin
3460 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 got park request while park state is already transitioning! Possible diag conflict (multiple parkers)! (enabled=%0d)",enabled);
3461 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +noDebugChecks to disable all debug checkes!");
3462 disable parkingCheck7;
3463 end
3464
3465 parkTrans[7] = 1;
3466
3467 // wait before checking signals
3468 repeat (2) @(negedge `SPC0.l2clk);
3469
3470 // need to see at least one assertion of flush
3471 // if (`SPC0.tlu_flush_ifu[7] !== 1)
3472 // @(posedge `SPC0.tlu_flush_ifu[7]); // has glitches
3473 if (`SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[7] !== 1)
3474 @(posedge `SPC0.ifu_ftu.ftu_agc_ctl.tlu_flush_ifu_f[7]);
3475
3476 // need to see all of these go idle
3477 while (`SPC0.pku_quiesce[7] == 0 ||
3478 `SPC0.ftu_ifu_quiesce[7] == 0 ||
3479 `SPC0.lsu_stb_empty[7] == 0)
3480 @(negedge `SPC0.l2clk);
3481
3482// // need to see all of these go idle
3483// while (`SPC0.pku_quiesce[7] == 0 ||
3484// `SPC0.ftu_ifu_quiesce[7] == 0 ||
3485// `SPC0.lsu_stb_empty[7] == 0 ||
3486// `SPC0.tlu.fls1.idl_request == 0)
3487// @(negedge `SPC0.l2clk);
3488
3489 parkedState[7] <= 1;
3490 parkTrans[7] <= 0;
3491 // `PR_ALWAYS("dbg_chk", `ALWAYS, "INFO: TID %0d has parked!", 7);
3492 `PR_DEBUG("dbg_chk", `DEBUG, "INFO: TID 7 has parked!");
3493
3494end
3495endtask
3496
3497
3498// in parked state.
3499// also called between single steps.
3500task parkedCheck7;
3501reg notified;
3502begin //{
3503
3504 notified = 0;
3505 // loop while not transitioning out of park if not SS mode.
3506 // loop while in SS virtualPark if SS mode.
3507 while ((parkTrans[7] == 0 && ssMode == 0) ||
3508 (virtualPark[7] == 1 && ssMode == 1 &&
3509 `TOP.cpu.tcu_ss_request[0] == 0)) begin //{
3510 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 7 watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[7],virtualPark[7],`TOP.cpu.tcu_ss_request[0]);
3511
3512 @(negedge `SPC0.l2clk);
3513
3514 // if in SS mode and core_running goes to zero for that thread, the thread
3515 // will self step once and flush in order to change to a parked state
3516 // (core_running_status=0). This looks like an un-asked for step so it
3517 // has to be detected and ignored. Try stalling here during it.
3518 while (`SPC0.tlu.tcu_core_running[7] == 0 &&
3519 `SPC0.tlu.tlu_core_running_status[7] == 1)
3520 @(negedge `SPC0.l2clk);
3521
3522 // watch for instructions sneaking in
3523 // dec_inst_valid_m[1:0], one bit per group
3524 if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 7 && `SPC0.tlu.tlu_retry[1] == 1)
3525 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 had tlu_trap_pc_1_valid activity while parked/between steps!");
3526
3527 if (`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 3)
3528 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 had dec_inst_valid_m activity while parked/between steps!");
3529
3530
3531 end //} while
3532
3533 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 7 STOP watching for activity while parked/between steps. trans=%0h, virtualPark=%0h, tcu_ss_request=%0h",parkTrans[7],virtualPark[7],`TOP.cpu.tcu_ss_request[0]);
3534
3535end //}
3536endtask
3537
3538
3539// leaving parked state
3540task unparkCheck7;
3541integer count;
3542begin
3543
3544 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 7 got unpark request!");
3545
3546 if (parkTrans[7] == 1) begin
3547 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 got unpark request while park state is already transitioning! Possible diag conflict! (trans=%0h)",parkTrans);
3548 disable unparkCheck7;
3549 end
3550
3551 parkTrans[7] = 1;
3552
3553 // must see `SPC0.tlu.core_running_status[7] w/in count clocks
3554 count7 = 0;
3555
3556 while (`SPC0.tlu.tlu_core_running_status[7] == 0) begin
3557 @(negedge `SPC0.l2clk);
3558 if (count7 > parkWait) begin // <--- may need to adjust
3559 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 did not assert spc_core_running_status as soon as it should have (%0d clocks)!", count7);
3560 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +parkWait=n (currently %0d). +noDebugChecks disables all checks!",parkWait);
3561 end
3562 count7 = count7 + 1;
3563 end
3564
3565 if (!doMode && !ssMode) begin
3566 // need to see re-direct w/in "redirectWait" more clocks
3567 count7 = 0;
3568
3569 // if this is true, the redirect and the assertion of core_running_status
3570 // happened at once so while loop can be skipped.
3571 while (! (`SPC0.tlu_trap_pc_1_valid &&
3572 `SPC0.tlu_trap_1_tid[1:0] == 3)) begin
3573 @(negedge `SPC0.l2clk);
3574 if (count7 > redirectWait) begin // <--- may need to adjust
3575 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: TID 7 did not redirect within %d clocks after core_running_status assert!", redirectWait);
3576 `PR_ERROR ("dbg_chk", `ERROR, "NOTICE: For unusual circumstances, use +redirectWait=n (currently %0d). +noDebugChecks disables all checks!",redirectWait);
3577 end
3578 count7 = count7 + 1;
3579 end
3580 end
3581
3582 parkedState[7] <= 0;
3583 parkTrans[7] <= 0;
3584 count7 <= 0;
3585
3586end
3587endtask
3588
3589
3590// watch this tid step correctly. Should step 1 instruction
3591// and then "virtual park".
3592// for SS and DO modes.
3593task watchStep7;
3594begin
3595
3596 watchStepFlush[7] = 0; // set if we got a flush
3597 watchStepMMU[7] = 0; // set if we got a mmu reload
3598 stepDone[7] = 0;
3599 stepActive[7] = 1;
3600
3601 if (flushCount7) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 repeating watchStep task due to flush (flushCount=%0d, redirectCount=%0d)!",flushCount7,redirectCount7);
3602
3603
3604 fork
3605 // timeout fork
3606 begin : FORK10_7
3607 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3608 `PR_ERROR ("dbg_chk", `ERROR, "watchStep7: TID 7 did not see valid PC retry (waitTime=%0d)!", stepWaitTime);
3609 end
3610
3611// // look for SPU going active
3612// begin : FORK11_7
3613// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)))
3614// @(negedge `SPC0.l2clk);
3615// `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 see SPU active!");
3616// spuActive[7] = 1;
3617// end
3618
3619 // might get ss_complete due to not knowing if there are 1 or 2 or more flushes.
3620 // this task gets called w/o knowing in advance if there will be one more
3621 // assertion of tlu_trap_pc_0/1_valid or not.
3622 begin : FORK8_7
3623 if (ssMode) begin
3624 @(posedge `SPC0.spc_ss_complete);
3625 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount7, redirectCount7);
3626 stepDone[7] = 1;
3627 stepActive[7] = 0;
3628 disable watchStep7; // return
3629 end
3630 end
3631
3632 // valid PC / retry
3633 begin : FORK9_7
3634 // start step. tid wakes up/redirects and does "one instruction"
3635 while (!(`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 3 && `SPC0.tlu.tlu_retry[1] == 1)) begin
3636 // might see `SPC0.tlu.mmu_reload_done[7] here if previous
3637 // redirect was due to a MMU miss. If so, decrement flush count because
3638 // the previous flush on prev pc_valid "does not count" and there can be
3639 // any number of them w/ no way to predict quantity.
3640 if (`SPC0.tlu.mmu_reload_done[7] && ssMode) begin
3641 flushCount7 = flushCount7-1;
3642 redirectCount7 = redirectCount7-1;
3643 watchStepMMU[7] = 1;
3644 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 saw mmu_reload_done (hwtw)! flushCount/redirectCount decremented to %0d/%0d", flushCount7, redirectCount7);
3645 end
3646 @(negedge `SPC0.l2clk);
3647 end
3648
3649 redirectCount7 = redirectCount7+1;
3650 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 got valid retry, step waiting on negedge pku_quiesce (redirectCount=%0d)!",redirectCount7);
3651 disable FORK8_7; // kill sync on spc_ss_complete
3652
3653 @(negedge `SPC0.pku_quiesce[7]);
3654 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 got negedge pku_quiesce, step waiting on dec_inst_valid_m!");
3655
3656 while (!(`SPC0.dec_inst_valid_m[1] == 1 && `SPC0.dec_tid1_m[1:0] == 3)) @(negedge `SPC0.l2clk);
3657
3658 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 valid step starting!");
3659 disable FORK10_7; // kill timeout
3660 //disable FORK11_7;
3661 // if (!`SPC0.spu_tlu_cwq_busy &&
3662// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3663// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)) spuActive[7] = 0;
3664 end
3665 join
3666
3667
3668
3669 // finish step
3670 fork
3671 // timeout fork
3672 begin : FORK4_7
3673 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3674
3675 // may need to adjust. If a tid is doing a SPU sync ctl reg sync read,
3676 // it could stay "busy" for a REAL long time!!! Need delayed check of busy
3677 // since it can assert after the step has started.
3678 `PR_ERROR ("dbg_chk", `ERROR, "watchStep7: TID 7 did not quiesce/complete after step (SS or DO) as it should have. not SPU busy (waitTime=%0d)!", stepWaitTime);
3679 end
3680
3681 // look for SPU going active
3682// begin : FORK12_7
3683// while (!(`SPC0.spu_tlu_cwq_busy ||
3684// ((`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7 && doMode) || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && ssMode))))
3685// @(negedge `SPC0.l2clk);
3686// spuActive[7] = 1;
3687// end
3688
3689
3690 // look for flush_ifu (w/o lsu_trap_flush (aka ptrap_flush) if SS)
3691 // and end this task if seen. tlu_flush_ifu assertion always means
3692 // this "instruction" is done, but may repeat (tlb miss, etc) w/in the SS.
3693 begin : FORK6_7
3694 // checking ptrap_flush to make sure that flush is not caused by lsu_trap_flush
3695 while (`SPC0.tlu_flush_ifu[7] == 0)
3696 @(negedge `SPC0.l2clk);
3697
3698// // debug!!!!!!!!!!!!!!!!!!!!!!!!!!!
3699// if (`SPC0.tlu.fls1.ptrap_flush[3] == 1) begin
3700// `PR_ERROR ("dbg_chk", `ERROR, "watchStep7: TID 7 have tlu_flush_ifu !!!!!!!!!!!!!!!!!!!!!!!");
3701// end
3702//
3703
3704 if ((ssMode && `SPC0.tlu.fls1.ptrap_flush[3] == 0) || doMode) begin
3705 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 have tlu_flush_ifu (flushCount=%0d)!",flushCount7);
3706 watchStepFlush[7] = 1;
3707 flushCount7 = flushCount7+1;
3708 stepActive[7] = 0;
3709 disable watchStep7; // return
3710 end
3711 end
3712
3713
3714 // are we done fork, DO mode quiesce
3715 begin : FORK5_7
3716 if (doMode) begin
3717 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 watching for quiesce (only matters fo DO mode)!");
3718 while (`SPC0.pku_quiesce[7] == 0 ||
3719 `SPC0.ftu_ifu_quiesce[7] == 0 ||
3720 `SPC0.lsu_stb_empty[7] == 0) @(negedge `SPC0.l2clk);
3721
3722 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 have quiesce (only matters for DO mode)!");
3723 if (doMode) begin
3724 disable FORK4_7; // TO
3725 disable FORK6_7; // flush check
3726 //disable FORK12_7;
3727// @(negedge `SPC0.l2clk);
3728// if (!`SPC0.spu_tlu_cwq_busy &&
3729// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3730// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)) spuActive[7] = 0;
3731 end
3732 end
3733 end
3734
3735
3736 // are we done fork, SS mode only
3737 begin : FORK7_7
3738 // wait for SS complete
3739 if (ssMode) begin
3740 @(posedge `SPC0.spc_ss_complete);
3741 `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 see spc_ss_complete, step done, bailing (flushCount=%0d/redirectCount=%0d)!", flushCount7,redirectCount7);
3742 stepDone[7] = 1;
3743
3744// while (ssMode && !`SPC0.spc_ss_complete) begin
3745// // detect a second inst valid w/o a flush between
3746// if (`SPC0.tlu_trap_pc_1_valid && `SPC0.tlu_trap_1_tid[1:0] == 3 && `SPC0.tlu.tlu_retry[1] == 1) begin
3747// // delay error so flush thread can kill this in the "got flush" case
3748// @(negedge `SPC0.l2clk);
3749// `PR_ERROR ("dbg_chk", `ERROR, "watchStep7: TID 7 had another inst start before SS done was asserted!");
3750// end
3751// @(negedge `SPC0.l2clk);
3752// end // while
3753
3754 if (`SPC0.pku_quiesce[7] == 0 ||
3755 `SPC0.ftu_ifu_quiesce[7] == 0 ||
3756 `SPC0.lsu_stb_empty[7] == 0)
3757 `PR_ERROR ("dbg_chk", `ERROR, "watchStep7: TID 7 was not quiesce at ss_complete assertion!");
3758
3759 disable FORK4_7; // TO
3760 disable FORK6_7; // flush check
3761 //disable FORK12_7;
3762// @(negedge `SPC0.l2clk);
3763// if (!`SPC0.spu_tlu_cwq_busy &&
3764// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3765// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)) spuActive[7] = 0;
3766 end
3767 end
3768
3769 join
3770
3771
3772 if (flushCount7 == 0) `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 watchStep end!");
3773 else `PR_DEBUG("dbg_chk", `DEBUG, "watchStep7: TID 7 repeated watchStep end!");
3774
3775 stepActive[7] = 0;
3776
3777end
3778endtask
3779
3780
3781
3782// check that thread does DO mode correctly
3783task watchDOsteps7;
3784begin
3785
3786 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7: TID 7 watchDOsteps starting!");
3787
3788 if (! `TOP.cpu.tcu_do_mode[0]) disable watchDOsteps7;
3789
3790 // now wait for a thread to start. TCU internal signal.
3791 if (`SPC0.tlu.tlu_core_running_status[7] == 0)
3792 @(posedge `SPC0.tlu.tlu_core_running_status[7]);
3793
3794 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7 TID 7 unparked and running in DO mode!");
3795
3796 // loop on step checking. DO mode is self stepping
3797 while (doMode) begin : watchDOsteps7loop// && `SPC0.tlu.tlu_core_running_status[7:0] != 0) begin
3798
3799 stepDone[7] = 0;
3800 watchStepFlush[7] = 0;
3801 watchStepMMU[7] = 0;
3802
3803 // are we starting to park in middle of DO mode (or end)?
3804 // wait here until unparked again
3805 if (parkTrans[7]) begin
3806 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7 TID 7 getting parked, will delay");
3807 @(negedge parkTrans[7]);
3808 if (!doMode) disable watchDOsteps7loop; // no longer in DO mode, bail
3809 // wait to be unparked or !doMode
3810 if (parkedState[7]) begin
3811 @(negedge doMode or negedge parkedState[7]);
3812 if (!doMode) disable watchDOsteps7loop; // no longer in DO mode, bail
3813 end
3814 end
3815
3816
3817 // an unparked thread does one instruction to completion before thread starts
3818 // the next instruction.
3819 fork
3820 // timeout fork
3821 begin : FORKDO17
3822 repeat (stepWaitTime) @(negedge `SPC0.l2clk);
3823 `PR_ERROR ("dbg_chk", `ERROR, "watchDOsteps7: DO mode, TID 7 timeout waiting for watchStep call to return, not SPU busy (+stepWaitTime=%0d)!", stepWaitTime);
3824 end
3825
3826 // look for SPU going active
3827// begin : FORKDO27
3828// while (!(`SPC0.spu_tlu_cwq_busy || (`SPC0.spu.mct.spu_pmu_ma_busy[3] && `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)))
3829// @(negedge `SPC0.l2clk);
3830// `PR_ALWAYS("dbg_chk", `ALWAYS, "watchDOsteps7: DO mode, TID 7 sees SPU busy!");
3831// spuActive[7] = 1;
3832// end
3833
3834 // watch step
3835 begin
3836 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7: TID 7 calling watchStep7 in DO mode!");
3837 watchStep7; // returns when step is done or flushed
3838 if (watchStepFlush[7])
3839 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 7 in DO mode had flush!");
3840 if (watchStepMMU[7])
3841 `PR_DEBUG ("dbg_chk", `DEBUG, "TID 7 in DO mode had mmu reload!");
3842 // calling flush as a done in DO mode
3843 disable FORKDO17; // TO
3844 //disable FORKDO27; // SPU going active
3845 end
3846
3847 join
3848
3849 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7: TID 7 DO mode watchDOsteps step done!");
3850 stepDone[7] = 1;
3851 flushCount7 = 0;
3852// if (!`SPC0.spu_tlu_cwq_busy &&
3853// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3854// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)) spuActive[7] = 0;
3855
3856 @(negedge `SPC0.l2clk);
3857 end // while
3858
3859 `PR_DEBUG("dbg_chk", `DEBUG, "watchDOsteps7: TID 7 DO mode watchDOsteps task ending!");
3860end
3861endtask
3862
3863
3864
3865
3866////////////////////////// end tid 7 ///////////////////////////////////////
3867
3868
3869
3870////////////// DO mode checks ////////////////////
3871
3872always @(posedge `TOP.cpu.tcu_do_mode[0]) begin: DOMODE
3873 if (enabled) begin
3874
3875 `PR_ALWAYS ("dbg_chk", `ALWAYS, "Entering Disable Overlap mode!");
3876 if (parkedState !== 8'hff)
3877 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: All threads must be parked when enabling/disabling DO mode!");
3878 doMode = 1;
3879 stepDone = 0;
3880
3881 // wait for core_running to change (unparking) so DO steps can start
3882 // Assumes (safely) a SINGLE change to this register!
3883 if (`SPC0.tlu.tcu_core_running[7:0] == 0)
3884 @(`SPC0.tlu.tcu_core_running[7:0])
3885
3886 stepAllowed[7:0] = `SPC0.tlu.tcu_core_running[7:0];
3887
3888 `PR_DEBUG("dbg_chk", `DEBUG, "DO mode, ready to run in DO mode!");
3889
3890
3891 // for each thread, call a task that checks DO mode.
3892 // these return when DO mode ends
3893 fork
3894 if (stepAllowed[0]) watchDOsteps0;
3895 if (stepAllowed[1]) watchDOsteps1;
3896 if (stepAllowed[2]) watchDOsteps2;
3897 if (stepAllowed[3]) watchDOsteps3;
3898 if (stepAllowed[4]) watchDOsteps4;
3899 if (stepAllowed[5]) watchDOsteps5;
3900 if (stepAllowed[6]) watchDOsteps6;
3901 if (stepAllowed[7]) watchDOsteps7;
3902 join
3903
3904 end
3905end
3906
3907
3908
3909always @(negedge `TOP.cpu.tcu_do_mode[0]) begin
3910 if (enabled) begin
3911 `PR_ALWAYS ("dbg_chk", `ALWAYS, "Ending Disable Overlap mode!");
3912 doMode = 0;
3913 if (parkedState !== 8'hff)
3914 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: All threads must be parked when enabling/disabling DO mode!");
3915 if (stepAllowed[0]) disable watchStep0;
3916 if (stepAllowed[1]) disable watchStep1;
3917 if (stepAllowed[2]) disable watchStep2;
3918 if (stepAllowed[3]) disable watchStep3;
3919 if (stepAllowed[4]) disable watchStep4;
3920 if (stepAllowed[5]) disable watchStep5;
3921 if (stepAllowed[6]) disable watchStep6;
3922 if (stepAllowed[7]) disable watchStep7;
3923 stepAllowed[7:0] = 0;
3924 end
3925end
3926
3927
3928
3929////////////// SS mode checks ////////////////////
3930////////////// SS mode checks ////////////////////
3931////////////// SS mode checks ////////////////////
3932
3933always @(posedge `TOP.cpu.tcu_ss_mode[0]) begin: SSMODE
3934
3935 if (enabled) begin
3936
3937 // initial value in case ss_mode and tcu_core_running change at once
3938 stepAllowed[7:0] = `SPC0.tlu.tcu_core_running[7:0]; // need?
3939
3940 `PR_ALWAYS ("dbg_chk", `ALWAYS, "Entering Single Step mode!");
3941 if (parkedState !== 8'hff)
3942 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: All threads must be parked when enabling SS mode!");
3943
3944 stepDone = 0;
3945 ssMode = 1;
3946 @(negedge `SPC0.l2clk);
3947 // use virtualPark for SS mode, not parkedState
3948 //virtualPark = threadEnable;
3949 virtualPark = `PARGS.th_check_enable; // th_check_enable is set dynamically
3950
3951 // wait for core_running to change so steps can start
3952 if (`SPC0.tlu.tcu_core_running[7:0] == 0)
3953 @(`SPC0.tlu.tcu_core_running[7:0]) stepAllowed[7:0] = `SPC0.tlu.tcu_core_running[7:0];
3954
3955 `PR_DEBUG("dbg_chk", `DEBUG, "SS mode, ready to run in SS mode!");
3956
3957 // loop on this step checking
3958 while (`TOP.cpu.tcu_ss_mode[0] === 1) begin
3959
3960 // wait for TCU to request a step or for SS mode to end
3961 @(posedge `TOP.cpu.tcu_ss_request or negedge `TOP.cpu.tcu_ss_mode[0]);
3962
3963 if (`TOP.cpu.tcu_ss_mode[0] === 1) begin
3964
3965 @(negedge `SPC0.l2clk);
3966
3967 virtualPark = 0;
3968 stepCount = stepCount+1;
3969 stepDone = 0;
3970 watchStepFlush = 0;
3971 watchStepMMU = 0;
3972
3973 fork
3974 if (stepAllowed[0]) begin
3975 flushCount0 = 0;
3976 redirectCount0 = 0;
3977 watchStep0; // returns when inst is done
3978 // got a flush, will be more activity
3979 if (flushCount0 != 0) begin
3980 while (!stepDone[0]) begin
3981 @(negedge `SPC0.l2clk);
3982 watchStep0; // returns when inst is done
3983 if (flushCount0 > 2)
3984 `PR_ERROR ("dbg_chk", `ERROR, "TID 0 too many flushes in SS mode (%0d)",flushCount0);
3985 if (redirectCount0 > 2)
3986 `PR_ERROR ("dbg_chk", `ERROR, "TID 0 too many redirects in SS mode (%0d)",redirectCount0);
3987 if (redirectCount0 > 1 && watchStepMMU[0])
3988 `PR_ERROR ("dbg_chk", `ERROR, "TID 0 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount0);
3989 end
3990 end
3991 virtualPark[0] = 1; // should be in virtual park. starts parkedCheck0
3992 stepDone[0] = 1;
3993// if (!`SPC0.spu_tlu_cwq_busy &&
3994// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
3995// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 0)) spuActive[0] = 0;
3996 end
3997
3998 if (stepAllowed[1]) begin
3999 flushCount1 = 0;
4000 redirectCount1 = 0;
4001 watchStep1; // returns when inst is done
4002 // got a flush, will be more activity
4003 if (flushCount1 != 0) begin
4004 while (!stepDone[1]) begin
4005 @(negedge `SPC0.l2clk);
4006 watchStep1; // returns when inst is done
4007 if (flushCount1 > 2)
4008 `PR_ERROR ("dbg_chk", `ERROR, "TID 1 too many flushes in SS mode (%0d)",flushCount1);
4009 if (redirectCount1 > 2)
4010 `PR_ERROR ("dbg_chk", `ERROR, "TID 1 too many redirects in SS mode (%0d)",redirectCount1);
4011 if (redirectCount1 > 1 && watchStepMMU[1])
4012 `PR_ERROR ("dbg_chk", `ERROR, "TID 1 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount1);
4013 end
4014 end
4015 virtualPark[1] = 1; // should be in virtual park. starts parkedCheck0
4016 stepDone[1] = 1;
4017// if (!`SPC0.spu_tlu_cwq_busy &&
4018// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4019// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 1)) spuActive[1] = 0;
4020 end
4021
4022 if (stepAllowed[2]) begin
4023 flushCount2 = 0;
4024 redirectCount2 = 0;
4025 watchStep2; // returns when inst is done
4026 // got a flush, will be more activity
4027 if (flushCount2 != 0) begin
4028 while (!stepDone[2]) begin
4029 @(negedge `SPC0.l2clk);
4030 watchStep2; // returns when inst is done
4031 if (flushCount2 > 2)
4032 `PR_ERROR ("dbg_chk", `ERROR, "TID 2 too many flushes in SS mode (%0d)",flushCount2);
4033 if (redirectCount2 > 2)
4034 `PR_ERROR ("dbg_chk", `ERROR, "TID 2 too many redirects in SS mode (%0d)",redirectCount2);
4035 if (redirectCount2 > 1 && watchStepMMU[2])
4036 `PR_ERROR ("dbg_chk", `ERROR, "TID 2 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount2);
4037 end
4038 end
4039 virtualPark[2] = 1; // should be in virtual park. starts parkedCheck0
4040 stepDone[2] = 1;
4041// if (!`SPC0.spu_tlu_cwq_busy &&
4042// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4043// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 2)) spuActive[2] = 0;
4044 end
4045
4046 if (stepAllowed[3]) begin
4047 flushCount3 = 0;
4048 redirectCount3 = 0;
4049 watchStep3; // returns when inst is done
4050 // got a flush, will be more activity
4051 if (flushCount3 != 0) begin
4052 while (!stepDone[3]) begin
4053 @(negedge `SPC0.l2clk);
4054 watchStep3; // returns when inst is done
4055 if (flushCount3 > 2)
4056 `PR_ERROR ("dbg_chk", `ERROR, "TID 3 too many flushes in SS mode (%0d)",flushCount3);
4057 if (redirectCount3 > 2)
4058 `PR_ERROR ("dbg_chk", `ERROR, "TID 3 too many redirects in SS mode (%0d)",redirectCount3);
4059 if (redirectCount3 > 1 && watchStepMMU[3])
4060 `PR_ERROR ("dbg_chk", `ERROR, "TID 3 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount3);
4061 end
4062 end
4063 virtualPark[3] = 1; // should be in virtual park. starts parkedCheck0
4064 stepDone[3] = 1;
4065// if (!`SPC0.spu_tlu_cwq_busy &&
4066// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4067// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 3)) spuActive[3] = 0;
4068 end
4069
4070 if (stepAllowed[4]) begin
4071 flushCount4 = 0;
4072 redirectCount4 = 0;
4073 watchStep4; // returns when inst is done
4074 // got a flush, will be more activity
4075 if (flushCount4 != 0) begin
4076 while (!stepDone[4]) begin
4077 @(negedge `SPC0.l2clk);
4078 watchStep4; // returns when inst is done
4079 if (flushCount4 > 2)
4080 `PR_ERROR ("dbg_chk", `ERROR, "TID 4 too many flushes in SS mode (%0d)",flushCount4);
4081 if (redirectCount4 > 2)
4082 `PR_ERROR ("dbg_chk", `ERROR, "TID 4 too many redirects in SS mode (%0d)",redirectCount4);
4083 if (redirectCount4 > 1 && watchStepMMU[4])
4084 `PR_ERROR ("dbg_chk", `ERROR, "TID 4 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount4);
4085 end
4086 end
4087 virtualPark[4] = 1; // should be in virtual park. starts parkedCheck0
4088 stepDone[4] = 1;
4089// if (!`SPC0.spu_tlu_cwq_busy &&
4090// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4091// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 4)) spuActive[4] = 0;
4092 end
4093
4094 if (stepAllowed[5]) begin
4095 flushCount5 = 0;
4096 redirectCount5 = 0;
4097 watchStep5; // returns when inst is done
4098 // got a flush, will be more activity
4099 if (flushCount5 != 0) begin
4100 while (!stepDone[5]) begin
4101 @(negedge `SPC0.l2clk);
4102 watchStep5; // returns when inst is done
4103 if (flushCount5 > 2)
4104 `PR_ERROR ("dbg_chk", `ERROR, "TID 5 too many flushes in SS mode (%0d)",flushCount5);
4105 if (redirectCount5 > 2)
4106 `PR_ERROR ("dbg_chk", `ERROR, "TID 5 too many redirects in SS mode (%0d)",redirectCount5);
4107 if (redirectCount5 > 1 && watchStepMMU[5])
4108 `PR_ERROR ("dbg_chk", `ERROR, "TID 5 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount5);
4109 end
4110 end
4111 virtualPark[5] = 1; // should be in virtual park. starts parkedCheck0
4112 stepDone[5] = 1;
4113// if (!`SPC0.spu_tlu_cwq_busy &&
4114// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4115// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 5)) spuActive[5] = 0;
4116 end
4117
4118 if (stepAllowed[6]) begin
4119 flushCount6 = 0;
4120 redirectCount6 = 0;
4121 watchStep6; // returns when inst is done
4122 // got a flush, will be more activity
4123 if (flushCount6 != 0) begin
4124 while (!stepDone[6]) begin
4125 @(negedge `SPC0.l2clk);
4126 watchStep6; // returns when inst is done
4127 if (flushCount6 > 2)
4128 `PR_ERROR ("dbg_chk", `ERROR, "TID 6 too many flushes in SS mode (%0d)",flushCount6);
4129 if (redirectCount6 > 2)
4130 `PR_ERROR ("dbg_chk", `ERROR, "TID 6 too many redirects in SS mode (%0d)",redirectCount6);
4131 if (redirectCount6 > 1 && watchStepMMU[6])
4132 `PR_ERROR ("dbg_chk", `ERROR, "TID 6 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount6);
4133 end
4134 end
4135 virtualPark[6] = 1; // should be in virtual park. starts parkedCheck0
4136 stepDone[6] = 1;
4137// if (!`SPC0.spu_tlu_cwq_busy &&
4138// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4139// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 6)) spuActive[6] = 0;
4140 end
4141
4142 if (stepAllowed[7]) begin
4143 flushCount7 = 0;
4144 redirectCount7 = 0;
4145 watchStep7; // returns when inst is done
4146 // got a flush, will be more activity
4147 if (flushCount7 != 0) begin
4148 while (!stepDone[7]) begin
4149 @(negedge `SPC0.l2clk);
4150 watchStep7; // returns when inst is done
4151 if (flushCount7 > 2)
4152 `PR_ERROR ("dbg_chk", `ERROR, "TID 7 too many flushes in SS mode (%0d)",flushCount7);
4153 if (redirectCount7 > 2)
4154 `PR_ERROR ("dbg_chk", `ERROR, "TID 7 too many redirects in SS mode (%0d)",redirectCount7);
4155 if (redirectCount7 > 1 && watchStepMMU[7])
4156 `PR_ERROR ("dbg_chk", `ERROR, "TID 7 too many redirects in SS mode when mmu_reload_done (%0d)",redirectCount7);
4157 end
4158 end
4159 virtualPark[7] = 1; // should be in virtual park. starts parkedCheck0
4160 stepDone[7] = 1;
4161// if (!`SPC0.spu_tlu_cwq_busy &&
4162// !(`SPC0.spu.mct.spu_pmu_ma_busy[3] &&
4163// `SPC0.spu.mct.spu_pmu_ma_busy[2:0] == 7)) spuActive[7] = 0;
4164 end
4165
4166
4167 join
4168
4169
4170 // redundant sanity check
4171 if (stepDone[7:0] !== `SPC0.tlu.tcu_core_running[7:0])
4172 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: SS mode stepDone not correct (%b/%b/%b stepAllowed,stepDone,core_running)!",stepAllowed, stepDone, `SPC0.tlu.tcu_core_running[7:0]);
4173
4174 // DUT must assert ss_complete AND stay idle. timeout for ss_complete
4175// fork
4176// begin : FORK2
4177// repeat (stepWaitTime) @(negedge `SPC0.l2clk);
4178// `PR_ERROR ("dbg_chk", `ERROR, "ERROR: Core did not assert ss_complete when it should have! Waited %0d clocks after watchStep return.",stepWaitTime);
4179// end
4180// @(posedge `SPC0.spc_ss_complete) disable FORK2;
4181// join
4182
4183 // DUT must have asserted ss_complete
4184// if (!`SPC0.spc_ss_complete)
4185// `PR_ERROR ("dbg_chk", `ERROR, "ERROR: Not seeing ss_complete after all threads stepped. Checker problem?");
4186
4187 // all threads must be in virtual park state and quiesced
4188 if (virtualPark[7:0] !== `SPC0.tlu.tcu_core_running[7:0])
4189 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: Core at ss_complete assertion, threads were not idle.");
4190
4191 `PR_DEBUG("dbg_chk", `DEBUG, "SS mode stepDone (%0d)!", stepCount);
4192
4193 end // while
4194 end
4195 `PR_ALWAYS ("dbg_chk", `ALWAYS, "Ending Single Step mode (running step count: %0d!",stepCount);
4196 end
4197end
4198
4199
4200always @(negedge `TOP.cpu.tcu_ss_mode[0]) begin
4201 if (enabled) begin
4202 `PR_DEBUG("dbg_chk", `DEBUG, "Clearing out Single Step mode state!");
4203 ssMode = 0;
4204 stepAllowed = 0;
4205 virtualPark = 0;
4206 if (!(`SPC0.tcu_core_running[7:0] == 0 &&
4207 `SPC0.spc_core_running_status[7:0] == 8'h0))
4208 `PR_ERROR ("dbg_chk", `ERROR, "ERROR: All threads must be parked when disabling SS mode!");
4209 disable watchStep0;
4210 disable watchStep1;
4211 disable watchStep2;
4212 disable watchStep3;
4213 disable watchStep4;
4214 disable watchStep5;
4215 disable watchStep6;
4216 disable watchStep7;
4217 end
4218end
4219
4220
4221
4222
4223// TID 0 ifetch buffer check
4224// make sure that buffer zero is the only buffer valid.
4225//
4226always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4227 if (enabled) begin
4228 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4229 @(negedge `SPC0.l2clk);
4230 if (`TOP.cpu.spc0.ifu_ibu.ibq0.buf_valid_p[7:1] != 0 &&
4231 `TOP.cpu.spc0.ifu_ibu.ibq0.instr_sf_valid_except_p == 0 &&
4232 `SPC0.tcu_core_running[0])
4233 `PR_ERROR ("dbg_chk", `ERROR, "TID 0 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq0.buf_valid_p[7:1]);
4234 end
4235 end
4236end
4237
4238// TID 1 ifetch buffer check
4239// make sure that buffer zero is the only buffer valid.
4240//
4241always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4242 if (enabled) begin
4243 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4244 @(negedge `SPC0.l2clk);
4245 if (`TOP.cpu.spc0.ifu_ibu.ibq1.buf_valid_p[7:1] != 0 &&
4246 `TOP.cpu.spc0.ifu_ibu.ibq1.instr_sf_valid_except_p == 0 &&
4247 `SPC0.tcu_core_running[1])
4248 `PR_ERROR ("dbg_chk", `ERROR, "TID 1 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq1.buf_valid_p[7:1]);
4249 end
4250 end
4251end
4252
4253// TID 2 ifetch buffer check
4254// make sure that buffer zero is the only buffer valid.
4255//
4256always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4257 if (enabled) begin
4258 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4259 @(negedge `SPC0.l2clk);
4260 if (`TOP.cpu.spc0.ifu_ibu.ibq2.buf_valid_p[7:1] != 0 &&
4261 `TOP.cpu.spc0.ifu_ibu.ibq2.instr_sf_valid_except_p == 0 &&
4262 `SPC0.tcu_core_running[2])
4263 `PR_ERROR ("dbg_chk", `ERROR, "TID 2 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq2.buf_valid_p[7:1]);
4264 end
4265 end
4266end
4267
4268// TID 3 ifetch buffer check
4269// make sure that buffer zero is the only buffer valid.
4270//
4271always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4272 if (enabled) begin
4273 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4274 @(negedge `SPC0.l2clk);
4275 if (`TOP.cpu.spc0.ifu_ibu.ibq3.buf_valid_p[7:1] != 0 &&
4276 `TOP.cpu.spc0.ifu_ibu.ibq3.instr_sf_valid_except_p == 0 &&
4277 `SPC0.tcu_core_running[3])
4278 `PR_ERROR ("dbg_chk", `ERROR, "TID 3 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq3.buf_valid_p[7:1]);
4279 end
4280 end
4281end
4282
4283// TID 4 ifetch buffer check
4284// make sure that buffer zero is the only buffer valid.
4285//
4286always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4287 if (enabled) begin
4288 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4289 @(negedge `SPC0.l2clk);
4290 if (`TOP.cpu.spc0.ifu_ibu.ibq4.buf_valid_p[7:1] != 0 &&
4291 `TOP.cpu.spc0.ifu_ibu.ibq4.instr_sf_valid_except_p == 0 &&
4292 `SPC0.tcu_core_running[4])
4293 `PR_ERROR ("dbg_chk", `ERROR, "TID 4 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq4.buf_valid_p[7:1]);
4294 end
4295 end
4296end
4297
4298// TID 5 ifetch buffer check
4299// make sure that buffer zero is the only buffer valid.
4300//
4301always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4302 if (enabled) begin
4303 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4304 @(negedge `SPC0.l2clk);
4305 if (`TOP.cpu.spc0.ifu_ibu.ibq5.buf_valid_p[7:1] != 0 &&
4306 `TOP.cpu.spc0.ifu_ibu.ibq5.instr_sf_valid_except_p == 0 &&
4307 `SPC0.tcu_core_running[5])
4308 `PR_ERROR ("dbg_chk", `ERROR, "TID 5 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq5.buf_valid_p[7:1]);
4309 end
4310 end
4311end
4312
4313// TID 6 ifetch buffer check
4314// make sure that buffer zero is the only buffer valid.
4315//
4316always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4317 if (enabled) begin
4318 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4319 @(negedge `SPC0.l2clk);
4320 if (`TOP.cpu.spc0.ifu_ibu.ibq6.buf_valid_p[7:1] != 0 &&
4321 `TOP.cpu.spc0.ifu_ibu.ibq6.instr_sf_valid_except_p == 0 &&
4322 `SPC0.tcu_core_running[6])
4323 `PR_ERROR ("dbg_chk", `ERROR, "TID 6 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq6.buf_valid_p[7:1]);
4324 end
4325 end
4326end
4327
4328// TID 7 ifetch buffer check
4329// make sure that buffer zero is the only buffer valid.
4330//
4331always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4332 if (enabled) begin
4333 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4334 @(negedge `SPC0.l2clk);
4335 if (`TOP.cpu.spc0.ifu_ibu.ibq7.buf_valid_p[7:1] != 0 &&
4336 `TOP.cpu.spc0.ifu_ibu.ibq7.instr_sf_valid_except_p == 0 &&
4337 `SPC0.tcu_core_running[7])
4338 `PR_ERROR ("dbg_chk", `ERROR, "TID 7 had ifetch buffer(s) valid other than zero (buf_valid_p[7:1]=%0b)!",`TOP.cpu.spc0.ifu_ibu.ibq7.buf_valid_p[7:1]);
4339 end
4340 end
4341end
4342
4343// TID 0 pipelineing check
4344// watch m stage and make sure that the tid does not have a valid inst
4345// there more often than every 9 clocks. counter must get to at least 9.
4346always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4347 if (enabled) begin
4348 pipelineCount0 = 9;
4349 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4350 @(negedge `SPC0.l2clk);
4351 if (`TOP.cpu.spc0.tlu.dec_tid0_m[1:0] == 0 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[0] == 1 && `SPC0.tcu_core_running[0] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4352 // have inst
4353 if (pipelineCount0 < 9) begin
4354 `PR_ERROR ("dbg_chk", `ERROR, "TID 0 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount0);
4355 //stall
4356 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4357 end
4358 pipelineCount0 = 0; // reset after each inst
4359 end
4360 else
4361 // no new inst for tid yet
4362 pipelineCount0 = pipelineCount0+1;
4363
4364 end // while DO/SS mode
4365 end // if
4366end // always
4367
4368
4369
4370// TID 1 pipelineing check
4371// watch m stage and make sure that the tid does not have a valid inst
4372// there more often than every 9 clocks. counter must get to at least 9.
4373always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4374 if (enabled) begin
4375 pipelineCount1 = 9;
4376 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4377 @(negedge `SPC0.l2clk);
4378 if (`TOP.cpu.spc0.tlu.dec_tid0_m[1:0] == 1 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[0] == 1 && `SPC0.tcu_core_running[1] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4379 // have inst
4380 if (pipelineCount1 < 9) begin
4381 `PR_ERROR ("dbg_chk", `ERROR, "TID 1 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount1);
4382 //stall
4383 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4384 end
4385 pipelineCount1 = 0; // reset after each inst
4386 end
4387 else
4388 // no new inst for tid yet
4389 pipelineCount1 = pipelineCount1+1;
4390
4391 end // while DO/SS mode
4392 end // if
4393end // always
4394
4395
4396
4397// TID 2 pipelineing check
4398// watch m stage and make sure that the tid does not have a valid inst
4399// there more often than every 9 clocks. counter must get to at least 9.
4400always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4401 if (enabled) begin
4402 pipelineCount2 = 9;
4403 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4404 @(negedge `SPC0.l2clk);
4405 if (`TOP.cpu.spc0.tlu.dec_tid0_m[1:0] == 2 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[0] == 1 && `SPC0.tcu_core_running[2] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4406 // have inst
4407 if (pipelineCount2 < 9) begin
4408 `PR_ERROR ("dbg_chk", `ERROR, "TID 2 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount2);
4409 //stall
4410 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4411 end
4412 pipelineCount2 = 0; // reset after each inst
4413 end
4414 else
4415 // no new inst for tid yet
4416 pipelineCount2 = pipelineCount2+1;
4417
4418 end // while DO/SS mode
4419 end // if
4420end // always
4421
4422
4423
4424// TID 3 pipelineing check
4425// watch m stage and make sure that the tid does not have a valid inst
4426// there more often than every 9 clocks. counter must get to at least 9.
4427always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4428 if (enabled) begin
4429 pipelineCount3 = 9;
4430 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4431 @(negedge `SPC0.l2clk);
4432 if (`TOP.cpu.spc0.tlu.dec_tid0_m[1:0] == 3 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[0] == 1 && `SPC0.tcu_core_running[3] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4433 // have inst
4434 if (pipelineCount3 < 9) begin
4435 `PR_ERROR ("dbg_chk", `ERROR, "TID 3 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount3);
4436 //stall
4437 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4438 end
4439 pipelineCount3 = 0; // reset after each inst
4440 end
4441 else
4442 // no new inst for tid yet
4443 pipelineCount3 = pipelineCount3+1;
4444
4445 end // while DO/SS mode
4446 end // if
4447end // always
4448
4449
4450
4451// TID 4 pipelineing check
4452// watch m stage and make sure that the tid does not have a valid inst
4453// there more often than every 9 clocks. counter must get to at least 9.
4454always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4455 if (enabled) begin
4456 pipelineCount4 = 9;
4457 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4458 @(negedge `SPC0.l2clk);
4459 if (`TOP.cpu.spc0.tlu.dec_tid1_m[1:0] == 0 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[1] == 1 && `SPC0.tcu_core_running[4] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4460 // have inst
4461 if (pipelineCount4 < 9) begin
4462 `PR_ERROR ("dbg_chk", `ERROR, "TID 4 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount4);
4463 //stall
4464 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4465 end
4466 pipelineCount4 = 0; // reset after each inst
4467 end
4468 else
4469 // no new inst for tid yet
4470 pipelineCount4 = pipelineCount4+1;
4471
4472 end // while DO/SS mode
4473 end // if
4474end // always
4475
4476
4477
4478// TID 5 pipelineing check
4479// watch m stage and make sure that the tid does not have a valid inst
4480// there more often than every 9 clocks. counter must get to at least 9.
4481always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4482 if (enabled) begin
4483 pipelineCount5 = 9;
4484 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4485 @(negedge `SPC0.l2clk);
4486 if (`TOP.cpu.spc0.tlu.dec_tid1_m[1:0] == 1 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[1] == 1 && `SPC0.tcu_core_running[5] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4487 // have inst
4488 if (pipelineCount5 < 9) begin
4489 `PR_ERROR ("dbg_chk", `ERROR, "TID 5 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount5);
4490 //stall
4491 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4492 end
4493 pipelineCount5 = 0; // reset after each inst
4494 end
4495 else
4496 // no new inst for tid yet
4497 pipelineCount5 = pipelineCount5+1;
4498
4499 end // while DO/SS mode
4500 end // if
4501end // always
4502
4503
4504
4505// TID 6 pipelineing check
4506// watch m stage and make sure that the tid does not have a valid inst
4507// there more often than every 9 clocks. counter must get to at least 9.
4508always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4509 if (enabled) begin
4510 pipelineCount6 = 9;
4511 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4512 @(negedge `SPC0.l2clk);
4513 if (`TOP.cpu.spc0.tlu.dec_tid1_m[1:0] == 2 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[1] == 1 && `SPC0.tcu_core_running[6] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4514 // have inst
4515 if (pipelineCount6 < 9) begin
4516 `PR_ERROR ("dbg_chk", `ERROR, "TID 6 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount6);
4517 //stall
4518 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4519 end
4520 pipelineCount6 = 0; // reset after each inst
4521 end
4522 else
4523 // no new inst for tid yet
4524 pipelineCount6 = pipelineCount6+1;
4525
4526 end // while DO/SS mode
4527 end // if
4528end // always
4529
4530
4531
4532// TID 7 pipelineing check
4533// watch m stage and make sure that the tid does not have a valid inst
4534// there more often than every 9 clocks. counter must get to at least 9.
4535always @(posedge `TOP.cpu.tcu_ss_mode[0] or posedge `TOP.cpu.tcu_do_mode[0]) begin
4536 if (enabled) begin
4537 pipelineCount7 = 9;
4538 while (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0]) begin
4539 @(negedge `SPC0.l2clk);
4540 if (`TOP.cpu.spc0.tlu.dec_tid1_m[1:0] == 3 && `TOP.cpu.spc0.tlu.dec_inst_valid_m[1] == 1 && `SPC0.tcu_core_running[7] && (`TOP.cpu.tcu_ss_mode[0] || `TOP.cpu.tcu_do_mode[0])) begin
4541 // have inst
4542 if (pipelineCount7 < 9) begin
4543 `PR_ERROR ("dbg_chk", `ERROR, "TID 7 had pipelining in DO or SS mode (pipelineCount=%0d)!",pipelineCount7);
4544 //stall
4545 @(negedge `TOP.cpu.tcu_ss_mode[0] or negedge `TOP.cpu.tcu_do_mode[0]);
4546 end
4547 pipelineCount7 = 0; // reset after each inst
4548 end
4549 else
4550 // no new inst for tid yet
4551 pipelineCount7 = pipelineCount7+1;
4552
4553 end // while DO/SS mode
4554 end // if
4555end // always
4556
4557
4558// commit output for each thread group
4559always @(negedge `SPC0.l2clk) begin
4560
4561 if (!noCmtCheck && enabled) begin
4562 if (cmtValid0) cmtCount0 = cmtCount0 + 1;
4563
4564 // should we see non zero this cycle?
4565 if (cmtValid0 !== `TOP.cpu.spc0.tlu_dbg_instr_cmt_grp0[1:0]) begin
4566 `PR_ERROR ("dbg_chk", `ERROR, "tlu_dbg_instr_cmt_grp0 not right, (cmtValid0=%0h, tlu_dbg_instr_cmt_grp0=%0h)",cmtValid0,`TOP.cpu.spc0.tlu_dbg_instr_cmt_grp0[1:0]);
4567 `PR_ALWAYS ("dbg_chk", `ALWAYS, "tlu_dbg_instr_cmt_grp0 not right, IF THE VALUE IS X, SPC IS NOT RESET OR SOME SPC INPUT IS X!");
4568 end
4569
4570 // should see non zero next cycle
4571 if (`TOP.cpu.spc0.tlu.fls0.inst_valid_w &&
4572 !(`TOP.cpu.spc0.tlu.fls0.flush_ifu[3:0] &
4573 `TOP.cpu.spc0.tlu.fls0.tid_dec_w[3:0])) begin
4574 if (`TOP.cpu.spc0.tlu.fls0.cti_w) cmtValid0 = 1;
4575 else if (`TOP.cpu.spc0.tlu.fls0.lsu_inst_w) cmtValid0 = 3;
4576 else cmtValid0 = 2;
4577 end
4578 else cmtValid0 = 0;
4579 end
4580end
4581
4582// commit output for each thread group
4583always @(negedge `SPC0.l2clk) begin
4584
4585 if (!noCmtCheck && enabled) begin
4586 if (cmtValid1) cmtCount1 = cmtCount1 + 1;
4587
4588 // should we see non zero this cycle?
4589 if (cmtValid1 !== `TOP.cpu.spc0.tlu_dbg_instr_cmt_grp1[1:0]) begin
4590 `PR_ERROR ("dbg_chk", `ERROR, "tlu_dbg_instr_cmt_grp1 not right, (cmtValid1=%0h, tlu_dbg_instr_cmt_grp1=%0h)",cmtValid1,`TOP.cpu.spc0.tlu_dbg_instr_cmt_grp1[1:0]);
4591 `PR_ALWAYS ("dbg_chk", `ALWAYS, "tlu_dbg_instr_cmt_grp1 not right, IF THE VALUE IS X, SPC IS NOT RESET OR SOME SPC INPUT IS X!");
4592 end
4593
4594 // should see non zero next cycle
4595 if (`TOP.cpu.spc0.tlu.fls1.inst_valid_w &&
4596 !(`TOP.cpu.spc0.tlu.fls1.flush_ifu[3:0] &
4597 `TOP.cpu.spc0.tlu.fls1.tid_dec_w[3:0])) begin
4598 if (`TOP.cpu.spc0.tlu.fls1.cti_w) cmtValid1 = 1;
4599 else if (`TOP.cpu.spc0.tlu.fls1.lsu_inst_w) cmtValid1 = 3;
4600 else cmtValid1 = 2;
4601 end
4602 else cmtValid1 = 0;
4603 end
4604end
4605
4606
4607// second count tid 0
4608always @(negedge `SPC0.l2clk) begin
4609 if(`TOP.nas_top.c0.t0.complete_fw2[7:0]) cmtCountT0 = cmtCountT0+1;
4610 if(`TOP.nas_top.c0.t1.complete_fw2[7:0]) cmtCountT1 = cmtCountT1+1;
4611 if(`TOP.nas_top.c0.t2.complete_fw2[7:0]) cmtCountT2 = cmtCountT2+1;
4612 if(`TOP.nas_top.c0.t3.complete_fw2[7:0]) cmtCountT3 = cmtCountT3+1;
4613end
4614
4615// always @(`TOP.sim_status) begin
4616// if (!noCmtCheck && enabled) begin
4617// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final commit count for group 0 is %0d!",cmtCount0);
4618// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final commit count for group 1 is %0d!",cmtCount1);
4619// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final commit count for groups is %0d!",cmtCount0+cmtCount1);
4620// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final nas pipe complete_fw2 count for T0 is %0d!",cmtCountT0);
4621// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final nas pipe complete_fw2 count for T1 is %0d!",cmtCountT1);
4622// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final nas pipe complete_fw2 count for T2 is %0d!",cmtCountT2);
4623// `PR_ALWAYS ("dbg_chk", `ALWAYS, "Final nas pipe complete_fw2 count for T3 is %0d!",cmtCountT3);
4624// end
4625// end
4626
4627
4628endmodule