URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/docs/datasheet
- from Rev 69 to Rev 70
- ↔ Reverse comparison
Rev 69 → Rev 70
/cpu.adoc
39,7 → 39,7
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 |
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] |
This documentation assumes the reader is familiar with the official RISC-V "User" and "Privileged Architecture" specifications. |
197,8 → 197,9
Check sw-align-01 ... OK |
Check xor-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** |
260,7 → 261,7
|
.Physical Memory Protection |
[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. |
|
.Atomic Memory Operations |
426,18 → 427,18
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset |
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` |
* `clz`, `ctz`, `cpop` |
* `max`, `maxu`, `min`, `minu` |
* `sext.b`, `sext.h`, `zext.h` |
* `rol`, `ror`, `rori` |
* `orc.b`, `rev8` |
* `andn` `orn` `xnor` |
* `clz` `ctz` `cpop` |
* `max` `maxu` `min` `minu` |
* `sext.b` `sext.h` `zext.h` |
* `rol` `ror` `rori` |
* `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] |
By default, the bit-manipulation unit uses an _iterative_ approach to compute shift-related operations |
458,8 → 459,8
The `C` extension is available when the `CPU_EXTENSION_RISCV_C` configuration generic is _true_. |
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.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.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` |
|
[NOTE] |
When the compressed instructions extension is enabled, branches to an _unaligned_ and _uncompressed_ instruction require |
475,7 → 476,7
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. |
|
[IMPORTANT] |
[NOTE] |
Due to the reduced register file size an alternate toolchain ABI (**`ilp32e`**) is required. |
|
|
485,22 → 486,22
regardless of the setting of the remaining exceptions. The base instruction set includes the following |
instructions: |
|
* immediate: `lui`, `auipc` |
* jumps: `jal`, `jalr` |
* branches: `beq`, `bne`, `blt`, `bge`, `bltu`, `bgeu` |
* 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` |
* environment: `ecall`, `ebreak`, `fence` |
* immediate: `lui` `auipc` |
* jumps: `jal` `jalr` |
* branches: `beq` `bne` `blt` `bge` `bltu` `bgeu` |
* 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` |
* environment: `ecall` `ebreak` `fence` |
|
[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 |
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. |
|
[NOTE] |
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. |
|
|
510,8 → 511,8
`CPU_EXTENSION_RISCV_M` configuration generic is _true_. In this case the following instructions are |
available: |
|
* multiplication: `mul`, `mulh`, `mulhsu`, `mulhu` |
* division: `div`, `divu`, `rem`, `remu` |
* multiplication: `mul` `mulh` `mulhsu` `mulhu` |
* division: `div` `divu` `rem` `remu` |
|
[NOTE] |
By default, multiplication and division operations are executed in a bit-serial approach. |
527,7 → 528,7
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. |
|
* 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`) |
will raise an _illegal instruction exception_. |
569,7 → 570,7
register file-related load/store or move instructions. |
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 `Zfinx` extensions only supports single-precision (`.s` instruction suffix), so it is a direct alternative |
576,13 → 577,13
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: |
|
* conversion: `fcvt.s.w`, `fcvt.s.wu`, `fcvt.w.s`, `fcvt.wu.s` |
* comparison: `fmin.s`, `fmax.s`, `feq.s`, `flt.s`, `fle.s` |
* computational: `fadd.s`, `fsub.s`, `fmul.s` |
* sign-injection: `fsgnj.s`, `fsgnjn.s`, `fsgnjx.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` |
* computational: `fadd.s` `fsub.s` `fmul.s` |
* sign-injection: `fsgnj.s` `fsgnjn.s` `fsgnjx.s` |
* number classification: `fclass.s` |
|
* additional CSRs: `fcsr`, `frm`, `fflags` |
* additional CSRs: `fcsr` `frm` `fflags` |
|
[WARNING] |
Fused multiply-add instructions `f[n]m[add/sub].s` are not supported! |
609,12 → 610,12
[IMPORTANT] |
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 |
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: |
|
* CSR access: `csrrw`, `csrrs`, `csrrc`, `csrrwi`, `csrrsi`, `csrrci` |
* environment: `mret`, `wfi` |
* CSR access: `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` |
* environment: `mret` `wfi` |
|
[NOTE] |
If `rd=x0` for the `csrrw[i]` instructions there will be no actual read access to the according CSR. |
699,7 → 700,7
* `pmpaddr*` (0..63, depending on configuration): PMP address registers |
|
[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 |
`PMP_MIN_GRANULARITY` and `PMP_NUM_REGIONS` generics. `PMP_MIN_GRANULARITY` defines the minimal available |
823,12 → 824,13
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 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 |
while all remaining exceptions are ignored. If several _interrupts_ trigger at once, the one with highest priority |
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 _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 |
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 |
[IMPORTANT] |
837,24 → 839,24
|
.Interrupt Signal Requirements - Fast Interrupt Requests |
[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 |
the according `mip` CSR bit). |
|
.Instruction Atomicity |
[NOTE] |
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 |
a new interrupt handler can start. |
All instructions execute as atomic operations - interrupts can only trigger _between_ two instructions. |
So even if there is a permanent interrupt request, exactly one instruction from the interrupt program will be executed before |
another interrupt handler can start. This allows program progress even if there are permanent interrupt requests. |
|
|
:sectnums: |
==== Memory Access Exceptions** |
==== Memory Access Exceptions |
|
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 |
trigger a bus read-operation at all. Exceptions caused by a store address misalignment or a store physical |
memory protection fault do not trigger a bus write-operation at all. |
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/memory write-operation at all. |
|
|
:sectnums: |
882,7 → 884,7
|
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 |
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 |
`mepc` and `mtval` CSRs when a trap is triggered: |
|
935,7 → 937,7
[cols="<3,<7"] |
[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_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 |
1003,7 → 1005,7
|
[NOTE] |
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: |
===== Protocol |
1107,7 → 1109,7
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. |
|
**Rational** |
**Rationale** |
|
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 |
1114,7 → 1116,7
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 |
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 |
this example "uncritical registers". |
|
1122,7 → 1124,7
|
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 |
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 |
interrupt control) is done by the software (to be more specific, this is done by the `crt0.S` start-up code). |
|
1129,21 → 1131,19
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`) |
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 |
hardware reset setting it to low (globally disabling interrupts). |
because the global interrupt enabled flag in the status register (`mstatsus(mie)`) _do_ provide a dedicated |
hardware reset setting this bit to low (globally disabling interrupts). |
|
**Reset Configuration** |
|
Most CPU-internal register do feature 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 |
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 all uncritical registers, effectively generating a flip-flop without a |
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 |
be enabled via a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`): |
require a more deterministic reset state. For this case, a defined reset level (reset-to-low) of all CPU registers can |
be enabled ba enabling a constant in the main VHDL package file (`rtl/core/neorv32_package.vhd`): |
|
[source,vhdl] |
---- |
-- "critical" number of PMP regions -- |
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) |
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) |
---- |
/cpu_csr.adoc
473,13 → 473,13
_PMP_MIN_GRANULARITY_ top entity generics. _PMP_NUM_REGIONS_ defines the number of implemented |
protection regions and thus, the availability of the according `pmpcfg*` and `pmpaddr*` CSRs. |
|
[TIP] |
[NOTE] |
If trying to access an PMP-related CSR beyond _PMP_NUM_REGIONS_ **no illegal instruction |
exception** is triggered. The according CSRs are read-only (writes are ignored) and always return zero. |
|
[IMPORTANT] |
The RISC-V-compatible NEORV32 physical memory protection only implements the _NAPOT_ |
(naturally aligned power-of-two region) mode with a minimal region granularity of 8 bytes. |
The RISC-V-compatible NEORV32 physical memory protection only implements the **NAPOT** |
(naturally aligned power-of-two region) mode yet with a minimal region granularity of 8 bytes. |
|
|
:sectnums!: |
500,7 → 500,7
[options="header",grid="rows"] |
|======================= |
| Bit | RISC-V name | R/W | Function |
| 7 | _L_ | r/w | lock bit, can be set - but not be cleared again (only via CPU reset) |
| 7 | _L_ | r/w | lock bit, can only be cleared by CPU reset |
| 6:5 | - | r/- | reserved, read as zero |
| 4:3 | _A_ | r/w | mode configuration; only OFF (`00`) and NAPOT (`11`) are supported |
| 2 | _X_ | r/w | execute permission |
515,9 → 515,9
[cols="4,27,>7"] |
[frame="topbot",grid="none"] |
|====== |
| 0x3b0 - 0x3ef| **Physical memory protection configuration registers** | `pmpaddr0` - `pmpaddr63` |
| 0x3b0 - 0x3ef| **Physical memory protection address registers** | `pmpaddr0` - `pmpaddr63` |
3+| Reset value: _UNDEFINED_ |
3+| The `pmpaddr*` CSRs are compatible to the RISC-V specifications. They are used to configure the base |
3+| The `pmpaddr*` CSRs are compatible to the RISC-V specifications. They are used to configure the PMP region's base |
address and the region size. |
|====== |
|
611,7 → 611,7
| 0xb80 | **Machine cycle counter - high word** | `mcycleh` |
3+| Reset value: _UNDEFINED_ |
3+| The `mcycle[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit cycle |
counter. The `mcycle[h]` CSR can also be written when in machine mode and is copied to the `cycle[h]` CSR. |
counter. The `mcycle[h]` CSR can also be written when in machine mode and is mirrored to the `cycle[h]` CSR. |
|====== |
|
|
625,7 → 625,7
| 0xb82 | **Machine instructions-retired counter - high word** | `minstreth` |
3+| Reset value: _UNDEFINED_ |
3+| The `minstret[h]` CSR is compatible to the RISC-V specifications. It shows the lower/upper 32-bit of the 64-bit retired |
instructions counter. The `minstret[h]` CSR also be written when in machine mode and is copied to the `instret[h]` CSR. |
instructions counter. The `minstret[h]` CSR also be written when in machine mode and is mirrored to the `instret[h]` CSR. |
|====== |
|
|
/overview.adoc
21,9 → 21,7
|
[TIP] |
Check out the processor's **https://stnolting.github.io/neorv32/ug[online User Guide]** |
that provides hands-on tutorial to get you started. |
|
[TIP] |
that provides hands-on tutorials to get you started. |
The project's change log is available in https://github.com/stnolting/neorv32/blob/master/CHANGELOG.md[CHANGELOG.md] |
in the root directory of the NEORV32 repository. Please also check out the <<_legal>> section. |
|
36,11 → 34,8
. <<_software_framework>> |
. <<_on_chip_debugger_ocd>> |
|
[TIP] |
Links in this document are <<_overview,highlighted>>. |
|
|
|
<<< |
// #################################################################################################################### |
:sectnums: |
135,6 → 130,7
** optional general purpose IO and PWM and native NeoPixel (c) compatible smart LED interface |
** optional embedded memories / caches for data, instructions and bootloader |
** optional external memory interface (Wishbone / AXI4-Lite) and stream link interface (AXI4-Stream) for custom connectivity |
** optional execute in place (XIP) module |
** on-chip debugger compatible with OpenOCD and gdb |
* **Software framework** |
** GCC-based toolchain - prebuilt toolchains available; application compilation based on GNU makefiles |
248,6 → 244,7
├neorv32_uart.vhd - Universal async. receiver/transmitter |
├neorv32_wdt.vhd - Watchdog timer |
├neorv32_wishbone.vhd - External (Wishbone) bus interface |
├neorv32_xip.vhd - Execute in place module |
├neorv32_xirq.vhd - External interrupt controller |
│ |
├mem/neorv32_dmem.default.vhd - _Default_ data memory (architecture-only) |
276,10 → 273,9
[cols="<2,<8"] |
[grid="topbot"] |
|======================= |
| Hardware version: | `1.5.7.10` |
| Top entity: | `rtl/core/neorv32_cpu.vhd` |
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6` |
| Toolchain: | Quartus Prime 20.1.0 |
| Top entity: | `rtl/core/neorv32_cpu.vhd` |
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6` |
| Toolchain: | Quartus Prime 20.1.0 |
|======================= |
|
[cols="<5,>1,>1,>1,>1,>1"] |
310,10 → 306,9
[cols="<2,<8"] |
[grid="topbot"] |
|======================= |
| Hardware version: | `1.5.7.15` |
| Top entity: | `rtl/core/neorv32_top.vhd` |
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6` |
| Toolchain: | Quartus Prime 20.1.0 |
| Top entity: | `rtl/core/neorv32_top.vhd` |
| FPGA: | Intel Cyclone IV E `EP4CE22F17C6` |
| Toolchain: | Quartus Prime 20.1.0 |
|======================= |
|
.Hardware utilization by the processor modules (mandatory core modules in **bold**) |
323,7 → 318,7
| Module | Description | LEs | FFs | MEM bits | DSPs |
| Boot ROM | Bootloader ROM (4kB) | 2 | 1 | 32768 | 0 |
| **BUSKEEPER** | Processor-internal bus monitor | 9 | 6 | 0 | 0 |
| **BUSSWITCH** | Bus mux for CPU instr. and data interface | 63 | 8 | 0 | 0 |
| **BUSSWITCH** | Bus multiplexer for CPU instr. and data interface | 63 | 8 | 0 | 0 |
| CFS | Custom functions subsystemfootnote:[Resource utilization depends on actually implemented custom functionality.] | - | - | - | - |
| DMEM | Processor-internal data memory (8kB) | 19 | 2 | 65536 | 0 |
| DM | On-chip debugger - debug module | 493 | 240 | 0 | 0 |
344,6 → 339,7
| WISHBONE | External memory interface | 114 | 110 | 0 | 0 |
| XIRQ | External interrupt controller (32 channels) | 241 | 201 | 0 | 0 |
| GPTMR | General Purpose Timer | 153 | 107 | 0 | 0 |
| XIP | Execute in place module | 305 | 243 | 0 | 0 |
|======================= |
|
|
/soc.adoc
26,6 → 26,7
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>) |
* _optional_ external interrupt controller with up to 32 channels (<<_external_interrupt_controller_xirq,**XIRQ**>>) |
* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>) |
* _optional_ execute in place module (<<_execute_in_place_module_xip,**XIP**>>) |
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>) |
* bus keeper to monitor processor-internal bus transactions (<<_internal_bus_monitor_buskeeper,**BUSKEEPER**>>) |
* system configuration information memory to check HW configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>) |
39,12 → 40,21
The following table shows signals of the processor top entity (`rtl/core/neorv32_top.vhd`). |
The type of all signals is `std_ulogic` or `std_ulogic_vector`, respectively. |
|
[IMPORTAN] |
.Default Values of Ports |
[IMPORTANT] |
All _input signals_ provide default values in case they are not explicitly assigned during instantiation. |
For control signals the value `L` (weak pull-down) is used. For serial and parallel data signals |
the value `U` (unknown) is used. Pulled-down signals will not cause "accidental" system crashes |
since all control signals have defined level. |
|
.Configurable Amount of Channels |
[IMPORTANT] |
Some peripherals allow to configure the number of channels to-be-implemented by a generic (for example the number |
of PWM or SLINK channels). The according input/output signals have a fixed sized regardless of the actually configured |
amount of channels. If less than the maximum number of channels is configured, only the LSB-aligned channels are used: |
in case of an _input port_ the remaining bits/channels are left unconnected; in case of an _output port_ the remaining |
bits/channels are hardwired to zero. |
|
[cols="<3,^2,^2,<11"] |
[options="header",grid="rows"] |
|======================= |
73,6 → 83,11
4+^| **Advanced Memory Control Signals** |
| `fence_o` | 1 | out | indicates an executed _fence_ instruction |
| `fencei_o` | 1 | out | indicates an executed _fencei_ instruction |
4+^| **Execute In Place Interface (<<_execute_in_place_module_xip,**XIP**>>)** |
| `xip_csn_o` | 1 | out | chi select, low-active |
| `xip_clk_o` | 1 | out | serial clock |
| `xip_sdi_i` | 1 | in | serial data input |
| `xip_sdo_o` | 1 | out | serial data output |
4+^| **Stream Link Interface (<<_stream_link_interface_slink,SLINK>>)** |
| `slink_tx_dat_o` | 8x32 | out | TX link _n_ data |
| `slink_tx_val_o` | 8 | out | TX link _n_ data valid |
102,7 → 117,7
| `twi_sda_io` | 1 | inout | TWI serial data line |
| `twi_scl_io` | 1 | inout | TWI serial clock line |
4+^| **Pulse-Width Modulation Channels (<<_pulse_width_modulation_controller_pwm,PWM>>)** |
| `pwm_o` | 0..60 | out | pulse-width modulated channels |
| `pwm_o` | 60 | out | pulse-width modulated channels |
4+^| **Custom Functions Subsystem (<<_custom_functions_subsystem_cfs,CFS>>)** |
| `cfs_in_i` | 32 | in | custom CFS input signal conduit |
| `cfs_out_o` | 32 | out | custom CFS output signal conduit |
140,6 → 155,10
Privileged software can determine the actual CPU and processor configuration via the `misa` and the |
<<_system_configuration_information_memory_sysinfo, SYSINFO>> registers. |
|
[TIP] |
Run a quick simulation using the provided simulation/GHDL scripts (https://stnolting.github.io/neorv32/ug/#_hello_world) |
to verify the configuration of the processor generics is valid. |
|
[NOTE] |
If optional modules (like CPU extensions or peripheral devices) are *not enabled* the according circuitry |
**will not be synthesized at all**. Hence, the disabled modules do not increase area and power requirements |
425,7 → 444,7
|====== |
| **CPU_CNT_WIDTH** | _natural_ | 64 |
3+| This generic configures the total size of the CPU's `[m]cycle` and `[m]instret` CSRs (low word + high word). |
The maximum value is 64, the minimum value is 0. See section <<_machine_counters_and_timers>> for more information. |
The maximum value is 64, the minimum value is 0. See section <<_machine_counter_and_timer_csrs>> for more information. |
This generic is only relevant if the `Zicntr` ISa extension is enabled (<<_cpu_extension_riscv_zicntr>>). |
Note: configurations with <<_cpu_cnt_width>> less than 64 bits do not comply to the RISC-V specs. |
|====== |
586,7 → 605,7
|
|
:sectnums!: |
===== _ICACHE_NUM_BLOCK_ |
===== _ICACHE_NUM_BLOCKS_ |
|
[cols="4,4,2"] |
[frame="all",grid="none"] |
593,7 → 612,7
|====== |
| **ICACHE_NUM_BLOCKS** | _natural_ | 4 |
3+| Number of blocks (cache "pages" or "lines") in the instruction cache. Has to be a power of two. Has no |
effect when <<_icache_dmem_en>> is false. |
effect when <<_icache_en>> is false. |
|====== |
|
|
605,7 → 624,7
|====== |
| **ICACHE_BLOCK_SIZE** | _natural_ | 64 |
3+| Size in bytes of each block in the instruction cache. Has to be a power of two. Has no effect when |
<<_icache_dmem_en>> is _false_. |
<<_icache_en>> is _false_. |
|====== |
|
|
617,7 → 636,7
|====== |
| **ICACHE_ASSOCIATIVITY** | _natural_ | 1 |
3+| Associativity (= number of sets) of the instruction cache. Has to be a power of two. Allowed configurations: |
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when <<_icache_dmem_en>> is _false_. |
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when <<_icache_en>> is _false_. |
|====== |
|
|
1029,7 → 1048,19
|====== |
|
|
:sectnums!: |
===== _IO_XIP_EN_ |
|
[cols="4,4,2"] |
[frame="all",grid="none"] |
|====== |
| **IO_XIP_EN** | _boolean_ | false |
3+| Implement the execute in place module (XIP) when _true_. |
See section <<_execute_in_place_module_xip>> for more information. |
|====== |
|
|
|
<<< |
// #################################################################################################################### |
:sectnums: |
1167,7 → 1198,7
accessed from programs running in less-privileged user mode. For example, if the system relies on |
a periodic interrupt from the _MTIME_ timer unit, user-level programs could alter the _MTIME_ |
configuration corrupting this interrupt. This kind of security issues can be compensated using the |
PMP system (see <<_machine_physical_memory_protection>>). |
PMP system (see <<_machine_physical_memory_protection_csrs>>). |
|
|
:sectnums: |
1221,7 → 1252,7
[TIP] |
The following table shows the _default hardware-defined_ physical memory attributes of each main address space region. |
Additional user-defined attributes (for example certain read/write/execute rights for specific address space regions) can be |
provided using the RISC-V <<_machine_physical_memory_protection>>. |
provided using the RISC-V <<_machine_physical_memory_protection_csrs>>. |
|
[cols="^1,^2,^2,^3,^2"] |
[options="header",grid="rows"] |
1280,8 → 1311,12
|
* access to the processor-internal IMEM and processor-internal IMEM is implemented |
* access to the processor-internal DMEM and processor-internal DMEM is implemented |
* access to the bootloader ROM and beyond → addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface |
* access to the bootloader ROM and beyond -> addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface |
|
[NOTE] |
If the Execute In Place module (XIP) is implemented accesses map to this module are not forwarded to the |
external memory interface. See section <<_execute_in_place_module_xip>> for more information. |
|
If no (or not all) processor-internal memories are implemented, the according base addresses are mapped to external memories. |
For example, if the processor-internal IMEM is not implemented (<<_mem_int_imem_en>> = _false_), the processor will forward |
any access to the instruction address space (starting at `ispace_base_c`) via the external bus interface to the external |
1407,7 → 1442,7
has to be a power of two (minimum 4 bytes)! Address spaces must not overlap! |
|
[IMPORTANT] |
When accessing an IO device that hast not been implemented (via the according _IO_x_EN_ generic), a |
When accessing an IO device that hast not been implemented (via the according generic), a |
load/store access fault exception is triggered. |
|
[IMPORTANT] |
1416,6 → 1451,11
Processor-internal memories as well as modules connected to the external memory interface can still |
be written with a byte-wide granularity. |
|
[NOTE] |
Most of the IO devices do not have a hardware reset. Instead, the devices are reset via software by |
writing zero to the unit's control register. A general software-based reset of all devices is done by the |
application start-up code `crt0.S`. |
|
[TIP] |
You should use the provided core software library to interact with the peripheral devices. This |
prevents incompatibilities with future versions, since the hardware driver functions handle all the |
1424,11 → 1464,6
[TIP] |
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`. |
|
[TIP] |
Most of the IO devices do not have a hardware reset. Instead, the devices are reset via software by |
writing zero to the unit's control register. A general software-based reset of all devices is done by the |
application start-up code `crt0.S`. |
|
**Interrupts of Processor-Internal Modules** |
|
Most peripheral/IO devices provide some kind of interrupt (for example to signal available incoming data). These |
1460,12 → 1495,12
* `r/-` registers / bits are read-only; any write access to them has no effect |
* `-/w` these registers / bits are write-only; they auto-clear in the next cycle and are always read as zero |
|
[TIP] |
[NOTE] |
Bits / registers that are not listed in the register map tables are not (yet) implemented. These registers |
/ bits are always read as zero. A write access to them has no effect, but user programs should only |
write zero to them to keep compatible with future extension. |
|
[TIP] |
[NOTE] |
When writing to read-only registers, the access is nevertheless acknowledged, but no actual data is |
written. When reading data from a write-only register the result is undefined. |
|
1508,4 → 1543,6
|
include::soc_gptmr.adoc[] |
|
include::soc_xip.adoc[] |
|
include::soc_sysinfo.adoc[] |
/soc_buskeeper.adoc
6,7 → 6,7
[frame="topbot",grid="none"] |
|======================= |
| Hardware source file(s): | neorv32_buskeeper.vhd | |
| Software driver file(s): | none | explicitly used |
| Software driver file(s): | none | |
| Top entity port: | none | |
| Configuration generics: | none | |
| Package constants: | `max_proc_int_response_time_c` | Access time window (#cycles) |
32,24 → 32,42
In case of a bus access fault exception application software can evaluate the Bus Keeper's control register |
`NEORV32_BUSKEEPER.CTRL` to retrieve further details of the bus exception. The _BUSKEEPER_ERR_FLAG_ bit indicates |
that an actual bus access fault has occurred. The bit is sticky once set and is automatically cleared when reading or |
writing the `NEORV32_BUSKEEPER.CTRL` register. The _BUSKEEPER_ERR_TYPE_ indicated the tape of the bus fault: |
writing the `NEORV32_BUSKEEPER.CTRL` register. The _BUSKEEPER_ERR_TYPE_ bit defines the type of the bus fault: |
|
* _BUSKEEPER_ERR_TYPE_ = `0` - "Device Error": The bus access exception was cause by the memory-mapped device that |
* `0` - "Device Error": The bus access exception was cause by the memory-mapped device that |
has been accessed (the device asserted it's `err_o`). |
* _BUSKEEPER_ERR_TYPE_ = `1` - "Timeout Error": The bus access exception was caused by the Bus Keeper because the |
* `1` - "Timeout Error": The bus access exception was caused by the Bus Keeper because the |
accessed memory-mapped device did not respond within the access time window. Note that this error type can also be raised |
by the optional timeout feature of the <<_processor_external_memory_interface_wishbone_axi4_lite>>). |
|
[NOTE] |
Bus access fault exceptions are also raised if a physical memory protection rule is violated. In this case |
the _BUSKEEPER_ERR_FLAG_ bit remains zero. |
Bus access fault exceptions are also raised if a physical memory protection (PMP) rule is violated. In this case |
the _BUSKEEPER_ERR_FLAG_ bit remains zero (since the error signal is not triggered by the BUSKEEPER but by |
the CPU's PMP logic). |
|
|
**NULL Address Check** |
|
The bus keeper can ensure that no accesses are permitted to NULL addresses (`addr = 0x00000000`). These kind of |
access often occur when using uninitialized pointers. If the _BUSKEEPER_NULL_CHECK_EN_ bit is set, any access to |
address zero (instruction fetch, load data, store data) will raise an according bus exception. This flag |
automatically clears on a hardware reset. |
|
If a NULL address access has been detected the _BUSKEEPER_ERR_FLAG_ flag is set and the _BUSKEEPER_ERR_TYPE_ |
flag is cleared indicating a "Device Error". |
|
[NOTE] |
Address 0 is normally used by the IMEM and contains boot code instructions that are executed _once_ right after |
hardware reset. Hence, activating the bus keeper's NULL check in application code will not corrupt code execution |
at all. |
|
|
.BUSKEEPER register map (`struct NEORV32_BUSKEEPER`) |
[cols="<2,<2,<4,^1,<4"] |
[options="header",grid="all"] |
|======================= |
| Address | Name [C] | Bit(s), Name [C] | R/W | Function |
.2+<| `0xffffff7C` .2+<| `NEORV32_BUSKEEPER.CTRL` <|`0` _BUSKEEPER_ERR_TYPE_ ^| r/- <| Bus error type, valid if _BUSKEEPER_ERR_FLAG_ is set: `0`=device error, `1`=access timeout |
<|`31` _BUSKEEPER_ERR_FLAG_ ^| r/- <| Sticky error flag, clears after read or write access |
.3+<| `0xffffff7C` .3+<| `NEORV32_BUSKEEPER.CTRL` <|`0` _BUSKEEPER_ERR_TYPE_ ^| r/- | Bus error type, valid if _BUSKEEPER_ERR_FLAG_ |
<|`16` _BUSKEEPER_NULL_CHECK_EN_ ^| r/w <| Enable NULL address check when set |
<|`31` _BUSKEEPER_ERR_FLAG_ ^| r/- <| Sticky error flag, clears after read or write access |
|======================= |
/soc_dmem.adoc
14,6 → 14,11
| CPU interrupts: | none | |
|======================= |
|
Implementation of the processor-internal data memory is enabled via the processor's _MEM_INT_DMEM_EN_ |
generic. The size in bytes is defined via the _MEM_INT_DMEM_SIZE_ generic. If the DMEM is implemented, |
the memory is mapped into the data memory space and located right at the beginning of the data memory |
space (default `dspace_base_c` = 0x80000000). The DMEM is always implemented as true RAM. |
|
[NOTE] |
The actual DMEM is split into two design files: a plain entity definition (`neorv32_dmem.entity.vhd`) and the actual |
architecture definition (`mem/neorv32_dmem.default.vhd`). This **default architecture** provides a _generic_ and |
20,8 → 25,3
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture |
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping |
and/or timing. |
|
Implementation of the processor-internal data memory is enabled via the processor's _MEM_INT_DMEM_EN_ |
generic. The size in bytes is defined via the _MEM_INT_DMEM_SIZE_ generic. If the DMEM is implemented, |
the memory is mapped into the data memory space and located right at the beginning of the data memory |
space (default `dspace_base_c` = 0x80000000). The DMEM is always implemented as RAM. |
/soc_gpio.adoc
14,26 → 14,30
| CPU interrupts: | none | |
|======================= |
|
**Theory of Operation** |
|
The general purpose parallel IO port unit provides a simple 64-bit parallel input port and a 64-bit parallel |
output port. These ports can be used chip-externally (for example to drive status LEDs, connect buttons, etc.) |
or system-internally to provide control signals for other IP modules. The component is disabled for |
implementation when the _IO_GPIO_EN_ generic is set _false_. In this case GPIO output port is tied to all-zero. |
or chip-internally to provide control signals for other IP modules. The component is disabled for |
implementation when the _IO_GPIO_EN_ generic is set _false_. In this case the GPIO output port `gpio_o` is tied to all-zero. |
|
.Access atomicity |
.Access Atomicity |
[NOTE] |
The GPIO modules uses two memory-mapped registers (each 32-bit) each for accessing the input and |
output signals. Since the CPU can only process 32-bit "at once" updating the entire output cannot |
be performed within a single clock cycle. |
|
.INPUT is read-only |
[NOTE] |
Write accesses to the `NEORV32_GPIO.INPUT_LO` and `NEORV32_GPIO.INPUT_HI` registers will raise a store bus |
error exception. The BUSKEEPER will indicate a "DEVICE_ERR" in this case. |
|
|
.GPIO unit register map (`struct NEORV32_GPIO`) |
[cols="<2,<2,^1,^1,<6"] |
[options="header",grid="rows"] |
|======================= |
| Address | Name [C] | Bit(s) | R/W | Function |
| `0xffffffc0` | `NEORV32_GPIO.INPUT_LO` | 31:0 | r/- | parallel input port pins 31:0 (write accesses are ignored) |
| `0xffffffc4` | `NEORV32_GPIO.INPUT_HI` | 31:0 | r/- | parallel input port pins 63:32 (write accesses are ignored) |
| Address | Name [C] | Bit(s) | R/W | Function |
| `0xffffffc0` | `NEORV32_GPIO.INPUT_LO` | 31:0 | r/- | parallel input port pins 31:0 |
| `0xffffffc4` | `NEORV32_GPIO.INPUT_HI` | 31:0 | r/- | parallel input port pins 63:32 |
| `0xffffffc8` | `NEORV32_GPIO.OUTPUT_LO` | 31:0 | r/w | parallel output port pins 31:0 |
| `0xffffffcc` | `NEORV32_GPIO.OUTPUT_HI` | 31:0 | r/w | parallel output port pins 63:32 |
|======================= |
/soc_icache.adoc
15,21 → 15,10
| CPU interrupts: | none | |
|======================= |
|
[NOTE] |
The default `neorv32_icache.vhd` HDL source file provides a _generic_ memory design that infers embedded |
memory. You might need to replace/modify the source file in order to use platform-specific features |
(like advanced memory resources) or to improve technology mapping and/or timing. |
The processor features an optional cache for instructions to improve performance when using memories with high |
access latencies. The cache is directly connected to the CPU's instruction fetch interface and provides |
full-transparent buffering of instruction fetch accesses to the entire address space. |
|
The processor features an optional cache for instructions to compensate memories with high latency. The |
cache is directly connected to the CPU's instruction fetch interface and provides a full-transparent buffering |
of instruction fetch accesses to the entire 4GB address space. |
|
[IMPORTANT] |
The instruction cache is intended to accelerate instruction fetch via the external memory interface. |
Since all processor-internal memories provide an access latency of one cycle (by default), caching |
internal memories does not bring any performance gain. However, it _might_ reduce traffic on the |
processor-internal bus. |
|
The cache is implemented if the _ICACHE_EN_ generic is true. The size of the cache memory is defined via |
_ICACHE_BLOCK_SIZE_ (the size of a single cache block/page/line in bytes; has to be a power of two and >= |
4 bytes), _ICACHE_NUM_BLOCKS_ (the total amount of cache blocks; has to be a power of two and >= 1) and |
36,20 → 25,33
the actual cache associativity _ICACHE_ASSOCIATIVITY_ (number of sets; 1 = direct-mapped, 2 = 2-way set-associative, |
has to be a power of two and >= 1). |
|
If the cache associativity (_ICACHE_ASSOCIATIVITY_) is > 1 the LRU replacement policy (least recently |
If the cache associativity (_ICACHE_ASSOCIATIVITY_) is greater than 1 the LRU replacement policy (least recently |
used) is used. |
|
[TIP] |
Keep the features of the targeted FPGA's memory resources (block RAM) in mind when configuring |
.Cache Memory HDL |
[NOTE] |
The default `neorv32_icache.vhd` HDL source file provides a _generic_ memory design that infers embedded |
memory. You might need to replace/modify the source file in order to use platform-specific features |
(like advanced memory resources) or to improve technology mapping and/or timing. Also, keep the features |
of the targeted FPGA's memory resources (block RAM) in mind when configuring |
the cache size/layout to maximize and optimize resource utilization. |
|
.Caching Internal Memories |
[NOTE] |
The instruction cache is intended to accelerate instruction fetches from _processor-external_ memories. |
Since all processor-internal memories provide an access latency of one cycle (by default), caching |
internal memories does not bring a relevant performance gain. However, it will slightly reduce traffic on the |
processor-internal bus. |
|
.Manual Cache Clear/Reload |
[NOTE] |
By executing the `ifence.i` instruction (`Zifencei` CPU extension) the cache is cleared and a reload from |
main memory is forced. Among other things, this allows to implement self-modifying code. |
main memory is triggered. Among other things this allows to implement self-modifying code. |
|
**Bus Access Fault Handling** |
|
The cache always loads a complete cache block (_ICACHE_BLOCK_SIZE_ bytes) aligned to the size of a cache |
block if a miss is detected. If any of the accessed addresses within a single block do not successfully |
acknowledge (i.e. issuing an error signal or timing out) the whole cache block is invalidate and any access to |
an address within this cache block will also raise an instruction fetch bus error fault exception. |
The cache always loads a complete cache block (_ICACHE_BLOCK_SIZE_ bytes) aligned to it's size every time a |
cache miss is detected. If any of the accessed addresses within a single block do not successfully |
acknowledge the transfer (i.e. issuing an error signal or timing out) the whole cache block is invalidated and |
any access to an address within this cache block will raise an instruction fetch bus error exception. |
|
/soc_imem.adoc
15,25 → 15,25
| CPU interrupts: | none | |
|======================= |
|
[NOTE] |
The actual IMEM is split into two design files: a plain entity definition (`neorv32_imem.entity.vhd`) and the actual |
architecture definition (`mem/neorv32_imem.default.vhd`). This **default architecture** provides a _generic_ and |
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture |
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping |
and/or timing. |
|
Implementation of the processor-internal instruction memory is enabled via the processor's |
_MEM_INT_IMEM_EN_ generic. The size in bytes is defined via the _MEM_INT_IMEM_SIZE_ generic. If the |
IMEM is implemented, the memory is mapped into the instruction memory space and located right at the |
beginning of the instruction memory space (default `ispace_base_c` = 0x00000000). |
|
By default, the IMEM is implemented as RAM, so the content can be modified during run time. This is |
By default the IMEM is implemented as true RAM so the content can be modified during run time. This is |
required when using a bootloader that can update the content of the IMEM at any time. If you do not need |
the bootloader anymore - since your application development has completed and you want the program to |
permanently reside in the internal instruction memory - the IMEM is automatically implemented as _pre-intialized_ |
ROM when the processor-internal bootloader is disabled (_INT_BOOTLOADER_EN_ = _false_). |
|
When the IMEM is implemented as ROM, it will be initialized during synthesis with the actual application |
program image. The compiler toolchain will generate a VHDL initialization |
When the IMEM is implemented as ROM, it will be initialized during synthesis (actually, by the bitstream) |
with the actual application program image. The compiler toolchain will generate a VHDL initialization |
file `rtl/core/neorv32_application_image.vhd`, which is automatically inserted into the IMEM. If |
the IMEM is implemented as RAM (default), the memory will **not be initialized** at all. |
the IMEM is implemented as RAM (default), the memory will **not be initialized at all**. |
|
[NOTE] |
The actual IMEM is split into two design files: a plain entity definition (`neorv32_imem.entity.vhd`) and the actual |
architecture definition (`mem/neorv32_imem.default.vhd`). This **default architecture** provides a _generic_ and |
_platform independent_ memory design that (should) infers embedded memory block. You can replace/modify the architecture |
source file in order to use platform-specific features (like advanced memory resources) or to improve technology mapping |
and/or timing. |
/soc_mtime.adoc
14,22 → 14,23
| CPU interrupts: | `MTI` | machine timer interrupt (see <<_processor_interrupts>>) |
|======================= |
|
**Theory of Operation** |
The MTIME module implements the memory-mapped MTIME machine timer from the official RISC-V |
specifications. This module features a 64-bit system timer incrementing with the primary processor clock. |
Besides accessing the MTIME register via memory operation the current system time can also be obtained using |
the `time[h]` CSRs. Furthermore, the current system time is made available for processor-external |
usage via the top's `mtime_o` signal. |
|
The MTIME machine system timer implements the memory-mapped MTIME timer from the official RISC-V |
specifications. This unit features a 64-bit system timer incremented with the primary processor clock. |
The current system time can also be obtained using the `time[h]` CSRs and is made available for processor-external |
use via the top's `mtime_o` signal. |
The 64-bit system time can be accessed via the `TIME_LO` and `TIME_HI` memory-mapped registers (read/write) and also via |
the CPU's `time[h]` CSRs (read-only). A 64-bit time compare register - accessible via the memory-mapped `TIMECMP_LO` and `TIMECMP_HI` |
registers - is used to configure the CPU's MTI (machine timer interrupt). The interrupt is triggered |
whenever `TIME` (high & low part) is greater than or equal to `TIMECMP` (high & low part). |
The interrupt remain active (=pending) until `TIME` becomes less `TIMECMP` again (either by modifying `TIME` or `TIMECMP`). |
|
[NOTE] |
If the processor-internal **MTIME unit is NOT implemented**, the top's `mtime_i` input signal is used to update the `time[h]` CSRs |
and the `MTI` machine timer CPU interrupt (`MTI`) is directly connected to the top's `mtime_irq_i` input. |
If the processor-internal **MTIME module is NOT implemented**, the top's `mtime_i` input signal is used to update the `time[h]` CSRs |
and the `MTI` machine timer CPU interrupt (`MTI`) is directly connected to the top's `mtime_irq_i` input. The `mtime_o` signal |
is hardwired to zero in this case. |
|
The 64-bit system time can be accessed via the `TIME_LO` and `TIME_HI` memory-mapped registers (read/write) and also via |
the CPU's `time[h]` CSRs (read-only). A 64-bit time compare register - accessible via memory-mapped `TIMECMP_LO` and `TIMECMP_HI` |
registers - is used to configure an interrupt to the CPU. The interrupt is triggered |
whenever `TIME` (high & low part) >= `TIMECMP` (high & low part) and is directly forwarded to the CPU's `MTI` interrupt. |
The interrupt remain active (=pending) until `TIME` < `TIMECMP` (either by modifying `TIME` or `TIMECMP`). |
|
.MTIME register map (`struct NEORV32_MTIME`) |
[cols="<3,<3,^1,^1,<6"] |
/soc_pwm.adoc
8,7 → 8,7
| Hardware source file(s): | neorv32_pwm.vhd | |
| Software driver file(s): | neorv32_pwm.c | |
| | neorv32_pwm.h | |
| Top entity port: | `pwm_o` | up to 60 PWM output channels (1-bit per channel) |
| Top entity port: | `pwm_o` | up to 60 PWM output channels (60-bit, fixed) |
| Configuration generics: | _IO_PWM_NUM_CH_ | number of PWM channels to implement (0..60) |
| CPU interrupts: | none | |
|======================= |
17,6 → 17,10
bit resolution per channel. The actual number of implemented channels is defined by the _IO_PWM_NUM_CH_ generic. |
Setting this generic to zero will completely remove the PWM controller from the design. |
|
[NOTE] |
The `pwm_o` has a static size of 60-bit. Is less than 60 PWM channels are configured, only the LSB-aligned channels |
(bits) are used while the remaining bits are hardwired to zero. |
|
The PWM controller is based on an 8-bit base counter with a programmable threshold comparators for each channel |
that defines the actual duty cycle. The controller can be used to drive fancy RGB-LEDs with 24- |
bit true color, to dim LCD back-lights or even for "analog" control. An external integrator (RC low-pass filter) |
/soc_spi.adoc
104,7 → 104,13
|
Hence, the maximum SPI clock is f~main~ / 4. |
|
.High-Speed SPI mode |
[TIP] |
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (SPI_CTRL_PRSCx) is ignored |
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting |
the control register's _SPI_CTRL_HIGHSPEED_ bit. |
|
|
**SPI Interrupt** |
|
The SPI module provides a single interrupt to signal "transmission done" to the CPU. Whenever the SPI |
117,23 → 123,24
[options="header",grid="all"] |
|======================= |
| Address | Name [C] | Bit(s), Name [C] | R/W | Function |
.18+<| `0xffffffa8` .18+<| `NEORV32_SPI.CTRL` <|`0` _SPI_CTRL_CS0_ ^| r/w .8+<| Direct chip-select 0..7; setting `spi_csn_o(x)` low when set |
<|`1` _SPI_CTRL_CS1_ ^| r/w |
<|`2` _SPI_CTRL_CS2_ ^| r/w |
<|`3` _SPI_CTRL_CS3_ ^| r/w |
<|`4` _SPI_CTRL_CS4_ ^| r/w |
<|`5` _SPI_CTRL_CS5_ ^| r/w |
<|`6` _SPI_CTRL_CS6_ ^| r/w |
<|`7` _SPI_CTRL_CS7_ ^| r/w |
<|`8` _SPI_CTRL_EN_ ^| r/w <| SPI enable |
<|`9` _SPI_CTRL_CPHA_ ^| r/w <| clock phase (`0`=sample RX on rising edge & update TX on falling edge; `1`=sample RX on falling edge & update TX on rising edge) |
<|`10` _SPI_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select |
<|`11` _SPI_CTRL_PRSC1_ ^| r/w |
<|`12` _SPI_CTRL_PRSC2_ ^| r/w |
<|`13` _SPI_CTRL_SIZE0_ ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit) |
<|`14` _SPI_CTRL_SIZE1_ ^| r/w |
<|`15` _SPI_CTRL_CPOL_ ^| r/w <| clock polarity |
<|`16` .. `30` ^| r/- <| _reserved, read as zero |
<|`31` _SPI_CTRL_BUSY_ ^| r/- <| transmission in progress when set |
.19+<| `0xffffffa8` .19+<| `NEORV32_SPI.CTRL` <|`0` _SPI_CTRL_CS0_ ^| r/w .8+<| Direct chip-select 0..7; setting `spi_csn_o(x)` low when set |
<|`1` _SPI_CTRL_CS1_ ^| r/w |
<|`2` _SPI_CTRL_CS2_ ^| r/w |
<|`3` _SPI_CTRL_CS3_ ^| r/w |
<|`4` _SPI_CTRL_CS4_ ^| r/w |
<|`5` _SPI_CTRL_CS5_ ^| r/w |
<|`6` _SPI_CTRL_CS6_ ^| r/w |
<|`7` _SPI_CTRL_CS7_ ^| r/w |
<|`8` _SPI_CTRL_EN_ ^| r/w <| SPI enable |
<|`9` _SPI_CTRL_CPHA_ ^| r/w <| clock phase (`0`=sample RX on rising edge & update TX on falling edge; `1`=sample RX on falling edge & update TX on rising edge) |
<|`10` _SPI_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select |
<|`11` _SPI_CTRL_PRSC1_ ^| r/w |
<|`12` _SPI_CTRL_PRSC2_ ^| r/w |
<|`13` _SPI_CTRL_SIZE0_ ^| r/w .2+<| transfer size (`00`=8-bit, `01`=16-bit, `10`=24-bit, `11`=32-bit) |
<|`14` _SPI_CTRL_SIZE1_ ^| r/w |
<|`15` _SPI_CTRL_CPOL_ ^| r/w <| clock polarity |
<|`16` _SPI_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _SPI_CTRL_PRSC_) |
<|`17:30` ^| r/- <| _reserved, read as zero |
<|`31` _SPI_CTRL_BUSY_ ^| r/- <| transmission in progress when set |
| `0xffffffac` | `NEORV32_SPI.DATA` |`31:0` | r/w | receive/transmit data, LSB-aligned |
|======================= |
/soc_sysinfo.adoc
21,6 → 21,11
as the NEORV32 software runtime environment require information from this device (like memory layout |
and default clock speed) for correct operation. |
|
[NOTE] |
Any write access to the SYSINFO module will raise a store bus error exception. The <<_internal_bus_monitor_buskeeper>> |
will signal a "DEVICE ERROR" in this case. |
|
|
.SYSINFO register map (`struct NEORV32_SYSINFO`) |
[cols="<2,<4,<7"] |
[options="header",grid="all"] |
50,9 → 55,9
| `5` | _SYSINFO_CPU_ZFINX_ | `Zfinx` extension (`F` sub-/alternative-extension) available when set (via top's <<_cpu_extension_riscv_zfinx>> generic) |
| `6` | _SYSINFO_CPU_ZXSCNT_ | Custom extension - _Small_ CPU counters: `[m]cycle` & `[m]instret` CSRs have less than 64-bit when set (via top's <<_cpu_cnt_width>> generic) |
| `7` | _SYSINFO_CPU_ZXNOCNT_ | Custom extension - _NO_ CPU counters: `[m]cycle` & `[m]instret` CSRs are NOT available at all when set (via top's <<_cpu_cnt_width>> generic) |
| `8` | _SYSINFO_CPU_PMP_ | `PMP` (physical memory protection) extension available when set (via top's <<_>> generic) |
| `9` | _SYSINFO_CPU_HPM_ | `HPM` (hardware performance monitors) extension available when set (via top's <<_>> generic) |
| `10` | _SYSINFO_CPU_DEBUGMODE_ | RISC-V CPU `debug_mode` available when set (via top's <<_>> generic) |
| `8` | _SYSINFO_CPU_PMP_ | `PMP` (physical memory protection) extension available when set (via top's <<_pmp_num_regions>> generic) |
| `9` | _SYSINFO_CPU_HPM_ | `HPM` (hardware performance monitors) extension available when set (via top's <<_cpu_extension_riscv_zihpm>> generic) |
| `10` | _SYSINFO_CPU_DEBUGMODE_ | RISC-V CPU `debug_mode` available when set (via top's <<_on_chip_debugger_en>> generic) |
| `30 | _SYSINFO_CPU_FASTMUL_ | fast multiplication available when set (via top's <<_fast_mul_en>> generic) |
| `31` | _SYSINFO_CPU_FASTSHIFT_ | fast shifts available when set (via top's <<_fast_shift_en>> generic) |
|======================= |
79,7 → 84,7
| `18` | _SYSINFO_SOC_IO_UART0_ | set if the primary UART0 is implemented (via top's <<_io_uart0_en>> generic) |
| `19` | _SYSINFO_SOC_IO_SPI_ | set if the SPI is implemented (via top's <<_io_spi_en>> generic) |
| `20` | _SYSINFO_SOC_IO_TWI_ | set if the TWI is implemented (via top's <<_io_twi_en>> generic) |
| `21` | _SYSINFO_SOC_IO_PWM_ | set if the PWM is implemented (via top's <<_io_pwm_en>> generic) |
| `21` | _SYSINFO_SOC_IO_PWM_ | set if the PWM is implemented (via top's <<_io_pwm_num_ch>> generic) |
| `22` | _SYSINFO_SOC_IO_WDT_ | set if the WDT is implemented (via top's <<_io_wdt_en>> generic) |
| `23` | _SYSINFO_SOC_IO_CFS_ | set if the custom functions subsystem is implemented (via top's <<_io_cfs_en>> generic) |
| `24` | _SYSINFO_SOC_IO_TRNG_ | set if the TRNG is implemented (via top's _IO_TRNG_EN_ generic) |
86,6 → 91,9
| `25` | _SYSINFO_SOC_IO_SLINK_ | set if the SLINK is implemented (via top's <<_slink_num_tx>> and/or <<_slink_num_rx>> generics) |
| `26` | _SYSINFO_SOC_IO_UART1_ | set if the secondary UART1 is implemented (via top's <<_io_uart1_en>> generic) |
| `27` | _SYSINFO_SOC_IO_NEOLED_ | set if the NEOLED is implemented (via top's <<_io_neoled_en>> generic) |
| `28` | _SYSINFO_SOC_IO_XIRQ_ | set if the XIRQ is implemented (via top's <<_xirq_num_ch>> generic) |
| `29` | _SYSINFO_SOC_IO_GPTMR_ | set if the GPTMR is implemented (via top's <<_io_gptmr_en>> generic) |
| `30` | _SYSINFO_SOC_IO_XIP_ | set if the XIP module is implemented (via top's <<_io_xip_en>> generic) |
|======================= |
|
|
/soc_wishbone.adoc
42,6 → 42,10
. **and** it does not target the internal bootloader ROM or any of the IO devices - regardless if one or more of these components are |
actually implemented or not. |
|
[NOTE] |
If the Execute In Place module (XIP) is implemented accesses map to this module are not forwarded to the |
external memory interface. See section <<_execute_in_place_module_xip>> for more information. |
|
[TIP] |
See section <<_address_space>> for more information. |
|
/soc_xip.adoc
0,0 → 1,195
<<< |
:sectnums: |
==== Execute In Place Module (XIP) |
|
[cols="<3,<3,<4"] |
[frame="topbot",grid="none"] |
|======================= |
| Hardware source file(s): | neorv32_xip.vhd | |
| Software driver file(s): | neorv32_xip.c | |
| | neorv32_xip.h | |
| Top entity port: | `xip_csn_o` | 1-bit chip select, low-active |
| | `xip_clk_o` | 1-bit serial clock output |
| | `xip_sdi_i` | 1-bit serial data input |
| | `xip_sdo_o` | 1-bit serial data output |
| Configuration generics: | _IO_XIP_EN_ | implement XIP module when _true_ |
| CPU interrupts: | none | |
|======================= |
|
|
**Overview** |
|
The execute in place (XIP) module is probably one of the more complicated modules of the NEORV32. The module |
allows to execute code (and read constant data) directly from a SPI flash memory. Hence, it uses the standard |
serial peripheral interface (SPI) as transfer protocol under the hood. |
|
The XIP flash is not mapped to a specific region of the processor's address space. Instead, the XIP module |
provides a programmable mapping scheme to allow a flexible user-defined mapping of the flash to _any section_ |
of the address space. |
|
From the CPU side, the modules provides two different interfaces: one for transparently accessing the XIP flash and another |
one for accessing the module's control and status registers. The first interface provides a _transparent_ |
gateway to the SPI flash, so the CPU can directly fetch and execute instructions (and/or read constant _data_). |
Note that this interface is read-only. Any write access will raise a bus error exception. |
The second interface is mapped to the processor's IO space and allows data accesses to the XIP module's |
configuration registers. |
|
[TIP] |
An example program for the XIP module is available in `sw/example/demo_xip`. |
|
[WARNING] |
Debugging XIP code execution using the on-chip debugger is constrained. The debugger cannot insert breakpoints |
(`ebreak` instructions) into XIP code as the XIP access is read-only. |
|
[NOTE] |
Quad-SPI (QSPI) support, which is about 4x times faster, is planned for the future. 😉 |
|
|
**SPI Protocol** |
|
The XIP module accesses external flash using the standard SPI protocol. The module always sends data MSB-first and |
provides all of the standard four clock modes (0..3), which are configured via the _XIP_CTRL_CPOL_ (clock polarity) |
and _XIP_CTRL_CPHA_ (clock phase) control register bits, respectively. The clock speed of the interface (`xip_clk_o`) |
is defined by a three-bit clock pre-scaler configured using the _XIP_CTRL_PRSCx_ bits: |
|
.XIP prescaler configuration |
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"] |
[options="header",grid="rows"] |
|======================= |
| **`XIP_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111` |
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096 |
|======================= |
|
Based on the _XIP_CTRL_PRSCx_ configuration the actual XIP SPI clock frequency f~XIP~ is derived from the processor's |
main clock f~main~ and is determined by: |
|
_**f~XIP~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`) |
|
Hence, the maximum XIP clock speed is f~main~ / 4. |
|
.High-Speed SPI mode |
[TIP] |
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (_XIP_CTRL_PRSCx_) is ignored |
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting |
the control register's _XIP_CTRL_HIGHSPEED_ bit. |
|
The flash's "read command", which initiates a read access, is defined by the _XIP_CTRL_RD_CMD_ control register bits. |
For most SPI flash memories this is `0x03` for normal SPI mode. |
|
|
**Direct SPI Access** |
|
The XIP module allows to initiate _direct_ SPI transactions. This feature can be used to configure the attached SPI |
flash or to perform direct read and write accesses to the flash memory. Two data registers `NEORV32_XIP.DATA_LO` and |
`NEORV32_XIP.DATA_HI` are provided to send up to 64-bit of SPI data. The `NEORV32_XIP.DATA_HI` register is write-only, |
so a total of 32-bit receive data is provided. Note that the module handles the chip-select |
line (`xip_csn_o`) by itself so it is not possible to construct larger consecutive transfers. |
|
The actual data transmission size in bytes is defined by the control register's _XIP_CTRL_SPI_NBYTES_ bits. |
Any configuration from 1 byte to 8 bytes is valid. Other value will result in unpredictable behavior. |
|
Since data is always transferred MSB-first, the data in `DATA_HI:DATA_LO` also has to be MSB-aligned. Receive data is |
available in `DATA_LO` only - `DATA_HI` is write-only. Writing to `DATA_HI` triggers the actual SPI transmission. |
The _XIP_CTRL_PHY_BUSY_ control register flag indicates a transmission being in progress. |
|
The chip-select line of the XIP module (`xip_csn_o`) will only become asserted (enabled, pulled low) if the |
_XIP_CTRL_SPI_CSEN_ control register bit is set. If this bit is cleared, `xip_csn_o` is always disabled |
(pulled high). |
|
[NOTE] |
Direct SPI mode is only possible when the module is enabled (setting _XIP_CTRL_EN_) but **before** the actual |
XIP mode is enabled via _XIP_CTRL_XIP_EN_. |
|
[TIP] |
When the XIP mode is not enabled, the XIP module can also be used as additional general purpose SPI controller |
with a transfer size of up to 64 bits per transmission. |
|
|
**Address Mapping** |
|
The address mapping of the XIP flash is not fixed by design. It can be mapped to _any section_ within the processor's |
address space. A _section_ refers to one out of 16 naturally aligned 256MB wide memory segments. This segment |
is defined by the four most significant bits of the address (`31:28`) and the XIP's segment is programmed by the |
four _XIP_CTRL_XIP_PAGE_ bits in the unit's control register. All accesses within this page will be mapped to the XIP flash. |
|
[NOTE] |
Care must be taken when programming the page mapping to prevent access collisions with other modules (like internal memories |
or modules attached to the external memory interface). |
|
Example: to map the XIP flash to the address space starting at `0x20000000` write a "2" (`0b0010`) to the _XIP_CTRL_XIP_PAGE_ |
control register bits. Any access within `0x20000000 .. 0x2fffffff` will be forwarded to the XIP flash. |
Note that the SPI access address might wrap around. |
|
|
**Using the XIP Mode** |
|
The XIP module is globally enabled by setting the _XIP_CTRL_EN_ bit in the device's `CTRL` control register. |
Clearing this bit will reset the whole module and will also terminate any pending SPI transfer. |
|
Since there is a wide variety of SPI flash components with different sizes, the XIP module allows to specify |
the address width of the flash: the number of address bytes used for addressing flash memory content has to be |
configured using the control register's _XIP_CTRL_XIP_ABYTES_ bits. These two bits contain the number of SPI |
address bytes (**minus one**). For example for a SPI flash with 24-bit addresses these bits have to be set to |
`0b10`. |
|
The transparent XIP accesses are transformed into SPI transmissions with the following format (starting with the MSB): |
|
* 8-bit command: configured by the _XIP_CTRL_RD_CMD_ control register bits ("SPI read command") |
* 8 to 32 bits address: defined by the _XIP_CTRL_XIP_ABYTES_ control register bits ("number of address bytes") |
* 32-bit data: sending zeros and receiving the according flash word (32-bit) |
|
Hence, the maximum XIP transmission size is 72-bit, which has to be configured via the _XIP_CTRL_SPI_NBYTES_ |
control register bits. Note that the 72-bit transmission size is only available in XIP mode. The transmission |
size of the direct SPI accesses is limited to 64-bit. |
|
[NOTE] |
There is no _continuous read_ feature (i.e. a burst SPI transmission fetching several data words at once) implemented yet. |
|
[NOTE] |
When using four SPI flash address bytes, the most significant 4 bits of the address are always hardwired |
to zero allowing a maximum **accessible** flash size of 256MB. |
|
After the SPI properties (including the amount of address bytes **and** the total amount of SPI transfer bytes) |
and XIP address mapping are configured, the actual XIP mode can be enabled by setting |
the control register's _XIP_CTRL_XIP_EN_ bit. This will enable the "transparent SPI access port" of the module and thus, |
the _transparent_ conversion of access requests into proper SPI flash transmissions. Make sure _XIP_CTRL_SPI_CSEN_ |
is also set so the module can actually select/enable the attached SPI flash. |
No more direct SPI accesses via `DATA_HI:DATA_LO` are possible when the XIP mode is enabled. However, the |
XIP mode can be disabled at any time. |
|
[NOTE] |
If the XIP module is disabled (_XIP_CTRL_EN_ = `0`) any accesses to the programmed XIP memory segment are ignored |
by the module and might be forwarded to the processor's external memory interface (if implemented) or will cause a bus |
exception. If the XIP module is enabled (_XIP_CTRL_EN_ = `1`) but XIP mode is not enabled yet (_XIP_CTRL_XIP_EN_ = '0') |
any access to the programmed XIP memory segment will raise a bus exception. |
|
[TIP] |
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some |
of the SPI access latency. |
|
|
.XIP register map (`struct NEORV32_XIP`) |
[cols="<2,<2,<4,^1,<7"] |
[options="header",grid="all"] |
|======================= |
| Address | Name [C] | Bit(s), Name [C] | R/W | Function |
.16+<| `0xffffff40` .16+<| `NEORV32_XIP.CTRL` <|`0` _XIP_CTRL_EN_ ^| r/w <| XIP module enable |
<|`1` _XIP_CTRL_PRSC0_ ^| r/w .3+| 3-bit SPI clock prescaler select |
<|`2` _XIP_CTRL_PRSC1_ ^| r/w |
<|`3` _XIP_CTRL_PRSC2_ ^| r/w |
<|`4` _XIP_CTRL_CPOL_ ^| r/w <| SPI clock polarity |
<|`5` _XIP_CTRL_CPHA_ ^| r/w <| SPI clock phase |
<|`9:6` _XIP_CTRL_SPI_NBYTES_MSB_ : _XIP_CTRL_SPI_NBYTES_LSB_ ^| r/w <| Number of bytes in SPI transaction (1..9) |
<|`10` _XIP_CTRL_XIP_EN_ ^| r/w <| XIP mode enable |
<|`12:11` _XIP_CTRL_XIP_ABYTES_MSB_ : _XIP_CTRL_XIP_ABYTES_LSB_ ^| r/w <| Number of address bytes for XIP flash (minus 1) |
<|`20:13` _XIP_CTRL_RD_CMD_MSB_ : _XIP_CTRL_RD_CMD_LSB_ ^| r/w <| Flash read command |
<|`24:21` _XIP_CTRL_XIP_PAGE_MSB_ : _XIP_CTRL_XIP_PAGE_LSB_ ^| r/w <| XIP memory page |
<|`25` _XIP_CTRL_SPI_CSEN_ ^| r/w <| Allow SPI chip-select to be actually asserted when set |
<|`26` _XIP_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _XIP_CTRL_PRSC_) |
<|`29:27` ^| r/- <| _reserved_, read as zero |
<|`30` _XIP_CTRL_PHY_BUSY_ ^| r/- <| SPI PHY busy when set |
<|`31` _XIP_CTRL_XIP_BUSY_ ^| r/- <| XIP access in progress when set |
| `0xffffff44` | _reserved_ |`31:0` | r/- | _reserved_, read as zero |
| `0xffffff48` | `NEORV32_XIP.DATA_LO` |`31:0` | r/w | Direct SPI access - data register low |
| `0xffffff4C` | `NEORV32_XIP.DATA_HI` |`31:0` | -/w | Direct SPI access - data register high; write access triggers SPI transfer |
|======================= |
/soc_xirq.adoc
8,7 → 8,7
| Hardware source file(s): | neorv32_xirq.vhd | |
| Software driver file(s): | neorv32_xirq.c | |
| | neorv32_xirq.h | |
| Top entity port: | `xirq_i` | IRQ input (up to 32-bit) |
| Top entity port: | `xirq_i` | IRQ input (32-bit, fixed) |
| Configuration generics: | _XIRQ_NUM_CH_ | Number of IRQs to implement (0..32) |
| | _XIRQ_TRIGGER_TYPE_ | IRQ trigger type configuration |
| | _XIRQ_TRIGGER_POLARITY_ | IRQ trigger polarity configuration |
22,7 → 22,8
**Theory of Operation** |
|
The XIRQ provides up to 32 interrupt _channels_ (configured via the _XIRQ_NUM_CH_ generic). Each bit in the `xirq_i` |
input signal vector represents one interrupt channel. An interrupt channel is enabled by setting the according bit in the |
input signal vector represents one interrupt channel. If less than 32 channels are configure, only the LSB-aligned channels |
are used while the remaining bits are left unconnected. An interrupt channel is enabled by setting the according bit in the |
interrupt enable register `IER`. |
|
If the configured trigger (see below) of an enabled channel fires, the request is stored into an internal buffer. |
/software.adoc
79,6 → 79,7
| `neorv32_twi.c` | `neorv32_twi.h` | HW driver functions for the **TWI** |
| `neorv32_uart.c` | `neorv32_uart.h` | HW driver functions for the **UART0** and **UART1** |
| `neorv32_wdt.c` | `neorv32_wdt.h` | HW driver functions for the **WDT** |
| `neorv32_xip.c` | `neorv32_xip.h` | HW driver functions for the **XIP** |
| `neorv32_xirq.c` | `neorv32_xirq.h` | HW driver functions for the **XIRQ** |
|======================= |
|
201,7 → 202,6
| _MABI_ | The default 32-bit integer ABI. |
| _USER_FLAGS_ | Additional flags that will be forwarded to the compiler tools |
| _NEORV32_HOME_ | Relative or absolute path to the NEORV32 project home folder. Adapt this if the makefile/project is not in the project's `sw/example folder`. |
| _COM_PORT_ | Default serial port for executable upload to bootloader. |
|======================= |
|
:sectnums: |
384,7 → 384,7
`__neorv32_crt0_after_main` function is irrelevant as there is no further "software instance" executed afterwards that can check this. |
However, the on-chip debugger could still evaluate the return value of the after-main handler. |
|
A simple `printf` can be used to inform the user when the application main function return |
A simple `printf` can be used to inform the user when the application's main function returns |
(this example assumes that UART0 has been already properly configured in the actual application): |
|
.After-main handler - example |
448,6 → 448,12
* newline on `\r\n` (carriage return, newline) |
* no transfer protocol / control flow protocol - just the raw byte stuff |
|
[IMPORTANT] |
_Any_ terminal program that can connect to a serial port should work. However, make sure the program |
can transfer data in _raw_ byte mode without any protocol overhead around it. Some terminal programs struggle with |
transmitting files larger than 4kB (see https://github.com/stnolting/neorv32/pull/215). Try a different program |
if uploading a binary does not work (terminal stall). |
|
The bootloader uses the LSB of the top entity's `gpio_o` output port as high-active status LED (all other |
output pin are set to low level by the bootloader). After reset, this LED will start blinking at ~2Hz and the |
following intro screen should show up in your terminal: |