|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
== NEORV32 Processor (SoC)
|
== NEORV32 Processor (SoC)
|
|
|
The NEORV32 Processor is based on the NEORV32 CPU. Together with common peripheral
|
The NEORV32 Processor is based on the NEORV32 CPU. Together with common peripheral
|
interfaces and embedded memories it provides a RISC-V-based full-scale microcontroller-like SoC platform.
|
interfaces and embedded memories it provides a RISC-V-based full-scale microcontroller-like SoC platform.
|
|
|
image::neorv32_processor.png[align=center]
|
image::neorv32_processor.png[align=center]
|
|
|
**Key Features**
|
**Key Features**
|
|
|
* _optional_ processor-internal data and instruction memories (<<_data_memory_dmem,**DMEM**>>/<<_instruction_memory_imem,**IMEM**>>) + cache (<<_processor_internal_instruction_cache_icache,**iCACHE**>>)
|
* _optional_ processor-internal data and instruction memories (<<_data_memory_dmem,**DMEM**>>/<<_instruction_memory_imem,**IMEM**>>) + cache (<<_processor_internal_instruction_cache_icache,**iCACHE**>>)
|
* _optional_ internal bootloader (<<_bootloader_rom_bootrom,**BOOTROM**>>) with UART console & SPI flash boot option
|
* _optional_ internal bootloader (<<_bootloader_rom_bootrom,**BOOTROM**>>) with UART console & SPI flash boot option
|
* _optional_ machine system timer (<<_machine_system_timer_mtime,**MTIME**>>), RISC-V-compatible
|
* _optional_ machine system timer (<<_machine_system_timer_mtime,**MTIME**>>), RISC-V-compatible
|
* _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_ 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_ 8/16/24/32-bit serial peripheral interface controller (<<_serial_peripheral_interface_controller_spi,**SPI**>>) with 8 dedicated CS lines
|
* _optional_ 8/16/24/32-bit serial peripheral interface controller (<<_serial_peripheral_interface_controller_spi,**SPI**>>) with 8 dedicated CS lines
|
* _optional_ two wire serial interface controller (<<_two_wire_serial_interface_controller_twi,**TWI**>>), compatible to the I²C standard
|
* _optional_ two wire serial interface controller (<<_two_wire_serial_interface_controller_twi,**TWI**>>), compatible to the I²C standard
|
* _optional_ general purpose parallel IO port (<<_general_purpose_input_and_output_port_gpio,**GPIO**>>), 32xOut, 32xIn
|
* _optional_ general purpose parallel IO port (<<_general_purpose_input_and_output_port_gpio,**GPIO**>>), 64xOut, 64xIn
|
* _optional_ 32-bit external bus interface, Wishbone b4 / AXI4-Lite compatible (<<_processor_external_memory_interface_wishbone_axi4_lite,**WISHBONE**>>)
|
* _optional_ 32-bit external bus interface, Wishbone b4 / AXI4-Lite compatible (<<_processor_external_memory_interface_wishbone_axi4_lite,**WISHBONE**>>)
|
|
* _optional_ 32-bit stream link interface with up to 8 independent links, AXI4-Stream compatible (<<_stream_link_interface_slink,**SLINK**>>)
|
* _optional_ watchdog timer (<<_watchdog_timer_wdt,**WDT**>>)
|
* _optional_ watchdog timer (<<_watchdog_timer_wdt,**WDT**>>)
|
* _optional_ PWM controller with up to 60 channels & 8-bit duty cycle resolution (<<_pulse_width_modulation_controller_pwm,**PWM**>>)
|
* _optional_ PWM controller with up to 60 channels & 8-bit duty cycle resolution (<<_pulse_width_modulation_controller_pwm,**PWM**>>)
|
* _optional_ ring-oscillator-based true random number generator (<<_true_random_number_generator_trng,**TRNG**>>)
|
* _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_ custom functions subsystem for custom co-processor extensions (<<_custom_functions_subsystem_cfs,**CFS**>>)
|
* _optional_ numerically-controlled oscillator (<<_numerically_controlled_oscillator_nco,**NCO**>>) with 3 independent channels
|
|
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
|
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
|
|
* _optional_ external interrupt controller with up to 32 channels (<<_external_interrupt_controller_xirq,**XIRQ**>>)
|
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>)
|
* _optional_ on-chip debugger with JTAG TAP (<<_on_chip_debugger_ocd,**OCD**>>)
|
* system configuration information memory to check HW configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)
|
* system configuration information memory to check HW configuration via software (<<_system_configuration_information_memory_sysinfo,**SYSINFO**>>)
|
|
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== Processor Top Entity - Signals
|
=== Processor Top Entity - Signals
|
|
|
The following table shows all interface ports of the processor top entity (`rtl/core/neorv32_top.vhd`).
|
The following table shows all interface ports of the processor top entity (`rtl/core/neorv32_top.vhd`).
|
The type of all signals is _std_ulogic_ or _std_ulogic_vector_, respectively.
|
The type of all signals is _std_ulogic_ or _std_ulogic_vector_, respectively.
|
|
|
[TIP]
|
[TIP]
|
A wrapper for the NEORV32 Processor setup providing resolved port signals can be found in
|
A wrapper for the NEORV32 Processor setup providing resolved port signals can be found in
|
`rtl/top_templates/neorv32_top_stdlogic.vhd`.
|
`rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd`.
|
|
|
[cols="<3,^2,^2,<11"]
|
[cols="<3,^2,^2,<11"]
|
[options="header",grid="rows"]
|
[options="header",grid="rows"]
|
|=======================
|
|=======================
|
| Signal | Width | Dir. | Function
|
| Signal | Width | Dir. | Function
|
4+^| **Global Control**
|
4+^| **Global Control**
|
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
|
| `clk_i` | 1 | in | global clock line, all registers triggering on rising edge
|
| `rstn_i` | 1 | in | global reset, asynchronous, **low-active**
|
| `rstn_i` | 1 | in | global reset, asynchronous, **low-active**
|
4+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
|
4+^| **JTAG Access Port for <<_on_chip_debugger_ocd>>**
|
| `jtag_trst_i` | 1 | in | TAP reset, low-active (optionalfootnote:[Pull high if not used.])
|
| `jtag_trst_i` | 1 | in | TAP reset, low-active (optionalfootnote:[Pull high if not used.])
|
| `jtag_tck_i ` | 1 | in | serial clock
|
| `jtag_tck_i` | 1 | in | serial clock
|
| `jtag_tdi_i ` | 1 | in | serial data input
|
| `jtag_tdi_i` | 1 | in | serial data input
|
| `jtag_tdo_o ` | 1 | out | serial data outputfootnote:[If the on-chip debugger is not implemented (_ON_CHIP_DEBUGGER_EN_ = false) `jtag_tdi_i` is directly forwarded to `jtag_tdo_o` to maintain the JTAG chain.]
|
| `jtag_tdo_o` | 1 | out | serial data outputfootnote:[If the on-chip debugger is not implemented (_ON_CHIP_DEBUGGER_EN_ = false) `jtag_tdi_i` is directly forwarded to `jtag_tdo_o` to maintain the JTAG chain.]
|
| `jtag_tms_i ` | 1 | in | mode select
|
| `jtag_tms_i` | 1 | in | mode select
|
4+^| **External Bus Interface (<<_processor_external_memory_interface_wishbone_axi4_lite,WISHBONE>>)**
|
4+^| **External Bus Interface (<<_processor_external_memory_interface_wishbone_axi4_lite,WISHBONE>>)**
|
| `wb_tag_o` | 3 | out | tag (access type identifier)
|
| `wb_tag_o` | 3 | out | tag (access type identifier)
|
| `wb_adr_o` | 32 | out | destination address
|
| `wb_adr_o` | 32 | out | destination address
|
| `wb_dat_i` | 32 | in | write data
|
| `wb_dat_i` | 32 | in | write data
|
| `wb_dat_o` | 32 | out | read data
|
| `wb_dat_o` | 32 | out | read data
|
| `wb_we_o` | 1 | out | write enable ('0' = read transfer)
|
| `wb_we_o` | 1 | out | write enable ('0' = read transfer)
|
| `wb_sel_o` | 4 | out | byte enable
|
| `wb_sel_o` | 4 | out | byte enable
|
| `wb_stb_o` | 1 | out | strobe
|
| `wb_stb_o` | 1 | out | strobe
|
| `wb_cyc_o` | 1 | out | valid cycle
|
| `wb_cyc_o` | 1 | out | valid cycle
|
| `wb_lock_o`| 1 | out | exclusive access request
|
| `wb_lock_o`| 1 | out | exclusive access request
|
| `wb_ack_i` | 1 | in | transfer acknowledge
|
| `wb_ack_i` | 1 | in | transfer acknowledge
|
| `wb_err_i` | 1 | in | transfer error
|
| `wb_err_i` | 1 | in | transfer error
|
4+^| **Advanced Memory Control Signals**
|
4+^| **Advanced Memory Control Signals**
|
| `fence_o` | 1 | out | indicates an executed _fence_ instruction
|
| `fence_o` | 1 | out | indicates an executed _fence_ instruction
|
| `fencei_o` | 1 | out | indicates an executed _fencei_ instruction
|
| `fencei_o` | 1 | out | indicates an executed _fencei_ instruction
|
|
4+^| **Stream Link Interface (<<_stream_link_interface_slink,SLINK>>)**
|
|
| `slink_tx_dat_o` | 8x32 | out | TX link _n_ data
|
|
| `slink_tx_val_o` | 8 | out | TX link _n_ data valid
|
|
| `slink_tx_rdy_i` | 8 | in | TX link _n_ allowed to send
|
|
| `slink_rx_dat_i` | 8x32 | in | RX link _n_ data
|
|
| `slink_rx_val_i` | 8 | in | RX link _n_ data valid
|
|
| `slink_rx_rdy_o` | 8 | out | RX link _n_ ready to receive
|
4+^| **General Purpose Inputs & Outputs (<<_general_purpose_input_and_output_port_gpio,GPIO>>)**
|
4+^| **General Purpose Inputs & Outputs (<<_general_purpose_input_and_output_port_gpio,GPIO>>)**
|
| `gpio_o` | 32 | out | general purpose parallel output
|
| `gpio_o` | 64 | out | general purpose parallel output
|
| `gpio_i` | 32 | in | general purpose parallel input
|
| `gpio_i` | 64 | in | general purpose parallel input
|
4+^| **Primary Universal Asynchronous Receiver/Transmitter (<<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>>)**
|
4+^| **Primary Universal Asynchronous Receiver/Transmitter (<<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>>)**
|
| `uart0_txd_o` | 1 | out | UART0 serial transmitter
|
| `uart0_txd_o` | 1 | out | UART0 serial transmitter
|
| `uart0_rxd_i` | 1 | in | UART0 serial receiver
|
| `uart0_rxd_i` | 1 | in | UART0 serial receiver
|
| `uart0_rts_o` | 1 | out | UART0 RX ready to receive new char
|
| `uart0_rts_o` | 1 | out | UART0 RX ready to receive new char
|
| `uart0_cts_i` | 1 | in | UART0 TX allowed to start sending
|
| `uart0_cts_i` | 1 | in | UART0 TX allowed to start sending
|
4+^| **Primary Universal Asynchronous Receiver/Transmitter (<<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>>)**
|
4+^| **Primary Universal Asynchronous Receiver/Transmitter (<<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>>)**
|
| `uart1_txd_o` | 1 | out | UART1 serial transmitter
|
| `uart1_txd_o` | 1 | out | UART1 serial transmitter
|
| `uart1_rxd_i` | 1 | in | UART1 serial receiver
|
| `uart1_rxd_i` | 1 | in | UART1 serial receiver
|
| `uart1_rts_o` | 1 | out | UART1 RX ready to receive new char
|
| `uart1_rts_o` | 1 | out | UART1 RX ready to receive new char
|
| `uart1_cts_i` | 1 | in | UART1 TX allowed to start sending
|
| `uart1_cts_i` | 1 | in | UART1 TX allowed to start sending
|
4+^| **Serial Peripheral Interface Controller (<<_serial_peripheral_interface_controller_spi,SPI>>)**
|
4+^| **Serial Peripheral Interface Controller (<<_serial_peripheral_interface_controller_spi,SPI>>)**
|
| `spi_sck_o` | 1 | out | SPI controller clock line
|
| `spi_sck_o` | 1 | out | SPI controller clock line
|
| `spi_sdo_o` | 1 | out | SPI serial data output
|
| `spi_sdo_o` | 1 | out | SPI serial data output
|
| `spi_sdi_i` | 1 | in | SPI serial data input
|
| `spi_sdi_i` | 1 | in | SPI serial data input
|
| `spi_csn_o` | 8 | out | SPI dedicated chip select (low-active)
|
| `spi_csn_o` | 8 | out | SPI dedicated chip select (low-active)
|
4+^| **Two-Wire Interface Controller (<<_two_wire_serial_interface_controller_twi,TWI>>)**
|
4+^| **Two-Wire Interface Controller (<<_two_wire_serial_interface_controller_twi,TWI>>)**
|
| `twi_sda_io` | 1 | inout | TWI serial data line
|
| `twi_sda_io` | 1 | inout | TWI serial data line
|
| `twi_scl_io` | 1 | inout | TWI serial clock line
|
| `twi_scl_io` | 1 | inout | TWI serial clock line
|
4+^| **Custom Functions Subsystem (<<_custom_functions_subsystem_cfs,CFS>>)**
|
4+^| **Custom Functions Subsystem (<<_custom_functions_subsystem_cfs,CFS>>)**
|
| `cfs_in_i` | 32 | in | custom CFS input signal conduit
|
| `cfs_in_i` | 32 | in | custom CFS input signal conduit
|
| `cfs_out_o` | 32 | out | custom CFS output signal conduit
|
| `cfs_out_o` | 32 | out | custom CFS output signal conduit
|
4+^| **Pulse-Width Modulation Channels (<<_pulse_width_modulation_controller_pwm,PWM>>)**
|
4+^| **Pulse-Width Modulation Channels (<<_pulse_width_modulation_controller_pwm,PWM>>)**
|
| `pwm_o` | 4 | out | pulse-width modulated channels
|
| `pwm_o` | 4 | out | pulse-width modulated channels
|
4+^| **Numerically-Controller Oscillator (<<_numerically_controlled_oscillator_nco,NCO>>)**
|
|
| `nco_o` | 3 | out | NCO output channels
|
|
4+^| **Smart LED Interface - NeoPixel(TM) compatible (<<_smart_led_interface_neoled,NEOLED>>)**
|
4+^| **Smart LED Interface - NeoPixel(TM) compatible (<<_smart_led_interface_neoled,NEOLED>>)**
|
| `neoled_o` | 1 | out | asynchronous serial data output
|
| `neoled_o` | 1 | out | asynchronous serial data output
|
4+^| **System time (<<_machine_system_timer_mtime,MTIME>>)**
|
4+^| **System time (<<_machine_system_timer_mtime,MTIME>>)**
|
| `mtime_i` | 64 | in | machine timer time (to `time[h]` CSRs) from _external MTIME_ unit if the processor-internal _MTIME_ unit is NOT implemented
|
| `mtime_i` | 64 | in | machine timer time (to `time[h]` CSRs) from _external MTIME_ unit if the processor-internal _MTIME_ unit is NOT implemented
|
| `mtime_o` | 64 | out | machine timer time from _internal MTIME_ unit if processor-internal _MTIME_ unit IS implemented
|
| `mtime_o` | 64 | out | machine timer time from _internal MTIME_ unit if processor-internal _MTIME_ unit IS implemented
|
4+^| **<<_processor_interrupts>>**
|
4+^| **<<_processor_interrupts, External Interrupts>>**
|
|
| `xirq_i` | 32 | in | external interrupt requests (up to 32 channels)
|
|
4+^| **<<_processor_interrupts, CPU Interrupts>>**
|
| `nm_irq_i` | 1 | in | non-maskable interrupt
|
| `nm_irq_i` | 1 | in | non-maskable interrupt
|
| `soc_firq_i` | 6 | in | platform fast interrupt channels (custom)
|
|
| `mtime_irq_i` | 1 | in | machine timer interrupt13 (RISC-V)
|
| `mtime_irq_i` | 1 | in | machine timer interrupt13 (RISC-V)
|
| `msw_irq_i` | 1 | in | machine software interrupt (RISC-V)
|
| `msw_irq_i` | 1 | in | machine software interrupt (RISC-V)
|
| `mext_irq_i` | 1 | in | machine external interrupt (RISC-V)
|
| `mext_irq_i` | 1 | in | machine external interrupt (RISC-V)
|
|=======================
|
|=======================
|
|
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== Processor Top Entity - Generics
|
=== Processor Top Entity - Generics
|
|
|
This is a list of all configuration generics of the NEORV32 processor top entity rtl/neorv32_top.vhd.
|
This is a list of all configuration generics of the NEORV32 processor top entity rtl/neorv32_top.vhd.
|
The generic name is shown in orange, followed by the type in printed in black and concluded by the default
|
The generic name is shown in orange, followed by the type in printed in black and concluded by the default
|
value printed in light gray.
|
value printed in light gray.
|
|
|
[TIP]
|
[TIP]
|
The NEORV32 generics allow to configure the system according to your needs. The generics are
|
The NEORV32 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
|
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.
|
optimize the system for certain design goals like minimal area or maximum performance.
|
|
|
[TIP]
|
[TIP]
|
Privileged software can determine the actual CPU and processor configuration via the `misa` and
|
Privileged software can determine the actual CPU and processor configuration via the `misa` and
|
`mzext` (see <<_machine_trap_setup>> and <<_neorv32_specific_custom_csrs>>) CSRs and via the memory-mapped _SYSINFO_ module (see <<_system_configuration_information_memory_sysinfo>>),
|
`mzext` (see <<_machine_trap_setup>> and <<_neorv32_specific_custom_csrs>>) CSRs and via the memory-mapped _SYSINFO_ module (see <<_system_configuration_information_memory_sysinfo>>),
|
respectively.
|
respectively.
|
|
|
[TIP]
|
[TIP]
|
If optional modules (like CPU extensions or peripheral devices) are *not enabled* the according circuitry **will not be synthesized at all**.
|
If optional modules (like CPU extensions or peripheral devices) are *not enabled* the according circuitry **will not be synthesized at all**.
|
Hence, the disabled modules do not increase area and power requirements and do not impact the timing.
|
Hence, the disabled modules do not increase area and power requirements and do not impact the timing.
|
|
|
**CSR Description**
|
[TIP]
|
|
Not all configuration combinations are valid. The processor RTL code provides sanity checks to inform the user
|
|
during synthesis/simulation if an invalid combination has been detected.
|
|
|
|
**Generic Description**
|
|
|
The description of each CSR provides the following summary:
|
The description of each generic provides the following summary:
|
|
|
.Generic description
|
.Generic description
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| _Generic_ | _type_ | _default value_
|
| _Generic name_ | _type_ | _default value_
|
3+| _Description_
|
3+| _Description_
|
|======
|
|======
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== General
|
==== General
|
|
|
See section <<_system_configuration_information_memory_sysinfo>> for more information.
|
See section <<_system_configuration_information_memory_sysinfo>> for more information.
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CLOCK_FREQUENCY_
|
===== _CLOCK_FREQUENCY_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CLOCK_FREQUENCY** | _natural_ | 0
|
| **CLOCK_FREQUENCY** | _natural_ | 0
|
3+| The clock frequency of the processor's `clk_i` input port in Hertz (Hz).
|
3+| The clock frequency of the processor's `clk_i` input port in Hertz (Hz).
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _BOOTLOADER_EN_
|
===== _INT_BOOTLOADER_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **BOOTLOADER_EN** | _boolean_ | true
|
| **INT_BOOTLOADER_EN** | _boolean_ | true
|
3+| Implement the boot ROM, pre-initialized with the bootloader image when true. This will also change the
|
3+| Implement the processor-internal boot ROM, pre-initialized with the default bootloader image when _true_.
|
processor's boot address from the beginning of the instruction memory address space (default =
|
This will also change the processor's boot address from the beginning of the instruction memory address space (default =
|
0x00000000) to the base address of the boot ROM. See section <<_bootloader>> for more information.
|
0x00000000) to the base address of the boot ROM. See section <<_boot_configuration>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _USER_CODE_
|
===== _USER_CODE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **USER_CODE** | _std_ulogic_vector(31 downto 0)_ | x"00000000"
|
| **USER_CODE** | _std_ulogic_vector(31 downto 0)_ | x"00000000"
|
3+| Custom user code that can be read by software via the _SYSINFO_ module.
|
3+| Custom user code that can be read by software via the _SYSINFO_ module.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _HW_THREAD_ID_
|
===== _HW_THREAD_ID_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **HW_THREAD_ID** | _natural_ | 0
|
| **HW_THREAD_ID** | _natural_ | 0
|
3+| The hart ID of the CPU. Can be read via the `mhartid` CSR. Hart IDs must be unique within a system.
|
3+| The hart ID of the CPU. Can be read via the `mhartid` CSR. Hart IDs must be unique within a system.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _ON_CHIP_DEBUGGER_EN_
|
===== _ON_CHIP_DEBUGGER_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **ON_CHIP_DEBUGGER_EN** | _boolean_ | false
|
| **ON_CHIP_DEBUGGER_EN** | _boolean_ | false
|
3+| Implement on-chip debugger (OCD). See chapter <<_on_chip_debugger_ocd>>.
|
3+| Implement on-chip debugger (OCD). See chapter <<_on_chip_debugger_ocd>>.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== RISC-V CPU Extensions
|
==== RISC-V CPU Extensions
|
|
|
See section <<_instruction_sets_and_extensions>> for more information.
|
See section <<_instruction_sets_and_extensions>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_A_
|
===== _CPU_EXTENSION_RISCV_A_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_A** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_A** | _boolean_ | false
|
3+| Implement atomic memory access operations when _true_.
|
3+| Implement atomic memory access operations when _true_.
|
|
See section <<_a_atomic_memory_access>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_C_
|
===== _CPU_EXTENSION_RISCV_C_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_C** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_C** | _boolean_ | false
|
3+| Implement compressed instructions (16-bit) when _true_.
|
3+| Implement compressed instructions (16-bit) when _true_.
|
|
See section <<_c_compressed_instructions>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_E_
|
===== _CPU_EXTENSION_RISCV_E_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_E** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_E** | _boolean_ | false
|
3+| Implement the embedded CPU extension (only implement the first 16 data registers) when _true_.
|
3+| Implement the embedded CPU extension (only implement the first 16 data registers) when _true_.
|
|
See section <<_e_embedded_cpu>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_M_
|
===== _CPU_EXTENSION_RISCV_M_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_M** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_M** | _boolean_ | false
|
3+| Implement integer multiplication and division instructions when _true_.
|
3+| Implement integer multiplication and division instructions when _true_.
|
|
See section <<_m_integer_multiplication_and_division>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_U_
|
===== _CPU_EXTENSION_RISCV_U_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_U** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_U** | _boolean_ | false
|
3+| Implement less-privileged user mode when _true_.
|
3+| Implement less-privileged user mode when _true_.
|
|
See section <<_u_less_privileged_user_mode>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_Zfinx_
|
===== _CPU_EXTENSION_RISCV_Zfinx_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_Zfinx** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_Zfinx** | _boolean_ | false
|
3+| Implement the 32-bit single-precision floating-point extension (using integer registers) when _true_. For
|
3+| Implement the 32-bit single-precision floating-point extension (using integer registers) when _true_.
|
more information see section <<_zfinx_single_precision_floating_point_operations>>.
|
See section <<_zfinx_single_precision_floating_point_operations>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_Zicsr_
|
===== _CPU_EXTENSION_RISCV_Zicsr_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_Zicsr** | _boolean_ | true
|
| **CPU_EXTENSION_RISCV_Zicsr** | _boolean_ | true
|
3+| Implement the control and status register (CSR) access instructions when true. Note: When this option is
|
3+| Implement the control and status register (CSR) access instructions when true. Note: When this option is
|
disabled, the complete privileged architecture / trap system will be excluded from synthesis. Hence, no interrupts, no exceptions and
|
disabled, the complete privileged architecture / trap system will be excluded from synthesis. Hence, no interrupts, no exceptions and
|
no machine information will be available.
|
no machine information will be available.
|
|
See section <<_zicsr_control_and_status_register_access_privileged_architecture>>.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_EXTENSION_RISCV_Zifencei_
|
===== _CPU_EXTENSION_RISCV_Zifencei_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_EXTENSION_RISCV_Zifencei** | _boolean_ | false
|
| **CPU_EXTENSION_RISCV_Zifencei** | _boolean_ | false
|
3+| Implement the instruction fetch synchronization instruction _fence.i_. For example, this option is required
|
3+| Implement the instruction fetch synchronization instruction `fence.i`. For example, this option is required
|
for self-modifying code (and/or for i-cache flushes).
|
for self-modifying code (and/or for i-cache flushes).
|
|
See section <<_zifencei_instruction_stream_synchronization>>.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _CPU_EXTENSION_RISCV_Zmmul_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **CPU_EXTENSION_RISCV_Zmmul** | _boolean_ | false
|
|
3+| Implement integer multiplication-only instructions when _true_. This is a sub-extensions of the `M` extension.
|
|
See section <<_zmmul_integer_multiplication>>.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Extension Options
|
==== Extension Options
|
|
|
See section <<_instruction_sets_and_extensions>> for more information.
|
See section <<_instruction_sets_and_extensions>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _FAST_MUL_EN_
|
===== _FAST_MUL_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **FAST_MUL_EN** | _boolean_ | false
|
| **FAST_MUL_EN** | _boolean_ | false
|
3+| When this generic is enabled, the multiplier of the `M` extension is realized using DSPs blocks instead of an
|
3+| When this generic is enabled, the multiplier of the `M` extension is realized using DSPs blocks instead of an
|
iterative bit-serial approach. This generic is only relevant when the multiplier and divider CPU extension is
|
iterative bit-serial approach. This generic is only relevant when the multiplier and divider CPU extension is
|
enabled (<<_cpu_extension_riscv_m>> is _true_).
|
enabled (<<_cpu_extension_riscv_m>> is _true_).
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _FAST_SHIFT_EN_
|
===== _FAST_SHIFT_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **FAST_SHIFT_EN** | _boolean_ | false
|
| **FAST_SHIFT_EN** | _boolean_ | false
|
3+| When this generic is enabled the shifter unit of the CPU's ALU is implement as fast barrel shifter (requiring
|
3+| When this generic is set _true_ the shifter unit of the CPU's ALU is implemented as fast barrel shifter (requiring
|
more hardware resources).
|
more hardware resources). If it is set _false_ the CPU uses a serial shifter that only performs a single bit shift per cycle
|
|======
|
(small but slow).
|
|
|
|
|
:sectnums!:
|
|
===== _TINY_SHIFT_EN_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **TINY_SHIFT_EN** | _boolean_ | false
|
|
3+| If this generic is enabled the shifter unit of the CPU's ALU is implemented as (slow but tiny) single-bit iterative shifter
|
|
(requires up to 32 clock cycles for a shift operations, but reducing hardware footprint). The configuration of
|
|
this generic is ignored if <<_fast_shift_en>> is _true_.
|
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _CPU_CNT_WIDTH_
|
===== _CPU_CNT_WIDTH_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **CPU_CNT_WIDTH** | _natural_ | 0
|
| **CPU_CNT_WIDTH** | _natural_ | 0
|
3+| This generic configures the total size of the CPU's `cycle` and `instret` CSRs (low word + high word).
|
3+| This generic configures the total size of the CPU's `cycle` and `instret` CSRs (low word + high word).
|
The maximum value is 64, the minimal is 0. See
|
The maximum value is 64, the minimal is 0. See
|
section <<_machine_counters_and_timers>> for more information. Note: Configurations with <<_cpu_cnt_width>>
|
section <<_machine_counters_and_timers>> for more information. Note: Configurations with <<_cpu_cnt_width>>
|
less than 64 are not RISC-V compliant.
|
less than 64 are not RISC-V compliant.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Physical Memory Protection (PMP)
|
==== Physical Memory Protection (PMP)
|
|
|
See section <<_pmp_physical_memory_protection>> for more information.
|
See section <<_pmp_physical_memory_protection>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _PMP_NUM_REGIONS_
|
===== _PMP_NUM_REGIONS_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **PMP_NUM_REGIONS** | _natural_ | 0
|
| **PMP_NUM_REGIONS** | _natural_ | 0
|
3+| Total number of implemented protections regions (0..64). If this generics is zero no physical memory
|
3+| Total number of implemented protections regions (0..64). If this generics is zero no physical memory
|
protection logic will be implemented at all. Setting <<_pmp_num_regions>>_ > 0 will set the _CSR_MZEXT_PMP_ flag
|
protection logic will be implemented at all. Setting <<_pmp_num_regions>>_ > 0 will set the _CSR_MZEXT_PMP_ flag
|
in the <<_mzext>> CSR.
|
in the <<_mzext>> CSR.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _PMP_MIN_GRANULARITY_
|
===== _PMP_MIN_GRANULARITY_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **PMP_MIN_GRANULARITY** | _natural_ | 64*1024
|
| **PMP_MIN_GRANULARITY** | _natural_ | 64*1024
|
3+| Minimal region granularity in bytes. Has to be a power of two. Has to be at least 8 bytes.
|
3+| Minimal region granularity in bytes. Has to be a power of two. Has to be at least 8 bytes.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Hardware Performance Monitors (HPM)
|
==== Hardware Performance Monitors (HPM)
|
|
|
See section <<_hpm_hardware_performance_monitors>> for more information.
|
See section <<_hpm_hardware_performance_monitors>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _HPM_NUM_CNTS_
|
===== _HPM_NUM_CNTS_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **HPM_NUM_CNTS** | _natural_ | 0
|
| **HPM_NUM_CNTS** | _natural_ | 0
|
3+| Total number of implemented hardware performance monitor counters (0..29). If this generics is zero no
|
3+| Total number of implemented hardware performance monitor counters (0..29). If this generics is zero no
|
hardware performance monitor logic will be implemented at all. Setting <<_hpm_num_cnts>> > 0 will set the _CSR_MZEXT_HPM_ flag
|
hardware performance monitor logic will be implemented at all. Setting <<_hpm_num_cnts>> > 0 will set the _CSR_MZEXT_HPM_ flag
|
in the <<_mzext>> CSR.
|
in the <<_mzext>> CSR.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _HPM_CNT_WIDTH_
|
===== _HPM_CNT_WIDTH_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **HPM_CNT_WIDTH** | _natural_ | 40
|
| **HPM_CNT_WIDTH** | _natural_ | 40
|
3+| This generic defines the total LSB-aligned size of each HPM counter (size(`[m]hpmcounter*h`) +
|
3+| This generic defines the total LSB-aligned size of each HPM counter (size(`[m]hpmcounter*h`) +
|
size(`[m]hpmcounter*`)). The maximum value is 64, the minimal is 0. If the size is less than 64-bit, the
|
size(`[m]hpmcounter*`)). The maximum value is 64, the minimal is 0. If the size is less than 64-bit, the
|
unused MSB-aligned counter bits are hardwired to zero.
|
unused MSB-aligned counter bits are hardwired to zero.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Internal Instruction Memory
|
==== Internal Instruction Memory
|
|
|
See sections <<_address_space>> and <<_instruction_memory_imem>> for more information.
|
See sections <<_address_space>> and <<_instruction_memory_imem>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_INT_IMEM_EN_
|
===== _MEM_INT_IMEM_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_INT_IMEM_EN** | _boolean_ | true
|
| **MEM_INT_IMEM_EN** | _boolean_ | true
|
3+| Implement processor internal instruction memory (IMEM) when _true_.
|
3+| Implement processor internal instruction memory (IMEM) when _true_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_INT_IMEM_SIZE_
|
===== _MEM_INT_IMEM_SIZE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_INT_IMEM_SIZE** | _natural_ | 16*1024
|
| **MEM_INT_IMEM_SIZE** | _natural_ | 16*1024
|
3+| Size in bytes of the processor internal instruction memory (IMEM). Has no effect when _MEM_INT_IMEM_EN_ is _false_.
|
3+| Size in bytes of the processor internal instruction memory (IMEM). Has no effect when _MEM_INT_IMEM_EN_ is _false_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
|
===== _MEM_INT_IMEM_ROM_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **MEM_INT_IMEM_ROM** | _boolean_ | false
|
|
3+| Implement processor-internal instruction memory as read-only memory, which will be initialized with the
|
|
application image at synthesis time. Has no effect when _MEM_INT_IMEM_EN_ is _false_.
|
|
|======
|
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Internal Data Memory
|
==== Internal Data Memory
|
|
|
See sections <<_address_space>> and <<_data_memory_dmem>> for more information.
|
See sections <<_address_space>> and <<_data_memory_dmem>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_INT_DMEM_EN_
|
===== _MEM_INT_DMEM_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_INT_DMEM_EN** | _boolean_ | true
|
| **MEM_INT_DMEM_EN** | _boolean_ | true
|
3+| Implement processor internal data memory (DMEM) when _true_.
|
3+| Implement processor internal data memory (DMEM) when _true_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_INT_DMEM_SIZE_
|
===== _MEM_INT_DMEM_SIZE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_INT_DMEM_SIZE** | _natural_ | 8*1024
|
| **MEM_INT_DMEM_SIZE** | _natural_ | 8*1024
|
3+| Size in bytes of the processor-internal data memory (DMEM). Has no effect when _MEM_INT_DMEM_EN_ is _false_.
|
3+| Size in bytes of the processor-internal data memory (DMEM). Has no effect when _MEM_INT_DMEM_EN_ is _false_.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== Internal Cache Memory
|
==== Internal Cache Memory
|
|
|
See section <<_processor_internal_instruction_cache_icache>> for more information.
|
See section <<_processor_internal_instruction_cache_icache>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _ICACHE_EN_
|
===== _ICACHE_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **ICACHE_EN** | _boolean_ | false
|
| **ICACHE_EN** | _boolean_ | false
|
3+| Implement processor internal instruction cache when _true_.
|
3+| Implement processor internal instruction cache when _true_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _ICACHE_NUM_BLOCK_
|
===== _ICACHE_NUM_BLOCK_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **ICACHE_NUM_BLOCKS** | _natural_ | 4
|
| **ICACHE_NUM_BLOCKS** | _natural_ | 4
|
3+| Number of blocks (cache "pages" or "lines") in the instruction cache. Has to be a power of two. Has no
|
3+| Number of blocks (cache "pages" or "lines") in the instruction cache. Has to be a power of two. Has no
|
effect when _ICACHE_DMEM_EN_ is false.
|
effect when _ICACHE_DMEM_EN_ is false.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _ICACHE_BLOCK_SIZE_
|
===== _ICACHE_BLOCK_SIZE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **ICACHE_BLOCK_SIZE** | _natural_ | 64
|
| **ICACHE_BLOCK_SIZE** | _natural_ | 64
|
3+| Size in bytes of each block in the instruction cache. Has to be a power of two. Has no effect when
|
3+| Size in bytes of each block in the instruction cache. Has to be a power of two. Has no effect when
|
_ICACHE_EN_ is _false_.
|
_ICACHE_EN_ is _false_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _ICACHE_ASSOCIATIVITY_
|
===== _ICACHE_ASSOCIATIVITY_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **ICACHE_ASSOCIATIVITY** | _natural_ | 1
|
| **ICACHE_ASSOCIATIVITY** | _natural_ | 1
|
3+| Associativity (= number of sets) of the instruction cache. Has to be a power of two. Allowed configurations:
|
3+| Associativity (= number of sets) of the instruction cache. Has to be a power of two. Allowed configurations:
|
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when _ICACHE_EN_ is _false_.
|
`1` = 1 set, direct mapped; `2` = 2-way set-associative. Has no effect when _ICACHE_EN_ is _false_.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
==== External Memory Interface
|
==== External Memory Interface
|
|
|
See sections <<_address_space>> and <<_processor_external_memory_interface_wishbone_axi4_lite>> for more information.
|
See sections <<_address_space>> and <<_processor_external_memory_interface_wishbone_axi4_lite>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_EXT_EN_
|
===== _MEM_EXT_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_EXT_EN** | _boolean_ | false
|
| **MEM_EXT_EN** | _boolean_ | false
|
3+| Implement external bus interface (WISHBONE) when _true_.
|
3+| Implement external bus interface (WISHBONE) when _true_.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _MEM_EXT_TIMEOUT_
|
===== _MEM_EXT_TIMEOUT_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **MEM_EXT_TIMEOUT** | _natural_ | 255
|
| **MEM_EXT_TIMEOUT** | _natural_ | 255
|
3+| Clock cycles after which a pending external bus access will auto-terminate and raise a bus fault exception. Set to 0 to disable auto-timeout.
|
3+| Clock cycles after which a pending external bus access will auto-terminate and raise a bus fault exception. Set to 0 to disable auto-timeout.
|
|======
|
|======
|
|
|
|
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
|
==== Stream Link Interface
|
|
|
|
See section <<_stream_link_interface_slink>> for more information.
|
|
|
|
|
|
:sectnums!:
|
|
===== _SLINK_NUM_TX_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **SLINK_NUM_TX** | _natural_ | 0
|
|
3+| Number of TX (send) links to implement. Valid values are 0..8.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _SLINK_NUM_RX_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **SLINK_NUM_RX** | _natural_ | 0
|
|
3+| Number of RX (receive) links to implement. Valid values are 0..8.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _SLINK_TX_FIFO_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **SLINK_TX_FIFO** | _natural_ | 1
|
|
3+| Internal FIFO depth for _all_ implemented TX links. Valid values are 1..32k and have to be a power of two.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _SLINK_RX_FIFO_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **SLINK_RX_FIFO** | _natural_ | 1
|
|
3+| Internal FIFO depth for _all_ implemented RX links. Valid values are 1..32k and have to be a power of two.
|
|
|======
|
|
|
|
|
|
// ####################################################################################################################
|
|
:sectnums:
|
|
==== External Interrupt Controller
|
|
|
|
See section <<_external_interrupt_controller_xirq>> for more information.
|
|
|
|
|
|
:sectnums!:
|
|
===== _XIRQ_NUM_CH_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **XIRQ_NUM_CH** | _natural_ | 0
|
|
3+| Number of external interrupt channels o implement. Valid values are 0..32.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _XIRQ_TRIGGER_TYPE_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **XIRQ_TRIGGER_TYPE** | _std_ulogic_vector(31 downto 0)_ | 0xFFFFFFFF
|
|
3+| Interrupt trigger type configuration (one bit for each IRQ channel): `0` = level-triggered, '1' = edge triggered.
|
|
_XIRQ_TRIGGER_POLARITY_ generic is used to specify the actual level (high/low) or edge (falling/rising).
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _XIRQ_TRIGGER_POLARITY_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **XIRQ_TRIGGER_POLARITY** | _std_ulogic_vector(31 downto 0)_ | 0xFFFFFFFF
|
|
3+| Interrupt trigger polarity configuration (one bit for each IRQ channel): `0` = low-level/falling-edge,
|
|
'1' = high-level/rising-edge. _XIRQ_TRIGGER_TYPE_ generic is used to specify the actual type (level or edge).
|
|
|======
|
|
|
|
|
|
// ####################################################################################################################
|
|
:sectnums:
|
==== Processor Peripheral/IO Modules
|
==== Processor Peripheral/IO Modules
|
|
|
See section <<_processor_internal_modules>> for more information.
|
See section <<_processor_internal_modules>> for more information.
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_GPIO_EN_
|
===== _IO_GPIO_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_GPIO_EN** | _boolean_ | true
|
| **IO_GPIO_EN** | _boolean_ | true
|
3+| Implement general purpose input/output port unit (GPIO) when _true_.
|
3+| Implement general purpose input/output port unit (GPIO) when _true_.
|
See section <<_general_purpose_input_and_output_port_gpio>> for more information.
|
See section <<_general_purpose_input_and_output_port_gpio>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_MTIME_EN_
|
===== _IO_MTIME_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_MTIME_EN** | _boolean_ | true
|
| **IO_MTIME_EN** | _boolean_ | true
|
3+| Implement machine system timer (MTIME) when _true_.
|
3+| Implement machine system timer (MTIME) when _true_.
|
See section <<_machine_system_timer_mtime>> for more information.
|
See section <<_machine_system_timer_mtime>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_UART0_EN_
|
===== _IO_UART0_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_UART0_EN** | _boolean_ | true
|
| **IO_UART0_EN** | _boolean_ | true
|
3+| Implement primary universal asynchronous receiver/transmitter (UART0) when _true_.
|
3+| Implement primary universal asynchronous receiver/transmitter (UART0) when _true_.
|
See section <<_primary_universal_asynchronous_receiver_and_transmitter_uart0>> for
|
See section <<_primary_universal_asynchronous_receiver_and_transmitter_uart0>> for
|
more information.
|
more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_UART1_EN_
|
===== _IO_UART1_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_UART1_EN** | _boolean_ | true
|
| **IO_UART1_EN** | _boolean_ | true
|
3+| Implement secondary universal asynchronous receiver/transmitter (UART1) when _true_.
|
3+| Implement secondary universal asynchronous receiver/transmitter (UART1) when _true_.
|
See section <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1>> for more information.
|
See section <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_SPI_EN_
|
===== _IO_SPI_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_SPI_EN** | _boolean_ | true
|
| **IO_SPI_EN** | _boolean_ | true
|
3+| Implement serial peripheral interface controller (SPI) when _true_.
|
3+| Implement serial peripheral interface controller (SPI) when _true_.
|
See section <<_serial_peripheral_interface_controller_spi>> for more information.
|
See section <<_serial_peripheral_interface_controller_spi>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_TWI_EN_
|
===== _IO_TWI_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_TWI_EN** | _boolean_ | true
|
| **IO_TWI_EN** | _boolean_ | true
|
3+| Implement two-wire interface controller (TWI) when _true_.
|
3+| Implement two-wire interface controller (TWI) when _true_.
|
See section <<_two_wire_serial_interface_controller_twi>> for
|
See section <<_two_wire_serial_interface_controller_twi>> for
|
more information.
|
more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_PWM_NUM_CH_
|
===== _IO_PWM_NUM_CH_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_PWM_NUM_CH** | _natural_ | 4
|
| **IO_PWM_NUM_CH** | _natural_ | 4
|
3+| Number of pulse-width modulation (PWM) channels (0..60) to implement. The PWM controller is _not_ implemented if zero.
|
3+| Number of pulse-width modulation (PWM) channels (0..60) to implement. The PWM controller is _not_ implemented if zero.
|
See section <<_pulse_width_modulation_controller_pwm>> for more information.
|
See section <<_pulse_width_modulation_controller_pwm>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_WDT_EN_
|
===== _IO_WDT_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_WDT_EN** | _boolean_ | true
|
| **IO_WDT_EN** | _boolean_ | true
|
3+| Implement watchdog timer (WDT) when _true_. See section <<_watchdog_timer_wdt>> for more
|
3+| Implement watchdog timer (WDT) when _true_. See section <<_watchdog_timer_wdt>> for more
|
information.
|
information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_TRNG_EN_
|
===== _IO_TRNG_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_TRNG_EN** | _boolean_ | false
|
| **IO_TRNG_EN** | _boolean_ | false
|
3+| Implement true-random number generator (TRNG) when _true_. See section <<_true_random_number_generator_trng>> for more information.
|
3+| Implement true-random number generator (TRNG) when _true_. See section <<_true_random_number_generator_trng>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_CFS_EN_
|
===== _IO_CFS_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_CFS_EN** | _boolean_ | false
|
| **IO_CFS_EN** | _boolean_ | false
|
3+| Implement custom functions subsystem (CFS) when _true_. See section <<_custom_functions_subsystem_cfs>> for more information.
|
3+| Implement custom functions subsystem (CFS) when _true_. See section <<_custom_functions_subsystem_cfs>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_CFS_CONFIG_
|
===== _IO_CFS_CONFIG_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_CFS_CONFIG** | _std_ulogic_vector(31 downto 0)_ | 0x"00000000"
|
| **IO_CFS_CONFIG** | _std_ulogic_vector(31 downto 0)_ | 0x"00000000"
|
3+| This is a "conduit" generic that can be used to pass user-defined CFS implementation flags to the custom
|
3+| This is a "conduit" generic that can be used to pass user-defined CFS implementation flags to the custom
|
functions subsystem entity. See section <<_custom_functions_subsystem_cfs>> for more information.
|
functions subsystem entity. See section <<_custom_functions_subsystem_cfs>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_CFS_IN_SIZE_
|
===== _IO_CFS_IN_SIZE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_CFS_IN_SIZE** | _positive_ | 32
|
| **IO_CFS_IN_SIZE** | _positive_ | 32
|
3+| Defines the size of the CFS input signal conduit (`cfs_in_i`). See section <<_custom_functions_subsystem_cfs>> for more information.
|
3+| Defines the size of the CFS input signal conduit (`cfs_in_i`). See section <<_custom_functions_subsystem_cfs>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_CFS_OUT_SIZE_
|
===== _IO_CFS_OUT_SIZE_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_CFS_OUT_SIZE** | _positive_ | 32
|
| **IO_CFS_OUT_SIZE** | _positive_ | 32
|
3+| Defines the size of the CFS output signal conduit (`cfs_out_o`). See section <<_custom_functions_subsystem_cfs>> for more information.
|
3+| Defines the size of the CFS output signal conduit (`cfs_out_o`). See section <<_custom_functions_subsystem_cfs>> for more information.
|
|======
|
|======
|
|
|
|
|
:sectnums!:
|
:sectnums!:
|
===== _IO_NCO_EN_
|
|
|
|
[cols="4,4,2"]
|
|
[frame="all",grid="none"]
|
|
|======
|
|
| **IO_NCO_EN** | _boolean_ | true
|
|
3+| Implement numerically-controlled oscillator (NCO) when _true_.
|
|
See section <<_numerically_controlled_oscillator_nco>> for more information.
|
|
|======
|
|
|
|
|
|
:sectnums!:
|
|
===== _IO_NEOLED_EN_
|
===== _IO_NEOLED_EN_
|
|
|
[cols="4,4,2"]
|
[cols="4,4,2"]
|
[frame="all",grid="none"]
|
[frame="all",grid="none"]
|
|======
|
|======
|
| **IO_NEOLED_EN** | _boolean_ | true
|
| **IO_NEOLED_EN** | _boolean_ | true
|
3+| Implement smart LED interface (WS2812 / NeoPixel(TM)-compatible) (NEOLED) when _true_.
|
3+| Implement smart LED interface (WS2812 / NeoPixel(TM)-compatible) (NEOLED) when _true_.
|
See section <<_smart_led_interface_neoled>> for more information.
|
See section <<_smart_led_interface_neoled>> for more information.
|
|======
|
|======
|
|
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== Processor Interrupts
|
=== Processor Interrupts
|
|
|
[TIP]
|
The NEORV32 Processor provides several interrupt request signals (IRQs) for custom platform use.
|
The interrupt request signals have specific `mip` CSR bits (see <<_machine_trap_setup>>), specifc
|
|
`mie` CSR bits (see <<_machine_trap_handling>>) and specifc `mcause` CSR trap codes and trap
|
|
priorities. For more information (also regarding the signaling protocol) see section <<_traps_exceptions_and_interrupts>>.
|
|
|
|
**RISC-V Standard Interrupts**
|
|
|
:sectnums:
|
|
==== RISC-V Standard Interrupts
|
|
|
The processor setup features the standard RISC-V interrupt lines for "machine timer interrupt", "machine
|
The processor setup features the standard RISC-V interrupt lines for "machine timer interrupt", "machine
|
software interrupt" and "machine external interrupt". The software and external interrupt lines are available
|
software interrupt" and "machine external interrupt". Their usage is defined by the RISC-V privileged architecture
|
via the processor's top entity. By default, the timer interrupt is connected to the internal machine timer
|
specifications. However, bare-metal system can also repurpose these interrupts. See CPU section
|
MTIME timer unit (<<_machine_system_timer_mtime>>). If this module has not been enabled for
|
<<_traps_exceptions_and_interrupts>> for more information.
|
synthesis, the machine timer interrupt is also available via the processor's top entity.
|
|
|
|
**NEORV32-Specific Fast Interrupt Requests**
|
[cols="<3,^2,<11"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| Top signal | Width | Description
|
|
| `mtime_irq_i` | 1 | Machine timer interrupt from _processor-external_ MTIME unit. This IRQ is only available if the processor-internal MTIME unit is not used (<<_io_mtime_en>> = false).
|
|
| `msw_irq_i` | 1 | Machine software interrupt. This interrupt is used for inter-processor interrupts in multi-core systems. However, it can also be used for any custom purpose.
|
|
| `mext_irq_i` | 1 | Machine external interrupt. This interrupt is used for any processor-external interrupt source (like a platform interrupt controller).
|
|
|=======================
|
|
|
As part of the custom/NEORV32-specific CPU extensions, the CPU features 16 fast interrupt request signals
|
[NOTE]
|
(`FIRQ0` – `FIRQ15`).
|
These IRQs trigger on high-level.
|
|
|
|
|
|
:sectnums:
|
|
==== Non-Maskable Interrupt
|
|
|
|
[cols="<3,^2,<11"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| Top signal | Width | Description
|
|
| `nm_irq_i` | 1 | Non-maskable interrupt.
|
|
|=======================
|
|
|
The fast interrupt request signals are divided into two groups. The FIRQs with higher priority (FIRQ0 –
|
The processor features a single non-maskable interrupt source via the `nm_irq_i` top
|
FIRQ9) are dedicated for processor-internal usage. The FIRQs with lower priority (FIRQ10 – FIRQ15) are
|
entity signal that can be used to signal _critical system conditions_. This interrupt source _cannot_ be masked/disabled.
|
available for custom usage via the processor's top entity signal `soc_firq_i`.
|
See CPU section <<_traps_exceptions_and_interrupts>> for more information.
|
|
|
The mapping of the 16 FIRQ channels is shown in the following table (the channel number corresponds to the FIRQ priority):
|
[NOTE]
|
|
This IRQ triggers on high-level.
|
|
|
|
|
|
:sectnums:
|
|
==== Platform External Interrupts
|
|
|
|
[cols="<3,^2,<11"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| Top signal | Width | Description
|
|
| `xirq_i` | up to 32 | External platform interrupts (user-defined).
|
|
|=======================
|
|
|
|
The processor provides an optional interrupt controller for up to 32 user-defined external interrupts
|
|
(see section <<_external_interrupt_controller_xirq>>). These external IRQs are mapped to a _single_ CPU
|
|
fast interrupt request so a software handler is required to differentiate / prioritize these interrupts.
|
|
|
|
[NOTE]
|
|
The trigger for these interrupt can be defines via generics. See section
|
|
<<_external_interrupt_controller_xirq>> for more information.
|
|
|
|
|
|
:sectnums:
|
|
==== NEORV32-Specific Fast Interrupt Requests
|
|
|
|
As part of the custom/NEORV32-specific CPU extensions, the CPU features 16 fast interrupt request signals
|
|
(`FIRQ0` – `FIRQ15`). These are used 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 is shown in the following table (the channel number also corresponds to
|
|
the according FIRQ priority; 0 = highest, 15 = lowest):
|
|
|
.NEORV32 fast interrupt channel mapping
|
.NEORV32 fast interrupt channel mapping
|
[cols="^1,<2,<7"]
|
[cols="^1,<2,<7"]
|
[options="header",grid="rows"]
|
[options="header",grid="rows"]
|
|=======================
|
|=======================
|
| Channel | Source | Description
|
| Channel | Source | Description
|
| 0 | _WDT_ | watchdog timeout interrupt
|
| 0 | <<_watchdog_timer_wdt,WDT>> | watchdog timeout interrupt
|
| 1 | _CFS_ | custom functions subsystem (CFS) interrupt (user-defined)
|
| 1 | <<_custom_functions_subsystem_cfs,CFS>> | custom functions subsystem (CFS) interrupt (user-defined)
|
| 2 | _UART0_ (RXD) | UART0 data received interrupt (RX complete)
|
| 2 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 data received interrupt (RX complete)
|
| 3 | _UART0_ (TXD) | UART0 sending done interrupt (TX complete)
|
| 3 | <<_primary_universal_asynchronous_receiver_and_transmitter_uart0,UART0>> | UART0 sending done interrupt (TX complete)
|
| 4 | _UART1_ (RXD) | UART1 data received interrupt (RX complete)
|
| 4 | <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>> | UART1 data received interrupt (RX complete)
|
| 5 | _UART1_ (TXD) | UART1 sending done interrupt (TX complete)
|
| 5 | <<_secondary_universal_asynchronous_receiver_and_transmitter_uart1,UART1>> | UART1 sending done interrupt (TX complete)
|
| 6 | _SPI_ | SPI transmission done interrupt
|
| 6 | <<_serial_peripheral_interface_controller_spi,SPI>> | SPI transmission done interrupt
|
| 7 | _TWI_ | TWI transmission done interrupt
|
| 7 | <<_two_wire_serial_interface_controller_twi,TWI>> | TWI transmission done interrupt
|
| 8 | _GPIO_ | GPIO input pin-change interrupt
|
| 8 | <<_external_interrupt_controller_xirq,XIRQ>> | External interrupt controller interrupt
|
| 9 | _NEOLED_ | NEOLED buffer TX empty / not full interrupt
|
| 9 | <<_smart_led_interface_neoled,NEOLED>> | NEOLED buffer TX empty / not full interrupt
|
| 10:15 | `soc_firq_i(5:0)` | Custom platform use; available via processor's top signal
|
| 10 | <<_stream_link_interface_slink,SLINK>> | RX data received
|
|
| 11 | <<_stream_link_interface_slink,SLINK>> | TX data send
|
|
| 12:15 | - | _reserved_, cannot fire
|
|=======================
|
|=======================
|
|
|
**Non-Maskable Interrupt**
|
|
|
|
The NEORV32 features a single non-maskable interrupt source via the `nm_irq_i` top
|
|
entity signal that can be used to signal critical system conditions. This interrupt source _cannot_ be disabled. Hence, it does _not_ provide
|
|
configuration/status flags in the `mie` and `mip` CSRs. The RISC-V-compatible `mcause` value `0x80000000` is used to indicate the non-maskable interrupt.
|
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== Address Space
|
=== Address Space
|
|
|
By default, the total 32-bit (4GB) address space of the NEORV32 Processor is divided into four main regions:
|
The NEORV32 Processor provides 32-bit physical addresses accessing up to 4GB of address space.
|
|
By default, this address space is divided into four main regions:
|
|
|
1. Instruction memory (IMEM) space – for instructions and constants.
|
1. **Instruction address space** – for instructions (=code) and constants. A configurable section of this address space is used by
|
2. Data memory (DMEM) space – for application runtime data (heap, stack, etc.).
|
internal and/or external _instruction memory_ (IMEM).
|
3. Bootloader ROM address space – for the processor-internal bootloader.
|
2. **Data address space** – for application runtime data (heap, stack, etc.). A configurable section of this address space is used by
|
4. IO/peripheral address space – for the processor-internal IO/peripheral devices (e.g., UART).
|
internal and/or external _data memory_ (DMEM).
|
|
3. **Bootloader address space**. A _fixed_ section of this address space is used by
|
.NEORV32 processor - address space (default configuration)
|
internal _bootloader memory_ (BOOTLDROM).
|
image::address_space.png[900]
|
4. **IO/peripheral address space** – for the processor-internal IO/peripheral devices (e.g., UART).
|
|
|
[TIP]
|
[TIP]
|
These four memory regions are handled by the linker when compiling a NEORV32 executable.
|
These four memory regions are handled by the linker when compiling a NEORV32 executable.
|
See section <<_executable_image_format>> for more information.
|
See section <<_executable_image_format>> for more information.
|
|
|
**Address Space Layout**
|
.NEORV32 processor - address space (default configuration)
|
|
image::address_space.png[900]
|
The general address space layout consists of two main configuration constants: `ispace_base_c` defining
|
|
the base address of the instruction memory address space and `dspace_base_c` defining the base address of
|
|
the data memory address space. Both constants are defined in the NEORV32 VHDL package file
|
|
`rtl/core/neorv32_package.vhd`:
|
|
|
|
[source,vhdl]
|
|
----
|
|
-- Architecture Configuration ----------------------------------------------------
|
|
-- ----------------------------------------------------------------------------------
|
|
constant ispace_base_c : std_ulogic_vector(31 downto 0) := x"00000000";
|
|
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000";
|
|
----
|
|
|
|
The default configuration assumes the instruction memory address space starting at address _0x00000000_
|
|
and the data memory address space starting at _0x80000000_. Both values can be modified for a specific
|
|
setup and the address space may overlap or can be completely identical.
|
|
|
|
The base address of the bootloader (at _0xFFFF0000_) and the IO region (at _0xFFFFFF00_) for the peripheral
|
|
devices are also defined in the package and are fixed. These address regions cannot be used for other
|
|
applications – even if the bootloader or all IO devices are not implemented.
|
|
|
|
[WARNING]
|
|
When using the processor-internal data and/or instruction memories (DMEM/IMEM) and using a non-default
|
|
configuration for the `dspace_base_c` and/or `ispace_base_c` base addresses, the
|
|
following requirements have to be fulfilled:
|
|
**1.** Both base addresses have to be aligned to a 4-byte boundary.
|
|
**2.** Both base addresses have to be aligned to the according internal memory sizes.
|
|
|
|
:sectnums:
|
:sectnums:
|
==== CPU Data and Instruction Access
|
==== CPU Data and Instruction Access
|
|
|
The CPU can access all of the 4GB address space from the instruction fetch interface (**I**) and also from the
|
The CPU can access all of the 4GB address space from the instruction fetch interface (**I**) and also from the
|
data access interface (**D**). These two CPU interfaces are multiplexed by a simple bus switch
|
data access interface (**D**). These two CPU interfaces are multiplexed by a simple bus switch
|
(`rtl/core/neorv32_busswitch.vhd`) into a _single_ processor-internal bus. All processor-internal
|
(`rtl/core/neorv32_busswitch.vhd`) into a _single_ processor-internal bus. All processor-internal
|
memories, peripherals and also the external memory interface are connected to this bus. Hence, both CPU
|
memories, peripherals and also the external memory interface are connected to this bus. Hence, both CPU
|
interfaces (instruction fetch & data access) have access to the same (**identical**) address space making the
|
interfaces (instruction fetch & data access) have access to the same (**identical**) address space making the
|
setup a modified von-Neumann architecture.
|
setup a modified von-Neumann architecture.
|
|
|
.Processor-internal bus architecture
|
.Processor-internal bus architecture
|
image::neorv32_bus.png[1300]
|
image::neorv32_bus.png[1300]
|
|
|
[NOTE]
|
[NOTE]
|
The internal processor bus might appear as bottleneck. In order to reduce traffic jam on this bus
|
The internal processor bus might appear as bottleneck. In order to reduce traffic jam on this bus
|
(when instruction fetch and data interface access the bus at the same time) the instruction fetch of
|
(when instruction fetch and data interface access the bus at the same time) the instruction fetch of
|
the CPU is equipped with a prefetch buffer. Instruction fetches can be further buffered using the i-cache.
|
the CPU is equipped with a prefetch buffer. Instruction fetches can be further buffered using the i-cache.
|
Furthermore, data accesses (loads and stores) have higher priority than instruction fetch
|
Furthermore, data accesses (loads and stores) have higher priority than instruction fetch
|
accesses.
|
accesses.
|
|
|
[IMPORTANT]
|
[IMPORTANT]
|
Please note that all processor-internal components including the peripheral/IO devices can also be
|
Please note that all processor-internal components including the peripheral/IO devices can also be
|
accessed from programs running in less-privileged user mode. For example, if the system relies on
|
accessed from programs running in less-privileged user mode. For example, if the system relies on
|
a periodic interrupt from the _MTIME_ timer unit, user-level programs could alter the _MTIME_
|
a periodic interrupt from the _MTIME_ timer unit, user-level programs could alter the _MTIME_
|
configuration corrupting this interrupt. This kind of security issues can be compensated using the
|
configuration corrupting this interrupt. This kind of security issues can be compensated using the
|
PMP system (see <<_machine_physical_memory_protection>>).
|
PMP system (see <<_machine_physical_memory_protection>>).
|
|
|
|
|
|
:sectnums:
|
|
==== Address Space Layout
|
|
|
|
The general address space layout consists of two main configuration constants: `ispace_base_c` defining
|
|
the base address of the _instruction memory address space_ and `dspace_base_c` defining the base address of
|
|
the _data memory address space_. Both constants are defined in the NEORV32 VHDL package file
|
|
`rtl/core/neorv32_package.vhd`:
|
|
|
|
[source,vhdl]
|
|
----
|
|
-- Architecture Configuration ----------------------------------------------------
|
|
-- ----------------------------------------------------------------------------------
|
|
constant ispace_base_c : std_ulogic_vector(31 downto 0) := x"00000000";
|
|
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000";
|
|
----
|
|
|
|
The default configuration assumes the _instruction memory address space_ starting at address _0x00000000_
|
|
and the _data memory address space_ starting at _0x80000000_. Both values can be modified for a specific
|
|
setup and the address space may overlap or can be completely identical. Make sure that both base addresses
|
|
are _aligned_ to a 4-byte boundary.
|
|
|
|
[NOTE]
|
|
The base address of the internal bootloader (at _0xFFFF0000_) and the internal IO region (at _0xFFFFFE00_) for
|
|
peripheral devices are also defined in the package and are fixed. These address regions cannot not be used for other
|
|
applications – even if the bootloader or all IO devices are not implemented - without modifying the core's
|
|
hardware sources.
|
|
|
|
|
:sectnums:
|
:sectnums:
|
==== Physical Memory Attributes
|
==== Physical Memory Attributes
|
|
|
The processor setup defines four simple attributes for the four processor-internal address space regions:
|
The processor setup defines fixed attributes for the four processor-internal address space regions.
|
|
Accessing a memory region in a way that violates any of these attributes will raise an according
|
|
access exception..
|
|
|
* `r` – read access (from CPU data access interface, e.g. via "load")
|
* `r` – read access (from CPU data access interface, e.g. via "load")
|
* `w` – write access (from CPU data access interface, e.g. via "store")
|
* `w` – write access (from CPU data access interface, e.g. via "store")
|
* `x` – execute access (from CPU instruction fetch interface)
|
* `x` – execute access (from CPU instruction fetch interface)
|
* `a` – atomic access (from CPU data access interface)
|
* `a` – atomic access (from CPU data access interface)
|
* `8` – byte (8-bit)-accessible (when writing)
|
* `8` – byte (8-bit)-accessible (when writing)
|
* `16` – half-word (16-bit)-accessible (when writing)
|
* `16` – half-word (16-bit)-accessible (when writing)
|
* `32` – word (32-bit)-accessible (when writing)
|
* `32` – word (32-bit)-accessible (when writing)
|
|
|
The following table shows the provided physical memory attributes of each region. Additional attributes (like
|
[NOTE]
|
denying execute right for certain region of the IMEM) can be provided using the RISC-V <<_machine_physical_memory_protection>> extension.
|
Read accesses (i.e. loads) can always access data in word, half-word and byte quantities (requiring an accordingly aligned address).
|
|
|
[cols="^1,^2,^2,^3,^2"]
|
[cols="^1,^2,^2,^3,^2"]
|
[options="header",grid="rows"]
|
[options="header",grid="rows"]
|
|=======================
|
|=======================
|
| # | Region | Base address | Size | Attributes
|
| # | Region | Base address | Size | Attributes
|
| 4 | IO/peripheral devices | 0xfffffe00 | 512 bytes | `r/w/a/32`
|
| 4 | IO/peripheral devices | 0xfffffe00 | 512 bytes | `r/w/a/32`
|
| 3 | bootloader ROM | 0xffff0000 | up to 32kB| `r/x/a`
|
| 3 | bootloader ROM | 0xffff0000 | up to 32kB| `r/x/a`
|
| 2 | DMEM | 0x80000000 | up to 2GB (-64kB) | `r/w/x/a/8/16/32`
|
| 2 | DMEM | 0x80000000 | up to 2GB (-64kB) | `r/w/x/a/8/16/32`
|
| 1 | IMEM | 0x00000000 | up to 2GB | `r/w/x/a/8/16/32`
|
| 1 | IMEM | 0x00000000 | up to 2GB | `r/w/x/a/8/16/32`
|
|=======================
|
|=======================
|
|
|
Only the CPU of the processor has access to the internal memories and IO devices, hence all accesses are
|
[TIP]
|
always exclusive. Accessing a memory region in a way that violates the provided attributes will trigger a
|
The following table shows the provided physical memory attributes of each region. Additional attributes (for example
|
load/store/instruction fetch access exception or will return a failed atomic access result, respectively.
|
controlling certain right for specific address space regions) can be provided using the RISC-V <<_machine_physical_memory_protection>> extension.
|
|
|
The physical memory attributes of memories and/or devices connected via the external bus interface have to
|
|
defined by those components or the interconnection fabric.
|
|
|
|
:sectnums:
|
:sectnums:
|
==== Internal Memories
|
==== Memory Configuration
|
|
|
|
The NEORV32 Processor was designed to provide maximum flexibility for the memory configuration.
|
|
The processor can populate the _instruction address space_ and/or the _data address space_ with **internal memories**
|
|
for instructions (IMEM) and data (DMEM). Processor **external memories** can be used as an _alternative_ or even _in combination_ with
|
|
the internal ones. The figure below show some exemplary memory configurations.
|
|
|
The processor can implement internal memories for instructions (IMEM) and data (DMEM), which will be
|
.Exemplary memory configurations
|
mapped to FPGA block RAMs. The implementation of these memories is controlled via the boolean
|
image::neorv32_memory_configurations.png[800]
|
<<_mem_int_imem_en>> and <<_mem_int_dmem_en>> generics.
|
|
|
|
The size of these memories are configured via the _MEM_INT_IMEM_SIZE_ and _MEM_INT_DMEM_SIZE_
|
:sectnums!:
|
generics (in bytes), respectively. The processor-internal instruction memory (IMEM) can optionally be
|
===== Internal Memories
|
implemented as true ROM (<<_mem_int_imem_rom>>), which is initialized with the application code during
|
|
synthesis.
|
The processor-internal memories (<<_instruction_memory_imem>> and <<_data_memory_dmem>>) are enabled (=implemented)
|
|
via the <<_mem_int_imem_en>> and <<_mem_int_dmem_en>> generics. Their sizes are configures via the according
|
|
<<_mem_int_imem_size>> and <<_mem_int_dmem_size>> generics.
|
|
|
If the processor-internal IMEM is implemented, it is located right at the base address of the instruction
|
If the processor-internal IMEM is implemented, it is located right at the base address of the instruction
|
address space (default `ispace_base_c` = _0x00000000_). Vice versa, the processor-internal data memory is
|
address space (default `ispace_base_c` = _0x00000000_). Vice versa, the processor-internal data memory is
|
located right at the beginning of the data address space (default `dspace_base_c` = _0x80000000_) when
|
located right at the beginning of the data address space (default `dspace_base_c` = _0x80000000_) when
|
implemented.
|
implemented.
|
|
|
:sectnums:
|
[TIP]
|
==== External Memory/Bus Interface
|
The default processor setup uses only _internal_ memories.
|
|
|
|
[NOTE]
|
|
If the IMEM (internal or external) is less than the (default) maximum size (2GB), there is
|
|
a "dead address space" between it and the DMEM. This provides an additional safety feature
|
|
since data corrupting scenarios like stack overflow cannot directly corrupt the content of the IMEM:
|
|
any access to the "dead address space" in between will raise an exception that can be caught
|
|
by the runtime environment.
|
|
|
|
:sectnums!:
|
|
===== External Memories
|
|
|
|
If external memories (or further IP modules) shall be connected via the _processor's external bus interface_,
|
|
the interface has to be enabled via <<_mem_ext_en>> generic (=_true_). More information regarding this interface can be
|
|
found in section <<_processor_external_memory_interface_wishbone_axi4_lite>>.
|
|
|
Any CPU access (data or instructions), which does not fulfill one of the following conditions, is forwarded
|
Any CPU access (data or instructions), which does not fulfill _at least one_ of the following conditions, is forwarded
|
to the <<_processor_external_memory_interface_wishbone_axi4_lite>>:
|
via the processor's bus interface to external components:
|
|
|
* access to the processor-internal IMEM and processor-internal IMEM is implemented
|
* access to the processor-internal IMEM and processor-internal IMEM is implemented
|
* access to the processor-internal DMEM and processor-internal DMEM is implemented
|
* access to the processor-internal DMEM and processor-internal DMEM is implemented
|
* access to the bootloader ROM and beyond → addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface
|
* access to the bootloader ROM and beyond → addresses >= _BOOTROM_BASE_ (default 0xFFFF0000) will never be forwarded to the external memory interface
|
|
|
The external bus interface is available when the <<_mem_ext_en>> generic is _true_. If this interface is
|
If no (or not all) processor-internal memories are implemented, the according base addresses are mapped to external memories.
|
deactivated, any access exceeding the internal memories or peripheral devices will trigger a bus access fault
|
For example, if the processor-internal IMEM is not implemented (<<_mem_int_imem_en>> = _false_), the processor will forward
|
exception. If <<_mem_ext_timeout>> is greater than zero any external bus access that is not acknowledged or terminated
|
any access to the instruction address space (starting at `ispace_base_c`) via the external bus interface to the external
|
within <<_mem_ext_timeout>> clock cycles will auto-timeout and raise the according bus fault exception.
|
memory system.
|
|
|
|
[NOTE]
|
|
If the external interface is deactivated, any access exceeding the internal memory address space (instruction, data, bootloader) or
|
|
the internal peripheral address space will trigger a bus access fault exception.
|
|
|
|
|
|
:sectnums:
|
|
==== Boot Configuration
|
|
|
|
Due to the flexible memory configuration concept, the NEORV32 Processor provides several different boot concepts.
|
|
The figure below shows the exemplary concepts for the two most common boot scenarios.
|
|
|
|
.NEORV32 boot configurations
|
|
image::neorv32_boot_configurations.png[800]
|
|
|
|
[NOTE]
|
|
The configuration of internal or external data memory (DMEM; <<_mem_int_dmem_en>> = _true_ / _false_) is not further
|
|
relevant for the boot configuration itself. Hence, it is not further illustrated here.
|
|
|
|
There are two general boot scenarios: _Indirect Boot_ (1a and 1b) and _Direct Boot_ (2a and 2b) configured via the
|
|
<<_int_bootloader_en>> generic If this generic is set **true** the _indirect_ boot scenario is used. This is also the
|
|
default boot configuration of the processor. If <<_int_bootloader_en>> is set **false** the _direct_ boot scenario is used.
|
|
|
|
[NOTE]
|
|
Please note that the provided boot scenarios are just exemplary setups that (should) fit most common requirements.
|
|
Much more sophisticated boot scenarios are possible by combining internal and external memories. For example, the default
|
|
internal bootloader could be used as first-level bootloader that loads (from extern SPI flash) a second-level bootloader
|
|
that is placed and execute in internal IMEM. This second-level bootloader could then fetch the actual application and
|
|
store it to external _data_ memory and transfers CPU control to that.
|
|
|
|
:sectnums!:
|
|
===== Indirect Boot
|
|
|
|
The _indirect_ boot scenarios **1a** and **1b** use the processor-internal <<_bootloader>>. This general setup is enabled
|
|
by setting the <<_int_bootloader_en>> generic to true, which will implement the processor-internal <<_bootloader_rom_bootrom>>.
|
|
This read-only memory is pre-initialized during synthesis with the default bootloader firmware.
|
|
|
|
The bootloader provides several options to upload an executable (via UART or from external SPI flash) and store it to
|
|
the _instruction address space_ so the CPU can execute it. Boot scenario **1a** uses the processor-internal IMEM
|
|
(<<_mem_int_imem_en>> = _true_). This scenario implements the internal <<_instruction_memory_imem>> as non-initialized
|
|
RAM so the bootloader can write the actual executable to it.
|
|
|
|
Boot scenario **1b** uses a processor-external IMEM (<<_mem_int_imem_en>> = _false_) that is connected via the processor's
|
|
bus interface. In this scenario the internal <<_instruction_memory_imem>> is not implemented at all and the bootloader will
|
|
write the executable to the processor-external memory.
|
|
|
|
:sectnums!:
|
|
===== Direct Boot
|
|
|
|
The _direct_ boot scenarios **2a** and **2b** do not use the processor-internal bootloader. Hence, the <<_int_bootloader_en>>
|
|
generic is set _false_. In this configuration the <<_bootloader_rom_bootrom>> is not implemented at all and the CPU will
|
|
directly begin executing code from the instruction address space after reset. A "pre-initialization mechanism is required
|
|
in order to provide an executable _in_ memory.
|
|
|
|
Boot scenario **2a** uses the processor-internal IMEM (<<_mem_int_imem_en>> = _true_) that is implemented as _read-only memory_
|
|
in this scenario. It is pre-initialized (by the bitstream) with the actual application executable.
|
|
|
|
In contrast, boot scenario **2b** uses a processor-external IMEM (<<_mem_int_imem_en>> = _false_). In this scenario the
|
|
system designer is responsible for providing a initialized external memory that contains the actual application to be executed.
|
|
|
|
|
|
|
<<<
|
<<<
|
// ####################################################################################################################
|
// ####################################################################################################################
|
:sectnums:
|
:sectnums:
|
=== Processor-Internal Modules
|
=== Processor-Internal Modules
|
|
|
Basically, the processor is a SoC consisting of the NEORV32 CPU, peripheral/IO devices, embedded
|
Basically, the processor is a SoC consisting of the NEORV32 CPU, peripheral/IO devices, embedded
|
memories, an external memory interface and a bus infrastructure to interconnect all units. Additionally, the
|
memories, an external memory interface and a bus infrastructure to interconnect all units. Additionally, the
|
system implements an internal reset generator and a global clock generator/divider.
|
system implements an internal reset generator and a global clock generator/divider.
|
|
|
**Internal Reset Generator**
|
**Internal Reset Generator**
|
|
|
Most processor-internal modules – except for the CPU and the watchdog timer – do not have a dedicated
|
Most processor-internal modules – except for the CPU and the watchdog timer – do not have a dedicated
|
reset signal. However, all devices can be reset by software by clearing the corresponding unit's control
|
reset signal. However, all devices can be reset by software by clearing the corresponding unit's control
|
register. The automatically included application start-up code (`crt0.S`) will perform a software-reset of all
|
register. The automatically included application start-up code (`crt0.S`) will perform a software-reset of all
|
modules to ensure a clean system reset state.
|
modules to ensure a clean system reset state.
|
|
|
The hardware reset signal of the processor can either be
|
The hardware reset signal of the processor can either be
|
triggered via the external reset pin (`rstn_i`, low-active) or by the internal watchdog timer (if implemented).
|
triggered via the external reset pin (`rstn_i`, low-active) or by the internal watchdog timer (if implemented).
|
Before the external reset signal is applied to the system, it is extended to have a minimal duration of eight
|
Before the external reset signal is applied to the system, it is extended to have a minimal duration of eight
|
clock cycles.
|
clock cycles.
|
|
|
**Internal Clock Divider**
|
**Internal Clock Divider**
|
|
|
An internal clock divider generates 8 clock signals derived from the processor's main clock input `clk_i`.
|
An internal clock divider generates 8 clock signals derived from the processor's main clock input `clk_i`.
|
These derived clock signals are not actual _clock signals_. Instead, they are derived from a simple counter and
|
These derived clock signals are not actual _clock signals_. Instead, they are derived from a simple counter and
|
are used as "clock enable" signal by the different processor modules. Thus, the whole design operates using
|
are used as "clock enable" signal by the different processor modules. Thus, the whole design operates using
|
only the main clock signal (single clock domain). Some of the processor peripherals like the Watchdog or the
|
only the main clock signal (single clock domain). Some of the processor peripherals like the Watchdog or the
|
UARTs can select one of the derived clock enabled signals for their internal operation. If none of the
|
UARTs can select one of the derived clock enabled signals for their internal operation. If none of the
|
connected modules require a clock signal from the divider, it is automatically deactivated to reduce dynamic
|
connected modules require a clock signal from the divider, it is automatically deactivated to reduce dynamic
|
power.
|
power.
|
|
|
The peripheral devices, which feature a time-based configuration, provide a three-bit prescaler select in their
|
The peripheral devices, which feature a time-based configuration, provide a three-bit prescaler select in their
|
according control register to select one out of the eight available clocks. The mapping of the prescaler select
|
according control register to select one out of the eight available clocks. The mapping of the prescaler select
|
bits to the actually obtained clock are shown in the table below. Here, f represents the processor main clock
|
bits to the actually obtained clock are shown in the table below. Here, f represents the processor main clock
|
from the top entity's `clk_i` signal.
|
from the top entity's `clk_i` signal.
|
|
|
[cols="<3,^1,^1,^1,^1,^1,^1,^1,^1"]
|
[cols="<3,^1,^1,^1,^1,^1,^1,^1,^1"]
|
[grid="rows"]
|
[grid="rows"]
|
|=======================
|
|=======================
|
| Prescaler bits: | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
|
| 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_
|
| Resulting clock: | _f/2_ | _f/4_ | _f/8_ | _f/64_ | _f/128_ | _f/1024_| _f/2048_| _f/4096_
|
|=======================
|
|=======================
|
|
|
**Peripheral / IO Devices**
|
**Peripheral / IO Devices**
|
|
|
The processor-internal peripheral/IO devices are located at the end of the 32-bit address space at base
|
The processor-internal peripheral/IO devices are located at the end of the 32-bit address space at base
|
address _0xFFFFFE00_. A region of 512 bytes is reserved for this devices. Hence, all peripheral/IO devices are
|
address _0xFFFFFE00_. A region of 512 bytes is reserved for this devices. Hence, all peripheral/IO devices are
|
accessed using a memory-mapped scheme. A special linker script as well as the NEORV32 core software
|
accessed using a memory-mapped scheme. A special linker script as well as the NEORV32 core software
|
library abstract the specific memory layout for the user.
|
library abstract the specific memory layout for the user.
|
|
|
[IMPORTANT]
|
[IMPORTANT]
|
When accessing an IO device that hast not been implemented (via the according _IO_x_EN_ generic), a
|
When accessing an IO device that hast not been implemented (via the according _IO_x_EN_ generic), a
|
load/store access fault exception is triggered.
|
load/store access fault exception is triggered.
|
|
|
[IMPORTANT]
|
[IMPORTANT]
|
The peripheral/IO devices can only be written in full-word mode (i.e. 32-bit). Byte or half-word
|
The peripheral/IO devices can only be written in full-word mode (i.e. 32-bit). Byte or half-word
|
(8/16-bit) writes will trigger a store access fault exception. Read accesses are not size constrained.
|
(8/16-bit) writes will trigger a store access fault exception. Read accesses are not size constrained.
|
Processor-internal memories as well as modules connected to the external memory interface can still
|
Processor-internal memories as well as modules connected to the external memory interface can still
|
be written with a byte-wide granularity.
|
be written with a byte-wide granularity.
|
|
|
[TIP]
|
[TIP]
|
You should use the provided core software library to interact with the peripheral devices. This
|
You should use the provided core software library to interact with the peripheral devices. This
|
prevents incompatibilities with future versions, since the hardware driver functions handle all the
|
prevents incompatibilities with future versions, since the hardware driver functions handle all the
|
register and register bit accesses.
|
register and register bit accesses.
|
|
|
[TIP]
|
[TIP]
|
Most of the IO devices do not have a hardware reset. Instead, the devices are reset via software by
|
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
|
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`.
|
application start-up code `crt0.S`.
|
|
|
**Nomenclature for the Peripheral / IO Devices Listing**
|
**Nomenclature for the Peripheral / IO Devices Listing**
|
|
|
Each peripheral device chapter features a register map showing accessible control and data registers of the
|
Each peripheral device chapter features a register map showing accessible control and data registers of the
|
according device including the implemented control and status bits. You can directly interact with these
|
according device including the implemented control and status bits. You can directly interact with these
|
registers/bits via the provided _C-code defines_. These defines are set in the main processor core library
|
registers/bits via the provided _C-code defines_. These defines are set in the main processor core library
|
include file `sw/lib/include/neorv32.h`. The registers and/or register bits, which can be accessed
|
include file `sw/lib/include/neorv32.h`. The registers and/or register bits, which can be accessed
|
directly using plain C-code, are marked with a "[C]".
|
directly using plain C-code, are marked with a "[C]".
|
|
|
Not all registers or register bits can be arbitrarily read/written. The following read/write access types are
|
Not all registers or register bits can be arbitrarily read/written. The following read/write access types are
|
available:
|
available:
|
|
|
* `r/w` registers / bits can be read and written
|
* `r/w` registers / bits can be read and written
|
* `r/-` registers / bits are read-only; any write access to them has no effect
|
* `r/-` registers / bits are read-only; any write access to them has no effect
|
* `-/w` these registers / bits are write-only; they auto-clear in the next cycle and are always read as zero
|
* `-/w` these registers / bits are write-only; they auto-clear in the next cycle and are always read as zero
|
|
|
[TIP]
|
[TIP]
|
Bits / registers that are not listed in the register map tables are not (yet) implemented. These registers
|
Bits / registers that are not listed in the register map tables are not (yet) implemented. These registers
|
/ bits are always read as zero. A write access to them has no effect, but user programs should only
|
/ bits are always read as zero. A write access to them has no effect, but user programs should only
|
write zero to them to keep compatible with future extension.
|
write zero to them to keep compatible with future extension.
|
|
|
[TIP]
|
[TIP]
|
When writing to read-only registers, the access is nevertheless acknowledged, but no actual data is
|
When writing to read-only registers, the access is nevertheless acknowledged, but no actual data is
|
written. When reading data from a write-only register the result is undefined.
|
written. When reading data from a write-only register the result is undefined.
|
|
|
|
|
include::soc_imem.adoc[]
|
include::soc_imem.adoc[]
|
|
|
include::soc_dmem.adoc[]
|
include::soc_dmem.adoc[]
|
|
|
include::soc_bootrom.adoc[]
|
include::soc_bootrom.adoc[]
|
|
|
include::soc_icache.adoc[]
|
include::soc_icache.adoc[]
|
|
|
include::soc_wishbone.adoc[]
|
include::soc_wishbone.adoc[]
|
|
|
|
include::soc_slink.adoc[]
|
|
|
include::soc_gpio.adoc[]
|
include::soc_gpio.adoc[]
|
|
|
include::soc_wdt.adoc[]
|
include::soc_wdt.adoc[]
|
|
|
include::soc_mtime.adoc[]
|
include::soc_mtime.adoc[]
|
|
|
include::soc_uart.adoc[]
|
include::soc_uart.adoc[]
|
|
|
include::soc_spi.adoc[]
|
include::soc_spi.adoc[]
|
|
|
include::soc_twi.adoc[]
|
include::soc_twi.adoc[]
|
|
|
include::soc_pwm.adoc[]
|
include::soc_pwm.adoc[]
|
|
|
include::soc_trng.adoc[]
|
include::soc_trng.adoc[]
|
|
|
include::soc_cfs.adoc[]
|
include::soc_cfs.adoc[]
|
|
|
include::soc_nco.adoc[]
|
|
|
|
include::soc_neoled.adoc[]
|
include::soc_neoled.adoc[]
|
|
|
|
include::soc_xirq.adoc[]
|
|
|
include::soc_sysinfo.adoc[]
|
include::soc_sysinfo.adoc[]
|
|
|
|
|
|
|