Line 44... |
Line 44... |
via the external memory bus interface or use some of the processor's GPIO ports to implement custom data
|
via the external memory bus interface or use some of the processor's GPIO ports to implement custom data
|
tag signals.
|
tag signals.
|
|
|
**Theory of Operation**
|
**Theory of Operation**
|
|
|
The SLINK provides eight data registers (_SLINK_CHx_) to access the links (read accesses will access the RX links, write
|
The SLINK provides eight data registers (`DATA[i]`) to access the links (read accesses will access the RX links, write
|
accesses will access the TX links), one control register (_SLINK_CT_) and one status register (_SLINK_STATUS_).
|
accesses will access the TX links), one control register (`CTRL`) and one status register (`STATUS`).
|
|
|
The SLINK is globally activated by setting the control register's enable bit _SLINK_CT_EN_.
|
The SLINK is globally activated by setting the control register's enable bit _SLINK_CTRL_EN_.
|
The actual data links are accessed by reading or writing the according link data registers _SLINK_CH0_
|
The actual data links are accessed by reading or writing the according link data registers `DATA[0]`
|
to _SLINK_CH7_. For example, writing the _SLINK_CH0_ will put the according data into the FIFO of TX link 0.
|
to `DATA[7]`. For example, writing the `DATA[0]` will put the according data into the FIFO of TX link 0.
|
Accordingly, reading from _SLINK_CH0_ will return one data word from the FIFO of RX link 0.
|
Accordingly, reading from `DATA[0]` will return one data word from the FIFO of RX link 0.
|
|
|
The configuration (done via the SLINK generics) can be checked by software by evaluating bit fields in the
|
The configuration (done via the SLINK generics) can be checked by software by evaluating bit fields in the
|
control register. The _SLINK_CT_TX_FIFO_Sx_ and _SLINK_CT_RX_FIFO_Sx_ indicate the TX & RX FIFO sizes.
|
control register. The _SLINK_CTRL_TX_FIFO_Sx_ and _SLINK_CTRL_RX_FIFO_Sx_ indicate the TX & RX FIFO sizes.
|
The _SLINK_CT_TX_NUMx_ and _SLINK_CT_RX_NUMx_ bits represent the absolute number of implemented TX and RX links.
|
The _SLINK_CTRL_TX_NUMx_ and _SLINK_CTRL_RX_NUMx_ bits represent the absolute number of implemented TX and RX links.
|
|
|
The status register shows the FIFO status flags of each RX and TX link. The _SLINK_CT_RXx_AVAIL_ flags indicate
|
The status register shows the FIFO status flags of each RX and TX link. The _SLINK_CTRL_RXx_AVAIL_ flags indicate
|
that there is _at least_ one data word in the according RX link's FIFO. The _SLINK_CT_TXx_FREE_ flags indicate
|
that there is _at least_ one data word in the according RX link's FIFO. The _SLINK_CTRL_TXx_FREE_ flags indicate
|
there is _at least_ one free entry in the according TX link's FIFO. The _SLINK_STATUS_RXx_HALF_ and
|
there is _at least_ one free entry in the according TX link's FIFO. The _SLINK_STATUS_RXx_HALF_ and
|
_SLINK_STATUS_RXx_HALF_ flags show if a certain FIFO's fill level has exceeded half of its capacity.
|
_SLINK_STATUS_RXx_HALF_ flags show if a certain FIFO's fill level has exceeded half of its capacity.
|
|
|
|
|
**Blocking Link Access**
|
**Blocking Link Access**
|
|
|
When directly accessing the link data registers (without checking the according FIFO status flags) the access
|
When directly accessing the link data registers (without checking the according FIFO status flags) the access
|
is as _blocking_. That means the CPU access will stall until the accessed link responds. For
|
is as _blocking_. That means the CPU access will stall until the accessed link responds. For
|
example, when reading RX link 0 (via _SLINK_CH0_ register) the CPU will stall, if there is not data
|
example, when reading RX link 0 (via `DATA[0]` register) the CPU will stall, if there is not data
|
available in the according FIFO yet. The CPU access will complete as soon as RX link 0 receives new data.
|
available in the according FIFO yet. The CPU access will complete as soon as RX link 0 receives new data.
|
|
|
Vice versa, writing data to TX link 0 (via _SLINK_CH0_ register) will stall the CPU access until there is
|
Vice versa, writing data to TX link 0 (via `DATA[0]` register) will stall the CPU access until there is
|
at least one free entry in the link's FIFO.
|
at least one free entry in the link's FIFO.
|
|
|
[WARNING]
|
[WARNING]
|
The NEORV32 processor ensures that _any_ CPU access to memory-mapped devices (including the SLINK module)
|
The NEORV32 processor ensures that _any_ CPU access to memory-mapped devices (including the SLINK module)
|
will **time out** after a certain number of cycles (see section <<_bus_interface>>).
|
will **time out** after a certain number of cycles (see section <<_bus_interface>>).
|
Line 82... |
Line 82... |
from an _empty_ RX link. Hence, this concept should only be used when evaluating the half-full FIFO condition
|
from an _empty_ RX link. Hence, this concept should only be used when evaluating the half-full FIFO condition
|
(for example via the SLINK interrupts) before actual accessing links.
|
(for example via the SLINK interrupts) before actual accessing links.
|
|
|
**Non-Blocking Link Access**
|
**Non-Blocking Link Access**
|
|
|
For a non-blocking link access concept, the FIFO status flags in _SLINK_STATUS_ need to be checked _before_
|
For a non-blocking link access concept, the FIFO status flags in `STATUS` need to be checked _before_
|
reading/writing the actual link data register. For example, a non-blocking write access to a TX link 0 has
|
reading/writing the actual link data register. For example, a non-blocking write access to a TX link 0 has
|
to check _SLINK_STATUS_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data word
|
to check _SLINK_STATUS_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data word
|
and the actual data can be written to _SLINK_CH0_. If the bit is cleared, the link's FIFO is full
|
and the actual data can be written to `DATA[0]`. If the bit is cleared, the link's FIFO is full
|
and the status flag can be polled until it there is free space in the available.
|
and the status flag can be polled until it there is free space in the available.
|
|
|
This concept will not raise any exception as there is no "direct" access to the link data registers.
|
This concept will not raise any exception as there is no "direct" access to the link data registers.
|
However, non-blocking accesses require additional instructions to check the according status flags prior
|
However, non-blocking accesses require additional instructions to check the according status flags prior
|
to the actual link access, which will reduce performance for high-bandwidth data streams.
|
to the actual link access, which will reduce performance for high-bandwidth data streams.
|
Line 109... |
Line 109... |
The interrupt service handler has to evaluate the SLINK status register is order to detect which link(s) has caused the
|
The interrupt service handler has to evaluate the SLINK status register is order to detect which link(s) has caused the
|
interrupt. No further interrupt can fire until the CPU acknowledges the last interrupt by _reading the SLINK status register_.
|
interrupt. No further interrupt can fire until the CPU acknowledges the last interrupt by _reading the SLINK status register_.
|
However, further IRQ conditions are buffered and will trigger another interrupt after the current one has been acknowledged.
|
However, further IRQ conditions are buffered and will trigger another interrupt after the current one has been acknowledged.
|
|
|
Note that these interrupts can only fire if the SLINK module is actually enabled by setting the
|
Note that these interrupts can only fire if the SLINK module is actually enabled by setting the
|
_SLINK_CT_EN_ bit in the unit's control register.
|
_SLINK_CTRL_EN_ bit in the unit's control register.
|
|
|
**Stream Link Interface & Protocol**
|
**Stream Link Interface & Protocol**
|
|
|
The SLINK interface consists of three signals `dat`, `val` and `rdy` for each RX and TX link.
|
The SLINK interface consists of three signals `dat`, `val` and `rdy` for each RX and TX link.
|
Each signal is an "array" with eight entires (one for each link). Note that an entry in `slink_*x_dat` is 32-bit
|
Each signal is an "array" with eight entires (one for each link). Note that an entry in `slink_*x_dat` is 32-bit
|
Line 131... |
Line 131... |
image::stream_link_interface.png[width=560,align=center]
|
image::stream_link_interface.png[width=560,align=center]
|
|
|
[TIP]
|
[TIP]
|
The SLINK handshake protocol is compatible with the https://developer.arm.com/documentation/ihi0051/a/Introduction/About-the-AXI4-Stream-protocol[AXI4-Stream] base protocol.
|
The SLINK handshake protocol is compatible with the https://developer.arm.com/documentation/ihi0051/a/Introduction/About-the-AXI4-Stream-protocol[AXI4-Stream] base protocol.
|
|
|
.SLINK register map
|
.SLINK register map (`struct NEORV32_SLINK`)
|
[cols="^4,<5,^2,^2,<14"]
|
[cols="^4,<5,^2,^2,<14"]
|
[options="header",grid="all"]
|
[options="header",grid="all"]
|
|=======================
|
|=======================
|
| Address | Name [C] | Bit(s) | R/W | Function
|
| Address | Name [C] | Bit(s) | R/W | Function
|
.6+<| `0xfffffec0` .6+<| _SLINK_CT_ <| `31` _SLINK_CT_EN_ ^| r/w | SLINK global enable
|
.6+<| `0xfffffec0` .6+<| `NEORV32_SLINK.CTRL` <| `31` _SLINK_CTRL_EN_ ^| r/w | SLINK global enable
|
<| `30:16` _reserved_ ^| r/- <| reserved, read as zero
|
<| `30:16` _reserved_ ^| r/- <| reserved, read as zero
|
<| `15:12` _SLINK_CT_TX_FIFO_S3_ : _SLINK_CT_TX_FIFO_S0_ ^| r/- <| TX links FIFO depth, log2 of_SLINK_TX_FIFO_ generic
|
<| `15:12` _SLINK_CTRL_TX_FIFO_S3_ : _SLINK_CTRL_TX_FIFO_S0_ ^| r/- <| TX links FIFO depth, log2 of_SLINK_TX_FIFO_ generic
|
<| `11:8` _SLINK_CT_RX_FIFO_S3_ : _SLINK_CT_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic
|
<| `11:8` _SLINK_CTRL_RX_FIFO_S3_ : _SLINK_CTRL_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic
|
<| `7:4` _SLINK_CT_TX_NUM3_ : _SLINK_CT_TX_NUM0_ ^| r/- <| Number of implemented TX links
|
<| `7:4` _SLINK_CTRL_TX_NUM3_ : _SLINK_CTRL_TX_NUM0_ ^| r/- <| Number of implemented TX links
|
<| `3:0` _SLINK_CT_RX_NUM3_ : _SLINK_CT_RX_NUM0_ ^| r/- <| Number of implemented RX links
|
<| `3:0` _SLINK_CTRL_RX_NUM3_ : _SLINK_CTRL_RX_NUM0_ ^| r/- <| Number of implemented RX links
|
| `0xfffffec4` : `0xfffffeec` | _SLINK_CT_ |`31:0` | | _mirrored control register_
|
| `0xfffffec4` : `0xfffffeec` | - |`31:0` | | _reserved
|
.4+<| `0xfffffed0` .4+<| _SLINK_STATUS_ <| `31:24` _SLINK_STATUS_TX7_HALF_ : _SLINK_STATUS_TX0_HALF_ ^| r/- | TX link 7..0 FIFO fill level is > half-full
|
.4+<| `0xfffffed0` .4+<| `NEORV32_SLINK.STATUS` <| `31:24` _SLINK_STATUS_TX7_HALF_ : _SLINK_STATUS_TX0_HALF_ ^| r/- | TX link 7..0 FIFO fill level is > half-full
|
<| `23:16` _SLINK_STATUS_RX7_HALF_ : _SLINK_STATUS_RX0_HALF_ ^| r/- <| RX link 7..0 FIFO fill level is >= half-full
|
<| `23:16` _SLINK_STATUS_RX7_HALF_ : _SLINK_STATUS_RX0_HALF_ ^| r/- <| RX link 7..0 FIFO fill level is >= half-full
|
<| `15:8` _SLINK_CT_TX7_FREE_ : _SLINK_CT_TX0_FREE_ ^| r/- <| At least one free TX FIFO entry available for link 7..0
|
<| `15:8` _SLINK_STATUS_TX7_FREE_ : _SLINK_STATUS_TX0_FREE_ ^| r/- <| At least one free TX FIFO entry available for link 7..0
|
<| `7:0` _SLINK_CT_RX7_AVAIL_ : _SLINK_CT_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 7..0
|
<| `7:0` _SLINK_STATUS_RX7_AVAIL_ : _SLINK_STATUS_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 7..0
|
| `0xfffffed4` : `0xfffffedc` | _SLINK_STATUS_ |`31:0` | | _mirrored status register_
|
| `0xfffffed4` : `0xfffffedc` | - |`31:0` | | _reserved_
|
| `0xfffffee0` | _SLINK_CH0_ | `31:0` | r/w | Link 0 RX/TX data
|
| `0xfffffee0` | `NEORV32_SLINK.DATA[0]` | `31:0` | r/w | Link 0 RX/TX data
|
| `0xfffffee4` | _SLINK_CH1_ | `31:0` | r/w | Link 1 RX/TX data
|
| `0xfffffee4` | `NEORV32_SLINK.DATA[1]` | `31:0` | r/w | Link 1 RX/TX data
|
| `0xfffffee8` | _SLINK_CH2_ | `31:0` | r/w | Link 2 RX/TX data
|
| `0xfffffee8` | `NEORV32_SLINK.DATA[2]` | `31:0` | r/w | Link 2 RX/TX data
|
| `0xfffffeec` | _SLINK_CH3_ | `31:0` | r/w | Link 3 RX/TX data
|
| `0xfffffeec` | `NEORV32_SLINK.DATA[3]` | `31:0` | r/w | Link 3 RX/TX data
|
| `0xfffffef0` | _SLINK_CH4_ | `31:0` | r/w | Link 4 RX/TX data
|
| `0xfffffef0` | `NEORV32_SLINK.DATA[4]` | `31:0` | r/w | Link 4 RX/TX data
|
| `0xfffffef4` | _SLINK_CH5_ | `31:0` | r/w | Link 5 RX/TX data
|
| `0xfffffef4` | `NEORV32_SLINK.DATA[5]` | `31:0` | r/w | Link 5 RX/TX data
|
| `0xfffffef8` | _SLINK_CH6_ | `31:0` | r/w | Link 6 RX/TX data
|
| `0xfffffef8` | `NEORV32_SLINK.DATA[6]` | `31:0` | r/w | Link 6 RX/TX data
|
| `0xfffffefc` | _SLINK_CH7_ | `31:0` | r/w | Link 7 RX/TX data
|
| `0xfffffefc` | `NEORV32_SLINK.DATA[7]` | `31:0` | r/w | Link 7 RX/TX data
|
|=======================
|
|=======================
|