📚 remove A extension and LOCK signals

This commit is contained in:
stnolting 2022-04-27 14:08:08 +02:00
parent 8ba2c960be
commit d181788b25
8 changed files with 33 additions and 134 deletions

View file

@ -18,7 +18,6 @@ image::neorv32_cpu_block.png[width=600,align=center]
* 32-bit little-endian, multi-cycle, in-order `rv32` RISC-V CPU
* Compatible to the RISC-V. **Privileged Architecture - Machine ISA Version 1.12** specifications
* Available <<_instruction_sets_and_extensions>>:
** `A` - atomic memory access operations
** `B` - bit-manipulation instructions
** `C` - 16-bit compressed instructions
** `I` - integer base ISA (always enabled)
@ -272,11 +271,6 @@ The RISC-V-compatible NEORV32 <<_machine_physical_memory_protection_csrs>> only
the according PMP entry and not the entries below. All region rules are checked in parallel **without**
prioritization so for identical memory regions the most restrictive PMP rule will be enforced.
.Atomic Memory Operations
[IMPORTANT]
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.
.No HW-Support of Misaligned Memory Accesses
[WARNING]
The CPU does not support the resolution of unaligned memory access by the hardware. This is not a
@ -303,18 +297,17 @@ direction seen from the CPU.
| `rstn_i` | 1 | in | global reset, low-active
| `sleep_o` | 1 | out | CPU is in sleep mode when set
| `debug_o` | 1 | out | CPU is in debug mode when set
| `priv_o` | 1 | out | current _effective_ CPU privilege level (`0` = user, `1` = machine)
4+^| **Instruction <<_bus_interface>>**
| `i_bus_addr_o` | 32 | out | access address
| `i_bus_rdata_i` | 32 | in | read data
| `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 (always zero)
| `i_bus_we_o` | 1 | out | write transaction (always zero)
| `i_bus_re_o` | 1 | out | read transaction
| `i_bus_lock_o` | 1 | out | exclusive access request (always zero)
| `i_bus_ack_i` | 1 | in | bus transfer acknowledge from accessed peripheral
| `i_bus_err_i` | 1 | in | bus transfer terminate from accessed peripheral
| `i_bus_fence_o` | 1 | out | indicates an executed `fence.i` instruction
| `i_bus_priv_o` | 1 | out | current _effective_ CPU privilege level (`0` user, `1` machine or debug)
4+^| **Data <<_bus_interface>>**
| `d_bus_addr_o` | 32 | out | access address
| `d_bus_rdata_i` | 32 | in | read data
@ -322,11 +315,9 @@ direction seen from the CPU.
| `d_bus_ben_o` | 4 | out | byte enable
| `d_bus_we_o` | 1 | out | write transaction
| `d_bus_re_o` | 1 | out | read transaction
| `d_bus_lock_o` | 1 | out | exclusive access request
| `d_bus_ack_i` | 1 | in | bus transfer acknowledge from accessed peripheral
| `d_bus_err_i` | 1 | in | bus transfer terminate from accessed peripheral
| `d_bus_fence_o` | 1 | out | indicates an executed `fence` instruction
| `d_bus_priv_o` | 1 | out | current _effective_ CPU privilege level (`0` user, `1` machine or debug)
4+^| **System Time (for <<_timeh>> CSR)**
| `time_i` | 64 | in | system time input from <<_machine_system_timer_mtime>>
4+^| **Interrupts, RISC-V-compatible (<<_traps_exceptions_and_interrupts>>)**
@ -394,37 +385,6 @@ Executing an instruction from an extension that is not supported yet or that is
(via the according top entity generic) will raise an illegal instruction exception.
==== **`A`** - Atomic Memory Access
Atomic memory access instructions allow more sophisticated memory operations like implementing semaphores and mutexes.
The RICS-C specs. defines a specific _atomic_ extension that provides instructions for atomic memory accesses. The `A`
ISA extension is enabled if the <<_cpu_extension_riscv_a>> configuration generic is _true_.
In this case the following additional instructions are available:
* `lr.w`: load-reservate
* `sc.w`: store-conditional
[NOTE]
Even though only `lr.w` and `sc.w` instructions are implemented yet, all further atomic operations
(load-modify-write instruction) can be emulated using these two instruction. Furthermore, the
instruction's ordering flags (`aq` and `lr`) are ignored by the CPU hardware. Using any other (not yet
implemented) AMO (atomic memory operation) will raise an illegal instruction exception.
The *load-reservate* instruction behaves as a "normal" load-word instruction (`lw`) but will also set a CPU-internal
_data memory access lock_. Executing a *store-conditional* behaves as "normal" store-word instruction (`sw`) that will
only conduct an actual memory write operations if the lock is still intact. Additionally, the store-conditional instruction
will also return the lock state (returns zero if the lock is still intact or non-zero if the lock has been broken).
After the execution of the `sc` instruction, the lock is automatically removed.
The lock is broken if at least one of the following conditions occur:
. executing any data memory access instruction other than `lr.w`
. raising _any_ t (for example an interrupt or a memory access exception)
[NOTE]
The atomic instructions have special requirements for memory system / bus interconnect. More
information can be found in sections <<_bus_interface>> and <<_processor_external_memory_interface_wishbone_axi4_lite>>, respectively.
==== **`B`** - Bit-Manipulation Operations
The `B` ISA extension adds instructions for bit-manipulation operations. This extension is enabled if the
@ -1050,18 +1010,16 @@ by the CPU / outputs, `*_i` signals are read by the CPU / inputs). Both interfac
[cols="<2,^1,^1,<6"]
[options="header",grid="rows"]
|=======================
| Signal | Width | Direction | Description
| `i/d_bus_addr_o` | 32 | out | access address
| `i/d_bus_rdata_i` | 32 | in | data input for read operations
| `i/d_bus_wdata_o` | 32 | out | data output for write operations
| `i/d_bus_ben_o` | 4 | out | byte enable signal for write operations
| `i/d_bus_we_o` | 1 | out | bus write access (always zero for instruction fetches)
| `i/d_bus_re_o` | 1 | out | bus read access
| `i/d_bus_lock_o` | 1 | out | exclusive access request
| `i/d_bus_ack_i` | 1 | in | accessed peripheral indicates a successful completion of the bus transaction
| `i/d_bus_err_i` | 1 | in | accessed peripheral indicates an error during the bus transaction
| `i/d_bus_fence_o` | 1 | out | this signal is set for one cycle when the CPU executes an instruction/data fence operation
| `i/d_bus_priv_o` | 2 | out | current CPU privilege level
| Signal | Width | Direction | Description
| `i/d_bus_addr_o` | 32 | out | access address
| `i/d_bus_rdata_i` | 32 | in | data input for read operations
| `i/d_bus_wdata_o` | 32 | out | data output for write operations (always zero for instruction fetch)
| `i/d_bus_ben_o` | 4 | out | byte enable signal for write operations (always zero for instruction fetch)
| `i/d_bus_we_o` | 1 | out | bus write access (always zero for instruction fetch)
| `i/d_bus_re_o` | 1 | out | bus read access
| `i/d_bus_ack_i` | 1 | in | accessed peripheral indicates a successful completion of the bus transaction
| `i/d_bus_err_i` | 1 | in | accessed peripheral indicates an error during the bus transaction
| `i/d_bus_fence_o` | 1 | out | this signal is set for one cycle when the CPU executes an instruction/data fence operation
|=======================
.Pipelined Transfers
@ -1155,32 +1113,6 @@ compressed (16-bit) instructions. The data interface can access memory on byte (
bit) and word (= 32-bit) boundaries.
**Exclusive (Atomic) Access**
The CPU can access memory in an exclusive manner by generating a load-reservate and store-conditional
combination. Normally, these combinations should target the same memory address.
The CPU starts an exclusive access to memory via the _load-reservate instruction_ (`lr.w`). This instruction
will set the CPU-internal _exclusive access lock_, which directly drives the `d_bus_lock_o`. It is the task of
the memory system to manage this exclusive access reservation by storing the according access address and
the source of the access itself (for example via the CPU ID in a multi-core system).
When the CPU executes a _store-conditional instruction_ (`sc.w`) the _CPU-internal exclusive access lock_ is
evaluated to check if the exclusive access was successful. If the lock is still OK, the instruction will write-back
zero and will allow the according store operation to the memory system. If the lock is broken, the
instruction will write-back non-zero and will not generate an actual memory store operation.
The CPU-internal exclusive access lock is broken if at least one of the situations appear.
* when executing any other memory-access operation than `lr.w`
* when any trap (sync. or async.) is triggered (for example to force a context switch)
* when the memory system signals a bus error (via the `bus_err_i` signal)
[TIP]
For more information regarding the SoC-level behavior and requirements of atomic operations see
section <<_processor_external_memory_interface_wishbone_axi4_lite>>.
**Memory Barriers**
Whenever the CPU executes a _fence_ instruction, the according interface signal is set high for one cycle

View file

@ -263,7 +263,6 @@ CSR is simply ignored and will _NOT_ cause an illegal instruction exception.
| 8 | _CSR_MISA_I_EXT_ | r/- | **I**: CPU base ISA, cleared when _CPU_EXTENSION_RISCV_E_ enabled
| 4 | _CSR_MISA_E_EXT_ | r/- | **E**: CPU extension (embedded) available, set when _CPU_EXTENSION_RISCV_E_ enabled
| 2 | _CSR_MISA_C_EXT_ | r/- | **C**: CPU extension (compressed instruction) available, set when _CPU_EXTENSION_RISCV_C_ enabled
| 0 | _CSR_MISA_A_EXT_ | r/- | **A**: CPU extension (atomic memory access) available, set when _CPU_EXTENSION_RISCV_A_ enabled
|=======================
[TIP]

View file

@ -243,19 +243,18 @@ just _exemplary_. If not otherwise mentioned all implementations use the default
[cols="<6,>1,>1,>1,>1,>1"]
[options="header",grid="rows"]
|=======================
| CPU ISA Configuration | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32e` | 830 | 400 | 512 | 0 | 129 MHz
| `rv32i` | 834 | 400 | 1024 | 0 | 129 MHz
| `rv32i_Zicsr` | 1328 | 678 | 1024 | 0 | 128 MHz
| `rv32i_Zicsr_Zicntr` | 1614 | 808 | 1024 | 0 | 128 MHz
| `rv32im_Zicsr_Zicntr` | 2087 | 983 | 1024 | 0 | 128 MHz
| `rv32ima_Zicsr_Zicntr` | 2129 | 987 | 1024 | 0 | 128 MHz
| `rv32imac_Zicsr_Zicntr` | 2338 | 992 | 1024 | 0 | 128 MHz
| `rv32imacb_Zicsr_Zicntr` | 3175 | 1247 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr` | 3186 | 1254 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei` | 3187 | 1254 | 1024 | 0 | 128 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx` | 4450 | 1906 | 1024 | 7 | 123 MHz
| `rv32imacbu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 4825 | 2018 | 1024 | 7 | 123 MHz
| CPU ISA Configuration | LEs | FFs | MEM bits | DSPs | _f~max~_
| `rv32e` | 830 | 400 | 512 | 0 | 129 MHz
| `rv32i` | 834 | 400 | 1024 | 0 | 129 MHz
| `rv32i_Zicsr` | 1328 | 678 | 1024 | 0 | 128 MHz
| `rv32i_Zicsr_Zicntr` | 1614 | 808 | 1024 | 0 | 128 MHz
| `rv32im_Zicsr_Zicntr` | 2087 | 983 | 1024 | 0 | 128 MHz
| `rv32imc_Zicsr_Zicntr` | 2338 | 992 | 1024 | 0 | 128 MHz
| `rv32imcb_Zicsr_Zicntr` | 3175 | 1247 | 1024 | 0 | 128 MHz
| `rv32imcbu_Zicsr_Zicntr` | 3186 | 1254 | 1024 | 0 | 128 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei` | 3187 | 1254 | 1024 | 0 | 128 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei_Zfinx` | 4450 | 1906 | 1024 | 7 | 123 MHz
| `rv32imcbu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 4825 | 2018 | 1024 | 7 | 123 MHz
|=======================
.**RISC-V Compliance**
@ -298,7 +297,7 @@ https://stnolting.github.io/neorv32/ug/#_application_specific_processor_configur
| Boot ROM | Bootloader ROM (4kB) | 3 | 2 | 32768 | 0
| **BUSKEEPER** | Processor-internal bus monitor | 28 | 15 | 0 | 0
| **BUSSWITCH** | Bus multiplexer for CPU instr. and data interface | 69 | 8 | 0 | 0
| CFS | Custom functions subsystemfootnote:[Resource utilization depends on custom design logic.] | - | - | - | -
| CFS | Custom functions subsystem footnote:[Resource utilization depends on custom design logic.] | - | - | - | -
| DM | On-chip debugger - debug module | 473 | 240 | 0 | 0
| DTM | On-chip debugger - debug transfer module (JTAG) | 259 | 221 | 0 | 0
| DMEM | Processor-internal data memory (8kB) | 18 | 2 | 65536 | 0

View file

@ -248,18 +248,6 @@ See section <<_instruction_sets_and_extensions>> for more information. The confi
can be determined via the NEORV32-specific <<_mxisa>> CSR.
:sectnums!:
===== _CPU_EXTENSION_RISCV_A_
[cols="4,4,2"]
[frame="all",grid="none"]
|======
| **CPU_EXTENSION_RISCV_A** | _boolean_ | false
3+| Implement atomic memory access operations when _true_.
See section <<_a_atomic_memory_access>>.
|======
:sectnums!:
===== _CPU_EXTENSION_RISCV_B_

View file

@ -15,7 +15,6 @@
| | `wb_sel_o` | byte enable (4-bit)
| | `wb_stb_o` | strobe (1-bit)
| | `wb_cyc_o` | valid cycle (1-bit)
| | `wb_lock_o` | exclusive access request (1-bit)
| | `wb_ack_i` | acknowledge (1-bit)
| | `wb_err_i` | bus error (1-bit)
| | `fence_o` | an executed `fence` instruction
@ -111,23 +110,6 @@ is compatible to the AXI4 _AxPROT_ signal.
* `wb_tag_o(2)` 1: instruction fetch access, 0: data access
**Exclusive / Atomic Bus Access**
If the atomic memory access CPU extension (via _CPU_EXTENSION_RISCV_A_) is enabled, the CPU can
request an atomic/exclusive bus access via the external memory interface.
The load-reservate instruction (`lr.w`) will set the `wb_lock_o` signal telling the bus interconnect to establish a
reservation for the current accessed address (start of an exclusive access). This signal will stay asserted until
another memory access instruction is executed (for example a `sc.w`).
The memory system has to make sure that no other entity can access the reservated address until `wb_lock_o`
is released again. If this attempt fails, the memory system has to assert `wb_err_i` in order to indicate that the
reservation was broken.
[TIP]
See section <<_bus_interface>> for the CPU bus interface protocol.
**Endianness**
The NEORV32 CPU and the Processor setup are *little-endian* architectures. To allow direct connection

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Before After
Before After

View file

@ -46,7 +46,6 @@ Attributes:
* `r` = read
* `w` = write
* `e` = execute
* `a` = atomic accesses possible
* `8` = byte-accessible
* `16` = half-word-accessible
* `32` = word-accessible
@ -56,11 +55,11 @@ Attributes:
[cols="^4,>3,^5,<11"]
[options="header",grid="rows"]
|=======================
| Base address | Size | Attributes | Description
| `0x00000000` | `imem_size_c` | `r/w/e, a, 8/16/32` | external IMEM (initialized with application image)
| `0x80000000` | `dmem_size_c` | `r/w/e, a, 8/16/32` | external DMEM
| `0xf0000000` | 64 bytes | `r/w/e, !a, 8/16/32` | external "IO" memory, atomic accesses will fail
| `0xff000000` | 4 bytes | `-/w/-, a, -/-/32` | memory-mapped register to trigger "machine external", "machine software" and "SoC Fast Interrupt" interrupts
| Base address | Size | Attributes | Description
| `0x00000000` | `imem_size_c` | `r/w/e 8/16/32` | external IMEM (initialized with application image)
| `0x80000000` | `dmem_size_c` | `r/w/e 8/16/32` | external DMEM
| `0xf0000000` | 64 bytes | `r/w/e 8/16/32` | external "IO" memory
| `0xff000000` | 4 bytes | `-/w/- -/-/32` | memory-mapped register to trigger "machine external", "machine software" and "SoC Fast Interrupt" interrupts
|=======================
[IMPORTANT]
@ -141,7 +140,7 @@ Blinking LED demo program
To do a quick test of the NEORV32 make sure to have https://github.com/ghdl/ghdl[GHDL] and a
https://github.com/stnolting/riscv-gcc-prebuilt[RISC-V gcc toolchain] installed.
Navigate to the project's `sw/example/hello_world` folder and run `make USER_FLAGS+=-DUART0_SIM_MODE MARCH=rv32imac clean_all sim`:
Navigate to the project's `sw/example/hello_world` folder and run `make USER_FLAGS+=-DUART0_SIM_MODE MARCH=rv32imc clean_all sim`:
[TIP]
The simulator will output some _sanity check_ notes (and warnings or even errors if something is ill-configured)
@ -149,7 +148,7 @@ right at the beginning of the simulation to give a brief overview of the actual
[source, bash]
----
stnolting@Einstein:/mnt/n/Projects/neorv32/sw/example/hello_world$ make USER_FLAGS+=-DUART0_SIM_MODE MARCH=rv32imac clean_all sim
stnolting@Einstein:/mnt/n/Projects/neorv32/sw/example/hello_world$ make USER_FLAGS+=-DUART0_SIM_MODE MARCH=rv32imc clean_all sim
../../../sw/lib/source/neorv32_uart.c: In function 'neorv32_uart0_setup':
../../../sw/lib/source/neorv32_uart.c:301:4: warning: #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! [-Wcpp]
301 | #warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only! <1>
@ -165,7 +164,7 @@ Using simulation runtime args: --stop-time=10ms <5>
../rtl/core/neorv32_top.vhd:347:3:@0ms:(assertion note): NEORV32 PROCESSOR IO Configuration: GPIO MTIME UART0 UART1 SPI TWI PWM WDT CFS SLINK NEOLED XIRQ <6>
../rtl/core/neorv32_top.vhd:370:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM).
../rtl/core/neorv32_top.vhd:394:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD).
../rtl/core/neorv32_cpu.vhd:169:3:@0ms:(assertion note): NEORV32 CPU ISA Configuration (MARCH): RV32IMACU_Zbb_Zicsr_Zifencei_Zfinx_Debug
../rtl/core/neorv32_cpu.vhd:169:3:@0ms:(assertion note): NEORV32 CPU ISA Configuration (MARCH): RV32IMCU_Zbb_Zicsr_Zifencei_Zfinx_Debug
../rtl/core/neorv32_cpu.vhd:189:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant <dedicated_reset_c> = TRUE to configure a DEFINED reset value for all CPU registers.
../rtl/core/neorv32_imem.vhd:107:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (16384 bytes), pre-initialized with application (4612 bytes).
../rtl/core/neorv32_dmem.vhd:89:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal DMEM (RAM, 8192 bytes).