Skip to content

Commit

Permalink
✨ add support for Zalrsc ISA extension (#1181)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting authored Feb 8, 2025
2 parents 067bd01 + 138dc37 commit 2b7d619
Show file tree
Hide file tree
Showing 23 changed files with 458 additions and 126 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 08.02.2025 | 1.11.1.1 | :sparkles: add support for `A` and `Zalrsc` ISA extensions | [#1181](https://github.com/stnolting/neorv32/pull/1181) |
| 07.02.2025 | [**:rocket:1.11.1**](https://github.com/stnolting/neorv32/releases/tag/v1.11.1) | **New release** | |
| 07.02.2025 | 1.11.0.10 | :warning: rename UART RTS/CTS signals | [#1180](https://github.com/stnolting/neorv32/pull/1180) |
| 07.02.2025 | 1.11.0.9 | minor rtl edits and cleanups | [#1179](https://github.com/stnolting/neorv32/pull/1179) |
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@ setup according to your needs. Note that all of the following SoC modules are en
`RV32`
[[`I`](https://stnolting.github.io/neorv32/#_i_isa_extension)/[`E`](https://stnolting.github.io/neorv32/#_e_isa_extension)]
[[`M`](https://stnolting.github.io/neorv32/#_m_isa_extension)]
[[`A`](https://stnolting.github.io/neorv32/#_a_isa_extension)]
[[`C`](https://stnolting.github.io/neorv32/#_c_isa_extension)]
[[`B`](https://stnolting.github.io/neorv32/#_b_isa_extension)]
[[`U`](https://stnolting.github.io/neorv32/#_u_isa_extension)]
[[`X`](https://stnolting.github.io/neorv32/#_x_isa_extension)]
[[`Zaamo`](https://stnolting.github.io/neorv32/#_zaamo_isa_extension)]
[[`Zalrsc`](https://stnolting.github.io/neorv32/#_zalrsc_isa_extension)]
[[`Zba`](https://stnolting.github.io/neorv32/#_zba_isa_extension)]
[[`Zbb`](https://stnolting.github.io/neorv32/#_zbb_isa_extension)]
[[`Zbkb`](https://stnolting.github.io/neorv32/#_zbkb_isa_extension)]
Expand Down
85 changes: 58 additions & 27 deletions docs/datasheet/cpu.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -472,33 +472,32 @@ additional latency). However, _all_ bus signals (request and response) need to b
:sectnums:
==== Atomic Memory Access

The <<_zaamo_isa_extension>> adds atomic read-modify-write memory operations. Since the <<_bus_interface_protocol>>
only supports read-or-write operations, the atomic memory requests are handled by a dedicated module of the bus
infrastructure - the <<_atomic_memory_operations_controller>>.

For the CPU, the atomic memory accesses are handled as plain "load" operation but with the `amo` signal set
and also providing write data (see <<_bus_interface>>). The `amoop` signal defines the actual atomic processing
operation:
As the <<_bus_interface_protocol>> only supports read-or-write operations, all atomic memory requests are
handled by a dedicated module of the bus infrastructure - the <<_atomic_memory_operations_controller>>.
For the CPU, the atomic memory accesses are handled as plain load/store operation but with the `amo` signal set.
The `amoop` signal specifies the actual atomic processing operation:

.AMO Operation Type Encoding
[cols="<1,<4"]
[cols="<1,<4,<4"]
[options="header",grid="rows"]
|=======================
| `bus_req_t.amoop` | Description
| `-000` | swap
| `-001` | unsigned add
| `-010` | logical xor
| `-011` | logical and
| `-100` | logical or
| `0110` | unsigned minimum
| `0111` | unsigned maximum
| `1110` | signed minimum
| `1111` | signed maximum
| `bus_req_t.amoop` | Description | ISA Extension
| `-000` | swap | <<_zaamo_isa_extension,`Zaamo`>>
| `-001` | unsigned add | <<_zaamo_isa_extension,`Zaamo`>>
| `-010` | logical xor | <<_zaamo_isa_extension,`Zaamo`>>
| `-011` | logical and | <<_zaamo_isa_extension,`Zaamo`>>
| `-100` | logical or | <<_zaamo_isa_extension,`Zaamo`>>
| `0110` | unsigned minimum | <<_zaamo_isa_extension,`Zaamo`>>
| `0111` | unsigned maximum | <<_zaamo_isa_extension,`Zaamo`>>
| `1110` | signed minimum | <<_zaamo_isa_extension,`Zaamo`>>
| `1111` | signed maximum | <<_zaamo_isa_extension,`Zaamo`>>
| `1000` | load-reservate | <<_zalrsc_isa_extension,`Zalrsc`>>
| `1001` | store-conditional | <<_zalrsc_isa_extension,`Zalrsc`>>
|=======================

.Cache Coherency
[IMPORTANT]
Atomic operations **always bypass** the (CPU) caches using direct/uncached accesses. Care must be taken
Atomic operations **always bypass** the caches using direct/uncached accesses. Care must be taken
to maintain data synchronization. See section <<_memory_coherence>> for more information.


Expand All @@ -516,14 +515,16 @@ This chapter gives a brief overview of all available ISA extensions.
[options="header",grid="rows"]
|=======================
| Name | Description | <<_processor_top_entity_generics, Enabled by Generic>>
| <<_a_isa_extension,`B`>> | Atomic memory instructions | _Implicitly_ enabled
| <<_b_isa_extension,`B`>> | Bit manipulation instructions | _Implicitly_ enabled
| <<_c_isa_extension,`C`>> | Compressed (16-bit) instructions | <<_processor_top_entity_generics, `RISCV_ISA_C`>>
| <<_e_isa_extension,`E`>> | Embedded CPU extension (reduced register file size) | <<_processor_top_entity_generics, `RISCV_ISA_E`>>
| <<_i_isa_extension,`I`>> | Integer base ISA | Enabled if `RISCV_ISA_E` is **not** enabled
| <<_m_isa_extension,`M`>> | Integer multiplication and division instructions | <<_processor_top_entity_generics, `RISCV_ISA_M`>>
| <<_u_isa_extension,`U`>> | Less-privileged _user_ mode extension | <<_processor_top_entity_generics, `RISCV_ISA_U`>>
| <<_x_isa_extension,`X`>> | Platform-specific / NEORV32-specific extension | Always enabled
| <<_zaamo_isa_extension,`Zaamo`>> | Atomic memory operations | <<_processor_top_entity_generics, `RISCV_ISA_Zaamo`>>
| <<_zaamo_isa_extension,`Zaamo`>> | Atomic read-modify-write memory operations | <<_processor_top_entity_generics, `RISCV_ISA_Zaamo`>>
| <<_zalrsc_isa_extension,`Zalrsc`>> | Atomic reservation-set memory operations | <<_processor_top_entity_generics, `RISCV_ISA_Zalrsc`>>
| <<_zba_isa_extension,`Zba`>> | Shifted-add bit manipulation instructions | <<_processor_top_entity_generics, `RISCV_ISA_Zba`>>
| <<_zbb_isa_extension,`Zbb`>> | Basic bit manipulation instructions | <<_processor_top_entity_generics, `RISCV_ISA_Zbb`>>
| <<_zbkb_isa_extension,`Zbkb`>> | Scalar cryptographic bit manipulation instructions | <<_processor_top_entity_generics, `RISCV_ISA_Zbkb`>>
Expand Down Expand Up @@ -570,13 +571,23 @@ To benchmark a certain processor configuration for its setup-specific CPI value
`sw/example/performance_tests` test programs.


==== `A` ISA Extension

The `A` ISA extension adds instructions for bit-manipulation operations.
This ISA extension cannot be enabled by a specific generic. Instead, it is enabled if a specific set of
sub-extensions is enabled. The `A` extension is shorthand for the following set of other extensions:

* <<_zaamo_isa_extension>> - Atomic read-modify-write instructions.
* <<_zalrsc_isa_extension>> - Atomic reservation-set instructions.

A processor configuration which implements `A` must implement all of the above extensions.


==== `B` ISA Extension

The `B` ISA extension adds instructions for bit-manipulation operations.
This ISA extension cannot be enabled by a specific generic. Instead, it is enabled if a specific set of
bit-manipulation sub-extensions are enabled.

The `B` extension is shorthand for the following set of other extensions:
sub-extensions is enabled. The `B` extension is shorthand for the following set of other extensions:

* <<_zba_isa_extension>> - Address-generation / shifted-add instructions.
* <<_zbb_isa_extension>> - Basic bit manipulation instructions.
Expand Down Expand Up @@ -689,20 +700,40 @@ The NEORV32-specific ISA extensions `X` is always enabled. The most important po
and <<_mip>> CSRs. These extensions are mapped to CSR bits, that are available for custom use according to the
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>>).
* There are <<_neorv32_specific_csrs>>.
* Additional <<_neorv32_specific_csrs>>.


==== `Zaamo` ISA Extension

The `Zaamo` ISA extension is a sub-extension of the RISC-V `A` ISA extension and compromises instructions for read-modify-write
<<_atomic_memory_access>> operations. It is enabled by the top's <<_processor_top_entity_generics, `RISCV_ISA_Zaamo`>> generic.
The `Zaamo` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension,`A`>> ISA extension and compromises
instructions for read-modify-write <<_atomic_memory_access>> operations. It is enabled by the top's
<<_processor_top_entity_generics, `RISCV_ISA_Zaamo`>> generic.

.Instructions and Timing
[cols="<2,<4,<1"]
[options="header", grid="rows"]
|=======================
| Class | Instructions | Execution cycles
| Atomic read-modify-write | `amoswap.w` `amoadd.w` `amoand.w` `amoor.w` `amoxor.w` `amomax[u].w` `amomin[u].w` | 5 + 2 * _memory_latency_
|=======================

.`aq` and `rl` Bits
[NOTE]
The instruction word's `aq` and `lr` memory ordering bits are not evaluated by the hardware at all.


==== `Zalrsc` ISA Extension

The `Zalrsc` ISA extension is a sub-extension of the RISC-V <<_a_isa_extension,`A`>> ISA extension and compromises
instructions for reservation-set <<_atomic_memory_access>> operations. It is enabled by the top's
<<_processor_top_entity_generics, `RISCV_ISA_Zalrsc`>> generic.

.Instructions and Timing
[cols="<2,<4,<1"]
[options="header", grid="rows"]
|=======================
| Class | Instructions | Execution cycles
| Atomic memory operations | `amoswap.w` `amoadd.w` `amoand.w` `amoor.w` `amoxor.w` `amomax[u].w` `amomin[u].w` | 5 + 2 * _memory_latency_
| Atomic reservation-set | `lr.w` `sc.w` | 5 +_memory_latency_
|=======================

.`aq` and `rl` Bits
Expand Down
8 changes: 7 additions & 1 deletion docs/datasheet/cpu_csr.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ will _not_ cause an illegal instruction exception.
[options="header",grid="rows"]
|=======================
| Bit | Name [C] | R/W | Function
| 0 | `CSR_MISA_A_EXT` | r/- | **A**: CPU extension (atomic memory access) available, set when <<_a_isa_extension>> enabled
| 1 | `CSR_MISA_B_EXT` | r/- | **B**: CPU extension (bit-manipulation) available, set when <<_b_isa_extension>> enabled
| 2 | `CSR_MISA_C_EXT` | r/- | **C**: CPU extension (compressed instruction) available, set when <<_c_isa_extension>> enabled
| 4 | `CSR_MISA_E_EXT` | r/- | **E**: CPU extension (embedded) available, set when <<_e_isa_extension>> enabled
Expand Down Expand Up @@ -760,6 +761,11 @@ caused by a fence instruction, a control flow transfer or a instruction fetch bu
The CPU HPM/counter logic treats all executed instruction as "retired" even if they raise an exception,
cause an interrupt, trigger a privilege mode change or were not meant to retire (i.e. claimed by the RISC-V spec.).

.Atomic Memory Access
[NOTE]
The read-modify-write instructions of the <<_zaamo_isa_extension>> operate as simple load for the CPU hardware.
Hence, they will only trigger `HPMCNT_EVENT_LOAD` and only once.


{empty} +
[discrete]
Expand Down Expand Up @@ -1022,7 +1028,7 @@ discover additional ISA (sub-)extensions and CPU configuration options.
| 23 | `CSR_MXISA_ZBB` | r/- | <<_zbb_isa_extension>> available
| 24 | `CSR_MXISA_ZBS` | r/- | <<_zbs_isa_extension>> available
| 25 | `CSR_MXISA_ZAAMO` | r/- | <<_zaamo_isa_extension>> available
| 28:26 | - | r/- | _reserved_, hardwired to zero
| 26 | `CSR_MXISA_ZALRSC` | r/- | <<_zalrsc_isa_extension>> available
| 27 | `CSR_MXISA_CLKGATE` | r/- | sleep-mode clock gating implemented when set (`CPU_CLOCK_GATING_EN`), see <<_cpu_tuning_options>>
| 28 | `CSR_MXISA_RFHWRST` | r/- | full hardware reset of register file available when set (`CPU_RF_HW_RST_EN`), see <<_cpu_tuning_options>>
| 29 | `CSR_MXISA_FASTMUL` | r/- | fast multiplication available when set (`CPU_FAST_MUL_EN`), see <<_cpu_tuning_options>>
Expand Down
63 changes: 49 additions & 14 deletions docs/datasheet/soc.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ The generic type "`suv(x:y)`" is an abbreviation for "`std_ulogic_vector(x downt
| `RISCV_ISA_E` | boolean | false | Enable <<_e_isa_extension>> (reduced register file size).
| `RISCV_ISA_M` | boolean | false | Enable <<_m_isa_extension>> (hardware-based integer multiplication and division).
| `RISCV_ISA_U` | boolean | false | Enable <<_u_isa_extension>> (less-privileged user mode).
| `RISCV_ISA_Zaamo` | boolean | false | Enable <<_zaamo_isa_extension>> (atomic memory operations).
| `RISCV_ISA_Zaamo` | boolean | false | Enable <<_zaamo_isa_extension>> (atomic read-modify-write operations).
| `RISCV_ISA_Zalrsc` | boolean | false | Enable <<_zalrsc_isa_extension>> (atomic reservation-set operations).
| `RISCV_ISA_Zba` | boolean | false | Enable <<_zba_isa_extension>> (shifted-add bit-manipulation instructions).
| `RISCV_ISA_Zbb` | boolean | false | Enable <<_zbb_isa_extension>> (basic bit-manipulation instructions).
| `RISCV_ISA_Zbkb` | boolean | false | Enable <<_zbkb_isa_extension>> (scalar cryptography bit manipulation instructions).
Expand Down Expand Up @@ -574,8 +575,32 @@ constant base_io_dma_c : std_ulogic_vector(31 downto 0) := x"ffffed00";
:sectnums:
==== Atomic Memory Operations Controller

The atomic memory operations (AMO) controller is responsible for handling the read-modify-write operations issued by the
CPU's <<_zaamo_isa_extension>>. For each AMO request, the controller executes an atomic set of three operations:
The atomic memory operations controller is split into two individual modules. Each module
implements a specific sub-extensions of the <<_a_isa_extension,`A`>> ISA extension:

[cols="<3,<3,<4"]
[options="header",grid="rows"]
|=======================
| Hardware Module | ISA Extensions | Description
| `neorv32_bus_amo_rmw` | <<_zaamo_isa_extension>> | Atomic read-modify-write operations
| `neorv32_bus_amo_rvs` | <<_zalrsc_isa_extension>> | Atomic reservation-set operations
|=======================

.Direct Access
[IMPORTANT]
Atomic operations **always bypass** the CPU's <<_processor_internal_data_cache_dcache, data cache>>
using direct/uncached accesses. Care must be taken to maintain data <<_memory_coherence>>.

.Physical Memory Attributes
[NOTE]
Atomic memory operations can be executed for _any_ address. This also includes
cached memory, memory-mapped IO devices and processor-external address spaces.

===== Atomic Read-Modify-Write Controller

This modules converts a single atomic memory operations request into a set of bus transactions
to execute an un-interruptable read-modify-write (RMW) operation. For each request, the controller
executes an atomic set of three operations:

.Simplified AMO Controller Operation
[cols="^1,<3,<6"]
Expand All @@ -591,21 +616,31 @@ written to the addressed memory cell. In parallel, the data from the first buffe
content of the addresses memory cell) is sent back to the requesting CPU.
|=======================

.Direct Access
[IMPORTANT]
Atomic operations **always bypass** the CPU's <<_processor_internal_data_cache_dcache, data cache>>
using direct/uncached accesses. Care must be taken to maintain data <<_memory_coherence>>.
The controller performs two bus transactions: a read operations and a write operation. Only the acknowledge/error
handshake of the last transaction is sent back to the CPU. As the RMW controller is the memory-nearest instance
(see <<_bus_system>>) the previously described set of operations cannot be interrupted. Hence, they execute in
an atomic way.

.Physical Memory Attributes
===== Atomic Reservation-Set Controller

A "reservation" defines an address or address range that provides a guarding mechanism to support atomic accesses. A new
reservation is registered by the `LR` instruction. The address provided by this instruction defines the memory location
that is now monitored for atomic accesses. The according `SC` instruction evaluates the state of this reservation. If
the reservation is still valid the write access triggered by the SC instruction is finally executed and the instruction
return a "success" state (`rd` = 0). If the reservation has been invalidated the SC instruction will not write to memory
and will return a "failed" state (`rd` = 1).

.Reservation Set and Granule
[NOTE]
Atomic memory operations can be executed for _any_ address. This also includes
cached memory, memory-mapped IO devices and processor-external address spaces.
The reservation set controller supports only **single global`` reservation set. Hence, the entire physical address
space is treated as single granule.

The controller performs two bus transactions: a read operations and a write operation. Only the acknowledge/error
handshake of the last transaction is sent back to the CPU.
The reservation-set controller implements the _strong semnatics_. An active reservation is invalidated if...

As the AMO controller is the memory-nearest instance (see <<_bus_system>>) the previously described set of operations
cannot be interrupted. Hence, they execute in an atomic way.
* an `SC` instruction is executed. If there is **no** previous `LR` instruction, the `SC` instruction will **fail** (not writing to memory).
* an `SC` instruction is executed. If there **is** a previous `LR` instruction, the `SC` instruction will **succeed** (finally writing to memory).
* a normal store operation is executed (by a CPU / CPU cache, the DMA or the on-chip debugger).
* a hardware reset is triggered.


:sectnums:
Expand Down
8 changes: 5 additions & 3 deletions docs/datasheet/soc_xbus.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ However, classic mode can still be _emulated_ by connecting the processor's `xbu
device's / bus system's `cyc` and `stb` signals (omitting the processor's `xbus_stb_o` signal).

.Atomic Memory Accesses
[NOTE]
<<_atomic_memory_access>> operations keep the `cyc` signal active to perform a back-to-back bus access
consisting of two `stb` strobes (one for the load/read operation and another one for the store/write operation).
[IMPORTANT]
<<_atomic_memory_access>> operations (read-modify-write) keep the `cyc` signal active to perform a
back-to-back bus access consisting of two `stb` strobes (one for the load/read operation and another
one for the store/write operation). Reservation-set operations (<<_zalrsc_isa_extension>>) are not
propagated via the XBUS interface and appear as normal load/store operations.

.Wishbone Specs.
[TIP]
Expand Down
Binary file modified docs/figures/neorv32_processor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2b7d619

Please sign in to comment.