Skip to content

Commit

Permalink
Merge pull request #192 from stnolting/Zicnt_Zihpm_update
Browse files Browse the repository at this point in the history
RISC-V "Zicntr" and "Zihpm" extensions
  • Loading branch information
stnolting authored Nov 1, 2021
2 parents 34d9ab1 + fdc885f commit 0860f38
Show file tree
Hide file tree
Showing 28 changed files with 301 additions and 218 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ defined by the `hw_version_c` constant in the main VHDL package file [`rtl/core/

| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 30.10.2021 | 1.6.2.12 | :sparkles: :lock: added memory-mapped register to BUSKEEPER module - software can now retrieve the actual cause of an instruction / data-load / data-store bus access fault exception (access timeout or device error); see [PR #192](https://github.com/stnolting/neorv32/pull/191) |
| 01.11.2021 | 1.6.2.13 | added new top generics to explicitly control implementation of `Zicntr` (CPU base counters) and `Zihpm` (hardware performance monitors, see [PR #192](https://github.com/stnolting/neorv32/pull/192) |
| 30.10.2021 | 1.6.2.12 | :sparkles: :lock: added memory-mapped register to BUSKEEPER module - software can now retrieve the actual cause of an instruction / data-load / data-store bus access fault exception (access timeout or device error); see [PR #191](https://github.com/stnolting/neorv32/pull/191) |
| 28.10.2021 | 1.6.2.11 | :sparkles: added `Zba` bit-manipulation sub-extension; :warning: removed configuration option for `B` sub-extensions: removed `CPU_EXTENSION_RISCV_Zbb` generic and according SYSINFO flag, added new `CPU_EXTENSION_RISCV_B` generic (to implement bit-manipulation `B` ISA extension with _all_ currently supported subsets), see [PR #190](https://github.com/stnolting/neorv32/pull/190) |
| 27.10.2021 | 1.6.2.10 | :bug: CPU control unit: fixed _imprecise_ illegal instruction exceptions - `MEPC` and `MTAVL` did not reflect the correct exception-causing data for illegal ALU-class (non-multi-cycle like `SUB`) operations; optimized critical path of exception logic (illegal compressed instruction detection) |
| 27.10.2021 | 1.6.2.9 | CPU control unit: minor logic optimization - `fence.i` instruction needs 1 cycle less to execute, reduced HW footprint of control engine, shortened CPU's critical path (PC update logic) |
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,11 @@ documentation section). Note that the `X` extension is always enabled.
[[`X`](https://stnolting.github.io/neorv32/#_x_neorv32_specific_custom_extensions)]
[[`Zfinx`](https://stnolting.github.io/neorv32/#_zfinx_single_precision_floating_point_operations)]
[[`Zicsr`](https://stnolting.github.io/neorv32/#_zicsr_control_and_status_register_access_privileged_architecture)]
[[`Zicntr`](https://stnolting.github.io/neorv32/#_zicntr_cpu_base_counters)]
[[`Zihpm`](https://stnolting.github.io/neorv32/#_zihpm_hardware_performance_monitors)]
[[`Zifencei`](https://stnolting.github.io/neorv32/#_zifencei_instruction_stream_synchronization)]
[[`Zmmul`](https://stnolting.github.io/neorv32/#_zmmul_integer_multiplication)]
[[`PMP`](https://stnolting.github.io/neorv32/#_pmp_physical_memory_protection)]
[[`HPM`](https://stnolting.github.io/neorv32/#_hpm_hardware_performance_monitors)]
[[`DEBUG`](https://stnolting.github.io/neorv32/#_cpu_debug_mode)]**

:warning: The `B`, `Zfinx` and `Zmmul` RISC-V extensions are frozen but not officially ratified yet. Hence, there is no
Expand All @@ -223,8 +224,8 @@ Results generated for hardware version [`1.5.7.10`](https://github.com/stnolting
| CPU Configuration | LEs | FFs | Memory bits | DSPs (9-bit) | f_max |
|:--------------------------------------------------|:----:|:----:|:-----------:|:------------:|:-------:|
| `rv32i` | 806 | 359 | 1024 | 0 | 125 MHz |
| `rv32i_Zicsr` | 1729 | 813 | 1024 | 0 | 124 MHz |
| `rv32imac_Zicsr` | 2511 | 1074 | 1024 | 0 | 124 MHz |
| `rv32i_Zicsr_Zicntr` | 1729 | 813 | 1024 | 0 | 124 MHz |
| `rv32imac_Zicsr_Zicntr` | 2511 | 1074 | 1024 | 0 | 124 MHz |

:information_source: An incremental list of CPU extension's hardware utilization can found in
[online documentation - _"FPGA Implementation Results - CPU"_](https://stnolting.github.io/neorv32/#_cpu).
Expand Down
86 changes: 47 additions & 39 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ image::riscv_logo.png[width=350,align=center]
** `U` - less-privileged _user_ mode
** `Zfinx` - single-precision floating-point unit
** `Zicsr` - control and status register access (privileged architecture)
** `Zicntr` - CPU base counters
** `Zihpm` - hardware performance monitors
** `Zifencei` - instruction stream synchronization
** `Zmmul` - integer multiplication hardware
** `PMP` - physical memory protection
** `HPM` - hardware performance monitors
** `DB` - debug mode
** `Debug` - debug mode
* Compatible to the RISC-V user specifications and a subset of the RISC-V privileged architecture specifications - passes the official RISC-V Architecture Tests (v2+)
* Official RISC-V open-source architecture ID
* Standard RISC-V interrupts (_external_, _timer_, _software_) plus 16 _fast_ interrupts
Expand Down Expand Up @@ -630,6 +631,50 @@ The `wfi` instruction may also be executed in user-mode without causing an excep
`TW` (timeout wait) is hardwired to zero.




==== **`Zicntr`** CPU Base Counters

The `Zicntr` ISA extension adds the basic cycle `[m]cycle[h]`), instruction-retired (`[m]instret[h]`) and time (`time[h]`)
counters. This extensions is stated is _mandatory_ by the RISC-V spec. However, size-constrained setups may remove support for
these counters. Section <<_machine_counter_and_timer_csrs>> shows a list of all `Zicntr`-related CSRs.
These are available if the `Zicntr` ISA extensions is enabled via the <<_cpu_extension_riscv_zicntr>> generic.

[NOTE]
Disabling the `Zicntr` extension does not remove the `time[h]`-driving MTIME unit.

If `Zicntr` is disabled, all accesses to the according counter CSRs will raise an illegal instruction exception.



==== **`Zihpm`** Hardware Performance Monitors

In additions to the base cycle, instructions-retired and time counters the NEORV32 CPU provides
up to 29 hardware performance monitors (HPM 3..31), which can be used to benchmark applications. Each HPM consists of an
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
CSR defines the architectural events that lead to an increment of the associated HPM counter.

The HPM counters are available if the `Zihpm` ISA extensions is enabled via the <<_cpu_extension_riscv_zihpm>> generic.

Depending on the configuration the following additional CSR are available:

* counters: `mhpmcounter*[h]` (3..31, depending on `HPM_NUM_CNTS`)
* event configuration: `mhpmevent*` (3..31, depending on `HPM_NUM_CNTS`)

[IMPORTANT]
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
are always zero and read-only. Any access from less-privileged modes will raise an illegal instruction
exception.

[TIP]
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.

[TIP]
For a list of all HPM-related CSRs and all provided event configurations
see section <<_hardware_performance_monitors_hpm>>.


==== **`Zifencei`** Instruction Stream Synchronization

The `Zifencei` CPU extension is implemented if the `CPU_EXTENSION_RISCV_Zifencei` configuration
Expand Down Expand Up @@ -703,43 +748,6 @@ For more information regarding RISC-V physical memory protection see the officia
Instruction Set Manual - Volume II: Privileged Architecture_ specifications.


==== **`HPM`** Hardware Performance Monitors

In additions to the mandatory cycle (`[m]cycle[h]`) and instruction (`[m]instret[h]`) counters the NEORV32 CPU provides
up to 29 hardware performance monitors (HPM 3..31), which can be used to benchmark applications. Each HPM consists of an
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
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
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
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 remove
all HPM logic from the design.

If `HPM_NUM_CNTS` is lower than the maximum value (=29) the remaining HPM CSRs are not implemented and the
according `mcountinhibit` CSR bits are hardwired to zero.
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.

Depending on the configuration the following additional CSR are available:

* counters: `mhpmcounter*[h]` (3..31, depending on `HPM_NUM_CNTS`)
* event configuration: `mhpmevent*` (3..31, depending on `HPM_NUM_CNTS`)

[IMPORTANT]
The HPM counter CSR can only be accessed in machine-mode. Hence, the according `mcounteren` CSR bits
are always zero and read-only. Any access from less-privileged modes will raise an illegal instruction
exception.

[TIP]
Auto-increment of the HPMs can be individually deactivated via the `mcountinhibit` CSR.

[TIP]
For a list of all HPM-related CSRs and all provided event configurations
see section <<_hardware_performance_monitors_hpm>>.


<<<
// ####################################################################################################################
Expand Down
60 changes: 33 additions & 27 deletions docs/datasheet/cpu_csr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,26 @@ CSRs with the following notes ...
| 0x001 | <<_fflags>> | _CSR_FFLAGS_ | r/w | Floating-point accrued exceptions |
| 0x002 | <<_frm>> | _CSR_FRM_ | r/w | Floating-point dynamic rounding mode |
| 0x003 | <<_fcsr>> | _CSR_FCSR_ | r/w | Floating-point control and status (`frm` + `fflags`) |
6+^| **<<_machine_configuration>>**
6+^| **<<_machine_configuration_csrs>>**
| 0x30a | <<_menvcfg>> | _CSR_MENVCFG_ | r/- | Machine environment configuration register - low word | `R`
| 0x31a | <<_menvcfgh>> | _CSR_MENVCFGH_ | r/- | Machine environment configuration register - low word | `R`
6+^| **<<_machine_trap_setup>>**
6+^| **<<_machine_trap_setup_csrs>>**
| 0x300 | <<_mstatus>> | _CSR_MSTATUS_ | r/w | Machine status register - low word | `C`
| 0x301 | <<_misa>> | _CSR_MISA_ | r/- | Machine CPU ISA and extensions | `R`
| 0x304 | <<_mie>> | _CSR_MIE_ | r/w | Machine interrupt enable register | `X`
| 0x305 | <<_mtvec>> | _CSR_MTVEC_ | r/w | Machine trap-handler base address (for ALL traps) |
| 0x306 | <<_mcounteren>> | _CSR_MCOUNTEREN_ | r/w | Machine counter-enable register | `C`
| 0x310 | <<_mstatush>> | _CSR_MSTATUSH_ | r/- | Machine status register - high word | `C`
6+^| **<<_machine_trap_handling>>**
6+^| **<<_machine_trap_handling_csrs>>**
| 0x340 | <<_mscratch>> | _CSR_MSCRATCH_ | r/w | Machine scratch register |
| 0x341 | <<_mepc>> | _CSR_MEPC_ | r/w | Machine exception program counter |
| 0x342 | <<_mcause>> | _CSR_MCAUSE_ | r/w | Machine trap cause | `X`
| 0x343 | <<_mtval>> | _CSR_MTVAL_ | r/- | Machine bad address or instruction | `XR`
| 0x344 | <<_mip>> | _CSR_MIP_ | r/- | Machine interrupt pending register | `XR`
6+^| **<<_machine_physical_memory_protection>>**
6+^| **<<_machine_physical_memory_protection_csrs>>**
| 0x3a0 .. 0x3af | <<_pmpcfg, `pmpcfg0`>> .. <<_pmpcfg, `pmpcfg15`>> | _CSR_PMPCFG0_ .. _CSR_PMPCFG15_ | r/w | Physical memory protection config. for region 0..63 | `C`
| 0x3b0 .. 0x3ef | <<_pmpaddr, `pmpaddr0`>> .. <<_pmpaddr, `pmpaddr63`>> | _CSR_PMPADDR0_ .. _CSR_PMPADDR63_ | r/w | Physical memory protection addr. register region 0..63 |
6+^| **<<_machine_counters_and_timers>>**
6+^| **<<_machine_counter_and_timer_csrs>>**
| 0xb00 | <<_mcycleh, `mcycle`>> | _CSR_MCYCLE_ | r/w | Machine cycle counter low word |
| 0xb02 | <<_minstreth, `minstret`>> | _CSR_MINSTRET_ | r/w | Machine instruction-retired counter low word |
| 0xb80 | <<_mcycleh>> | _CSR_MCYCLE_ | r/w | Machine cycle counter high word |
Expand All @@ -98,13 +98,13 @@ CSRs with the following notes ...
| 0xc80 | <<_cycleh>> | _CSR_CYCLEH_ | r/- | Cycle counter high word |
| 0xc81 | <<_timeh>> | _CSR_TIMEH_ | r/- | System time (from MTIME) high word |
| 0xc82 | <<_instreth>> | _CSR_INSTRETH_ | r/- | Instruction-retired counter high word |
6+^| **<<_hardware_performance_monitors_hpm>>**
6+^| **<<_hardware_performance_monitors_hpm_csrs>>**
| 0x323 .. 0x33f | <<_mhpmevent, `mhpmevent3`>> .. <<_mhpmevent, `mhpmevent31`>> | _CSR_MHPMEVENT3_ .. _CSR_MHPMEVENT31_ | r/w | Machine performance-monitoring event selector 3..31 | `X`
| 0xb03 .. 0xb1f | <<_mhpmcounterh, `mhpmcounter3`>> .. <<_mhpmcounterh, `mhpmcounter31`>> | _CSR_MHPMCOUNTER3_ .. _CSR_MHPMCOUNTER31_ | r/w | Machine performance-monitoring counter 3..31 low word |
| 0xb83 .. 0xb9f | <<_mhpmcounterh, `mhpmcounter3h`>> .. <<_mhpmcounterh, `mhpmcounter31h`>> | _CSR_MHPMCOUNTER3H_ .. _CSR_MHPMCOUNTER31H_ | r/w | Machine performance-monitoring counter 3..31 high word |
6+^| **<<_machine_counter_setup>>**
6+^| **<<_machine_counter_setup_csrs>>**
| 0x320 | <<_mcountinhibit>> | _CSR_MCOUNTINHIBIT_ | r/w | Machine counter-enable register |
6+^| **<<_machine_information_registers>>**
6+^| **<<_machine_information_csrs>>**
| 0xf11 | <<_mvendorid>> | _CSR_MVENDORID_ | r/- | Vendor ID |
| 0xf12 | <<_marchid>> | _CSR_MARCHID_ | r/- | Architecture ID |
| 0xf13 | <<_mimpid>> | _CSR_MIMPID_ | r/- | Machine implementation ID / version |
Expand Down Expand Up @@ -168,7 +168,7 @@ RISC-V ISA spec for more information.
<<<
// ####################################################################################################################
:sectnums:
==== Machine Configuration
==== Machine Configuration CSRs

:sectnums!:
===== **`menvcfg`**
Expand Down Expand Up @@ -199,7 +199,7 @@ only exists if the `U` ISA extensions is enabled.
<<<
// ####################################################################################################################
:sectnums:
==== Machine Trap Setup
==== Machine Trap Setup CSRs

:sectnums!:
===== **`mstatus`**
Expand Down Expand Up @@ -361,7 +361,7 @@ in order to comply with the RISC-V privilege architecture specs.
<<<
// ####################################################################################################################
:sectnums:
==== Machine Trap Handling
==== Machine Trap Handling CSRs

:sectnums!:
===== **`mscratch`**
Expand Down Expand Up @@ -469,7 +469,7 @@ The NEORV32 `mip` CSR is read-only. However, a write access will _NOT_ raise an
<<<
// ####################################################################################################################
:sectnums:
==== Machine Physical Memory Protection
==== Machine Physical Memory Protection CSRs

The available physical memory protection logic is configured via the _PMP_NUM_REGIONS_ and
_PMP_MIN_GRANULARITY_ top entity generics. _PMP_NUM_REGIONS_ defines the number of implemented
Expand Down Expand Up @@ -532,7 +532,10 @@ before modifying `pmpaddr*`.
<<<
// ####################################################################################################################
:sectnums:
==== (Machine) Counters and Timers
==== (Machine) Counter and Timer CSRs

The (machine) counters and timers are implemented when the `Zicntr` ISA extensions is enabled (default)
via the <<_cpu_extension_riscv_zicntr>> generic.

[NOTE]
The <<_cpu_cnt_width>> generic defines the total size of the CPU's <<_cycleh>> and <<_instreth>>
Expand All @@ -553,8 +556,7 @@ and always read as zero. This configuration will also set the _SYSINFO_CPU_ZXSCN
the `CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register. +
+
If _CPU_CNT_WIDTH_ is 0, the <<_cycleh>> and <<_instreth>> / <<_mcycleh>> and <<_minstreth>> CSRs are hardwired to zero
and any write access to them is ignored. This configuration will also set the _SYSINFO_CPU_ZXNOCNT_ flag ("no counters") in the
`CPU` <<_system_configuration_information_memory_sysinfo, SYSINFO>> register.
and any write access to them is ignored.


:sectnums!:
Expand Down Expand Up @@ -633,23 +635,27 @@ instructions counter. The `minstret[h]` CSR also be written when in machine mode
<<<
// ####################################################################################################################
:sectnums:
==== Hardware Performance Monitors (HPM)

The available hardware performance logic is configured via the <<_hpm_num_cnts>> top entity generic,
which defines the number of implemented performance monitors and thus, the availability of the
according `mhpmcounter*[h]` and `mhpmevent*` CSRs.
==== Hardware Performance Monitors (HPM) CSRs

[IMPORTANT]
The HPM system only implements machine-mode access. Hence, `hpmcounter*[h]` CSR are not implemented
and any access (even) from machine mode will raise an exception. Furthermore, the according bits of <<_mcounteren>>
used to configure user-mode access to `hpmcounter*[h]` are hard-wired to zero.
The hardware performance monitor CSRs are implemented when the `Zihpm` ISA extension is enabled via the
<<_cpu_extension_riscv_zihpm>> generic.

The total counter size of the HPMs can be configured before synthesis via the <<_hpm_cnt_width>> generic (0..64-bit).
The actually implemented hardware performance logic is configured via the <<_hpm_num_cnts>> top entity generic,
which defines the number of implemented performance monitors. Note that always all 28 HPM counter and configuration registers
(`mhpmcounter*[h]` and `mhpmevent*`) are implemented, but only the actually configured ones are real registers and
not hardwired to zero.

[TIP]
If trying to access an HPM-related CSR beyond <<_hpm_num_cnts>> **no illegal instruction exception is
triggered**. The according CSRs are read-only (writes are ignored) and always return zero.

[IMPORTANT]
The HPM system only allows machine-mode access. Hence, `hpmcounter*[h]` CSR are not implemented
and any access (even) from machine mode will raise an exception. Furthermore, the according bits of <<_mcounteren>>
used to configure user-mode access to `hpmcounter*[h]` are hard-wired to zero.

The total counter width of the HPMs can be configured before synthesis via the <<_hpm_cnt_width>> generic (0..64-bit).

[NOTE]
The total LSB-aligned HPM counter size (low word CSR + high word CSR) is defined via the
<<_hpm_num_cnts>> generic (0..64-bit). If <<_hpm_num_cnts>> is less than 64, all unused MSB-aligned
Expand Down Expand Up @@ -717,7 +723,7 @@ bit of arbitrary event counters. The event(s) that trigger an increment of these
<<<
// ####################################################################################################################
:sectnums:
==== Machine Counter Setup
==== Machine Counter Setup CSRs

:sectnums!:
===== **`mcountinhibit`**
Expand Down Expand Up @@ -747,7 +753,7 @@ always zero and are read-only).
<<<
// ####################################################################################################################
:sectnums:
==== Machine Information Registers
==== Machine Information CSRs

[NOTE]
All machine information registers can only be accessed in machine mode and are read-only.
Expand Down
Loading

0 comments on commit 0860f38

Please sign in to comment.