Files
ldpc_optical/CLAUDE.md
cah b93a6f5769 Initial LDPC optical decoder project scaffold
Rate-1/8 QC-LDPC decoder for photon-starved optical communication.
Target: Efabless chipIgnite (SkyWater 130nm, Caravel harness).

- RTL: decoder top, core (layered min-sum), Wishbone interface
- Python behavioral model with Poisson channel simulation
- 7x8 base matrix, Z=32, n=256, k=32

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:47:40 -07:00

5.5 KiB

ldpc_optical - LDPC Decoder for Photon-Starved Optical Communication

Overview

Low-Density Parity Check (LDPC) decoder targeting the Efabless chipIgnite program (SkyWater 130nm, Caravel harness). Designed for photon-starved optical communication links where received signals are soft probabilities (partial bits), not hard 0/1 decisions.

Target Application

  • Channel: Photon-counting optical (Poisson channel, single-photon detectors)
  • Use case: Deep space optical, underwater optical, or any photon-starved link
  • Input format: Soft LLR (log-likelihood ratios) representing probability of 0 vs 1
  • Code rate: 1/8 (32 info bits -> 256 coded bits) for maximum coding gain
  • Decoding: Offset min-sum (hardware-friendly approximation of belief propagation)

Architecture

Caravel SoC (Sky130, ~10 mm^2 user area)
+==============================================+
|  PicoRV32 (Caravel)                          |
|      |                                       |
|      | Wishbone B4                           |
|      |                                       |
|  +---v--------------------------------------+|
|  | ldpc_decoder_top                         ||
|  |   |                                     ||
|  |   +-- wishbone_interface                 ||
|  |   +-- llr_ram (256 x 6-bit)             ||
|  |   +-- msg_ram (1792 x 6-bit)            ||
|  |   +-- vn_update_array [Z=32]            ||
|  |   +-- cn_update_array [Z=32]            ||
|  |   +-- barrel_shifter_z32                 ||
|  |   +-- iteration_controller               ||
|  |   +-- syndrome_checker                   ||
|  |   +-- hard_decision_out                  ||
|  +------------------------------------------+|
+==============================================+

Code Parameters

Parameter Value Notes
Code type QC-LDPC Quasi-cyclic for hardware efficiency
Rate 1/8 (R = 0.125) k=32 info bits, n=256 coded bits
Base matrix 7 x 8 M_BASE=7 rows, N_BASE=8 cols
Lifting factor Z 32 n = N_BASE * Z = 256
Quantization 6-bit signed 1 sign + 5 magnitude
Max iterations 30 With early termination on syndrome check
Decoding algorithm Offset min-sum Offset ~0.5, ~0.2 dB from sum-product
Scheduling Layered (row-serial) ~2x faster convergence than flooding

Fabrication Target

Parameter Value
Process SkyWater 130nm (Sky130)
Platform Efabless Caravel harness
User area ~10.3 mm^2 (2.92 x 3.52 mm)
Target clock 150 MHz (aggressive for Sky130)
Estimated area ~1.5 mm^2 (decoder only)
Interface Wishbone B4 slave

Directory Structure

  • rtl/ - SystemVerilog RTL sources
  • tb/ - Verilator testbenches
  • model/ - Python behavioral model (bit-exact reference)
  • data/ - H-matrix definitions, test vectors
  • openlane/ - OpenLane ASIC flow configuration (future)
  • docs/ - Design documentation

Channel Model (Photon-Counting Optical)

The receiver uses single-photon detectors. Each time slot produces a photon count (or binary click/no-click). The channel LLR is:

LLR(y) = log(P(y | bit=1) / P(y | bit=0))

For binary detection (click/no-click):

  • P(click | bit=1) = 1 - exp(-(lambda_s + lambda_b))
  • P(click | bit=0) = 1 - exp(-lambda_b)

where lambda_s = signal photons/slot, lambda_b = background photons/slot.

LLR computation is done in software (PicoRV32). The decoder only sees quantized 6-bit LLRs.

Simulation

# Verilator lint check
verilator --lint-only -Wall rtl/*.sv

# Run testbench
verilator --binary --timing -o sim_ldpc tb/tb_ldpc_decoder.sv rtl/*.sv
./obj_dir/sim_ldpc

# Python behavioral model
cd model && python3 ldpc_sim.py

Key Design Decisions

  1. Soft input (LLR), not hard bits: The whole point of LDPC for photon-starved channels. Hard-decision decoding would lose ~2-3 dB of coding gain.
  2. Rate 1/8: Extreme redundancy for very low SNR. Shannon limit at R=1/8 is Eb/N0 ~ -1.59 dB; practical LDPC can approach 0 to +1 dB.
  3. Min-sum over sum-product: No multipliers or LUT-based tanh needed. Just comparators and adders. Critical for area on Sky130.
  4. Layered scheduling: Process one row of base matrix at a time, updating messages immediately. Converges in ~half the iterations of flooding schedule.
  5. Z=32 parallelism: 32 VN/CN processors working in parallel. Matches lifting factor for natural throughput.

Performance Estimates

  • Codeword decode: ~630 cycles (30 iterations x 21 cycles/iter)
  • At 150 MHz: ~238K codewords/sec
  • Decoded throughput: 238K x 32 bits = 7.6 Mbps
  • Latency: ~4.2 us per codeword
  • Area: ~1.5 mm^2 at Sky130 (leaves ~8.5 mm^2 for additional blocks)

Register Map (Wishbone, word-addressed)

Offset Name R/W Description
0x00 CTRL R/W [0]=start, [1]=early_term_en, [12:8]=max_iter
0x04 STATUS R [0]=busy, [1]=converged, [12:8]=iterations_used
0x08 CONFIG R/W [2:0]=code_sel (future: multiple H matrices)
0x10-0x4F LLR_IN W Channel LLRs, packed 5x6-bit per word
0x50-0x57 DECODED R 32 decoded bits (1 word)
0x5C SYNDROME_WT R Syndrome weight (0 = valid codeword)

Notes

  • No multipliers in the entire design (add/compare/select only)
  • 150 MHz is aggressive for Sky130 — may need to relax to 100 MHz depending on synthesis results
  • Error floor at rate 1/8 expected around BER 10^-7 to 10^-9 — may need outer RS code for optical comm BER requirements
  • Base matrix H must be carefully designed (PEG algorithm or density evolution optimization)