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

Subversion Repositories neorv32

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

Show entire file | Details | Blame | View Log

Rev 73 Rev 74
Line 215... Line 215...
  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");
 
 
  // sync (test)
 
  asm volatile ("fence.i");
 
 
 
  // enable global interrupts
  // enable global interrupts
  neorv32_cpu_eint();
  neorv32_cpu_eint();
 
 
 
 
  // **********************************************************************************************
  // **********************************************************************************************
  // Run CPU and SoC tests
  // Run CPU and SoC tests
  // **********************************************************************************************
  // **********************************************************************************************
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test fence instructions (just make sure CPU does not crash)
  // Test fence instructions 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
 
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
  PRINT_STANDARD("[%i] FENCE(.I): ", cnt_test);
 
 
 
  cnt_test++;
 
 
 
  asm volatile ("fence");
 
  asm volatile ("fence.i");
  asm volatile ("fence");
  asm volatile ("fence");
  asm volatile ("fence.i");
  asm volatile ("fence.i");
 
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
 
    test_ok();
 
  }
 
  else {
 
    test_fail();
 
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // 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);
Line 273... Line 284...
  else {
  else {
    PRINT_STANDARD("skipped (n.a.)\n");
    PRINT_STANDARD("skipped (n.a.)\n");
  }
  }
 
 
 
 
//// ----------------------------------------------------------
  // ----------------------------------------------------------
//// 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] cycle counter: ", cnt_test);
  PRINT_STANDARD("[%i] cycle counter: ", cnt_test);
//
 
//cnt_test++;
 
//
 
//// make sure counter is enabled
 
//asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
 
//
 
//// prepare overflow
 
//neorv32_cpu_set_mcycle(0x00000000FFFFFFFFULL);
 
//
 
//// get current cycle counter HIGH
 
//tmp_a = neorv32_cpu_csr_read(CSR_MCYCLEH);
 
//
 
//// make sure cycle counter high has incremented and there was no exception during access
 
//if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
 
//  test_ok();
 
//}
 
//else {
 
//  test_fail();
 
//}
 
 
 
 
  cnt_test++;
 
 
//// ----------------------------------------------------------
  // make sure counter is enabled
//// Test standard RISC-V performance counter [m]instret[h]
  asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_CY));
//// ----------------------------------------------------------
 
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  // prepare overflow
//PRINT_STANDARD("[%i] instret counter: ", cnt_test);
  neorv32_cpu_set_mcycle(0x00000000FFFFFFFFULL);
//
 
//cnt_test++;
  // get current cycle counter HIGH
//
  tmp_a = neorv32_cpu_csr_read(CSR_MCYCLEH);
//// make sure counter is enabled
 
//asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
  // make sure cycle counter high has incremented and there was no exception during access
//
  if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
//// prepare overflow
    test_ok();
//neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
  }
//
  else {
//// get instruction counter HIGH
    test_fail();
//tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
  }
//
 
//// make sure instruction counter high has incremented and there was no exception during access
 
//if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
  // ----------------------------------------------------------
//  test_ok();
  // Test standard RISC-V performance counter [m]instret[h]
//}
  // ----------------------------------------------------------
//else {
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//  test_fail();
  PRINT_STANDARD("[%i] instret counter: ", cnt_test);
//}
 
 
  cnt_test++;
 
 
 
  // make sure counter is enabled
 
  asm volatile ("csrci %[addr], %[imm]" : : [addr] "i" (CSR_MCOUNTINHIBIT), [imm] "i" (1<<CSR_MCOUNTINHIBIT_IR));
 
 
 
  // prepare overflow
 
  neorv32_cpu_set_minstret(0x00000000FFFFFFFFULL);
 
 
 
  // get instruction counter HIGH
 
  tmp_a = neorv32_cpu_csr_read(CSR_INSTRETH);
 
 
 
  // make sure instruction counter high has incremented and there was no exception during access
 
  if ((tmp_a == 1) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
 
    test_ok();
 
  }
 
  else {
 
    test_fail();
 
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test mcountinhibt: inhibit auto-inc of [m]cycle
  // Test mcountinhibt: inhibit auto-inc of [m]cycle
  // ----------------------------------------------------------
  // ----------------------------------------------------------
Line 374... Line 385...
  // 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
  neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
  neorv32_cpu_csr_write(CSR_MCOUNTEREN, tmp_a);
 
 
  neorv32_cpu_csr_write(CSR_CYCLEH, 1); // make sure CSR is != 0 for this test
  neorv32_cpu_csr_write(CSR_MCYCLE, 0);
 
  neorv32_cpu_csr_write(CSR_MCYCLEH, 123); // make sure CSR is != 0 for this 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)
  goto_user_mode();
  goto_user_mode();
  {
  {
    // access to cycle CSR is no longer allowed
    // access to cycle CSR is no longer allowed
    asm volatile (" li       %[result], 0xcc11aa22  \n" // initialize
    asm volatile (" li       %[result], 0xcc11aa22  \n" // initialize
                  " rdcycleh %[result]                " // read CSR_CYCLE, is not allowed and should not alter [result]
                  " csrrw %[result], cycleh, %[input]   " // read and write CSR_CYCLE, not allowed and should not alter [result] nor CSR
                  : [result] "=r" (tmp_a) : );
                  : [result] "=r" (tmp_a) : [input] "r" (tmp_a) );
  }
  }
 
 
  // 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) &&
 
      (neorv32_cpu_csr_read(CSR_CYCLEH) == 123) && // csr not altered
      (tmp_a == 0xcc11aa22)) { // destination register not altered
      (tmp_a == 0xcc11aa22)) { // destination register not altered
    test_ok();
    test_ok();
  }
  }
  else {
  else {
    test_fail();
    test_fail();
Line 497... Line 510...
  else {
  else {
    test_fail();
    test_fail();
  }
  }
 
 
 
 
//// ----------------------------------------------------------
  // ----------------------------------------------------------
//// No "real" CSR write access (because rs1 = r0)
  // No "real" CSR write access (because rs1 = r0)
//// ----------------------------------------------------------
  // ----------------------------------------------------------
//neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
//PRINT_STANDARD("[%i] Read-only CSR 'no-write' (rs1=0) access: ", cnt_test);
  PRINT_STANDARD("[%i] Read-only CSR 'no-write' (rs1=0) access: ", cnt_test);
//
 
//cnt_test++;
  cnt_test++;
//
 
//// time CSR is read-only, but no actual write is performed because rs1=r0
  // time CSR is read-only, but no actual write is performed because rs1=r0
//// -> should cause no exception
  // -> should cause no exception
//asm volatile("csrrs zero, time, zero");
  asm volatile("csrrs zero, time, zero");
//
 
//if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
//  test_ok();
    test_ok();
//}
  }
//else {
  else {
//  test_fail();
    test_fail();
//}
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Unaligned instruction address
  // Unaligned instruction address
  // ----------------------------------------------------------
  // ----------------------------------------------------------
Line 571... Line 584...
  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++;
 
 
  // illegal 32-bit instruction (malformed SRA)
  // clear mstatus.mie and set mstatus.mpie
 
  tmp_a = neorv32_cpu_csr_read(CSR_MSTATUS);
 
  tmp_a &= ~(1 << CSR_MSTATUS_MIE);
 
  tmp_a |=  (1 << CSR_MSTATUS_MPIE);
 
  neorv32_cpu_csr_write(CSR_MSTATUS, tmp_a);
 
 
 
  // illegal 32-bit instruction (MRET with incorrect opcode)
  asm volatile (".align 4 \n"
  asm volatile (".align 4 \n"
                ".word 0xC0000033");
                ".word 0x3020007f");
 
 
  // 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) && // illegal instruction exception
    // make sure this is really the instruction that caused the exception
      (neorv32_cpu_csr_read(CSR_MTVAL) == 0x3020007f) && // correct instruction word
    // -> for illegal instructions MTVAL contains the faulting instruction word
      ((neorv32_cpu_csr_read(CSR_MSTATUS) & (1 << CSR_MSTATUS_MIE)) == 0)) { // MIE should still be cleared
    if (neorv32_cpu_csr_read(CSR_MTVAL) == 0xC0000033) {
 
      test_ok();
      test_ok();
    }
    }
    else {
    else {
      test_fail();
      test_fail();
    }
    }
  }
 
  else {
  // clear mstatus.mie
    test_fail();
  neorv32_cpu_dint();
  }
 
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Illegal compressed instruction
  // Illegal compressed instruction
  // ----------------------------------------------------------
  // ----------------------------------------------------------
Line 1437... Line 1454...
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  // Test WFI ("sleep") instruction (executed in user mode), wakeup via MTIME
  // Test WFI ("sleep") instruction (executed in user mode), wakeup via MTIME
  // ----------------------------------------------------------
  // ----------------------------------------------------------
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
  PRINT_STANDARD("[%i] WFI (sleep instruction, wake-up via MTIME): ", cnt_test);
  PRINT_STANDARD("[%i] WFI (wake-up via MTIME): ", cnt_test);
 
 
  cnt_test++;
  cnt_test++;
 
 
  // program wake-up timer
  // program wake-up timer
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 500);
  neorv32_mtime_set_timecmp(neorv32_mtime_get_time() + 500);
Line 1469... Line 1486...
    test_ok();
    test_ok();
  }
  }
 
 
 
 
  // ----------------------------------------------------------
  // ----------------------------------------------------------
 
  // Test unallowed WFI ("sleep") instruction (executed in user mode)
 
  // ----------------------------------------------------------
 
  neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
  PRINT_STANDARD("[%i] WFI (not allowed in u-mode): ", cnt_test);
 
 
 
  cnt_test++;
 
 
 
  // set mstatus.TW to disallow execution of WFI in user-mode
 
  neorv32_cpu_csr_write(CSR_MSTATUS, neorv32_cpu_csr_read(CSR_MSTATUS) | (1<<CSR_MSTATUS_TW));
 
 
 
  // put CPU into sleep mode (from user mode)
 
  goto_user_mode();
 
  {
 
    asm volatile ("wfi"); // this has to fail
 
  }
 
 
 
  if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
 
    test_ok();
 
  }
 
  else {
 
    test_fail();
 
  }
 
 
 
 
 
  // ----------------------------------------------------------
  // 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);
 
 

powered by: WebSVN 2.1.0

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