Commit | Line | Data |
---|---|---|
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 ============================================ | |
35 | module l2_scrub; | |
36 | ||
37 | `ifndef GATESIM | |
38 | `ifndef NOL2RTL | |
39 | `ifndef AXIS | |
40 | `ifndef AXIS_TL | |
41 | ||
42 | ||
43 | reg [31:0] scrub_freq; | |
44 | integer indexType; | |
45 | reg [16*8:0] fcModesTempstr; | |
46 | reg [8:0] bank_index; | |
47 | reg [31:0] localSeed; | |
48 | ||
49 | integer scrub_count0; | |
50 | integer scrub_count1; | |
51 | integer scrub_count2; | |
52 | integer scrub_count3; | |
53 | integer scrub_count4; | |
54 | integer scrub_count5; | |
55 | integer scrub_count6; | |
56 | integer scrub_count7; | |
57 | ||
58 | initial 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 | |
71 | end | |
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 | ||
971 | endmodule |