URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/sw/example
- from Rev 12 to Rev 13
- ↔ Reverse comparison
Rev 12 → Rev 13
/cpu_test/main.c
70,8 → 70,15
|
// Prototypes |
void global_trap_handler(void); |
void test_ok(void); |
void test_fail(void); |
|
// Global variables (also test initialization of global vars here) |
int cnt_fail = 0; |
int cnt_ok = 0; |
int cnt_test = 0; |
|
|
/**********************************************************************//** |
* Unreachable memory-mapped register that should be always available |
**************************************************************************/ |
91,10 → 98,6
register uint32_t tmp_a; |
volatile uint32_t dummy_dst __attribute__((unused)); |
|
int cnt_fail = 0; |
int cnt_ok = 0; |
int cnt_test = 0; |
|
union { |
uint64_t uint64; |
uint32_t uint32[sizeof(uint64_t)/2]; |
127,7 → 130,7
neorv32_mtime_set_timecmp(mtime_cmp_max); |
|
// intro |
neorv32_uart_printf("\n\n------ CPU TEST ------\n\n"); |
neorv32_uart_printf("\n\n-==== CPU TEST ====-\n\n"); |
|
// show project credits |
neorv32_rte_print_credits(); |
185,7 → 188,7
// Instruction memory test |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IMEM_TEST: "); |
neorv32_uart_printf("IMEM_TEST: "); |
#if (PROBING_MEM_TEST == 1) |
cnt_test++; |
|
204,12 → 207,10
neorv32_uart_printf("%u bytes (should be %u bytes) ", dmem_probe_cnt, neorv32_cpu_csr_read(CSR_MISPACESIZE)); |
neorv32_uart_printf("@ 0x%x ", neorv32_cpu_csr_read(CSR_MISPACEBASE)); |
if (dmem_probe_cnt == neorv32_cpu_csr_read(CSR_MISPACESIZE)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#else |
neorv32_uart_printf("skipped (disabled)\n"); |
219,7 → 220,7
// Data memory test |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("DMEM_TEST: "); |
neorv32_uart_printf("DMEM_TEST: "); |
#if (PROBING_MEM_TEST == 1) |
cnt_test++; |
|
238,12 → 239,10
neorv32_uart_printf("%u bytes (should be %u bytes) ", imem_probe_cnt, neorv32_cpu_csr_read(CSR_MDSPACESIZE)); |
neorv32_uart_printf("@ 0x%x ", neorv32_cpu_csr_read(CSR_MDSPACEBASE)); |
if (imem_probe_cnt == neorv32_cpu_csr_read(CSR_MDSPACESIZE)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#else |
neorv32_uart_printf("skipped (disabled)\n"); |
253,7 → 252,7
// ---------------------------------------------------------- |
// Test counter CSR access for mcycle[h] |
// ---------------------------------------------------------- |
neorv32_uart_printf("MCYCLE[H]: "); |
neorv32_uart_printf("MCYCLE[H]: "); |
cnt_test++; |
|
neorv32_cpu_csr_write(CSR_MCYCLE, 0x1BCD1234); |
261,12 → 260,10
|
if (((neorv32_cpu_csr_read(CSR_MCYCLE) & 0xffff0000L) == 0x1BCD0000) && |
(neorv32_cpu_csr_read(CSR_MCYCLEH) == 0x00034455)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
|
|
273,7 → 270,7
// ---------------------------------------------------------- |
// Test counter CSR access for minstret[h] |
// ---------------------------------------------------------- |
neorv32_uart_printf("MINSTRET[H]: "); |
neorv32_uart_printf("MINSTRET[H]: "); |
cnt_test++; |
|
neorv32_cpu_csr_write(CSR_MINSTRET, 0x11224499); |
281,12 → 278,10
|
if (((neorv32_cpu_csr_read(CSR_MINSTRET) & 0xffff0000L) == 0x11220000) && |
(neorv32_cpu_csr_read(CSR_MINSTRETH) == 0x00090011)) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
|
|
293,7 → 288,7
// ---------------------------------------------------------- |
// Test time[h] (must be == MTIME) |
// ---------------------------------------------------------- |
neorv32_uart_printf("TIME[H]: "); |
neorv32_uart_printf("TIME[H]: "); |
cnt_test++; |
|
cpu_systime.uint32[0] = neorv32_cpu_csr_read(CSR_TIME); |
303,12 → 298,10
uint64_t mtime_systime = neorv32_mtime_get_time() & 0xFFFFFFFFFFFF0000LL; |
|
if (cpu_systime.uint64 == mtime_systime) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
|
|
317,28 → 310,46
// a more complex test is provided by the RISC-V compliance test |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("FENCE(.I): "); |
neorv32_uart_printf("FENCE(.I): "); |
cnt_test++; |
asm volatile ("fence"); |
asm volatile ("fence.i"); |
|
if (exception_handler_answer != 0xFFFFFFFF) { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
else { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
|
|
// ---------------------------------------------------------- |
// Illegal CSR access |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("ILLEGAL CSR: "); |
|
cnt_test++; |
|
neorv32_cpu_csr_read(0xfff); // CSR 0xfff not implemented |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_I_ILLEGAL) { |
test_ok(); |
} |
else { |
test_fail(); |
} |
#endif |
|
|
// ---------------------------------------------------------- |
// Unaligned instruction address |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ALIGN: "); |
neorv32_uart_printf("EXC I_ALIGN: "); |
|
// skip if C-mode is not implemented |
// skip if C-mode is implemented |
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_C_EXT)) == 0) { |
|
cnt_test++; |
366,7 → 377,7
// Instruction access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ACC: "); |
neorv32_uart_printf("EXC I_ACC: "); |
cnt_test++; |
|
// call unreachable aligned address |
374,12 → 385,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_I_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
388,7 → 397,7
// Illegal instruction |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC I_ILLEG: "); |
neorv32_uart_printf("EXC I_ILLEG: "); |
cnt_test++; |
|
// create test program in RAM |
402,21 → 411,53
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_I_ILLEGAL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
|
// ---------------------------------------------------------- |
// Illegal compressed instruction |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC CI_ILLEG: "); |
|
// skip if C-mode is not implemented |
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CPU_MISA_C_EXT)) != 0) { |
|
cnt_test++; |
|
// create test program in RAM |
static const uint32_t dummy_sub_program_ci[2] = { |
0x00000001, // 2nd: official_illegal_op | 1st: NOP -> illegal instruction exception |
0x00008067 // ret (32-bit) |
}; |
|
tmp_a = (uint32_t)&dummy_sub_program_ci; // call the dummy sub program |
asm volatile ( "jalr ra, %0 " : "=r" (tmp_a) : "r" (tmp_a)); |
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_I_ILLEGAL) { |
test_ok(); |
} |
else { |
test_fail(); |
} |
#endif |
} |
else { |
neorv32_uart_printf("skipped (not possible when C-EXT disabled)\n"); |
} |
|
|
// ---------------------------------------------------------- |
// Breakpoint instruction |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC BREAK: "); |
neorv32_uart_printf("EXC BREAK: "); |
cnt_test++; |
|
asm volatile("EBREAK"); |
423,12 → 464,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_BREAKPOINT) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
437,7 → 476,7
// Unaligned load address |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC L_ALIGN: "); |
neorv32_uart_printf("EXC L_ALIGN: "); |
cnt_test++; |
|
// load from unaligned address |
445,12 → 484,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_L_MISALIGNED) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
459,7 → 496,7
// Load access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC L_ACC: "); |
neorv32_uart_printf("EXC L_ACC: "); |
cnt_test++; |
|
// load from unreachable aligned address |
467,12 → 504,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_L_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
481,7 → 516,7
// Unaligned store address |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC S_ALIGN: "); |
neorv32_uart_printf("EXC S_ALIGN: "); |
cnt_test++; |
|
// store to unaligned address |
489,12 → 524,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_S_MISALIGNED) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
503,7 → 536,7
// Store access fault |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC S_ACC: "); |
neorv32_uart_printf("EXC S_ACC: "); |
cnt_test++; |
|
// store to unreachable aligned address |
511,12 → 544,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_S_ACCESS) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
525,7 → 556,7
// Environment call |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("EXC ENVCALL: "); |
neorv32_uart_printf("EXC ENVCALL: "); |
cnt_test++; |
|
asm volatile("ECALL"); |
532,12 → 563,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_MENV_CALL) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
546,7 → 575,7
// Machine timer interrupt (MTIME) |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IRQ MTI: "); |
neorv32_uart_printf("IRQ MTI: "); |
cnt_test++; |
|
// force MTIME IRQ |
560,12 → 589,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_MTI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
577,7 → 604,7
// Machine external interrupt (via CLIC) |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("IRQ MEI: "); |
neorv32_uart_printf("IRQ MEI: "); |
cnt_test++; |
|
// manually trigger CLIC channel (watchdog interrupt) |
591,12 → 618,10
|
#if (DETAILED_EXCEPTION_DEBUG==0) |
if (exception_handler_answer == EXCCODE_MEI) { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
else { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
#endif |
|
605,7 → 630,7
// Test WFI ("sleep") instructions |
// ---------------------------------------------------------- |
exception_handler_answer = 0xFFFFFFFF; |
neorv32_uart_printf("WFI: "); |
neorv32_uart_printf("WFI: "); |
cnt_test++; |
|
// program timer to wake up |
615,12 → 640,10
asm volatile ("wfi"); |
|
if (exception_handler_answer != EXCCODE_MTI) { |
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
test_fail(); |
} |
else { |
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
test_ok(); |
} |
|
|
644,5 → 667,26
* Trap handler for ALL exceptions/interrupts. |
**************************************************************************/ |
void global_trap_handler(void) { |
|
exception_handler_answer = neorv32_cpu_csr_read(CSR_MCAUSE); |
} |
|
|
/**********************************************************************//** |
* Test results helper function: Shows "ok" and increments global cnt_ok |
**************************************************************************/ |
void test_ok(void) { |
|
neorv32_uart_printf("ok\n"); |
cnt_ok++; |
} |
|
|
/**********************************************************************//** |
* Test results helper function: Shows "fail" and increments global cnt_fail |
**************************************************************************/ |
void test_fail(void) { |
|
neorv32_uart_printf("fail\n"); |
cnt_fail++; |
} |