// 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
