117 lines
7.9 KiB
Plaintext
117 lines
7.9 KiB
Plaintext
<<<
|
|
:sectnums:
|
|
==== Stream Link Interface (SLINK)
|
|
|
|
[cols="<3,<3,<4"]
|
|
[frame="topbot",grid="none"]
|
|
|=======================
|
|
| Hardware source file(s): | neorv32_slink.vhd |
|
|
| Software driver file(s): | neorv32_slink.c |
|
|
| | neorv32_slink.h |
|
|
| Top entity port(s): | `slink_rx_dat_i` | RX link data (32-bit)
|
|
| | `slink_rx_val_i` | RX link data valid (1-bit)
|
|
| | `slink_rx_lst_i` | RX link last element of stream (1-bit)
|
|
| | `slink_rx_rdy_o` | RX link ready to receive (1-bit)
|
|
| | `slink_tx_dat_o` | TX link data (32-bit)
|
|
| | `slink_tx_val_o` | TX link data valid (1-bit)
|
|
| | `slink_tx_lst_o` | TX link last element of stream (1-bit)
|
|
| | `slink_tx_rdy_i` | TX link allowed to send (1-bit)
|
|
| Configuration generics: | `IO_SLINK_EN` | implement SLINK when _true_
|
|
| | `IO_SLINK_RX_FIFO` | RX FIFO depth (1..32k), has to be a power of two
|
|
| | `IO_SLINK_TX_FIFO` | TX FIFO depth (1..32k), has to be a power of two
|
|
| CPU interrupt: | fast IRQ channel 14 | SLINK IRQ (see <<_processor_interrupts>>)
|
|
|=======================
|
|
|
|
|
|
**Overview**
|
|
|
|
The stream link interface provides independent RX and TX channels for sending for sending and receiving
|
|
stream data. Each channel features an internal FIFO with configurable depth to buffer stream data
|
|
(`IO_SLINK_RX_FIFO` for the RX FIFO, `IO_SLINK_TX_FIFO` for the TX FIFO). The SLINK interface provides higher
|
|
bandwidth and less latency than the external bus interface making it ideally suited for coupling custom
|
|
stream processing units or streaming peripherals.
|
|
|
|
.Example Program
|
|
[TIP]
|
|
An example program for the SLINK module is available in `sw/example/demo_slink`.
|
|
|
|
|
|
**Interface & Protocol**
|
|
|
|
The SLINK interface consists of four signals per channel:
|
|
|
|
* `dat` contains the actual data word
|
|
* `val` marks the current transmission cycle as valid
|
|
* `lst` makes the current transmission cycle as the last element of a stream
|
|
* `rdy` indicates that the receiving part is ready to receive
|
|
|
|
.AXI4-Stream Compatibility
|
|
[NOTE]
|
|
The interface names and the underlying protocol is compatible to the AXI4-Stream standard.
|
|
|
|
|
|
**Theory of Operation**
|
|
|
|
The SLINK provides four interface registers. The control register (`CTRL`) is used to configure
|
|
the module and to check its status. Three individual data registers (`RX_DATA`, `TX_DATA`, `TX_DATA_LAST`)
|
|
are used to send and received the link's actual data stream.
|
|
|
|
The `RX_DATA` register provides direct access to the RX link FIFO buffer. After reading data from this the register
|
|
the control register's `SLINK_CTRL_RX_LAST` can be checked to determine if the according data word has been marked
|
|
as "end of stream" via the `slink_rx_lst_i` signal (this signal is also buffered by the link's FIFO).
|
|
|
|
Writing to the `TX_DATA` or `TX_DATA_LAST` register will immediately write to the TX link FIFO buffer.
|
|
When writing to the `TX_DATA_LAST` the according data word will be marked as "end of stream" via the
|
|
`slink_tx_lst_o` signal (this signal is also buffered by the link's FIFO).
|
|
|
|
The configured FIFO sizes can be retrieved by software via the control register's `SLINK_CTRL_RX_FIFO_*` and
|
|
`SLINK_CTRL_TX_FIFO_*` bits.
|
|
|
|
The SLINK is globally activated by setting the control register's enable bit `SLINK_CTRL_EN`. Clearing this bit will
|
|
reset all internal logic and will also clear both FIFOs. The FIFOs can also be cleared manually at all time by
|
|
setting the `SLINK_CTRL_RX_CLR` and `SLINK_CTRL_TX_CLR` bits (these bits will auto-clear).
|
|
|
|
[NOTE]
|
|
Writing to the TX channel's FIFO while it is _full_ will have no effect. Reading from the RX channel's FIFO while it
|
|
is _empty_ will also have no effect and will return the last received data word.
|
|
|
|
The current status of the RX and TX FIFOs can be determined via the `SLINK_CTRL_RX_*` and `SLINK_CTRL_TX_*` flags.
|
|
A global interrupt can be programmed based on these FIFO status flags via the control register's `SLINK_CTRL_IRQ_*`
|
|
bits. Note that all enabled interrupt conditions are logically OR-ed. Once the SLINK's interrupt has become pending,
|
|
it has to be explicitly cleared again by writing zero to the according <<_mip>> CSR bit(s).
|
|
|
|
|
|
**Register Map**
|
|
|
|
.SLINK register map (`struct NEORV32_SLINK`)
|
|
[cols="<2,<2,<4,^1,<4"]
|
|
[options="header",grid="all"]
|
|
|=======================
|
|
| Address | Name [C] | Bit(s) | R/W | Function
|
|
.22+<| `0xffffec00` .22+<| `NEORV32_SLINK.CTRL` <| `0` `SLINK_CTRL_EN` ^| r/w <| SLINK global enable
|
|
<| `1` `SLINK_CTRL_RX_CLR` ^| -/w <| Clear RX FIFO when set (bit auto-clears)
|
|
<| `2` `SLINK_CTRL_TX_CLR` ^| -/w <| Clear TX FIFO when set (bit auto-clears)
|
|
<| `3` _reserved_ ^| r/- <| _reserved_, read as zero
|
|
<| `4` `SLINK_CTRL_RX_LAST` ^| r/- <| Last word read from `RX_DATA` is marked as "end of stream"
|
|
<| `7:5` _reserved_ ^| r/- <| _reserved_, read as zero
|
|
<| `8` `SLINK_CTRL_RX_EMPTY` ^| r/- <| RX FIFO empty
|
|
<| `9` `SLINK_CTRL_RX_HALF` ^| r/- <| RX FIFO at least half full
|
|
<| `10` `SLINK_CTRL_RX_FULL` ^| r/- <| RX FIFO full
|
|
<| `11` `SLINK_CTRL_TX_EMPTY` ^| r/- <| TX FIFO empty
|
|
<| `12` `SLINK_CTRL_TX_HALF` ^| r/- <| TX FIFO at least half full
|
|
<| `13` `SLINK_CTRL_TX_FULL` ^| r/- <| TX FIFO full
|
|
<| `15:14` _reserved_ ^| r/- <| _reserved_, read as zero
|
|
<| `16` `SLINK_CTRL_IRQ_RX_NEMPTY` ^| r/w <| IRQ if RX FIFO not empty
|
|
<| `17` `SLINK_CTRL_IRQ_RX_HALF` ^| r/w <| IRQ if RX FIFO at least half full
|
|
<| `18` `SLINK_CTRL_IRQ_RX_FULL` ^| r/w <| IRQ if RX FIFO full
|
|
<| `19` `SLINK_CTRL_IRQ_TX_EMPTY` ^| r/w <| IRQ if TX FIFO empty
|
|
<| `20` `SLINK_CTRL_IRQ_TX_NHALF` ^| r/w <| IRQ if TX FIFO not at least half full
|
|
<| `21` `SLINK_CTRL_IRQ_TX_NFULL` ^| r/w <| IRQ if TX FIFO not full
|
|
<| `23:22` _reserved_ ^| r/- <| _reserved_, read as zero
|
|
<| `27:24` `SLINK_CTRL_RX_FIFO_MSB : SLINK_CTRL_RX_FIFO_LSB` ^| r/- <| log2(RX FIFO size)
|
|
<| `31:28` `SLINK_CTRL_TX_FIFO_MSB : SLINK_CTRL_TX_FIFO_LSB` ^| r/- <| log2(TX FIFO size)
|
|
| `0xffffec04` | `NEORV32_SLINK.RX_DATA` | `31:0` | r/- | Read word from RX link FIFO
|
|
| `0xffffec08` | `NEORV32_SLINK.TX_DATA` | `31:0` | -/w | Write word to TX link FIFO
|
|
| `0xffffec0c` | `NEORV32_SLINK.TX_DATA_LAST` | `31:0` | -/w | Write word to TX link FIFO and also set "end-of-stream" delimiter
|
|
|=======================
|