1 |
61 |
zero_gravi |
<<<
|
2 |
|
|
:sectnums:
|
3 |
|
|
==== Stream Link Interface (SLINK)
|
4 |
|
|
|
5 |
|
|
[cols="<3,<3,<4"]
|
6 |
|
|
[frame="topbot",grid="none"]
|
7 |
|
|
|=======================
|
8 |
|
|
| Hardware source file(s): | neorv32_slink.vhd |
|
9 |
|
|
| Software driver file(s): | neorv32_slink.c |
|
10 |
|
|
| | neorv32_slink.h |
|
11 |
|
|
| Top entity port: | `slink_tx_dat_o` | TX link data (8x32-bit)
|
12 |
|
|
| | `slink_tx_val_o` | TX link data valid (8-bit)
|
13 |
|
|
| | `slink_tx_rdy_i` | TX link allowed to send (8-bit)
|
14 |
|
|
| | `slink_rx_dat_i` | RX link data (8x32-bit)
|
15 |
|
|
| | `slink_rx_val_i` | RX link data valid (8-bit)
|
16 |
|
|
| | `slink_rx_rdy_o` | RX link ready to receive (8-bit)
|
17 |
|
|
| Configuration generics: | _SLINK_NUM_TX_ | Number of TX links to implement (0..8)
|
18 |
|
|
| | _SLINK_NUM_RX_ | Number of RX links to implement (0..8)
|
19 |
|
|
| | _SLINK_TX_FIFO_ | FIFO depth (1..32k) of TX links, has to be a power of two
|
20 |
|
|
| | _SLINK_RX_FIFO_ | FIFO depth (1..32k) of RX links, has to be a power of two
|
21 |
|
|
| CPU interrupts: | fast IRQ channel 10 | RX data available (see <<_processor_interrupts>>)
|
22 |
|
|
| | fast IRQ channel 11 | TX data send (see <<_processor_interrupts>>)
|
23 |
|
|
|=======================
|
24 |
|
|
|
25 |
|
|
The SLINK component provides up to 8 independent RX (receiving) and TX (sending) links for transmitting
|
26 |
|
|
stream data. The interface provides higher bandwidth (and less latency) than the external memory bus
|
27 |
|
|
interface, which makes it ideally suited to couple custom stream processing units (like CORDIC, FFTs or
|
28 |
|
|
cryptographic accelerators).
|
29 |
|
|
|
30 |
|
|
Each individual link provides an internal FIFO for data buffering. The FIFO depth is globally defined
|
31 |
|
|
for all TX links via the _SLINK_TX_FIFO_ generic and for all RX links via the _SLINK_RX_FIFO_ generic.
|
32 |
|
|
The FIFO depth has to be at least 1, which will implement a simple input/output register. The maximum
|
33 |
|
|
value is limited to 32768 entries. Note that the FIFO depth has to be a power of two (for optimal
|
34 |
|
|
logic mapping).
|
35 |
|
|
|
36 |
|
|
The actual number of implemented RX/TX links is configured by the _SLINK_NUM_RX_ and _SLINK_NUM_TX_
|
37 |
|
|
generics. The SLINK module will be synthesized only if at least one of these generics is greater than
|
38 |
|
|
zero. All unimplemented links are internally terminated and their according output signals are pulled
|
39 |
|
|
to low level.
|
40 |
|
|
|
41 |
|
|
[NOTE]
|
42 |
|
|
The SLINK interface does not provide any additional tag signals (for example to define a "stream destination
|
43 |
|
|
address" or to indicate the last data word of a "package"). Use a custom controller connected
|
44 |
|
|
via the external memory bus interface or the processor's GPIO ports to implement custom data tags.
|
45 |
|
|
|
46 |
|
|
**Theory of Operation**
|
47 |
|
|
|
48 |
|
|
The SLINK is activated by setting the control register's (_SLINK_CT_) enable bit _SLINK_CT_EN_.
|
49 |
|
|
The actual data links are accessed by reading or writing the according link data registers _SLINK_CH0_
|
50 |
|
|
to _SLINK_CH7_. For example, writing the _SLINK_CH0_ will put the according data into the FIFO of TX link 0.
|
51 |
|
|
Accordingly, reading from _SLINK_CH0_ will return one data word from the FIFO of RX link 0.
|
52 |
|
|
|
53 |
|
|
The FIFO status of each RX and TX link is available via read-only bits in the device's control register.
|
54 |
|
|
Bits _SLINK_CT_TX0_FREE_ to _SLINK_CT_TX7_FREE_ indicate if the FIFO of the according TX link can take another
|
55 |
|
|
data word. Bits _SLINK_CT_RX0_AVAIL_ to _SLINK_CT_RX7_AVAIL_ indicate if the FIFO of the according RX link
|
56 |
|
|
contains another data word.
|
57 |
|
|
|
58 |
|
|
The _SLINK_CT_TX_FIFO_Sx_ and _SLINK_CT_RX_FIFO_Sx_ bits allow software to determine the total TX & RX FIFO sizes.
|
59 |
|
|
The _SLINK_CT_TX_NUMx_ and _SLINK_CT_RX_NUMx_ bits represent the absolute number of implemented TX and RX links
|
60 |
|
|
with an offset of "-1" (`0b000` = 1 link implemented, ..., `0b111` = 8 links implemented.
|
61 |
|
|
|
62 |
|
|
**Blocking Link Access**
|
63 |
|
|
|
64 |
|
|
When directly accessing the link data registers (without checking the according FIFO status flags) the access
|
65 |
|
|
might be executed as _blocking_. That means the CPU access will stall until the accessed link responds. For
|
66 |
|
|
example, when reading RX link 0 (via _SLINK_CH0_ register) the CPU access will stall, if there is not data
|
67 |
|
|
available in the according FIFO. The CPU access will complete as soon as RX link0 receives new data.
|
68 |
|
|
|
69 |
|
|
Vice versa, writing data to TX link 0 (via _SLINK_CH0_ register) might stall the CPU access until there is
|
70 |
|
|
at least one free entry in the link's FIFO.
|
71 |
|
|
|
72 |
|
|
[WARNING]
|
73 |
|
|
The NEORV32 processor ensures that _any_ CPU access to memory-mapped devices (including the SLINK module)
|
74 |
|
|
will **time out** after a certain number of cycles (see section <<_bus_interface>>).
|
75 |
|
|
Hence, blocking access to a stream link that does not complete within a certain amount of cycles will
|
76 |
|
|
raise a _store bus access exception_ when writing a TX link or a _load bus access exception_ when reading
|
77 |
|
|
an RX link.
|
78 |
|
|
|
79 |
|
|
**Non-Blocking Link Access**
|
80 |
|
|
|
81 |
|
|
For a non-blocking link access concept, the FIFO status signal in _SLINK_CT_ needs to be checked before
|
82 |
|
|
reading/writing the actual link data register. For example, a non-blocking write access to a TX link 0 has
|
83 |
|
|
to check _SLINK_CT_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data word
|
84 |
|
|
and the actual data can be written to _SLINK_CH0_. If the bit is cleared, the link's FIFO is full
|
85 |
|
|
and the status flag can be polled until it indicates free space in the FIFO.
|
86 |
|
|
|
87 |
|
|
This concept will not raise any exception as there is no "direct" access to the link data registers.
|
88 |
|
|
However, non-blocking accesses require additional instruction to check the according status flags prior
|
89 |
|
|
to the actual link access, which will reduce performance for high-bandwidth data stream.
|
90 |
|
|
|
91 |
|
|
**Interrupts**
|
92 |
|
|
|
93 |
|
|
The stream interface provides two interrupts that are _globally_ driven by the RX and TX link's
|
94 |
|
|
FIFO level status. If the FIFO of **any** TX link _was full_ and _becomes empty_ again, the TX interrupt fires.
|
95 |
|
|
Accordingly, if the FIFO of **any** RX link _was empty_ and a _new data word_ appears in it, the RX interrupt fires.
|
96 |
|
|
|
97 |
|
|
Note that these interrupts can only fire if the SLINK module is actually enabled by setting the
|
98 |
|
|
_SLINK_CT_EN_ bit in the unit's control register.
|
99 |
|
|
|
100 |
|
|
**Stream Link Interface & Protocol**
|
101 |
|
|
|
102 |
|
|
The SLINK interface consists of three signals `dat`, `val` and `rdy` for each RX and TX link.
|
103 |
|
|
Each signal is an "array" with eight entires (one for each link). Note that an entry in `slink_*x_dat` is 32-bit
|
104 |
|
|
wide while entries in `slink_*x_val` and `slink_*x_rdy` are are just 1-bit wide.
|
105 |
|
|
|
106 |
|
|
The stream link protocol is based on a simple FIFO-like interface between a source (sender) and a sink (receiver).
|
107 |
|
|
Each link provides two signals for implementing a simple FIFO-style handshake. The `slink_*x_val` signal is set
|
108 |
|
|
if the according `slink_*x_dat` contains valid data. The stream source has to ensure that both signals remain
|
109 |
|
|
stable until the according `slink_*x_rdy` signal is set. This signal is set by the stream source to indicate it
|
110 |
|
|
can accept another data word.
|
111 |
|
|
|
112 |
|
|
In summary, a data word is transferred if both `slink_*x_val` and `slink_*x_rdy` are high.
|
113 |
|
|
|
114 |
|
|
.Exemplary stream link transfer
|
115 |
|
|
image::stream_link_interface.png[width=560,align=center]
|
116 |
|
|
|
117 |
|
|
[TIP]
|
118 |
|
|
The SLINK handshake protocol is compatible to the AXI4-Stream base protocol.
|
119 |
|
|
|
120 |
|
|
.SLINK register map
|
121 |
|
|
[cols="^4,<5,^2,^2,<14"]
|
122 |
|
|
[options="header",grid="all"]
|
123 |
|
|
|=======================
|
124 |
|
|
| Address | Name [C] | Bit(s) | R/W | Function
|
125 |
|
|
.8+<| `0xfffffec0` .8+<| _SLINK_CT_ <| `31` _SLINK_CT_EN_ ^| r/w | SLINK global enable
|
126 |
|
|
<| `30` _reserved_ ^| r/- <| reserved, read as zero
|
127 |
|
|
<| `29:26` _SLINK_CT_TX_FIFO_S3_ : _SLINK_CT_TX_FIFO_S0_ ^| r/- <| TX links FIFO depth, log2 of_SLINK_TX_FIFO_ generic
|
128 |
|
|
<| `25:22` _SLINK_CT_RX_FIFO_S3_ : _SLINK_CT_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic
|
129 |
|
|
<| `21:19` _SLINK_CT_TX_NUM2_ : _SLINK_CT_TX_NUM0_ ^| r/- <| Number of implemented TX links minus 1
|
130 |
|
|
<| `18:16` _SLINK_CT_RX_NUM2_ : _SLINK_CT_RX_NUM0_ ^| r/- <| Number of implemented RX links minus 1
|
131 |
|
|
<| `15:8` _SLINK_CT_TX7_FREE_ : _SLINK_CT_TX0_FREE_ ^| r/- <| At least one free TX FIFO entry available for link 0..7
|
132 |
|
|
<| `7:0` _SLINK_CT_RX7_AVAIL_ : _SLINK_CT_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 0..7
|
133 |
|
|
| `0xfffffec4` : `0xfffffedc` | _SLINK_CT_ |`31:0` | | _mirrored control register_
|
134 |
|
|
| `0xfffffee0` | _SLINK_CH0_ | `31:0` | r/w | Link 0 RX/TX data
|
135 |
|
|
| `0xfffffee4` | _SLINK_CH1_ | `31:0` | r/w | Link 1 RX/TX data
|
136 |
|
|
| `0xfffffee8` | _SLINK_CH2_ | `31:0` | r/w | Link 2 RX/TX data
|
137 |
|
|
| `0xfffffeec` | _SLINK_CH3_ | `31:0` | r/w | Link 3 RX/TX data
|
138 |
|
|
| `0xfffffef0` | _SLINK_CH4_ | `31:0` | r/w | Link 4 RX/TX data
|
139 |
|
|
| `0xfffffef4` | _SLINK_CH5_ | `31:0` | r/w | Link 5 RX/TX data
|
140 |
|
|
| `0xfffffef8` | _SLINK_CH6_ | `31:0` | r/w | Link 6 RX/TX data
|
141 |
|
|
| `0xfffffefc` | _SLINK_CH7_ | `31:0` | r/w | Link 7 RX/TX data
|
142 |
|
|
|=======================
|