Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtl] set mtval CSR to zero on ebreak instructions #289

Merged
merged 5 commits into from
Mar 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
63 changes: 32 additions & 31 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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**
...................................
Expand Down Expand Up @@ -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**
|=======================


Expand Down
11 changes: 5 additions & 6 deletions docs/datasheet/cpu_csr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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!:
Expand Down
6 changes: 2 additions & 4 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -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 -------------------------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion sim/run_riscv_arch_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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'
Expand Down
13 changes: 9 additions & 4 deletions sw/isa-test/port-neorv32/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# 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:

* replace the original processor's IMEM rtl file by a simulation-optimized IMEM (ROM!)
* `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`
Expand All @@ -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.
4 changes: 4 additions & 0 deletions sw/isa-test/port-neorv32/model_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
00000000
11111111
0000008f
00000003
00000108
00000000
00000000
00000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
00000000
11111111
0000008f
00000003
00000108
00000000
00000000
00000000