neorv32/docs/datasheet/soc_xip.adoc

212 lines
13 KiB
Plaintext

<<<
:sectnums:
==== Execute In Place Module (XIP)
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
|=======================
| Hardware source file(s): | neorv32_xip.vhd |
| Software driver file(s): | neorv32_xip.c |
| | neorv32_xip.h |
| Top entity port: | `xip_csn_o` | 1-bit chip select, low-active
| | `xip_clk_o` | 1-bit serial clock output
| | `xip_dat_i` | 1-bit serial data input
| | `xip_dat_o` | 1-bit serial data output
| Configuration generics: | `XIP_EN` | implement XIP module when `true`
| | `XIP_CACHE_EN` | implement XIP cache when `true`
| | `XIP_CACHE_NUM_BLOCKS` | number of blocks in XIP cache; has to be a power of two
| | `XIP_CACHE_BLOCK_SIZE` | number of bytes per XIP cache block; has to be a power of two, min 4
| CPU interrupts: | none |
|=======================
**Overview**
The execute in-place (XIP) module allows to execute code (and read constant data) directly from an external SPI flash memory.
The standard serial peripheral interface (SPI) is used as transfer protocol. All bus requests issued by the CPU
are converted transparently into SPI flash access commands. Hence, the external XIP flash behaves like a simple on-chip ROM.
From the CPU side, the modules provides two independent interfaces: one for transparently accessing the XIP flash and another
one for accessing the module's control and status registers. The first interface provides the _transparent_
gateway to the SPI flash, so the CPU can directly fetch and execute instructions and/or read constant data.
Note that this interface is read-only. Any write access will raise a bus error exception. The second interface is
mapped to the processor's IO space and allows accesses to the XIP module's configuration registers as well as
conducting individual SPI transfers.
The XIP module provides an optional configurable cache to accelerate SPI flash accesses.
.XIP Address Mapping
[NOTE]
When XIP mode is enabled the flash is mapped to fixed address space region starting at address
`0xE0000000` (see section <<_address_space>>) supporting a maximum flash size of 256MB.
.XIP Example Program
[TIP]
An example program is provided in `sw/example/demo_xip` that illustrate how to program and configure
an external SPI flash to run a program from it.
**SPI Configuration**
The XIP module accesses external flash using the standard SPI protocol. The module always sends data MSB-first and
provides all of the standard four clock modes (0..3), which are configured via the `XIP_CTRL_CPOL` (clock polarity)
and `XIP_CTRL_CPHA` (clock phase) control register bits, respectively. The flash's "read command", which initiates
a read access, is defined by the `XIP_CTRL_RD_CMD` control register bits. For most SPI flash memories this is `0x03`
for _normal_ SPI mode.
The SPI clock (`xip_clk_o`) frequency is programmed by the 3-bit `XIP_CTRL_PRSCx` clock prescaler for a coarse clock
selection and a 4-bit clock divider `XPI_CTRL_CDIVx` for a fine clock selection.
The following clock prescalers (`XIP_CTRL_PRSCx`) are available:
.XIP clock prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
|=======================
| **`XIP_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================
Based on the programmed clock configuration, the actual SPI clock frequency f~SPI~ is derived
from the processor's main clock f~main~ according to the following equation:
_**f~SPI~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler` * (1 + `XPI_CTRL_CDIVx`))
Hence, the maximum SPI clock is f~main~ / 4 and the lowest SPI clock is f~main~ / 131072. The SPI clock is always
symmetric having a duty cycle of 50%.
**High-Speed Mode**
The XIP module provides a high-speed mode to further boost the maximum SPI clock frequency. When enabled via the control
register's `XIP_CTRL_HIGHSPEED` bit the clock prescaler configuration (`XIP_CTRL_PRSCx` bits) is overridden setting it
to a minimal factor of 1. However, the clock speed can still be fine-tuned using the `XPI_CTRL_CDIVx` bits.
_**f~SPI~**_ = _f~main~[Hz]_ / (2 * 1 * (1 + `XPI_CTRL_CDIVx`))
Hence, the maximum SPI clock when in high-speed mode is f~main~ / 2.
**Direct SPI Access**
The XIP module allows to initiate _direct_ SPI transactions. This feature can be used to configure the attached SPI
flash or to perform direct read and write accesses to the flash memory. Two data registers `DATA_LO` and
`DATA_HI` are provided to send up to 64-bit of SPI data. The `DATA_HI` register is write-only,
so a total of just 32-bits of receive data is provided. Note that the module handles the chip-select
line (`xip_csn_o`) by itself so it is not possible to construct larger consecutive transfers.
The actual data transmission size in bytes is defined by the control register's `XIP_CTRL_SPI_NBYTES` bits.
Any configuration from 1 byte to 8 bytes is valid. Other value will result in unpredictable behavior.
Since data is always transferred MSB-first, the data in `DATA_HI:DATA_LO` also has to be MSB-aligned. Receive data is
available in `DATA_LO` only since `DATA_HI` is write-only. Writing to `DATA_HI` triggers the actual SPI transmission.
The `XIP_CTRL_PHY_BUSY` control register flag indicates a transmission being in progress.
The chip-select line of the XIP module (`xip_csn_o`) will only become asserted (enabled, pulled low) if the
`XIP_CTRL_SPI_CSEN` control register bit is set. If this bit is cleared, `xip_csn_o` is always disabled
(pulled high).
[NOTE]
Direct SPI mode is only possible when the module is enabled (setting `XIP_CTRL_EN`) but **before** the actual
XIP mode is enabled via `XIP_CTRL_XIP_EN`.
[TIP]
When the XIP mode is not enabled, the XIP module can also be used as additional general purpose SPI controller
with a transfer size of up to 64 bits per transmission.
**Using the XIP Mode**
The XIP module is globally enabled by setting the `XIP_CTRL_EN` bit in the device's `CTRL` control register.
Clearing this bit will reset the whole module and will also terminate any pending SPI transfer.
Since there is a wide variety of SPI flash components with different sizes, the XIP module allows to specify
the address width of the flash: the number of address bytes used for addressing flash memory content has to be
configured using the control register's _XIP_CTRL_XIP_ABYTES_ bits. These two bits contain the number of SPI
address bytes (**minus one**). For example for a SPI flash with 24-bit addresses these bits have to be set to
`0b10`.
The transparent XIP accesses are transformed into SPI transmissions with the following format (starting with the MSB):
* 8-bit command: configured by the `XIP_CTRL_RD_CMD` control register bits ("SPI read command")
* 8 to 32 bits address: defined by the `XIP_CTRL_XIP_ABYTES` control register bits ("number of address bytes")
* 32-bit data: sending zeros and receiving the according flash word (32-bit)
Hence, the maximum XIP transmission size is 72-bit, which has to be configured via the `XIP_CTRL_SPI_NBYTES`
control register bits. Note that the 72-bit transmission size is only available in XIP mode. The transmission
size of the direct SPI accesses is limited to 64-bit.
[NOTE]
When using four SPI flash address bytes, the most significant 4 bits of the address are always hardwired
to zero allowing a maximum **accessible** flash size of 256MB.
[NOTE]
The XIP module always fetches a full naturally aligned 32-bit word from the SPI flash. Any sub-word data masking
or alignment will be performed by the CPU core logic.
[IMPORTANT]
The XIP mode requires the 4-byte data words in the flash to be ordered in **little-endian** byte order.
After the SPI properties (including the amount of address bytes **and** the total amount of SPI transfer bytes)
and XIP address mapping are configured, the actual XIP mode can be enabled by setting
the control register's `XIP_CTRL_XIP_EN` bit. This will enable the "transparent SPI access port" of the module and thus,
the _transparent_ conversion of access requests into proper SPI flash transmissions. Hence, any access to the processor's
memory-mapped XIP region (`0xE0000000` to `0xEFFFFFFF`) will be converted into SPI flash accesses.
Make sure `XIP_CTRL_SPI_CSEN` is also set so the module can actually select/enable the attached SPI flash.
No more direct SPI accesses via `DATA_HI:DATA_LO` are possible when the XIP mode is enabled. However, the
XIP mode can be disabled at any time.
[NOTE]
If the XIP module is disabled (_XIP_CTRL_EN_ = `0`) any accesses to the memory-mapped XIP flash address region
will raise a bus access exception. If the XIP module is enabled (_XIP_CTRL_EN_ = `1`) but XIP mode is not enabled
yet (_XIP_CTRL_XIP_EN_ = '0') any access to the programmed XIP memory segment will also raise a bus access exception.
[TIP]
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some
of the SPI access latency.
**XIP Cache**
Since every single instruction fetch request from the CPU is translated into serial SPI transmissions the access latency is
very high resulting in a low throughput. In order to improve performance, the XIP module provides an optional cache that
allows to buffer recently-accessed data. The cache is implemented as a simple direct-mapped read-only cache with a configurable
cache layout:
* `XIP_CACHE_EN`: when set to `true` the CIP cache is implemented
* `XIP_CACHE_NUM_BLOCKS` defines the number of cache blocks (or lines)
* `XIP_CACHE_BLOCK_SIZE` defines the size in bytes of each cache block
When the cache is implemented, the XIP module operates in **burst mode** utilizing the flash's _incremental read_ capabilities.
Thus, several bytes (= `XIP_CACHE_BLOCK_SIZE`) are read consecutively from the flash using a single read command.
The XIP cache is cleared when the XIP module is disabled (`XIP_CTRL_EN = 0`), when XIP mode is disabled
(`XIP_CTRL_XIP_EN = 0`) or when the CPU issues a `fence(.i)` instruction.
**Register Map**
.XIP Register Map (`struct NEORV32_XIP`)
[cols="<2,<1,<4,^1,<7"]
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.15+<| `0xffffff40` .15+<| `CTRL` <|`0` `XIP_CTRL_EN` ^| r/w <| XIP module enable
<|`3:1` `XIP_CTRL_PRSC2 : XIP_CTRL_PRSC0` ^| r/w <| 3-bit SPI clock prescaler select
<|`4` `XIP_CTRL_CPOL` ^| r/w <| SPI clock polarity
<|`5` `XIP_CTRL_CPHA` ^| r/w <| SPI clock phase
<|`9:6` `XIP_CTRL_SPI_NBYTES_MSB : XIP_CTRL_SPI_NBYTES_LSB` ^| r/w <| Number of bytes in SPI transaction (1..9)
<|`10` `XIP_CTRL_XIP_EN` ^| r/w <| XIP mode enable
<|`12:11` `XIP_CTRL_XIP_ABYTES_MSB : XIP_CTRL_XIP_ABYTES_LSB` ^| r/w <| Number of address bytes for XIP flash (minus 1)
<|`20:13` `XIP_CTRL_RD_CMD_MSB : XIP_CTRL_RD_CMD_LSB` ^| r/w <| Flash read command
<|`21` `XIP_CTRL_SPI_CSEN` ^| r/w <| Allow SPI chip-select to be actually asserted when set
<|`22` `XIP_CTRL_HIGHSPEED` ^| r/w <| enable SPI high-speed mode (ignoring `XIP_CTRL_PRSCx`)
<|`23:26` `XIP_CTRL_CDIV3 : XIP_CTRL_CDIV0` ^| r/- <| 4-bit clock divider for fine-tuning
<|`27:28` - ^| r/- <| _reserved_, read as zero
<|`29` `XIP_CTRL_BURST_EN` ^| r/- <| XIP burst mode enabled (if XIP cache is implemented)
<|`30` `XIP_CTRL_PHY_BUSY` ^| r/- <| SPI PHY busy when set
<|`31` `XIP_CTRL_XIP_BUSY` ^| r/- <| XIP access in progress when set
| `0xffffff44` | _reserved_ |`31:0` | r/- | _reserved_, read as zero
| `0xffffff48` | `DATA_LO` |`31:0` | r/w | Direct SPI access - data register low
| `0xffffff4C` | `DATA_HI` |`31:0` | -/w | Direct SPI access - data register high; write access triggers SPI transfer
|=======================