OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [processor_check/] [main.c] - Diff between revs 63 and 64

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 63 Rev 64
Line 48... Line 48...
 **************************************************************************/
 **************************************************************************/
/**@{*/
/**@{*/
/** UART BAUD rate */
/** UART BAUD rate */
#define BAUD_RATE           (19200)
#define BAUD_RATE           (19200)
//** Reachable unaligned address */
//** Reachable unaligned address */
#define ADDR_UNALIGNED      (0x00000002)
#define ADDR_UNALIGNED_1    (0x00000001)
 
//** Reachable unaligned address */
 
#define ADDR_UNALIGNED_2    (0x00000002)
//** Unreachable word-aligned address */
//** Unreachable word-aligned address */
#define ADDR_UNREACHABLE    (IO_BASE_ADDRESS-4)
#define ADDR_UNREACHABLE    (IO_BASE_ADDRESS-4)
//** external memory base address */
//** external memory base address */
#define EXT_MEM_BASE        (0xF0000000)
#define EXT_MEM_BASE        (0xF0000000)
/**@}*/
/**@}*/
Line 113... Line 115...
int main() {
int main() {
 
 
  register uint32_t tmp_a, tmp_b;
  register uint32_t tmp_a, tmp_b;
  uint8_t id;
  uint8_t id;
 
 
 
  // disable global interrupts
 
  neorv32_cpu_dint();
 
 
  // init UARTs at default baud rate, no parity bits, no hw flow control
  // init UARTs at default baud rate, no parity bits, no hw flow control
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
  UART1_CT = UART0_CT; // copy configuration to initialize UART1
  NEORV32_UART1.CTRL = NEORV32_UART0.CTRL; // copy configuration to initialize UART1
 
 
#ifdef SUPPRESS_OPTIONAL_UART_PRINT
#ifdef SUPPRESS_OPTIONAL_UART_PRINT
  neorv32_uart0_disable(); // do not generate any UART0 output
  neorv32_uart0_disable(); // do not generate any UART0 output
#endif
#endif
 
 
Line 155... Line 159...
  neorv32_cpu_csr_write(CSR_MINSTRETH, 0);
  neorv32_cpu_csr_write(CSR_MINSTRETH, 0);
  neorv32_cpu_csr_write(CSR_MINSTRET, 0);
  neorv32_cpu_csr_write(CSR_MINSTRET, 0);
  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
 
 
  neorv32_mtime_set_time(0);
 
  // 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
  uint64_t mtime_cmp_max = 0xffffffffffffffffULL;
  neorv32_mtime_set_timecmp(-1);
  neorv32_mtime_set_timecmp(mtime_cmp_max);
  neorv32_mtime_set_time(0);
 
 
 
 
  // fancy intro
  // fancy intro
  // -----------------------------------------------
  // -----------------------------------------------
  // logo
  // logo
Line 188... Line 191...
  if (install_err) {
  if (install_err) {
    PRINT_CRITICAL("RTE install error (%i)!\n", install_err);
    PRINT_CRITICAL("RTE install error (%i)!\n", install_err);
    return 1;
    return 1;
  }
  }
 
 
  // enable interrupt sources
  // clear testbench IRQ triggers
  neorv32_cpu_irq_enable(CSR_MIE_MSIE); // machine software interrupt
  sim_irq_trigger(0);
  neorv32_cpu_irq_enable(CSR_MIE_MTIE); // machine timer interrupt
 
  neorv32_cpu_irq_enable(CSR_MIE_MEIE); // machine external interrupt
  // clear all interrupt enables, enable only where needed
  // enable FAST IRQ sources only where actually needed
  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
Line 339... Line 342...
  // Test mcounteren: do not allow cycle[h] access from user-mode
  // Test mcounteren: do not allow cycle[h] access from user-mode
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] mcounteren.cy CSR: ", cnt_test);
  PRINT_STANDARD("[%i] mcounteren.cy CSR: ", cnt_test);
 
 
  // skip if U-mode is not implemented
 
  if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
    cnt_test++;
    cnt_test++;
 
 
    // do not allow user-level code to access cycle[h] CSRs
    // do not allow user-level code to access cycle[h] CSRs
    tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
    tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
    tmp_a &= ~(1<<CSR_MCOUNTEREN_CY); // clear access right
    tmp_a &= ~(1<<CSR_MCOUNTEREN_CY); // clear access right
Line 357... Line 358...
      tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
      tmp_a = neorv32_cpu_csr_read(CSR_CYCLE);
    }
    }
 
 
    // make sure there was an illegal instruction trap
    // make sure there was an illegal instruction trap
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
      if (tmp_a == 0) { // make sure user-level code CANNOT read locked CSR content!
 
        test_ok();
        test_ok();
      }
      }
      else {
      else {
        test_fail();
        test_fail();
      }
      }
    }
 
    else {
 
      test_fail();
 
    }
 
  }
 
    else {
 
    PRINT_STANDARD("skipped (n.a.)\n");
 
  }
 
 
 
 
 
  // re-allow user-level code to access cycle[h] CSRs
  // re-allow user-level code to access cycle[h] CSRs
  tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
  tmp_a = neorv32_cpu_csr_read(CSR_MCOUNTEREN);
  tmp_a |= (1<<CSR_MCOUNTEREN_CY); // re-allow access right
  tmp_a |= (1<<CSR_MCOUNTEREN_CY); // re-allow access right
  neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
  neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
 
 
 
/*
 
  // ----------------------------------------------------------
 
  // Execute DRET in M-mode (has to trap!)
 
  // ----------------------------------------------------------
 
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
  PRINT_STANDARD("[%i] DRET in M-mode: ", cnt_test);
 
 
 
  // skip if U-mode is not implemented
 
  if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
 
 
    cnt_test++;
 
 
 
    asm volatile("dret");
 
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
 
      test_ok();
 
    }
 
    else {
 
      test_fail();
 
    }
 
 
 
  }
 
  else {
 
    PRINT_STANDARD("skipped (n.a. without U-ext)\n");
 
  }
 
*/
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Execute MRET in U-mode (has to trap!)
  // Execute MRET in U-mode (has to trap!)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] MRET in U-mode: ", cnt_test);
  PRINT_STANDARD("[%i] MRET in U-mode: ", cnt_test);
 
 
  // skip if U-mode is not implemented
 
  if (SYSINFO_CPU & (1<<SYSINFO_CPU_DEBUGMODE)) {
 
 
 
    cnt_test++;
    cnt_test++;
 
 
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    neorv32_cpu_goto_user_mode();
    neorv32_cpu_goto_user_mode();
    {
    {
Line 431... Line 391...
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
 
 
  }
 
  else {
 
    PRINT_STANDARD("skipped (n.a. without U-ext)\n");
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // External memory interface test
  // External memory interface test
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] External memory access (@ 0x%x): ", cnt_test, (uint32_t)EXT_MEM_BASE);
  PRINT_STANDARD("[%i] External memory access (@ 0x%x): ", cnt_test, (uint32_t)EXT_MEM_BASE);
 
 
  if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)) {
  if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT)) {
    cnt_test++;
    cnt_test++;
 
 
    // create test program in RAM
    // create test program in RAM
    static const uint32_t dummy_ext_program[2] __attribute__((aligned(8))) = {
    static const uint32_t dummy_ext_program[2] __attribute__((aligned(8))) = {
      0x3407D073, // csrwi mscratch, 15
      0x3407D073, // csrwi mscratch, 15
Line 510... Line 465...
 
 
  cnt_test++;
  cnt_test++;
 
 
  tmp_a = neorv32_cpu_csr_read(0xfff); // CSR 0xfff not implemented
  tmp_a = neorv32_cpu_csr_read(0xfff); // CSR 0xfff not implemented
 
 
  if (tmp_a != 0) {
 
    PRINT_CRITICAL("%c[1m<SECURITY FAILURE> %c[0m\n", 27, 27);
 
  }
 
 
 
  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 {
    test_fail();
    test_fail();
Line 561... Line 512...
    test_fail();
    test_fail();
  }
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test pending interrupt
 
  // ----------------------------------------------------------
 
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
  PRINT_STANDARD("[%i] Pending IRQ test (MTIME): ", cnt_test);
 
 
 
  cnt_test++;
 
 
 
  // disable global interrupts
 
  neorv32_cpu_dint();
 
 
 
  // prepare MTIME IRQ
 
  neorv32_mtime_set_time(0x00000000FFFFFFF8ULL); // prepare overflow
 
  neorv32_mtime_set_timecmp(0x0000000100000000ULL); // IRQ on overflow
 
 
 
  // wait some time for the IRQ to arrive the CPU
 
  asm volatile("nop");
 
  asm volatile("nop");
 
 
 
  // no more mtime interrupts
 
  neorv32_mtime_set_timecmp(-1);
 
 
 
  // re-enable global interrupts
 
  neorv32_cpu_eint();
 
 
 
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
 
    test_ok();
 
  }
 
  else {
 
    test_fail();
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
 
  // Unaligned instruction address
  // Unaligned instruction address
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] I_ALIGN (instr. alignment) EXC: ", cnt_test);
  PRINT_STANDARD("[%i] I_ALIGN (instr. alignment) EXC: ", cnt_test);
 
 
Line 606... Line 523...
  if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C)) == 0) {
  if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C)) == 0) {
 
 
    cnt_test++;
    cnt_test++;
 
 
    // call unaligned address
    // call unaligned address
    ((void (*)(void))ADDR_UNALIGNED)();
    ((void (*)(void))ADDR_UNALIGNED_2)();
 
    asm volatile("nop");
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_MISALIGNED) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_MISALIGNED) {
      PRINT_STANDARD("ok\n");
      test_ok();
      cnt_ok++;
 
    }
    }
    else {
    else {
      PRINT_STANDARD("fail\n");
      test_fail();
      cnt_fail++;
 
    }
    }
 
 
  }
  }
  else {
  else {
    PRINT_STANDARD("skipped (n.a. with C-ext)\n");
    PRINT_STANDARD("skipped (n.a. with C-ext)\n");
  }
  }
 
 
Line 648... Line 565...
  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++;
 
 
  // invalid instruction: using x0=x0 OP x0 with invalid opcode
  // not allowed outside of debug mode
  CUSTOM_INSTR_R2_TYPE(0b0000000, x0, x0, 0b000, x0, 0b1111111);
  asm volatile ("dret");
 
 
  // 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 actual instruction word
    // -> for illegal instructions mtval contains the failing instruction word
    if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x0000007f) {
    if (neorv32_cpu_csr_read(CSR_MTVAL) == 0x7b200073) {
      test_ok();
      test_ok();
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
Line 674... Line 591...
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] CI_ILLEG (illegal compr. instr.) EXC: ", cnt_test);
  PRINT_STANDARD("[%i] CI_ILLEG (illegal compr. instr.) EXC: ", cnt_test);
 
 
  // 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)) != 0) {
  if ((neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_C))) {
 
 
    cnt_test++;
    cnt_test++;
 
 
    // create test program in RAM
    // create test program in RAM
    static const uint32_t dummy_sub_program_ci[2] __attribute__((aligned(8))) = {
    static const uint32_t dummy_sub_program_ci[2] __attribute__((aligned(8))) = {
Line 724... Line 641...
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] L_ALIGN (load addr alignment) EXC: ", cnt_test);
  PRINT_STANDARD("[%i] L_ALIGN (load addr alignment) EXC: ", cnt_test);
  cnt_test++;
  cnt_test++;
 
 
  // load from unaligned address
  // load from unaligned address
  neorv32_cpu_load_unsigned_word(ADDR_UNALIGNED);
  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) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
Line 760... Line 677...
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] S_ALIGN (store addr alignment) EXC: ", cnt_test);
  PRINT_STANDARD("[%i] S_ALIGN (store addr alignment) EXC: ", cnt_test);
  cnt_test++;
  cnt_test++;
 
 
  // store to unaligned address
  // store to unaligned address
  asm volatile ("sw zero, %[input_i](zero)" :  : [input_i] "i" (ADDR_UNALIGNED));
  neorv32_cpu_store_unsigned_word(ADDR_UNALIGNED_2, 0);
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_MISALIGNED) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_MISALIGNED) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
Line 811... Line 728...
  // Environment call from U-mode
  // Environment call from U-mode
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] ENVCALL (ecall instr.) from U-mode EXC: ", cnt_test);
  PRINT_STANDARD("[%i] ENVCALL (ecall instr.) from U-mode EXC: ", cnt_test);
 
 
  // skip if U-mode is not implemented
 
  if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
 
 
    cnt_test++;
    cnt_test++;
 
 
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    neorv32_cpu_goto_user_mode();
    neorv32_cpu_goto_user_mode();
    {
    {
Line 829... Line 743...
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
 
 
  }
 
  else {
 
    PRINT_STANDARD("skipped (n.a. without U-ext)\n");
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Machine timer interrupt (MTIME)
  // Machine timer interrupt (MTIME)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] MTI (via MTIME): ", cnt_test);
  PRINT_STANDARD("[%i] MTI (via MTIME): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
  // configure MTIME IRQ (and check overflow form low owrd to high word)
  // configure MTIME IRQ (and check overflow from low word to high word)
  neorv32_mtime_set_timecmp(-1);
  neorv32_mtime_set_timecmp(-1);
  neorv32_mtime_set_time(0);
  neorv32_mtime_set_time(0);
 
 
  neorv32_cpu_csr_write(CSR_MIP, 0); // clear all pending IRQs
  // enable interrupt
 
 
  neorv32_mtime_set_timecmp(0x0000000100000000ULL);
  neorv32_mtime_set_timecmp(0x0000000100000000ULL);
  neorv32_mtime_set_time(   0x00000000FFFFFFFEULL);
  neorv32_mtime_set_time(   0x00000000FFFFFFFEULL);
 
  neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
 
  // wait some time for the IRQ to trigger and arrive the CPU
  // wait some time for the IRQ to trigger and arrive the CPU
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
 
  asm volatile("nop");
  // disable interrupt
 
  neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
Line 877... Line 787...
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] MSI (via testbench): ", cnt_test);
  PRINT_STANDARD("[%i] MSI (via testbench): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
 
  // enable interrupt
 
  neorv32_cpu_irq_enable(CSR_MIE_MSIE);
 
 
  // trigger IRQ
  // trigger IRQ
  sim_irq_trigger(1 << CSR_MIE_MSIE);
  sim_irq_trigger(1 << CSR_MIE_MSIE);
 
 
  // wait some time for the IRQ to arrive the CPU
  // wait some time for the IRQ to arrive the CPU
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
 
 
 
  // disable interrupt
 
  neorv32_cpu_irq_disable(CSR_MIE_MSIE);
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MSI) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MSI) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
    test_fail();
    test_fail();
Line 900... Line 816...
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] MEI (via testbench): ", cnt_test);
  PRINT_STANDARD("[%i] MEI (via testbench): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
 
  // enable interrupt
 
  neorv32_cpu_irq_enable(CSR_MIE_MEIE);
 
 
  // trigger IRQ
  // trigger IRQ
  sim_irq_trigger(1 << CSR_MIE_MEIE);
  sim_irq_trigger(1 << CSR_MIE_MEIE);
 
 
  // wait some time for the IRQ to arrive the CPU
  // wait some time for the IRQ to arrive the CPU
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
 
 
 
  // enable interrupt
 
  neorv32_cpu_irq_disable(CSR_MIE_MEIE);
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MEI) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MEI) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
    test_fail();
    test_fail();
  }
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Non-maskable interrupt (NMI) via testbench
  // Permanent IRQ (make sure interrupted program advances)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] NMI (via testbench): ", cnt_test);
  PRINT_STANDARD("[%i] Permanent IRQ (MTIME): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
  // trigger IRQ
  // fire MTIME IRQ
  sim_irq_trigger(1 << 0);
  neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
  neorv32_mtime_set_time(1); // prepare overflow
 
  neorv32_mtime_set_timecmp(0); // IRQ on overflow
 
 
 
  register int test_cnt = 0;
 
  while(test_cnt < 2) {
 
    test_cnt++;
 
  }
 
 
 
  // end MTIME IRQ
 
  neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
  neorv32_mtime_set_timecmp(-1);
 
 
 
  if (test_cnt == 2) {
 
    test_ok();
 
  }
 
  else {
 
    test_fail();
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
 
  // Test pending interrupt
 
  // ----------------------------------------------------------
 
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
  PRINT_STANDARD("[%i] Pending IRQ test (MTIME): ", cnt_test);
 
 
 
  cnt_test++;
 
 
 
  // enable interrupt
 
  neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
 
 
  // disable global interrupts
 
  neorv32_cpu_dint();
 
 
 
  // fire MTIME IRQ
 
  neorv32_mtime_set_time(1); // prepare overflow
 
  neorv32_mtime_set_timecmp(0); // IRQ on overflow
 
 
  // wait some time for the IRQ to arrive the CPU
  // wait some time for the IRQ to arrive the CPU
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
  asm volatile("nop");
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_NMI) {
  int was_pending = 0;
 
  if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CSR_MIP_MTIP)) { // should be pending now
 
    was_pending = 1;
 
  }
 
 
 
  // clear pending MTI
 
  neorv32_mtime_set_timecmp(-1);
 
 
 
  int is_pending = 0;
 
  if (neorv32_cpu_csr_read(CSR_MIP) & (1 << CSR_MIP_MTIP)) { // should NOT be pending anymore
 
    is_pending = 1;
 
  }
 
 
 
  neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
 
 
  if ((was_pending == 1) && (is_pending == 0)) {
    test_ok();
    test_ok();
  }
  }
  else {
  else {
    test_fail();
    test_fail();
  }
  }
 
 
 
  // re-enable global interrupts
 
  neorv32_cpu_eint();
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Fast interrupt channel 0 (WDT)
  // Fast interrupt channel 0 (WDT)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  if (neorv32_wdt_available()) {
  if (neorv32_wdt_available()) {
Line 952... Line 929...
    // enable fast interrupt
    // enable fast interrupt
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ0E);
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ0E);
 
 
    // configure WDT
    // configure WDT
    neorv32_wdt_setup(CLK_PRSC_4096, 0, 1); // highest clock prescaler, trigger IRQ on timeout, lock access
    neorv32_wdt_setup(CLK_PRSC_4096, 0, 1); // highest clock prescaler, trigger IRQ on timeout, lock access
    WDT_CT = 0; // try to deactivate WDT (should fail as access is loced)
    NEORV32_WDT.CTRL = 0; // try to deactivate WDT (should fail as access is loced)
    neorv32_wdt_force(); // force watchdog into action
    neorv32_wdt_force(); // force watchdog into action
 
 
    // wait some time for the IRQ to arrive the CPU
    // wait some time for the IRQ to arrive the CPU
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
Line 966... Line 943...
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
 
 
    // no more WDT interrupts
 
    neorv32_wdt_disable();
 
 
 
    // disable fast interrupt
    // disable fast interrupt
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ0E);
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ0E);
 
 
 
    // no more WDT interrupts
 
    neorv32_wdt_disable();
  }
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Fast interrupt channel 1 (CFS)
  // Fast interrupt channel 1 (CFS)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  PRINT_STANDARD("[%i] FIRQ1 test (via CFS): ", cnt_test);
  PRINT_STANDARD("[%i] FIRQ1 test (via CFS): ", cnt_test);
  PRINT_STANDARD("skipped (n.a.)\n");
  PRINT_STANDARD("skipped \n");
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Fast interrupt channel 2 (UART0.RX)
  // Fast interrupt channel 2 (UART0.RX)
  // ----------------------------------------------------------
  // ----------------------------------------------------------
Line 997... Line 974...
 
 
    // wait for UART0 to finish transmitting
    // wait for UART0 to finish transmitting
    while(neorv32_uart0_tx_busy());
    while(neorv32_uart0_tx_busy());
 
 
    // backup current UART0 configuration
    // backup current UART0 configuration
    tmp_a = UART0_CT;
    tmp_a = NEORV32_UART0.CTRL;
 
 
    // make sure UART is enabled
    // make sure UART is enabled
    UART0_CT |= (1 << UART_CT_EN);
    NEORV32_UART0.CTRL |= (1 << UART_CTRL_EN);
    // make sure sim mode is disabled
    // make sure sim mode is disabled
    UART0_CT &= ~(1 << UART_CT_SIM_MODE);
    NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
 
    // trigger UART0 RX IRQ
    // trigger UART0 RX IRQ
    neorv32_uart0_putc(0);
    neorv32_uart0_putc(0);
 
 
    // wait for UART0 to finish transmitting
    // wait for UART0 to finish transmitting
Line 1015... Line 992...
    // wait some time for the IRQ to arrive the CPU
    // wait some time for the IRQ to arrive the CPU
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
 
 
    // restore original configuration
    // restore original configuration
    UART0_CT = tmp_a;
    NEORV32_UART0.CTRL = tmp_a;
 
 
    // disable fast interrupt
    // disable fast interrupt
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ2E);
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ2E);
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_2) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_2) {
Line 1045... Line 1022...
 
 
    // wait for UART0 to finish transmitting
    // wait for UART0 to finish transmitting
    while(neorv32_uart0_tx_busy());
    while(neorv32_uart0_tx_busy());
 
 
    // backup current UART0 configuration
    // backup current UART0 configuration
    tmp_a = UART0_CT;
    tmp_a = NEORV32_UART0.CTRL;
 
 
    // make sure UART is enabled
    // make sure UART is enabled
    UART0_CT |= (1 << UART_CT_EN);
    NEORV32_UART0.CTRL |= (1 << UART_CTRL_EN);
    // make sure sim mode is disabled
    // make sure sim mode is disabled
    UART0_CT &= ~(1 << UART_CT_SIM_MODE);
    NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
 
    // trigger UART0 TX IRQ
    // trigger UART0 TX IRQ
    neorv32_uart0_putc(0);
    neorv32_uart0_putc(0);
 
 
    // wait for UART to finish transmitting
    // wait for UART to finish transmitting
Line 1063... Line 1040...
    // wait some time for the IRQ to arrive the CPU
    // wait some time for the IRQ to arrive the CPU
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
 
 
    // restore original configuration
    // restore original configuration
    UART0_CT = tmp_a;
    NEORV32_UART0.CTRL = tmp_a;
 
 
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ3E);
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ3E);
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_3) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_3) {
      test_ok();
      test_ok();
Line 1089... Line 1066...
 
 
    // UART1 RX interrupt enable
    // UART1 RX interrupt enable
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ4E);
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ4E);
 
 
    // backup current UART1 configuration
    // backup current UART1 configuration
    tmp_a = UART1_CT;
    tmp_a = NEORV32_UART1.CTRL;
 
 
    // make sure UART is enabled
    // make sure UART is enabled
    UART1_CT |= (1 << UART_CT_EN);
    NEORV32_UART1.CTRL |= (1 << UART_CTRL_EN);
    // make sure sim mode is disabled
    // make sure sim mode is disabled
    UART1_CT &= ~(1 << UART_CT_SIM_MODE);
    NEORV32_UART1.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
 
    // trigger UART1 RX IRQ
    // trigger UART1 RX IRQ
    neorv32_uart1_putc(0);
    neorv32_uart1_putc(0);
 
 
    // wait for UART1 to finish transmitting
    // wait for UART1 to finish transmitting
Line 1107... Line 1084...
    // wait some time for the IRQ to arrive the CPU
    // wait some time for the IRQ to arrive the CPU
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
 
 
    // restore original configuration
    // restore original configuration
    UART1_CT = tmp_a;
    NEORV32_UART1.CTRL = tmp_a;
 
 
    // disable fast interrupt
    // disable fast interrupt
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ4E);
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ4E);
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_4) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_4) {
Line 1134... Line 1111...
 
 
    // UART1 RX interrupt enable
    // UART1 RX interrupt enable
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ5E);
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ5E);
 
 
    // backup current UART1 configuration
    // backup current UART1 configuration
    tmp_a = UART1_CT;
    tmp_a = NEORV32_UART1.CTRL;
 
 
    // make sure UART is enabled
    // make sure UART is enabled
    UART1_CT |= (1 << UART_CT_EN);
    NEORV32_UART1.CTRL |= (1 << UART_CTRL_EN);
    // make sure sim mode is disabled
    // make sure sim mode is disabled
    UART1_CT &= ~(1 << UART_CT_SIM_MODE);
    NEORV32_UART1.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
 
 
    // trigger UART1 TX IRQ
    // trigger UART1 TX IRQ
    neorv32_uart1_putc(0);
    neorv32_uart1_putc(0);
 
 
    // wait for UART1 to finish transmitting
    // wait for UART1 to finish transmitting
Line 1152... Line 1129...
    // wait some time for the IRQ to arrive the CPU
    // wait some time for the IRQ to arrive the CPU
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
    asm volatile("nop");
 
 
    // restore original configuration
    // restore original configuration
    UART1_CT = tmp_a;
    NEORV32_UART1.CTRL = tmp_a;
 
 
    // disable fast interrupt
    // disable fast interrupt
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ5E);
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ5E);
 
 
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_5) {
    if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_5) {
Line 1256... Line 1233...
 
 
    xirq_err_cnt += neorv32_xirq_setup(); // initialize XIRQ
    xirq_err_cnt += neorv32_xirq_setup(); // initialize XIRQ
    xirq_err_cnt += neorv32_xirq_install(0, xirq_trap_handler0); // install XIRQ IRQ handler channel 0
    xirq_err_cnt += neorv32_xirq_install(0, xirq_trap_handler0); // install XIRQ IRQ handler channel 0
    xirq_err_cnt += neorv32_xirq_install(1, xirq_trap_handler1); // install XIRQ IRQ handler channel 1
    xirq_err_cnt += neorv32_xirq_install(1, xirq_trap_handler1); // install XIRQ IRQ handler channel 1
 
 
    neorv32_xirq_global_enable(); // enable XIRQ FIRQ
    // enable XIRQ FIRQ
 
    neorv32_cpu_irq_enable(CSR_MIE_FIRQ8E);
 
 
    // trigger XIRQ channel 1 and 0
    // trigger XIRQ channel 1 and 0
    neorv32_gpio_port_set(3);
    neorv32_gpio_port_set(3);
 
 
    // wait for IRQs to arrive CPU
    // wait for IRQs to arrive CPU
Line 1275... Line 1253...
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
 
 
    neorv32_xirq_global_disable();
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ8E);
    XIRQ_IER = 0;
    NEORV32_XIRQ.IER = 0;
    XIRQ_IPR = -1;
    NEORV32_XIRQ.IPR = -1;
  }
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Fast interrupt channel 9 (NEOLED)
  // Fast interrupt channel 9 (NEOLED)
Line 1294... Line 1272...
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  if (neorv32_slink_available()) {
  if (neorv32_slink_available()) {
    neorv32_cpu_csr_write(CSR_MCAUSE, 0);
    neorv32_cpu_csr_write(CSR_MCAUSE, 0);
    PRINT_STANDARD("[%i] FIRQ10 & 11 (SLINK): ", cnt_test);
    PRINT_STANDARD("[%i] FIRQ10 & 11 (SLINK): ", cnt_test);
 
 
 
    // NOTE: this test requires FIFO sizes = 1
 
 
    cnt_test++;
    cnt_test++;
 
 
    // enable SLINK
    // enable SLINK
    neorv32_slink_enable();
    neorv32_slink_enable();
 
 
Line 1332... Line 1312...
      test_fail();
      test_fail();
    }
    }
 
 
    // shutdown SLINK
    // shutdown SLINK
    neorv32_slink_disable();
    neorv32_slink_disable();
 
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ10E);
 
    neorv32_cpu_irq_disable(CSR_MIE_FIRQ11E);
  }
  }
 
 
 
 
//// ----------------------------------------------------------
//// ----------------------------------------------------------
//// Fast interrupt channel 12..15 (reserved)
//// Fast interrupt channel 12..15 (reserved)
Line 1350... Line 1332...
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] WFI (sleep instruction) test (wake-up via MTIME): ", cnt_test);
  PRINT_STANDARD("[%i] WFI (sleep instruction) test (wake-up via MTIME): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
  // program wake-up timer
 
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 1000);
 
 
 
  // clear timeout wait flag
  // clear timeout wait flag
  tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
  tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
  tmp_a &= ~(1 << CSR_MSTATUS_TW);
  tmp_a &= ~(1 << CSR_MSTATUS_TW);
  neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
  neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
 
 
 
  // program wake-up timer
 
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 500);
 
 
 
  // enable interrupt
 
  neorv32_cpu_irq_enable(CSR_MIE_MTIE);
 
 
  // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
  // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
  neorv32_cpu_goto_user_mode();
  neorv32_cpu_goto_user_mode();
  {
  {
    // only when mstatus.TW = 0 executing WFI in user mode is allowed
    // only when mstatus.TW = 0 executing WFI in user mode is allowed
    asm volatile ("wfi"); // put CPU into sleep mode
    asm volatile ("wfi"); // put CPU into sleep mode
  }
  }
 
 
 
  // no more mtime interrupts
 
  neorv32_cpu_irq_disable(CSR_MIE_MTIE);
 
  neorv32_mtime_set_timecmp(-1);
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_MTI) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_MTI) {
    test_fail();
    test_fail();
  }
  }
  else {
  else {
    test_ok();
    test_ok();
  }
  }
 
 
  // no more mtime interrupts
 
  neorv32_mtime_set_timecmp(-1);
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test invalid CSR access in user mode
  // Test invalid CSR access in user mode
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] Invalid CSR access (mstatus) from user mode: ", cnt_test);
  PRINT_STANDARD("[%i] Invalid CSR access (mstatus) from user mode: ", cnt_test);
 
 
  // skip if U-mode is not implemented
 
  if (neorv32_cpu_csr_read(CSR_MISA) & (1<<CSR_MISA_U)) {
 
 
 
    cnt_test++;
    cnt_test++;
 
 
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    neorv32_cpu_goto_user_mode();
    neorv32_cpu_goto_user_mode();
    {
    {
      // access to misa not allowed for user-level programs
      // access to misa not allowed for user-level programs
      tmp_a = neorv32_cpu_csr_read(CSR_MISA);
      tmp_a = neorv32_cpu_csr_read(CSR_MISA);
    }
    }
 
 
    if (tmp_a != 0) {
 
      PRINT_CRITICAL("%c[1m<SECURITY FAILURE> %c[0m\n", 27, 27);
 
    }
 
 
 
    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 {
      test_fail();
      test_fail();
    }
    }
 
 
  }
 
  else {
 
    PRINT_STANDARD("skipped (n.a. without U-ext)\n");
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test RTE debug trap handler
  // Test RTE debug trap handler
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
Line 1454... Line 1428...
    cnt_test++;
    cnt_test++;
 
 
    // find out minimal region size (granularity)
    // find out minimal region size (granularity)
    tmp_b = neorv32_cpu_pmp_get_granularity();
    tmp_b = neorv32_cpu_pmp_get_granularity();
 
 
    tmp_a = SYSINFO_DSPACE_BASE; // base address of protected region
    tmp_a = NEORV32_SYSINFO.DSPACE_BASE; // base address of protected region
    PRINT_STANDARD("Creating protected page (NAPOT, [!X,!W,!R], %u bytes) @ 0x%x: ", tmp_b, tmp_a);
    PRINT_STANDARD("Creating protected page (NAPOT, [!X,!W,!R], %u bytes) @ 0x%x: ", tmp_b, tmp_a);
 
 
    // configure
    // configure
    int pmp_return = neorv32_cpu_pmp_configure_region(0, tmp_a, tmp_b, 0b00011000); // NAPOT, NO read permission, NO write permission, and NO execute permissions
    int pmp_return = neorv32_cpu_pmp_configure_region(0, tmp_a, tmp_b, 0b00011000); // NAPOT, NO read permission, NO write permission, and NO execute permissions
 
 
Line 1500... Line 1474...
    cnt_test++;
    cnt_test++;
    neorv32_cpu_csr_write(CSR_MCAUSE, 0);
    neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
 
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    // switch to user mode (hart will be back in MACHINE mode when trap handler returns)
    neorv32_cpu_goto_user_mode();
    neorv32_cpu_goto_user_mode();
 
    tmp_b = 0;
    {
    {
      tmp_b = neorv32_cpu_load_unsigned_word(tmp_a); // load access -> should fail
      tmp_b = neorv32_cpu_load_unsigned_word(tmp_a); // load access -> should fail
    }
    }
 
 
    if (tmp_b != 0) {
    if (tmp_b != 0) {
Line 1730... Line 1705...
 * @param[in] sel IRQ select mask (bit positions according to #NEORV32_CSR_MIE_enum).
 * @param[in] sel IRQ select mask (bit positions according to #NEORV32_CSR_MIE_enum).
 **************************************************************************/
 **************************************************************************/
void sim_irq_trigger(uint32_t sel) {
void sim_irq_trigger(uint32_t sel) {
 
 
  *(IO_REG32 (0xFF000000)) = sel;
  *(IO_REG32 (0xFF000000)) = sel;
 
  asm volatile("nop"); // interrupt should kick in here (latest)
 
  *(IO_REG32 (0xFF000000)) = 0;
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Trap handler for ALL exceptions/interrupts.
 * Trap handler for ALL exceptions/interrupts.
Line 1790... Line 1767...
 * test report to physical UART
 * test report to physical UART
 **************************************************************************/
 **************************************************************************/
int __neorv32_crt0_after_main(int32_t return_code) {
int __neorv32_crt0_after_main(int32_t return_code) {
 
 
  // make sure sim mode is disabled and UARTs are actually enabled
  // make sure sim mode is disabled and UARTs are actually enabled
  UART0_CT |=  (1 << UART_CT_EN);
  NEORV32_UART0.CTRL |=  (1 << UART_CTRL_EN);
  UART0_CT &= ~(1 << UART_CT_SIM_MODE);
  NEORV32_UART0.CTRL &= ~(1 << UART_CTRL_SIM_MODE);
  UART1_CT = UART0_CT;
  NEORV32_UART1.CTRL = NEORV32_UART0.CTRL;
 
 
  // minimal result report
  // minimal result report
  PRINT_CRITICAL("%u/%u\n", (uint32_t)return_code, (uint32_t)cnt_test);
  PRINT_CRITICAL("%u/%u\n", (uint32_t)return_code, (uint32_t)cnt_test);
 
 
  return 0;
  return 0;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.