Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / verilog / misc / l2_scrub.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: l2_scrub.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 l2_scrub;
36
37`ifndef GATESIM
38`ifndef NOL2RTL
39`ifndef AXIS
40`ifndef AXIS_TL
41
42
43reg [31:0] scrub_freq;
44integer indexType;
45reg [16*8:0] fcModesTempstr;
46reg [8:0] bank_index;
47reg [31:0] localSeed;
48
49integer scrub_count0;
50integer scrub_count1;
51integer scrub_count2;
52integer scrub_count3;
53integer scrub_count4;
54integer scrub_count5;
55integer scrub_count6;
56integer scrub_count7;
57
58initial begin
59 #10;
60 while (scrub_freq) begin
61 @(scrub_count0 or
62 scrub_count1 or
63 scrub_count2 or
64 scrub_count3 or
65 scrub_count4 or
66 scrub_count5 or
67 scrub_count6 or
68 scrub_count7);
69 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB, scrubs done b0-b7 =%d,%d,%d,%d,%d,%d,%d,%d", scrub_count0,scrub_count1,scrub_count2,scrub_count3,scrub_count4,scrub_count5,scrub_count6,scrub_count7);
70 end
71end
72
73
74 initial begin
75 #10;
76 if (scrub_freq) begin
77 @(`TOP.sim_status);
78 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB, final scrubs done b0-b7 = %d,%d,%d,%d,%d,%d,%d,%d", scrub_count0,scrub_count1,scrub_count2,scrub_count3,scrub_count4,scrub_count5,scrub_count6,scrub_count7);
79 end
80 end
81
82
83 initial begin
84
85 scrub_freq = 0;
86 bank_index = 0;
87 indexType = 0;
88 scrub_count0 = 0;
89 scrub_count1 = 0;
90 scrub_count2 = 0;
91 scrub_count3 = 0;
92 scrub_count4 = 0;
93 scrub_count5 = 0;
94 scrub_count6 = 0;
95 scrub_count7 = 0;
96
97 // if L2_SCRUB, use default freq. If L2_SCRUB_FREQ, use given freq,
98 // else do nothing.
99 if ($test$plusargs("L2_SCRUB") ||
100 $value$plusargs("L2_SCRUB_FREQ=%d",scrub_freq)) begin
101 // default of every 2200 clks. scrubs take about 1800 clocks!
102 // don't want > 50% of time spent in scrubs!
103 if (scrub_freq == 0) scrub_freq = 2200;
104 if (scrub_freq < 1000) begin
105 scrub_freq = 1000;
106 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB_FREQ min is 1000");
107 end
108
109 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB_FREQ is set to %d (min=1000)", scrub_freq);
110
111 // index choices:
112 // 0) leave alone. do not use -> L2_SCRUB_IDX
113 // 1) random idx always picked +L2_SCRUB_IDX=rand
114 // 2) increment from x +L2_SCRUB_IDX=n
115 if ($test$plusargs("L2_SCRUB_IDX")) begin
116 if ($value$plusargs("L2_SCRUB_IDX=%s", fcModesTempstr)) begin
117 if (fcModesTempstr == "rand" || fcModesTempstr == "random") indexType = 1;
118 else if ($value$plusargs("L2_SCRUB_IDX=%h", bank_index)) indexType = 2;
119 end
120 end
121
122 if (indexType == 0) `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB_IDX will be left alone");
123 if (indexType == 1) `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB_IDX will be random");
124 if (indexType == 2) `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB_IDX will increment from %h", bank_index);
125
126
127 // wait...
128 #10;
129
130 // get the original seed and use it locally so others
131 // are not affected by this "somtimes used" code.
132 localSeed = `PARGS.seedin;
133
134 // wait for a thread to be unparked
135 @(negedge `TOP.in_reset);
136
137 // wait for any one thread to be out of boot.
138 @(`TOP.gOutOfBoot);
139
140 // increase timeouts since scrubbing is slow
141 `PARGS.timeout = `PARGS.timeout * 4;
142 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB `PARGS.timeout increased to %d",`PARGS.timeout);
143 `PARGS.th_timeout = `PARGS.timeout * 5;
144 `PR_ALWAYS ("l2_scrub", `ALWAYS,"L2_SCRUB `PARGS.th_timeout increased to %d",`PARGS.th_timeout);
145
146 repeat (100) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
147
148 fork
149 scrubBank0(bank_index);
150 scrubBank1(bank_index);
151 scrubBank2(bank_index);
152 scrubBank3(bank_index);
153 scrubBank4(bank_index);
154 scrubBank5(bank_index);
155 scrubBank6(bank_index);
156 scrubBank7(bank_index);
157 join
158 end // if
159 end // initial
160
161
162 // 1) force the counter to a high value for 2 clocks,
163 // force the scrub index to a random value.
164 // 2) release the forces.
165 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
166 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
167 // 5) repeat
168 task scrubBank0;
169 input l2_bank_index;
170
171 reg [8:0] l2_bank_index;
172 reg [12:0] rtl_idx;
173 reg [11:0] randVal;
174 reg [31:0] value;
175
176 begin
177
178
179$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",0,`PARGS.seed,localSeed);
180
181
182 if (`TOP.cpu.ncu_l2t_pm == 0 ||
183 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba01 == 1)) begin
184 // initial skew between banks
185 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
186
187 if (indexType == 2) begin
188 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 0, l2_bank_index);
189 force `TOP.cpu.l2t0.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
190 force `TOP.cpu.l2t0.arbadr.arb_data_ecc_idx_en = 1;
191 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
192 release `TOP.cpu.l2t0.arbadr.arbadr_data_ecc_idx_plus1;
193 release `TOP.cpu.l2t0.arbadr.arb_data_ecc_idx_en;
194 end
195
196 while (1) begin
197
198$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",0,`PARGS.seed,localSeed);
199
200 // set counter to be valueIn clocks away from matching
201 // {csr_l2_control_reg[14:3], 20'b0}.
202 // Pick csr_l2_control_reg[14:3] at random then subtract
203 // valueIn. Force this new value into the scrub_counter so
204 // it will count up naturally and then match.
205 randVal = $random(localSeed);
206 if (randVal == 12'hfff) randVal = 12'hffe;
207 if (randVal == 0) randVal = 1;
208 value = {randVal,20'h0} - scrub_freq;
209 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 0,value);
210 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 0, randVal);
211 force `TOP.cpu.l2t0.csr.scrub_counter = value;
212 force `TOP.cpu.l2t0.csr.csr_l2_control_reg[14:3] = randVal;
213 force `TOP.cpu.l2t0.csr.csr_l2_control_reg[2] = 1;
214
215 if (indexType == 1) begin
216 l2_bank_index = $random(localSeed);
217 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 0, l2_bank_index);
218 // force `TOP.cpu.l2t0.csr.arbadr_data_ecc_idx = l2_bank_index;
219 force `TOP.cpu.l2t0.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
220 force `TOP.cpu.l2t0.arbadr.arb_data_ecc_idx_en = 1;
221 end
222
223 else begin
224 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 0, `TOP.cpu.l2t0.csr.arbadr_data_ecc_idx);
225 end
226
227 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
228
229 // 2 release the forces.
230 release `TOP.cpu.l2t0.csr.scrub_counter;
231 release `TOP.cpu.l2t0.csr.csr_l2_control_reg[14:3];
232 // if (indexType == 1) release `TOP.cpu.l2t0.csr.arbadr_data_ecc_idx;
233 if (indexType == 1) release `TOP.cpu.l2t0.arbadr.arbadr_data_ecc_idx_plus1;
234 if (indexType == 1) release `TOP.cpu.l2t0.arbadr.arb_data_ecc_idx_en;
235
236 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
237 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 0);
238 @(posedge `TOP.cpu.l2t0.csr.csr_filbuf_scrub_ready);
239 rtl_idx = `TOP.cpu.l2t0.csr.scrub_addr;
240
241 // 3 wait for scrub to start
242 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 0);
243 @(posedge `TOP.cpu.l2t0.tagctl.scrub_fsm_en);
244
245 // 4 wait for scrub to be done (all ways)
246 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 0);
247 @(negedge `TOP.cpu.l2t0.tagctl.scrub_fsm_en);
248 scrub_count0 = scrub_count0+1;
249 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 0,scrub_count0);
250
251 // check index incrementing
252 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
253 if (rtl_idx == `TOP.cpu.l2t0.csr.scrub_addr)
254 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 0 RTL did not increment the scrub index!");
255
256 end // 5 while 1
257 end
258 end
259 endtask
260
261
262 // 1) force the counter to a high value for 2 clocks,
263 // force the scrub index to a random value.
264 // 2) release the forces.
265 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
266 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
267 // 5) repeat
268 task scrubBank1;
269 input l2_bank_index;
270
271 reg [8:0] l2_bank_index;
272 reg [12:0] rtl_idx;
273 reg [11:0] randVal;
274 reg [31:0] value;
275
276 begin
277
278
279$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",1,`PARGS.seed,localSeed);
280
281
282 if (`TOP.cpu.ncu_l2t_pm == 0 ||
283 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba01 == 1)) begin
284 // initial skew between banks
285 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
286
287 if (indexType == 2) begin
288 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 1, l2_bank_index);
289 force `TOP.cpu.l2t1.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
290 force `TOP.cpu.l2t1.arbadr.arb_data_ecc_idx_en = 1;
291 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
292 release `TOP.cpu.l2t1.arbadr.arbadr_data_ecc_idx_plus1;
293 release `TOP.cpu.l2t1.arbadr.arb_data_ecc_idx_en;
294 end
295
296 while (1) begin
297
298$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",1,`PARGS.seed,localSeed);
299
300 // set counter to be valueIn clocks away from matching
301 // {csr_l2_control_reg[14:3], 20'b0}.
302 // Pick csr_l2_control_reg[14:3] at random then subtract
303 // valueIn. Force this new value into the scrub_counter so
304 // it will count up naturally and then match.
305 randVal = $random(localSeed);
306 if (randVal == 12'hfff) randVal = 12'hffe;
307 if (randVal == 0) randVal = 1;
308 value = {randVal,20'h0} - scrub_freq;
309 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 1,value);
310 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 1, randVal);
311 force `TOP.cpu.l2t1.csr.scrub_counter = value;
312 force `TOP.cpu.l2t1.csr.csr_l2_control_reg[14:3] = randVal;
313 force `TOP.cpu.l2t1.csr.csr_l2_control_reg[2] = 1;
314
315 if (indexType == 1) begin
316 l2_bank_index = $random(localSeed);
317 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 1, l2_bank_index);
318 // force `TOP.cpu.l2t1.csr.arbadr_data_ecc_idx = l2_bank_index;
319 force `TOP.cpu.l2t1.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
320 force `TOP.cpu.l2t1.arbadr.arb_data_ecc_idx_en = 1;
321 end
322
323 else begin
324 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 1, `TOP.cpu.l2t1.csr.arbadr_data_ecc_idx);
325 end
326
327 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
328
329 // 2 release the forces.
330 release `TOP.cpu.l2t1.csr.scrub_counter;
331 release `TOP.cpu.l2t1.csr.csr_l2_control_reg[14:3];
332 // if (indexType == 1) release `TOP.cpu.l2t1.csr.arbadr_data_ecc_idx;
333 if (indexType == 1) release `TOP.cpu.l2t1.arbadr.arbadr_data_ecc_idx_plus1;
334 if (indexType == 1) release `TOP.cpu.l2t1.arbadr.arb_data_ecc_idx_en;
335
336 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
337 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 1);
338 @(posedge `TOP.cpu.l2t1.csr.csr_filbuf_scrub_ready);
339 rtl_idx = `TOP.cpu.l2t1.csr.scrub_addr;
340
341 // 3 wait for scrub to start
342 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 1);
343 @(posedge `TOP.cpu.l2t1.tagctl.scrub_fsm_en);
344
345 // 4 wait for scrub to be done (all ways)
346 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 1);
347 @(negedge `TOP.cpu.l2t1.tagctl.scrub_fsm_en);
348 scrub_count1 = scrub_count1+1;
349 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 1,scrub_count1);
350
351 // check index incrementing
352 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
353 if (rtl_idx == `TOP.cpu.l2t1.csr.scrub_addr)
354 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 1 RTL did not increment the scrub index!");
355
356 end // 5 while 1
357 end
358 end
359 endtask
360
361
362 // 1) force the counter to a high value for 2 clocks,
363 // force the scrub index to a random value.
364 // 2) release the forces.
365 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
366 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
367 // 5) repeat
368 task scrubBank2;
369 input l2_bank_index;
370
371 reg [8:0] l2_bank_index;
372 reg [12:0] rtl_idx;
373 reg [11:0] randVal;
374 reg [31:0] value;
375
376 begin
377
378
379$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",2,`PARGS.seed,localSeed);
380
381
382 if (`TOP.cpu.ncu_l2t_pm == 0 ||
383 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba23 == 1)) begin
384 // initial skew between banks
385 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
386
387 if (indexType == 2) begin
388 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 2, l2_bank_index);
389 force `TOP.cpu.l2t2.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
390 force `TOP.cpu.l2t2.arbadr.arb_data_ecc_idx_en = 1;
391 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
392 release `TOP.cpu.l2t2.arbadr.arbadr_data_ecc_idx_plus1;
393 release `TOP.cpu.l2t2.arbadr.arb_data_ecc_idx_en;
394 end
395
396 while (1) begin
397
398$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",2,`PARGS.seed,localSeed);
399
400 // set counter to be valueIn clocks away from matching
401 // {csr_l2_control_reg[14:3], 20'b0}.
402 // Pick csr_l2_control_reg[14:3] at random then subtract
403 // valueIn. Force this new value into the scrub_counter so
404 // it will count up naturally and then match.
405 randVal = $random(localSeed);
406 if (randVal == 12'hfff) randVal = 12'hffe;
407 if (randVal == 0) randVal = 1;
408 value = {randVal,20'h0} - scrub_freq;
409 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 2,value);
410 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 2, randVal);
411 force `TOP.cpu.l2t2.csr.scrub_counter = value;
412 force `TOP.cpu.l2t2.csr.csr_l2_control_reg[14:3] = randVal;
413 force `TOP.cpu.l2t2.csr.csr_l2_control_reg[2] = 1;
414
415 if (indexType == 1) begin
416 l2_bank_index = $random(localSeed);
417 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 2, l2_bank_index);
418 // force `TOP.cpu.l2t2.csr.arbadr_data_ecc_idx = l2_bank_index;
419 force `TOP.cpu.l2t2.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
420 force `TOP.cpu.l2t2.arbadr.arb_data_ecc_idx_en = 1;
421 end
422
423 else begin
424 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 2, `TOP.cpu.l2t2.csr.arbadr_data_ecc_idx);
425 end
426
427 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
428
429 // 2 release the forces.
430 release `TOP.cpu.l2t2.csr.scrub_counter;
431 release `TOP.cpu.l2t2.csr.csr_l2_control_reg[14:3];
432 // if (indexType == 1) release `TOP.cpu.l2t2.csr.arbadr_data_ecc_idx;
433 if (indexType == 1) release `TOP.cpu.l2t2.arbadr.arbadr_data_ecc_idx_plus1;
434 if (indexType == 1) release `TOP.cpu.l2t2.arbadr.arb_data_ecc_idx_en;
435
436 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
437 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 2);
438 @(posedge `TOP.cpu.l2t2.csr.csr_filbuf_scrub_ready);
439 rtl_idx = `TOP.cpu.l2t2.csr.scrub_addr;
440
441 // 3 wait for scrub to start
442 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 2);
443 @(posedge `TOP.cpu.l2t2.tagctl.scrub_fsm_en);
444
445 // 4 wait for scrub to be done (all ways)
446 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 2);
447 @(negedge `TOP.cpu.l2t2.tagctl.scrub_fsm_en);
448 scrub_count2 = scrub_count2+1;
449 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 2,scrub_count2);
450
451 // check index incrementing
452 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
453 if (rtl_idx == `TOP.cpu.l2t2.csr.scrub_addr)
454 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 2 RTL did not increment the scrub index!");
455
456 end // 5 while 1
457 end
458 end
459 endtask
460
461
462 // 1) force the counter to a high value for 2 clocks,
463 // force the scrub index to a random value.
464 // 2) release the forces.
465 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
466 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
467 // 5) repeat
468 task scrubBank3;
469 input l2_bank_index;
470
471 reg [8:0] l2_bank_index;
472 reg [12:0] rtl_idx;
473 reg [11:0] randVal;
474 reg [31:0] value;
475
476 begin
477
478
479$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",3,`PARGS.seed,localSeed);
480
481
482 if (`TOP.cpu.ncu_l2t_pm == 0 ||
483 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba23 == 1)) begin
484 // initial skew between banks
485 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
486
487 if (indexType == 2) begin
488 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 3, l2_bank_index);
489 force `TOP.cpu.l2t3.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
490 force `TOP.cpu.l2t3.arbadr.arb_data_ecc_idx_en = 1;
491 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
492 release `TOP.cpu.l2t3.arbadr.arbadr_data_ecc_idx_plus1;
493 release `TOP.cpu.l2t3.arbadr.arb_data_ecc_idx_en;
494 end
495
496 while (1) begin
497
498$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",3,`PARGS.seed,localSeed);
499
500 // set counter to be valueIn clocks away from matching
501 // {csr_l2_control_reg[14:3], 20'b0}.
502 // Pick csr_l2_control_reg[14:3] at random then subtract
503 // valueIn. Force this new value into the scrub_counter so
504 // it will count up naturally and then match.
505 randVal = $random(localSeed);
506 if (randVal == 12'hfff) randVal = 12'hffe;
507 if (randVal == 0) randVal = 1;
508 value = {randVal,20'h0} - scrub_freq;
509 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 3,value);
510 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 3, randVal);
511 force `TOP.cpu.l2t3.csr.scrub_counter = value;
512 force `TOP.cpu.l2t3.csr.csr_l2_control_reg[14:3] = randVal;
513 force `TOP.cpu.l2t3.csr.csr_l2_control_reg[2] = 1;
514
515 if (indexType == 1) begin
516 l2_bank_index = $random(localSeed);
517 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 3, l2_bank_index);
518 // force `TOP.cpu.l2t3.csr.arbadr_data_ecc_idx = l2_bank_index;
519 force `TOP.cpu.l2t3.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
520 force `TOP.cpu.l2t3.arbadr.arb_data_ecc_idx_en = 1;
521 end
522
523 else begin
524 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 3, `TOP.cpu.l2t3.csr.arbadr_data_ecc_idx);
525 end
526
527 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
528
529 // 2 release the forces.
530 release `TOP.cpu.l2t3.csr.scrub_counter;
531 release `TOP.cpu.l2t3.csr.csr_l2_control_reg[14:3];
532 // if (indexType == 1) release `TOP.cpu.l2t3.csr.arbadr_data_ecc_idx;
533 if (indexType == 1) release `TOP.cpu.l2t3.arbadr.arbadr_data_ecc_idx_plus1;
534 if (indexType == 1) release `TOP.cpu.l2t3.arbadr.arb_data_ecc_idx_en;
535
536 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
537 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 3);
538 @(posedge `TOP.cpu.l2t3.csr.csr_filbuf_scrub_ready);
539 rtl_idx = `TOP.cpu.l2t3.csr.scrub_addr;
540
541 // 3 wait for scrub to start
542 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 3);
543 @(posedge `TOP.cpu.l2t3.tagctl.scrub_fsm_en);
544
545 // 4 wait for scrub to be done (all ways)
546 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 3);
547 @(negedge `TOP.cpu.l2t3.tagctl.scrub_fsm_en);
548 scrub_count3 = scrub_count3+1;
549 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 3,scrub_count3);
550
551 // check index incrementing
552 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
553 if (rtl_idx == `TOP.cpu.l2t3.csr.scrub_addr)
554 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 3 RTL did not increment the scrub index!");
555
556 end // 5 while 1
557 end
558 end
559 endtask
560
561
562 // 1) force the counter to a high value for 2 clocks,
563 // force the scrub index to a random value.
564 // 2) release the forces.
565 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
566 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
567 // 5) repeat
568 task scrubBank4;
569 input l2_bank_index;
570
571 reg [8:0] l2_bank_index;
572 reg [12:0] rtl_idx;
573 reg [11:0] randVal;
574 reg [31:0] value;
575
576 begin
577
578
579$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",4,`PARGS.seed,localSeed);
580
581
582 if (`TOP.cpu.ncu_l2t_pm == 0 ||
583 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba45 == 1)) begin
584 // initial skew between banks
585 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
586
587 if (indexType == 2) begin
588 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 4, l2_bank_index);
589 force `TOP.cpu.l2t4.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
590 force `TOP.cpu.l2t4.arbadr.arb_data_ecc_idx_en = 1;
591 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
592 release `TOP.cpu.l2t4.arbadr.arbadr_data_ecc_idx_plus1;
593 release `TOP.cpu.l2t4.arbadr.arb_data_ecc_idx_en;
594 end
595
596 while (1) begin
597
598$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",4,`PARGS.seed,localSeed);
599
600 // set counter to be valueIn clocks away from matching
601 // {csr_l2_control_reg[14:3], 20'b0}.
602 // Pick csr_l2_control_reg[14:3] at random then subtract
603 // valueIn. Force this new value into the scrub_counter so
604 // it will count up naturally and then match.
605 randVal = $random(localSeed);
606 if (randVal == 12'hfff) randVal = 12'hffe;
607 if (randVal == 0) randVal = 1;
608 value = {randVal,20'h0} - scrub_freq;
609 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 4,value);
610 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 4, randVal);
611 force `TOP.cpu.l2t4.csr.scrub_counter = value;
612 force `TOP.cpu.l2t4.csr.csr_l2_control_reg[14:3] = randVal;
613 force `TOP.cpu.l2t4.csr.csr_l2_control_reg[2] = 1;
614
615 if (indexType == 1) begin
616 l2_bank_index = $random(localSeed);
617 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 4, l2_bank_index);
618 // force `TOP.cpu.l2t4.csr.arbadr_data_ecc_idx = l2_bank_index;
619 force `TOP.cpu.l2t4.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
620 force `TOP.cpu.l2t4.arbadr.arb_data_ecc_idx_en = 1;
621 end
622
623 else begin
624 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 4, `TOP.cpu.l2t4.csr.arbadr_data_ecc_idx);
625 end
626
627 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
628
629 // 2 release the forces.
630 release `TOP.cpu.l2t4.csr.scrub_counter;
631 release `TOP.cpu.l2t4.csr.csr_l2_control_reg[14:3];
632 // if (indexType == 1) release `TOP.cpu.l2t4.csr.arbadr_data_ecc_idx;
633 if (indexType == 1) release `TOP.cpu.l2t4.arbadr.arbadr_data_ecc_idx_plus1;
634 if (indexType == 1) release `TOP.cpu.l2t4.arbadr.arb_data_ecc_idx_en;
635
636 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
637 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 4);
638 @(posedge `TOP.cpu.l2t4.csr.csr_filbuf_scrub_ready);
639 rtl_idx = `TOP.cpu.l2t4.csr.scrub_addr;
640
641 // 3 wait for scrub to start
642 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 4);
643 @(posedge `TOP.cpu.l2t4.tagctl.scrub_fsm_en);
644
645 // 4 wait for scrub to be done (all ways)
646 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 4);
647 @(negedge `TOP.cpu.l2t4.tagctl.scrub_fsm_en);
648 scrub_count4 = scrub_count4+1;
649 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 4,scrub_count4);
650
651 // check index incrementing
652 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
653 if (rtl_idx == `TOP.cpu.l2t4.csr.scrub_addr)
654 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 4 RTL did not increment the scrub index!");
655
656 end // 5 while 1
657 end
658 end
659 endtask
660
661
662 // 1) force the counter to a high value for 2 clocks,
663 // force the scrub index to a random value.
664 // 2) release the forces.
665 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
666 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
667 // 5) repeat
668 task scrubBank5;
669 input l2_bank_index;
670
671 reg [8:0] l2_bank_index;
672 reg [12:0] rtl_idx;
673 reg [11:0] randVal;
674 reg [31:0] value;
675
676 begin
677
678
679$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",5,`PARGS.seed,localSeed);
680
681
682 if (`TOP.cpu.ncu_l2t_pm == 0 ||
683 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba45 == 1)) begin
684 // initial skew between banks
685 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
686
687 if (indexType == 2) begin
688 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 5, l2_bank_index);
689 force `TOP.cpu.l2t5.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
690 force `TOP.cpu.l2t5.arbadr.arb_data_ecc_idx_en = 1;
691 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
692 release `TOP.cpu.l2t5.arbadr.arbadr_data_ecc_idx_plus1;
693 release `TOP.cpu.l2t5.arbadr.arb_data_ecc_idx_en;
694 end
695
696 while (1) begin
697
698$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",5,`PARGS.seed,localSeed);
699
700 // set counter to be valueIn clocks away from matching
701 // {csr_l2_control_reg[14:3], 20'b0}.
702 // Pick csr_l2_control_reg[14:3] at random then subtract
703 // valueIn. Force this new value into the scrub_counter so
704 // it will count up naturally and then match.
705 randVal = $random(localSeed);
706 if (randVal == 12'hfff) randVal = 12'hffe;
707 if (randVal == 0) randVal = 1;
708 value = {randVal,20'h0} - scrub_freq;
709 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 5,value);
710 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 5, randVal);
711 force `TOP.cpu.l2t5.csr.scrub_counter = value;
712 force `TOP.cpu.l2t5.csr.csr_l2_control_reg[14:3] = randVal;
713 force `TOP.cpu.l2t5.csr.csr_l2_control_reg[2] = 1;
714
715 if (indexType == 1) begin
716 l2_bank_index = $random(localSeed);
717 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 5, l2_bank_index);
718 // force `TOP.cpu.l2t5.csr.arbadr_data_ecc_idx = l2_bank_index;
719 force `TOP.cpu.l2t5.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
720 force `TOP.cpu.l2t5.arbadr.arb_data_ecc_idx_en = 1;
721 end
722
723 else begin
724 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 5, `TOP.cpu.l2t5.csr.arbadr_data_ecc_idx);
725 end
726
727 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
728
729 // 2 release the forces.
730 release `TOP.cpu.l2t5.csr.scrub_counter;
731 release `TOP.cpu.l2t5.csr.csr_l2_control_reg[14:3];
732 // if (indexType == 1) release `TOP.cpu.l2t5.csr.arbadr_data_ecc_idx;
733 if (indexType == 1) release `TOP.cpu.l2t5.arbadr.arbadr_data_ecc_idx_plus1;
734 if (indexType == 1) release `TOP.cpu.l2t5.arbadr.arb_data_ecc_idx_en;
735
736 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
737 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 5);
738 @(posedge `TOP.cpu.l2t5.csr.csr_filbuf_scrub_ready);
739 rtl_idx = `TOP.cpu.l2t5.csr.scrub_addr;
740
741 // 3 wait for scrub to start
742 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 5);
743 @(posedge `TOP.cpu.l2t5.tagctl.scrub_fsm_en);
744
745 // 4 wait for scrub to be done (all ways)
746 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 5);
747 @(negedge `TOP.cpu.l2t5.tagctl.scrub_fsm_en);
748 scrub_count5 = scrub_count5+1;
749 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 5,scrub_count5);
750
751 // check index incrementing
752 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
753 if (rtl_idx == `TOP.cpu.l2t5.csr.scrub_addr)
754 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 5 RTL did not increment the scrub index!");
755
756 end // 5 while 1
757 end
758 end
759 endtask
760
761
762 // 1) force the counter to a high value for 2 clocks,
763 // force the scrub index to a random value.
764 // 2) release the forces.
765 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
766 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
767 // 5) repeat
768 task scrubBank6;
769 input l2_bank_index;
770
771 reg [8:0] l2_bank_index;
772 reg [12:0] rtl_idx;
773 reg [11:0] randVal;
774 reg [31:0] value;
775
776 begin
777
778
779$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",6,`PARGS.seed,localSeed);
780
781
782 if (`TOP.cpu.ncu_l2t_pm == 0 ||
783 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba67 == 1)) begin
784 // initial skew between banks
785 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
786
787 if (indexType == 2) begin
788 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 6, l2_bank_index);
789 force `TOP.cpu.l2t6.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
790 force `TOP.cpu.l2t6.arbadr.arb_data_ecc_idx_en = 1;
791 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
792 release `TOP.cpu.l2t6.arbadr.arbadr_data_ecc_idx_plus1;
793 release `TOP.cpu.l2t6.arbadr.arb_data_ecc_idx_en;
794 end
795
796 while (1) begin
797
798$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",6,`PARGS.seed,localSeed);
799
800 // set counter to be valueIn clocks away from matching
801 // {csr_l2_control_reg[14:3], 20'b0}.
802 // Pick csr_l2_control_reg[14:3] at random then subtract
803 // valueIn. Force this new value into the scrub_counter so
804 // it will count up naturally and then match.
805 randVal = $random(localSeed);
806 if (randVal == 12'hfff) randVal = 12'hffe;
807 if (randVal == 0) randVal = 1;
808 value = {randVal,20'h0} - scrub_freq;
809 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 6,value);
810 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 6, randVal);
811 force `TOP.cpu.l2t6.csr.scrub_counter = value;
812 force `TOP.cpu.l2t6.csr.csr_l2_control_reg[14:3] = randVal;
813 force `TOP.cpu.l2t6.csr.csr_l2_control_reg[2] = 1;
814
815 if (indexType == 1) begin
816 l2_bank_index = $random(localSeed);
817 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 6, l2_bank_index);
818 // force `TOP.cpu.l2t6.csr.arbadr_data_ecc_idx = l2_bank_index;
819 force `TOP.cpu.l2t6.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
820 force `TOP.cpu.l2t6.arbadr.arb_data_ecc_idx_en = 1;
821 end
822
823 else begin
824 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 6, `TOP.cpu.l2t6.csr.arbadr_data_ecc_idx);
825 end
826
827 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
828
829 // 2 release the forces.
830 release `TOP.cpu.l2t6.csr.scrub_counter;
831 release `TOP.cpu.l2t6.csr.csr_l2_control_reg[14:3];
832 // if (indexType == 1) release `TOP.cpu.l2t6.csr.arbadr_data_ecc_idx;
833 if (indexType == 1) release `TOP.cpu.l2t6.arbadr.arbadr_data_ecc_idx_plus1;
834 if (indexType == 1) release `TOP.cpu.l2t6.arbadr.arb_data_ecc_idx_en;
835
836 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
837 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 6);
838 @(posedge `TOP.cpu.l2t6.csr.csr_filbuf_scrub_ready);
839 rtl_idx = `TOP.cpu.l2t6.csr.scrub_addr;
840
841 // 3 wait for scrub to start
842 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 6);
843 @(posedge `TOP.cpu.l2t6.tagctl.scrub_fsm_en);
844
845 // 4 wait for scrub to be done (all ways)
846 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 6);
847 @(negedge `TOP.cpu.l2t6.tagctl.scrub_fsm_en);
848 scrub_count6 = scrub_count6+1;
849 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 6,scrub_count6);
850
851 // check index incrementing
852 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
853 if (rtl_idx == `TOP.cpu.l2t6.csr.scrub_addr)
854 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 6 RTL did not increment the scrub index!");
855
856 end // 5 while 1
857 end
858 end
859 endtask
860
861
862 // 1) force the counter to a high value for 2 clocks,
863 // force the scrub index to a random value.
864 // 2) release the forces.
865 // 3) wait for the scrub (posedge csr_filbuf_scrub_ready).
866 // 4) wait for scrub to be done (posedge filbuf.fb_tecc_pend_reset)
867 // 5) repeat
868 task scrubBank7;
869 input l2_bank_index;
870
871 reg [8:0] l2_bank_index;
872 reg [12:0] rtl_idx;
873 reg [11:0] randVal;
874 reg [31:0] value;
875
876 begin
877
878
879$strobe("1 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",7,`PARGS.seed,localSeed);
880
881
882 if (`TOP.cpu.ncu_l2t_pm == 0 ||
883 (`TOP.cpu.ncu_l2t_pm == 1 && `TOP.cpu.ncu_l2t_ba67 == 1)) begin
884 // initial skew between banks
885 repeat ($random(localSeed)%16) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
886
887 if (indexType == 2) begin
888 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d starting index = %h", 7, l2_bank_index);
889 force `TOP.cpu.l2t7.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
890 force `TOP.cpu.l2t7.arbadr.arb_data_ecc_idx_en = 1;
891 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
892 release `TOP.cpu.l2t7.arbadr.arbadr_data_ecc_idx_plus1;
893 release `TOP.cpu.l2t7.arbadr.arb_data_ecc_idx_en;
894 end
895
896 while (1) begin
897
898$strobe("2 bank %0d PARGS.seed=%d, l2_scrub.localSeed=%d",7,`PARGS.seed,localSeed);
899
900 // set counter to be valueIn clocks away from matching
901 // {csr_l2_control_reg[14:3], 20'b0}.
902 // Pick csr_l2_control_reg[14:3] at random then subtract
903 // valueIn. Force this new value into the scrub_counter so
904 // it will count up naturally and then match.
905 randVal = $random(localSeed);
906 if (randVal == 12'hfff) randVal = 12'hffe;
907 if (randVal == 0) randVal = 1;
908 value = {randVal,20'h0} - scrub_freq;
909 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d scrub_counter = %d", 7,value);
910 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB seting bank %d csr_l2_control_reg[14:3] = %d", 7, randVal);
911 force `TOP.cpu.l2t7.csr.scrub_counter = value;
912 force `TOP.cpu.l2t7.csr.csr_l2_control_reg[14:3] = randVal;
913 force `TOP.cpu.l2t7.csr.csr_l2_control_reg[2] = 1;
914
915 if (indexType == 1) begin
916 l2_bank_index = $random(localSeed);
917 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB set bank %d index = %h", 7, l2_bank_index);
918 // force `TOP.cpu.l2t7.csr.arbadr_data_ecc_idx = l2_bank_index;
919 force `TOP.cpu.l2t7.arbadr.arbadr_data_ecc_idx_plus1 = l2_bank_index;
920 force `TOP.cpu.l2t7.arbadr.arb_data_ecc_idx_en = 1;
921 end
922
923 else begin
924 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB RTL bank %d index = %h", 7, `TOP.cpu.l2t7.csr.arbadr_data_ecc_idx);
925 end
926
927 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
928
929 // 2 release the forces.
930 release `TOP.cpu.l2t7.csr.scrub_counter;
931 release `TOP.cpu.l2t7.csr.csr_l2_control_reg[14:3];
932 // if (indexType == 1) release `TOP.cpu.l2t7.csr.arbadr_data_ecc_idx;
933 if (indexType == 1) release `TOP.cpu.l2t7.arbadr.arbadr_data_ecc_idx_plus1;
934 if (indexType == 1) release `TOP.cpu.l2t7.arbadr.arb_data_ecc_idx_en;
935
936 // 3 wait for the scrub to be signaled (posedge csr_filbuf_scrub_ready).
937 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on csr_filbuf_scrub_ready (scrub counter matching)", 7);
938 @(posedge `TOP.cpu.l2t7.csr.csr_filbuf_scrub_ready);
939 rtl_idx = `TOP.cpu.l2t7.csr.scrub_addr;
940
941 // 3 wait for scrub to start
942 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en assert (wait for scrub to start)", 7);
943 @(posedge `TOP.cpu.l2t7.tagctl.scrub_fsm_en);
944
945 // 4 wait for scrub to be done (all ways)
946 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d waiting on scrub_fsm_en de-assert(scrub has started, wait for finish)", 7);
947 @(negedge `TOP.cpu.l2t7.tagctl.scrub_fsm_en);
948 scrub_count7 = scrub_count7+1;
949 `PR_NORMAL ("l2_scrub", `NORMAL,"L2_SCRUB bank %d scrub has finished (count=%d)", 7,scrub_count7);
950
951 // check index incrementing
952 repeat (2) @(posedge `TOP.cpu.cmp_gclk_c3_l2t0);
953 if (rtl_idx == `TOP.cpu.l2t7.csr.scrub_addr)
954 `PR_ERROR ("l2_scrub", `ERROR, "ERROR: bank 7 RTL did not increment the scrub index!");
955
956 end // 5 while 1
957 end
958 end
959 endtask
960
961
962`endif
963
964`endif
965
966
967`endif
968
969`endif
970
971endmodule