Framer 16 (framer16)
Converts a single-channel complex IQ sample stream into 16-sample positional frames, mimicking the channelizer output expected by the folded demod chain.
Tested platforms include xsim.
Design
The folded demod front-end (cr_x16, ted_x16, dsd_x16,
fs_x16) expects its input as a stream of 16-sample
complex_short_timed_sample messages — one message per channelizer output
cycle — where each sample slot corresponds to one of the 16 frequency bins
assigned to that port. framer16 generates this framing from a
single-channel stream so that the folded chain can be exercised in pure
simulation, without a real channelizer or AD9361 hardware.
For each input sample the worker emits a 16-beat output message. The
sample is placed in beat position (a writable property); all other beats
carry zero. som is asserted on beat 0 and eom on beat 15. The
output opcode is always complex_short_timed_sample_sample_op_e.
The worker accepts one input sample per emitted frame. While it is
serialising the 16-beat output burst (busy = '1'), the input port is
back-pressured (take is deasserted). At the nominal OPV waveform rate of
216.8 kHz (after 1/15 decimation, SPS = 4), the output burst runs at
3.47 MHz — well below the fabric clock — so the input effectively never
stalls.
The swap_iq property swaps the two 16-bit halves of each input sample
word before latching. This accommodates the cr_x16 I/Q word convention
(I/real in bits 31:16, Q/imag in bits 15:0) when the upstream decimator or
file source uses the opposite packing (real in bits 15:0).
Input samples with any opcode other than complex_short_timed_sample_sample
are silently discarded; only sample-opcode beats are latched and framed.
EOF from the input is latched and propagated to the output after the current frame (if any) has been fully emitted and the worker has returned to the idle state.
Interface
<?xml version='1.0' encoding='utf-8'?>
<!-- framer16: wrap a single-channel IQ stream into the 16-channel POSITIONAL
frame format the folded demod chain (cr_x16 ...) expects, exactly mimicking
the channelizer's output. For each input sample it emits one 16-sample
complex_short_timed_sample message (SOM on position 0, EOM on position 15)
with the sample placed in `position` and zeros in the other 15 positions.
Use in pure-sim validation (no channelizer / no AD9361):
file_read(frame_bits) -> msk_mod -> polyphase_decimator(/15) -> framer16
-> cr_x16 -> ted_x16 -> dsd_x16 -> fs_x16 -> msk_decode_x16 -> file_write
The decimator sets the rate (216.8 kHz, SPS=4); framer16 sets the framing.
I/Q convention: cr_x16 reads I/real = data[31:16] (high 16). If the upstream
decimator puts real in the low 16, set swap_iq=true. -->
<ComponentSpec>
<property name='init' type='bool' writable='true' default='false'
description="Pulse high to reset the framer"/>
<property name='position' type='uchar' writable='true' default='0'
description="Which of the 16 frame positions (0..15) carries the signal; others are zero"/>
<property name='swap_iq' type='bool' writable='true' default='false'
description="Swap the I/Q 16-bit halves of each sample (set if upstream uses real=low 16 but cr_x16 expects real=high 16)"/>
<port name="input" producer="false" protocol="complex_short_timed_sample-prot"/>
<port name="output" producer="true" protocol="complex_short_timed_sample-prot"/>
</ComponentSpec>
Ports
Inputs:
input: Single-channel complex_short_timed_sample stream to be framed.Protocol:
complex_short_timed_sample-protOptional:
False
Outputs:
output: 16-sample positional frame stream compatible with the folded demod chain input.Protocol:
complex_short_timed_sample-protOptional:
False
Opcode Handling
Only sample opcodes on the input are processed. Any other opcode is
consumed (taken from the input) but does not trigger a framing cycle and
produces no output. The output always carries the sample opcode.
Properties
init: Pulse high to reset the framer.Type:
boolAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
false
position: Which of the 16 frame positions (0..15) carries the signal; others are zero.Type:
ucharAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
0
swap_iq: Swap the I/Q 16-bit halves of each sample (set if upstream uses real=low 16 but cr_x16 expects real=high 16).Type:
boolAccess:
Parameter:
FalseWritable:
TrueInitial:
FalseVolatile:
False
Default value:
false
Implementations
framer16(HDL)Wraps a single-channel IQ sample stream into 16-sample positional frames for simulation testing of the folded demod chain.
Dependencies
The framer16 HDL worker depends on:
ieee.std_logic_1164
ieee.numeric_std
ocpi.types(forcomplex_short_timed_sampleopcode constants)
Limitations
Limitations of framer16 are:
Designed for simulation use only. The 16x output expansion is not suitable for production placement ahead of a real channelizer.
positionmust be in the range 0 to 15. Values of 15 or higher are accepted but values of 16 or above exceed the 4-bitpos_cntcounter range and will never match, producing a frame of all zeros.Only the
sampleopcode is forwarded. Metadata or time-tag opcodes from an upstream worker are silently dropped.
Testing
The unit test drives the input with a sequence of complex_short_timed_sample
messages at position = 0. The verify script checks that each output
message is exactly 16 samples long, that beat 0 carries the expected I/Q
value, that all other beats are zero, and that som/eom framing is
correct.
Tested platforms: None
Component testing not completed.