1 /******************************************************************************
3 * (c) Copyright 2009 Xilinx, Inc. All rights reserved.
5 * This file contains confidential and proprietary information of Xilinx, Inc.
6 * and is protected under U.S. and international copyright and other
7 * intellectual property laws.
10 * This disclaimer is not a license and does not grant any rights to the
11 * materials distributed herewith. Except as otherwise provided in a valid
12 * license issued to you by Xilinx, and to the maximum extent permitted by
13 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 * and (2) Xilinx shall not be liable (whether in contract or tort, including
18 * negligence, or under any other theory of liability) for any loss or damage
19 * of any kind or nature related to, arising under or in connection with these
20 * materials, including for any direct, or any indirect, special, incidental,
21 * or consequential loss or damage (including loss of data, profits, goodwill,
22 * or any type of loss or damage suffered as a result of any action brought by
23 * a third party) even if such damage or loss was reasonably foreseeable or
24 * Xilinx had been advised of the possibility of the same.
26 * CRITICAL APPLICATIONS
27 * Xilinx products are not designed or intended to be fail-safe, or for use in
28 * any application requiring fail-safe performance, such as life-support or
29 * safety devices or systems, Class III medical devices, nuclear facilities,
30 * applications related to the deployment of airbags, or any other applications
31 * that could lead to death, personal injury, or severe property or
32 * environmental damage (individually and collectively, "Critical
33 * Applications"). Customer assumes the sole risk and liability of any use of
34 * Xilinx products in Critical Applications, subject only to applicable laws
35 * and regulations governing limitations on product liability.
37 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
41 ******************************************************************************/
42 /*****************************************************************************/
47 * Contains the memory test utility functions.
50 * MODIFICATION HISTORY:
52 * Ver Who Date Changes
53 * ----- ---- -------- -----------------------------------------------
54 * 1.00a hbm 08/25/09 First release
57 *****************************************************************************/
59 /***************************** Include Files ********************************/
60 #include "xil_testmem.h"
62 #include "xil_assert.h"
64 /************************** Constant Definitions ****************************/
65 /************************** Function Prototypes *****************************/
67 static u32 RotateLeft(u32 Input, u8 Width);
69 /* define ROTATE_RIGHT to give access to this functionality */
70 /* #define ROTATE_RIGHT */
72 static u32 RotateRight(u32 Input, u8 Width);
73 #endif /* ROTATE_RIGHT */
76 /*****************************************************************************/
79 * Perform a destructive 32-bit wide memory test.
81 * @param Addr is a pointer to the region of memory to be tested.
82 * @param Words is the length of the block.
83 * @param Pattern is the constant used for the constant pattern test, if 0,
85 * @param Subtest is the test selected. See xil_testmem.h for possible
90 * - 0 is returned for a pass
91 * - -1 is returned for a failure
95 * Used for spaces where the address range of the region is smaller than
96 * the data width. If the memory range is greater than 2 ** Width,
97 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
98 * repeat on a boundry of a power of two making it more difficult to detect
99 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
100 * tests suffer the same problem. Ideally, if large blocks of memory are to be
101 * tested, break them up into smaller regions of memory to allow the test
102 * patterns used not to repeat over the region tested.
104 *****************************************************************************/
105 int Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest)
113 Xil_AssertNonvoid(Words != 0);
114 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
117 * variable initialization
119 Val = XIL_TESTMEM_INIT_VALUE;
120 FirtVal = XIL_TESTMEM_INIT_VALUE;
123 * Select the proper Subtest
127 case XIL_TESTMEM_ALLMEMTESTS:
129 /* this case executes all of the Subtests */
131 /* fall through case statement */
133 case XIL_TESTMEM_INCREMENT:
136 * Fill the memory with incrementing
137 * values starting from 'FirtVal'
139 for (I = 0L; I < Words; I++) {
145 * Restore the reference 'Val' to the
151 * Check every word within the words
152 * of tested memory and compare it
153 * with the incrementing reference
157 for (I = 0L; I < Words; I++) {
168 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
175 /* fall through case statement */
177 case XIL_TESTMEM_WALKONES:
179 * set up to cycle through all possible initial
180 * test Patterns for walking ones test
183 for (J = 0L; J < 32; J++) {
185 * Generate an initial value for walking ones test
186 * to test for bad data bits
192 * START walking ones test
193 * Write a one to each data bit indifferent locations
196 for (I = 0L; I < 32; I++) {
197 /* write memory location */
199 Val = (u32) RotateLeft(Val, 32);
203 * Restore the reference 'val' to the
208 /* Read the values from each location that was
210 for (I = 0L; I < 32; I++) {
211 /* read memory location */
219 Val = (u32)RotateLeft(Val, 32);
224 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
229 /* fall through case statement */
231 case XIL_TESTMEM_WALKZEROS:
233 * set up to cycle through all possible
234 * initial test Patterns for walking zeros test
237 for (J = 0L; J < 32; J++) {
240 * Generate an initial value for walking ones test
241 * to test for bad data bits
247 * START walking zeros test
248 * Write a one to each data bit indifferent locations
251 for (I = 0L; I < 32; I++) {
252 /* write memory location */
254 Val = ~((u32)RotateLeft(~Val, 32));
258 * Restore the reference 'Val' to the
264 /* Read the values from each location that was
266 for (I = 0L; I < 32; I++) {
267 /* read memory location */
272 Val = ~((u32)RotateLeft(~Val, 32));
277 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
283 /* fall through case statement */
285 case XIL_TESTMEM_INVERSEADDR:
286 /* Fill the memory with inverse of address */
287 for (I = 0L; I < Words; I++) {
288 /* write memory location */
289 Val = (u32) (~((u32) (&Addr[I])));
294 * Check every word within the words
298 for (I = 0L; I < Words; I++) {
299 /* Read the location */
301 Val = (u32) (~((u32) (&Addr[I])));
303 if ((Word ^ Val) != 0x00000000) {
308 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
313 /* fall through case statement */
315 case XIL_TESTMEM_FIXEDPATTERN:
317 * Generate an initial value for
329 * Fill the memory with fixed Pattern
332 for (I = 0L; I < Words; I++) {
333 /* write memory location */
338 * Check every word within the words
339 * of tested memory and compare it
340 * with the fixed Pattern
343 for (I = 0L; I < Words; I++) {
345 /* read memory location */
353 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
358 /* this break is for the prior fall through case statements */
365 } /* end of switch */
367 /* Successfully passed memory test ! */
372 /*****************************************************************************/
375 * Perform a destructive 16-bit wide memory test.
377 * @param Addr is a pointer to the region of memory to be tested.
378 * @param Words is the length of the block.
379 * @param Pattern is the constant used for the constant Pattern test, if 0,
380 * 0xDEADBEEF is used.
381 * @param Subtest is the test selected. See xil_testmem.h for possible
386 * - -1 is returned for a failure
387 * - 0 is returned for a pass
391 * Used for spaces where the address range of the region is smaller than
392 * the data width. If the memory range is greater than 2 ** Width,
393 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
394 * repeat on a boundry of a power of two making it more difficult to detect
395 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
396 * tests suffer the same problem. Ideally, if large blocks of memory are to be
397 * tested, break them up into smaller regions of memory to allow the test
398 * patterns used not to repeat over the region tested.
400 *****************************************************************************/
401 int Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest)
409 Xil_AssertNonvoid(Words != 0);
410 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
413 * variable initialization
415 Val = XIL_TESTMEM_INIT_VALUE;
416 FirtVal = XIL_TESTMEM_INIT_VALUE;
419 * selectthe proper Subtest(s)
424 case XIL_TESTMEM_ALLMEMTESTS:
426 /* this case executes all of the Subtests */
428 /* fall through case statement */
430 case XIL_TESTMEM_INCREMENT:
432 * Fill the memory with incrementing
433 * values starting from 'FirtVal'
435 for (I = 0L; I < Words; I++) {
436 /* write memory location */
441 * Restore the reference 'Val' to the
447 * Check every word within the words
448 * of tested memory and compare it
449 * with the incrementing reference val
452 for (I = 0L; I < Words; I++) {
453 /* read memory location */
460 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
465 /* fall through case statement */
467 case XIL_TESTMEM_WALKONES:
469 * set up to cycle through all possible initial test
470 * Patterns for walking ones test
473 for (J = 0L; J < 16; J++) {
475 * Generate an initial value for walking ones test
476 * to test for bad data bits
481 * START walking ones test
482 * Write a one to each data bit indifferent locations
485 for (I = 0L; I < 16; I++) {
486 /* write memory location */
488 Val = (u16)RotateLeft(Val, 16);
491 * Restore the reference 'Val' to the
495 /* Read the values from each location that was written */
496 for (I = 0L; I < 16; I++) {
497 /* read memory location */
502 Val = (u16)RotateLeft(Val, 16);
506 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
510 /* fall through case statement */
512 case XIL_TESTMEM_WALKZEROS:
514 * set up to cycle through all possible initial
515 * test Patterns for walking zeros test
518 for (J = 0L; J < 16; J++) {
520 * Generate an initial value for walking ones
521 * test to test for bad
527 * START walking zeros test
528 * Write a one to each data bit indifferent locations
531 for (I = 0L; I < 16; I++) {
532 /* write memory location */
534 Val = ~((u16)RotateLeft(~Val, 16));
537 * Restore the reference 'Val' to the
541 /* Read the values from each location that was written */
542 for (I = 0L; I < 16; I++) {
543 /* read memory location */
548 Val = ~((u16)RotateLeft(~Val, 16));
552 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
556 /* fall through case statement */
558 case XIL_TESTMEM_INVERSEADDR:
559 /* Fill the memory with inverse of address */
560 for (I = 0L; I < Words; I++) {
561 /* write memory location */
562 Val = (u16) (~((u32) (&Addr[I])));
566 * Check every word within the words
570 for (I = 0L; I < Words; I++) {
571 /* read memory location */
573 Val = (u16) (~((u32) (&Addr[I])));
574 if ((Word ^ Val) != 0x0000) {
578 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
582 /* fall through case statement */
584 case XIL_TESTMEM_FIXEDPATTERN:
586 * Generate an initial value for
597 * Fill the memory with fixed pattern
600 for (I = 0L; I < Words; I++) {
601 /* write memory location */
606 * Check every word within the words
607 * of tested memory and compare it
608 * with the fixed pattern
611 for (I = 0L; I < Words; I++) {
612 /* read memory location */
618 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
622 /* this break is for the prior fall through case statements */
629 } /* end of switch */
631 /* Successfully passed memory test ! */
637 /*****************************************************************************/
640 * Perform a destructive 8-bit wide memory test.
642 * @param Addr is a pointer to the region of memory to be tested.
643 * @param Words is the length of the block.
644 * @param Pattern is the constant used for the constant pattern test, if 0,
645 * 0xDEADBEEF is used.
646 * @param Subtest is the test selected. See xil_testmem.h for possible
651 * - -1 is returned for a failure
652 * - 0 is returned for a pass
656 * Used for spaces where the address range of the region is smaller than
657 * the data width. If the memory range is greater than 2 ** Width,
658 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
659 * repeat on a boundry of a power of two making it more difficult to detect
660 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
661 * tests suffer the same problem. Ideally, if large blocks of memory are to be
662 * tested, break them up into smaller regions of memory to allow the test
663 * patterns used not to repeat over the region tested.
665 *****************************************************************************/
666 int Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest)
674 Xil_AssertNonvoid(Words != 0);
675 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
678 * variable initialization
680 Val = XIL_TESTMEM_INIT_VALUE;
681 FirtVal = XIL_TESTMEM_INIT_VALUE;
684 * select the proper Subtest(s)
689 case XIL_TESTMEM_ALLMEMTESTS:
690 /* this case executes all of the Subtests */
691 /* fall through case statement */
693 case XIL_TESTMEM_INCREMENT:
695 * Fill the memory with incrementing
696 * values starting from 'FirtVal'
698 for (I = 0L; I < Words; I++) {
699 /* write memory location */
704 * Restore the reference 'Val' to the
709 * Check every word within the words
710 * of tested memory and compare it
711 * with the incrementing reference
715 for (I = 0L; I < Words; I++) {
716 /* read memory location */
724 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
729 /* fall through case statement */
731 case XIL_TESTMEM_WALKONES:
733 * set up to cycle through all possible initial
734 * test Patterns for walking ones test
737 for (J = 0L; J < 8; J++) {
739 * Generate an initial value for walking ones test
740 * to test for bad data bits
744 * START walking ones test
745 * Write a one to each data bit indifferent locations
747 for (I = 0L; I < 8; I++) {
748 /* write memory location */
750 Val = (u8)RotateLeft(Val, 8);
753 * Restore the reference 'Val' to the
757 /* Read the values from each location that was written */
758 for (I = 0L; I < 8; I++) {
759 /* read memory location */
764 Val = (u8)RotateLeft(Val, 8);
768 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
772 /* fall through case statement */
774 case XIL_TESTMEM_WALKZEROS:
776 * set up to cycle through all possible initial test
777 * Patterns for walking zeros test
780 for (J = 0L; J < 8; J++) {
782 * Generate an initial value for walking ones test to test
787 * START walking zeros test
788 * Write a one to each data bit indifferent locations
790 for (I = 0L; I < 8; I++) {
791 /* write memory location */
793 Val = ~((u8)RotateLeft(~Val, 8));
796 * Restore the reference 'Val' to the
800 /* Read the values from each location that was written */
801 for (I = 0L; I < 8; I++) {
802 /* read memory location */
808 Val = ~((u8)RotateLeft(~Val, 8));
812 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
816 /* fall through case statement */
818 case XIL_TESTMEM_INVERSEADDR:
819 /* Fill the memory with inverse of address */
820 for (I = 0L; I < Words; I++) {
821 /* write memory location */
822 Val = (u8) (~((u32) (&Addr[I])));
827 * Check every word within the words
831 for (I = 0L; I < Words; I++) {
832 /* read memory location */
834 Val = (u8) (~((u32) (&Addr[I])));
835 if ((Word ^ Val) != 0x00) {
839 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
843 /* fall through case statement */
845 case XIL_TESTMEM_FIXEDPATTERN:
847 * Generate an initial value for
858 * Fill the memory with fixed Pattern
860 for (I = 0L; I < Words; I++) {
861 /* write memory location */
865 * Check every word within the words
866 * of tested memory and compare it
867 * with the fixed Pattern
870 for (I = 0L; I < Words; I++) {
871 /* read memory location */
878 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
884 /* this break is for the prior fall through case statements */
891 } /* end of switch */
893 /* Successfully passed memory test ! */
899 /*****************************************************************************/
902 * Rotates the provided value to the left one bit position
904 * @param Input is value to be rotated to the left
905 * @param Width is the number of bits in the input data
909 * The resulting unsigned long value of the rotate left
915 *****************************************************************************/
916 static u32 RotateLeft(u32 Input, u8 Width)
924 * set up the WidthMask and the MsbMask
927 MsbMask = 1 << (Width - 1);
929 WidthMask = (MsbMask << 1) - 1;
932 * set the Width of the Input to the correct width
935 Input = Input & WidthMask;
937 Msb = Input & MsbMask;
939 ReturnVal = Input << 1;
941 if (Msb != 0x00000000) {
942 ReturnVal = ReturnVal | 0x00000001;
945 ReturnVal = ReturnVal & WidthMask;
952 /*****************************************************************************/
955 * Rotates the provided value to the right one bit position
957 * @param Input is value to be rotated to the right
958 * @param Width is the number of bits in the input data
962 * The resulting u32 value of the rotate right
968 *****************************************************************************/
969 static u32 RotateRight(u32 Input, u8 Width)
977 * set up the WidthMask and the MsbMask
980 MsbMask = 1 << (Width - 1);
982 WidthMask = (MsbMask << 1) - 1;
985 * set the width of the input to the correct width
988 Input = Input & WidthMask;
990 ReturnVal = Input >> 1;
992 Lsb = Input & 0x00000001;
994 if (Lsb != 0x00000000) {
995 ReturnVal = ReturnVal | MsbMask;
998 ReturnVal = ReturnVal & WidthMask;
1003 #endif /* ROTATE_RIGHT */