OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_xip.adoc] - Diff between revs 70 and 72

Only display areas with differences | Details | Blame | View Log

Rev 70 Rev 72
<<<
<<<
:sectnums:
:sectnums:
==== Execute In Place Module (XIP)
==== Execute In Place Module (XIP)
[cols="<3,<3,<4"]
[cols="<3,<3,<4"]
[frame="topbot",grid="none"]
[frame="topbot",grid="none"]
|=======================
|=======================
| Hardware source file(s): | neorv32_xip.vhd |
| Hardware source file(s): | neorv32_xip.vhd |
| Software driver file(s): | neorv32_xip.c |
| Software driver file(s): | neorv32_xip.c |
|                          | neorv32_xip.h |
|                          | neorv32_xip.h |
| Top entity port:         | `xip_csn_o` | 1-bit chip select, low-active
| Top entity port:         | `xip_csn_o` | 1-bit chip select, low-active
|                          | `xip_clk_o` | 1-bit serial clock output
|                          | `xip_clk_o` | 1-bit serial clock output
|                          | `xip_sdi_i` | 1-bit serial data input
|                          | `xip_sdi_i` | 1-bit serial data input
|                          | `xip_sdo_o` | 1-bit serial data output
|                          | `xip_sdo_o` | 1-bit serial data output
| Configuration generics:  | _IO_XIP_EN_ | implement XIP module when _true_
| Configuration generics:  | _IO_XIP_EN_ | implement XIP module when _true_
| CPU interrupts:          | none |
| CPU interrupts:          | none |
|=======================
|=======================
**Overview**
**Overview**
The execute in place (XIP) module is probably one of the more complicated modules of the NEORV32. The module
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
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.
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
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_
provides a programmable mapping scheme to allow a flexible user-defined mapping of the flash to _any section_
of the address space.
of the address space.
From the CPU side, the modules provides two different interfaces: one for transparently accessing the XIP flash and another
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_
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_).
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.
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
The second interface is mapped to the processor's IO space and allows data accesses to the XIP module's
configuration registers.
configuration registers.
[TIP]
[TIP]
An example program for the XIP module is available in `sw/example/demo_xip`.
An example program for the XIP module is available in `sw/example/demo_xip`.
 
 
[WARNING]
 
Debugging XIP code execution using the on-chip debugger is constrained. The debugger cannot insert breakpoints
 
(`ebreak` instructions) into XIP code as the XIP access is read-only.
 
 
 
[NOTE]
[NOTE]
Quad-SPI (QSPI) support, which is about 4x times faster, is planned for the future. 😉
Quad-SPI (QSPI) support, which is about 4x times faster, is planned for the future. 😉
**SPI Protocol**
**SPI Protocol**
The XIP module accesses external flash using the standard SPI protocol. The module always sends data MSB-first and
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)
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`)
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:
is defined by a three-bit clock pre-scaler configured using the _XIP_CTRL_PRSCx_ bits:
.XIP prescaler configuration
.XIP prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
[options="header",grid="rows"]
[options="header",grid="rows"]
|=======================
|=======================
| **`XIP_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| **`XIP_CTRL_PRSCx`**        | `0b000` | `0b001` | `0b010` | `0b011` | `0b100` | `0b101` | `0b110` | `0b111`
| Resulting `clock_prescaler` |       2 |       4 |       8 |      64 |     128 |    1024 |    2048 |    4096
| 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
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:
main clock f~main~ and is determined by:
_**f~XIP~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)
_**f~XIP~**_ = _f~main~[Hz]_ / (2 * `clock_prescaler`)
Hence, the maximum XIP clock speed is f~main~ / 4.
Hence, the maximum XIP clock speed is f~main~ / 4.
.High-Speed SPI mode
.High-Speed SPI mode
[TIP]
[TIP]
The module provides a "high-speed" SPI mode. In this mode the clock prescaler configuration (_XIP_CTRL_PRSCx_) is ignored
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
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 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.
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.
For most SPI flash memories this is `0x03` for normal SPI mode.
**Direct SPI Access**
**Direct SPI Access**
The XIP module allows to initiate _direct_ SPI transactions. This feature can be used to configure the attached SPI
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
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,
`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
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.
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.
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.
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
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.
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 _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
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
_XIP_CTRL_SPI_CSEN_ control register bit is set. If this bit is cleared, `xip_csn_o` is always disabled
(pulled high).
(pulled high).
[NOTE]
[NOTE]
Direct SPI mode is only possible when the module is enabled (setting _XIP_CTRL_EN_) but **before** the actual
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_.
XIP mode is enabled via _XIP_CTRL_XIP_EN_.
[TIP]
[TIP]
When the XIP mode is not enabled, the XIP module can also be used as additional general purpose SPI controller
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.
with a transfer size of up to 64 bits per transmission.
**Address Mapping**
**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
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
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
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.
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]
[NOTE]
Care must be taken when programming the page mapping to prevent access collisions with other modules (like internal memories
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).
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_
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.
control register bits. Any access within `0x20000000 .. 0x2fffffff` will be forwarded to the XIP flash.
Note that the SPI access address might wrap around.
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**
**Using the XIP Mode**
The XIP module is globally enabled by setting the _XIP_CTRL_EN_ bit in the device's `CTRL` control register.
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.
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
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
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
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
address bytes (**minus one**). For example for a SPI flash with 24-bit addresses these bits have to be set to
`0b10`.
`0b10`.
The transparent XIP accesses are transformed into SPI transmissions with the following format (starting with the MSB):
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-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")
* 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)
* 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_
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
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.
size of the direct SPI accesses is limited to 64-bit.
[NOTE]
[NOTE]
There is no _continuous read_ feature (i.e. a burst SPI transmission fetching several data words at once) implemented yet.
There is no _continuous read_ feature (i.e. a burst SPI transmission fetching several data words at once) implemented yet.
[NOTE]
[NOTE]
When using four SPI flash address bytes, the most significant 4 bits of the address are always hardwired
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.
to zero allowing a maximum **accessible** flash size of 256MB.
After the SPI properties (including the amount of address bytes **and** the total amount of SPI transfer bytes)
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
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 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_
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.
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
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.
XIP mode can be disabled at any time.
[NOTE]
[NOTE]
If the XIP module is disabled (_XIP_CTRL_EN_ = `0`) any accesses to the programmed XIP memory segment are ignored
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
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')
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.
any access to the programmed XIP memory segment will raise a bus exception.
[TIP]
[TIP]
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some
It is highly recommended to enable the <<_processor_internal_instruction_cache_icache>> to cover some
of the SPI access latency.
of the SPI access latency.
.XIP register map (`struct NEORV32_XIP`)
.XIP register map (`struct NEORV32_XIP`)
[cols="<2,<2,<4,^1,<7"]
[cols="<2,<2,<4,^1,<7"]
[options="header",grid="all"]
[options="header",grid="all"]
|=======================
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.16+<| `0xffffff40` .16+<| `NEORV32_XIP.CTRL` <|`0`  _XIP_CTRL_EN_    ^| r/w <| XIP module enable
.16+<| `0xffffff40` .16+<| `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
                                              <|`1`  _XIP_CTRL_PRSC0_ ^| r/w .3+| 3-bit SPI clock prescaler select
                                              <|`2`  _XIP_CTRL_PRSC1_ ^| r/w
                                              <|`2`  _XIP_CTRL_PRSC1_ ^| r/w
                                              <|`3`  _XIP_CTRL_PRSC2_ ^| r/w
                                              <|`3`  _XIP_CTRL_PRSC2_ ^| r/w
                                              <|`4`  _XIP_CTRL_CPOL_  ^| r/w <| SPI clock polarity
                                              <|`4`  _XIP_CTRL_CPOL_  ^| r/w <| SPI clock polarity
                                              <|`5`  _XIP_CTRL_CPHA_  ^| r/w <| SPI clock phase
                                              <|`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)
                                              <|`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
                                              <|`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)
                                              <|`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
                                              <|`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
                                              <|`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
                                              <|`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_)
                                              <|`26` _XIP_CTRL_HIGHSPEED_ ^| r/w <| enable SPI high-speed mode (ignoring _XIP_CTRL_PRSC_)
                                              <|`29:27`                   ^| r/- <| _reserved_, read as zero
                                              <|`29:27`                   ^| r/- <| _reserved_, read as zero
                                              <|`30` _XIP_CTRL_PHY_BUSY_  ^| r/- <| SPI PHY busy when set
                                              <|`30` _XIP_CTRL_PHY_BUSY_  ^| r/- <| SPI PHY busy when set
                                              <|`31` _XIP_CTRL_XIP_BUSY_  ^| r/- <| XIP access in progress when set
                                              <|`31` _XIP_CTRL_XIP_BUSY_  ^| r/- <| XIP access in progress when set
| `0xffffff44` | _reserved_            |`31:0` | r/- | _reserved_, read as zero
| `0xffffff44` | _reserved_            |`31:0` | r/- | _reserved_, read as zero
| `0xffffff48` | `NEORV32_XIP.DATA_LO` |`31:0` | r/w | Direct SPI access - data register low
| `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
| `0xffffff4C` | `NEORV32_XIP.DATA_HI` |`31:0` | -/w | Direct SPI access - data register high; write access triggers SPI transfer
|=======================
|=======================
 
 

powered by: WebSVN 2.1.0

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