URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2/sw/tests/or1200
- from Rev 435 to Rev 439
- ↔ Reverse comparison
Rev 435 → Rev 439
/board/or1200-mul.c
0,0 → 1,225
/* |
Test integer multiply |
|
Use a software multiplication algorithm to compare against hardware |
calculated results |
|
Julius Baxter, julius@opencores.org |
|
*/ |
|
#include "cpu-utils.h" |
#include "uart.h" |
#include "printf.h" |
#include "board.h" |
|
static int smul_errors, umul_errors; |
|
#define VERBOSE_TESTS 0 |
|
// Make this bigger when running on FPGA target. For simulation it's enough. |
#define NUM_TESTS 2000000 |
|
int |
or1k_mul(int multiplicant, int multiplier) |
{ |
int result; |
asm ("l.mul\t%0,%1,%2" : "=r" (result) : "r" (multiplicant), |
"r" (multiplier)); |
return result; |
} |
|
unsigned int |
or1k_mulu(unsigned int mulidend, unsigned int mulisor) |
{ |
int result; |
asm ("l.mulu\t%0,%1,%2" : "=r" (result) : "r" (mulidend), "r" (mulisor)); |
return result; |
} |
|
|
void |
check_mul(int multiplicand, int multiplier, int expected_result) |
{ |
#if VERBOSE_TESTS |
printf("l.mul 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier, |
expected_result); |
#endif |
int result = or1k_mul(multiplicand, multiplier); |
report(result); |
if ( result != expected_result) |
{ |
printf("l.mul 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier, |
expected_result); |
|
printf("(HW) 0x%.8x - MISMATCH\n",result); |
smul_errors++; |
} |
#if VERBOSE_TESTS |
else |
printf("OK\n"); |
#endif |
|
} |
|
void |
check_mulu(unsigned int multiplicand, unsigned int multiplier, |
unsigned int expected_result) |
{ |
#if VERBOSE_TESTS |
printf("l.mulu 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier, |
expected_result); |
#endif |
|
unsigned int result = or1k_mulu(multiplicand, multiplier); |
report(result); |
if ( result != expected_result) |
{ |
printf("l.mulu 0x%.8x * 0x%.8x = (SW) 0x%.8x : ", multiplicand, multiplier, |
expected_result); |
|
printf("(HW) 0x%.8x - MISMATCH\n",result); |
umul_errors++; |
} |
#if VERBOSE_TESTS |
else |
printf("OK\n"); |
#endif |
} |
|
|
// Software implementation of multiply |
unsigned int |
mul_soft(unsigned int n, unsigned int d) |
{ |
|
unsigned int m = 0; |
//printf("sft: 0x%x 0x%xd\n",n,d); |
int i; |
for(i=0; i<32; i++) |
{ |
//printf("bit %d: 0x%x\n",i, (((1<<i) & d))); |
if ((1<<i) & d) |
{ |
m += (unsigned int) (n << i); |
} |
} |
|
return (unsigned int) m; |
} |
|
int |
main(void) |
{ |
#ifdef _UART_H_ |
uart_init(DEFAULT_UART); |
#endif |
|
unsigned int seconds = 0; |
cpu_reset_timer_ticks(); |
cpu_enable_timer(); |
|
printf("\n\n\tOR1200 Multiplication Instruction Tests\n"); |
printf("\tRunning %d tests\n", NUM_TESTS); |
printf("\tElapsed time: 000"); |
|
// Variables for tracking errors |
umul_errors = 0; |
smul_errors = 0; |
|
int i; |
|
unsigned int n, d; |
unsigned int expected_result; |
i=0; |
n=0;d=0; |
while(i < NUM_TESTS) |
{ |
|
n = rand() >> 20; |
d = (rand() >> 24); |
|
report(0x10101010); |
|
|
if (n&0x10) // Randomly select if we should negate n |
{ |
// 2's complement of n |
n = ~n + 1; |
} |
|
if (d&0x80) // Randomly select if we should negate d |
{ |
// 2's complement of d |
d = ~d + 1; |
} |
|
if ((n & 0x80000000) && (d & 0x80000000)) |
expected_result = mul_soft(~(n-1), ~(d-1)); |
else if ((n & 0x80000000) && !(d & 0x80000000)) |
{ |
expected_result = mul_soft(~(n-1), d); |
expected_result = ~expected_result + 1; // 2's complement |
} |
else if (!(n & 0x80000000) && (d & 0x80000000)) |
{ |
expected_result = mul_soft(n, ~(d-1)); |
expected_result = ~expected_result + 1; // 2's complement |
} |
else if (!(n & 0x80000000) && !(d & 0x80000000)) |
expected_result = mul_soft(n, d); |
|
|
/* Report things */ |
report(n); |
report(d); |
report(expected_result); |
|
|
/* Signed mulide */ |
check_mul(n, d, expected_result); |
|
|
/* Unsigned mulide test */ |
/* Ensure numerator's bit 31 is clear */ |
n >>= 1; |
|
expected_result = mul_soft(n, d); |
|
/* Report things */ |
report(n); |
report(d); |
report(expected_result); |
|
/* Unsigned mulide */ |
check_mulu(n, d, expected_result); |
|
report(i); |
i++; |
|
|
if (cpu_get_timer_ticks() >= TICKS_PER_SEC) |
{ |
cpu_reset_timer_ticks(); |
seconds++; |
printf("\b\b\b%.3d",seconds); |
} |
|
} |
|
printf("\n"); |
|
printf("Integer multiply check complete\n"); |
printf("Unsigned:\t%d tests\t %d errors\n", |
NUM_TESTS, umul_errors); |
printf("Signed:\t\t%d tests\t %d errors\n", |
NUM_TESTS, smul_errors); |
|
if ((umul_errors > 0) || (smul_errors > 0)) |
report(0xbaaaaaad); |
else |
report(0x8000000d); |
|
return 0; |
|
} |
/board/or1200-div.c
0,0 → 1,229
/* |
Test integer division |
|
Use a software division algorithm to perform division and compare against |
the hardware calculated results |
|
TODO: Check the signed division software calculation stuff is 100% correct! |
|
Julius Baxter, julius@opencores.org |
|
*/ |
|
#include "cpu-utils.h" |
#include "uart.h" |
#include "printf.h" |
#include "board.h" |
|
static int sdiv_errors, udiv_errors; |
|
#define VERBOSE_TESTS 0 |
|
// Make this bigger when running on FPGA target. For simulation it's enough. |
#define NUM_TESTS 2000000 |
|
int |
or1k_div(int dividend, int divisor) |
{ |
int result; |
asm ("l.div\t%0,%1,%2" : "=r" (result) : "r" (dividend), "r" (divisor)); |
return result; |
} |
|
unsigned int |
or1k_divu(unsigned int dividend, unsigned int divisor) |
{ |
int result; |
asm ("l.divu\t%0,%1,%2" : "=r" (result) : "r" (dividend), "r" (divisor)); |
return result; |
} |
|
|
void |
check_div(int dividend, int divisor, int expected_result) |
{ |
#if VERBOSE_TESTS |
printf("l.div 0x%.8x / 0x%.8x = (SW) 0x%.8x : ", dividend, divisor, |
expected_result); |
#endif |
int result = or1k_div(dividend, divisor); |
report(result); |
if ( result != expected_result) |
{ |
printf("l.div 0x%.8x / 0x%.8x = (SW) 0x%.8x : ", dividend, divisor, |
expected_result); |
|
printf("(HW) 0x%.8x - MISMATCH\n",result); |
sdiv_errors++; |
} |
#if VERBOSE_TESTS |
else |
printf("OK\n"); |
#endif |
|
} |
|
void |
check_divu(unsigned int dividend, unsigned int divisor, |
unsigned int expected_result) |
{ |
#if VERBOSE_TESTS |
printf("l.divu 0x%.8x / 0x%.8x = (SW) 0x%.8x : ", dividend, divisor, |
expected_result); |
#endif |
|
unsigned int result = or1k_divu(dividend, divisor); |
report(result); |
if ( result != expected_result) |
{ |
printf("l.divu 0x%.8x / 0x%.8x = (SW) 0x%.8x : ", dividend, divisor, |
expected_result); |
|
printf("(HW) 0x%.8x - MISMATCH\n",result); |
udiv_errors++; |
} |
#if VERBOSE_TESTS |
else |
printf("OK\n"); |
#endif |
} |
|
|
// Software implementation of division |
unsigned int |
div_soft(unsigned int n, unsigned int d) |
{ |
|
// unsigned 32-bit restoring divide algo: |
unsigned long long p, dd; |
long long p_signed; |
unsigned int q = 0; |
|
p = (unsigned long long) n; |
dd = (unsigned long long) d << 32; |
|
int i; |
for(i=31; i>-1; i--){ |
p_signed = (2*p) - dd; |
if (p_signed>=0) |
{ |
p = (2*p) - dd; |
q |= 1 << i; |
} |
else |
{ |
p = p_signed + dd; |
} |
} |
|
return q; |
|
} |
|
int |
main(void) |
{ |
#ifdef _UART_H_ |
uart_init(DEFAULT_UART); |
#endif |
|
unsigned int seconds = 0; |
cpu_reset_timer_ticks(); |
cpu_enable_timer(); |
|
printf("\n\n\tOR1200 Division Instruction Tests\n"); |
printf("\tRunning %d tests\n", NUM_TESTS); |
#if VERBOSE_TESTS==0 |
printf("\tElapsed time: 000"); |
#endif |
|
udiv_errors = 0; |
sdiv_errors = 0; |
|
int i; |
|
unsigned long n, d; |
unsigned long expected_result; |
i=0; |
while(i < NUM_TESTS) |
{ |
n = rand(); |
d = rand(); |
|
report(0x10101010); |
|
while ( d >= n ) |
d >>= (rand() & 0xff); |
|
if (n&0x80000000) // numerator is negative |
{ |
// Calculate a value that's really smaller than the numerator |
while ( d >= ~(n-1) ) |
d >>= (rand() & 0xff); |
|
if (!d) d = 1; |
// Processor thinks it's in 2's complement already, so we'll convert |
// from the interpreted 2's complement to unsigned for our calculation |
expected_result = div_soft(~(n-1), d); |
// Answer will be an unsigned +ve value, but of course it has to be |
// negative so convert back to 2's complment negative |
expected_result = ~expected_result + 1; // 2's complement |
} |
else |
expected_result = div_soft(n, d); |
|
/* Report things */ |
report(n); |
report(d); |
report(expected_result); |
|
/* Signed divide */ |
check_div(n, d, expected_result); |
|
|
/* Unsigned divide test */ |
/* Ensure numerator's bit 31 is clear */ |
n >>= 1; |
|
/* If divisor is > numerator, shift it by a random amount */ |
while ( d >= n ) |
d >>= (rand() & 0xff); |
if (!d) d = 1; |
|
expected_result = div_soft(n, d); |
|
/* Report things */ |
report(n); |
report(d); |
report(expected_result); |
|
/* Unsigned divide */ |
check_divu(n, d, expected_result); |
|
i++; |
#if VERBOSE_TESTS==0 |
if (cpu_get_timer_ticks() >= TICKS_PER_SEC) |
{ |
cpu_reset_timer_ticks(); |
seconds++; |
printf("\b\b\b%.3d",seconds); |
} |
#endif |
} |
|
printf("\n"); |
|
printf("Division check complete\n"); |
printf("Unsigned:\t%d tests\t %d errors\n", |
NUM_TESTS, udiv_errors); |
printf("Signed:\t\t%d tests\t %d errors\n", |
NUM_TESTS, sdiv_errors); |
|
if ((udiv_errors > 0) || (sdiv_errors > 0)) |
report(0xbaaaaaad); |
else |
report(0x8000000d); |
|
return 0; |
|
} |
/sim/or1200-dctest.c
14,8 → 14,9
#define LOOPS 64 |
#define WORD_STRIDE 8 |
|
// Memory area to test at |
#define TEST_BASE 0x600000 /* 6MB */ |
|
|
unsigned long int my_lfsr; |
|
unsigned long int next_rand() |
36,7 → 37,7
return 0; |
} |
|
volatile char* ptr = (volatile char*) 0xe00000; |
volatile char* ptr = (volatile char*) TEST_BASE; |
int i; |
|
ptr[0] = 0xab; |
98,7 → 99,7
|
// init LFSR |
my_lfsr = RAND_LFSR_SEED; |
volatile unsigned long int *lptr = (volatile unsigned long int*) 0xa00000; |
volatile unsigned long int *lptr = (volatile unsigned long int*) TEST_BASE; |
for(i=0;i<LOOPS;i++) |
{ |
lptr[(i*WORD_STRIDE)-1] = next_rand(); |
/sim/or1200-mmu.c
1427,8 → 1427,8
start_text_addr = (unsigned long*)&_stext; |
end_text_addr = (unsigned long*)&_endtext; |
end_data_addr = (unsigned long*)&_stack; |
end_data_addr += 4; |
|
|
#ifndef TLB_BOTTOM_TEST_PAGE_HARDSET |
TLB_TEXT_SET_NB = TLB_DATA_SET_NB = (end_data_addr+PAGE_SIZE) / PAGE_SIZE; |
#endif |