Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / verilog / mem / fbdimm / design / amb_dram_err_inject.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: amb_dram_err_inject.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 amb_dram_err_inject(
36 clk,
37 int_clk,
38 DRAM_RST_L,
39 DRAM_CS_L,
40 DRAM_BA,
41 DRAM_RAS_L,
42 DRAM_CAS_L,
43 DRAM_WE_L,
44 DRAM_DQ,
45 DRAM_DQS,
46 DRAM_CB,
47 AMB_L0_STATE,
48 CHNL_ERR_ENABLE
49 // DRAM_FAIL_OVER,
50 //DRAM_FAIL_PART
51 );
52
53 input clk;
54 input int_clk;
55 input DRAM_RST_L;
56 input [7:0] DRAM_CS_L;
57 input [2:0] DRAM_BA;
58 input DRAM_RAS_L;
59 input DRAM_CAS_L;
60 input DRAM_WE_L;
61 inout [63:0] DRAM_DQ;
62 inout [8:0] DRAM_DQS;
63 input [7:0] DRAM_CB;
64 input AMB_L0_STATE;
65 //input DRAM_FAIL_OVER;
66 //input [5:0] DRAM_FAIL_PART;
67 input CHNL_ERR_ENABLE;
68
69 parameter AUTOREF_PERIOD = 1500;
70 parameter ST_RAS = 2'b00;
71 parameter ST_CAS = 2'b01;
72 parameter ST_DATA = 2'b10;
73 parameter ST_REL = 2'b11;
74
75 integer ref_timer;
76 integer dq_dly;
77 integer flip_for_mecc;
78 integer stop_dq_dly;
79 reg [1:0] error_st;
80 reg inject_err_s1;
81 reg inject_err_s1_1;
82 reg inject_err_s1_2;
83 reg inject_err_s1_3;
84 reg inject_err_s1_4;
85 reg inject_err_s1_5;
86 reg inject_err_s2;
87 reg inject_err_s2_d1;
88 reg inject_err_s2_d2;
89 reg inject_err_s2_d3;
90 reg inject_err_s3;
91 reg inject_err_s3_d1;
92 reg inject_err_s3_d2;
93 reg inject_err_s3_d3;
94 reg [63:0] data;
95 reg [7:0] ecc;
96 reg [3:0] err_bits,err_bits1;
97 reg [3:0] inject_enable;
98 reg ecc_err_inject;
99 reg [31:0] err_pos;
100 reg [31:0] err_pos1;
101 reg [31:0] synd_err_pos;
102 reg addr_parity_err;
103 reg enb_mecc_error;
104 reg inject_err_once;
105 reg disable_mecc, disable_secc;
106 reg [2:0] cas_latency;
107 reg dram_enb_error;
108 wire synd_ecc_err_inject;
109 wire [3:0] synd_err_bits;
110 wire [31:0] synd_err_pos1;
111 reg [63:0] tmp;
112 reg one_bit_data_err;
113 reg multi_bit_data_err;
114 reg random_error;
115 reg scrub_mecc_secc_err;
116 reg mecc_secc_err;
117 reg secc_mecc_err;
118
119 time bcode_finish;
120
121 wire dqs;
122
123// dbg signals for error_mon
124 reg dbg_mecc_err_injected;
125 reg dbg_secc_err_injected;
126
127initial
128begin
129
130 @(posedge DRAM_RST_L)
131
132 ref_timer = 0;
133 flip_for_mecc = 1;
134 err_pos = 0;
135 err_pos1 = 0;
136 ecc_err_inject = 1;
137 error_st = ST_RAS;
138 dq_dly = 0;
139 inject_err_s1 = 1'b0;
140 inject_err_s3 = 1'b0;
141 inject_err_s3_d1 = 1'b0;
142 inject_err_s3_d2 = 1'b0;
143 inject_err_s3_d3 = 1'b0;
144 data = 64'h0;
145 ecc = 8'h0;
146 disable_mecc = 1'b0;
147 disable_secc = 1'b0;
148
149 if ($test$plusargs("INJECT_ERR_ONCE"))
150 inject_err_once = 1;
151 else
152 inject_err_once = 0;
153
154 if ($test$plusargs("ADDR_PARITY_ERR"))
155 addr_parity_err = 1;
156 else
157 addr_parity_err = 0;
158
159 if ($test$plusargs("ENB_MECC_ERROR"))
160 enb_mecc_error = 1;
161 else
162 enb_mecc_error = 0;
163
164 if (! $value$plusargs("force_cas_latency=%d", cas_latency))
165 cas_latency = 3 ;
166
167 if (CHNL_ERR_ENABLE)
168 dram_enb_error = 1;
169 else
170 dram_enb_error = 0;
171
172 if ($test$plusargs("1BIT_DATA_ERROR"))
173 one_bit_data_err = 1'b1;
174
175 if ($test$plusargs("MULTI_BIT_DATA_ERROR"))
176 multi_bit_data_err = 1'b1;
177
178 if ($test$plusargs("SCRUB_MECC_SECC_ERROR")) begin
179 scrub_mecc_secc_err = 1'b1;
180 one_bit_data_err = 1'b0;
181 multi_bit_data_err = 1'b1;
182 end
183
184 if ($test$plusargs("ONLY_ONE_MECC_SECC")) begin
185 mecc_secc_err = 1'b1;
186 one_bit_data_err = 1'b0;
187 multi_bit_data_err = 1'b1;
188 end
189
190 if ($test$plusargs("ONLY_ONE_SECC_MECC")) begin
191 secc_mecc_err = 1'b1;
192 one_bit_data_err = 1'b1;
193 multi_bit_data_err = 1'b0;
194 end
195
196 if ($test$plusargs("RANDOM_ERROR")) begin
197 one_bit_data_err = 1'b0;
198 multi_bit_data_err = 1'b0;
199 random_error = 1'b1;
200 end
201 else
202 random_error = 1'b0;
203
204 if(!$value$plusargs("BOOT_CODE_FINISH=%d",bcode_finish))
205 bcode_finish = 0;
206
207 dbg_mecc_err_injected <= 1'b0;
208 dbg_secc_err_injected <= 1'b0;
209end
210
211always @(clk)
212begin
213 if (!DRAM_RST_L && dram_enb_error && AMB_L0_STATE)
214 begin
215 case (error_st)
216 ST_RAS: begin
217 //$display ("%0d %m: Err injector state ST_RAS\n", $time);
218 dbg_secc_err_injected <= 1'b0;
219 dbg_mecc_err_injected <= 1'b0;
220 if ( !DRAM_RAS_L && DRAM_CAS_L && DRAM_WE_L && !DRAM_CS_L[0] )
221 error_st <= ST_CAS;
222 end
223 ST_CAS: begin
224 //$display ("%0d %m: Err injector state ST_CAS\n", $time);
225 if ( DRAM_RAS_L && !DRAM_CAS_L && DRAM_WE_L && !DRAM_CS_L[0] )
226 error_st <= ST_DATA;
227 end
228 ST_DATA: begin
229 //$display ("%0d %m: Err injector state ST_DATA\n", $time);
230
231 case(cas_latency)
232 3: stop_dq_dly = 3;
233 4: stop_dq_dly = 4;
234 5: stop_dq_dly = 6;
235 6: stop_dq_dly = 8;
236 7: stop_dq_dly = 10;
237 default: stop_dq_dly = cas_latency-1;
238 endcase
239
240 `ifdef IDT_FBDIMM
241 if (dq_dly == ((stop_dq_dly+3)*2) - 2) begin
242 `else
243 if (dq_dly == ((stop_dq_dly+3)*2) - 1) begin
244 `endif
245 inject_err_s1 <= 1'b1;
246 dq_dly <= 0;
247 error_st <= ST_REL;
248 end
249 else dq_dly <= dq_dly + 1;
250 end
251 ST_REL: begin
252 //$display ("%0d %m: Err injector state ST_REL\n", $time);
253 inject_err_s1 <= 1'b0;
254 error_st <= ST_RAS;
255 end
256 default: begin
257 $display ("%0d %m: Err injector entered unknown state\n", $time);
258 error_st <= ST_RAS;
259 end
260 endcase
261 end
262end
263
264assign dqs = |DRAM_DQS;
265reg [1:0] err_burst1;
266reg [1:0] err_burst2;
267
268always @(clk)
269begin
270 inject_err_s1_1 <= inject_err_s1;
271 inject_err_s1_2 <= inject_err_s1_1;
272 inject_err_s1_3 <= inject_err_s1_2;
273 inject_err_s1_4 <= inject_err_s1_3;
274 inject_err_s1_5 <= inject_err_s1_4;
275end
276
277always @ (posedge inject_err_s1)
278begin
279 err_burst1 = ($random() % 4);
280 inject_enable = 1'b1 << err_burst1;
281
282 if ($test$plusargs("TWO_ERROR_PER_BURST")) begin
283 err_burst2 = ($random() % 4);
284 if(err_burst2 != err_burst1)
285 inject_enable = inject_enable | (1'b1 << err_burst2);
286 else
287 inject_enable = inject_enable | (1'b1 << (err_burst2 + 1));
288 end
289 else if($test$plusargs("RANDOM_ERROR_PER_BURST"))
290 inject_enable = ($random() & 4'hf);
291
292 if(($test$plusargs("INJECT_ERR_ONCE")) && !inject_err_once)
293 inject_enable = 4'h0;
294
295 if($time < bcode_finish)
296 inject_enable = 4'b0;
297
298 @(posedge dqs);
299 inject_err_s3 = inject_enable[0];
300 inject_enable[0] = 1'b0;
301
302 @(negedge dqs);
303 inject_err_s3_d1 = inject_enable[1];
304 inject_enable[1] = 1'b0;
305 inject_err_s3 = 1'b0;
306
307 @(posedge dqs);
308 inject_err_s3_d2 = inject_enable[2];
309 inject_enable[2] = 1'b0;
310 inject_err_s3_d1 = 1'b0;
311
312 @(negedge dqs);
313 inject_err_s3_d3 = inject_enable[3];
314 inject_enable[3] = 1'b0;
315 inject_err_s3_d2 = 1'b0;
316
317 @(posedge dqs);
318 inject_err_s3_d3 = 1'b0;
319
320end
321
322/*
323always @ (posedge dqs)
324begin
325 inject_err_s3 = inject_enable[0];
326 inject_err_s3_d1 = 1'b0;
327 inject_err_s3_d2 = inject_enable[2];
328 inject_err_s3_d3 = 1'b0;
329end
330
331always @ (negedge dqs)
332begin
333 inject_err_s3 = 1'b0;
334 inject_err_s3_d1 = inject_enable[1];
335 inject_err_s3_d2 = 1'b0;
336 inject_err_s3_d3 = inject_enable[3];
337end
338*/
339
340/*
341always @(int_clk)
342begin
343 inject_err_s2 <= inject_err_s1;
344 inject_err_s2_d1 <= inject_err_s1_1;
345 inject_err_s2_d2 <= inject_err_s1_2;
346 inject_err_s2_d3 <= inject_err_s1_3;
347end
348
349always @ (posedge inject_err_s2 or
350 posedge inject_err_s2_d1 or
351 posedge inject_err_s2_d2 or
352 posedge inject_err_s2_d3 )
353begin
354 data = DRAM_DQ;
355 ecc = DRAM_CB;
356 inject_enable = #10 $random() & 4'hf;
357
358 if ($test$plusargs("ONE_ERROR_PER_BURST"))
359 inject_enable = 4'h1;
360 else if ($test$plusargs("TWO_ERROR_PER_BURST"))
361 inject_enable = 4'h5;
362
363 if(($test$plusargs("INJECT_ERR_ONCE")) && !inject_err_once)
364 inject_enable = 4'h0;
365
366 if($time < bcode_finish)
367 inject_enable = 4'b0;
368
369 inject_err_s3 <= (inject_enable[0] && inject_err_s2);
370 inject_err_s3_d1 <= (inject_enable[1] && inject_err_s2_d1);
371 inject_err_s3_d2 <= (inject_enable[2] && inject_err_s2_d2);
372 inject_err_s3_d3 <= (inject_enable[3] && inject_err_s2_d3);
373end
374
375always @ (negedge inject_err_s2)
376 inject_err_s3 = 1'b0;
377
378always @ (negedge inject_err_s2_d1)
379 inject_err_s3_d1 = 1'b0;
380
381always @ (negedge inject_err_s2_d2)
382 inject_err_s3_d2 = 1'b0;
383
384always @ (negedge inject_err_s2_d3)
385 inject_err_s3_d3 = 1'b0;
386
387
388always @ (posedge inject_err_s3_d3)
389 flip_for_mecc = !flip_for_mecc;
390*/
391
392
393reg [63:0] err_position;
394reg [63:0] err_position1;
395reg [1:0] err_type;
396
397always @ (posedge inject_err_s3 or
398 posedge inject_err_s3_d1 or
399 posedge inject_err_s3_d2 or
400 posedge inject_err_s3_d3)
401begin
402`ifdef IDT_FBDIMM
403data = DRAM_DQ;
404`else
405#310 data = DRAM_DQ;
406`endif
407 ecc = DRAM_CB;
408 inject_err_once <= 1'b0;
409
410 err_position = ($random % 63);
411 err_position1 = ($random % 63);
412
413
414 if(random_error == 1'b1) begin
415 err_type = ($random % 3);
416 if(err_type == 2'b0) begin
417 one_bit_data_err = 1'b0;
418 multi_bit_data_err = 1'b0;
419 end
420 else if(err_type == 2'b01) begin
421 one_bit_data_err = 1'b1;
422 multi_bit_data_err = 1'b0;
423 end
424 else if(err_type == 2'b10) begin
425 one_bit_data_err = 1'b0;
426 multi_bit_data_err = 1'b1;
427 end
428 end
429
430 if (one_bit_data_err) begin
431 $display ("%0d: Injecting 1 Bit error on data %x at bit %d\n", $time, data, err_position);
432 tmp = 64'b1 << err_position;
433 force DRAM_DQ = data ^ tmp;
434 dbg_secc_err_injected <= 1'b1;
435 $display ("%0d: Erred data is %x at bit %d\n", $time, (data ^ tmp), err_position);
436 end else if(multi_bit_data_err) begin
437 if((err_position / 4) == (err_position1 / 4)) begin
438 err_position1 = err_position1 + 4;
439 err_position1 = (err_position1 % 64);
440 end
441 $display ("%0d: Injecting Multi-bit error on data %x at bits %d and %d\n", $time, data, err_position, err_position1);
442 tmp = 64'b1 << err_position;
443 tmp = (tmp | (64'b1 << err_position1));
444 force DRAM_DQ = data ^ tmp;
445 dbg_mecc_err_injected <= 1'b1;
446 $display ("%0d: Erred data is %x, tmp = %x\n", $time, (data ^ tmp), tmp);
447 end
448
449 if (addr_parity_err) begin
450 $display ("%0d: Address parity inversion : Injecting error by inverting ecc %x \n", $time, ecc);
451 force DRAM_CB = ~ecc;
452 $display ("%0d: Erred ecc is %x\n", $time, ~ecc);
453 end
454
455 if(scrub_mecc_secc_err && multi_bit_data_err) begin
456 multi_bit_data_err = 1'b0;
457 one_bit_data_err = 1'b1;
458 end
459 else if(scrub_mecc_secc_err && one_bit_data_err) begin
460 multi_bit_data_err = 1'b0;
461 one_bit_data_err = 1'b0;
462 end
463 else if(scrub_mecc_secc_err)
464 multi_bit_data_err = 1'b1;
465
466 if(mecc_secc_err && multi_bit_data_err) begin
467 multi_bit_data_err = 1'b0;
468 one_bit_data_err = 1'b1;
469 end
470 else if(mecc_secc_err && one_bit_data_err) begin
471 multi_bit_data_err = 1'b0;
472 one_bit_data_err = 1'b0;
473 mecc_secc_err = 1'b0;
474 end
475
476 if(secc_mecc_err && one_bit_data_err) begin
477 multi_bit_data_err = 1'b1;
478 one_bit_data_err = 1'b0;
479 end
480 else if(secc_mecc_err && multi_bit_data_err) begin
481 multi_bit_data_err = 1'b0;
482 one_bit_data_err = 1'b0;
483 secc_mecc_err = 1'b0;
484 end
485
486
487
488
489
490
491 /* OLD N1 CODE; COMMENTED OUT BECAUSE IT DOESN'T WORK WELL WITH N2 -ncr
492 err_bits = $random() & 4'hf;
493 err_bits1 = $random() & 4'hf;
494 // If injecting error in each nibble
495 if ($test$plusargs("EACH_NIBBLE_ERROR")) begin
496 ecc_err_inject = (err_pos == 0) ? !ecc_err_inject : ecc_err_inject;
497 err_pos = (err_pos == 60) ? 0 : (((err_pos >> 2) + 1)*4);
498 err_pos1 = (err_pos1 == 60) ? 0 : (err_pos == 60) ? (((err_pos1 >> 2) + 1)*4) : err_pos1;
499 end else begin
500 ecc_err_inject = $random() & 1'b1;
501 err_pos = ($random() & 5'h1f) * 4;
502 err_pos1 = ($random() & 5'h1f) * 4;
503 end
504
505 // *** Commented out for now ********
506// if (dram_enb_error && DRAM_FAIL_OVER) begin
507// force DRAM_DQ = data ^ ((err_bits << err_pos) | (4'hf << (DRAM_FAIL_PART * 4)));
508// $display ("%0d: Injecting Err on data %x at bit %d\n", $time, data, err_pos);
509// end
510// *****************************************
511
512 if (dram_enb_error) begin
513 if ($test$plusargs("ONLY_ONE_MECC_SECC")) begin
514 if (addr_parity_err && !disable_mecc) begin
515 force DRAM_CB = ~ecc;
516 $display ("%0d: Address parity inversion : Injecting Err by inverting ecc %x \n", $time, ecc);
517 disable_mecc = 1;
518 end else begin
519 if(!disable_secc) begin
520 disable_secc = 1;
521 force DRAM_DQ = data ^ (err_bits << err_pos);
522 $display ("%0d: Injecting Err on data %x at bit %d\n", $time, data, err_pos);
523 end
524 end
525 end else
526 if ($test$plusargs("ONLY_ONE_SECC_MECC")) begin
527 if(!disable_secc) begin
528 disable_secc = 1;
529 force DRAM_DQ = data ^ (err_bits << err_pos);
530 $display ("%0d: Injecting Err on data %x at bit %d\n", $time, data, err_pos);
531 end else begin
532 if (addr_parity_err && !disable_mecc) begin
533 force DRAM_CB = ~ecc;
534 $display ("%0d: Address parity inversion : Injecting Err by inverting ecc %x \n", $time, ecc);
535 disable_mecc = 1;
536 end
537 end
538 end else
539 if ($test$plusargs("SYNDROME_TEST")) begin
540 synd_err_pos = (synd_err_pos1 & 5'h1f) * 4;
541 if(!synd_ecc_err_inject) begin // this is a random number so inject data or ecc errors randomly
542 force DRAM_DQ = data ^ (synd_err_bits << synd_err_pos);
543 $display ("%0d: Injecting Err on data %x at bit %d\n", $time, data, synd_err_pos);
544 $display ("%0d: Erred data %x at synd_err_pos %x with synd_err_bits %x\n", $time, DRAM_DQ, synd_err_pos,synd_err_bits);
545 end else begin
546 force DRAM_CB = ecc ^ (synd_err_bits << synd_err_pos[3:0]);
547 $display ("%0d: Injecting Err on ecc %x at bit %d\n", $time, ecc, synd_err_pos[3:0]);
548 $display ("%0d: Erred ecc %x at synd_err_pos %x with synd_err_bits %x\n", $time, DRAM_CB, synd_err_pos[3:0],synd_err_bits);
549 end
550 end else begin
551 // This is normal error injection
552 if (addr_parity_err) begin
553 force DRAM_CB = ~ecc;
554 $display ("%0d: Address parity inversion : Injecting Err by inverting ecc %x \n", $time, ecc);
555 end else begin
556 if (enb_mecc_error ) begin
557 // MECC is multiple errors in different chunks for data
558 force DRAM_DQ = (data ^ (err_bits << err_pos) ^ (err_bits1 << err_pos1) );
559 $display ("%0d: Injecting Err on data %x at bit %d %d\n", $time, data, err_pos,err_pos1);
560 end else
561 if(!ecc_err_inject) begin // this is a random number so inject data or ecc errors randomly
562 force DRAM_DQ = data ^ (err_bits << err_pos);
563 $display ("%0d: Injecting Err on data %x at bit %d\n", $time, data, err_pos);
564 $display ("%0d: Erred data %x at err_pos %x with err_bits %x\n", $time, DRAM_DQ, err_pos,err_bits);
565 end else begin
566 force DRAM_CB = ecc ^ (err_bits << err_pos[3:0]);
567 $display ("%0d: Injecting Err on ecc %x at bit %d\n", $time, ecc, err_pos[3:0]);
568 $display ("%0d: Erred ecc %x at err_pos %x with err_bits %x\n", $time, DRAM_CB, err_pos[3:0],err_bits);
569 end
570 end
571 end
572 end
573 // *********** Comment out for now *****************
574// else if (DRAM_FAIL_OVER)
575// force tb_top.mcusat_fbdimm.fbdimm_mem0.fbdimm0.fbdimm_DIMMx4.dq[63:0] = data ^ (4'hf << (DRAM_FAIL_PART * 4));
576// **************************************************
577 else
578 force DRAM_DQ = data;
579 */
580end //always
581
582
583 //always @ (negedge inject_err_s3 or negedge inject_err_s3_d1 or negedge inject_err_s3_d2 or negedge inject_err_s3_d3) begin
584 always @ ( DRAM_CB ) begin
585 release DRAM_DQ;
586 release DRAM_CB;
587 end
588
589endmodule