fs_x16 HDL Worker
16-channel time-shared frame synchronizer; sliding 24-bit sync-word correlator
and HUNT/VERIFY/LOCKED flywheel per channel, forwarding only payload symbols
tagged with channel id and a frame_start marker.
Detail
The fs_x16 RTL architecture (rtl of worker) implements all 16
channels in a single clocked process (p_fsync) that performs an atomic
per-channel update each time an input sample beat arrives.
Input parsing. The process tracks whether each incoming beat is a
metadata or sample opcode. A 3-bit metadata beat counter mcnt is reset
on every SOM beat. Word index 2 of a metadata message carries the channel
id in bits [3:0], which is latched into cur_in_ch. On a sample
beat, ce = to_integer(cur_in_ch) selects all per-channel arrays.
Shift register and correlation. The 24-deep per-channel soft shift
register sr(ce) is updated in a VHDL variable v_sr so that the
correlation sees the updated register within the same clock cycle — the
same single-cycle update technique used in frame_sync.vhd. The
correlation accumulates over 24 positions:
v_corr += sr[k]whenSYNC_WORD_V[k] = '1'
v_corr -= sr[k]whenSYNC_WORD_V[k] = '0'
The sync word constant is SYNC_WORD_V = 0x02B8DB (24 bits). The
accumulator v_corr is 22 bits signed (CORR_W = 22), wide enough to
hold the sum of 24 16-bit terms without overflow.
HUNT state. The FSM checks resize(v_corr, 32) >= props_in.hunt_thresh
(signed comparison, threshold read each clock from the control plane).
When first crossing threshold, hunt_above(ce) is set and
hunt_prev(ce) latches the current correlation. On subsequent beats above
threshold, if v_corr < hunt_prev(ce) (peak descent detected), the FSM
fires: frame_start is asserted, the current symbol is forwarded as the
first payload symbol, and the frame counter is seeded to SYNC_W + 1 = 25
so that the next frame_start check (at frame_ctr = SYNC_W = 24)
does not fire a spurious duplicate marker on the very next symbol. The same
transition fires if the correlation drops back below threshold after having
been above it.
VERIFY state. The frame counter frame_ctr(ce) advances each symbol.
Payload symbols (frame_ctr in [24, 2167]) are forwarded speculatively.
At frame_ctr = 23 the correlation is compared against
props_in.lock_thresh; a pass transitions to LOCKED, a fail drops back
to HUNT. frame_start is asserted when frame_ctr = 24.
LOCKED state. Identical payload forwarding and frame counter wrap
(0–2167). At frame_ctr = 23, if the correlation is below
props_in.lock_thresh the miss counter miss_count(ce) increments.
When miss_count >= props_in.miss_limit (default 16) the FSM returns to
HUNT and the miss counter resets. A passing correlation clears the miss
counter.
Output packing. For each forwarded payload symbol, a 36-bit FIFO word
is pushed: cur_in_ch[3:0] & 15'b0 & fs_v & soft_q[15:0], where
fs_v is the frame_start flag and soft_q is the low 16 bits of the
input sample (the 3-bit quantized soft sign-extended, passed through verbatim
from dsd_x16). This maps to output sample bit [16] =
frame_start and bits [15:0] = quantized soft.
Output FIFO and FSM. A 64-entry x 36-bit FIFO decouples the per-channel
update from the WSI output. The output FSM (states OST_IDLE,
OST_M0–OST_M3, OST_S, OST_EOF) emits 4 metadata beats
followed by 1 sample beat per forwarded symbol. Channel id is placed in
metadata word 2 bits [3:0]. Backpressure from the downstream port is
honoured per-beat via output_in.ready.
Reset. rst is asserted on ctl_in.reset or a pulse on the
init property. All 16 instances of all per-channel state arrays are
cleared synchronously, including the 16 x 24 shift-register array sr.
Settle counter. Each channel maintains a prime_cnt that counts
symbols received since reset. The HUNT threshold check is gated by
prime_cnt(ce) >= props_in.settle_syms. The default settle_syms = 0
disables this gate; setting it to a non-zero value suppresses false HUNT
transitions during front-end startup transients.
Latency. The process is fully combinational within the sample-beat clock cycle (no pipeline stages across clocks for the correlator or FSM). A forwarded payload symbol is pushed to the FIFO in the same clock as the input sample beat that triggers it. Output beat latency is bounded by FIFO occupancy and downstream readiness.
Worker Properties
ocpi_buffer_size_outputType:
ushortAccess:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
FalseRead back:
False
Default value:
0
ocpi_blocked_outputType:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
TrueRead back:
False
Default value:
None
ocpi_max_latency_outputType:
ushortAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
FalseRead back:
False
Default value:
None
ocpi_latency_outputType:
ushortAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
TrueRead back:
False
Default value:
None
ocpi_messages_outputType:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
TrueRead back:
False
Default value:
None
ocpi_bytes_outputType:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
TrueRead back:
False
Default value:
None
Worker Ports
inputProtocol:
complex_short_timed_sampleOptional:
False
outputProtocol:
complex_short_timed_sampleOptional:
False
Inputs:
Outputs:
Worker Ports
Inputs:
input:Type:
StreamInterfaceProtocol:
complex_short_timed_sample-protClockDirection:
inData width:
32
Outputs:
output:Type:
StreamInterfaceProtocol:
complex_short_timed_sample-protWorker EOF:
trueClock:
inputData width:
32
Utilisation
Utilization reporting is not currently implemented.