Line 152... |
Line 152... |
PRINT_STANDARD("\n<< PROCESSOR CHECK >>\n");
|
PRINT_STANDARD("\n<< PROCESSOR CHECK >>\n");
|
PRINT_STANDARD("build: "__DATE__" "__TIME__"\n");
|
PRINT_STANDARD("build: "__DATE__" "__TIME__"\n");
|
|
|
|
|
// reset performance counter
|
// reset performance counter
|
neorv32_cpu_csr_write(CSR_MCYCLEH, 0);
|
// neorv32_cpu_csr_write(CSR_MCYCLEH, 0); -> done in crt0.S
|
neorv32_cpu_csr_write(CSR_MCYCLE, 0);
|
// neorv32_cpu_csr_write(CSR_MCYCLE, 0); -> done in crt0.S
|
neorv32_cpu_csr_write(CSR_MINSTRETH, 0);
|
// neorv32_cpu_csr_write(CSR_MINSTRETH, 0); -> done in crt0.S
|
neorv32_cpu_csr_write(CSR_MINSTRET, 0);
|
// neorv32_cpu_csr_write(CSR_MINSTRET, 0); -> done in crt0.S
|
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable performance counter auto increment (ALL counters)
|
neorv32_cpu_csr_write(CSR_MCOUNTINHIBIT, 0); // enable performance counter auto increment (ALL counters)
|
neorv32_cpu_csr_write(CSR_MCOUNTEREN, 7); // allow access from user-mode code to standard counters only
|
neorv32_cpu_csr_write(CSR_MCOUNTEREN, 7); // allow access from user-mode code to standard counters only
|
|
|
// set CMP of machine system timer MTIME to max to prevent an IRQ
|
// set CMP of machine system timer MTIME to max to prevent an IRQ
|
neorv32_mtime_set_timecmp(-1);
|
neorv32_mtime_set_timecmp(-1);
|
Line 178... |
Line 178... |
neorv32_rte_print_hw_config();
|
neorv32_rte_print_hw_config();
|
|
|
|
|
// configure RTE
|
// configure RTE
|
// -----------------------------------------------
|
// -----------------------------------------------
|
PRINT_STANDARD("\n\nConfiguring NEORV32 RTE... ");
|
PRINT_STANDARD("\n\nRTE setup... ");
|
|
|
int install_err = 0;
|
int install_err = 0;
|
// initialize ALL provided trap handler (overriding the default debug handlers)
|
// initialize ALL provided trap handler (overriding the default debug handlers)
|
for (id=0; id<NEORV32_RTE_NUM_TRAPS; id++) {
|
for (id=0; id<NEORV32_RTE_NUM_TRAPS; id++) {
|
install_err += neorv32_rte_exception_install(id, global_trap_handler);
|
install_err += neorv32_rte_exception_install(id, global_trap_handler);
|
}
|
}
|
|
|
if (install_err) {
|
if (install_err) {
|
PRINT_CRITICAL("RTE install error (%i)!\n", install_err);
|
PRINT_CRITICAL("ERROR!\n");
|
return 1;
|
return 1;
|
}
|
}
|
|
|
// clear testbench IRQ triggers
|
// clear testbench IRQ triggers
|
sim_irq_trigger(0);
|
sim_irq_trigger(0);
|
|
|
// clear all interrupt enables, enable only where needed
|
// clear all interrupt enables, enable only where needed
|
neorv32_cpu_csr_write(CSR_MIE, 0);
|
neorv32_cpu_csr_write(CSR_MIE, 0);
|
|
|
// test intro
|
// test intro
|
PRINT_STANDARD("\nStarting tests...\n\n");
|
PRINT_STANDARD("\nStarting tests.\n\n");
|
|
|
// enable global interrupts
|
// enable global interrupts
|
neorv32_cpu_eint();
|
neorv32_cpu_eint();
|
|
|
|
|
Line 213... |
Line 212... |
|
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
// Test performance counter: setup as many events and counter as feasible
|
// Test performance counter: setup as many events and counter as feasible
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
PRINT_STANDARD("[%i] Configuring HPM events: ", cnt_test);
|
PRINT_STANDARD("[%i] Setup HPM events: ", cnt_test);
|
|
|
num_hpm_cnts_global = neorv32_cpu_hpm_get_counters();
|
num_hpm_cnts_global = neorv32_cpu_hpm_get_counters();
|
|
|
if (num_hpm_cnts_global != 0) {
|
if (num_hpm_cnts_global != 0) {
|
cnt_test++;
|
cnt_test++;
|
Line 252... |
Line 251... |
|
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
// Test standard RISC-V performance counter [m]cycle[h]
|
// Test standard RISC-V performance counter [m]cycle[h]
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
PRINT_STANDARD("[%i] [m]cycle[h] counter: ", cnt_test);
|
PRINT_STANDARD("[%i] cycle counter: ", cnt_test);
|
|
|
cnt_test++;
|
cnt_test++;
|
|
|
// make sure counter is enabled
|
// make sure counter is enabled
|
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
|
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
|
Line 278... |
Line 277... |
|
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
// Test standard RISC-V performance counter [m]instret[h]
|
// Test standard RISC-V performance counter [m]instret[h]
|
// ----------------------------------------------------------
|
// ----------------------------------------------------------
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
PRINT_STANDARD("[%i] [m]instret[h] counter: ", cnt_test);
|
PRINT_STANDARD("[%i] instret counter: ", cnt_test);
|
|
|
cnt_test++;
|
cnt_test++;
|
|
|
// make sure counter is enabled
|
// make sure counter is enabled
|
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
|
asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
|
Line 573... |
Line 572... |
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
|
PRINT_STANDARD("[%i] I_ILLEG (illegal instr.) EXC: ", cnt_test);
|
PRINT_STANDARD("[%i] I_ILLEG (illegal instr.) EXC: ", cnt_test);
|
|
|
cnt_test++;
|
cnt_test++;
|
|
|
// not allowed outside of debug mode
|
// illegal 32-bit instruction (malformed SUB)
|
asm volatile ("dret");
|
asm volatile (".align 4 \n"
|
|
".word 0x80000033");
|
|
|
// make sure this has cause an illegal exception
|
// make sure this has cause an illegal exception
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
|
// make sure this is really the instruction that caused the exception
|
// make sure this is really the instruction that caused the exception
|
// -> for illegal instructions mtval contains the failing instruction word
|
// -> for illegal instructions MTVAL contains the faulting instruction word
|
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x7b200073) {
|
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x80000033) {
|
test_ok();
|
test_ok();
|
}
|
}
|
else {
|
else {
|
test_fail();
|
test_fail();
|
}
|
}
|
Line 603... |
Line 603... |
// skip if C-mode is not implemented
|
// skip if C-mode is not implemented
|
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C))) {
|
if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C))) {
|
|
|
cnt_test++;
|
cnt_test++;
|
|
|
// create test program in RAM
|
// illegal 16-bit instruction (official UNIMP instruction)
|
static const uint32_t dummy_sub_program_ci[2] __attribute__((aligned(8))) = {
|
asm volatile (".align 2 \n"
|
0x00000001, // 2nd: official_illegal_op | 1st: NOP -> illegal instruction exception
|
".half 0x0001 \n" // NOP
|
0x00008067 // ret (32-bit)
|
".half 0x0000"); // UNIMP
|
};
|
|
|
|
tmp_a = (uint32_t)&dummy_sub_program_ci; // call the dummy sub program
|
|
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
|
|
|
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
|
test_ok();
|
test_ok();
|
}
|
}
|
else {
|
else {
|
Line 651... |
Line 647... |
cnt_test++;
|
cnt_test++;
|
|
|
// load from unaligned address
|
// load from unaligned address
|
neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED_1);
|
neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED_1);
|
|
|
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) {
|
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) &&
|
|
(neorv32_cpu_csr_read(CSR_MTVAL) == ADDR_UNALIGNED_1)) {
|
test_ok();
|
test_ok();
|
}
|
}
|
else {
|
else {
|
test_fail();
|
test_fail();
|
}
|
}
|