Priority Switch
Two-way single-word switch with a hard priority channel. Forwards data from a regular IN channel unless a PRIORITY channel has data pending, in which case PRIORITY always wins the output slot. Useful to inject synchronisation / T0 marker words into a downstream event stream while blocking the regular flow until the marker has been forwarded.
Introduction
The Priority Switch block is a two-input, one-output word switch where one input has hard priority over the other. It is designed to insert synchronisation or reference words (typically a “T0” absolute timestamp) into a stream of regular data words (typically relative timestamps of the same T0) that are being pushed toward a downstream FIFO or list.
Two input handshakes:
- IN + DV_IN + BUSY_IN - the regular data stream.
- PRIORITY + DV_PRIORITY + BUSY_PRIORITY - the synchronisation word.
One output handshake:
- OUT + DV_OUT + BUSY_OUT - toward the downstream module.
Both inputs share the same Word Size (set by a property).
Pin Description
Back-pressure toward the source of the IN channel.
- HIGH (1): either the IN latch is full OR the downstream is asserting BUSY_OUT (nothing can leave the block). In both cases the source should stop sending on IN.
- LOW (0): ready to accept a new IN word.
Back-pressure toward the source of the PRIORITY channel.
- HIGH (1): either the PRIORITY latch is full OR the downstream is asserting BUSY_OUT. Depending on the collision policy, further DV_PRIORITY pulses will still be dropped (Keep old) or will overwrite the pending word (Overwrite with new) if they arrive.
- LOW (0): ready to accept a new PRIORITY word.
Properties
Width of the IN, PRIORITY and OUT data ports in bits
Width in bits of the IN, PRIORITY and OUT data ports. Range: 2 to 1024, default 32. Changing this value re-designs the symbol (port widths change).Default: 32
Range: 2 – 1024
What to do when a new PRIORITY word arrives while the previous one is still waiting to be forwarded
Policy applied when a new PRIORITY word arrives while the previous PRIORITY word is still waiting to be forwarded downstream.
- Keep old (default): the new PRIORITY word is dropped; the older one is preserved and eventually forwarded.
- Overwrite with new: the new PRIORITY word replaces the older one in the latch; the older one is lost.
This policy applies only to the PRIORITY channel. On the IN channel new words are always dropped while BUSY_IN is high.
Default: Keep old
Options: Keep old Overwrite with new
Usage
Motivation
In systems where a downstream list holds photon (or generic event) timestamps referenced to a common absolute reference (a “T0” tick), the T0 word must reach the list before any of the events that follow it. Otherwise the software reader will attribute those events to the wrong T0.
The Priority Switch acts as a gate:
IN (regular events) ─────┐
DV_IN ──────────────────────►│
│
┌──────▼──────┐
│ PRIORITY │
│ SWITCH ├─── OUT ───► downstream list
│ ├─── DV_OUT
└──────▲──────┘
│
PRIORITY (T0 word) ─────────┘
DV_PRIORITY ────────────────►
As long as a PRIORITY word is waiting to be forwarded, no IN word can pass through, guaranteeing correct ordering downstream.
Handshake rules
Both input handshakes follow the standard SCI-Compiler DV / BUSY protocol:
- Source raises DV_x = ‘1’ for one clock cycle to publish a word.
- The block latches the word and, from the next clock cycle, raises BUSY_x = ‘1’ to tell the source not to send another word until the latch has been drained.
- When the latch is drained (the word has been forwarded to OUT), the block drops BUSY_x, so the source is free to send again.
In addition, BUSY_IN and BUSY_PRIORITY are also forced HIGH the moment the downstream asserts BUSY_OUT, even if the corresponding latch is still empty. Rationale: while the block cannot forward anything it makes no sense to keep accepting upstream traffic; the flag rise stops the source before it can push a burst that would fill the switch and then lose the tail. When BUSY_OUT drops, both BUSY_x flags fall back to reflect the state of their respective latches.
Arbitration
On every clock the block checks the internal latches in this order:
- PRIORITY pending and BUSY_OUT = ‘0’ → forward PRIORITY, clear the PRIORITY latch.
- Otherwise IN pending and BUSY_OUT = ‘0’ → forward IN, clear the IN latch.
- Otherwise no output (DV_OUT = ‘0’).
PRIORITY always wins over IN. IN never overtakes PRIORITY.
Simultaneous arrival
If both DV_IN and DV_PRIORITY fire on the same clock cycle:
- Both words are latched into their respective slots.
- Both BUSY_IN and BUSY_PRIORITY go high the next cycle.
- As soon as BUSY_OUT is low the PRIORITY word is forwarded first.
- The next cycle the IN word is forwarded and BUSY_IN drops.
So even in a collision the PRIORITY word wins with a small fixed latency (typically 2 clocks) and the IN word follows immediately after.
Collision on PRIORITY
If a new PRIORITY word arrives while the previous PRIORITY word is still waiting in the latch (BUSY_OUT was blocking, so nothing has been forwarded yet), the behaviour is compile-time selectable via the Priority collision policy property:
| Policy | Effect |
|---|---|
| Keep old | The new PRIORITY word is silently dropped, the old one wins the output slot. |
| Overwrite with new | The new PRIORITY word replaces the old one in the latch, the old one is lost. |
For IN there is no collision policy: while the IN latch is full, a new IN word is always dropped (upstream is expected to obey BUSY_IN).
Timing
All outputs are registered and update on the rising edge of clk.
Typical minimum latency (source to downstream) is 2 clock cycles (1 for latching, 1 for output). The latency grows if BUSY_OUT is asserted or if a collision is being resolved.
Reset
Reset is active-high and synchronous. When RESET = ‘1’ all internal latches, pending flags and outputs are cleared. BUSY_IN, BUSY_PRIORITY and DV_OUT all go low.
Resources & Timing
-
Latency: 2 clock cycles minimum, longer under BUSY_OUT or collisions
-
Throughput: Up to 1 word per clock cycle when the downstream is not busy
Fully synchronous, no external primitives, no FIFO. Uses two data latches (one per input channel) and two 1-bit pending flags. Resource usage scales with WordSize.