Files
ldpc_optical/rtl/ldpc_decoder_top.sv
2026-02-25 21:08:49 -07:00

110 lines
3.8 KiB
Systemverilog

// LDPC Decoder Top - QC-LDPC Rate 1/8 for Photon-Starved Optical Communication
// Target: Efabless chipIgnite (SkyWater 130nm, Caravel harness)
//
// Code parameters:
// Rate 1/8, n=256 coded bits, k=32 info bits
// QC-LDPC with 7x8 base matrix, lifting factor Z=32
// Offset min-sum decoding, layered scheduling
//
// Input: 6-bit signed LLRs (log-likelihood ratios from photon detector)
// Output: 32 decoded information bits + convergence status
module ldpc_decoder_top #(
parameter N_BASE = 8, // base matrix columns
parameter M_BASE = 7, // base matrix rows
parameter Z = 32, // lifting factor
parameter N = N_BASE * Z, // codeword length = 256
parameter K = Z, // info bits = 32 (rate 1/8)
parameter Q = 6, // LLR quantization bits (signed)
parameter MAX_ITER = 30, // maximum decoding iterations
parameter DC = 8, // check node degree (= N_BASE for regular)
parameter DV_MAX = 7 // max variable node degree (= M_BASE for regular)
)(
input logic clk,
input logic rst_n,
// Wishbone B4 pipelined slave interface
input logic wb_cyc_i,
input logic wb_stb_i,
input logic wb_we_i,
input logic [7:0] wb_adr_i, // byte address (256 bytes address space)
input logic [31:0] wb_dat_i,
output logic [31:0] wb_dat_o,
output logic wb_ack_o,
// Interrupt (active high, directly to Caravel IRQ)
output logic irq_o
);
// =========================================================================
// Wishbone register interface
// =========================================================================
// Control/status registers
logic ctrl_start; // pulse: begin decoding
logic ctrl_early_term; // enable early termination
logic [4:0] ctrl_max_iter; // max iterations (0 = use MAX_ITER)
logic stat_busy;
logic stat_converged;
logic [4:0] stat_iter_used;
// LLR input buffer (packed vector for Yosys compatibility)
logic [N*Q-1:0] llr_input_flat;
// Decoded output
logic [K-1:0] decoded_bits;
logic [7:0] syndrome_weight;
wishbone_interface #(
.N(N), .K(K), .Q(Q)
) u_wb (
.clk (clk),
.rst_n (rst_n),
.wb_cyc_i (wb_cyc_i),
.wb_stb_i (wb_stb_i),
.wb_we_i (wb_we_i),
.wb_adr_i (wb_adr_i),
.wb_dat_i (wb_dat_i),
.wb_dat_o (wb_dat_o),
.wb_ack_o (wb_ack_o),
.ctrl_start (ctrl_start),
.ctrl_early_term(ctrl_early_term),
.ctrl_max_iter (ctrl_max_iter),
.stat_busy (stat_busy),
.stat_converged (stat_converged),
.stat_iter_used (stat_iter_used),
.llr_input (llr_input_flat),
.decoded_bits (decoded_bits),
.syndrome_weight(syndrome_weight),
.irq_o (irq_o)
);
// =========================================================================
// Decoder core
// =========================================================================
ldpc_decoder_core #(
.N_BASE (N_BASE),
.M_BASE (M_BASE),
.Z (Z),
.Q (Q),
.MAX_ITER (MAX_ITER),
.DC (DC),
.DV_MAX (DV_MAX)
) u_core (
.clk (clk),
.rst_n (rst_n),
.start (ctrl_start),
.early_term_en (ctrl_early_term),
.max_iter (ctrl_max_iter),
.llr_in (llr_input_flat),
.busy (stat_busy),
.converged (stat_converged),
.iter_used (stat_iter_used),
.decoded_bits (decoded_bits),
.syndrome_weight(syndrome_weight)
);
endmodule