<<<
:sectnums:
== NEORV32 Processor (SoC)

The NEORV32 Processor is build around the <<_neorv32_central_processing_unit_cpu>>. Together with common peripheral
interfaces and embedded memories it provides a RISC-V-based full-scale microcontroller-like SoC platform.

.The NEORV32 Processor (Block Diagram)
image::neorv32_processor.png[align=center]

**Section Structure**

* <<_processor_top_entity_signals>> and <<_processor_top_entity_generics>>
* <<_processor_clocking>> and <<_processor_reset>>
* <<_processor_interrupts>>
* <<_address_space>> and <<_boot_configuration>>
* <<_processor_internal_modules>>

**Key Features**

* _optional_ SMP <<_dual_core_configuration>>
* _optional_ processor-internal data and instruction memories (<<_data_memory_dmem,**DMEM**>>/<<_instruction_memory_imem,**IMEM**>>)
* _optional_ caches (<<_processor_internal_instruction_cache_icache,**I-CACHE**>>, <<_processor_internal_data_cache_dcache,**D-CACHE**>>)
* _optional_ internal bootloader (<<_bootloader_rom_bootrom,**BOOTROM**>>) with UART console & SPI/TWI flash and SD card boot options
* _optional_ RISC-V-compatible core local interruptor (<<_core_local_interruptor_clint,**CLINT**>>)
* _optional_ two independent universal asynchronous receivers and transmitters (<<_primary_universal_asynchronous_receiver_and_transmitter_uart0,**UART0**>>,
<<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,**UART1**>>) with optional hardware flow control (RTS/CTS)
* _optional_ serial peripheral interface host controller (<<_serial_peripheral_interface_controller_spi,**SPI**>>) with 8 dedicated CS lines
* _optional_ 8-bit serial data device interface (<<_serial_data_interface_controller_spi,**SDI**>>)
* _optional_ two-wire serial interface controller (<<_two_wire_serial_interface_controller_twi,**TWI**>>), compatible to the I²C standard
* _optional_ two-wire serial device controller (<<_two_wire_serial_device_controller_twd,**TWD**>>), compatible to the I²C standard
* _optional_ general purpose parallel IO port (<<_general_purpose_input_and_output_port_gpio,**GPIO**>>), 32 inputs (interrupt capable), 32 outputs
* _optional_ 32-bit external bus interface, Wishbone-compatible (<<_processor_external_bus_interface_xbus,**XBUS**>>), AXI4-compatible bridge available
* _optional_ watchdog timer (<<_watchdog_timer_wdt,**WDT**>>)
* _optional_ PWM controller with up to 32 individual channels (<<_pulse_width_modulation_controller_pwm,**PWM**>>)
* _optional_ ring-oscillator-based true random number generator (<<_true_random_number_generator_trng,**TRNG**>>)
* _optional_ custom functions subsystem for custom co-processor extensions (<<_custom_functions_subsystem_cfs,**CFS**>>)
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>) with up to 16 individual timer slices
* _optional_ 1-wire serial interface controller (<<_one_wire_serial_interface_controller_onewire,**ONEWIRE**>>), compatible to the 1-wire standard
* _optional_ autonomous direct memory access controller (<<_direct_memory_access_controller_dma,**DMA**>>)
* _optional_ stream link interface (<<_stream_link_interface_slink,**SLINK**>>), AXI4-Stream-compatible
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>), optional authentication and hardware breakpoint
* _optional_ execution trace buffer to debug program flow (<<_execution_trace_buffer_tracer,**TRACER**>>) via branch tracing
* _optional_ RVFI-compatible <<_execution_trace_port>> for advanced debugging, profiling and verification
* _optional_ system configuration information memory to determine hardware configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)


<<<
// ####################################################################################################################
:sectnums:
=== Processor Top Entity - Signals

The following table shows all interface signals of the processor top entity (`rtl/core/neorv32_top.vhd`).
All signals are of type `std_ulogic` or `std_ulogic_vector`, respectively (except for the `trace_*` ports).

.Default Values of Inputs
[NOTE]
All _optional_ input signals provide default values in case they are not explicitly assigned during instantiation.
The weak driver strengths of VHDL (`'L'` and `'H'`) are used to model a pull-down or pull-up resistor.

.Variable-Sized Ports
[NOTE]
Some peripherals allow to configure the number of channels to-be-implemented by a generic (for example the number
of PWM 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.

.Tri-State Interfaces
[NOTE]
Some interfaces (like the TWI, the TWD and the 1-Wire bus) require explicit tri-state drivers in the final top module.

.Input/Output Registers
[NOTE]
By default all output signals are driven by register and all input signals are synchronized into the processor's
clock domain also using registers. However, for ASIC implementations it is recommended to add another register state
to all inputs and output so the synthesis tool can insert an explicit IO (boundary) scan chain.

.NEORV32 Processor Signal List
[cols="<4,^2,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Name | Width | Direction | Default | Description
5+^| **Global Control (<<_processor_clocking>> and <<_processor_reset>>)**
| `clk_i`          |  1 |  in | none  | global clock line, all registers triggering on rising edge
| `rstn_i`         |  1 |  in | none  | global reset, asynchronous, **low-active**
| `rstn_ocd_o`     |  1 | out | none  | <<_on_chip_debugger_ocd>> reset output, synchronous, **low-active**
| `rstn_wdt_o`     |  1 | out | none  | <<_watchdog_timer_wdt>> reset output, synchronous, **low-active**
5+^| **<<_execution_trace_port>>**
| `trace_cpu0_o`   |  * | out |   -   | CPU core 0 trace port (type `trace_port_t`).
| `trace_cpu1_o`   |  * | out |   -   | CPU core 1 trace port (type `trace_port_t`).
5+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
| `jtag_tck_i`     |  1 |  in | `'L'` | serial clock
| `jtag_tdi_i`     |  1 |  in | `'L'` | serial data input
| `jtag_tdo_o`     |  1 | out |   -   | serial data output
| `jtag_tms_i`     |  1 |  in | `'L'` | mode select
5+^| **<<_processor_external_bus_interface_xbus>>**
| `xbus_adr_o`     | 32 | out |   -   | destination address
| `xbus_dat_o`     | 32 | out |   -   | read data
| `xbus_cti_o`     |  3 | out |   -   | cycle type
| `xbus_tag_o`     |  3 | out |   -   | access tag
| `xbus_we_o`      |  1 | out |   -   | write enable ('0' = read transfer)
| `xbus_sel_o`     |  4 | out |   -   | byte enable
| `xbus_stb_o`     |  1 | out |   -   | strobe
| `xbus_cyc_o`     |  1 | out |   -   | valid cycle
| `xbus_dat_i`     | 32 |  in | `'L'` | write data
| `xbus_ack_i`     |  1 |  in | `'L'` | transfer acknowledge
| `xbus_err_i`     |  1 |  in | `'L'` | transfer error
5+^| **<<_stream_link_interface_slink>>**
| `slink_rx_dat_i` | 32 |  in | `'L'` | RX data
| `slink_rx_src_i` |  4 |  in | `'L'` | RX source routing information
| `slink_rx_val_i` |  1 |  in | `'L'` | RX data valid
| `slink_rx_lst_i` |  1 |  in | `'L'` | RX last element of stream
| `slink_rx_rdy_o` |  1 | out |   -   | RX ready to receive
| `slink_tx_dat_o` | 32 | out |   -   | TX data
| `slink_tx_dst_o` |  4 | out |   -   | TX destination routing information
| `slink_tx_val_o` |  1 | out |   -   | TX data valid
| `slink_tx_lst_o` |  1 | out |   -   | TX last element of stream
| `slink_tx_rdy_i` |  1 |  in | `'L'` | TX allowed to send
5+^| **<<_general_purpose_input_and_output_port_gpio>>**
| `gpio_o`         | 32 | out |   -   | general purpose parallel output
| `gpio_i`         | 32 |  in | `'L'` | general purpose parallel input (interrupt-capable)
5+^| **<<_primary_universal_asynchronous_receiver_and_transmitter_uart0>>**
| `uart0_txd_o`    |  1 | out |   -   | serial transmitter
| `uart0_rxd_i`    |  1 |  in | `'L'` | serial receiver
| `uart0_rtsn_o`   |  1 | out |   -   | RX ready to receive new char
| `uart0_ctsn_i`   |  1 |  in | `'L'` | TX allowed to start sending, low-active
5+^| **<<_secondary_universal_asynchronous_receiver_and_transmitter_uart1>>**
| `uart1_txd_o`    |  1 | out |   -   | serial transmitter
| `uart1_rxd_i`    |  1 |  in | `'L'` | serial receiver
| `uart1_rtsn_o`   |  1 | out |   -   | RX ready to receive new char
| `uart1_ctsn_i`   |  1 |  in | `'L'` | TX allowed to start sending, low-active
5+^| **<<_serial_peripheral_interface_controller_spi>>**
| `spi_clk_o`      |  1 | out |   -   | controller clock line
| `spi_dat_o`      |  1 | out |   -   | serial data output
| `spi_dat_i`      |  1 |  in | `'L'` | serial data input
| `spi_csn_o`      |  8 | out |   -   |  select (low-active)
5+^| **<<_serial_data_interface_controller_sdi>>**
| `sdi_clk_i`      |  1 |  in | `'L'` | controller clock line
| `sdi_dat_o`      |  1 | out |   -   | serial data output
| `sdi_dat_i`      |  1 |  in | `'L'` | serial data input
| `sdi_csn_i`      |  1 |  in | `'H'` | chip select, low-active
5+^| **<<_two_wire_serial_interface_controller_twi>>**
| `twi_sda_i`      |  1 |  in | `'H'` | serial data line sense input
| `twi_sda_o`      |  1 | out |   -   | serial data line output (pull low only)
| `twi_scl_i`      |  1 |  in | `'H'` | serial clock line sense input
| `twi_scl_o`      |  1 | out |   -   | serial clock line output (pull low only)
5+^| **<<_two_wire_serial_device_controller_twd>>**
| `twd_sda_i`      |  1 |  in | `'H'` | serial data line sense input
| `twd_sda_o`      |  1 | out |   -   | serial data line output (pull low only)
| `twd_scl_i`      |  1 |  in | `'H'` | serial clock line sense input
| `twd_scl_o`      |  1 | out |   -   | serial clock line output (pull low only)
5+^| **<<_one_wire_serial_interface_controller_onewire>>**
| `onewire_i`      |  1 |  in | `'H'` | 1-wire bus sense input
| `onewire_o`      |  1 | out |   -   | 1-wire bus output (pull low only)
5+^| **<<_pulse_width_modulation_controller_pwm>>**
| `pwm_o`          | 16 | out |   -   | pulse-width modulated channels
5+^| **<<_custom_functions_subsystem_cfs>>**
| `cfs_in_i`       | 256 |  in | `'L'` | custom CFS input signal conduit
| `cfs_out_o`      | 256 | out |   -   | custom CFS output signal conduit
5+^| **<<_smart_led_interface_neoled>>**
| `neoled_o`       |  1 | out |   -   | asynchronous serial data output
5+^| **<<_core_local_interruptor_clint>>**
| `mtime_time_o`   | 64 | out |   -   | CLINT.MTIMER system time output
5+^| **RISC-V Machine-Mode <<_processor_interrupts>>**
| `mtime_irq_i`    |  1 |  in | `'L'` | machine timer interrupt (RISC-V), high-level-active; for chip-internal usage only
| `msw_irq_i`      |  1 |  in | `'L'` | machine software interrupt (RISC-V), high-level-active; for chip-internal usage only
| `mext_irq_i`     |  1 |  in | `'L'` | machine external interrupt (RISC-V), high-level-active; for chip-internal usage only
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Processor Top Entity - Generics

This section lists all configuration generics of the NEORV32 processor top entity (`rtl/neorv32_top.vhd`).
These generics allow to configure the system according to your needs. The generics are
used to control implementation of certain CPU extensions and peripheral modules and even allow to
optimize the system for certain design goals like minimal area or maximum performance.

.Default Values
[NOTE]
All configuration generics provide default values in case they are not explicitly assigned during instantiation.
By default, all configuration options are **disabled**.

.Software Discovery of Configuration
[TIP]
Software can determine the actual CPU configuration via the <<_misa>> and <<_mxisa>> CSRs. The Soc/Processor
and can be determined via the <<_system_configuration_information_memory_sysinfo, SYSINFO>> memory-mapped registers.

.Excluded Modules and Extensions
[NOTE]
If optional modules (like CPU extensions or peripheral devices) are not enabled the according hardware
will not be synthesized at all. Hence, the disabled modules do not increase area and power requirements
and do not impact timing.

.Table Abbreviations
[NOTE]
The generic type "`suv(x:y)`" is an abbreviation for "`std_ulogic_vector(x downto y)`".

.NEORV32 Processor Generic List
[cols="<3,^2,^2,<8"]
[options="header",grid="rows"]
|=======================
| Name | Type | Default | Description
4+^| **General**
| `CLOCK_FREQUENCY`       | natural   | 0             | The clock frequency of the processor's `clk_i` input port in Hertz (Hz). See <<_processor_clocking>>.
| `TRACE_PORT_EN`         | boolean   | false         | Enable external CPU execution <<_execution_trace_port>>.
| `DUAL_CORE_EN`          | boolean   | false         | Enable the SMP <<_dual_core_configuration>>.
4+^| **<<_boot_configuration>>**
| `BOOT_MODE_SELECT`      | natural   | 0             | Boot mode select; see <<_boot_configuration>>.
| `BOOT_ADDR_CUSTOM`      | suv(31:0) | x"00000000"   | Custom CPU boot address (available if `BOOT_MODE_SELECT` = 1).
4+^| **<<_on_chip_debugger_ocd>>**
| `OCD_EN`                | boolean   | false         | Implement the on-chip debugger and the CPU debug mode (<<_sdext_isa_extension>>).
| `OCD_NUM_HW_TRIGGERS`   | natural   | 0             | Number of implemented HW triggers (<<_trigger_module>> / <<_sdtrig_isa_extension>>) for hardware break-/watchpoints (0..16).
| `OCD_AUTHENTICATION`    | boolean   | false         | Implement <<_debug_authentication>> module.
| `OCD_JEDEC_ID`          | suv(10:0) | "00000000000" | JEDEC ID; continuation codes plus vendor ID (passed to the JTAG <<_debug_transport_module_dtm>>).
4+^| **CPU <<_instruction_sets_and_extensions>>**
| `RISCV_ISA_C`           | boolean   | false         | Enable <<_c_isa_extension>> (compressed instructions).
| `RISCV_ISA_E`           | boolean   | false         | Enable <<_e_isa_extension>> (reduced register file size).
| `RISCV_ISA_M`           | boolean   | false         | Enable <<_m_isa_extension>> (hardware-based integer multiplication and division).
| `RISCV_ISA_U`           | boolean   | false         | Enable <<_u_isa_extension>> (less-privileged user mode).
| `RISCV_ISA_Zaamo`       | boolean   | false         | Enable <<_zaamo_isa_extension>> (atomic read-modify-write operations).
| `RISCV_ISA_Zalrsc`      | boolean   | false         | Enable <<_zalrsc_isa_extension>> (atomic reservation-set operations).
| `RISCV_ISA_Zba`         | boolean   | false         | Enable <<_zba_isa_extension>> (shifted-add bit-manipulation instructions).
| `RISCV_ISA_Zbb`         | boolean   | false         | Enable <<_zbb_isa_extension>> (basic bit-manipulation instructions).
| `RISCV_ISA_Zbkb`        | boolean   | false         | Enable <<_zbkb_isa_extension>> (scalar cryptography bit manipulation instructions).
| `RISCV_ISA_Zbkc`        | boolean   | false         | Enable <<_zbkc_isa_extension>> (scalar cryptography carry-less multiplication instructions).
| `RISCV_ISA_Zbkx`        | boolean   | false         | Enable <<_zbkx_isa_extension>> (scalar cryptography crossbar permutations).
| `RISCV_ISA_Zbs`         | boolean   | false         | Enable <<_zbs_isa_extension>> (single-bit bit-manipulation instructions).
| `RISCV_ISA_Zcb`         | boolean   | false         | Enable <<_zcb_isa_extension>> (additional code size reduction instruction; builds upon `C`).
| `RISCV_ISA_Zfinx`       | boolean   | false         | Enable <<_zfinx_isa_extension>> (single-precision floating-point unit).
| `RISCV_ISA_Zibi`        | boolean   | false         | Enable <<_zibi_isa_extension>> (CPU base counters).
| `RISCV_ISA_Zicntr`      | boolean   | false         | Enable <<_zicntr_isa_extension>> (CPU base counters).
| `RISCV_ISA_Zicond`      | boolean   | false         | Enable <<_zicond_isa_extension>> (integer conditional instructions).
| `RISCV_ISA_Zihpm`       | boolean   | false         | Enable <<_zihpm_isa_extension>> (hardware performance monitors).
| `RISCV_ISA_Zimop`       | boolean   | false         | Enable <<_zimop_isa_extension>> (may-be-operations).
| `RISCV_ISA_Zknd`        | boolean   | false         | Enable <<_zknd_isa_extension>> (scalar cryptography NIST AES decryption instructions).
| `RISCV_ISA_Zkne`        | boolean   | false         | Enable <<_zkne_isa_extension>> (scalar cryptography NIST AES encryption instructions).
| `RISCV_ISA_Zknh`        | boolean   | false         | Enable <<_zknh_isa_extension>> (scalar cryptography NIST hash instructions).
| `RISCV_ISA_Zksed`       | boolean   | false         | Enable <<_zksed_isa_extension>> (scalar cryptography ShangMi block cyphers).
| `RISCV_ISA_Zksh`        | boolean   | false         | Enable <<_zksh_isa_extension>> (scalar cryptography ShangMi hash functions).
| `RISCV_ISA_Zmmul`       | boolean   | false         | Enable <<_zmmul_isa_extension>> (hardware-based integer multiplication).
| `RISCV_ISA_Zxcfu`       | boolean   | false         | Enable NEORV32-specific <<_zxcfu_isa_extension>> (custom RISC-V instructions).
4+^| **<<_cpu_tuning_options>>**
| `CPU_CONSTT_BR_EN`      | boolean   | false         | Implement constant-time branches (same execution times for taken and not-taken branches).
| `CPU_FAST_MUL_EN`       | boolean   | false         | Implement fast but large full-parallel multipliers (trying to infer DSP blocks); see section <<_cpu_arithmetic_logic_unit>>.
| `CPU_FAST_SHIFT_EN`     | boolean   | false         | Implement fast but large full-parallel barrel shifters; see section <<_cpu_arithmetic_logic_unit>>.
| `CPU_RF_HW_RST_EN`      | boolean   | false         | Implement full hardware reset for register file (use individual FFs instead of BRAM); see section <<_cpu_register_file>>.
4+^| **Physical Memory Protection (<<_smpmp_isa_extension>>)**
| `PMP_NUM_REGIONS`       | natural   | 0             | Number of implemented PMP regions (0..16).
| `PMP_MIN_GRANULARITY`   | natural   | 4             | Minimal region granularity in bytes. Has to be a power of two, min 4.
| `PMP_TOR_MODE_EN`       | boolean   | false         | Implement support for top-of-region (TOR) mode.
| `PMP_NAP_MODE_EN`       | boolean   | false         | Implement support for naturally-aligned power-of-two (NAPOT & NA4) modes.
4+^| **Hardware Performance Monitors (<<_zihpm_isa_extension>>)**
| `HPM_NUM_CNTS`          | natural   | 0             | Number of implemented hardware performance monitor counters (0..13).
| `HPM_CNT_WIDTH`         | natural   | 40            | Total LSB-aligned size of each HPM counter. Min 0, max 64.
4+^| **Internal <<_instruction_memory_imem>>**
| `IMEM_EN`               | boolean   | false         | Implement the processor-internal instruction memory.
| `IMEM_SIZE`             | natural   | 16*1024       | Size in bytes of the processor internal instruction memory (use a power of 2).
| `IMEM_OUTREG_EN`        | boolean   | false         | Add IMEM output register stage (improves mapping/timing at the expense of latency).
4+^| **Internal <<_data_memory_dmem>>**
| `DMEM_EN`               | boolean   | false         | Implement the processor-internal data memory.
| `DMEM_SIZE`             | natural   | 8*1024        | Size in bytes of the processor-internal data memory (use a power of 2).
| `DMEM_OUTREG_EN`        | boolean   | false         | Add DMEM output register stage (improves mapping/timing at the expense of latency).
4+^| **CPU Caches (<<_processor_internal_instruction_cache_icache, instruction-cache>> & <<_processor_internal_data_cache_dcache, data-cache>>)**
| `ICACHE_EN`             | boolean   | false         | Implement the instruction cache (I$).
| `ICACHE_NUM_BLOCKS`     | natural   | 4             | Number of blocks ("lines") Has to be a power of two.
| `DCACHE_EN`             | boolean   | false         | Implement the data cache (D$)
| `DCACHE_NUM_BLOCKS`     | natural   | 4             | Number of blocks ("lines"). Has to be a power of two.
| `CACHE_BLOCK_SIZE`      | natural   | 64            | Size in bytes of each block (I$ and D$). Has to be a power of two, min 8.
| `CACHE_BURSTS_EN`       | boolean   | true          | Enable burst transfers for cache updates.
4+^| **<<_processor_external_bus_interface_xbus>> (Wishbone / AXI4-Compatible Bridging)**
| `XBUS_EN`               | boolean   | false         | Implement the external bus interface.
| `XBUS_TIMEOUT`          | natural   | 2048          | Number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled).
| `XBUS_REGSTAGE_EN`      | boolean   | false         | Implement XBUS register stages to ease timing closure.
4+^| **Peripheral/IO Modules**
| `IO_DISABLE_SYSINFO`    | boolean   | false         | Disable <<_system_configuration_information_memory_sysinfo>> module; not recommended - for advanced users only!
| `IO_GPIO_NUM`           | natural   | 0             | Number of general purpose input/output pairs of the <<_general_purpose_input_and_output_port_gpio>>, max 32.
| `IO_CLINT_EN`           | boolean   | false         | Implement the <<_core_local_interruptor_clint>>.
| `IO_UART0_EN`           | boolean   | false         | Implement the <<_primary_universal_asynchronous_receiver_and_transmitter_uart0>>.
| `IO_UART0_RX_FIFO`      | natural   | 1             | UART0 RX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_UART0_TX_FIFO`      | natural   | 1             | UART0 TX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_UART1_EN`           | boolean   | false         | Implement the <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1>>.
| `IO_UART1_RX_FIFO`      | natural   | 1             | UART1 RX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_UART1_TX_FIFO`      | natural   | 1             | UART1 TX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_SPI_EN`             | boolean   | false         | Implement the <<_serial_peripheral_interface_controller_spi>>.
| `IO_SPI_FIFO`           | natural   | 1             | Depth of the <<_serial_peripheral_interface_controller_spi>> FIFO. Has to be a power of two, min 1, max 32768.
| `IO_SDI_EN`             | boolean   | false         | Implement the <<_serial_data_interface_controller_sdi>>.
| `IO_SDI_FIFO`           | natural   | 1             | Depth of the <<_serial_data_interface_controller_sdi>> FIFO. Has to be a power of two, min 1, max 32768.
| `IO_TWI_EN`             | boolean   | false         | Implement the <<_two_wire_serial_interface_controller_twi>>.
| `IO_TWI_FIFO`           | natural   | 1             | Depth of the <<_two_wire_serial_interface_controller_twi>> FIFO. Has to be a power of two, min 1, max 32768.
| `IO_TWD_EN`             | boolean   | false         | Implement the <<_two_wire_serial_device_controller_twd>>.
| `IO_TWD_RX_FIFO`        | natural   | 1             | Depth of the <<_two_wire_serial_device_controller_twd>> RX FIFO. Has to be a power of two, min 1, max 32768.
| `IO_TWD_TX_FIFO`        | natural   | 1             | Depth of the <<_two_wire_serial_device_controller_twd>> TX FIFO. Has to be a power of two, min 1, max 32768.
| `IO_PWM_NUM`            | natural   | 0             | Number of channels of the <<_pulse_width_modulation_controller_pwm>> to implement (0..32).
| `IO_WDT_EN`             | boolean   | false         | Implement the <<_watchdog_timer_wdt>>.
| `IO_TRNG_EN`            | boolean   | false         | Implement the <<_true_random_number_generator_trng>>.
| `IO_TRNG_FIFO`          | natural   | 1             | Depth of the TRNG data FIFO. Has to be a power of two, min 1, max 32768.
| `IO_CFS_EN`             | boolean   | false         | Implement the <<_custom_functions_subsystem_cfs>>.
| `IO_NEOLED_EN`          | boolean   | false         | Implement the <<_smart_led_interface_neoled>>.
| `IO_NEOLED_TX_FIFO`     | natural   | 1             | TX FIFO depth of the <<_smart_led_interface_neoled>>. Has to be a power of two, min 1, max 32768.
| `IO_GPTMR_NUM`          | natural   | 0             | Number of individual <<_general_purpose_timer_gptmr>> timer slices (0..16).
| `IO_ONEWIRE_EN`         | boolean   | false         | Implement the <<_one_wire_serial_interface_controller_onewire>>.
| `IO_ONEWIRE_FIFO`       | natural   | 1             | Depth of the <<_one_wire_serial_interface_controller_onewire>> FIFO. Has to be a power of two, min 1, max 32768.
| `IO_DMA_EN`             | boolean   | false         | Implement the <<_direct_memory_access_controller_dma>>.
| `IO_DMA_DSC_FIFO`       | natural   | 4             | Depth of the DMA transfer descriptor FIFO. Has to be a power of two, min 4, max 512.
| `IO_SLINK_EN`           | boolean   | false         | Implement the <<_stream_link_interface_slink>> (AXI4-Stream-Compatible).
| `IO_SLINK_RX_FIFO`      | natural   | 1             | SLINK RX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_SLINK_TX_FIFO`      | natural   | 1             | SLINK TX FIFO depth, has to be a power of two, minimum value is 1, max 32768.
| `IO_TRACER_EN`          | boolean   | false         | Implement the <<_execution_trace_buffer_tracer>>.
| `IO_TRACER_BUFFER`      | natural   | 1             | Depth of the <<_execution_trace_buffer_tracer>>. Has to be a power of two, min 1, max 32768.
| `IO_TRACER_SIMLOG_EN`   | boolean   | false         | Write full trace log to file (simulation-only).
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Processor Clocking

The processor is implemented as fully-synchronous logic design using a single clock domain that is driven entirely
by the top's `clk_i` signal. This clock signal is used by all internal registers and memories. All of them trigger
on the **rising edge** of this clock signal. External "clocks" like the OCD's JTAG clock or the SDI's serial clock
are synchronized into the processor's clock domain before being used as "general logic signal" (and not as a dedicated clock).


==== Peripheral Clocks

Many processor modules like the UARTs or the timers provide a programmable time base for operations. In order to simplify
the hardware, the processor implements a global "clock generator" (`neorv32_sys.vhd`) that provides single-cycle _clock enables_
for certain frequencies which are derived from the main clock. These clock enable signals are synchronous to the system's
main clock. The processor modules can use these enables for sub-main-clock operations while still providing a single
clock domain only.

In total, 8 sub-main-clock signals are available. All processor modules, which feature a time-based configuration, provide a
programmable three-bit prescaler select in their control register to select one of the 8 available clocks. The
mapping of the prescaler select bits to the according clock source is shown in the table below. Here, _f_ represents the
processor main clock from the top entity's `clk_i` signal.

[cols="<3,^1,^1,^1,^1,^1,^1,^1,^1"]
[grid="rows"]
|=======================
| Prescaler bits:  | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting clock: | _f/2_   | _f/4_   | _f/8_   | _f/64_  | _f/128_ | _f/1024_| _f/2048_| _f/4096_
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Processor Reset

The NEORV32 processor includes a central reset sequencer (`neorv32_sys.vhd`) that handles all reset requests
and controls the internal reset nets. The processor-wide reset (aka "system reset") can be triggered by any
of the following sources:

* the asynchronous low-active `rstn_i` top entity input signal (External source)
* the <<_on_chip_debugger_ocd>> (internal source)
* the <<_watchdog_timer_wdt>> (internal source)

.Processor Reset Signal
[IMPORTANT]
Make sure to connect the processor's reset signal `rstn_i` to a valid reset source (a button, the "locked"
signal of a PLL, a dedicated reset controller, etc.).

.Reset Cause
[TIP]
The actual reset cause can be determined via the <<_watchdog_timer_wdt>>.

If any of these sources triggers a reset, the internal system-wide reset will be active for at least 4 clock cycles ensuring
a valid reset of the entire processor. This system reset is asserted _asynchronoulsy_ if triggered by the external
`rstn_i` signal and is asserted _synchronously_ if triggered by an internal reset source. However, the system reset is
always de-asserted _synchronously_ at the next rising clock edge.

Internally, **all registers** that are not meant for mapping to blockRAM (like the register file) do provide a dedicated and
**low-active asynchronous** hardware reset. This asynchronous reset ensures that the entire processor logic is reset to a
defined state even if the main clock is not operational yet.


<<<
// ####################################################################################################################
:sectnums:
=== Processor Interrupts

The NEORV32 Processor provides several interrupt request signals (IRQs) for custom platform use.

.Trigger Type
[IMPORTANT]
All interrupt request lines are **level-triggered and high-active**. Once set, the signal should remain high until
the interrupt request is explicitly acknowledged (e.g. writing to a memory-mapped register).


:sectnums:
==== RISC-V Standard Interrupts

The processor supports the standard RISC-V machine-level interrupts for "machine timer interrupt", "machine
software interrupt" and "machine external interrupt". Their usage is defined by the RISC-V privileged architecture
specifications. However, these interrupt could also be re-purposed for custom applications. See CPU section
<<_traps_exceptions_and_interrupts>> for more information.

.Processor Top RISC-V Machine-Level Interrupts
[cols="<4,<10"]
[options="header",grid="rows"]
|=======================
| Top signal | Description
| `mtime_irq_i` | Machine timer interrupt from _processor-external_ CLINT (`MTI`). This IRQ is only available if the processor-internal <<_core_local_interruptor_clint>> unit is not implemented.
| `msw_irq_i`   | Machine software interrupt from _processor-external_ CLINT (`MSI`). This IRQ is only available if the processor-internal <<_core_local_interruptor_clint>> unit is not implemented.
| `mext_irq_i`  | Machine external interrupt from _processor-external_ PLIC (`MEI`). This interrupt is always available as top-entity port.
|=======================


:sectnums:
==== NEORV32-Specific Fast Interrupt Requests

As part of the NEORV32-specific CPU extensions, the processor core features 16 fast interrupt request signals
(`FIRQ0` to `FIRQ15`) providing dedicated bits in the <<_mip>> and <<_mie>> CSRs and custom <<_mcause>> trap codes.
The FIRQ signals are reserved for _processor-internal_ modules only (for example for the communication
interfaces to signal "available incoming data" or "ready to send new data").

The mapping of the 16 FIRQ channels to the according processor-internal modules is shown in the following
table (the channel number also corresponds to the according FIRQ priority: 0 = highest, 15 = lowest):

.NEORV32 Fast Interrupt Request (FIRQ) Mapping
[cols="^2,^2,<6"]
[options="header",grid="rows"]
|=======================
| Channel / priority | Source | Description
| 0  | <<_two_wire_serial_device_controller_twd,TWD>> | TWD FIFO level interrupt
| 1  | <<_custom_functions_subsystem_cfs,CFS>> | Custom functions subsystem (CFS) interrupt (user-defined)
| 2  | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 FIFO level interrupt
| 3  | <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>> | UART1 FIFO level interrupt
| 4  | - | _reserved_
| 5  | <<_execution_trace_buffer_tracer,TRACER>> | Tracing stop-address match interrupt
| 6  | <<_serial_peripheral_interface_controller_spi,SPI>> | SPI FIFO level interrupt
| 7  | <<_two_wire_serial_interface_controller_twi,TWI>> | TWI FIFO level interrupt
| 8  | <<_general_purpose_input_and_output_port_gpio,GPIO>> | GPIO input pin(s) interrupt
| 9  | <<_smart_led_interface_neoled,NEOLED>> | NEOLED TX FIFO level interrupt
| 10 | <<_direct_memory_access_controller_dma,DMA>> | DMA transfer done interrupt
| 11 | <<_serial_data_interface_controller_sdi,SDI>> | SDI FIFO level interrupt
| 12 | <<_general_purpose_timer_gptmr,GPTMR>> | General purpose timer interrupt
| 13 | <<_one_wire_serial_interface_controller_onewire,ONEWIRE>> | 1-wire idle interrupt
| 14 | <<_stream_link_interface_slink,SLINK>> | SLINK FIFO level interrupt
| 15 | <<_true_random_number_generator_trng,TRNG>> | TRNG FIFO level interrupt
|=======================


<<<
// ####################################################################################################################
:sectnums:
=== Address Space

As a 32-bit architecture the NEORV32 can access a 4GB physical address space. By default, this address space is
split into three main regions. All accesses to "unmapped" addresses (a.k.a. "the void") are redirected to the
<<_processor_external_bus_interface_xbus>>. For example, if the internal IMEM is disabled, the accesses to the
_entire_ address space between `0x00000000` and `0x7FFFFFFF` are converted into XBUS requests. If the XBUS interface
is not enabled any access to the void will raise a bus error exception.

.NEORV32 Processor Address Space (Default Configuration)
image::address_space.png[900]

Each region provides specific _physical memory attributes_ ("PMAs") that define the access capabilities (`rwxac`;
`r` = read access, `w` = write access, `x` - execute access, `a` = atomic access, `c` = cached CPU access).

.Custom PMAs
[TIP]
Custom physical memory attributes enforced by the CPU's _physcial memory protection_ (<<_smpmp_isa_extension>>)
can be used to further constrain the physical memory attributes.

.Main Address Regions
[cols="<1,^4,^2,<7"]
[options="header",grid="rows"]
|=======================
| # | Region                      | PMAs      | Description
| 1 | Internal IMEM address space | `rwxac`   | For instructions / code and constants; mapped to the internal <<_instruction_memory_imem>> if implemented.
| 2 | Internal DMEM address space | `rwxac`   | For application runtime data (heap, stack, etc.); mapped to the internal <<_data_memory_dmem>>) if implemented.
| 3 | IO/peripheral address space | `rwxa-`   | Processor-internal peripherals / IO devices including the <<_bootloader_rom_bootrom>>.
| - | The "**void**"              | `rwxa[c]` | Unmapped address space. All accesses to this region(s) are redirected to the <<_processor_external_bus_interface_xbus>> if implemented.
|=======================


:sectnums:
==== Bus System

The CPU provides individual interfaces for instruction fetch and data access. It can can access all of the 32-bit
address space from each of the interface. Both of them can be equipped with optional caches (<<_processor_internal_data_cache_dcache>>
and <<_processor_internal_instruction_cache_icache>>).

The two CPU interfaces are multiplexed by a simple bus switch into a _single processor-internal bus_. Optionally,
this bus is further multiplexed by another instance of the bus switch so the <<_direct_memory_access_controller_dma>>
controller can also access the entire address space. Accesses via the resulting SoC bus are split by the <<_bus_gateway>>
that redirects accesses to the according main address regions (see table above). Accesses to the processor-internal
IO/peripheral devices are further redirected via a dedicated <<_io_switch>>.

.Processor-Internal Bus Architecture
image::neorv32_bus.png[1300]

.Bus System Infrastructure
[NOTE]
The components of the processor's bus system infrastructure are located in `rtl/core/neorv32_bus.vhd`.

.Bus Interface
[TIP]
See sections CPU <<_architecture>> and <<_bus_interface>> for more information regarding the CPU bus accesses.

.SMP Dual-Core Configuration
[TIP]
The dual-core configuration adds a second CPU core complex in parallel to the first one.
See section <<_dual_core_configuration>> for more information.


:sectnums:
==== Bus Gateway

The central bus gateway serves two purposes: it **redirects** accesses to the according modules (e.g. memory accesses
vs. memory-mapped IO accesses) and also **monitors** all bus transactions. The redirection of access request is based on a
customizable memory map implemented via VHDL constants in the main package file (`rtl/core/neorv32_package.vhd`):

.Main Address Regions Configuration in the VHDL Package File
[source,vhdl]
----
-- Main Address Regions ---
constant mem_imem_base_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- IMEM size via generic
constant mem_dmem_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- DMEM size via generic
constant mem_io_base_c   : std_ulogic_vector(31 downto 0) := x"ffe00000";
constant mem_io_size_c   : natural := 32*64*1024; -- = 32 * iodev_size_c
----

===== Bus Monitor and Timeout

Besides the redirecting of bus requests the gateway also implements a **bus monitor** (aka "the bus keeper") that
tracks all bus transactions to ensure _safe_ and _deterministic_ operations. Whenever a memory-mapped device is
accessed the bus monitor starts an internal countdown. The accessed module has to respond ("ACK") to the bus request
within a bound time window. For **processor-internal** accesses this time windows is defined by a constant in the main
NEORV32 package file (`neorv32_package.vhd`). For **processor-external accesses** via the
<<_processor_external_bus_interface_xbus>> this time window is defined by the `XBUS_TIMEOUT` top configuration generic.

.Internal Bus Timeout Configuration (package constant)
[source,vhdl]
----
constant int_bus_tmo_c : natural := 16;
----

.External Bus Timeout Configuration (top generic)
[source,vhdl]
----
XBUS_TIMEOUT : natural := 2048;
----

The according time window defines the _maximum_ number of cycles after which a non-responding bus request will
time out raising a bus access fault exception. For example this can happen when accessing "address space holes"
(aka _the void_) - addresses that are not mapped to any physical module. The specific bus access exception type
corresponds to the according access type, i.e. instruction fetch bus fault, load bus fault or store bus fault.


:sectnums:
==== IO Switch

The IO switch further decodes the address when accessing the processor-internal IO/peripheral devices and forwards
the access request to the according module. Note that a total address space size of 256 bytes is assigned to each
IO module in order to simplify address decoding. The IO-specific address map is also defined in the main VHDL
package file (`rtl/core/neorv32_package.vhd`).

.Exemplary Cut-Out from the IO Address Map
[source,vhdl]
----
-- IO Address Map --
constant iodev_size_c    : natural := 256; -- size of a single IO device (bytes)
constant base_io_cfs_c   : std_ulogic_vector(31 downto 0) := x"ffffeb00";
constant base_io_slink_c : std_ulogic_vector(31 downto 0) := x"ffffec00";
constant base_io_dma_c   : std_ulogic_vector(31 downto 0) := x"ffffed00";
----


:sectnums:
==== Atomic Memory Operations Controller

The atomic memory operations controller is split into two individual modules. Each module
implements a specific sub-extensions of the <<_a_isa_extension,`A`>> ISA extension:

[cols="<3,<3,<4"]
[options="header",grid="rows"]
|=======================
| Hardware Module | ISA Extensions | Description
| `neorv32_bus_amo_rmw` | <<_zaamo_isa_extension>>  | Atomic read-modify-write operations
| `neorv32_bus_amo_rvs` | <<_zalrsc_isa_extension>> | Atomic reservation-set operations
|=======================

.Direct Access
[IMPORTANT]
Atomic operations **always bypass** the CPU's <<_processor_internal_data_cache_dcache, data cache>>
using direct/uncached accesses. Care must be taken to maintain data <<_memory_coherence>>.

.Physical Memory Attributes
[NOTE]
Atomic memory operations can be executed for _any_ address. This also includes
cached memory, memory-mapped IO devices and processor-external address spaces.

===== Atomic Read-Modify-Write Controller

This modules converts a single atomic memory operations request into a set of bus transactions
to execute an un-interruptable read-modify-write (RMW) operation. For each request, the controller
executes an atomic set of three operations:

.Simplified AMO Controller Operation
[cols="^1,<3,<6"]
[options="header",grid="rows"]
|=======================
| Step | Pseudo Code | Description
| 1    | `tmp1 <= MEM[address];` | Perform a read operation accessing the addressed memory
cell and store the loaded data into an internal buffer (`tmp1`).
| 2    | `tmp2 <= tmp1 OP cpu_wdata` | The buffered data from the first step is processed
using the write data provide by the CPU. The result is stored to another internal buffer (`tmp2`).
| 3    | `MEM[address] <= tmp2;` `cpu_rdata <= tmp1;` | The data from the second buffer (`tmp2`) is
written to the addressed memory cell. In parallel, the data from the first buffer (`tmp1` = original
content of the addresses memory cell) is sent back to the requesting CPU.
|=======================

The controller performs two bus transactions: a read operations and a write operation. Only the acknowledge/error
handshake of the last transaction is sent back to the CPU. As the RMW controller is the memory-nearest instance
(see <<_bus_system>>) the previously described set of operations cannot be interrupted. Hence, they execute in
an atomic way.

===== Atomic Reservation-Set Controller

A "reservation" defines an address or address range that provides a guarding mechanism to support atomic
accesses. A new reservation is registered by the `LR` instruction. The address provided by this instruction
defines the memory location that is now monitored for atomic accesses. The according `SC` instruction
evaluates the state of this reservation. If the reservation is still valid the write access triggered by
the SC instruction is finally executed and the instruction return a "success" state (`rd` = 0). If the
reservation has been invalidated the SC instruction will not write to memory and will return a "failed"
state (`rd` = 1).

The reservation-set controller implements the _strong semnatics_. A reservation is created when executing
the `LR` instruction. Any other data memory access (for example by the DMA) will invalidate any active
reservation (instruction fetches do not affect the reservations at all). Furthermore, executing a `fence[.i]`
instruction will also invalidate any reservation.

The controller implements a **single, global reservation set only**, which is used by both cores in the
SMP <<_dual_core_configuration>>. Since the reservation is global, no access address is stored or compared.
Furthermore, no CPU IDs are used at all. The `LR` operation of one CPU generates a reservation (for the
entire address space, since it is global) that is also used by the other CPU. However, only one CPU will
receive a success state for the according `SC` operation, which invalidates the reservation.
This guarantees mutually exclusive access.

.External Reservations
[IMPORTANT]
Note that the reservation-set controller cannot track memory accesses outside
of the NEORV32 processor that are executed by processor-external agents.


:sectnums:
==== Memory Coherence

Depending on the configuration, the NEORV32 processor provides several _layers_ of memory consisting
of caches, buffers and storage.

[start=1]
. The CPU pipeline and its instruction prefetch buffer
. The <<_processor_internal_data_cache_dcache>> and <<_processor_internal_instruction_cache_icache>>
. Internal and external memories

All caches and buffers operate transparently for the software. Hence, special attention must therefore be
paid to maintain memory coherence. Note that coherence and cache _synchronization_ is **not** performed
automatically by the hardware itself as there is no snooping implemented.

NEORV32 uses two instructions for manual memory synchronization which are always available
regardless of the actual CPU/ISA configuration:

* `fence.i` (<<_zifencei_isa_extension>>): flush the CPU's instruction prefetch buffer and
clear the CPU's <<_processor_internal_instruction_cache_icache, instruction cache>>.
* `fence` (<<_i_isa_extension>> / <<_e_isa_extension>>): clear and reload the CPU's
<<_processor_internal_data_cache_dcache, data cache>>. Flushing is not required as the data cache
uses the **write-through** strategy. Hence, write operations are always synchronized with main memory.

.Weak Coherence Model
[IMPORTANT]
The NEORV32-specific implementation of the `fence[.i]` ordering instructions only provides a rather **weak**
coherence model. A core's `fence` just orders all memory accesses towards main memory. Hence, they _can_ become
visible by other agents (the secondary CPU core, the DMA, processor-external modules) if these agents also
synchronize (e.g. reload) their cache(s).

===== Coherence Example

The following C example shows how to declare and use an atomic variable using the`_Atomic` specifier:

.Atomic Variables - C Source Code
[source, c]
----
_Atomic int counter = 0;

counter = 3;
counter++;
----

.Atomic Variables - According RISC-V Assembly Code
[source, assembly]
----
li a3,3
li a4,1

fence rw,w
sw    a3,0(a2)
fence rw,rw

amoadd.w.aqrl zero,a4,(a2)
----

The initial assignment `counter = 0` is translated into a store-word instruction (`sw`) that is
automatically encapsulated within two `fence` instructions. This guarantees memory coherence as each
`fence` will synchronize the CPU's data cache with upstream/main memory.

The counter increment (`counter++`) is implemented as RISC-V atomic memory operation (`amoadd`). However, the
compiler does not encapsulate this in within FENCE instructions. Hence, the altered atomic variable
is **not** updated in the CPU's data cache (but in upstream/main memory).

The above example clearly shows that special attention must be paid to memory coherence when using
atomic memory operations.


<<<
// ####################################################################################################################
:sectnums:
=== Boot Configuration

The NEORV32 processor provides some pre-defined boot configurations to adjust system start-up to
the requirements of the application. The actual boot configuration is defined by the `BOOT_MODE_SELECT`
generic (see <<_processor_top_entity_generics>>).

.NEORV32 Boot Configurations
[cols="^2,^2,^2,<6"]
[options="header",grid="rows"]
|=======================
| `BOOT_MODE_SELECT` | Name           | Boot address | Description
| 0 (default)        | Bootloader     | Base of internal BOOTROM   | Implement the processor-internal <<_bootloader_rom_bootrom>> as pre-initialized ROM and boot from there.
| 1                  | Custom Address | `BOOT_ADDR_CUSTOM` generic | Start booting at user-defined address (`BOOT_ADDR_CUSTOM` top generic).
| 2                  | IMEM Image     | Base of internal IMEM      | Implement the processor-internal <<_instruction_memory_imem>> as pre-initialized ROM and boot from there.
|=======================

.Dual-Core Boot
[TIP]
For the SMPA dual-core CPU configuration boot procedure see section <<_dual_core_boot>>.


:sectnums:
==== Booting via Bootloader

This is the most common and thus, the default boot configuration. When selected, the processor-internal
<<_bootloader_rom_bootrom>> is enabled. This ROM contains the executable image (`rtl/core/neorv32_bootloader_image.vhd`)
of the default NEORV32 <<_bootloader>> that will be executed right after reset. The bootloader provides an interactive
user console for executable upload as well as an automatic boot-configuration targeting external (SPI) memories.

If the processor-internal <<_instruction_memory_imem>> is enabled it will be implemented as _blank_ RAM.


:sectnums:
==== Boot from Custom Address

This is the most flexible boot configuration as it allows the user to specify a custom boot address via the
`BOOT_ADDR_CUSTOM` generic. Note that this address has to be aligned to 4-byte boundary. The processor will
start executing from the defined address right after reset. For example, this boot configuration ca be used to
execute a _custom bootloader_ from a memory that is attached via the <<_processor_external_bus_interface_xbus>>.

The <<_bootloader_rom_bootrom>> is not enabled / implement at all.
If the processor-internal <<_instruction_memory_imem>> is enabled it will be implemented as _blank_ RAM.


:sectnums:
==== Boot IMEM Image

This configuration will implement the <<_instruction_memory_imem>> as _pre-initialized read-only memory_ (ROM).
The ROM is initialized during synthesis with the according application image file (`rtl/core/neorv32_application_image.vhd`).
After reset, the CPU will directly start executing this image. Since the IMEM is implemented as ROM, the executable cannot
be altered at runtime at all.

The <<_bootloader_rom_bootrom>> is not enabled / implement at all.

.Internal IMEM is Required
[IMPORTANT]
This boot configuration requires the IMEM to be enabled (`IMEM_EN` = true).

.Simulation Setup
[TIP]
This boot configuration is handy for simulations as the application software is executed right away without the
need for an explicit initialization / executable upload.


<<<
// ####################################################################################################################
:sectnums:
=== Processor-Internal Modules

.Full-Word Write Accesses Only
[NOTE]
All peripheral/IO devices should only be accessed in full-word mode (i.e. 32-bit).
Byte or half-word (8/16-bit) write accesses might cause undefined behavior.

.IO Module Address Space
[NOTE]
Each peripheral/IO module occupies an address space of 64kB bytes. Most devices do not fully utilize this
address space and will _mirror_ the available memory-mapped registers across the entire 64kB address space.
However, accessing memory-mapped registers other than the specified ones should be avoided.

.Unimplemented Modules / Address Holes
[NOTE]
When accessing an IO device that hast not been implemented (disabled via the according generic)
or when accessing an address that is actually unused, a load/store access fault exception is raised.

.Writing to Read-Only Registers
[NOTE]
Unless otherwise specified, writing to registers that are listed as read-only does not trigger an exception
as the write access is simply ignored by the corresponding hardware module.

.IO Access Latency
[NOTE]
In order to shorten the critical path of the IO system, the IO switch provides register stages for the request and
response buses.Hence, accesses to the processor-internal IO region require two additional clock cycles to complete.

.Module Interrupts
[NOTE]
Several peripheral/IO devices provide some kind of interrupt. These interrupts are mapped to the CPU's
<<_custom_fast_interrupt_request_lines>>. See section <<_processor_interrupts>> for more information.

.CMSIS System Description View (SVD)
[TIP]
A CMSIS-compatible **System View Description (SVD)** file including all peripherals is available in `sw/svd`.

include::soc_imem.adoc[]

include::soc_dmem.adoc[]

include::soc_bootrom.adoc[]

include::soc_icache.adoc[]

include::soc_dcache.adoc[]

include::soc_dma.adoc[]

include::soc_xbus.adoc[]

include::soc_slink.adoc[]

include::soc_gpio.adoc[]

include::soc_wdt.adoc[]

include::soc_clint.adoc[]

include::soc_uart.adoc[]

include::soc_spi.adoc[]

include::soc_sdi.adoc[]

include::soc_twi.adoc[]

include::soc_twd.adoc[]

include::soc_onewire.adoc[]

include::soc_pwm.adoc[]

include::soc_trng.adoc[]

include::soc_cfs.adoc[]

include::soc_neoled.adoc[]

include::soc_gptmr.adoc[]

include::soc_tracer.adoc[]

include::soc_sysinfo.adoc[]
