1 /******************************************************************************
3 * Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
37 * Contains the memory test utility functions.
40 * MODIFICATION HISTORY:
42 * Ver Who Date Changes
43 * ----- ---- -------- -----------------------------------------------
44 * 1.00a hbm 08/25/09 First release
47 *****************************************************************************/
49 /***************************** Include Files ********************************/
50 #include "xil_testmem.h"
52 #include "xil_assert.h"
54 /************************** Constant Definitions ****************************/
55 /************************** Function Prototypes *****************************/
57 static u32 RotateLeft(u32 Input, u8 Width);
59 /* define ROTATE_RIGHT to give access to this functionality */
60 /* #define ROTATE_RIGHT */
62 static u32 RotateRight(u32 Input, u8 Width);
63 #endif /* ROTATE_RIGHT */
66 /*****************************************************************************/
69 * Perform a destructive 32-bit wide memory test.
71 * @param Addr is a pointer to the region of memory to be tested.
72 * @param Words is the length of the block.
73 * @param Pattern is the constant used for the constant pattern test, if 0,
75 * @param Subtest is the test selected. See xil_testmem.h for possible
80 * - 0 is returned for a pass
81 * - -1 is returned for a failure
85 * Used for spaces where the address range of the region is smaller than
86 * the data width. If the memory range is greater than 2 ** Width,
87 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
88 * repeat on a boundry of a power of two making it more difficult to detect
89 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
90 * tests suffer the same problem. Ideally, if large blocks of memory are to be
91 * tested, break them up into smaller regions of memory to allow the test
92 * patterns used not to repeat over the region tested.
94 *****************************************************************************/
95 int Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest)
103 Xil_AssertNonvoid(Words != 0);
104 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
107 * variable initialization
109 Val = XIL_TESTMEM_INIT_VALUE;
110 FirtVal = XIL_TESTMEM_INIT_VALUE;
113 * Select the proper Subtest
117 case XIL_TESTMEM_ALLMEMTESTS:
119 /* this case executes all of the Subtests */
121 /* fall through case statement */
123 case XIL_TESTMEM_INCREMENT:
126 * Fill the memory with incrementing
127 * values starting from 'FirtVal'
129 for (I = 0L; I < Words; I++) {
135 * Restore the reference 'Val' to the
141 * Check every word within the words
142 * of tested memory and compare it
143 * with the incrementing reference
147 for (I = 0L; I < Words; I++) {
158 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
165 /* fall through case statement */
167 case XIL_TESTMEM_WALKONES:
169 * set up to cycle through all possible initial
170 * test Patterns for walking ones test
173 for (J = 0L; J < 32; J++) {
175 * Generate an initial value for walking ones test
176 * to test for bad data bits
182 * START walking ones test
183 * Write a one to each data bit indifferent locations
186 for (I = 0L; I < 32; I++) {
187 /* write memory location */
189 Val = (u32) RotateLeft(Val, 32);
193 * Restore the reference 'val' to the
198 /* Read the values from each location that was
200 for (I = 0L; I < 32; I++) {
201 /* read memory location */
209 Val = (u32)RotateLeft(Val, 32);
214 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
219 /* fall through case statement */
221 case XIL_TESTMEM_WALKZEROS:
223 * set up to cycle through all possible
224 * initial test Patterns for walking zeros test
227 for (J = 0L; J < 32; J++) {
230 * Generate an initial value for walking ones test
231 * to test for bad data bits
237 * START walking zeros test
238 * Write a one to each data bit indifferent locations
241 for (I = 0L; I < 32; I++) {
242 /* write memory location */
244 Val = ~((u32)RotateLeft(~Val, 32));
248 * Restore the reference 'Val' to the
254 /* Read the values from each location that was
256 for (I = 0L; I < 32; I++) {
257 /* read memory location */
262 Val = ~((u32)RotateLeft(~Val, 32));
267 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
273 /* fall through case statement */
275 case XIL_TESTMEM_INVERSEADDR:
276 /* Fill the memory with inverse of address */
277 for (I = 0L; I < Words; I++) {
278 /* write memory location */
279 Val = (u32) (~((u32) (&Addr[I])));
284 * Check every word within the words
288 for (I = 0L; I < Words; I++) {
289 /* Read the location */
291 Val = (u32) (~((u32) (&Addr[I])));
293 if ((Word ^ Val) != 0x00000000) {
298 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
303 /* fall through case statement */
305 case XIL_TESTMEM_FIXEDPATTERN:
307 * Generate an initial value for
319 * Fill the memory with fixed Pattern
322 for (I = 0L; I < Words; I++) {
323 /* write memory location */
328 * Check every word within the words
329 * of tested memory and compare it
330 * with the fixed Pattern
333 for (I = 0L; I < Words; I++) {
335 /* read memory location */
343 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
348 /* this break is for the prior fall through case statements */
355 } /* end of switch */
357 /* Successfully passed memory test ! */
362 /*****************************************************************************/
365 * Perform a destructive 16-bit wide memory test.
367 * @param Addr is a pointer to the region of memory to be tested.
368 * @param Words is the length of the block.
369 * @param Pattern is the constant used for the constant Pattern test, if 0,
370 * 0xDEADBEEF is used.
371 * @param Subtest is the test selected. See xil_testmem.h for possible
376 * - -1 is returned for a failure
377 * - 0 is returned for a pass
381 * Used for spaces where the address range of the region is smaller than
382 * the data width. If the memory range is greater than 2 ** Width,
383 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
384 * repeat on a boundry of a power of two making it more difficult to detect
385 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
386 * tests suffer the same problem. Ideally, if large blocks of memory are to be
387 * tested, break them up into smaller regions of memory to allow the test
388 * patterns used not to repeat over the region tested.
390 *****************************************************************************/
391 int Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest)
399 Xil_AssertNonvoid(Words != 0);
400 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
403 * variable initialization
405 Val = XIL_TESTMEM_INIT_VALUE;
406 FirtVal = XIL_TESTMEM_INIT_VALUE;
409 * selectthe proper Subtest(s)
414 case XIL_TESTMEM_ALLMEMTESTS:
416 /* this case executes all of the Subtests */
418 /* fall through case statement */
420 case XIL_TESTMEM_INCREMENT:
422 * Fill the memory with incrementing
423 * values starting from 'FirtVal'
425 for (I = 0L; I < Words; I++) {
426 /* write memory location */
431 * Restore the reference 'Val' to the
437 * Check every word within the words
438 * of tested memory and compare it
439 * with the incrementing reference val
442 for (I = 0L; I < Words; I++) {
443 /* read memory location */
450 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
455 /* fall through case statement */
457 case XIL_TESTMEM_WALKONES:
459 * set up to cycle through all possible initial test
460 * Patterns for walking ones test
463 for (J = 0L; J < 16; J++) {
465 * Generate an initial value for walking ones test
466 * to test for bad data bits
471 * START walking ones test
472 * Write a one to each data bit indifferent locations
475 for (I = 0L; I < 16; I++) {
476 /* write memory location */
478 Val = (u16)RotateLeft(Val, 16);
481 * Restore the reference 'Val' to the
485 /* Read the values from each location that was written */
486 for (I = 0L; I < 16; I++) {
487 /* read memory location */
492 Val = (u16)RotateLeft(Val, 16);
496 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
500 /* fall through case statement */
502 case XIL_TESTMEM_WALKZEROS:
504 * set up to cycle through all possible initial
505 * test Patterns for walking zeros test
508 for (J = 0L; J < 16; J++) {
510 * Generate an initial value for walking ones
511 * test to test for bad
517 * START walking zeros test
518 * Write a one to each data bit indifferent locations
521 for (I = 0L; I < 16; I++) {
522 /* write memory location */
524 Val = ~((u16)RotateLeft(~Val, 16));
527 * Restore the reference 'Val' to the
531 /* Read the values from each location that was written */
532 for (I = 0L; I < 16; I++) {
533 /* read memory location */
538 Val = ~((u16)RotateLeft(~Val, 16));
542 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
546 /* fall through case statement */
548 case XIL_TESTMEM_INVERSEADDR:
549 /* Fill the memory with inverse of address */
550 for (I = 0L; I < Words; I++) {
551 /* write memory location */
552 Val = (u16) (~((u32) (&Addr[I])));
556 * Check every word within the words
560 for (I = 0L; I < Words; I++) {
561 /* read memory location */
563 Val = (u16) (~((u32) (&Addr[I])));
564 if ((Word ^ Val) != 0x0000) {
568 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
572 /* fall through case statement */
574 case XIL_TESTMEM_FIXEDPATTERN:
576 * Generate an initial value for
587 * Fill the memory with fixed pattern
590 for (I = 0L; I < Words; I++) {
591 /* write memory location */
596 * Check every word within the words
597 * of tested memory and compare it
598 * with the fixed pattern
601 for (I = 0L; I < Words; I++) {
602 /* read memory location */
608 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
612 /* this break is for the prior fall through case statements */
619 } /* end of switch */
621 /* Successfully passed memory test ! */
627 /*****************************************************************************/
630 * Perform a destructive 8-bit wide memory test.
632 * @param Addr is a pointer to the region of memory to be tested.
633 * @param Words is the length of the block.
634 * @param Pattern is the constant used for the constant pattern test, if 0,
635 * 0xDEADBEEF is used.
636 * @param Subtest is the test selected. See xil_testmem.h for possible
641 * - -1 is returned for a failure
642 * - 0 is returned for a pass
646 * Used for spaces where the address range of the region is smaller than
647 * the data width. If the memory range is greater than 2 ** Width,
648 * the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
649 * repeat on a boundry of a power of two making it more difficult to detect
650 * addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
651 * tests suffer the same problem. Ideally, if large blocks of memory are to be
652 * tested, break them up into smaller regions of memory to allow the test
653 * patterns used not to repeat over the region tested.
655 *****************************************************************************/
656 int Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest)
664 Xil_AssertNonvoid(Words != 0);
665 Xil_AssertNonvoid(Subtest <= XIL_TESTMEM_MAXTEST);
668 * variable initialization
670 Val = XIL_TESTMEM_INIT_VALUE;
671 FirtVal = XIL_TESTMEM_INIT_VALUE;
674 * select the proper Subtest(s)
679 case XIL_TESTMEM_ALLMEMTESTS:
680 /* this case executes all of the Subtests */
681 /* fall through case statement */
683 case XIL_TESTMEM_INCREMENT:
685 * Fill the memory with incrementing
686 * values starting from 'FirtVal'
688 for (I = 0L; I < Words; I++) {
689 /* write memory location */
694 * Restore the reference 'Val' to the
699 * Check every word within the words
700 * of tested memory and compare it
701 * with the incrementing reference
705 for (I = 0L; I < Words; I++) {
706 /* read memory location */
714 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
719 /* fall through case statement */
721 case XIL_TESTMEM_WALKONES:
723 * set up to cycle through all possible initial
724 * test Patterns for walking ones test
727 for (J = 0L; J < 8; J++) {
729 * Generate an initial value for walking ones test
730 * to test for bad data bits
734 * START walking ones test
735 * Write a one to each data bit indifferent locations
737 for (I = 0L; I < 8; I++) {
738 /* write memory location */
740 Val = (u8)RotateLeft(Val, 8);
743 * Restore the reference 'Val' to the
747 /* Read the values from each location that was written */
748 for (I = 0L; I < 8; I++) {
749 /* read memory location */
754 Val = (u8)RotateLeft(Val, 8);
758 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
762 /* fall through case statement */
764 case XIL_TESTMEM_WALKZEROS:
766 * set up to cycle through all possible initial test
767 * Patterns for walking zeros test
770 for (J = 0L; J < 8; J++) {
772 * Generate an initial value for walking ones test to test
777 * START walking zeros test
778 * Write a one to each data bit indifferent locations
780 for (I = 0L; I < 8; I++) {
781 /* write memory location */
783 Val = ~((u8)RotateLeft(~Val, 8));
786 * Restore the reference 'Val' to the
790 /* Read the values from each location that was written */
791 for (I = 0L; I < 8; I++) {
792 /* read memory location */
798 Val = ~((u8)RotateLeft(~Val, 8));
802 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
806 /* fall through case statement */
808 case XIL_TESTMEM_INVERSEADDR:
809 /* Fill the memory with inverse of address */
810 for (I = 0L; I < Words; I++) {
811 /* write memory location */
812 Val = (u8) (~((u32) (&Addr[I])));
817 * Check every word within the words
821 for (I = 0L; I < Words; I++) {
822 /* read memory location */
824 Val = (u8) (~((u32) (&Addr[I])));
825 if ((Word ^ Val) != 0x00) {
829 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
833 /* fall through case statement */
835 case XIL_TESTMEM_FIXEDPATTERN:
837 * Generate an initial value for
848 * Fill the memory with fixed Pattern
850 for (I = 0L; I < Words; I++) {
851 /* write memory location */
855 * Check every word within the words
856 * of tested memory and compare it
857 * with the fixed Pattern
860 for (I = 0L; I < Words; I++) {
861 /* read memory location */
868 if (Subtest != XIL_TESTMEM_ALLMEMTESTS) {
874 /* this break is for the prior fall through case statements */
881 } /* end of switch */
883 /* Successfully passed memory test ! */
889 /*****************************************************************************/
892 * Rotates the provided value to the left one bit position
894 * @param Input is value to be rotated to the left
895 * @param Width is the number of bits in the input data
899 * The resulting unsigned long value of the rotate left
905 *****************************************************************************/
906 static u32 RotateLeft(u32 Input, u8 Width)
914 * set up the WidthMask and the MsbMask
917 MsbMask = 1 << (Width - 1);
919 WidthMask = (MsbMask << 1) - 1;
922 * set the Width of the Input to the correct width
925 Input = Input & WidthMask;
927 Msb = Input & MsbMask;
929 ReturnVal = Input << 1;
931 if (Msb != 0x00000000) {
932 ReturnVal = ReturnVal | 0x00000001;
935 ReturnVal = ReturnVal & WidthMask;
942 /*****************************************************************************/
945 * Rotates the provided value to the right one bit position
947 * @param Input is value to be rotated to the right
948 * @param Width is the number of bits in the input data
952 * The resulting u32 value of the rotate right
958 *****************************************************************************/
959 static u32 RotateRight(u32 Input, u8 Width)
967 * set up the WidthMask and the MsbMask
970 MsbMask = 1 << (Width - 1);
972 WidthMask = (MsbMask << 1) - 1;
975 * set the width of the input to the correct width
978 Input = Input & WidthMask;
980 ReturnVal = Input >> 1;
982 Lsb = Input & 0x00000001;
984 if (Lsb != 0x00000000) {
985 ReturnVal = ReturnVal | MsbMask;
988 ReturnVal = ReturnVal & WidthMask;
993 #endif /* ROTATE_RIGHT */