Skip to content

Conversation

@Abraxas3d
Copy link
Member

Major release adding forward error correction and LibreSDR hardware support.

Encoder/Decoder Changes

  • K=7 convolutional encoder and hard-decision Viterbi decoder
  • Byte-level interleaving (optional bit vs byte)
  • Fixed transmitter stall issues
  • Fixed decoder stall with no gaps between frames
  • Added dont_touch attributes to prevent Vivado optimization

LibreSDR Support (new TARGET=libre)

  • XC7Z020-CLG400: 53,200 LUTs (vs PlutoSDR's 17,600)
  • AD9363 with LVDS interface
  • Pin constraint fixes from hz12opensource patches
  • Full firmware build: make TARGET=libre
  • Tested on hardware: boots, AD9363 detected

Build Instructions

PlutoSDR (existing)

make TARGET=pluto

LibreSDR (new)

cd firmware/ori/libre && ./setup_libre.sh
cd ../../ && make TARGET=libre

mwishek and others added 30 commits October 26, 2025 21:35
… type cast from std_logic to boolean. Now make will work.
…k.axi4lite_intf_pkg.ALL;

--USE work.msk_top_regs_pkg.ALL;
USE work.pkg_msk_top_regs.ALL;
…e debug registers from sync_detect, and publishing the updated branch
- Updated signal naming: fifo_overflow -> frame_buffer_overflow in msk_top
- Added VHDL-2008 conversion to RDL Makefile for XSim compatibility
- Converted PeakRDL generated files to VHDL-2008 (context -> use clauses)
- Testbench successfully simulates with frame sync locking

XSim requires VHDL-2008 syntax while synthesis accepts VHDL-2019.
RDL Makefile now auto-converts generated files after generation.
…t using TLAST as a trigger. TLAST already works automatically with the AXIS DMA. It marks frame boundaries and the DMA respects it without needing any special config. SYNC_TRANSFER_START was erroneously set to TRUE, which overrode the FALSE setting in the ADC DMA block in system_bd.tcl. Once this was fixed, rx_buffer_refill() no longer timed out and data is being seen by the processor side application.
… that must be initialized and signals where the initialization can and was removed
- Add sdboot command for SD card booting
- Replace serial@e0001000 (Pluto) with serial@e0000000 (LibreSDR)
- Fixes applied as post-processing for PLATFORM=libre only
LVDS TX tuning fails because MSK block sits between DDS and DAC,
outputting zeros during boot before initialization. Setting
skip-mode=2 tells AD9361 driver to skip TX timing calibration
since FPGA constraints handle TX timing (met with 0.932ns slack).

RX tuning still runs normally as MSK is downstream of axi_ad9361
on receive path.
- viterbi_decoder_k7_simple: Add KEEP_HIERARCHY on architecture to prevent
  cross-boundary optimization that was reducing decoder to 3 LUTs
- viterbi_decoder_k7_simple: Add dont_touch on critical signals (state,
  metrics, decision_mem, shift registers, output buffer)
- ov_frame_encoder: Add dont_touch on buffers and state machine
- ov_frame_encoder: Add ram_style block on large buffers
- conv_encoder_k7: Add dont_touch on shift registers and state

Before: U_DECODER 3 LUTs, 3 FFs, 0 BRAM (completely optimized away)
After:  U_DECODER 1679 LUTs, 4828 FFs, 3 BRAM (functional decoder)
…ft-decision correlation for improved low-SNR performance with PSLR-optimized sync word (0x02B8DB).
- Add dont_touch attribute to bit_count in conv_encoder_k7.vhd
- Add dont_touch to encoder_start, encoder_busy, encoder_done in ov_frame_encoder.vhd
- Add dont_touch to U_ENCODER instance label
- Update msk_demodulator submodule: differential decode for soft decisions
…case it sneaks through configuration somehow
Previous commit 8a7f516a was force-pushed away from ADI repo.
This commit exists and can be fetched by fresh clones.
- Explicit DMA signal connections (m_axis_data, m_axis_valid, etc.)
  fixes data path - FIFO pointers now move, encoder leaves IDLE
- TSAMPL=30.72MHz in dtsi gives out_voltage_sampling_frequency=61.44MHz
- l_clk=245.76MHz, dac_datarate=3 should give 61.44MHz valid rate
- Remaining issue: NCO runs 4x too fast (216k bps vs expected 54k bps)
- dac_datarate changes spectrum but not bitrate - tx_valid gating broken
- Then tried: DAC_USERPORTS_DISABLE=0 in system_bd.tcl
LibreSDR LVDS mode runs l_clk at 245.76 MHz (4x sample rate).
MSK modem expects 61.44 MHz (1 clock = 1 sample).

Changes:
- clk_div_by4.vhd: BUFR-based divide-by-4, phase-aligned
- system_bd.tcl: MODE_1R1T=1, divider between l_clk and msk_top/clk
- system_bd.tcl: tx_valid/rx_svalid tied to VCC (every cycle valid)
- msk_top_ip.tcl: added clk_div_by4.vhd to source list

msk_top.vhd unchanged - clock domain change is external.

Revert this commit if clock divider approach fails.
- ov_frame_decoder: Fix deinterleaver to use forward interleave_address_bit()
  mapping (reads from where encoder wrote)
- byte_to_bit_deserializer: Hold last valid bit at byte boundaries instead
  of forcing to zero (avoids potential glitches)
- axis_async_fifo: Pipelined Gray-to-binary conversion for 245 MHz timing
- msk_top: Integration fixes for encoder/decoder chain
- system_bd.tcl: Connect AD9361 DAC channel 1 data ports to fix LVDS
  interleaving (was outputting zeros on ch1)
- Added ILA debug probes for TX path troubleshooting

Simulation passes end-to-end. Hardware still shows spectral anomalies
(6775 Hz comb at byte rate) - investigation ongoing.
New files:
- viterbi_decoder_k7_soft.vhd: Soft-decision Viterbi decoder
- tb_viterbi_soft.vhd: Basic soft vs hard comparison testbench
- tb_viterbi_extended.vhd: Extended BER sweep testbench

Soft decoder features:
- Configurable SOFT_WIDTH generic (default 3-bit, supports 3/4/8/16)
- Parallel soft input interface (NUM_SYMBOLS × SOFT_WIDTH bits)
- Soft branch metric calculation replaces Hamming distance
- debug_path_metric output for decode quality monitoring
- Same FSM structure as hard decoder for easy integration

BER test results (1 OV frame = 1072 payload bits):
- 0-5% BER: Both decoders perfect
- 10% BER: Hard=111 errors, Soft=0 errors
- 20% BER: Hard=491 errors, Soft=62 errors
- 25% BER: Hard=522 errors, Soft=109 errors
- 30% BER: Hard=533 errors, Soft=229 errors

Soft decoder provides ~2-3 dB coding gain, staying error-free
up to 15% channel BER vs hard decoder's ~5% threshold.

Next: Integrate with frame_sync_detector and ov_frame_decoder
to pass quantized soft values through the RX chain.
New files:
- run_soft_tb.tcl: Vivado batch script for basic test
- run_extended_tb.tcl: Vivado batch script for BER sweep

Soft decoder features:
- Configurable SOFT_WIDTH generic (default 3-bit)
- debug_path_metric output for decode quality monitoring

BER test results (1 OV frame = 1072 bits):
- 0-5% BER: Both decoders perfect
- 10% BER: Hard=111 errors, Soft=0
- 20% BER: Hard=491 errors, Soft=62
- 30% BER: Hard=533 errors, Soft=229

Soft decoder provides ~2-3 dB coding gain.
New files:
- frame_sync_detector_soft.vhd: Frame sync with 3-bit soft quantization
  - Stores soft values in arrival order
  - Outputs via AXI-Stream to decoder

- ov_frame_decoder_soft.vhd: Soft frame decoder
  - soft_deinterleave_address() handles bit ordering
  - Corrected randomizer table to match encoder

Modified:
- msk_top.vhd: Wire up soft decoder path
- msk_top_ip.tcl: Update IP packaging

Tested in simulation with 134-byte frames.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants