aboutsummaryrefslogblamecommitdiff
path: root/sw/test-adder/test-adder.c
blob: 70415d8bfb83312ec644080a7c75cc093e7555d4 (plain) (tree)













































































































































































































                                                                                                                                                              
//------------------------------------------------------------------------------
// setup-eim.c
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "novena-eim.h"


//------------------------------------------------------------------------------
// 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))


//------------------------------------------------------------------------------
// 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);


//------------------------------------------------------------------------------
// Testing Parameters
//------------------------------------------------------------------------------
const int	NUM_TEST_ROUNDS		= 10000;
const int	PRINT_XYZ_VALUES	= 1;


//------------------------------------------------------------------------------
int main()
//------------------------------------------------------------------------------
{
		// 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;
}


//------------------------------------------------------------------------------
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 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;
}


//------------------------------------------------------------------------------
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;
}	



//------------------------------------------------------------------------------
// End-of-File
//------------------------------------------------------------------------------