URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
[/] [neorv32/] [trunk/] [docs/] [datasheet/] [soc_slink.adoc] - Rev 65
Go to most recent revision | Compare with Previous | Blame | View Log
<<<: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: | `slink_tx_dat_o` | TX link data (8x32-bit)| | `slink_tx_val_o` | TX link data valid (8-bit)| | `slink_tx_rdy_i` | TX link allowed to send (8-bit)| | `slink_rx_dat_i` | RX link data (8x32-bit)| | `slink_rx_val_i` | RX link data valid (8-bit)| | `slink_rx_rdy_o` | RX link ready to receive (8-bit)| Configuration generics: | _SLINK_NUM_TX_ | Number of TX links to implement (0..8)| | _SLINK_NUM_RX_ | Number of RX links to implement (0..8)| | _SLINK_TX_FIFO_ | FIFO depth (1..32k) of TX links, has to be a power of two| | _SLINK_RX_FIFO_ | FIFO depth (1..32k) of RX links, has to be a power of two| CPU interrupts: | fast IRQ channel 10 | SLINK RX IRQ (see <<_processor_interrupts>>)| | fast IRQ channel 11 | SLINK TX IRQ (see <<_processor_interrupts>>)|=======================The SLINK component provides up to 8 independent RX (receiving) and TX (sending) links for transmittingstream data. The interface provides higher bandwidth (and less latency) than the external memory businterface, which makes it ideally suited to couple custom stream processing units (like CORDIC, FFTs orcryptographic accelerators).Each individual link provides an internal FIFO for data buffering. The FIFO depth is globally definedfor all TX links via the _SLINK_TX_FIFO_ generic and for all RX links via the _SLINK_RX_FIFO_ generic.The FIFO depth has to be at least 1, which will implement a simple input/output register. The maximumvalue is limited to 32768 entries. Note that the FIFO depth has to be a power of two (for optimallogic mapping).The actual number of implemented RX/TX links is configured by the _SLINK_NUM_RX_ and _SLINK_NUM_TX_generics. The SLINK module will be synthesized only if at least one of these generics is greater thanzero. All unimplemented links are internally terminated and their according output signals are pulledto low level.[NOTE]The SLINK interface does not provide any additional tag signals (for example to define a "stream destinationaddress" or to indicate the last data word of a "package"). Use a custom controller connectedvia the external memory bus interface or use some of the processor's GPIO ports to implement custom datatag signals.**Theory of Operation**The SLINK provides eight data registers (`DATA[i]`) to access the links (read accesses will access the RX links, writeaccesses 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_CTRL_EN_.The actual data links are accessed by reading or writing the according link data registers `DATA[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 `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 thecontrol register. The _SLINK_CTRL_TX_FIFO_Sx_ and _SLINK_CTRL_RX_FIFO_Sx_ indicate the TX & RX FIFO sizes.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_CTRL_RXx_AVAIL_ flags indicatethat there is _at least_ one data word in the according RX link's FIFO. The _SLINK_CTRL_TXx_FREE_ flags indicatethere 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.**Blocking Link Access**When directly accessing the link data registers (without checking the according FIFO status flags) the accessis as _blocking_. That means the CPU access will stall until the accessed link responds. Forexample, when reading RX link 0 (via `DATA[0]` register) the CPU will stall, if there is not dataavailable 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 `DATA[0]` register) will stall the CPU access until there isat least one free entry in the link's FIFO.[WARNING]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>>).Hence, blocking access to a stream link that does not complete within a certain amount of cycles willraise a _store bus access exception_ when writing a _full_ TX link or a _load bus access exception_ when readingfrom 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.**Non-Blocking Link Access**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 hasto check _SLINK_STATUS_TX0_FREE_ first. If the bit is set, the FIFO of TX link 0 can take another data wordand the actual data can be written to `DATA[0]`. If the bit is cleared, the link's FIFO is fulland 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.However, non-blocking accesses require additional instructions to check the according status flags priorto the actual link access, which will reduce performance for high-bandwidth data streams.**Stream Link Interface & Protocol**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-bitwide while entries in `slink_*x_val` and `slink_*x_rdy` are are just 1-bit wide.The stream link protocol is based on a simple FIFO-like interface between a source (sender) and a sink (receiver).Each link provides two signals for implementing a simple FIFO-style handshake. The `slink_*x_val` signal is set bythe source if the according `slink_*x_dat` (also set by the source) contains valid data. The stream source has toensure that both signals remain stable until the according `slink_*x_rdy` signal is set by the stream sink toindicate it can accept another data word.In summary, a data word is transferred if both `slink_*x_val(i)` and `slink_*x_rdy(i)` are high..Exemplary stream link transferimage::stream_link_interface.png[width=560,align=center][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.**Interrupts**The stream interface provides two independent interrupts that are _globally_ driven by the RX and TX link'sFIFO fill level status. Each RX and TX link provides an individual interrupt enable flag and an individualinterrupt type flag that allows to configure interrupts only for certain (or all) links and for application-specific interrupt conditions. The interrupt configuration is done using the `NEORV32_SLINK.IRQ` register.Any interrupt can only become pending if the SLINK module is enabled at all.The current FIFO fill-level of a specific **RX link** can only raise an interrupt request if it's interrupt enable flag_SLINK_IRQ_RX_EN_ is set. Vice versa, the current FIFO fill-level of a specific **TX link** can only raise an interruptrequest if it's interrupt enable flag _SLINK_IRQ_TX_EN_ is set.The **RX link's** _SLINK_IRQ_RX_MODE_ flags define the FIFO fill-level condition for raising an RX interrupt request:* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO is _not empty_ ("RX data available").* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO is _at least half-full_ ("time to get data from RX FIFO to prevent overflow").The **TX link's** _SLINK_IRQ_TX_MODE_ flags define the FIFO fill-level condition for raising an TX interrupt request:* If a link's interrupt mode flag is `1` an IRQ is generated when the link's FIFO is _not full_ ("space left in FIFO for new TX data").* If a link's interrupt mode flag is `0` an IRQ is generated when the link's FIFO is _less than half-full_ ("SW can send _SLINK_TX_FIFO_/2 data words without checking any flags").[NOTE]If _SLINK_RX_FIFO_ is 1 the _SLINK_IRQ_RX_MODE_ bits are hardwired to one.If _SLINK_TX_FIFO_ is 1 the _SLINK_IRQ_TX_MODE_ bits are hardwired to one.[NOTE]There is no RX FIFO overflow mechanism available yet.If _any_ configured interrupt condition is fulfilled, the according global SLINK RX / SLINK TX CPUinterrupt becomes pending.If the interrupt enable flags of several links are set, the interrupt service handler has to evaluate the SLINKstatus register is order to detect which link(s) caused the interrupt.[NOTE]If the programmed interrupt condition is fulfilled, the corresponding IRQ will become _pending_ untilthe causing interrupt conditions is resolved (for example by reading data from the according RX FIFO)..SLINK register map (`struct NEORV32_SLINK`)[cols="^4,<5,^2,^2,<14"][options="header",grid="all"]|=======================| Address | Name [C] | Bit(s) | R/W | Function.6+<| `0xfffffec0` .6+<| `NEORV32_SLINK.CTRL` <| `31` _SLINK_CTRL_EN_ ^| r/w | SLINK global enable<| `30:16` _reserved_ ^| r/- <| reserved, read as zero<| `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_CTRL_RX_FIFO_S3_ : _SLINK_CTRL_RX_FIFO_S0_ ^| r/- <| RX links FIFO depth, log2 of_SLINK_RX_FIFO_ generic<| `7:4` _SLINK_CTRL_TX_NUM3_ : _SLINK_CTRL_TX_NUM0_ ^| r/- <| Number of implemented TX links<| `3:0` _SLINK_CTRL_RX_NUM3_ : _SLINK_CTRL_RX_NUM0_ ^| r/- <| Number of implemented RX links| `0xfffffec4` | - |`31:0` | r/- | _reserved_.4+<| `0xfffffec8` .4+<| `NEORV32_SLINK.IRQ` <|`31:24` _SLINK_IRQ_RX_EN_MSB_ : _SLINK_IRQ_RX_EN_LSB_ ^| r/w <| RX interrupt enable for link 7..0<|`23:16` _SLINK_IRQ_RX_MODE_MSB_ : _SLINK_IRQ_RX_MODE_LSB_ ^| r/w <| RX IRQ mode for link 7..0: `0` = FIFO at least half-full; `1` = FIFO not empty<|`15:8` _SLINK_IRQ_TX_EN_MSB_ : _SLINK_IRQ_TX_EN_LSB_ ^| r/w <| TX interrupt enable for link 7..0<|`7:0` _SLINK_IRQ_TX_MODE_MSB_ : _SLINK_IRQ_TX_MODE_LSB_ ^| r/w <| TX IRQ mode for link 7..0: `0` = FIFO less than half-full; `1` = FIFO not full| `0xfffffeec` | - |`31:0` | r/- | _reserved_.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<| `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_STATUS_RX7_AVAIL_ : _SLINK_STATUS_RX0_AVAIL_ ^| r/- <| At least one data word in RX FIFO available for link 7..0| `0xfffffed4` : `0xfffffedc` | - |`31:0` | r/- | _reserved_| `0xfffffee0` | `NEORV32_SLINK.DATA[0]` | `31:0` | r/w | Link 0 RX/TX data| `0xfffffee4` | `NEORV32_SLINK.DATA[1]` | `31:0` | r/w | Link 1 RX/TX data| `0xfffffee8` | `NEORV32_SLINK.DATA[2]` | `31:0` | r/w | Link 2 RX/TX data| `0xfffffeec` | `NEORV32_SLINK.DATA[3]` | `31:0` | r/w | Link 3 RX/TX data| `0xfffffef0` | `NEORV32_SLINK.DATA[4]` | `31:0` | r/w | Link 4 RX/TX data| `0xfffffef4` | `NEORV32_SLINK.DATA[5]` | `31:0` | r/w | Link 5 RX/TX data| `0xfffffef8` | `NEORV32_SLINK.DATA[6]` | `31:0` | r/w | Link 6 RX/TX data| `0xfffffefc` | `NEORV32_SLINK.DATA[7]` | `31:0` | r/w | Link 7 RX/TX data|=======================
Go to most recent revision | Compare with Previous | Blame | View Log
