From b9ae056e38ad1e71403b79bed4892776b1971202 Mon Sep 17 00:00:00 2001 From: stnolting Date: Mon, 14 Mar 2022 08:46:11 +0100 Subject: [PATCH 1/5] set mtval CSR to zero on ebreak instruction --- rtl/core/neorv32_cpu_control.vhd | 6 ++---- rtl/core/neorv32_package.vhd | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/rtl/core/neorv32_cpu_control.vhd b/rtl/core/neorv32_cpu_control.vhd index eff895175..4449ed442 100644 --- a/rtl/core/neorv32_cpu_control.vhd +++ b/rtl/core/neorv32_cpu_control.vhd @@ -2130,16 +2130,14 @@ begin -- trap value -- cause_v := trap_ctrl.cause; - cause_v(5) := '0'; -- bit 5 is always zero here (= normal trapping), so we do not need to check that again + cause_v(5) := '0'; -- bit 5 is always zero here (= normal trapping / no debug-mode-entry), so we do not need to check that again case cause_v is when trap_ima_c | trap_iba_c => -- misaligned instruction address OR instruction access error csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction - when trap_brk_c => -- breakpoint - csr.mtval <= execute_engine.pc_last(data_width_c-1 downto 1) & '0'; -- address of breakpoint instruction when trap_lma_c | trap_lbe_c | trap_sma_c | trap_sbe_c => -- misaligned load/store address OR load/store access error csr.mtval <= mar_i; -- faulting data access address when trap_iil_c => -- illegal instruction - csr.mtval <= execute_engine.i_reg_last; -- faulting instruction itself + csr.mtval <= execute_engine.i_reg_last; -- faulting instruction word (decompressed if C-instruction) when others => -- everything else including all interrupts csr.mtval <= (others => '0'); end case; diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 1f85f8ea6..828568479 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -65,7 +65,7 @@ package neorv32_package is -- Architecture Constants (do not modify!) ------------------------------------------------ -- ------------------------------------------------------------------------------------------- constant data_width_c : natural := 32; -- native data path width - do not change! - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060900"; -- no touchy! + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060901"; -- no touchy! constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off! -- Check if we're inside the Matrix ------------------------------------------------------- From ae7caee8a633e2fa984c357ece7ba3ee58357087 Mon Sep 17 00:00:00 2001 From: stnolting Date: Mon, 14 Mar 2022 08:58:07 +0100 Subject: [PATCH 2/5] update mtval = zero for SW breakpoints --- docs/datasheet/cpu.adoc | 63 +++++++++++++++++++------------------ docs/datasheet/cpu_csr.adoc | 11 +++---- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/docs/datasheet/cpu.adoc b/docs/datasheet/cpu.adoc index d715833dc..9459967bb 100644 --- a/docs/datasheet/cpu.adoc +++ b/docs/datasheet/cpu.adoc @@ -180,7 +180,7 @@ Check blt-01 ... OK Check bltu-01 ... OK Check bne-01 ... OK Check fence-01 ... OK -Check jal-01 ... OK +Check jal-01 ... IGNORED <1> Check jalr-01 ... OK Check lb-align-01 ... OK Check lbu-align-01 ... OK @@ -210,6 +210,7 @@ Check fence-01 ... OK -------------------------------- OK: 39/39 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32 ................................... +<1> Test is skipped due to a GHDL simulation issue. .**RISC-V `rv32_m/M` Tests** ................................... @@ -969,38 +970,38 @@ be used in plain C code. The "`mepc`" and "`mtval`" columns show the value writt [cols="3,6,5,14,11,4,4"] [options="header",grid="rows"] |======================= -| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval` +| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval` 7+^| **Synchronous Exceptions** -| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | **PC** | **ADR** -| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access bus fault | **PC** | **ADR** -| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | **PC** | **INST** -| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode | **PC** | **0** -| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode | **PC** | **0** -| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint instruction | **PC** | **PC** -| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | **PC** | **ADR** -| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | **PC** | **ADR** -| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access bus fault | **PC** | **ADR** -| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access bus fault | **PC** | **ADR** +| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | **PC** | **ADR** +| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access bus fault | **PC** | **ADR** +| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | **PC** | **INST** +| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode (`ecall`) | **PC** | **0** +| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode (`ecall`) | **PC** | **0** +| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | software breakpoint (`ebreak`) | **PC** | **0** +| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | **PC** | **ADR** +| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | **PC** | **ADR** +| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access bus fault | **PC** | **ADR** +| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access bus fault | **PC** | **ADR** 7+^| **Asynchronous Exceptions (Interrupts)** -| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | **IPC** | **0** -| 12 | `0x80000011` | 1.17 | _TRAP_CODE_FIRQ_1_ | fast interrupt request channel 1 | **IPC** | **0** -| 13 | `0x80000012` | 1.18 | _TRAP_CODE_FIRQ_2_ | fast interrupt request channel 2 | **IPC** | **0** -| 14 | `0x80000013` | 1.19 | _TRAP_CODE_FIRQ_3_ | fast interrupt request channel 3 | **IPC** | **0** -| 15 | `0x80000014` | 1.20 | _TRAP_CODE_FIRQ_4_ | fast interrupt request channel 4 | **IPC** | **0** -| 16 | `0x80000015` | 1.21 | _TRAP_CODE_FIRQ_5_ | fast interrupt request channel 5 | **IPC** | **0** -| 17 | `0x80000016` | 1.22 | _TRAP_CODE_FIRQ_6_ | fast interrupt request channel 6 | **IPC** | **0** -| 18 | `0x80000017` | 1.23 | _TRAP_CODE_FIRQ_7_ | fast interrupt request channel 7 | **IPC** | **0** -| 19 | `0x80000018` | 1.24 | _TRAP_CODE_FIRQ_8_ | fast interrupt request channel 8 | **IPC** | **0** -| 20 | `0x80000019` | 1.25 | _TRAP_CODE_FIRQ_9_ | fast interrupt request channel 9 | **IPC** | **0** -| 21 | `0x8000001a` | 1.26 | _TRAP_CODE_FIRQ_10_ | fast interrupt request channel 10 | **IPC** | **0** -| 22 | `0x8000001b` | 1.27 | _TRAP_CODE_FIRQ_11_ | fast interrupt request channel 11 | **IPC** | **0** -| 23 | `0x8000001c` | 1.28 | _TRAP_CODE_FIRQ_12_ | fast interrupt request channel 12 | **IPC** | **0** -| 24 | `0x8000001d` | 1.29 | _TRAP_CODE_FIRQ_13_ | fast interrupt request channel 13 | **IPC** | **0** -| 25 | `0x8000001e` | 1.30 | _TRAP_CODE_FIRQ_14_ | fast interrupt request channel 14 | **IPC** | **0** -| 26 | `0x8000001f` | 1.31 | _TRAP_CODE_FIRQ_15_ | fast interrupt request channel 15 | **IPC** | **0** -| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt (MEI) | **IPC** | **0** -| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt (MSI) | **IPC** | **0** -| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt (MTI) | **IPC** | **0** +| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | **IPC** | **0** +| 12 | `0x80000011` | 1.17 | _TRAP_CODE_FIRQ_1_ | fast interrupt request channel 1 | **IPC** | **0** +| 13 | `0x80000012` | 1.18 | _TRAP_CODE_FIRQ_2_ | fast interrupt request channel 2 | **IPC** | **0** +| 14 | `0x80000013` | 1.19 | _TRAP_CODE_FIRQ_3_ | fast interrupt request channel 3 | **IPC** | **0** +| 15 | `0x80000014` | 1.20 | _TRAP_CODE_FIRQ_4_ | fast interrupt request channel 4 | **IPC** | **0** +| 16 | `0x80000015` | 1.21 | _TRAP_CODE_FIRQ_5_ | fast interrupt request channel 5 | **IPC** | **0** +| 17 | `0x80000016` | 1.22 | _TRAP_CODE_FIRQ_6_ | fast interrupt request channel 6 | **IPC** | **0** +| 18 | `0x80000017` | 1.23 | _TRAP_CODE_FIRQ_7_ | fast interrupt request channel 7 | **IPC** | **0** +| 19 | `0x80000018` | 1.24 | _TRAP_CODE_FIRQ_8_ | fast interrupt request channel 8 | **IPC** | **0** +| 20 | `0x80000019` | 1.25 | _TRAP_CODE_FIRQ_9_ | fast interrupt request channel 9 | **IPC** | **0** +| 21 | `0x8000001a` | 1.26 | _TRAP_CODE_FIRQ_10_ | fast interrupt request channel 10 | **IPC** | **0** +| 22 | `0x8000001b` | 1.27 | _TRAP_CODE_FIRQ_11_ | fast interrupt request channel 11 | **IPC** | **0** +| 23 | `0x8000001c` | 1.28 | _TRAP_CODE_FIRQ_12_ | fast interrupt request channel 12 | **IPC** | **0** +| 24 | `0x8000001d` | 1.29 | _TRAP_CODE_FIRQ_13_ | fast interrupt request channel 13 | **IPC** | **0** +| 25 | `0x8000001e` | 1.30 | _TRAP_CODE_FIRQ_14_ | fast interrupt request channel 14 | **IPC** | **0** +| 26 | `0x8000001f` | 1.31 | _TRAP_CODE_FIRQ_15_ | fast interrupt request channel 15 | **IPC** | **0** +| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt (MEI) | **IPC** | **0** +| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt (MSI) | **IPC** | **0** +| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt (MTI) | **IPC** | **0** |======================= diff --git a/docs/datasheet/cpu_csr.adoc b/docs/datasheet/cpu_csr.adoc index 596299950..00c2c5b19 100644 --- a/docs/datasheet/cpu_csr.adoc +++ b/docs/datasheet/cpu_csr.adoc @@ -422,8 +422,8 @@ interrupt) this register provides the address of the next not-yet-executed instr | 0x343 | **Machine bad address or instruction** | `mtval` 3+| Reset value: _UNDEFINED_ 3+| The `mtval` CSR is compatible to the RISC-V specifications. When a trap is triggered, the CSR shows either -the faulting address (for misaligned/faulting load/stores/fetch) or the faulting instruction itself (for illegal -instructions). For interrupts the CSR is set to zero. +the faulting address (for misaligned/faulting load/store/fetch) or the faulting instruction word itself (for illegal +instructions). For all other exceptions (including interrupts) the CSR is set to zero. |======================= .Machine bad address or instruction register @@ -432,13 +432,12 @@ instructions). For interrupts the CSR is set to zero. |======================= | Trap cause | `mtval` content | misaligned instruction fetch address or instruction fetch access fault | address of faulting instruction fetch -| breakpoint | program counter (= address) of faulting instruction itself -| misaligned load address, load access fault, misaligned store address or store access fault | program counter (= address) of faulting instruction itself -| illegal instruction | actual instruction word of faulting instruction +| misaligned load address, load access fault, misaligned store address or store access fault | program counter (= address) of faulting instruction +| illegal instruction | actual instruction word of faulting instruction (decoded 32-bit instruction word if caused by a compressed instruction) | anything else including interrupts | _0x00000000_ (always zero) |======================= -[IMPORTAN] +[IMPORTANT] The NEORV32 `mtval` CSR is read-only. However, a write access will _NOT_ raise an illegal instruction exception. :sectnums!: From 259dfad538da1ccb2f2be0fb87e55fd95f24f0b3 Mon Sep 17 00:00:00 2001 From: stnolting Date: Mon, 14 Mar 2022 09:24:50 +0100 Subject: [PATCH 3/5] add NEORV32-specific test references --- sim/run_riscv_arch_test.sh | 11 ++++++++--- sw/isa-test/port-neorv32/README.md | 13 +++++++++---- sw/isa-test/port-neorv32/model_test.h | 4 ++++ .../C/references/cebreak-01.reference_output | 8 ++++++++ .../privilege/references/ebreak.reference_output | 8 ++++++++ 5 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/C/references/cebreak-01.reference_output create mode 100644 sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/privilege/references/ebreak.reference_output diff --git a/sim/run_riscv_arch_test.sh b/sim/run_riscv_arch_test.sh index 227c11f9e..00b134556 100755 --- a/sim/run_riscv_arch_test.sh +++ b/sim/run_riscv_arch_test.sh @@ -16,8 +16,8 @@ RISCV_PREFIX="${RISCV_PREFIX:-riscv32-unknown-elf-}" header "Checking RISC-V GCC toolchain" "$RISCV_PREFIX"gcc -v -header "Checking 'riscv-arch-test' GitHub repository (submodule)" -git submodule update --init +#header "Checking 'riscv-arch-test' GitHub repository (submodule)" +#git submodule update --remote header "Copying neorv32 test-target into riscv-arch-test framework" ( @@ -25,6 +25,8 @@ header "Copying neorv32 test-target into riscv-arch-test framework" target_device='riscv-arch-test/riscv-target/neorv32' if [ -d "$target_device" ]; then rm -rf "$target_device"; fi cp -vr port-neorv32 "$target_device" + cp -f port-neorv32/riscv-test-suite/rv32i_m/C/references/* riscv-arch-test/riscv-test-suite/rv32i_m/C/references + cp -f port-neorv32/riscv-test-suite/rv32i_m/privilege/references/* riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references ) header "Making local copy of NEORV32 'rtl' and 'sim' folders" @@ -40,7 +42,10 @@ header "Starting RISC-V architecture tests" ./simple/ghdl.setup.sh # work in progress FIXME -printf "\n\e[1;33mWARNING! 'I/jal-01' test is currently disabled (GHDL simulation issue)! \e[0m\n\n" +printf "\n\e[1;33m[WARNING] 'I/jal-01' test is currently disabled (GHDL simulation issue)! \e[0m\n\n" +printf "\n\e[1;33m[WARNING] Overwriting default 'C/cebreak' and 'privilege/ebreak' test references! \e[0m\n\n" +sleep 4 + makeArgs="-C $(pwd)/../sw/isa-test/riscv-arch-test NEORV32_ROOT=$(pwd)/.. XLEN=32 RISCV_TARGET=neorv32" makeTargets='clean build run verify' diff --git a/sw/isa-test/port-neorv32/README.md b/sw/isa-test/port-neorv32/README.md index d263a245f..e3374bcc4 100644 --- a/sw/isa-test/port-neorv32/README.md +++ b/sw/isa-test/port-neorv32/README.md @@ -1,5 +1,8 @@ # NEORV32 Port for running the RISC-V Architecture Tests +**:warning: This folder might be _outsourced_ someday into an individual repository. Furthermore, the default +RISC-V architecture tests will be superseded by the RISCOF test framework. I am planning to make +a port for this new test framework.** The following tasks are executed by the device makefiles: @@ -7,6 +10,8 @@ The following tasks are executed by the device makefiles: * `sed` command is used to modify the default testbench (`neorv32/sim/neorv32_tb.simple.vhd`): * enable/disable the required `CPU_EXTENSION_RISCV_xxx` VHDL configuration generics in the testbench (`neorv32/sim/neorv32_tb.simple.vhd`) * set the processor memory configuration +* override the default frameworks reference data for `C/cebreak-01` and `privilege/ebreak` tests + * this is required as the NEORV32 sets `mtval` CSR to zero on software breakpoints * compile test code and install application image to processor's `rtl/core` folder * compilation uses the `link.imem_rom.ld` linker script as default; code (the test code) is executed from simulation-optimized IMEM (which is read-only); data including signature is stored to DMEM * certain areas in the DMEM are initialized using port code in `model_test.h` (`RVTEST` = 0xbabecafe and `SIGNATURE` = 0xdeadbeef); can be disabled using `RISCV_TARGET_FLAGS=-DNEORV32_NO_DATA_INIT` @@ -16,13 +21,13 @@ The following tasks are executed by the device makefiles: * data output (the "signature") is zero-padded to be always a multiple of 16 bytes -**Notes** +## Notes -:warning: The `Zifencei` test requires the r/w/e capabilities of the original IMEM rtl file. +:information_source: The `Zifencei` test requires the r/w/e capabilities of the original IMEM rtl file. Hence, the original file is restored for this test. Also, this test uses `link.imem_ram.ld` as linker script since the IMEM is used as RAM to allow self-modifying code. :information_source: The `RVMODEL_BOOT` macro in `model_test.h` provides a simple "dummy trap handler" that just advances to the next instruction. This trap handler is required for some `C` tests as the NEORV32 will raise an illegal instruction -exception for **all** unimplemented instructions. The trap handler can be overriden (by changing `mtval` CSR) if a test -uses the defualt trap handler of the test framework. +exception for **all** unimplemented instructions. The trap handler can be overridden (by changing `mtval` CSR) if a test +uses the default trap handler of the test framework. diff --git a/sw/isa-test/port-neorv32/model_test.h b/sw/isa-test/port-neorv32/model_test.h index 72a9255f6..b490432b5 100644 --- a/sw/isa-test/port-neorv32/model_test.h +++ b/sw/isa-test/port-neorv32/model_test.h @@ -2,6 +2,10 @@ // Modified by Stephan Nolting for the NEORV32 Processor +// override CODE_REL_TVAL_MSK to avoid PC adjustment for SW breakpoints (break instructions) +#define CODE_REL_TVAL_MSK 0xC008 << (REGWIDTH*8-16) + + #ifndef _COMPLIANCE_MODEL_H #define _COMPLIANCE_MODEL_H diff --git a/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/C/references/cebreak-01.reference_output b/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/C/references/cebreak-01.reference_output new file mode 100644 index 000000000..1fc1bf7ec --- /dev/null +++ b/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/C/references/cebreak-01.reference_output @@ -0,0 +1,8 @@ +00000000 +11111111 +0000008f +00000003 +00000108 +00000000 +00000000 +00000000 diff --git a/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/privilege/references/ebreak.reference_output b/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/privilege/references/ebreak.reference_output new file mode 100644 index 000000000..1fc1bf7ec --- /dev/null +++ b/sw/isa-test/port-neorv32/riscv-test-suite/rv32i_m/privilege/references/ebreak.reference_output @@ -0,0 +1,8 @@ +00000000 +11111111 +0000008f +00000003 +00000108 +00000000 +00000000 +00000000 From a15bf3bd32c6d20c50a0cf7cc351385168a9292a Mon Sep 17 00:00:00 2001 From: stnolting Date: Mon, 14 Mar 2022 09:25:20 +0100 Subject: [PATCH 4/5] add version 1.6.9.1 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 260f3f690..2d16c3f5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ The version number is globally defined by the `hw_version_c` constant in the mai | Date (*dd.mm.yyyy*) | Version | Comment | |:----------:|:-------:|:--------| +| 14.03.2022 | 1.6.9.1 | `mtval` CSR is set to zero for software breakpoints (`[c.]ebreak` instruction(s)) - this is permitted by the RISC-V machine ISA spec. v1.12; [PR #289](https://github.com/stnolting/neorv32/pull/289) | | 09.03.2022 | [**:rocket:1.6.9**](https://github.com/stnolting/neorv32/releases/tag/v1.6.9) | **New release** | | 09.03.2022 | 1.6.8.12 | CPU core: minor code clean-up | | 08.03.2022 | 1.6.8.11 | clean-up of CPU's privilege mode logic | From 3014c9710c72b1c3a1c86ea942599b2ba46587e2 Mon Sep 17 00:00:00 2001 From: stnolting Date: Mon, 14 Mar 2022 09:31:13 +0100 Subject: [PATCH 5/5] minor fix --- sim/run_riscv_arch_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/run_riscv_arch_test.sh b/sim/run_riscv_arch_test.sh index 00b134556..c0d576d9c 100755 --- a/sim/run_riscv_arch_test.sh +++ b/sim/run_riscv_arch_test.sh @@ -16,8 +16,8 @@ RISCV_PREFIX="${RISCV_PREFIX:-riscv32-unknown-elf-}" header "Checking RISC-V GCC toolchain" "$RISCV_PREFIX"gcc -v -#header "Checking 'riscv-arch-test' GitHub repository (submodule)" -#git submodule update --remote +header "Checking 'riscv-arch-test' GitHub repository (submodule)" +git submodule update --init header "Copying neorv32 test-target into riscv-arch-test framework" (