aboutsummaryrefslogtreecommitdiff
path: root/sw/test-adder/test-adder.c
diff options
context:
space:
mode:
Diffstat (limited to 'sw/test-adder/test-adder.c')
-rw-r--r--sw/test-adder/test-adder.c339
1 files changed, 188 insertions, 151 deletions
diff --git a/sw/test-adder/test-adder.c b/sw/test-adder/test-adder.c
index 70415d8..88d4353 100644
--- a/sw/test-adder/test-adder.c
+++ b/sw/test-adder/test-adder.c
@@ -1,6 +1,38 @@
-//------------------------------------------------------------------------------
-// setup-eim.c
-//------------------------------------------------------------------------------
+/*
+ * test-adder.c
+ * ------------
+ * This program tests the Novena EIM interface by repeatedly writing
+ * two 32-bit values to the FPGA, and reading back the sum.
+ *
+ * Author: Pavel Shatov
+ * Copyright (c) 2015, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
//------------------------------------------------------------------------------
@@ -14,70 +46,74 @@
//------------------------------------------------------------------------------
// Demo Adder
//------------------------------------------------------------------------------
-#define DEMO_ADDER_BASE_ADDR (0x3210)
-#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2))
-#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2))
-#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2))
-#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2))
+#define DEMO_ADDER_BASE_ADDR (0x3210)
+#define DEMO_ADDER_REG_X (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (0<<2))
+#define DEMO_ADDER_REG_Y (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (1<<2))
+#define DEMO_ADDER_REG_Z (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (2<<2))
+#define DEMO_ADDER_REG_SC (EIM_BASE_ADDR + DEMO_ADDER_BASE_ADDR + (3<<2))
//------------------------------------------------------------------------------
// Prototypes
//------------------------------------------------------------------------------
-unsigned int demo_adder_test_round (unsigned int, unsigned int);
-unsigned int lfsr_next_x (unsigned int);
-unsigned int lfsr_next_y (unsigned int);
+unsigned int demo_adder_test_round (unsigned int, unsigned int);
+unsigned int lfsr_next_x (unsigned int);
+unsigned int lfsr_next_y (unsigned int);
//------------------------------------------------------------------------------
// Testing Parameters
//------------------------------------------------------------------------------
-const int NUM_TEST_ROUNDS = 10000;
-const int PRINT_XYZ_VALUES = 1;
+const int NUM_TEST_ROUNDS = 10000;
+const int PRINT_XYZ_VALUES = 1;
//------------------------------------------------------------------------------
-int main()
+int main(void)
//------------------------------------------------------------------------------
{
- // try to setup eim (return value should be 1)
- printf("Configuring EIM .. ");
- int ok = eim_setup();
- if (ok < 1)
- { printf("ERROR\n");
- return EXIT_FAILURE;
- }
- else printf("OK\n");
-
- // run test
- int i;
- unsigned int x = 0x12341234, y = 0xABCDABCD, zyx;
- printf("Testing started.\n");
- for (i=0; i<NUM_TEST_ROUNDS; i++)
- {
- // run another round
- unsigned int z = demo_adder_test_round(x, y);
-
- // calculate correct answer
- zyx = x + y;
-
- // check result
- if (z != zyx)
- { printf("ERROR: round %10d of %10d: x == 0x%08X, y == 0x%08X, z == 0x%08X [z should be 0x%08X]\n", i+1, NUM_TEST_ROUNDS, x, y, z, zyx);
- exit(EXIT_FAILURE);
- }
- else if (PRINT_XYZ_VALUES) printf("OK: round %10d of %10d: x == 0x%08X, y == 0x%08X, z == 0x%08X\n", i+1, NUM_TEST_ROUNDS, x, y, z);
-
- // update input values
- x = lfsr_next_x(x);
- y = lfsr_next_x(y);
- }
-
- // ok
- printf("Testing completed successfully.\n");
-
- // done
- return EXIT_SUCCESS;
+ int i;
+ unsigned int x = 0x12341234, y = 0xABCDABCD, zyx;
+
+ // try to setup eim (return value should be 1)
+ printf("Configuring EIM .. ");
+ if (eim_setup() < 1) {
+ printf("ERROR\n");
+ return EXIT_FAILURE;
+ }
+ else
+ printf("OK\n");
+
+ // run test
+ printf("Testing started.\n");
+ for (i=0; i<NUM_TEST_ROUNDS; i++) {
+ // run another round
+ unsigned int z = demo_adder_test_round(x, y);
+
+ // calculate correct answer
+ zyx = x + y;
+
+ // check result
+ if (z != zyx) {
+ printf("ERROR: round %10d of %10d: x == 0x%08X, y == 0x%08X, "
+ "z == 0x%08X [z should be 0x%08X]\n",
+ i+1, NUM_TEST_ROUNDS, x, y, z, zyx);
+ exit(EXIT_FAILURE);
+ }
+ else if (PRINT_XYZ_VALUES)
+ printf("OK: round %10d of %10d: x == 0x%08X, y == 0x%08X, "
+ "z == 0x%08X\n", i+1, NUM_TEST_ROUNDS, x, y, z);
+
+ // update input values
+ x = lfsr_next_x(x);
+ y = lfsr_next_x(y);
+ }
+
+ // ok
+ printf("Testing completed successfully.\n");
+
+ // done
+ return EXIT_SUCCESS;
}
@@ -85,44 +121,45 @@ int main()
unsigned int demo_adder_test_round(unsigned int x, unsigned int y)
//------------------------------------------------------------------------------
{
- // write x
- eim_write_32(DEMO_ADDER_REG_X, &x);
-
- // write y
- eim_write_32(DEMO_ADDER_REG_Y, &y);
-
- /* To make adder calculate something we need to change its control register,
- * so we read it, increment and write back. Control register is in the lower 16 bits.
- */
- unsigned int ctl;
- eim_read_32(DEMO_ADDER_REG_SC, &ctl);
- ctl += 1;
- ctl &= 0x0000FFFF;
- eim_write_32(DEMO_ADDER_REG_SC, &ctl);
-
- /* When adder is done, it will write new control value into its status register. Adder has 1-cycle latency
- * which is very small, we don't even need to poll, just check that status was updated. Status register is
- * in the upper 16 bits.
- */
- unsigned int sts;
- eim_read_32(DEMO_ADDER_REG_SC, &sts);
- sts >>= 16;
- if (sts != ctl)
- { printf("ERROR: Adder timeout!\n");
- exit(EXIT_FAILURE);
- }
-
- // read z
- unsigned int z;
- eim_read_32(DEMO_ADDER_REG_Z, &z);
-
- // uncomment to trigger an error
- /**
- z++;
- **/
-
- // done
- return z;
+ unsigned int ctl;
+ unsigned int sts;
+ unsigned int z;
+
+ // write x
+ eim_write_32(DEMO_ADDER_REG_X, &x);
+
+ // write y
+ eim_write_32(DEMO_ADDER_REG_Y, &y);
+
+ /* To make adder calculate something we need to change its control
+ * register, so we read it, increment and write back. Control register is
+ * in the lower 16 bits.
+ */
+ eim_read_32(DEMO_ADDER_REG_SC, &ctl);
+ ctl += 1;
+ ctl &= 0x0000FFFF;
+ eim_write_32(DEMO_ADDER_REG_SC, &ctl);
+
+ /* When adder is done, it will write new control value into its status
+ * register. Adder has 1-cycle latency which is very small, we don't even
+ * need to poll, just check that status was updated. Status register is in
+ * the upper 16 bits.
+ */
+ eim_read_32(DEMO_ADDER_REG_SC, &sts);
+ sts >>= 16;
+ if (sts != ctl)
+ { printf("ERROR: Adder timeout!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // read z
+ eim_read_32(DEMO_ADDER_REG_Z, &z);
+
+ // uncomment to trigger an error
+ //z++;
+
+ // done
+ return z;
}
@@ -130,36 +167,36 @@ unsigned int demo_adder_test_round(unsigned int x, unsigned int y)
unsigned int lfsr_next_x(unsigned int value)
//------------------------------------------------------------------------------
{
- //
- // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2]
- // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30
- //
-
- unsigned int carry = 0;
-
- carry ^= (value >> 0);
- carry ^= (value >> 1);
- carry ^= (value >> 3);
- carry ^= (value >> 4);
-
- carry ^= (value >> 5);
- carry ^= (value >> 7);
- carry ^= (value >> 8);
- carry ^= (value >> 9);
-
- carry ^= (value >> 11);
- carry ^= (value >> 13);
- carry ^= (value >> 15);
- carry ^= (value >> 18);
-
- carry ^= (value >> 22);
- carry ^= (value >> 24);
- carry ^= (value >> 28);
- carry ^= (value >> 30);
-
- value >>= 1, value |= (carry << 31);
-
- return value;
+ //
+ // [32, 31, 29, 28, 27, 25, 24, 23, 21, 19, 17, 14, 10, 6, 4, 2]
+ // 0 1 3 4 5 7 8 9 11 13 15 18 22 24 28 30
+ //
+
+ unsigned int carry = 0;
+
+ carry ^= (value >> 0);
+ carry ^= (value >> 1);
+ carry ^= (value >> 3);
+ carry ^= (value >> 4);
+
+ carry ^= (value >> 5);
+ carry ^= (value >> 7);
+ carry ^= (value >> 8);
+ carry ^= (value >> 9);
+
+ carry ^= (value >> 11);
+ carry ^= (value >> 13);
+ carry ^= (value >> 15);
+ carry ^= (value >> 18);
+
+ carry ^= (value >> 22);
+ carry ^= (value >> 24);
+ carry ^= (value >> 28);
+ carry ^= (value >> 30);
+
+ value >>= 1, value |= (carry << 31);
+
+ return value;
}
@@ -167,37 +204,37 @@ unsigned int lfsr_next_x(unsigned int value)
unsigned int lfsr_next_y(unsigned int value)
//------------------------------------------------------------------------------
{
- //
- // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1]
- // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31
- //
-
- unsigned int carry = 0;
-
- carry ^= (value >> 0);
- carry ^= (value >> 15);
- carry ^= (value >> 16);
- carry ^= (value >> 17);
-
- carry ^= (value >> 18);
- carry ^= (value >> 19);
- carry ^= (value >> 20);
- carry ^= (value >> 21);
-
- carry ^= (value >> 22);
- carry ^= (value >> 23);
- carry ^= (value >> 24);
- carry ^= (value >> 25);
-
- carry ^= (value >> 26);
- carry ^= (value >> 27);
- carry ^= (value >> 28);
- carry ^= (value >> 31);
-
- value >>= 1, value |= (carry << 31);
-
- return value;
-}
+ //
+ // [32, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 1]
+ // 0 15 16 17 18 19 20 21 22 23 24 25 26 27 28 31
+ //
+
+ unsigned int carry = 0;
+
+ carry ^= (value >> 0);
+ carry ^= (value >> 15);
+ carry ^= (value >> 16);
+ carry ^= (value >> 17);
+
+ carry ^= (value >> 18);
+ carry ^= (value >> 19);
+ carry ^= (value >> 20);
+ carry ^= (value >> 21);
+
+ carry ^= (value >> 22);
+ carry ^= (value >> 23);
+ carry ^= (value >> 24);
+ carry ^= (value >> 25);
+
+ carry ^= (value >> 26);
+ carry ^= (value >> 27);
+ carry ^= (value >> 28);
+ carry ^= (value >> 31);
+
+ value >>= 1, value |= (carry << 31);
+
+ return value;
+}