24
24
| | fast IRQ channel 11 | SLINK TX IRQ (see <<_processor_interrupts>>)
25
25
|=======================
26
26
27
+
28
+ **Overview**
29
+
27
30
The SLINK component provides up to 8 independent RX (receiving) and TX (sending) links for moving
28
31
stream data. The interface provides higher bandwidth and less latency than the external memory bus
29
- interface, which makes it ideally suited to couple custom stream processing units (like CORDICs, FFTs or
30
- cryptographic accelerators).
32
+ interface, which makes it ideally suited to couple custom stream processing units.
31
33
32
- Each individual link provides an internal FIFO for data buffering. The FIFO depth is globally defined
34
+ Each link provides an individual internal FIFO for data buffering. The FIFO depth is globally defined
33
35
for all TX links via the _SLINK_TX_FIFO_ generic and for all RX links via the _SLINK_RX_FIFO_ generic.
34
36
The FIFO depth has to be at least 1, which will implement a simple input/output register. The maximum
35
- value is limited to 32768 entries. Note that the FIFO depth has to be a power of two (for optimal
36
- logic mapping).
37
+ value is limited to 32768 entries. Note that the FIFO depth has to be a power of two.
37
38
38
39
The actual number of implemented RX/TX links is configured by the _SLINK_NUM_RX_ and _SLINK_NUM_TX_
39
- generics. The SLINK module will be synthesized only if at least one of these generics is greater than
40
+ generics, respectively . The SLINK module will be synthesized only if at least one of these generics is greater than
40
41
zero. All unimplemented links are internally terminated and their according output signals are set to zero.
41
42
42
43
[NOTE]
43
44
The NEORV32 stream link interfaces are compatible to the _AXI Stream_ specs.
44
45
46
+ .Example Program
47
+ [TIP]
48
+ An example program for the SLINK module is available in `sw/example/demo_slink` .
49
+
45
50
46
51
**Theory of Operation**
47
52
48
- The SLINK provides eight data registers (`DATA[i]` ) to access the links (read accesses will access the RX links,
49
- write accesses will access the TX links), one control register (`CTRL` ) and one status register (`STATUS` ).
53
+ The SLINK provides eight data registers (`DATA[i]` ) to access the links (read accesses will access the RX link FIFOs,
54
+ write accesses will access the TX link FIFOs), one control register (`CTRL` ), one interrupt configuration register (`IRQ` )
55
+ and two status registers - one for the RX links (`RX_STATUS` ) and one for the TX links (`TX_STATUS` ).
50
56
51
57
The SLINK is globally activated by setting the control register's enable bit _SLINK_CTRL_EN_ . Clearing this
52
- bit will reset all internal logic and will also clear all data FIFOs. The actual data links are accessed by
53
- reading or writing the according link data registers `DATA[0]` to `DATA[7]` . For example, writing the `DATA[0]`
58
+ bit will reset all internal logic and will also clear all FIFOs. The actual data links are accessed by
59
+ reading or writing the according link data registers `DATA[0]` to `DATA[7]` . For example, writing to `DATA[0]`
54
60
will put the according data into the FIFO of TX link 0. Accordingly, reading from `DATA[0]` will return one data
55
61
word from the FIFO of RX link 0.
56
62
57
- The current link status of each RX and TX channel is accessible via the `STATUS` register. Each link provides a
58
- read-only FIFO status flag in this register: the _SLINK_CTRL_RX_AVAIL_ flags indicate that there is _at least_
59
- one data word available in the according RX link's FIFO. The _SLINK_CTRL_TX_FREE_ flags indicate
60
- there is _at least_ one free entry in the according TX link's FIFO.
63
+ The current link status of each RX and TX channel is accessible via the `*X_STATUS` registers. The FIFO's status
64
+ signals that represent the fill level (empty, at least half full, full) are exposed as read-only flags via those two
65
+ registers.
61
66
62
67
[NOTE]
63
68
Writing to a TX link's FIFO that is _full_ will have no effect. Reading data from a RX link's FIFO that is
64
69
_empty_ will have no effect and will return the last valid data word.
65
70
66
- The "end of packet" signal `lst ` is controlled by the status register's _SLINK_STATUS_RX_LAST_ and
67
- _SLINK_STATUS_TX_LAST_ bits. Note that the RX/TX `lst` signal is also buffered by the internal FIFOs.
68
- Setting a bit in _SLINK_STATUS_TX_LAST_ before writing data to `DATA` will set the `lst` signal when the
69
- written data word is actually send from the FIFO. Vice versa, a bit in _SLINK_STATUS_RX_LAST_ will be set
70
- if the according data word read from `DATA` was marked as "end of packet".
71
+ The TX link's "end of packet" signal `slink_tx_lst_o ` is controlled by the `TX_STATUS` register's _SLINK_TX_STATUS_LAST_
72
+ bits. Note that these bits are also buffered by the internal TX FIFOs, so setting one of these bits before writing data to
73
+ `DATA` will set the `slink_tx_lst_o` signal when the written data word is actually send from the FIFO. Vice versa, the
74
+ _SLINK_RX_STATUS_LAST_ bits in `RX_STATUS` represent the level of the according `slink_rx_lst_i` input when a new data word
75
+ was samples. These bits are also buffered in the internal RX FIFOs.
71
76
72
77
73
78
**Data Transmission**
74
79
75
80
To send (TX) data the program should ensure there is at least one left in the according link's FIFO by checking
76
- _SLINK_CTRL_TX_FREE_ . To mark the current data word to-be-send as "end of packet" the according _SLINK_STATUS_TX_LAST_
81
+ _SLINK_CTRL_TX_FREE_ . To mark the current data word to-be-send as "end of packet" the according _SLINK_TX_STATUS_LAST_
77
82
bit has to be set _before_ writing `DATA` .
78
83
79
- Receive (RX) is available when the according link's _SLINK_CTRL_RX_AVAIL_ bit is set . To check if the received data
80
- is marked as "end of packet" the according _SLINK_STATUS_RX_LAST_ has to be checked _before_ reading `DATA` .
84
+ Received data (RX) is available when the according link's _SLINK_RX_STATUS_EMPTY_ bit is cleared . To check if the received
85
+ data is marked as "end of packet" the according _SLINK_RX_STATUS_LAST_ bit has to be examined _before_ reading `DATA` .
81
86
82
87
83
88
**Interface & Protocol**
84
89
85
90
The SLINK interface consists of four signals `dat` , `val` , `rdy` and `lst` for each RX and TX link.
86
- Each signal is an "array" with eight entires ( one for each link) . Note that an entry in `slink_*x_dat` is 32-bit
87
- wide while entries in `slink_*x_val` and `slink_*x_rdy ` are are just 1-bit wide.
91
+ Each signal is constructed as an "array" with eight entries - one for each link. Note that an entry in `slink_*x_dat` is 32-bit
92
+ wide while entries in `slink_*x_val` , `slink_*x_rdy` and `slink_*x_lst ` are are just 1-bit wide.
88
93
89
94
* `dat` contains the actual data word
90
95
* `val` marks the current transmission cycle as valid
@@ -97,16 +102,27 @@ image::stream_link_interface.png[width=560,align=center]
97
102
98
103
**SLINK Interrupts**
99
104
100
- The stream interface provides two independent CPU interrupts - one for RX conditions (data received) and one
101
- for TX conditions (ready to send). The RX interrupt is controlled per-link by the _SLINK_CTRL_RX_IRQ_EN_
102
- control register bits while the TX interrupt is controlled per-link by the _SLINK_CTRL_TX_IRQ_EN_ control
103
- register bits. If any enabled link fulfills the RX/TX interrupt condition a RX/TX interrupt request is
104
- sent to the CPU. Note that all RX and TX interrupt conditions are logically OR-ed.
105
+ The stream interface provides two independent CPU interrupt channels - one for RX conditions and one
106
+ for TX conditions. These IRQs can be used to signal specific FIFO conditions (e.g. "data available") to the
107
+ CPU. The specific interrupt conditions are programmed per-link via the `IRQ` register.
108
+ A 2-bit-coded value is used to enable the according link's interrupt and to specify the actual condition.
109
+
110
+ [NOTE]
111
+ Note that all enabled interrupt configurations are logically OR-ed for the CPU RX and TX interrupts, respectively.
112
+ Hence, if **any** link fulfills the according interrupt configuration the according RX/TX interrupt request is
113
+ sent to the CPU.
114
+
115
+ For the TX links (in `IRQ` _SLINK_IRQ_TX_ ) the following interrupt conditions are supported:
116
+
117
+ * `0-` : off, no interrupt from link
118
+ * `10` : interrupt fires if FIFO _becomes_ not empty
119
+ * `11` : interrupt fires if FIFO _becomes_ at least half full
120
+
121
+ For the RX links (in `IRQ` _SLINK_IRQ_RX_ ) the following interrupt conditions are supported:
105
122
106
- * RX interrupt: if the FIFO of link _i_ changes from status "empty" to "not empty" (data available) and the
107
- according _SLINK_CTRL_RX_IRQ_EN_ bit is set the SLINK RX interrupt is triggered
108
- * TX interrupt: if the FIFO of link _i_ changes from status "full" to "not full" (ready to send) and the
109
- according _SLINK_CTRL_TX_IRQ_EN_ bit is set the SLINK TX interrupt is triggered
123
+ * `0-` : off, no interrupt from link
124
+ * `10` : interrupt fires if FIFO _becomes_ empty
125
+ * `11` : interrupt fires if FIFO _becomes_ less than half full
110
126
111
127
Once the SLINK's RX or TX CPU interrupt has become pending, it has to be explicitly cleared again by writing
112
128
zero to the according <<_mip>> CSR bit(s).
@@ -119,18 +135,23 @@ zero to the according <<_mip>> CSR bit(s).
119
135
[options="header",grid="all"]
120
136
|=======================
121
137
| Address | Name [C] | Bit(s) | R/W | Function
122
- .6+<| `0xfffffec0` .6+<| `NEORV32_SLINK.CTRL` <| `0` _SLINK_CTRL_EN_ ^| r/w | SLINK global enable
123
- <| `7:1` _reserved_ ^| r/- <| reserved, read as zero
124
- <| `11:8` _SLINK_CTRL_TX_FIFO_S3_ : _SLINK_CTRL_TX_FIFO_S0_ ^| r/- <| TX FIFO depth, log2(_SLINK_TX_FIFO_ )
125
- <| `15:12` _SLINK_CTRL_RX_FIFO_S3_ : _SLINK_CTRL_RX_FIFO_S0_ ^| r/- <| RX FIFO depth, log2(_SLINK_RX_FIFO_ )
126
- <| `23:13` _SLINK_CTRL_RX_IRQ_EN_MSB_ : _SLINK_CTRL_RX_IRQ_EN_LSB_ ^| r/- <| RX interrupt enable for link _i_
127
- <| `23:13` _SLINK_CTRL_TX_IRQ_EN_MSB_ : _SLINK_CTRL_TX_IRQ_EN_LSB_ ^| r/- <| TX interrupt enable for link _i_
128
- | `0xfffffec4` : `0xfffffecf` | - |`31:0` | r/- | _reserved_
129
- .4+<| `0xfffffed0` .4+<| `NEORV32_SLINK.STATUS` <|`7:0` _SLINK_STATUS_RX_AVAIL_MSB_ : _SLINK_STATUS_RX_AVAIL_LSB_ ^| r/- <| RX link _i_ FIFO is NOT empty (data available)
130
- <|`15:8` _SLINK_STATUS_TX_FREE_MSB_ : _SLINK_STATUS_TX_FREE_LSB_ ^| r/- <| TX link _i_ FIFO is NOT full (ready to send)
131
- <|`23:16` _SLINK_STATUS_RX_LAST_MSB_ : _SLINK_STATUS_RX_LAST_LSB_ ^| r/- <| Indicates end of packet for RX link _i_
132
- <|`31:24` _SLINK_STATUS_TX_LAST_MSB_ : _SLINK_STATUS_TX_LAST_LSB_ ^| r/w <| Set to indicate end of packet for TX link _i_
133
- | `0xfffffed4` : `0xfffffedf` | - |`31:0` | r/- | _reserved_
138
+ .6+<| `0xfffffec0` .6+<| `NEORV32_SLINK.CTRL` <| `0` _SLINK_CTRL_EN_ ^| r/w | SLINK global enable/reset
139
+ <| `7:1` _reserved_ ^| r/- <| _reserved_ , returns zero
140
+ <| `19:16` _SLINK_CTRL_RX_NUM_MSB_ : _SLINK_CTRL_RX_NUM_LSB_ ^| r/- <| Number of RX links (_SLINK_NUM_RX_ )
141
+ <| `23:20` _SLINK_CTRL_TX_NUM_MSB_ : _SLINK_CTRL_TX_NUM_LSB_ ^| r/- <| Number of TX links (_SLINK_NUM_TX_ )
142
+ <| `27:24` _SLINK_CTRL_RX_FIFO_MSB_ : _SLINK_CTRL_RX_FIFO_LSB_ ^| r/- <| RX FIFO depth, log2(_SLINK_RX_FIFO_ )
143
+ <| `31:28` _SLINK_CTRL_TX_FIFO_MSB_ : _SLINK_CTRL_TX_FIFO_MSB_ ^| r/- <| TX FIFO depth, log2(_SLINK_TX_FIFO_ )
144
+ .2+<| `0xfffffec4` .2+<| `NEORV32_SLINK.IRQ` <|`15:0` _SLINK_IRQ_RX_MSB_ : _SLINK_IRQ_RX_LSB_ ^| r/w <| RX link _i_ interrupt configuration (2 bits per link)
145
+ <|`31:16` _SLINK_IRQ_TX_MSB_ : _SLINK_IRQ_TX_LSB_ ^| r/w <| TX link _i_ interrupt configuration (2 bits per link)
146
+ .4+<| `0xfffffec8` .4+<| `NEORV32_SLINK.RX_STATUS` <|`7:0` _SLINK_RX_STATUS_EMPTY_MSB_ : _SLINK_RX_STATUS_EMPTY_LSB_ ^| r/- <| RX link _i_ FIFO empty
147
+ <|`15:8` _SLINK_RX_STATUS_HALF_MSB_ : _SLINK_RX_STATUS_HALF_LSB_ ^| r/- <| RX link _i_ FIFO at least half full
148
+ <|`23:16` _SLINK_RX_STATUS_FULL_MSB_ : _SLINK_RX_STATUS_FULL_LSB_ ^| r/- <| RX link _i_ FIFO full
149
+ <|`31:24` _SLINK_RX_STATUS_LAST_MSB_ : _SLINK_RX_STATUS_LAST_LSB_ ^| r/- <| Current data word of RX link _i_ is marked as "end of packet"
150
+ .4+<| `0xfffffecc` .4+<| `NEORV32_SLINK.TX_STATUS` <|`7:0` _SLINK_TX_STATUS_EMPTY_MSB_ : _SLINK_TX_STATUS_EMPTY_LSB_ ^| r/- <| TX link _i_ FIFO empty
151
+ <|`15:8` _SLINK_TX_STATUS_HALF_MSB_ : _SLINK_TX_STATUS_HALF_LSB_ ^| r/- <| TX link _i_ FIFO at least half full
152
+ <|`23:16` _SLINK_TX_STATUS_FULL_MSB_ : _SLINK_TX_STATUS_FULL_LSB_ ^| r/- <| TX link _i_ FIFO full
153
+ <|`31:24` _SLINK_TX_STATUS_LAST_MSB_ : _SLINK_TX_STATUS_LAST_LSB_ ^| r/w <| Set to mark next data word of TX link _i_ is "end of packet"
154
+ | `0xfffffed0` : `0xfffffedf` | - |`31:0` | r/- | _reserved_ , returns zero
134
155
| `0xfffffee0` | `NEORV32_SLINK.DATA[0]` | `31:0` | r/w | Link 0 RX/TX data
135
156
| `0xfffffee4` | `NEORV32_SLINK.DATA[1]` | `31:0` | r/w | Link 1 RX/TX data
136
157
| `0xfffffee8` | `NEORV32_SLINK.DATA[2]` | `31:0` | r/w | Link 2 RX/TX data
0 commit comments