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 68 to Rev 69
    Reverse comparison

Rev 68 → Rev 69

/cpu.adoc
252,36 → 252,29
This list shows the currently identified issues regarding full RISC-V-compatibility. More specific information
can be found in section <<_instruction_sets_and_extensions>>.
 
.Hardwired R/W CSRs
.Read-Only "Read-Write" CSRs
[IMPORTANT]
The `misa`, `mip` and `mtval` CSRs in the NEORV32 are _read-only_.
Any write access to it (in machine mode) to them are ignored and will _not_ cause any exceptions or side-effects.
Pending interrupt can only be cleared by acknowledging the interrupt-causing device. However, pending interrupts
can still be ignored by clearing the according `mie` register bits.
The `misa` and `mtval` CSRs in the NEORV32 are _read-only_.
Any machine-mode write access to them is ignored and will _not_ cause any exceptions or side-effects to maintain
RISC-V compatibility.
 
.Physical memory protection
.Physical Memory Protection
[IMPORTANT]
The physical memory protection (see section <<_machine_physical_memory_protection>>)
only supports the modes _OFF_ and _NAPOT_ yet and a minimal granularity of 8 bytes per region.
 
.Atomic memory operations
.Atomic Memory Operations
[IMPORTANT]
The `A` CPU extension only implements the `lr.w` and `sc.w` instructions yet.
However, these instructions are sufficient to emulate all further atomic memory operations.
 
.Bit-manipulation operations
.Bit-Manipulation ISA Extension
[IMPORTANT]
The NEORV32 `B` extension only implements the _basic bit-manipulation instructions_ (`Zbb`) subset
and the _address generation instructions_ (`Zba`) subset yet.
 
.Instruction Misalignment
[NOTE]
This is not a real RISC-V incompatibility, but something that might not be clear when studying the RISC-V privileged
architecture specifications: for 32-bit only instructions (no `C` extension) the misaligned instruction exception
is raised if bit 1 of the access address is set (i.e. not on 32-bit boundary). If the `C` extension is implemented
there will be no misaligned instruction exceptions _at all_.
In both cases bit 0 of the program counter and all related registers is hardwired to zero.
 
 
<<<
// ####################################################################################################################
:sectnums:
300,6 → 293,7
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
| `rstn_i` | 1 | in | global reset, low-active
| `sleep_o` | 1 | out | CPU is in sleep mode when set
| `debug_o` | 1 | out | CPU is in debug mode when set
4+^| **Instruction Bus Interface (<<_bus_interface>>)**
| `i_bus_addr_o` | 32 | out | destination address
| `i_bus_rdata_i` | 32 | in | read data
561,7 → 555,7
 
The most important points of the NEORV32-specific extensions are:
* The CPU provides 16 _fast interrupt_ interrupts (`FIRQ)`, which are controlled via custom bits in the `mie`
and `mip` CSR. This extension is mapped to _reserved_ CSR bits, that are available for custom use (according to the
and `mip` CSR. This extension is mapped to CSR bits, that are available for custom use (according to the
RISC-V specs). Also, custom trap codes for `mcause` are implemented.
* All undefined/unimplemented/malformed/illegal instructions do raise an illegal instruction exception (see <<_full_virtualization>>).
 
780,8 → 774,8
| Memory access | `I/E` | `lb` `lh` `lw` `lbu` `lhu` `sb` `sh` `sw` | 4 + ML
| Memory access | `C` | `c.lw` `c.sw` `c.lwsp` `c.swsp` | 4 + ML
| Memory access | `A` | `lr.w` `sc.w` | 4 + ML
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+31+3; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 5
| Division | `M` | `div` `divu` `rem` `remu` | 22+32+4
| Multiplication | `M` | `mul` `mulh` `mulhsu` `mulhu` | 2+32+2; FAST_MULfootnote:[DSP-based multiplication; enabled via `FAST_MUL_EN`.]: 4
| Division | `M` | `div` `divu` `rem` `remu` | 2+32+2
| CSR access | `Zicsr` | `csrrw` `csrrs` `csrrc` `csrrwi` `csrrsi` `csrrci` | 4
| System | `I/E`+`Zicsr` | `ecall` `ebreak` | 4
| System | `I/E` | `fence` | 3
836,11 → 830,17
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.
 
.Interrupt Signal Requirements
.Interrupt Signal Requirements - Standard RISC-V Interrupts
[IMPORTANT]
All interrupts request signals (including FIRQs) are **high-active**. A request has to stay at high-level (=asserted)
All standard RISC-V interrupts request signals are **high-active**. A request has to stay at high-level (=asserted)
until it is explicitly acknowledged by the CPU software (for example by writing to a specific memory-mapped register).
 
.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
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.
868,10 → 868,31
 
<<<
// ####################################################################################################################
:sectnums!:
===== NEORV32 Trap Listing
:sectnums:
==== NEORV32 Trap Listing
 
.NEORV32 trap listing
The following table shows all traps that are currently supported by the NEORV32 CPU. It also shows the prioritization
and the CSR side-effects. A more detailed description of the actual trap triggering events is provided in a further table.
 
[NOTE]
_Asynchronous exceptions_ (= interrupts) set the MSB of `mcause` while _synchronous exception_ (= "software exception")
clear the MSB.
 
**Table Annotations**
 
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
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:
 
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
* _B-ADR_- bad memory access address that cause the trap
* _PC_ - address of instruction that caused the trap
* _0_ - zero
* _Inst_ - the faulting instruction itself
 
.NEORV32 Trap Listing
[cols="3,6,5,14,11,4,4"]
[options="header",grid="rows"]
|=======================
881,7 → 902,7
| 3 | `0x00000002` | 0.2 | _TRAP_CODE_I_ILLEGAL_ | illegal instruction | _PC_ | _Inst_
| 4 | `0x0000000B` | 0.11 | _TRAP_CODE_MENV_CALL_ | environment call from M-mode (`ecall` in machine-mode) | _PC_ | _PC_
| 5 | `0x00000008` | 0.8 | _TRAP_CODE_UENV_CALL_ | environment call from U-mode (`ecall` in user-mode) | _PC_ | _PC_
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint (EBREAK) | _PC_ | _PC_
| 6 | `0x00000003` | 0.3 | _TRAP_CODE_BREAKPOINT_ | breakpoint (`ebreak`) | _PC_ | _PC_
| 7 | `0x00000006` | 0.6 | _TRAP_CODE_S_MISALIGNED_ | store address misaligned | _B-ADR_ | _B-ADR_
| 8 | `0x00000004` | 0.4 | _TRAP_CODE_L_MISALIGNED_ | load address misaligned | _B-ADR_ | _B-ADR_
| 9 | `0x00000007` | 0.7 | _TRAP_CODE_S_ACCESS_ | store access fault | _B-ADR_ | _B-ADR_
907,20 → 928,36
| 29 | `0x80000007` | 1.7 | _TRAP_CODE_MTI_ | machine timer interrupt | _I-PC_ | _0_
|=======================
 
**Notes**
 
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
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:
The following table provides a summarized description of the actual events for triggering a specific trap.
 
* _I-PC_ - address of interrupted instruction (instruction has not been execute/completed yet)
* _B-ADR_- bad memory access address that cause the trap
* _PC_ - address of instruction that caused the trap
* _0_ - zero
* _Inst_ - the faulting instruction itself
.NEORV32 Trap Description
[cols="<3,<7"]
[options="header",grid="rows"]
|=======================
| Trap ID | 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
| _TRAP_CODE_MENV_CALL_ | executing `ecall` instruction in machine-mode
| _TRAP_CODE_UENV_CALL_ | executing `ecall` instruction in user-mode
| _TRAP_CODE_BREAKPOINT_ | executing `ebreak` instruction (or triggered by on-chip debugger)
| _TRAP_CODE_S_MISALIGNED_ | storing data to an address that is not naturally aligned to the data size (byte, half, word) being stored
| _TRAP_CODE_L_MISALIGNED_ | loading data from an address that is not naturally aligned to the data size (byte, half, word) being loaded
| _TRAP_CODE_S_ACCESS_ | bus timeout or bus error during load data operation
| _TRAP_CODE_L_ACCESS_ | bus timeout or bus error during store data operation
| _TRAP_CODE_FIRQ_0_ ... _TRAP_CODE_FIRQ_15_| caused by interrupt-condition of processor-internal modules, see <<_neorv32_specific_fast_interrupt_requests>>
| _TRAP_CODE_MEI_ | user-defined processor-external source (via dedicated top-entity signal)
| _TRAP_CODE_MSI_ | user-defined processor-external source (via dedicated top-entity signal)
| _TRAP_CODE_MTI_ | processor-internal machine timer overflow OR user-defined processor-external source (via dedicated top-entity signal)
|=======================
 
.Instruction Address Misaligned Exception
[NOTE]
For 32-bit-only instructions (= no `C` extension) the misaligned instruction exception
is raised if bit 1 of the fetch address is set (i.e. not on a 32-bit boundary). If the `C` extension is implemented
there will never be a misaligned instruction exception _at all_.
In both cases bit 0 of the program counter (and all related registers) is hardwired to zero.
 
 
<<<
/cpu_csr.adoc
60,7 → 60,7
* `C`: _constrained_ - have a constrained compatibility, not all specified bits are implemented
 
.NEORV32 Control and Status Registers (CSRs)
[cols="<4,<7,<10,^3,<11,^3"]
[cols="<6,<11,<16,^3,<25,^3"]
[options="header"]
|=======================
| Address | Name [ASM] | Name [C] | R/W | Function | Note
82,8 → 82,8
| 0x340 | <<_mscratch>> | _CSR_MSCRATCH_ | r/w | Machine scratch register |
| 0x341 | <<_mepc>> | _CSR_MEPC_ | r/w | Machine exception program counter |
| 0x342 | <<_mcause>> | _CSR_MCAUSE_ | r/w | Machine trap cause | `X`
| 0x343 | <<_mtval>> | _CSR_MTVAL_ | r/- | Machine bad address or instruction | `XR`
| 0x344 | <<_mip>> | _CSR_MIP_ | r/- | Machine interrupt pending register | `XR`
| 0x343 | <<_mtval>> | _CSR_MTVAL_ | r/- | Machine bad address or instruction | `R`
| 0x344 | <<_mip>> | _CSR_MIP_ | r/w | Machine interrupt pending register | `X`
6+^| **<<_machine_physical_memory_protection_csrs>>**
| 0x3a0 .. 0x3af | <<_pmpcfg, `pmpcfg0`>> .. <<_pmpcfg, `pmpcfg15`>> | _CSR_PMPCFG0_ .. _CSR_PMPCFG15_ | r/w | Physical memory protection config. for region 0..63 | `C`
| 0x3b0 .. 0x3ef | <<_pmpaddr, `pmpaddr0`>> .. <<_pmpaddr, `pmpaddr63`>> | _CSR_PMPADDR0_ .. _CSR_PMPADDR63_ | r/w | Physical memory protection addr. register region 0..63 |
446,9 → 446,10
| 0x344 | **Machine interrupt Pending** | `mip`
3+| Reset value: _0x00000000_
3+| The `mip` CSR is compatible to the RISC-V specifications and also provides custom extensions. It shows currently _pending_ interrupts.
Since this register is read-only, pending interrupts of processor-internal modules can only be cleared by acknowledging the interrupt-causing
device. However, pending interrupts can be ignored by clearing the according <<_mie>> register bits.
The following CSR bits are implemented (all remaining bits are always zero and are read-only).
The bits for the standard RISC-V interrupts are read-only. Hence, these interrupts cannot be cleared using the `mip` register and must
be cleared/acknowledged within the according interrupt-generating device.
The upper 16 bits represent the status of the CPU's fast interrupt request lines (FIRQ). Once triggered, these _have to be cleared_ again by setting
the according `mip` bit in the interrupt handler routine to clear the current interrupt request.
|======
 
.Machine interrupt pending register
456,16 → 457,13
[options="header",grid="rows"]
|=======================
| Bit | Name [C] | R/W | Function
| 31:16 | _CSR_MIP_FIRQ15P_ : _CSR_MIP_FIRQ0P_ | r/- | fast interrupt channel 15..0 pending
| 11 | _CSR_MIP_MEIP_ | r/- | machine _external_ interrupt pending
| 7 | _CSR_MIP_MTIP_ | r/- | machine _timer_ interrupt pending
| 3 | _CSR_MIP_MSIP_ | r/- | machine _software_ interrupt pending
| 31:16 | _CSR_MIP_FIRQ15P_ : _CSR_MIP_FIRQ0P_ | r/w | fast interrupt channel 15..0 pending; cleared request by writing 1
| 11 | _CSR_MIP_MEIP_ | r/- | machine _external_ interrupt pending; _cleared by user-defined mechanism_
| 7 | _CSR_MIP_MTIP_ | r/- | machine _timer_ interrupt pending; cleared by incrementing MTIME's time compare register
| 3 | _CSR_MIP_MSIP_ | r/- | machine _software_ interrupt pending; _cleared by user-defined mechanism_
|=======================
 
[IMPORTAN]
The NEORV32 `mip` CSR is read-only. However, a write access will _NOT_ raise an illegal instruction exception.
 
 
<<<
// ####################################################################################################################
:sectnums:
/overview.adoc
181,15 → 181,16
├common - Linker script, crt0.S start-up code and central makefile
├example - Various example programs
│└...
├lib - Processor core library
│├include - Header files (*.h)
│└source - Source files (*.c)
├image_gen - Helper program to generate NEORV32 executables
├isa-test
│├riscv-arch-test - RISC-V spec. compatibility test framework (submodule)
│└port-neorv32 - Port files for the official RISC-V architecture tests
├ocd_firmware - Source code for on-chip debugger's "park loop"
├openocd - OpenOCD on-chip debugger configuration files
├image_gen - Helper program to generate NEORV32 executables
└lib - Processor core library
├include - Header files (*.h)
└source - Source files (*.c)
└svd - Processor system view description file (CMSIS-SVD)
...................................
 
 
277,6 → 278,8
|=======================
| 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
|=======================
 
[cols="<5,>1,>1,>1,>1,>1"]
294,9 → 297,6
| `rv32imacu_Zicsr_Zicntr_Zifencei_Zfinx_DebugMode` | 3974 | 1815 | 1024 | 7 | 116 MHz
|=======================
 
[NOTE]
No HPM counters and no PMP regions were implemented for generating these results.
 
[TIP]
The CPU provides further options to reduce the area footprint (for example by constraining the CPU-internal
counter sizes) or to increase performance (for example by using a barrel-shifter; at cost of extra hardware).
312,6 → 312,8
|=======================
| 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
|=======================
 
.Hardware utilization by the processor modules (mandatory core modules in **bold**)
/soc.adoc
1057,9 → 1057,8
 
.Trigger type
[IMPORTANT]
The fast interrupt request channel trigger on **high-level** and have to stay asserted until explicitly acknowledged
by the software (for example by writing to a specific memory-mapped register). Hence, pending interrupts remain pending
as long as the interrupt-causing device's state fulfills it's interrupt condition(s).
The fast interrupt request channels become pending after being triggering by **a rising edge**. A pending FIRQ has to
be explicitly cleared by setting the according `mip` CSR bit.
 
 
:sectnums:
1117,9 → 1116,8
 
.Trigger type
[IMPORTANT]
The fast interrupt request channel trigger on **high-level** and have to stay asserted until explicitly acknowledged
by the software (for example by writing to a specific memory-mapped register). Hence, pending interrupts remain pending
as long as the interrupt-causing device's state fulfills it's interrupt condition(s).
The fast interrupt request channels become pending after being triggering by **a rising edge**. A pending FIRQ has to
be explicitly cleared by setting the according `mip` CSR bit.
 
 
 
1424,6 → 1422,9
register and register bit accesses.
 
[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`.
/soc_cfs.adoc
55,9 → 55,9
 
**CFS Interrupt**
 
The CFS provides a single high-level-triggered interrupt request signal mapped to the CPU's fast interrupt channel 1.
Once set, the interrupt has to stay asserted until explicitly acknowledged by the software (for example by
writing to a specific CFS register). See section <<_processor_interrupts>> for more information.
The CFS provides a single rising-edge-triggered interrupt request signal mapped to the CPU's fast interrupt channel 1.
Once triggered, the interrupt becomes pending (if enabled in the `mis` CSR) and has to be explicitly cleared again by setting
the according `mip` CSR bit. See section <<_processor_interrupts>> for more information.
 
 
**CFS Configuration Generic**
/soc_gptmr.adoc
46,10 → 46,8
 
**Timer Interrupt**
 
The timer interrupt gets pending when the timer is enabled and `COUNT` matches `THRES`. The interrupt
request is indicated via the _GPTMR_CTRL_ALARM_ control register bit. This bit as well as the actual
interrupt keeps pending until the bit is explicitly cleared by application software or if the
timer is disabled.
The timer interrupt is triggered when the timer is enabled and `COUNT` matches `THRES`. The interrupt
remains pending until explicitly cleared by writing the according `mip` CSR bit.
 
 
.GPTMR register map (`struct NEORV32_GPTMR`)
57,12 → 55,11
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.6+<| `0xffffff60` .6+<| `NEORV32_GPTMR.CTRL` <|`0` _GPTMR_CTRL_EN_ ^| r/w <| Timer enable flag
.5+<| `0xffffff60` .5+<| `NEORV32_GPTMR.CTRL` <|`0` _GPTMR_CTRL_EN_ ^| r/w <| Timer enable flag
<|`1` _GPTMR_CTRL_PRSC0_ ^| r/w .3+| 3-bit clock prescaler select
<|`2` _GPTMR_CTRL_PRSC1_ ^| r/w
<|`3` _GPTMR_CTRL_PRSC2_ ^| r/w
<|`4` _GPTMR_CTRL_MODE_ ^| r/w <| Counter mode: `0`=single-shot, `1`=continuous
<|`5` _GPTMR_CTRL_ALARM_ ^| r/c <| Pending interrupt/alarm, cleared by setting bit to zero
| `0xffffff64` | `NEORV32_GPTMR.THRES` |`31:0` | r/w | Threshold value register
| `0xffffff68` | `NEORV32_GPTMR.COUNT` |`31:0` | r/w | Counter register
|=======================
/soc_neoled.adoc
173,14 → 173,11
In this case software can write up to _IO_NEOLED_TX_FIFO_/2 new data words to `DATA` without checking the FIFO
status flags. If _NEOLED_CTRL_IRQ_CONF_ is set, an interrupt is generated whenever the TX FIFO _becomes_ empty.
 
A pending interrupt request is cleared is cleared by any of the following operations:
* write access to `NEORV32_NEOLED.DATA` (for example to send more LED data)
* write access to `NEORV32_NEOLED.CTRL`
* disabling the NEOLED module
One the NEOLED interrupt has been triggered and became pending, it has to explicitly cleared again by setting the
according `mip` CSR bit.
 
[NOTE]
The _NEOLED_CTRL_IRQ_CONF_ is hardwired to one if _IO_NEOLED_TX_FIFO_ = 1 (-> IRQ if FIFO is empty).
 
If the FIFO is configured to contain only a single entry (_IO_NEOLED_TX_FIFO_ = 1) the interrupt
will become pending if the FIFO (which is just a single register providing simple _double-buffering_) is empty.
 
/soc_slink.adoc
137,13 → 137,16
request if it's interrupt enable flag _SLINK_IRQ_TX_EN_ is set.
 
The **RX link's** _SLINK_IRQ_RX_MODE_ flags define the FIFO fill-level condition for raising an RX interrupt request:
* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO _becomes_ not empty ("RX data available").
* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO _becomes_ at least half-full ("time to get data from RX FIFO to prevent overflow").
* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO _becomes_ not empty ("RX data available").
* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO _becomes_ at least half-full ("time to get data from RX FIFO to prevent overflow").
 
The **TX link's** _SLINK_IRQ_TX_MODE_ flags define the FIFO fill-level condition for raising an TX interrupt request:
* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO _becomes_ not full ("space left in FIFO for new TX data").
* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO _becomes_ less than half-full ("SW can send _SLINK_TX_FIFO_/2 data words without checking any flags").
* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO _becomes_ not full ("space left in FIFO for new TX data").
* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO _becomes_ less than half-full ("SW can send _SLINK_TX_FIFO_/2 data words without checking any flags").
 
Once the SLINK's RX or TX interrupt has become pending, it has to be explicitly cleared again by setting the according
`mip` CSR bit.
 
[IMPORTANT]
The interrupt configuration register `NEORV32_SLINK.IRQ` should we written _before_ the SLINK
module is actually enabled.
152,21 → 155,7
If _SLINK_RX_FIFO_ is 1 all _SLINK_IRQ_RX_MODE_ bits are hardwired to one.
If _SLINK_TX_FIFO_ is 1 all _SLINK_IRQ_TX_MODE_ bits are hardwired to one.
 
A **pending RX interrupt** request is cleared by any of the following operations:
* read access to any `NEORV32_SLINK.DATA` (for example to read incoming data)
* write access to `NEORV32_SLINK.CTRL`
* disabling the SLINK module
 
A **pending TX interrupt** request is cleared by any of the following operations:
* write access any `NEORV32_SLINK.DATA` (for example to send more data)
* write access to `NEORV32_SLINK.CTRL`
* disabling the SLINK module
 
[TIP]
A dummy write to to the control register (i.e. `NEORV32_SLINK.DATA = NEORV32_SLINK.DATA`)
can be executed to acknowledge any interrupt.
 
 
.SLINK register map (`struct NEORV32_SLINK`)
[cols="^4,<5,^2,^2,<14"]
[options="header",grid="all"]
/soc_spi.adoc
108,17 → 108,10
**SPI Interrupt**
 
The SPI module provides a single interrupt to signal "transmission done" to the CPU. Whenever the SPI
module completes the current transfer operation, the interrupt request is set. A pending interrupt request
is cleared by any of the following operations:
* read or write access to `NEORV32_SPI.DATA` (for example to trigger a new transmission)
* write access to `NEORV32_SPI.CTRL`
* disabling the SPI module
module completes the current transfer operation, the interrupt is triggered and has to be explicitly cleared again
by setting the according `mip` CSR bit.
 
[TIP]
A dummy read from `NEORV32_SPI.DATA` can be executed to acknowledge the interrupt without affecting data
or the state of the SPI module.
 
 
.SPI register map (`struct NEORV32_SPI`)
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
/soc_sysinfo.adoc
71,6 → 71,7
| `3` | _SYSINFO_SOC_MEM_INT_DMEM_ | set if the processor-internal IMEM is implemented (via top's <<_mem_int_imem_en>> generic)
| `4` | _SYSINFO_SOC_MEM_EXT_ENDIAN_ | set if external bus interface uses BIG-endian byte-order (via top's <<_mem_ext_big_endian>> generic)
| `5` | _SYSINFO_SOC_ICACHE_ | set if processor-internal instruction cache is implemented (via top's <<_icache_en>> generic)
| `13` | _SYSINFO_SOC_IS_SIM_ | set if processor is being **simulated** (⚠️ not guaranteed)
| `14` | _SYSINFO_SOC_OCD_ | set if on-chip debugger implemented (via top's <<_on_chip_debugger_en>> generic)
| `15` | _SYSINFO_SOC_HW_RESET_ | set if a dedicated hardware reset of all core registers is implemented (via package's `dedicated_reset_c` constant)
| `16` | _SYSINFO_SOC_IO_GPIO_ | set if the GPIO is implemented (via top's <<_io_gpio_en>> generic)
/soc_twi.adoc
74,17 → 74,10
 
The SPI module provides a single interrupt to signal "operation done" to the CPU. Whenever the TWI
module completes the current operation (generate stop condition, generate start conditions or transfer byte),
the interrupt request is set. A pending interrupt request is cleared is cleared by any of
the following operations:
* read or write access to `NEORV32_TWI.DATA` (for example to trigger a new transmission)
* write access to `NEORV32_TWI.CTRL`
* disabling the TWI module
the interrupt is triggered. Once triggered, the interrupt has to be explicitly cleared again by setting the according
`mip` CSR bit.
 
[TIP]
A dummy read from `NEORV32_TWI.DATA` can be executed to acknowledge the interrupt without affecting data
or the state of the TWI module.
 
 
.TWI register map (`struct NEORV32_TWI`)
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
/soc_uart.adoc
127,21 → 127,10
in the TX FIFO _becomes_ free (-> _UART_CTRL_TX_FULL_ clears). If _UART_CTRL_TX_IRQ_ is `1` the TX interrupt goes pending
when the RX FIFO _becomes_ less than half-full (-> _UART_CTRL_TX_HALF_ clears).
 
A **pending RX interrupt** request is cleared by any of the following operations:
* read access to `NEORV32_UART0.DATA` (for example to read incoming data)
* write access to `NEORV32_UART0.CTRL`
* disabling the UART module
Once the RX or TX interrupt has become pending, it has to be explicitly cleared again by setting the
according `mip` CSR bit.
 
A **pending TX interrupt** request is cleared by any of the following operations:
* write access to `NEORV32_UART0.DATA` (for example to send more data)
* write access to `NEORV32_UART0.CTRL`
* disabling the UART module
 
[TIP]
A dummy write to to the control register (i.e. `NEORV32_UART0.DATA = NEORV32_UART0.DATA`)
can be executed to acknowledge any interrupt.
 
 
**Simulation Mode**
 
The default UART0 operation will transmit any data written to the `DATA` register via the serial TX line at
/soc_wdt.adoc
13,15 → 13,17
| CPU interrupts: | fast IRQ channel 0 | watchdog timer overflow (see <<_processor_interrupts>>)
|=======================
 
 
**Theory of Operation**
 
The watchdog (WDT) provides a last resort for safety-critical applications. The WDT has an internal 20-bit
wide counter that needs to be reset every now and then by the user program. If the counter overflows, either
a system reset or an interrupt is generated (depending on the configured operation mode).
The _WDT_CTRL_HALF_ flag of the control register `CTRL` indicates that at least half of the maximum timeout
value has been reached.
 
Configuration of the watchdog is done by a single control register `CTRL`. The watchdog is enabled by
setting the _WDT_CTRL_EN_ bit. The clock used to increment the internal counter is selected via the 3-bit
_WDT_CTRL_CLK_SELx_ prescaler:
The watchdog is enabled by setting the _WDT_CTRL_EN_ bit. The clock used to increment the internal counter
is selected via the 3-bit _WDT_CTRL_CLK_SELx_ prescaler:
 
[cols="^3,^3,>4"]
[options="header",grid="rows"]
44,7 → 46,7
any time by setting the _WDT_CTRL_FORCE_ bit. The watchdog is reset by setting the _WDT_CTRL_RESET_ bit.
 
A watchdog interrupt can only occur if the watchdog is enabled and interrupt mode is enabled.
A pending interrupt is cleared by either disabling the watchdog or by resetting the watchdog.
A triggered interrupt has to be cleared again by setting the according `mip` CSR bit.
 
The cause of the last action of the watchdog can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
zero, the processor has been reset via the external reset signal. If this flag is set the last system reset was
52,21 → 54,32
 
The Watchdog control register can be locked in order to protect the current configuration. The lock is
activated by setting bit _WDT_CTRL_LOCK_. In the locked state any write access to the configuration flags is
ignored (see table below, "accessible if locked"). Read accesses to the control register are not effected. The
ignored (see table below, "writable if locked"). Read accesses to the control register are not effected. The
lock can only be removed by a system reset (via external reset signal or via a watchdog reset action).
 
.Watchdog Operation during Debugging
[IMPORTANT]
By default the watchdog pauses operation when the CPU enters debug mode and will resume normal operation after
the CPU has left debug mode. This will prevent an unintended watchdog timeout (and a hardware reset if configured)
during a debug session. However, the watchdog can be configured to keep operating even when the CPU is in debug
mode by setting the control register's _WDT_CTRL_DBEN_ bit. If the CPU's debug mode is not implemented this flag
is hardwired to zero.
 
 
.WDT register map (`struct NEORV32_WDT`)
[cols="<2,<2,<4,^1,^2,<4"]
[cols="<2,<2,<4,^1,^1,^2,<4"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Writable if locked | Function
.9+<| `0xffffffbc` .9+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| no <| watchdog enable
<|`1` _WDT_CTRL_CLK_SEL0_ ^| r/w ^| no .3+<| 3-bit clock prescaler select
<|`2` _WDT_CTRL_CLK_SEL1_ ^| r/w ^| no
<|`3` _WDT_CTRL_CLK_SEL2_ ^| r/w ^| no
<|`4` _WDT_CTRL_MODE_ ^| r/w ^| no <| overflow action: `1`=reset, `0`=IRQ
<|`5` _WDT_CTRL_RCAUSE_ ^| r/- ^| - <| cause of last system reset: `0`=caused by external reset signal, `1`=caused by watchdog
<|`6` _WDT_CTRL_RESET_ ^| -/w ^| yes <| watchdog reset when set, auto-clears
<|`7` _WDT_CTRL_FORCE_ ^| -/w ^| yes <| force configured watchdog action when set, auto-clears
<|`8` _WDT_CTRL_LOCK_ ^| r/w ^| no <| lock access to configuration when set, clears only on system reset (via external reset signal OR watchdog reset action = reset)
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
.11+<| `0xffffffbc` .11+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| `0` ^| no <| watchdog enable
<|`1` _WDT_CTRL_CLK_SEL0_ ^| r/w ^| `0` ^| no .3+<| 3-bit clock prescaler select
<|`2` _WDT_CTRL_CLK_SEL1_ ^| r/w ^| `0` ^| no
<|`3` _WDT_CTRL_CLK_SEL2_ ^| r/w ^| `0` ^| no
<|`4` _WDT_CTRL_MODE_ ^| r/w ^| `0` ^| no <| overflow action: `1`=reset, `0`=IRQ
<|`5` _WDT_CTRL_RCAUSE_ ^| r/- ^| `0` ^| - <| cause of last system reset: `0`=caused by external reset signal, `1`=caused by watchdog
<|`6` _WDT_CTRL_RESET_ ^| -/w ^| - ^| yes <| watchdog reset when set, auto-clears
<|`7` _WDT_CTRL_FORCE_ ^| -/w ^| - ^| yes <| force configured watchdog action when set, auto-clears
<|`8` _WDT_CTRL_LOCK_ ^| r/w ^| `0` ^| no <| lock access to configuration when set, clears only on system reset (via external reset signal OR watchdog reset action = reset)
<|`9` _WDT_CTRL_DBEN_ ^| r/w ^| `0` ^| no <| allow WDT to continue operation even when in debug mode
<|`10` _WDT_CTRL_HALF_ ^| r/- ^| `0` ^| - <| set if at least half of the max. timeout counter value has been reached
|=======================
/soc_wishbone.adoc
28,28 → 28,32
| CPU interrupts: | none |
|=======================
 
The external memory interface uses the Wishbone interface protocol. The external interface port is available
when the _MEM_EXT_EN_ generic is _true_. This interface can be used to attach external memories, custom
hardware accelerators additional IO devices or all other kinds of IP blocks. All memory accesses from the
CPU, that do not target the internal bootloader ROM, the internal IO region or the internal data/instruction
memories (if implemented at all) are forwarded to the Wishbone gateway and thus to the external memory
interface.
 
The external memory interface provides a Wishbone b4-compatible on-chip bus interface. The bus interface is
implemented when the _MEM_EXT_EN_ generic is _true_. This interface can be used to attach external memories,
custom hardware accelerators, additional IO devices or all other kinds of IP blocks.
 
The external interface is _not_ mapped to a _specific_ address space region. Instead, all CPU memory accesses that
do not target a processor-internal module are delegated to the external memory interface. In summary, a CPU load/store
access is delegated to the external bus interface if...
 
. it does not target the internal instruction memory IMEM (if implemented at all)
. **and** it does not target the internal data memory DMEM (if implemented at all)
. **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.
 
[TIP]
When using the default processor setup, all access addresses between 0x00000000 and
0xffff0000 (= beginning of processor-internal BOOT ROM) are delegated to the external memory
/ bus interface if they are not targeting the (actually enabled/implemented) processor-internal
instruction memory (IMEM) or the (actually enabled/implemented) processor-internal data memory
(DMEM). See section <<_address_space>> for more information.
See section <<_address_space>> for more information.
 
 
**Wishbone Bus Protocol**
 
The external memory interface either uses **standard** ("classic") Wishbone transactions (default) or
**pipelined** Wishbone transactions. The transaction protocol is configured via the _MEM_EXT_PIPE_MODE_ generic:
The external memory interface either uses the **standard** ("classic") Wishbone transaction protocol (default) or
**pipelined** Wishbone transaction protocol. The transaction protocol is configured via the _MEM_EXT_PIPE_MODE_ generic:
 
When _MEM_EXT_PIPE_MODE_ is _false_, all bus control signals including _STB_ are active (and stable) until the
When _MEM_EXT_PIPE_MODE_ is _false_, all bus control signals including _STB_ are active and remain stable until the
transfer is acknowledged/terminated. If _MEM_EXT_PIPE_MODE_ is _true_, all bus control except _STB_ are active
(and stable) until the transfer is acknowledged/terminated. In this case, _STB_ is active only during the very
and remain until the transfer is acknowledged/terminated. In this case, _STB_ is asserted only during the very
first bus clock cycle.
 
.Exemplary Wishbone bus accesses using "classic" and "pipelined" protocol
62,39 → 66,37
|=======================
 
 
[TOP]
[TIP]
A detailed description of the implemented Wishbone bus protocol and the according interface signals
can be found in the data sheet "Wishbone B4 - WISHBONE System-on-Chip (SoC) Interconnection
Architecture for Portable IP Cores". A copy of this document can be found in the docs folder of this
project.
 
**Interface Latency**
 
By default, the Wishbone gateway introduces two additional latency cycles: processor-outgoing ("TX") and
processor-incoming ("RX") signals are fully registered. Thus, any access from the CPU to a processor-external devices
via Wishbone requires 2 additional clock cycles (at least; depending on device's latency).
**Bus Access**
 
If the attached Wishbone network / peripheral already provides output registers or if the Wishbone network is not relevant
for timing closure, the default buffering of incoming ("RX") data within the gateway can be disabled by implementing an
"asynchronous" RX path. The configuration is done via the _MEM_EXT_ASYNC_RX_ generic.
The NEORV32 Wishbone gateway does not support burst transfer yet, so there is always just one transfer in progress.
Hence, the Wishbone `STALL` signal is not implemented. An accessed Wishbone device does not have to respond immediately to a bus
request by sending an ACK. instead, there is a _time window_ where the device has to acknowledge the transfer. This time window
id configured by the _MEM_EXT_TIMEOUT_ top generic that defines the maximum time (in clock cycles) a bus access can be pending
before it is automatically terminated. If _MEM_EXT_TIMEOUT_ is set to zero, the timeout disabled an a bus access can take an
arbitrary number of cycles to complete.
 
**Bus Access Timeout**
 
The Wishbone bus interface provides an option to configure a bus access timeout counter. The _MEM_EXT_TIMEOUT_
top generic is used to specify the _maximum_ time (in clock cycles) a bus access can be pending before it is automatically
terminated. If _MEM_EXT_TIMEOUT_ is set to zero, the timeout disabled an a bus access can take an arbitrary number of cycles to complete.
 
When _MEM_EXT_TIMEOUT_ is greater than zero, the WIshbone adapter starts an internal countdown whenever the CPU
When _MEM_EXT_TIMEOUT_ is greater than zero, the Wishbone gateway starts an internal countdown whenever the CPU
accesses a memory address via the external memory interface. If the accessed memory / device does not acknowledge (via `wb_ack_i`)
or terminate (via `wb_err_i`) the transfer within _MEM_EXT_TIMEOUT_ clock cycles, the bus access is automatically canceled
(setting `wb_cyc_o` low again) and a load/store/instruction fetch bus access fault exception is raised.
setting `wb_cyc_o` low again and a CPU load/store/instruction fetch bus access fault exception is raised.
 
[TIP]
This feature can be used as **safety guard** if the external memory system does not check for "address space holes". That means that addresses, which
do not belong to a certain memory or device, do not permanently stall the processor due to an unacknowledged/unterminated bus access. If the external
memory system can guarantee to access **any** bus access (even it targets an unimplemented address) the timeout feature should be disabled
(_MEM_EXT_TIMEOUT_ = 0).
[IMPORTANT]
Setting _MEM_EXT_TIMEOUT_ to zero will permanently stall the CPU if the targeted Wishbone device never responds. Hence,
_MEM_EXT_TIMEOUT_ should be always set to a value greater than zero. +
+
This feature can be used as **safety guard** if the external memory system does not check for "address space holes". That means
that accessing addresses, which do not belong to a certain memory or device, do not permanently stall the processor due to an
unacknowledged/unterminated bus access. If the external memory system can guarantee to access **any** bus access
(even it targets an unimplemented address) the timeout feature should be disabled (_MEM_EXT_TIMEOUT_ = 0).
 
 
**Wishbone Tag**
 
The 3-bit wishbone `wb_tag_o` signal provides additional information regarding the access type. This signal
104,6 → 106,7
* `wb_tag_o(1)` always zero (indicating "secure access")
* `wb_tag_o(2)` 1: instruction fetch access, 0: data access
 
 
**Exclusive / Atomic Bus Access**
 
If the atomic memory access CPU extension (via _CPU_EXTENSION_RISCV_A_) is enabled, the CPU can
120,6 → 123,7
[TIP]
See section <<_bus_interface>> for the CPU bus interface protocol.
 
 
**Endianness**
 
The NEORV32 CPU and the Processor setup are *little-endian* architectures. To allow direct connection
130,6 → 134,18
Application software can check the Endianness configuration of the external bus interface via the
SYSINFO module (see section <<_system_configuration_information_memory_sysinfo>> for more information).
 
 
**Gateway Latency**
 
By default, the Wishbone gateway introduces two additional latency cycles: processor-outgoing ("TX") and
processor-incoming ("RX") signals are fully registered. Thus, any access from the CPU to a processor-external devices
via Wishbone requires 2 additional clock cycles (at least; depending on device's latency).
 
If the attached Wishbone network / peripheral already provides output registers or if the Wishbone network is not relevant
for timing closure, the default buffering of incoming ("RX") data within the gateway can be disabled by implementing an
"asynchronous" RX path. The configuration is done via the _MEM_EXT_ASYNC_RX_ generic.
 
 
**AXI4-Lite Connectivity**
 
The AXI4-Lite wrapper (`rtl/system_integration/neorv32_SystemTop_axi4lite.vhd`) provides a Wishbone-to-
143,5 → 159,6
image::neorv32_axi_soc.png[]
 
[WARNING]
Using the auto-termination timeout feature (_MEM_EXT_TIMEOUT_ greater than zero) is **not AXI4 compliant** as the AXI protocol does not support canceling of
bus transactions. Therefore, the NEORV32 top wrapper with AXI4-Lite interface (`rtl/system_integration/neorv32_SystemTop_axi4lite`) configures _MEM_EXT_TIMEOUT_ = 0 by default.
Using the auto-termination timeout feature (_MEM_EXT_TIMEOUT_ greater than zero) is **not AXI4 compliant** as
the AXI protocol does not support canceling of bus transactions. Therefore, the NEORV32 top wrapper with AXI4-Lite interface
(`rtl/system_integration/neorv32_SystemTop_axi4lite`) configures _MEM_EXT_TIMEOUT_ = 0 by default.
/soc_xirq.adoc
42,7 → 42,8
The CPU can use the ID from `SCR` to service IRQ according to their priority. To acknowledge the according
interrupt the CPU can write `1 << SCR` to `IPR`.
 
In order to clear a pending FIRQ interrupt from the external interrupt controller, the CPU has to write _any_
In order to clear a pending FIRQ interrupt from the external interrupt controller again, the according `mip` CSR bit has
to be set. Additionally, the XIRQ interrupt has to be acknowledged by writing _any_
value to the interrupt source register `SRC`.
 
[NOTE]
/software.adoc
51,6 → 51,9
#include <neorv32.h>
----
 
[TIP]
A CMSIS-SVD-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.
 
Together with the makefile, this will automatically include all the processor's header files located in
`sw/lib/include` into your application. The actual source files of the core libraries are located in
`sw/lib/source` and are automatically included into the source list of your software project. The following
65,8 → 68,7
| `neorv32_cpu.c` | `neorv32_cpu.h` | HW driver functions for the NEORV32 **CPU**
| `neorv32_gpio.c` | `neorv32_gpio.h` | HW driver functions for the **GPIO**
| `neorv32_gptmr.c` | `neorv32_gptmr.h` | HW driver functions for the **GPTRM**
| - | `neorv32_intrinsics.h` | macros for custom intrinsics/instructions
| - | `neorv32_legacy.h` | legacy back-compatibility layer
| - | `neorv32_intrinsics.h` | macros for (custom) intrinsics/instructions
| `neorv32_mtime.c` | `neorv32_mtime.h` | HW driver functions for the **MTIME**
| `neorv32_neoled.c` | `neorv32_neoled.h` | HW driver functions for the **NEOLED**
| `neorv32_pwm.c` | `neorv32_pwm.h` | HW driver functions for the **PWM**
119,23 → 121,34
[source,makefile]
----
$ make
<<< NEORV32 Application Makefile >>>
<<< NEORV32 SW Application Makefile >>>
Make sure to add the bin folder of RISC-V GCC to your PATH variable.
Targets:
help - show this text
check - check toolchain
info - show makefile/toolchain configuration
exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader
hex - compile and generate <neorv32_exe.hex> executable raw file
image - compile and generate VHDL IMEM boot image (for application) in local folder
install - compile, generate and install VHDL IMEM boot image (for application)
sim - in-console simulation using default/simple testbench and GHDL
all - exe + hex + install
elf_info - show ELF layout info
clean - clean up project
clean_all - clean up project, core libraries and image generator
bl_image - compile and generate VHDL BOOTROM boot image (for bootloader only!) in local folder
bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)
 
== Targets ==
help - show this text
check - check toolchain
info - show makefile/toolchain configuration
exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader
hex - compile and generate <neorv32_exe.hex> executable raw file
image - compile and generate VHDL IMEM boot image (for application) in local folder
install - compile, generate and install VHDL IMEM boot image (for application)
sim - in-console simulation using default/simple testbench and GHDL
all - exe + hex + install
elf_info - show ELF layout info
clean - clean up project
clean_all - clean up project, core libraries and image generator
bl_image - compile and generate VHDL BOOTROM boot image (for bootloader only!) in local folder
bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)
 
== Variables ==
USER_FLAGS - Custom toolchain flags [append only], default ""
EFFORT - Optimization level, default "-Os"
MARCH - Machine architecture, default "rv32i"
MABI - Machine binary interface, default "ilp32"
APP_INC - C include folder(s) [append only], default "-I ."
ASM_INC - ASM include folder(s) [append only], default "-I ."
RISCV_PREFIX - Toolchain prefix, default "riscv32-unknown-elf-"
NEORV32_HOME - NEORV32 home folder, default "../../.."
----
 
 
506,8 → 519,8
* `h`: Show the help text (again)
* `r`: Restart the bootloader and the auto-boot sequence
* `u`: Upload new program executable (`neorv32_exe.bin`) via UART into the instruction memory
* `s`: Store executable to SPI flash at `spi_csn_o(0)`
* `l`: Load executable from SPI flash at `spi_csn_o(0)`
* `s`: Store executable to SPI flash at `spi_csn_o(0)` (little-endian byte order)
* `l`: Load executable from SPI flash at `spi_csn_o(0)` (little-endian byte order)
* `e`: Start the application, which is currently stored in the instruction memory (IMEM)
 
A new executable can be uploaded via UART by executing the `u` command. After that, the executable can be directly

powered by: WebSVN 2.1.0

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