|
CIRCT 23.0.0git
|
Functions | |
| List[int] | _select_reg_levels (int num_inputs, Optional[int] mux_pipeline_levels) |
| int | _select_latency (int num_inputs, Optional[int] mux_pipeline_levels) |
| BitsSignal | _select_mux (BitsSignal sel, List[BitsSignal] values, ClockSignal clk, Signal rst, Optional[int] mux_pipeline_levels) |
| RoundRobinArbiterMod (int num_inputs) | |
| ChannelArbiterMod (Channel channel_type, int num_inputs, int output_fifo_depth, bool buffer_inputs, bool telemetry, Optional[int] mux_pipeline_levels) | |
| ChannelSignal | ChannelArbiter (List[ChannelSignal] input_channels, ClockSignal clk, Signal rst, *Optional[AppID] appid=None, Optional[int] output_fifo_depth=None, bool buffer_inputs=True, Optional[int] mux_pipeline_levels=None, bool telemetry=True) |
|
protected |
Pipeline-register latency (cycles) that `_select_mux` inserts.
Definition at line 44 of file channel_arbiter.py.
References esiaccel.components.channel_arbiter._select_reg_levels().
Referenced by esiaccel.components.channel_arbiter.ChannelArbiterMod().
|
protected |
Return `values[sel]`. With `mux_pipeline_levels` falsy this is a flat combinational mux (a single `hw.array_get`, which CIRCT lowers to an unpipelined mux tree). Otherwise it is built as an explicit balanced binary mux tree -- 2:1 nodes consuming one `sel` bit per level -- with a pipeline register inserted after every `mux_pipeline_levels` levels. This lets a large/wide selection mux (the Fmax bottleneck of a big fan-in mux) be retimed across registers. The remaining `sel` bits are pipelined alongside the partial results so each level selects with the correctly-delayed index. The added latency is `_select_latency(len(values), mux_pipeline_levels)` cycles.
Definition at line 49 of file channel_arbiter.py.
References esiaccel.components.channel_arbiter._select_reg_levels().
Referenced by esiaccel.components.channel_arbiter.ChannelArbiterMod().
|
protected |
Tree levels after which `_select_mux` inserts a pipeline register. A register is placed after every `mux_pipeline_levels` levels, except after the final (root) level -- its result is registered downstream. This is the single source of truth for the mux-tree pipelining: `_select_mux` builds the registers at these levels and `_select_latency` just counts them.
Definition at line 27 of file channel_arbiter.py.
Referenced by esiaccel.components.channel_arbiter._select_latency(), and esiaccel.components.channel_arbiter._select_mux().
| ChannelSignal esiaccel.components.channel_arbiter.ChannelArbiter | ( | List[ChannelSignal] | input_channels, |
| ClockSignal | clk, | ||
| Signal | rst, | ||
| *Optional[AppID] | appid = None, |
||
| Optional[int] | output_fifo_depth = None, |
||
| bool | buffer_inputs = True, |
||
| Optional[int] | mux_pipeline_levels = None, |
||
| bool | telemetry = True |
||
| ) |
Build a pipelined, list-aware N:1 channel multiplexer.
Unlike the combinational `pycde.esi.ChannelMux`, this is a flat registered
round-robin arbiter with a feed-forward output stage (output register + FIFO
+ credit counter), so it closes timing at high fan-in. It also keeps
multi-flit list messages contiguous: once an input is granted, it holds the
output until a flit whose 'last' field is set has been transferred. List
framing is auto-detected from the channel type (window payloads with a 'last'
field); all other payloads are treated as single-flit messages.
Arguments:
input_channels: the channels to multiplex. All must share the same
(ValidReady) type.
clk, rst: clock and reset.
appid: optional `AppID` for the arbiter instance (e.g. to address it or to
disambiguate its telemetry in the appid hierarchy).
output_fifo_depth: depth of the output FIFO; must be greater than the
pipeline latency (one output register plus any selection-mux pipeline
latency). Defaults to that plus a small internal slack.
buffer_inputs: insert a per-input skid buffer to localize backpressure.
mux_pipeline_levels: if set, build the N:1 data-selection mux as an explicit
binary tree and insert a pipeline register after every this-many tree
levels (1 = register every level). This retimes the wide selection mux
for very large fan-in; the added latency is absorbed by the output FIFO /
credit counter. `None` (default) uses a flat combinational mux.
telemetry: emit telemetry (selected channel, list-length stats, etc.).
See `docs/components/ChannelArbiter.md`.
Definition at line 415 of file channel_arbiter.py.
| esiaccel.components.channel_arbiter.ChannelArbiterMod | ( | Channel | channel_type, |
| int | num_inputs, | ||
| int | output_fifo_depth, | ||
| bool | buffer_inputs, | ||
| bool | telemetry, | ||
| Optional[int] | mux_pipeline_levels | ||
| ) |
Build a pipelined, list-aware N:1 channel multiplexer module. See the `ChannelArbiter` convenience function for the user-facing entry point and `docs/components/ChannelArbiter.md` for the design.
Definition at line 147 of file channel_arbiter.py.
References esiaccel.components.channel_arbiter._select_latency(), esiaccel.components.channel_arbiter._select_mux(), and esiaccel.components.channel_arbiter.RoundRobinArbiterMod().
| esiaccel.components.channel_arbiter.RoundRobinArbiterMod | ( | int | num_inputs | ) |
Combinational round-robin winner selection, factored into its own module for waveform visibility. Given a per-input `valids` bitmask (bit `i` is input `i`) and a `start` index, `winner` is the lowest-index input that is valid and at index `>= start` (cyclically), falling back to the lowest-index valid input overall; `any_valid` is high when any input is valid. Purely combinational -- the owning state (`grant`/`busy`/`rr_ptr`) lives in the arbiter.
Definition at line 85 of file channel_arbiter.py.
Referenced by esiaccel.components.channel_arbiter.ChannelArbiterMod().