OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [cpu.adoc] - Diff between revs 69 and 70

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 69 Rev 70
Line 37... Line 37...
[NOTE]
[NOTE]
It is recommended to use the **NEORV32 Processor** as default top instance even if you only want to use the actual
It is recommended to use the **NEORV32 Processor** as default top instance even if you only want to use the actual
CPU. Simply disable all the processor-internal modules via the generics and you will get a "CPU
CPU. Simply disable all the processor-internal modules via the generics and you will get a "CPU
wrapper" that provides a minimal CPU environment and an external bus interface (like AXI4). This
wrapper" that provides a minimal CPU environment and an external bus interface (like AXI4). This
setup also allows to further use the default bootloader and software framework. From this base you
setup also allows to further use the default bootloader and software framework. From this base you
can start building your own SoC. Of course you can also use the CPU in it’s true stand-alone mode.
can start building your own SoC. Of course you can also use the CPU in it's true stand-alone mode.
 
 
[NOTE]
[NOTE]
This documentation assumes the reader is familiar with the official RISC-V "User" and "Privileged Architecture" specifications.
This documentation assumes the reader is familiar with the official RISC-V "User" and "Privileged Architecture" specifications.
 
 
 
 
Line 195... Line 195...
Check srli-01           ... OK
Check srli-01           ... OK
Check sub-01            ... OK
Check sub-01            ... OK
Check sw-align-01       ... OK
Check sw-align-01       ... OK
Check xor-01            ... OK
Check xor-01            ... OK
Check xori-01           ... OK
Check xori-01           ... OK
 
Check fence-01          ... OK
--------------------------------
--------------------------------
OK: 38/38 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32
OK: 39/39 RISCV_TARGET=neorv32 RISCV_DEVICE=I XLEN=32
...................................
...................................
 
 
.**RISC-V `rv32_m/M` Tests**
.**RISC-V `rv32_m/M` Tests**
...................................
...................................
Check div-01            ... OK
Check div-01            ... OK
Line 258... Line 259...
Any machine-mode write access to them is ignored and will _not_ cause any exceptions or side-effects to maintain
Any machine-mode write access to them is ignored and will _not_ cause any exceptions or side-effects to maintain
RISC-V compatibility.
RISC-V compatibility.
 
 
.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_csrs>>)
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.
Line 424... Line 425...
 
 
[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.
 
 
The `Zbb` sub-extension adds the following instruction:
The `Zbb` sub-extension adds the following instructions:
 
 
* `andn`, `orn`, `xnor`
* `andn` `orn` `xnor`
* `clz`, `ctz`, `cpop`
* `clz` `ctz` `cpop`
* `max`, `maxu`, `min`, `minu`
* `max` `maxu` `min` `minu`
* `sext.b`, `sext.h`, `zext.h`
* `sext.b` `sext.h` `zext.h`
* `rol`, `ror`, `rori`
* `rol` `ror` `rori`
* `orc.b`, `rev8`
* `orc.b` `rev8`
 
 
The `Zba` sub-extension adds the following instruction:
The `Zba` sub-extension adds the following instructions:
 
 
* `sh1add`, `sh2add`, `sh3add`
* `sh1add` `sh2add` `sh3add`
 
 
[TIP]
[TIP]
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
like `clz` and `rol`. To increase performance (at the cost of additional hardware resources) the
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
<<_fast_shift_en>> generic can be enabled to implement full-parallel logic (like barrel shifters) for all
Line 456... Line 457...
 
 
The _compressed_ ISA extension provides 16-bit encodings of commonly used instructions to reduce code space size.
The _compressed_ ISA extension provides 16-bit encodings of commonly used instructions to reduce code space size.
The `C` extension is available when the `CPU_EXTENSION_RISCV_C` configuration generic is _true_.
The `C` extension is available when the `CPU_EXTENSION_RISCV_C` configuration generic is _true_.
In this case the following instructions are available:
In this case the following instructions are available:
 
 
* `c.addi4spn`, `c.lw`, `c.sw`, `c.nop`, `c.addi`, `c.jal`, `c.li`, `c.addi16sp`, `c.lui`, `c.srli`, `c.srai` `c.andi`, `c.sub`,
* `c.addi4spn` `c.lw` `c.sw` `c.nop` `c.addi` `c.jal` `c.li` `c.addi16sp` `c.lui` `c.srli` `c.srai` `c.andi` `c.sub`
`c.xor`, `c.or`, `c.and`, `c.j`, `c.beqz`, `c.bnez`, `c.slli`, `c.lwsp`, `c.jr`, `c.mv`, `c.ebreak`, `c.jalr`, `c.add`, `c.swsp`
`c.xor` `c.or` `c.and` `c.j` `c.beqz` `c.bnez` `c.slli` `c.lwsp` `c.jr` `c.mv` `c.ebreak` `c.jalr` `c.add` `c.swsp`
 
 
[NOTE]
[NOTE]
When the compressed instructions extension is enabled, branches to an _unaligned_ and _uncompressed_ instruction require
When the compressed instructions extension is enabled, branches to an _unaligned_ and _uncompressed_ instruction require
an additional instruction fetch to load the according second half-word of that instruction. The performance can be increased
an additional instruction fetch to load the according second half-word of that instruction. The performance can be increased
again by forcing a 32-bit alignment of branch target addresses. By default, this is enforced via the GCC `-falign-functions=4`,
again by forcing a 32-bit alignment of branch target addresses. By default, this is enforced via the GCC `-falign-functions=4`,
Line 473... Line 474...
The embedded CPU extensions reduces the size of the general purpose register file from 32 entries to 16 entries to
The embedded CPU extensions reduces the size of the general purpose register file from 32 entries to 16 entries to
decrease physical hardware requirements (for example block RAM). This extensions is enabled when the `CPU_EXTENSION_RISCV_E`
decrease physical hardware requirements (for example block RAM). This extensions is enabled when the `CPU_EXTENSION_RISCV_E`
configuration generic is _true_. Accesses to registers beyond `x15` will raise and _illegal instruction exception_.
configuration generic is _true_. Accesses to registers beyond `x15` will raise and _illegal instruction exception_.
This extension does not add any additional instructions or features.
This extension does not add any additional instructions or features.
 
 
[IMPORTANT]
[NOTE]
Due to the reduced register file size an alternate toolchain ABI (**`ilp32e`**) is required.
Due to the reduced register file size an alternate toolchain ABI (**`ilp32e`**) is required.
 
 
 
 
==== **`I`** - Base Integer ISA
==== **`I`** - Base Integer ISA
 
 
The CPU always supports the complete `rv32i` base integer instruction set. This base set is always enabled
The CPU always supports the complete `rv32i` base integer instruction set. This base set is always enabled
regardless of the setting of the remaining exceptions. The base instruction set includes the following
regardless of the setting of the remaining exceptions. The base instruction set includes the following
instructions:
instructions:
 
 
* immediate: `lui`, `auipc`
* immediate: `lui` `auipc`
* jumps: `jal`, `jalr`
* jumps: `jal` `jalr`
* branches: `beq`, `bne`, `blt`, `bge`, `bltu`, `bgeu`
* branches: `beq` `bne` `blt` `bge` `bltu` `bgeu`
* memory: `lb`, `lh`, `lw`, `lbu`, `lhu`, `sb`, `sh`, `sw`
* memory: `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw`
* alu: `addi`, `slti`, `sltiu`, `xori`, `ori`, `andi`, `slli`, `srli`, `srai`, `add`, `sub`, `sll`, `slt`, `sltu`, `xor`, `srl`, `sra`, `or`, `and`
* alu: `addi` `slti` `sltiu` `xori` `ori` `andi` `slli` `srli` `srai` `add` `sub` `sll` `slt` `sltu` `xor` `srl` `sra` `or` `and`
* environment: `ecall`, `ebreak`, `fence`
* environment: `ecall` `ebreak` `fence`
 
 
[NOTE]
[NOTE]
In order to keep the hardware footprint low, the CPU's shift unit uses a bit-serial serial approach. Hence, shift operations
In order to keep the hardware footprint low, the CPU's shift unit uses a bit-serial approach. Hence, shift operations
take up to 32 cycles (plus overhead) depending on the actual shift amount. Alternatively, the shift operations can be processed
take up to 32 cycles (plus overhead) depending on the actual shift amount. Alternatively, the shift operations can be processed
completely in parallels by a fast (but large) barrel shifter when the `FAST_SHIFT_EN` generic is _true_. In that case, shift operations
completely in parallel by a fast (but large) barrel shifter if the `FAST_SHIFT_EN` generic is _true_. In that case, shift operations
complete within 2 cycles (plus overhead) regardless of the actual shift amount.
complete within 2 cycles (plus overhead) regardless of the actual shift amount.
 
 
[NOTE]
[NOTE]
Internally, the `fence` instruction does not perform any operation inside the CPU. It only sets the
Internally, the `fence` instruction does not perform any operation inside the CPU. It only sets the
top’s `d_bus_fence_o` signal high for one cycle to inform the memory system a `fence` instruction has been
top's `d_bus_fence_o` signal high for one cycle to inform the memory system a `fence` instruction has been
executed. Any flags within the `fence` instruction word are ignore by the hardware.
executed. Any flags within the `fence` instruction word are ignore by the hardware.
 
 
 
 
==== **`M`** - Integer Multiplication and Division
==== **`M`** - Integer Multiplication and Division
 
 
Hardware-accelerated integer multiplication and division operations are available when the
Hardware-accelerated integer multiplication and division operations are available when the
`CPU_EXTENSION_RISCV_M` configuration generic is _true_. In this case the following instructions are
`CPU_EXTENSION_RISCV_M` configuration generic is _true_. In this case the following instructions are
available:
available:
 
 
* multiplication: `mul`, `mulh`, `mulhsu`, `mulhu`
* multiplication: `mul` `mulh` `mulhsu` `mulhu`
* division: `div`, `divu`, `rem`, `remu`
* division: `div` `divu` `rem` `remu`
 
 
[NOTE]
[NOTE]
By default, multiplication and division operations are executed in a bit-serial approach.
By default, multiplication and division operations are executed in a bit-serial approach.
Alternatively, the multiplier core can be implemented using DSP blocks if the `FAST_MUL_EN`
Alternatively, the multiplier core can be implemented using DSP blocks if the `FAST_MUL_EN`
generic is _true_ allowing faster execution. Multiplications and divisions
generic is _true_ allowing faster execution. Multiplications and divisions
Line 525... Line 526...
This is a _sub-extension_ of the `M` ISA extension. It implements the multiplication-only operations
This is a _sub-extension_ of the `M` ISA extension. It implements the multiplication-only operations
of the `M` extensions and is intended for size-constrained setups that require hardware-based
of the `M` extensions and is intended for size-constrained setups that require hardware-based
integer multiplications but not hardware-based divisions, which will be computed entirely in software.
integer multiplications but not hardware-based divisions, which will be computed entirely in software.
This extension requires only ~50% of the hardware utilization of the "full" `M` extension.
This extension requires only ~50% of the hardware utilization of the "full" `M` extension.
 
 
* multiplication: `mul`, `mulh`, `mulhsu`, `mulhu`
* multiplication: `mul` `mulh` `mulhsu` `mulhu`
 
 
If `Zmmul` is enabled, executing any division instruction from the `M` ISA extension (`div`, `divu`, `rem`, `remu`)
If `Zmmul` is enabled, executing any division instruction from the `M` ISA extension (`div`, `divu`, `rem`, `remu`)
will raise an _illegal instruction exception_.
will raise an _illegal instruction exception_.
 
 
Note that `M` and `Zmmul` extensions _cannot_ be enabled at the same time.
Note that `M` and `Zmmul` extensions _cannot_ be enabled at the same time.
Line 567... Line 568...
instead of a dedicated floating-point register file (hence, `F-in-x`). Thus, the `Zfinx` extension requires
instead of a dedicated floating-point register file (hence, `F-in-x`). Thus, the `Zfinx` extension requires
less hardware resources and features faster context changes. This also implies that there are NO dedicated `f`
less hardware resources and features faster context changes. This also implies that there are NO dedicated `f`
register file-related load/store or move instructions.
register file-related load/store or move instructions.
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-zfinx
The official RISC-V specifications can be found here: https://github.com/riscv/riscv-zfinx
 
 
[TIP]
[NOTE]
The NEORV32 floating-point unit used by the `Zfinx` extension is compatible to the _IEEE-754_ specifications.
The NEORV32 floating-point unit used by the `Zfinx` extension is compatible to the _IEEE-754_ specifications.
 
 
The `Zfinx` extensions only supports single-precision (`.s` instruction suffix), so it is a direct alternative
The `Zfinx` extensions only supports single-precision (`.s` instruction suffix), so it is a direct alternative
to the `F` extension. The `Zfinx` extension is implemented when the `CPU_EXTENSION_RISCV_Zfinx` configuration
to the `F` extension. The `Zfinx` extension is implemented when the `CPU_EXTENSION_RISCV_Zfinx` configuration
generic is _true_. In this case the following instructions and CSRs are available:
generic is _true_. In this case the following instructions and CSRs are available:
 
 
* conversion: `fcvt.s.w`, `fcvt.s.wu`, `fcvt.w.s`, `fcvt.wu.s`
* conversion: `fcvt.s.w` `fcvt.s.wu` `fcvt.w.s` `fcvt.wu.s`
* comparison: `fmin.s`, `fmax.s`, `feq.s`, `flt.s`, `fle.s`
* comparison: `fmin.s` `fmax.s` `feq.s` `flt.s` `fle.s`
* computational: `fadd.s`, `fsub.s`, `fmul.s`
* computational: `fadd.s` `fsub.s` `fmul.s`
* sign-injection: `fsgnj.s`, `fsgnjn.s`, `fsgnjx.s`
* sign-injection: `fsgnj.s` `fsgnjn.s` `fsgnjx.s`
* number classification: `fclass.s`
* number classification: `fclass.s`
 
 
* additional CSRs: `fcsr`, `frm`, `fflags`
* additional CSRs: `fcsr` `frm` `fflags`
 
 
[WARNING]
[WARNING]
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported!
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported!
Division `fdiv.s` and square root `fsqrt.s` instructions are not supported yet!
Division `fdiv.s` and square root `fsqrt.s` instructions are not supported yet!
 
 
Line 607... Line 608...
is implemented when the `CPU_EXTENSION_RISCV_Zicsr` configuration generic is _true_.
is implemented when the `CPU_EXTENSION_RISCV_Zicsr` configuration generic is _true_.
 
 
[IMPORTANT]
[IMPORTANT]
If the `Zicsr` extension is disabled the CPU does not provide any _privileged architecture_ features at all!
If the `Zicsr` extension is disabled the CPU does not provide any _privileged architecture_ features at all!
In order to provide the full set of privileged functions that are required to run more complex tasks like
In order to provide the full set of privileged functions that are required to run more complex tasks like
operating system and to allow a secure execution environment the `Zicsr` extension should always be enabled.
operating system and to allow a secure execution environment the `Zicsr` extension should be always enabled.
 
 
In this case the following instructions are available:
In this case the following instructions are available:
 
 
* CSR access: `csrrw`, `csrrs`, `csrrc`, `csrrwi`, `csrrsi`, `csrrci`
* CSR access: `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci`
* environment: `mret`, `wfi`
* environment: `mret` `wfi`
 
 
[NOTE]
[NOTE]
If `rd=x0` for the `csrrw[i]` instructions there will be no actual read access to the according CSR.
If `rd=x0` for the `csrrw[i]` instructions there will be no actual read access to the according CSR.
However, access privileges are still enforced so these instruction variants _do_ cause side-effects
However, access privileges are still enforced so these instruction variants _do_ cause side-effects
(the RISC-V spec. state that these combinations "_shall_ not cause any side-effects").
(the RISC-V spec. state that these combinations "_shall_ not cause any side-effects").
Line 697... Line 698...
 
 
* `pmpcfg*` (0..15, depending on configuration): PMP configuration registers
* `pmpcfg*` (0..15, depending on configuration): PMP configuration registers
* `pmpaddr*` (0..63, depending on configuration): PMP address registers
* `pmpaddr*` (0..63, depending on configuration): PMP address registers
 
 
[TIP]
[TIP]
See section <<_machine_physical_memory_protection>> for more information regarding the PMP CSRs.
See section <<_machine_physical_memory_protection_csrs>> for more information regarding the PMP CSRs.
 
 
The actual number of regions and the minimal region granularity are defined via the top entity
The actual number of regions and the minimal region granularity are defined via the top entity
`PMP_MIN_GRANULARITY` and `PMP_NUM_REGIONS` generics. `PMP_MIN_GRANULARITY` defines the minimal available
`PMP_MIN_GRANULARITY` and `PMP_NUM_REGIONS` generics. `PMP_MIN_GRANULARITY` defines the minimal available
granularity of each region in bytes. `PMP_NUM_REGIONS` defines the total number of implemented regions and thus, the
granularity of each region in bytes. `PMP_NUM_REGIONS` defines the total number of implemented regions and thus, the
number of available `pmpcfg*` and `pmpaddr*` CSRs.
number of available `pmpcfg*` and `pmpaddr*` CSRs.
Line 821... Line 822...
* _traps_ = exceptions + interrupts (synchronous or asynchronous exceptions)
* _traps_ = exceptions + interrupts (synchronous or asynchronous exceptions)
 
 
Whenever an exception or interrupt is triggered, the CPU transfers control to the address stored in `mtvec`
Whenever an exception or interrupt is triggered, the CPU transfers control to the address stored in `mtvec`
CSR. The cause of the according interrupt or exception can be determined via the content of `mcause`
CSR. The cause of the according interrupt or exception can be determined via the content of `mcause`
CSR. The address that reflects the current program counter when a trap was taken is stored to `mepc` CSR.
CSR. The address that reflects the current program counter when a trap was taken is stored to `mepc` CSR.
Additional information regarding the cause of the trap can be retrieved from `mtval` CSR.
Additional information regarding the cause of the trap can be retrieved from `mtval` CSR and the processor's
 
<<_internal_bus_monitor_buskeeper>> (for memory access exceptions)
 
 
The traps are prioritized. If several _exceptions_ occur at once only the one with highest priority is triggered
The traps are prioritized. If several _synchronous 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 _asynchronous exceptions_ (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 interrupts are pending.
 
 
.Interrupt Signal Requirements - Standard RISC-V Interrupts
.Interrupt Signal Requirements - Standard RISC-V Interrupts
[IMPORTANT]
[IMPORTANT]
All standard RISC-V interrupts request signals 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
.Interrupt Signal Requirements - Fast Interrupt Requests
[IMPORTANT]
[IMPORTANT]
The NEORV32-specific FIRQ request lines are triggered by a rising edge. Each request is buffered in the CPU control
The NEORV32-specific FIRQ request lines are triggered by a one-shot high-level (i.e. 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
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).
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 even if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before
a new interrupt handler can start.
another interrupt handler can start. This allows program progress even if there are permanent interrupt requests.
 
 
 
 
:sectnums:
:sectnums:
==== Memory Access Exceptions**
==== Memory Access Exceptions
 
 
If a load operation causes any exception, the instruction's destination register is
If a load operation causes any exception, the instruction's destination register is
_not written_ at all. Load exceptions caused by a misalignment or a physical memory protection fault do not
_not written_ at all. Load exceptions caused by a misalignment or a physical memory protection fault do not
trigger a bus read-operation at all. Exceptions caused by a store address misalignment or a store physical
trigger a bus/memory read-operation at all. Vice versa, exceptions caused by a store address misalignment or a store physical
memory protection fault do not trigger a bus write-operation at all.
memory protection fault do not trigger a bus/memory write-operation at all.
 
 
 
 
:sectnums:
:sectnums:
==== Custom Fast Interrupt Request Lines
==== Custom Fast Interrupt Request Lines
 
 
Line 880... Line 882...
 
 
**Table Annotations**
**Table Annotations**
 
 
The "Prio." column shows the priority of each trap. The highest priority is 1. The "`mcause`" column shows the
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
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
official RISC-V privileged architecture manual. The "[C]" names are defined by the NEORV32 core library (the runtime environment _RTE_) and can
be used in plain C code. The "`mepc`" and "`mtval`" columns show the value written to
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:
`mepc` and `mtval` CSRs when a trap is triggered:
 
 
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
* _B-ADR_- bad memory access address that cause the trap
* _B-ADR_- bad memory access address that cause the trap
Line 933... Line 935...
 
 
.NEORV32 Trap Description
.NEORV32 Trap Description
[cols="<3,<7"]
[cols="<3,<7"]
[options="header",grid="rows"]
[options="header",grid="rows"]
|=======================
|=======================
| Trap ID | Triggered when ...
| Trap ID [C] | Triggered when ...
| _TRAP_CODE_I_MISALIGNED_ | fetching an 32-bit instruction word that is not 32-bit-aligned (_see note below!_)
| _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_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_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_MENV_CALL_    | executing `ecall` instruction in machine-mode
| _TRAP_CODE_UENV_CALL_    | executing `ecall` instruction in user-mode
| _TRAP_CODE_UENV_CALL_    | executing `ecall` instruction in user-mode
Line 1001... Line 1003...
| `bus_priv_o`   | 2  | current CPU privilege level
| `bus_priv_o`   | 2  | current CPU privilege level
|=======================
|=======================
 
 
[NOTE]
[NOTE]
Currently, there a no pipelined or overlapping operations implemented within the same bus interface.
Currently, there a no pipelined or overlapping operations implemented within the same bus interface.
So only a single transfer request can be "on the fly".
So only a single transfer request can be "on the fly" (pending) at once.
 
 
:sectnums:
:sectnums:
===== Protocol
===== Protocol
 
 
A bus request is triggered either by the `bus_re_o` signal (for reading data) or by the `bus_we_o` signal (for
A bus request is triggered either by the `bus_re_o` signal (for reading data) or by the `bus_we_o` signal (for
Line 1105... Line 1107...
In order to reduce routing constraints (and by this the actual hardware requirements), most uncritical
In order to reduce routing constraints (and by this the actual hardware requirements), most uncritical
registers of the NEORV32 CPU as well as most register of the whole NEORV32 Processor do not use **a
registers of the NEORV32 CPU as well as most register of the whole NEORV32 Processor do not use **a
dedicated hardware reset**. "Uncritical registers" in this context means that the initial value of these registers
dedicated hardware reset**. "Uncritical registers" in this context means that the initial value of these registers
after power-up is not relevant for a defined CPU boot process.
after power-up is not relevant for a defined CPU boot process.
 
 
**Rational**
**Rationale**
 
 
A good example to illustrate the concept of uncritical registers is a pipelined processing engine. Each stage
A good example to illustrate the concept of uncritical registers is a pipelined processing engine. Each stage
of the engine features an N-bit _data register_ and a 1-bit _status register_. The status register is set when the
of the engine features an N-bit _data register_ and a 1-bit _status register_. The status register is set when the
data in the according data register is valid. At the end of the pipeline the status register might trigger a write-back
data in the according data register is valid. At the end of the pipeline the status register might trigger a write-back
of the processing result to some kind of memory. The initial status of the data registers after power-up is
of the processing result to some kind of memory. The initial status of the data registers after power-up is
irrelevant as long as the status registers are all reset to a defined value that indicates there is no valid data in
irrelevant as long as the status registers are all reset to a defined value that indicates there is no valid data in
the pipeline’s data register. Therefore, the pipeline data register do no require a dedicated reset as they do not
the pipeline's data register. Therefore, the pipeline data register do no require a dedicated reset as they do not
control the actual operation (in contrast to the status register). This makes the pipeline data registers from
control the actual operation (in contrast to the status register). This makes the pipeline data registers from
this example "uncritical registers".
this example "uncritical registers".
 
 
**NEORV32 CPU Reset**
**NEORV32 CPU Reset**
 
 
In terms of the NEORV32 CPU, there are several pipeline registers, state machine registers and even status
In terms of the NEORV32 CPU, there are several pipeline registers, state machine registers and even status
and control registers (CSRs) that do not require a defined initial state to ensure a correct boot process. The
and control registers (CSRs) that do not require a defined initial state to ensure a correct boot process. The
pipeline register will get initialized by the CPU’s internal state machines, which are initialized from the main
pipeline register will get initialized by the CPU's internal state machines, which are initialized from the main
control engine that actually features a defined reset. The initialization of most of the CPU's core CSRs (like
control engine that actually features a defined reset. The initialization of most of the CPU's core CSRs (like
interrupt control) is done by the software (to be more specific, this is done by the `crt0.S` start-up code).
interrupt control) is done by the software (to be more specific, this is done by the `crt0.S` start-up code).
 
 
During the very early boot process (where `crt0.S` is running) there is no chance for undefined behavior due to
During the very early boot process (where `crt0.S` is running) there is no chance for undefined behavior due to
the lack of dedicated hardware resets of certain CSRs. For example the machine interrupt-enable CSR (`mie`)
the lack of dedicated hardware resets of certain CSRs. For example the machine interrupt-enable CSR (`mie`)
does not provide a dedicated reset. The value after reset of this register is uncritical as interrupts cannot fire
does not provide a dedicated reset. The value after reset of this register is uncritical as interrupts cannot fire
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) provides a dedicated
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) _do_ provide a dedicated
hardware reset setting it to low (globally disabling interrupts).
hardware reset setting this bit to low (globally disabling interrupts).
 
 
**Reset Configuration**
**Reset Configuration**
 
 
Most CPU-internal register do feature an asynchronous reset in the VHDL code, but the "don't care" value
Most CPU-internal register do provide an asynchronous reset in the VHDL code, but the "don't care" value
(VHDL `'-'`) is used for initialization of the uncritical register, effectively generating a flip-flop without a
(VHDL `'-'`) is used for initialization of all uncritical registers, effectively generating a flip-flop without a
reset. However, certain applications or situations (like advanced gate-level / timing simulations) might
reset. However, certain applications or situations (like advanced gate-level / timing simulations) might
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all registers can
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all CPU registers can
be enabled via a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
be enabled ba enabling a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`):
 
 
[source,vhdl]
[source,vhdl]
----
----
-- "critical" number of PMP regions --
-- "critical" number of PMP regions --
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value)
for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW),
 
default; TRUE=defined LOW reset value)
 
----
----

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.