A Rust implementation of CCSDS LDPC decoding algorithms originally prototyped in the DelfiSpace LDPC‑Simulation project.
The codebase replaces the original Python/C++ scripts with a single memory‑safe, deterministic Rust library.
All decoding operations use fixed‑size arrays, checked indexing, and embedded CCSDS parity‑check matrices.
The implementation covers:
- Hard-decision decoders: Gallager‑A, Gallager‑B, WBF, MWBF, NWBF
- Soft-decision decoders: SPA, Min‑Sum, and Normalized Min‑Sum (NMS) in the LLR domain, featuring SIMD-accelerated vectorization for inner loops
- Layered Decoding Scheduling: Configurable layered belief propagation (shuffled scheduling) for soft-decision decoders, updating check node rows sequentially within a single iteration to halve the required iteration count for identical error-correction performance
-
Optimized SPA Architecture: Pre-allocated row buffers in
SpaDecoderLLR::decodeto eliminate per-iteration heap allocations -
Const-Generic Matrix Sizes: Generic
const M: usize, const N: usizeimplementations across encoders and decoders supporting alternative CCSDS matrices (128×256 and 256×512) without duplicated logic -
Custom Parity-Check Matrix Macro: Ergonomic
define_custom_matrix!macro helper allowing researchers to define and test arbitrary$(M, N)$ block codes using the const-generic architecture without modifying library source files -
Alternative Wireless Channel Models: Comprehensive channel simulation module (
src/channel.rs) supporting Binary Symmetric Channel (BSC) for hard-decision evaluations, alongside soft-decision fading models (Rayleigh, Rician$K$ , and Nakagami-m) with perfect CSI, block fading, frequency-selective fading, and burst-noise impairments -
High-Level Channel Abstraction: Ergonomic
Channelenum supporting dynamic simulation routing (simulate_llr) and CLI integration across all benchmark and simulation binaries - Robust Convergence Metrics: Structured decode return types exposing iteration counts and convergence status for microservice health tracking
-
Systematic LDPC Encoder: Generates valid codewords (
$k = 256 \to n = 512$ ) via lazily computed generator matrices over$\text{GF}(2)$ -
Embedded Flight-Software Readiness (
no_std): Core decoders and encoders support#![no_std]withalloc, allowing bare-metal execution on microcontrollers or flight computers without an operating system -
Zero-Copy Axum Routing: JSON request handlers mapping directly to fixed-size arrays and slices via Serde, backed by structured telemetry via
tracing -
Flexible CLI Arguments: Runtime configuration for simulation scripts via
clap(e.g., trial limits, seeds, smoke modes, scheduling strategies, and channel models) - BER Simulation Tools & Performance Benchmarks: Custom multithreaded simulation binaries, CSV outputs, and statistical Criterion suites measuring LLR computation and decoding overheads
-
Comprehensive Test Suite: Includes property-based testing via
proptestalongside deterministic correctness and fuzz trials
The structure of the CCSDS reference algorithms is preserved.
Hard‑decision decoders behave as defined in the literature; Gallager‑B, MWBF, NWBF, and SPA provide reliable correction behavior across all bit positions.
WBF is included for completeness but does not guarantee convergence for every single‑bit error on the CCSDS matrices.
The original DelfiSpace repository mixes Python control logic with C++ decoding kernels.
Porting the algorithms to Rust consolidates the implementation into a single, safe binary and removes:
- Python loop overhead
- C++ pointer arithmetic
- manual memory management
- ad‑hoc threading scripts
Rust provides deterministic memory safety and predictable performance for LDPC decoding workloads that evaluate thousands of parity‑check equations per iteration.
The SPA, Min‑Sum, and NMS decoders run tight numerical loops without garbage‑collection pauses or undefined behavior.
The core library is fully compatible with #![no_std] (using alloc), allowing deterministic decoders and encoders to run directly on bare-metal microcontrollers or space-grade flight computers without an operating system.
When compiled in standard environments, the default std feature flag automatically unlocks the Axum web service, CLI tools, and tracing infrastructure.
src/
bitarray.rs
channel.rs
encoder.rs
ldpc_decoder.rs
spa_decoder_llr.rs
matrices/
h_128_256.rs
h_256_512.rs
mod.rs
server_router.rs
src/bin/
ber_spa.rs
bench.rs
custom_ber_spa.rs
server.rs
benches/
ldpc_bench.rs
tests/
custom_matrix_tests.rs
encoder_tests.rs
fuzz_decoders.rs
ldpc_tests.rs
property_tests.rs
server_tests.rs
spa_decoder_tests.rs
Cargo.toml
README.md
The library includes an embedded systematic encoder for the CCSDS
use ldpc_rust::encoder::LDPC_ENCODER;
let message = [0u8; 256]; // raw message
let codeword = LDPC_ENCODER.encode(&message); // 512-bit systematic codeword [u | p]Define and evaluate arbitrary block codes seamlessly using the built-in macro interface:
use ldpc_rust::define_custom_matrix;
use ldpc_rust::spa_decoder_llr::SpaDecoderLLR;
define_custom_matrix!(
pub struct CustomMatrix4x8,
const M = 4,
const N = 8,
[
[1, 1, 0, 0, 1, 0, 0, 0],
[0, 1, 1, 0, 0, 1, 0, 0],
[0, 0, 1, 1, 0, 0, 1, 0],
[1, 0, 0, 1, 0, 0, 0, 1],
]
);
let mut decoder: SpaDecoderLLR<{ CustomMatrix4x8::ROWS }, { CustomMatrix4x8::COLS }> =
SpaDecoderLLR::new(&CustomMatrix4x8::DATA);Run standard tests (including the web server and CLI utilities):
cargo testRun bare-metal/embedded tests (no_std mode):
cargo test --no-default-featuresProperty-based testing suites automatically fuzz encoder-decoder roundtrips across randomized message payloads and noise bursts.
The multithreaded SPA/Min‑Sum decoder generates BER curves concurrently across multiple SNR points, channel models, and scheduling strategies (--scheduling layered or flooding). Live progress indicators are printed to stderr during execution, keeping stdout clean for CSV redirection.
cargo run --release --bin ber_spa -- --channel rician --scheduling layered --seed 42 > ber_spa_rician.csvFor custom matrix simulations:
cargo run --release --bin custom_ber_spa -- --channel rayleigh --scheduling layered > custom_ber_rayleigh.csvcargo run --release --bin benchReports total time, average time per trial, and throughput for custom micro-benchmarks.
cargo benchExecutes statistical performance tracking for bit-flip trials, LLR channel generation overheads, and SPA decoding loops, outputting detailed distribution metrics.
An HTTP service exposes the decoders for external tools with structured request telemetry.
Start:
cargo run --bin serverHealth check:
curl http://localhost:8080/healthcurl -X POST http://localhost:8080/decode/bitflip \
-H "Content-Type: application/json" \
-d '{"cw":[...], "iterations":10}'curl -X POST http://localhost:8080/decode/spa \
-H "Content-Type: application/json" \
-d '{"cw":[...], "snr_db":1.0, "iterations":10, "scaling_factor":0.75}'Build:
docker build -t ldpc-server .Run:
docker run -p 8080:8080 ldpc-serverThis project is based on CCSDS LDPC decoding algorithms and the DelfiSpace LDPC‑Simulation project:
https://github.com/DelfiSpace/LDPC-Simulation
The Rust version removes pointer‑level edge cases and undefined behavior present in the C++ implementation while maintaining algorithmic structure and matrix definitions consistent with CCSDS specifications.