Line 83... |
Line 83... |
:sectnums:
|
:sectnums:
|
=== RISC-V Compatibility
|
=== RISC-V Compatibility
|
|
|
The NEORV32 CPU passes the rv32_m/I, rv32_m/M, rv32_m/C, rv32_m/privilege, and
|
The NEORV32 CPU passes the rv32_m/I, rv32_m/M, rv32_m/C, rv32_m/privilege, and
|
rv32_m/Zifencei tests of the official RISC-V Architecture Tests (GitHub). The port files for the
|
rv32_m/Zifencei tests of the official RISC-V Architecture Tests (GitHub). The port files for the
|
NEORV32 processor are located in the repository's `riscv-arch-test` folder. See section <<_risc_v_architecture_test_framework>>
|
NEORV32 processor are located in the repository's `sw/isa-test` folder.
|
|
|
|
[NOTE]
|
|
See section https://stnolting.github.io/neorv32/ug/#_risc_v_architecture_test_framework[User Guide: RISC-V Architecture Test Framework]
|
for information how to run the tests on the NEORV32.
|
for information how to run the tests on the NEORV32.
|
|
|
.**RISC-V `rv32_m/C` Tests**
|
.**RISC-V `rv32_m/C` Tests**
|
...................................
|
...................................
|
Check cadd-01 ... OK
|
Check cadd-01 ... OK
|
Line 470... |
Line 473... |
A custom CSR `mzext` is available that can be used to check for implemented `Z*` CPU extensions
|
A custom CSR `mzext` is available that can be used to check for implemented `Z*` CPU extensions
|
(for example `Zifencei`). This CSR is mapped to the official "custom CSR address region".
|
(for example `Zifencei`). This CSR is mapped to the official "custom CSR address region".
|
|
|
[NOTE]
|
[NOTE]
|
All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception
|
All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception
|
(see <<_execution_safety>>).
|
(see <<_full_virtualization>>).
|
|
|
|
|
==== **`Zfinx`** Single-Precision Floating-Point Operations
|
==== **`Zfinx`** Single-Precision Floating-Point Operations
|
|
|
The `Zfinx` floating-point extension is an alternative of the `F` floating-point instruction that also uses the
|
The `Zfinx` floating-point extension is an alternative of the `F` floating-point instruction that also uses the
|
Line 511... |
Line 514... |
The `Zfinx` extension is not yet officially ratified, but is expected to stay unchanged. There is no
|
The `Zfinx` extension is not yet officially ratified, but is expected to stay unchanged. There is no
|
software support for the `Zfinx` extension in the upstream GCC RISC-V port yet. However, an
|
software support for the `Zfinx` extension in the upstream GCC RISC-V port yet. However, an
|
intrinsic library is provided to utilize the provided `Zfinx` floating-point extension from C-language
|
intrinsic library is provided to utilize the provided `Zfinx` floating-point extension from C-language
|
code (see `sw/example/floating_point_test`).
|
code (see `sw/example/floating_point_test`).
|
|
|
|
[IMPORTANT]
|
|
Note that any FPU instruction including all FPU-related CSR accesses will raise an illegal instruction exception
|
|
if the FPU is not enabled via the <<_mstatus>> CSR (`FS` bits).
|
|
|
|
|
==== **`Zicsr`** Control and Status Register Access / Privileged Architecture
|
==== **`Zicsr`** Control and Status Register Access / Privileged Architecture
|
|
|
The CSR access instructions as well as the exception and interrupt system (= the privileged architecture) is implemented when the
|
The CSR access instructions as well as the exception and interrupt system (= the privileged architecture) is implemented when the
|
`CPU_EXTENSION_RISCV_Zicsr` configuration generic is _true_. In this case the following instructions are
|
`CPU_EXTENSION_RISCV_Zicsr` configuration generic is _true_. In this case the following instructions are
|
Line 531... |
Line 538... |
[NOTE]
|
[NOTE]
|
The "wait for interrupt instruction" `wfi` works like a sleep command. When executed, the CPU is
|
The "wait for interrupt instruction" `wfi` works like a sleep command. When executed, the CPU is
|
halted until a valid interrupt request occurs. To wake up again, the according interrupt source has to
|
halted until a valid interrupt request occurs. To wake up again, the according interrupt source has to
|
be enabled via the `mie` CSR and the global interrupt enable flag in `mstatus` has to be set.
|
be enabled via the `mie` CSR and the global interrupt enable flag in `mstatus` has to be set.
|
|
|
|
[IMPORTANT]
|
|
The `wfi` instruction will raise an illegal instruction exception when executed outside of machine-mode
|
|
and <<_mstatus>> bit `TW` (timeout wait) is set.
|
|
|
|
|
==== **`Zifencei`** Instruction Stream Synchronization
|
==== **`Zifencei`** Instruction Stream Synchronization
|
|
|
The `Zifencei` CPU extension is implemented if the `CPU_EXTENSION_RISCV_Zifencei` configuration
|
The `Zifencei` CPU extension is implemented if the `CPU_EXTENSION_RISCV_Zifencei` configuration
|
generic is _true_. It allows manual synchronization of the instruction stream via the following instruction:
|
generic is _true_. It allows manual synchronization of the instruction stream via the following instruction:
|
Line 618... |
Line 629... |
N-bit wide counter (split in a high-word 32-bit CSR and a low-word 32-bit CSR), where N is defined via the top's
|
N-bit wide counter (split in a high-word 32-bit CSR and a low-word 32-bit CSR), where N is defined via the top's
|
`HPM_CNT_WIDTH` generic (0..64-bit), and a corresponding event configuration CSR. The event configuration
|
`HPM_CNT_WIDTH` generic (0..64-bit), and a corresponding event configuration CSR. The event configuration
|
CSR defines the architectural events that lead to an increment of the associated HPM counter.
|
CSR defines the architectural events that lead to an increment of the associated HPM counter.
|
|
|
The cycle, time and instructions-retired counters (`[m]cycle[h]`, `time[h]`, `[m]instret[h]`) are
|
The cycle, time and instructions-retired counters (`[m]cycle[h]`, `time[h]`, `[m]instret[h]`) are
|
mandatory performance monitors on every RISC-V platform and have fixed increment event. For example,
|
mandatory performance monitors on every RISC-V platform and have fixed increment events. For example,
|
the instructions-retired counter increments with each executed instructions. The actual hardware performance
|
the instructions-retired counter increments with each executed instructions. The actual hardware performance
|
monitors are optional and can be configured to increment on arbitrary hardware events. The number of
|
monitors are optional and can be configured to increment on arbitrary hardware events. The number of
|
available HPM is configured via the top's `HPM_NUM_CNTS` generic at synthesis time. Assigning a zero will exclude
|
available HPM is configured via the top's `HPM_NUM_CNTS` generic at synthesis time. Assigning a zero will exclude
|
all HPM logic from the design.
|
all HPM logic from the design.
|
|
|
Depending on the configuration, the following additional CSR are available:
|
Depending on the configuration, the following additional CSR are available:
|
|
|
* counters: `[m]hpmcounter*[h]` (3..31, depending on configuration)
|
* counters: `mhpmcounter*[h]` (3..31, depending on configuration)
|
* event configuration: `mhpmevent*` (3..31, depending on configuration)
|
* event configuration: `mhpmevent*` (3..31, depending on configuration)
|
|
|
User-level access to the counter registers `hpmcounter*[h]` can be individually restricted via the `mcounteren` CSR.
|
[IMPORTANT]
|
|
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
|
|
are always zero and read-only.
|
|
|
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.
|
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.
|
|
|
If `HPM_NUM_CNTS` is lower than the maximumg value (=29) the remaining HPMs are not implemented.
|
If `HPM_NUM_CNTS` is lower than the maximum value (=29) the remaining HPM CSRs are not implemented and the
|
However, accessing their associated CSRs will not raise an illegal instructions exception. These CSR are
|
according `mcountinhibit` CSR bits are hardwired to zero.
|
read-only and will always return 0.
|
However, accessing their associated CSRs will not raise an illegal instruction exception (if in machine mode).
|
|
The according CSRs are read-only and will always return 0.
|
|
|
[NOTE]
|
[NOTE]
|
For a list of all allocated HPM-related CSRs and all provided event configurations see section <<_hardware_performance_monitors_hpm>>.
|
For a list of all allocated HPM-related CSRs and all provided event configurations see section <<_hardware_performance_monitors_hpm>>.
|
|
|
|
|
Line 706... |
Line 721... |
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Execution Safety
|
==== Full Virtualization
|
|
|
The hardware of the NEORV32 CPU was designed for maximum *execution safety*. If the `Zicsr` CPU
|
|
extension is enabled, the core supports **all** traps specified by the official RISC-V specifications (obviously,
|
|
not the ones that are related to yet unimplemented extensions/features). Thus, the CPU provides well-defined
|
|
hardware fall-backs for (nearly) everything that can go wrong. Even if any kind of trap is triggered, the core
|
|
is always in a defined and fully synchronized state throughout the whole architecture (i.e. no need to make
|
|
out-of-order operations undone) that allows predictable execution behavior at any time.
|
|
|
|
**Core Safety Features**
|
|
|
|
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system (no speculative execution / out-of-order states).
|
|
* The CPU supports all bus exceptions including bus access exceptions that are triggered if an
|
|
accessed address does not respond or encounters an internal error during access (which is a rare
|
|
feature in many open-source RISC-V cores).
|
|
* The CPU raises an illegal instruction trap for **all** unimplemented/malformed/illegal instructions (to support _full_ virtualization).
|
|
* If user-level code tries to read from machine-level-only CSRs (like `mstatus`) an illegal instruction
|
|
exception is raised. The results of this operations is always zero (though, machine-level
|
|
code handling this exception can modify the target register of the illegal access-causing
|
|
instruction to allow full virtualization). Illegal write accesses to machine CSRs will not be write any data at all.
|
|
* Illegal user-level memory accesses to protected addresses or address regions (via physical memory
|
|
protection) will not be conducted at all (no actual write and no actual read; prevents triggering of
|
|
memory-mapped devices). Illegal load operations will not return any data (the instruction's
|
|
destination register will not be written at all).
|
|
|
|
|
Just like the RISC-V ISA the NEORV32 aims to support _ maximum virtualization_ capabilities
|
|
on CPU _and_ SoC level. The CPU supports **all** traps specified by the official RISC-V specifications.footnote:[If the `Zicsr` CPU
|
|
extension is enabled (implementing the full set of the privileged architecture).]
|
|
Thus, the CPU provides defined hardware fall-backs for any expected and unexpected situation (e.g. executing an
|
|
malformed instruction word or accessing a not-allocated address). For any kind of trap the core is always in a
|
|
defined and fully synchronized state throughout the whole architecture (i.e. there are no out-of-order operations that
|
|
have to be made undone). This allows predictable execution behavior - and thus, defined operations to resolve the cause
|
|
of the trap - at any time improving overall _execution safety_.
|
|
|
|
**NEORV32-Specific Virtualization Features**
|
|
|
|
* Due to the acknowledged memory accesses the CPU is _always_ sync with the memory system
|
|
(i.e. there is no speculative execution / no out-of-order states).
|
|
* The CPU supports _all_ RISC-V bus exceptions including access exceptions that are triggered if an
|
|
accessed address does not respond or encounters an internal error during access.
|
|
* The CPU raises an illegal instruction trap for _all_ unimplemented/malformed/illegal instructions.
|
|
* To be continued...
|
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|