fix: flatten LLR interface to packed vector for Yosys compatibility

Yosys doesn't support unpacked array ports. Changed llr_in/llr_input
from `logic signed [Q-1:0] llr[N]` to `logic [N*Q-1:0] llr` packed
vector. Also fixed blocking assignment in INIT loops (Verilator
BLKLOOPINIT requirement).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
cah
2026-02-25 21:07:29 -07:00
parent c74ab93ae5
commit f2e419e25d
3 changed files with 11 additions and 10 deletions

View File

@@ -30,8 +30,8 @@ module ldpc_decoder_core #(
input logic early_term_en,
input logic [4:0] max_iter,
// Channel LLRs (loaded before start)
input logic signed [Q-1:0] llr_in [N],
// Channel LLRs (loaded before start) - packed vector for Yosys compatibility
input logic [N*Q-1:0] llr_in,
// Status
output logic busy,
@@ -208,14 +208,15 @@ module ldpc_decoder_core #(
INIT: begin
// Initialize beliefs from channel LLRs
// Use blocking assignment for array in loop (Verilator requirement)
for (int j = 0; j < N; j++) begin
beliefs[j] <= llr_in[j];
beliefs[j] = $signed(llr_in[j*Q +: Q]);
end
// Zero all CN->VN messages
for (int r = 0; r < M_BASE; r++)
for (int c = 0; c < N_BASE; c++)
for (int z = 0; z < Z; z++)
msg_cn2vn[r][c][z] <= {Q{1'b0}};
msg_cn2vn[r][c][z] = {Q{1'b0}};
row_idx <= '0;
col_idx <= '0;
iter_cnt <= '0;

View File

@@ -6,6 +6,7 @@
// - USE_POWER_PINS ifdef for Caravel power pass-through
// - 32-bit Wishbone address (lower 8 bits passed to wishbone_interface)
// - wb_sel_i byte selects accepted but unused (word-aligned access only)
// - LLR interface uses packed vector (Yosys compatibility)
module ldpc_decoder_top #(
parameter N_BASE = 8,
@@ -13,7 +14,6 @@ module ldpc_decoder_top #(
parameter Z = 32,
parameter N = N_BASE * Z,
parameter K = Z,
parameter M = M_BASE * Z,
parameter Q = 6,
parameter MAX_ITER = 30,
parameter DC = 8,
@@ -42,7 +42,7 @@ module ldpc_decoder_top #(
logic stat_busy;
logic stat_converged;
logic [4:0] stat_iter_used;
logic signed [Q-1:0] llr_input [N];
logic [N*Q-1:0] llr_input_flat; // packed LLR vector
logic [K-1:0] decoded_bits;
logic [7:0] syndrome_weight;
@@ -55,7 +55,7 @@ module ldpc_decoder_top #(
.ctrl_max_iter(ctrl_max_iter),
.stat_busy(stat_busy), .stat_converged(stat_converged),
.stat_iter_used(stat_iter_used),
.llr_input(llr_input), .decoded_bits(decoded_bits),
.llr_input(llr_input_flat), .decoded_bits(decoded_bits),
.syndrome_weight(syndrome_weight), .irq_o(irq_o)
);
@@ -65,7 +65,7 @@ module ldpc_decoder_top #(
) 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),
.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)

View File

@@ -32,7 +32,7 @@ module wishbone_interface #(
input logic stat_busy,
input logic stat_converged,
input logic [4:0] stat_iter_used,
output logic signed [Q-1:0] llr_input [N],
output logic [N*Q-1:0] llr_input, // packed LLR vector
input logic [K-1:0] decoded_bits,
input logic [7:0] syndrome_weight,
@@ -99,7 +99,7 @@ module wishbone_interface #(
int llr_idx;
llr_idx = word_idx * 5 + p;
if (llr_idx < N)
llr_input[llr_idx] <= wb_dat_i[p*Q +: Q];
llr_input[llr_idx*Q +: Q] <= wb_dat_i[p*Q +: Q];
end
end
end