OpenCores
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:

powered by: WebSVN 2.1.0

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