225 lines
14 KiB
Text
225 lines
14 KiB
Text
<<<
|
|
:sectnums:
|
|
==== Execute In Place Module (XIP)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_xip.vhd |
|
|
| Software driver file(s): | neorv32_xip.c |
|
|
| | neorv32_xip.h |
|
|
| Top entity port: | `xip_csn_o` | 1-bit chip select, low-active
|
|
| | `xip_clk_o` | 1-bit serial clock output
|
|
| | `xip_sdi_i` | 1-bit serial data input
|
|
| | `xip_sdo_o` | 1-bit serial data output
|
|
| Configuration generics: | _IO_XIP_EN_ | implement XIP module when _true_
|
|
| CPU interrupts: | none |
|
|
|=======================
|
|
|
|
|
|
**Overview**
|
|
|
|
The execute in place (XIP) module is probably one of the more complicated modules of the NEORV32. The module
|
|
allows to execute code (and read constant data) directly from a SPI flash memory. Hence, it uses the standard
|
|
serial peripheral interface (SPI) as transfer protocol under the hood.
|
|
|
|
The XIP flash is not mapped to a specific region of the processor's address space. Instead, the XIP module
|
|
provides a programmable mapping scheme to allow a flexible user-defined mapping of the flash to _any section_
|
|
of the address space.
|
|
|
|
From the CPU side, the modules provides two different interfaces: one for transparently accessing the XIP flash and another
|
|
one for accessing the module's control and status registers. The first interface provides a _transparent_
|
|
gateway to the SPI flash, so the CPU can directly fetch and execute instructions (and/or read constant _data_).
|
|
Note that this interface is read-only. Any write access will raise a bus error exception.
|
|
The second interface is mapped to the processor's IO space and allows data accesses to the XIP module's
|
|
configuration registers.
|
|
|
|
.Example Program
|
|
[TIP]
|
|
An example program for the XIP module is available in `sw/example/demo_xip`.
|
|
|
|
.Compiling a Program for XIP Execution
|
|
[NOTE]
|
|
If you want to compile a program that shall be executed using the XIP module, the default NEORV32 linker script
|
|
(`sw/common/neorv32.ld`) has to be modified: the `ORIGIN` attribute of the `rom` section needs to be adapted to
|
|
the XIP page base address and the flash base address. For example if the XIP page is set to `0x20000000` and the
|
|
executable is placed in the flash as offset `0x00400000` the `ORIGIN` attribute has to be set to the sum of both
|
|
address offsets (`0x20000000 + 0x00400000 = 0x20400000` -> `rom (rx) : ORIGIN = DEFINED(make_bootloader) ? 0xFFFF0000 : 0x20400000`).
|
|
See sections <<_linker_script>>, <<_application_makefile>> and <<_executable_image_generator>> for more information.
|
|
|
|
|
|
**SPI Protocol**
|
|
|
|
The XIP module accesses external flash using the standard SPI protocol. The module always sends data MSB-first and
|
|
provides all of the standard four clock modes (0..3), which are configured via the _XIP_CTRL_CPOL_ (clock polarity)
|
|
and _XIP_CTRL_CPHA_ (clock phase) control register bits, respectively. The clock speed of the interface (`xip_clk_o`)
|
|
is defined by a three-bit clock pre-scaler configured using the _XIP_CTRL_PRSCx_ bits:
|
|
|
|
.XIP prescaler configuration
|
|
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
|
|
[options="header",grid="rows"]
|
|
|=======================
|
|
| **`XIP_CTRL_PRSCx`** | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
|
|
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|
|
|=======================
|
|
|
|
Based on the _XIP_CTRL_PRSCx_ configuration the actual XIP SPI clock frequency f~XIP~ is derived from the processor's
|
|
main clock f~main~ and is determined by:
|
|
|
|
_**f~XIP~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)
|
|
|
|
Hence, the maximum XIP clock speed is f~main~ / 4.
|
|
|
|
.High-Speed SPI mode
|
|
[TIP]
|
|
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (_XIP_CTRL_PRSCx_) is ignored
|
|
and the SPI clock operates at f~main~ / 2 (half of the processor's main clock). High speed SPI mode is enabled by setting
|
|
the control register's _XIP_CTRL_HIGHSPEED_ bit.
|
|
|
|
The flash's "read command", which initiates a read access, is defined by the _XIP_CTRL_RD_CMD_ control register bits.
|
|
For most SPI flash memories this is `0x03` for normal SPI mode.
|
|
|
|
|
|
**Direct SPI Access**
|
|
|
|
The XIP module allows to initiate _direct_ SPI transactions. This feature can be used to configure the attached SPI
|
|
flash or to perform direct read and write accesses to the flash memory. Two data registers `NEORV32_XIP.DATA_LO` and
|
|
`NEORV32_XIP.DATA_HI` are provided to send up to 64-bit of SPI data. The `NEORV32_XIP.DATA_HI` register is write-only,
|
|
so a total of 32-bit receive data is provided. Note that the module handles the chip-select
|
|
line (`xip_csn_o`) by itself so it is not possible to construct larger consecutive transfers.
|
|
|
|
The actual data transmission size in bytes is defined by the control register's _XIP_CTRL_SPI_NBYTES_ bits.
|
|
Any configuration from 1 byte to 8 bytes is valid. Other value will result in unpredictable behavior.
|
|
|
|
Since data is always transferred MSB-first, the data in `DATA_HI:DATA_LO` also has to be MSB-aligned. Receive data is
|
|
available in `DATA_LO` only - `DATA_HI` is write-only. Writing to `DATA_HI` triggers the actual SPI transmission.
|
|
The _XIP_CTRL_PHY_BUSY_ control register flag indicates a transmission being in progress.
|
|
|
|
The chip-select line of the XIP module (`xip_csn_o`) will only become asserted (enabled, pulled low) if the
|
|
_XIP_CTRL_SPI_CSEN_ control register bit is set. If this bit is cleared, `xip_csn_o` is always disabled
|
|
(pulled high).
|
|
|
|
[NOTE]
|
|
Direct SPI mode is only possible when the module is enabled (setting _XIP_CTRL_EN_) but **before** the actual
|
|
XIP mode is enabled via _XIP_CTRL_XIP_EN_.
|
|
|
|
[TIP]
|
|
When the XIP mode is not enabled, the XIP module can also be used as additional general purpose SPI controller
|
|
with a transfer size of up to 64 bits per transmission.
|
|
|
|
|
|
**Address Mapping**
|
|
|
|
The address mapping of the XIP flash is not fixed by design. It can be mapped to _any section_ within the processor's
|
|
address space. A _section_ refers to one out of 16 naturally aligned 256MB wide memory segments. This segment
|
|
is defined by the four most significant bits of the address (`31:28`) and the XIP's segment is programmed by the
|
|
four _XIP_CTRL_XIP_PAGE_ bits in the unit's control register. All accesses within this page will be mapped to the XIP flash.
|
|
|
|
[NOTE]
|
|
Care must be taken when programming the page mapping to prevent access collisions with other modules (like internal memories
|
|
or modules attached to the external memory interface).
|
|
|
|
Example: to map the XIP flash to the address space starting at `0x20000000` write a "2" (`0b0010`) to the _XIP_CTRL_XIP_PAGE_
|
|
control register bits. Any access within `0x20000000 .. 0x2fffffff` will be forwarded to the XIP flash.
|
|
Note that the SPI access address might wrap around.
|
|
|
|
.Using the FPGA Bitstream Flash also for XIP
|
|
[TIP]
|
|
You can also use the FPGA's bitstream SPI flash for storing XIP programs. To prevent overriding the bitstream,
|
|
a certain offset needs to be added to the executable (which might require linker script modifications).
|
|
To execute the program stored in the SPI flash simply jump to the according base address. For example
|
|
if the executable starts at flash offset `0x8000` and the XIP flash is mapped to the base address `0x20000000`
|
|
then add the offset to the base address and use that as jump/call destination (=`0x20008000`).
|
|
|
|
|
|
**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. Make sure _XIP_CTRL_SPI_CSEN_
|
|
is also set so the module can actually select/enable the attached SPI flash.
|
|
No more direct SPI accesses via `DATA_HI:DATA_LO` are possible when the XIP mode is enabled. However, the
|
|
XIP mode can be disabled at any time.
|
|
|
|
[NOTE]
|
|
If the XIP module is disabled (_XIP_CTRL_EN_ = `0`) any accesses to the programmed XIP memory segment are ignored
|
|
by the module and might be forwarded to the processor's external memory interface (if implemented) or will cause a bus
|
|
exception. If the XIP module is enabled (_XIP_CTRL_EN_ = `1`) but XIP mode is not enabled yet (_XIP_CTRL_XIP_EN_ = '0')
|
|
any access to the programmed XIP memory segment will raise a bus exception.
|
|
|
|
[TIP]
|
|
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some
|
|
of the SPI access latency.
|
|
|
|
|
|
**XIP Burst Mode**
|
|
|
|
By default, every XIP access to the flash transmits the read command and the word-aligned address before reading four consecutive
|
|
data bytes. Obviously, this introduces a certain transmission overhead. To reduces this overhead, the XIP mode allows to utilize
|
|
the flash's _incrmental read_ function, which will return consecutive bytes when continuing to send clock cycles after a read command.
|
|
Hence, the XIP module provides an optional "burst mode" to accelerate consecutive read accesses.
|
|
|
|
The XIP burst mode is enabled by setting the _XIP_CTRL_BURST_EN_ bit in the module's control register. The burst mode only affects
|
|
the actual XIP mode and _not_ the direct SPI mode. Hence, it should be enabled right before enabling XIP mode only.
|
|
By using the XIP burst mode flash read accesses can be accelerated by up to 50%.
|
|
|
|
|
|
**Register Map**
|
|
|
|
.XIP Register Map (`struct NEORV32_XIP`)
|
|
[cols="<2,<2,<4,^1,<7"]
|
|
[options="header",grid="all"]
|
|
|=======================
|
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
|
|
.17+<| `0xffffff40` .17+<| `NEORV32_XIP.CTRL` <|`0` _XIP_CTRL_EN_ ^| r/w <| XIP module enable
|
|
<|`1` _XIP_CTRL_PRSC0_ ^| r/w .3+| 3-bit SPI clock prescaler select
|
|
<|`2` _XIP_CTRL_PRSC1_ ^| r/w
|
|
<|`3` _XIP_CTRL_PRSC2_ ^| r/w
|
|
<|`4` _XIP_CTRL_CPOL_ ^| r/w <| SPI clock polarity
|
|
<|`5` _XIP_CTRL_CPHA_ ^| r/w <| SPI clock phase
|
|
<|`9:6` _XIP_CTRL_SPI_NBYTES_MSB_ : _XIP_CTRL_SPI_NBYTES_LSB_ ^| r/w <| Number of bytes in SPI transaction (1..9)
|
|
<|`10` _XIP_CTRL_XIP_EN_ ^| r/w <| XIP mode enable
|
|
<|`12:11` _XIP_CTRL_XIP_ABYTES_MSB_ : _XIP_CTRL_XIP_ABYTES_LSB_ ^| r/w <| Number of address bytes for XIP flash (minus 1)
|
|
<|`20:13` _XIP_CTRL_RD_CMD_MSB_ : _XIP_CTRL_RD_CMD_LSB_ ^| r/w <| Flash read command
|
|
<|`24:21` _XIP_CTRL_XIP_PAGE_MSB_ : _XIP_CTRL_XIP_PAGE_LSB_ ^| r/w <| XIP memory page
|
|
<|`25` _XIP_CTRL_SPI_CSEN_ ^| r/w <| Allow SPI chip-select to be actually asserted when set
|
|
<|`26` _XIP_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _XIP_CTRL_PRSC_)
|
|
<|`27` _XIP_CTRL_BURST_EN_ ^| r/w <| Enable XIP burst mode
|
|
<|`29:28` ^| r/- <| _reserved_, read as zero
|
|
<|`30` _XIP_CTRL_PHY_BUSY_ ^| r/- <| SPI PHY busy when set
|
|
<|`31` _XIP_CTRL_XIP_BUSY_ ^| r/- <| XIP access in progress when set
|
|
| `0xffffff44` | _reserved_ |`31:0` | r/- | _reserved_, read as zero
|
|
| `0xffffff48` | `NEORV32_XIP.DATA_LO` |`31:0` | r/w | Direct SPI access - data register low
|
|
| `0xffffff4C` | `NEORV32_XIP.DATA_HI` |`31:0` | -/w | Direct SPI access - data register high; write access triggers SPI transfer
|
|
|=======================
|