Line 250... |
Line 250... |
==== RISC-V Incompatibility Issues and Limitations
|
==== RISC-V Incompatibility Issues and Limitations
|
|
|
This list shows the currently identified issues regarding full RISC-V-compatibility. More specific information
|
This list shows the currently identified issues regarding full RISC-V-compatibility. More specific information
|
can be found in section <<_instruction_sets_and_extensions>>.
|
can be found in section <<_instruction_sets_and_extensions>>.
|
|
|
.Hardwired R/W CSRs
|
.Read-Only "Read-Write" CSRs
|
[IMPORTANT]
|
[IMPORTANT]
|
The `misa`, `mip` and `mtval` CSRs in the NEORV32 are _read-only_.
|
The `misa` and `mtval` CSRs in the NEORV32 are _read-only_.
|
Any write access to it (in machine mode) to them are ignored and will _not_ cause any exceptions or side-effects.
|
Any machine-mode write access to them is ignored and will _not_ cause any exceptions or side-effects to maintain
|
Pending interrupt can only be cleared by acknowledging the interrupt-causing device. However, pending interrupts
|
RISC-V compatibility.
|
can still be ignored by clearing the according `mie` register bits.
|
|
|
|
.Physical memory protection
|
.Physical Memory Protection
|
[IMPORTANT]
|
[IMPORTANT]
|
The physical memory protection (see section <<_machine_physical_memory_protection>>)
|
The physical memory protection (see section <<_machine_physical_memory_protection>>)
|
only supports the modes _OFF_ and _NAPOT_ yet and a minimal granularity of 8 bytes per region.
|
only supports the modes _OFF_ and _NAPOT_ yet and a minimal granularity of 8 bytes per region.
|
|
|
.Atomic memory operations
|
.Atomic Memory Operations
|
[IMPORTANT]
|
[IMPORTANT]
|
The `A` CPU extension only implements the `lr.w` and `sc.w` instructions yet.
|
The `A` CPU extension only implements the `lr.w` and `sc.w` instructions yet.
|
However, these instructions are sufficient to emulate all further atomic memory operations.
|
However, these instructions are sufficient to emulate all further atomic memory operations.
|
|
|
.Bit-manipulation operations
|
.Bit-Manipulation ISA Extension
|
[IMPORTANT]
|
[IMPORTANT]
|
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
|
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
|
and the _address generation instructions_ (`Zba`) subset yet.
|
and the _address generation instructions_ (`Zba`) subset yet.
|
|
|
.Instruction Misalignment
|
|
[NOTE]
|
|
This is not a real RISC-V incompatibility, but something that might not be clear when studying the RISC-V privileged
|
|
architecture specifications: for 32-bit only instructions (no `C` extension) the misaligned instruction exception
|
|
is raised if bit 1 of the access address is set (i.e. not on 32-bit boundary). If the `C` extension is implemented
|
|
there will be no misaligned instruction exceptions _at all_.
|
|
In both cases bit 0 of the program counter and all related registers is hardwired to zero.
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== CPU Top Entity - Signals
|
=== CPU Top Entity - Signals
|
Line 298... |
Line 291... |
| Signal | Width | Dir. | Function
|
| Signal | Width | Dir. | Function
|
4+^| **Global Signals**
|
4+^| **Global Signals**
|
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
|
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
|
| `rstn_i` | 1 | in | global reset, low-active
|
| `rstn_i` | 1 | in | global reset, low-active
|
| `sleep_o` | 1 | out | CPU is in sleep mode when set
|
| `sleep_o` | 1 | out | CPU is in sleep mode when set
|
|
| `debug_o` | 1 | out | CPU is in debug mode when set
|
4+^| **Instruction Bus Interface (<<_bus_interface>>)**
|
4+^| **Instruction Bus Interface (<<_bus_interface>>)**
|
| `i_bus_addr_o` | 32 | out | destination address
|
| `i_bus_addr_o` | 32 | out | destination address
|
| `i_bus_rdata_i` | 32 | in | read data
|
| `i_bus_rdata_i` | 32 | in | read data
|
| `i_bus_wdata_o` | 32 | out | write data (always zero)
|
| `i_bus_wdata_o` | 32 | out | write data (always zero)
|
| `i_bus_ben_o` | 4 | out | byte enable
|
| `i_bus_ben_o` | 4 | out | byte enable
|
Line 559... |
Line 553... |
|
|
The NEORV32-specific extensions are always enabled and are indicated by the set `X` bit in the `misa` CSR.
|
The NEORV32-specific extensions are always enabled and are indicated by the set `X` bit in the `misa` CSR.
|
|
|
The most important points of the NEORV32-specific extensions are:
|
The most important points of the NEORV32-specific extensions are:
|
* The CPU provides 16 _fast interrupt_ interrupts (`FIRQ)`, which are controlled via custom bits in the `mie`
|
* The CPU provides 16 _fast interrupt_ interrupts (`FIRQ)`, which are controlled via custom bits in the `mie`
|
and `mip` CSR. This extension is mapped to _reserved_ CSR bits, that are available for custom use (according to the
|
and `mip` CSR. This extension is mapped to CSR bits, that are available for custom use (according to the
|
RISC-V specs). Also, custom trap codes for `mcause` are implemented.
|
RISC-V specs). Also, custom trap codes for `mcause` are implemented.
|
* All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception (see <<_full_virtualization>>).
|
* All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception (see <<_full_virtualization>>).
|
|
|
|
|
==== **`Zfinx`** Single-Precision Floating-Point Operations
|
==== **`Zfinx`** Single-Precision Floating-Point Operations
|
Line 778... |
Line 772... |
| Jumps / Calls | `I/E` | `jal` `jalr` | 4 + ML
|
| Jumps / Calls | `I/E` | `jal` `jalr` | 4 + ML
|
| Jumps / Calls | `C` | `c.jal` `c.j` `c.jr` `c.jalr` | 4 + ML
|
| Jumps / Calls | `C` | `c.jal` `c.j` `c.jr` `c.jalr` | 4 + ML
|
| Memory access | `I/E` | `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw` | 4 + ML
|
| Memory access | `I/E` | `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw` | 4 + ML
|
| Memory access | `C` | `c.lw` `c.sw` `c.lwsp` `c.swsp` | 4 + ML
|
| Memory access | `C` | `c.lw` `c.sw` `c.lwsp` `c.swsp` | 4 + ML
|
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
|
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
|
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+31+3; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 5
|
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+32+2; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 4
|
| Division | `M` | `div` `divu` `rem` `remu` | 22+32+4
|
| Division | `M` | `div` `divu` `rem` `remu` | 2+32+2
|
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 4
|
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 4
|
| System | `I/E`+`Zicsr` | `ecall` `ebreak` | 4
|
| System | `I/E`+`Zicsr` | `ecall` `ebreak` | 4
|
| System | `I/E` | `fence` | 3
|
| System | `I/E` | `fence` | 3
|
| System | `C`+`Zicsr` | `c.break` | 4
|
| System | `C`+`Zicsr` | `c.break` | 4
|
| System | `Zicsr` | `mret` `wfi` | 5
|
| System | `Zicsr` | `mret` `wfi` | 5
|
Line 834... |
Line 828... |
The traps are prioritized. If several _exceptions_ occur at once only the one with highest priority is triggered
|
The traps are prioritized. If several _exceptions_ occur at once only the one with highest priority is triggered
|
while all remaining exceptions are ignored. If several _interrupts_ trigger at once, the one with highest priority
|
while all remaining exceptions are ignored. If several _interrupts_ trigger at once, the one with highest priority
|
is serviced first while the remaining ones stay _pending_. After completing the interrupt handler the interrupt with
|
is serviced first while the remaining ones stay _pending_. After completing the interrupt handler the interrupt with
|
the second highest priority will get serviced and so on until no further interrupt are pending.
|
the second highest priority will get serviced and so on until no further interrupt are pending.
|
|
|
.Interrupt Signal Requirements
|
.Interrupt Signal Requirements - Standard RISC-V Interrupts
|
[IMPORTANT]
|
[IMPORTANT]
|
All interrupts request signals (including FIRQs) are **high-active**. A request has to stay at high-level (=asserted)
|
All standard RISC-V interrupts request signals are **high-active**. A request has to stay at high-level (=asserted)
|
until it is explicitly acknowledged by the CPU software (for example by writing to a specific memory-mapped register).
|
until it is explicitly acknowledged by the CPU software (for example by writing to a specific memory-mapped register).
|
|
|
|
.Interrupt Signal Requirements - Fast Interrupt Requests
|
|
[IMPORTANT]
|
|
The NEORV32-specific FIRQ request lines are triggered by a rising edge. Each request is buffered in the CPU control
|
|
unit until the channel is either disabled (by clearing the according `mie` CSR bit) or the request is explicitly cleared (by setting
|
|
the according `mip` CSR bit).
|
|
|
.Instruction Atomicity
|
.Instruction Atomicity
|
[NOTE]
|
[NOTE]
|
All instructions execute as atomic operations - interrupts can only trigger between two instructions.
|
All instructions execute as atomic operations - interrupts can only trigger between two instructions.
|
So if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before
|
So if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before
|
a new interrupt handler can start.
|
a new interrupt handler can start.
|
Line 866... |
Line 866... |
|
|
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums!:
|
:sectnums:
|
===== NEORV32 Trap Listing
|
==== NEORV32 Trap Listing
|
|
|
|
The following table shows all traps that are currently supported by the NEORV32 CPU. It also shows the prioritization
|
|
and the CSR side-effects. A more detailed description of the actual trap triggering events is provided in a further table.
|
|
|
|
[NOTE]
|
|
_Asynchronous exceptions_ (= interrupts) set the MSB of `mcause` while _synchronous exception_ (= "software exception")
|
|
clear the MSB.
|
|
|
|
**Table Annotations**
|
|
|
.NEORV32 trap listing
|
The "Prio." column shows the priority of each trap. The highest priority is 1. The "`mcause`" column shows the
|
|
cause ID of the according trap that is written to `mcause` CSR. The "[RISC-V]" columns show the interrupt/exception code value from the
|
|
official RISC-V privileged architecture manual. The "[C]" names are defined by the NEORV32 core library (`sw/lib/include/neorv32.h`) and can
|
|
be used in plain C code. The "`mepc`" and "`mtval`" columns show the value written to
|
|
`mepc` and `mtval` CSRs when a trap is triggered:
|
|
|
|
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
|
|
* _B-ADR_- bad memory access address that cause the trap
|
|
* _PC_ - address of instruction that caused the trap
|
|
* _0_ - zero
|
|
* _Inst_ - the faulting instruction itself
|
|
|
|
.NEORV32 Trap Listing
|
[cols="3,6,5,14,11,4,4"]
|
[cols="3,6,5,14,11,4,4"]
|
[options="header",grid="rows"]
|
[options="header",grid="rows"]
|
|=======================
|
|=======================
|
| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval`
|
| Prio. | `mcause` | [RISC-V] | ID [C] | Cause | `mepc` | `mtval`
|
| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | _B-ADR_ | _PC_
|
| 1 | `0x00000000` | 0.0 | _TRAP_CODE_I_MISALIGNED_ | instruction address misaligned | _B-ADR_ | _PC_
|
| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access fault | _B-ADR_ | _PC_
|
| 2 | `0x00000001` | 0.1 | _TRAP_CODE_I_ACCESS_ | instruction access fault | _B-ADR_ | _PC_
|
| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | _PC_ | _Inst_
|
| 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` in machine-mode) | _PC_ | _PC_
|
| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode (`ecall` in machine-mode) | _PC_ | _PC_
|
| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode (`ecall` in user-mode) | _PC_ | _PC_
|
| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode (`ecall` in user-mode) | _PC_ | _PC_
|
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint (EBREAK) | _PC_ | _PC_
|
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint (`ebreak`) | _PC_ | _PC_
|
| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | _B-ADR_ | _B-ADR_
|
| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | _B-ADR_ | _B-ADR_
|
| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | _B-ADR_ | _B-ADR_
|
| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | _B-ADR_ | _B-ADR_
|
| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access fault | _B-ADR_ | _B-ADR_
|
| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access fault | _B-ADR_ | _B-ADR_
|
| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access fault | _B-ADR_ | _B-ADR_
|
| 10 | `0x00000005` | 0.5 | _TRAP_CODE_L_ACCESS_ | load access fault | _B-ADR_ | _B-ADR_
|
| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | _I-PC_ | _0_
|
| 11 | `0x80000010` | 1.16 | _TRAP_CODE_FIRQ_0_ | fast interrupt request channel 0 | _I-PC_ | _0_
|
Line 905... |
Line 926... |
| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt | _I-PC_ | _0_
|
| 27 | `0x8000000B` | 1.11 | _TRAP_CODE_MEI_ | machine external interrupt | _I-PC_ | _0_
|
| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt | _I-PC_ | _0_
|
| 28 | `0x80000003` | 1.3 | _TRAP_CODE_MSI_ | machine software interrupt | _I-PC_ | _0_
|
| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt | _I-PC_ | _0_
|
| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt | _I-PC_ | _0_
|
|=======================
|
|=======================
|
|
|
**Notes**
|
|
|
|
The "Prio." column shows the priority of each trap. The highest priority is 1. The "`mcause`" column shows the
|
The following table provides a summarized description of the actual events for triggering a specific trap.
|
cause ID of the according trap that is written to `mcause` CSR. The "[RISC-V]" columns show the interrupt/exception code value from the
|
|
official RISC-V privileged architecture manual. The "[C]" names are defined by the NEORV32 core library (`sw/lib/include/neorv32.h`) and can
|
|
be used in plain C code. The "`mepc`" and "`mtval`" columns show the value written to
|
|
`mepc` and `mtval` CSRs when a trap is triggered:
|
|
|
|
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
|
.NEORV32 Trap Description
|
* _B-ADR_- bad memory access address that cause the trap
|
[cols="<3,<7"]
|
* _PC_ - address of instruction that caused the trap
|
[options="header",grid="rows"]
|
* _0_ - zero
|
|=======================
|
* _Inst_ - the faulting instruction itself
|
| Trap ID | Triggered when ...
|
|
| _TRAP_CODE_I_MISALIGNED_ | fetching an 32-bit instruction word that is not 32-bit-aligned (_see note below!_)
|
|
| _TRAP_CODE_I_ACCESS_ | bus timeout or bus error during instruction word fetch
|
|
| _TRAP_CODE_I_ILLEGAL_ | trying to execute an invalid instruction word (malformed or not supported) or on a privilege violation
|
|
| _TRAP_CODE_MENV_CALL_ | executing `ecall` instruction in machine-mode
|
|
| _TRAP_CODE_UENV_CALL_ | executing `ecall` instruction in user-mode
|
|
| _TRAP_CODE_BREAKPOINT_ | executing `ebreak` instruction (or triggered by on-chip debugger)
|
|
| _TRAP_CODE_S_MISALIGNED_ | storing data to an address that is not naturally aligned to the data size (byte, half, word) being stored
|
|
| _TRAP_CODE_L_MISALIGNED_ | loading data from an address that is not naturally aligned to the data size (byte, half, word) being loaded
|
|
| _TRAP_CODE_S_ACCESS_ | bus timeout or bus error during load data operation
|
|
| _TRAP_CODE_L_ACCESS_ | bus timeout or bus error during store data operation
|
|
| _TRAP_CODE_FIRQ_0_ ... _TRAP_CODE_FIRQ_15_| caused by interrupt-condition of processor-internal modules, see <<_neorv32_specific_fast_interrupt_requests>>
|
|
| _TRAP_CODE_MEI_ | user-defined processor-external source (via dedicated top-entity signal)
|
|
| _TRAP_CODE_MSI_ | user-defined processor-external source (via dedicated top-entity signal)
|
|
| _TRAP_CODE_MTI_ | processor-internal machine timer overflow OR user-defined processor-external source (via dedicated top-entity signal)
|
|
|=======================
|
|
|
|
.Instruction Address Misaligned Exception
|
|
[NOTE]
|
|
For 32-bit-only instructions (= no `C` extension) the misaligned instruction exception
|
|
is raised if bit 1 of the fetch address is set (i.e. not on a 32-bit boundary). If the `C` extension is implemented
|
|
there will never be a misaligned instruction exception _at all_.
|
|
In both cases bit 0 of the program counter (and all related registers) is hardwired to zero.
|
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|