Stream demultiplexer – openenoc_axis_demux

Routes or replicates each incoming stream frame to selected output paths.

Source: openenoc_axis_demux.sv.

Parameters

Parameters

Name

Default value

Allowed values

Description

M_COUNT

4

Integer >= 1

Number of output streams; route metadata must represent every output.

TID_ROUTE

1'b0

0 or 1; exclusive routing selection

Routes by the most significant ID bits; requires enabled ID on both sides with enough input index bits.

TDEST_ROUTE

1'b0

0 or 1; exclusive routing selection

Routes by the most significant DEST bits; requires enabled DEST on both sides with enough input index bits.

TUSER_BITMAP_ROUTE

1'b0

0 or 1; exclusive routing selection

Routes to the low M_COUNT USER bits; requires enabled USER on both sides and USER width >= M_COUNT. Zero selects frame discard.

Signals

Interface ports contain channels in both directions. The table identifies the selected modport or stream role; member directions follow that interface.

Public signals and interfaces

Name

Type

Direction / role

Description

clk

logic

input

Common clock for the input, output streams, and control.

rst

logic

input

Active-high synchronous reset of frame control and buffered data.

s_axis

taxi_axis_if.snk

sink

Incoming frame bytes and routing metadata.

m_axis[M_COUNT]

taxi_axis_if.src

source

Routed or replicated frame bytes and metadata.

enable

logic

input

Gates input READY on every beat, including within a frame. Already buffered output data can drain while enable is low.

drop

logic

input

In explicit mode, captures frame discard with the first accepted beat. Ignored when a metadata-routing option is enabled.

select

logic [$clog2(M_COUNT)-1:0]

input

In explicit mode, output index captured with the first accepted beat. Ignored when a metadata-routing option is enabled.

Architecture and operation

One s_axis feeds M_COUNT output streams. At the first input VALID/READY handshake of each frame, the block captures either one output index or a multicast bitmap, together with the decision to discard that frame. The decision remains in force through the accepted input TLAST. Changes to select, drop, or routing metadata after the first accepted beat do not redirect the remainder of that frame.

Let C = $clog2(M_COUNT). Routing options are mutually exclusive:

Route selection

Mode

Field sampled with the first accepted beat

Discard condition

All routing options zero

Explicit select input

drop = 1 or select >= M_COUNT

TID_ROUTE = 1

Most significant C bits of input TID

Index >= M_COUNT

TDEST_ROUTE = 1

Most significant C bits of input TDEST

Index >= M_COUNT

TUSER_BITMAP_ROUTE = 1

Low M_COUNT bits of input TUSER; bit n selects output n

Low M_COUNT bits are zero

drop and select apply only in explicit mode. Metadata-routing modes ignore both controls. For a single output, ID/DEST routing selects output zero. With a non-power-of-two output count, unused encoded indices select discard. A discarded frame is accepted through its input TLAST without creating output beats. It does not cancel earlier buffered output data.

enable gates input READY throughout a frame, rather than only at its start. Deasserting it pauses input acceptance while preserving the captured route or discard decision. Output data already accepted into the block can continue draining. The next frame takes a fresh routing decision after the current input TLAST; it can enter while that frame’s output tail is still buffered.

The output path implements a two-entry AXI-Stream register slice (skid buffer). It stores the output mask alongside each beat, so buffered beats retain their routing decisions across input frame boundaries. With ready outputs and uninterrupted input, a beat appears at the output in the clock interval after its input handshake, and one beat per cycle can follow. Input READY is registered before the combinational enable gate.

Multicast copies of a beat transfer together. The implementation asserts output VALID only when every selected output is READY. If one selected output is not ready, VALID is low on all selected outputs, even when other selected outputs are ready. The pending beat stays buffered, and input stops when the available storage fills. Unselected outputs remain invalid and their READY values do not block the selected transfer. Consumers must assert READY independently of VALID to allow this readiness-qualified output to progress. This behavior also applies to the single selected output in unicast modes.

DATA, KEEP, LAST, and enabled STRB pass through without adding or removing frame bytes. Enabled TUSER passes through on each beat; the captured route does not replace its value. TID and TDEST are cast to the output widths, preserving the low output-width bits. The routing bits are not separately stripped: if an output metadata field is as wide as the input field, it retains those bits as well. TUSER bitmap routing consumes a bitmap already prepared by the forwarding engine; this block does not remove the ingress port from it.

Use matching DATA widths and stream settings across all output interfaces. KEEP widths must agree with the input when KEEP is enabled. Frame operation requires TLAST. ID/DEST routing requires the selected metadata field to be enabled on both sides, with at least C input bits. Bitmap routing similarly requires enabled USER and at least M_COUNT input USER bits. Reset clears the captured frame decision, READY state, and both buffered beats; partial frames are abandoned.

Functional scenarios

All examples use M_COUNT = 4, 64-bit input/output DATA, KEEP_W = 8, and enabled KEEP and LAST. Input and output share a 10 ns clock, and reset has already been released. Each example states its routing configuration.

Every frame is 66 bytes, including the Ethernet header and excluding preamble, SFD, and FCS. Eight full beats use KEEP 0xFF; the final two-byte beat uses KEEP 0x03 and TLAST. FA uses DA0 through DA8, FB uses DB0 through DB8, and FC uses DC0 through DC8. Copies retain the same labels on every selected output. The source presents all queued frames continuously while they are pending. TUSER bitmaps show all four bits with a 0b prefix, in port order [3:0]. Metadata belongs to the internal processing stream and does not add Ethernet frame bytes.

A numbered tick marks a clock interval. A beat transfers at its ending rising edge when VALID and READY are high. x marks irrelevant payload values while VALID is low.

Explicit route retention, input gating, and frame discard

All three routing options are zero. The output consumers remain ready.

Queued frames and first-beat controls

Frame

Data beats

select

drop

Result

FA

DA0 through DA8

1

0

Output 1

FB

DB0 through DB8

3

1

Discard

FC

DC0 through DC8

2

0

Output 2

DA0 transfers in tick 1 with select = 1 and drop = 0. Changing those controls to select = 3 and drop = 1 in tick 3 does not redirect or discard FA. Input acceptance pauses in ticks 4 through 6 because enable = 0. The buffered DA2 still leaves output 1 in tick 4; the next input beat, DA3, waits until tick 7. FA’s final DA8 enters in tick 12 and leaves output 1 in tick 13.

In tick 13, DB0 also enters with the new select/drop decision. This captures discard for FB while FA’s output tail completes. The following diagram continues directly from the interval shown here.

The captured route survives control changes and an input pause.

The captured route survives control changes and an input pause

From tick 14, drop returns to zero and select becomes 2. FB remains discarded because its first beat already captured drop = 1. Its final DB8 is accepted in tick 21, and none of its beats appears on any output. FC starts in tick 22 with the new control values. It leaves output 2 in ticks 23 through 31, preserving all bytes and the final KEEP 0x03 mask.

The captured drop consumes FB before a fresh route sends FC to output 2.

The captured drop consumes FB before a fresh route sends FC to output 2

Unicast from the most significant destination bits

TDEST_ROUTE = 1; the other routing options are zero. Input TDEST is six bits wide, while output TDEST is four bits wide. The high two input bits select one of the four outputs, and the low four bits pass through. select = 0 and drop = 1 are held throughout this example and are ignored in this mode. All output consumers remain ready.

Destination metadata and selected outputs

Frame

Data beats

Input TDEST

Output

Output TDEST

FA

DA0 through DA8

0b110101

3

0b0101

FB

DB0 through DB8

0b010110

1

0b0110

FA enters in ticks 1 through 9 and leaves output 3 in ticks 2 through 10. FB enters immediately afterwards, in ticks 10 through 18, and leaves output 1 in ticks 11 through 19. Both frame boundaries and the reduced destination metadata remain associated with the correct output data. TID_ROUTE applies the same most-significant-bit selection to TID instead of TDEST.

The high destination bits select the output while the low bits pass through.

The high destination bits select the output while the low bits pass through

Multicast waits for every selected output; a zero bitmap discards

TUSER_BITMAP_ROUTE = 1; the other routing options are zero. USER is enabled and four bits wide on both sides. select = 0 and drop = 1 are ignored. Output 0 stays unready throughout the example; it is not a selected destination for either frame.

Frame bitmaps and output copies

Frame

Data beats

Input TUSER

Result

FA

DA0 through DA8

0b1010

Identical copies on outputs 1 and 3

FB

DB0 through DB8

0b0000

Discard

FA selects outputs 1 and 3. They receive DA0 through DA2 together in ticks 2 through 4. In ticks 5 through 8, output 3 is not ready. Output 1 remains ready, but both selected output VALID signals are low; neither copy advances. Input accepts DA4 in tick 5 into the remaining buffer space, then holds DA5 in ticks 6 through 9.

When output 3 becomes ready in tick 9, both outputs transfer the pending DA3. Input resumes in tick 10, and the remaining copies continue together. Both final DA8 beats transfer once in tick 14 with KEEP 0x03 and TLAST. Output 0’s low READY never blocks them.

FB starts entering in tick 14 with TUSER 0b0000 and is consumed through its final beat in tick 22 without an output copy. The externally asserted drop did not suppress FA; bitmap routing used the captured TUSER value for each frame.

Multicast copies advance together and a zero bitmap discards the next frame.

Multicast copies advance together and a zero bitmap discards the next frame

Verification

The test suite is in dv/core/openenoc_axis_demux/.

Testbench

This test suite validates the openenoc_axis_demux module, which demultiplexes AXI Stream input into multiple outputs based on routing configuration.

Routing Modes

The demux supports four routing modes, but only two are currently tested:

1. TID_ROUTE (Unicast/ID-based Routing)

  • Routes packets based on the TID (Transaction ID) field

  • Currently not tested

2. TDEST_ROUTE (Unicast/Destination-based Routing)

  • Routes packets based on the TDEST field

  • Packets are distributed to a single output port determined by TDEST

  • Useful for traditional address-based routing

3. TUSER_BITMAP_ROUTE (Multicast/User-Bitmap Routing)

  • Routes packets based on TUSER field interpreted as a bitmap

  • Each bit in TUSER selects one or more output ports

  • Supports multicast (one packet to multiple ports)

  • Includes “all-or-nothing” atomic delivery: all targeted ports receive the packet simultaneously or none do

4. Route using “select” signal (Manual/Select-based Routing)

  • Routes packets using an external select signal to directly specify output port(s)

  • Provides explicit control over routing decisions via a dedicated select input

  • Currently not tested

Coverage

TDEST_ROUTE Tests:

  • Single-port unicast delivery

  • Idle insertion and backpressure handling

  • Multiple data widths and output port counts

TUSER_BITMAP_ROUTE Tests:

  • Multicast to multiple ports

  • Idle insertion and backpressure handling

  • Multiple data widths and output port counts

  • Drop packets (empty bitmap)

  • All-or-nothing atomic delivery with varying backpressure per port