msk_decode_x16 HDL Worker

HDL implementation of the 16-channel OPV back-end decoder: per-channel double-buffered BRAM soft collection and a single time-shared Viterbi decoder.

Detail

This worker implements only the shared back-end of the OPV demodulator (the Viterbi decoder and output framing). All DSP front-end processing (carrier correction, matched filter / timing recovery, differential detection, soft quantization, frame synchronisation) is performed by the upstream folded workers cr_x16 → ted_x16 → dsd_x16 → fs_x16.

Input parser. The input stream uses complex_short_timed_sample metadata/sample framing produced by fs_x16. Per payload symbol, a metadata message (4 words) carries the local channel index (0..15) in byte 2 of the value field; the following one-word sample message carries bit 16 = frame_start and bits 2:0 = 3-bit signed soft decision. The parser registers the current channel index (cur_in_ch) on word 2 of each metadata message, then on the subsequent sample beat asserts dec_soft_valid(ch) and latches fe_soft_q_d(ch) / fe_frame_start(ch).

BRAM soft collect. 32 banks are laid out as a flat 1-D signal soft_bram of type bram_flat_t (N_BANKS*BRAM_DEPTH entries of 4-bit cells) with the attribute ram_style="block". Bank addressing is flat_addr = bank * 4096 + symbol_index. The power-of-2 depth of 4096 (only entries 0..2143 are used per bank) is required to keep the index in-range and allow Vivado to infer BRAM18; a non-power-of-2 depth of 2144 triggers Synth 8-7186 (“incorrect usage of block RAM”) and causes the array to fall back to flip-flops. A flat 1-D array with a registered outer index (wr_bank_r, rd_bank_r) is likewise required — an array-of-arrays indexed by a dynamic outer index is seen by Vivado as a “non-memory variable” (Synth 8-3514) and also falls back to flip-flops.

The write process maintains per-channel write pointers (wr_idx) and a double-buffer select bit (wr_buf_sel). At frame_start, the write pointer resets to 0 and the first soft symbol is written with address 0. Subsequent symbols advance the pointer. At symbol 2143 (ENCODED_BITS-1) the bank’s bank_ready flag is set, the buffer select bit is toggled, and collection continues into the alternate bank. A sample beat whose target bank is already marked ready is stalled via input_out.take = not input_stall, preventing the write process from overwriting an undecoded frame.

Scheduler (7-state FSM).

  • SCHED_IDLE: scans all 32 bank_ready flags (priority = lowest bank index); on the first ready bank, records decode_ch and decode_bank, issues a BRAM read for address 0, and transitions to SCHED_RD0.

  • SCHED_RD0: issues the read for address 1; transitions to SCHED_RD1.

  • SCHED_RD1: issues the read for address 2; transitions to SCHED_DRIVE.

  • SCHED_DRIVE: bram_rd_data holds the symbol at sym_count. Asserts dec_soft_vld; on sym_count = 0 also asserts dec_frame_str and enqueues abs_bin = port_index*16 + decode_ch into the tag FIFO. Issues the next BRAM read and increments drive_idx until the last address (ENCODED_BITS) has been issued, then transitions to SCHED_LAST1.

  • SCHED_LAST1 / SCHED_LAST2: drain the 2-cycle BRAM read pipeline, firing dec_soft_vld for symbols 2142 and 2143. At SCHED_LAST2, clears bank_ready(decode_bank) and transitions to SCHED_WAIT.

  • SCHED_WAIT: waits for dec_byte_last from opv_frame_decoder, then captures the path metric and returns to SCHED_IDLE.

Total re-drive time per channel: 2146 clocks (2144 symbols + 2 pipeline drain cycles). Viterbi decode time: approximately 70,881 clocks (~0.71 ms at 100 MHz). At 16:1 share, all 16 channels decode within 11.4 ms, well under the 40 ms OPV frame period (28.5% utilisation).

Output FSM. Waits in OST_IDLE until the tag FIFO is non-empty and the output byte FIFO holds at least 134 bytes (one complete frame). Emits a 16-byte metadata message (id = 0, pad = 0, value byte 0 = abs_bin) then a 134-byte sample message. Frame length is controlled by a byte counter, not FIFO drain level, ensuring EOM is always asserted on byte 133. After input EOF and all banks clear, asserts output_out.eof to terminate the application.

Source files. viterbi_decoder_k7_soft.vhd and opv_frame_decoder.vhd are shared with msk_demod.hdl and referenced via relative path in the OWD.

Worker Properties

  • ocpi_buffer_size_output

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: True

      • Volatile: False

      • Read back: False

    • Default value: 0

  • ocpi_blocked_output

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_max_latency_output

    • Type: ushort

    • Access:

      • Parameter: True

      • Writable: False

      • Initial: False

      • Volatile: False

      • Read back: False

    • Default value: None

  • ocpi_latency_output

    • Type: ushort

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_messages_output

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

  • ocpi_bytes_output

    • Type: ulong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

      • Read back: False

    • Default value: None

Worker Ports

    Inputs:

  • input

    • Protocol: complex_short_timed_sample

    • Optional: False

  • Outputs:

  • output

    • Protocol: uchar_timed_sample

    • Optional: False

Worker Ports

Inputs:

  • input:

    • Type: StreamInterface

    • Protocol: complex_short_timed_sample-prot

    • ClockDirection: in

    • Data width: 32

Outputs:

  • output:

    • Type: StreamInterface

    • Protocol: uchar_timed_sample-prot

    • Worker EOF: true

    • Clock: input

    • Data width: 8

Utilisation

Utilization reporting is not currently implemented.