From 65863e76b66bc07a6c47bc123d880c42b1231f54 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Sun, 29 Sep 2019 13:06:23 +0200 Subject: [PATCH] repeat layers with DDSMs to resolve write conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Idea taken from: HIGH-SPEED CONFLICT-FREE LAYERED LDPC DECODER FOR THE DVB-S2, -T2 AND -C2 STANDARDS By Cédric Marchand, Laura Conde-Canencia and Emmanuel Boutillon - 2013 --- ldpc_decoder.hh | 95 ++++++++++++++++++++++++++++-------------------- ldpc_decoder2.hh | 95 ++++++++++++++++++++++++++++-------------------- 2 files changed, 112 insertions(+), 78 deletions(-) diff --git a/ldpc_decoder.hh b/ldpc_decoder.hh index 32991c0..0c79318 100644 --- a/ldpc_decoder.hh +++ b/ldpc_decoder.hh @@ -161,46 +161,63 @@ class LDPCDecoder shift[c] = (shift[c] + 1) % M; } std::sort(lo, lo + cnt, [](const Loc &a, const Loc &b){ return a.off < b.off; }); - TYPE par[2]; - if (i) { - par[0] = pty[W*(i-1)+j]; - } else if (j) { - par[0] = pty[W*(q-1)+j-1]; - } else { - par[0] = rotate(pty[PTY-1], 1); - par[0].v[0] = 127; + bool wd[deg]; + for (int d = 0; d < deg; ++d) + wd[d] = false; + for (int c = 1; c < cnt; ++c) + if (lo[c].off == lo[c-1].off) + wd[c] = true; + for (bool repeat = true; repeat;) { + TYPE par[2]; + if (i) { + par[0] = pty[W*(i-1)+j]; + } else if (j) { + par[0] = pty[W*(q-1)+j-1]; + } else { + par[0] = rotate(pty[PTY-1], 1); + par[0].v[0] = 127; + } + par[1] = pty[W*i+j]; + TYPE mes[cnt]; + for (int c = 0; c < cnt; ++c) + mes[c] = rotate(msg[lo[c].off], -lo[c].shi); + TYPE inp[deg], out[deg]; + for (int c = 0; c < cnt; ++c) + inp[c] = vqsub(mes[c], bl[c]); + inp[cnt] = vqsub(par[0], bl[cnt]); + inp[cnt+1] = vqsub(par[1], bl[cnt+1]); + cnp(out, inp, deg); + for (int d = 0; d < deg; ++d) + out[d] = vclamp(out[d], -32, 31); + for (int d = 0; d < deg; ++d) + out[d] = selfcorr(bl[d], out[d]); + for (int d = 0; d < deg; ++d) + if (!wd[d]) + bl[d] = out[d]; + for (int c = 0; c < cnt; ++c) + mes[c] = vqadd(inp[c], out[c]); + par[0] = vqadd(inp[cnt], out[cnt]); + par[1] = vqadd(inp[cnt+1], out[cnt+1]); + if (i) { + pty[W*(i-1)+j] = par[0]; + } else if (j) { + pty[W*(q-1)+j-1] = par[0]; + } else { + par[0].v[0] = pty[PTY-1].v[D-1]; + pty[PTY-1] = rotate(par[0], -1); + } + pty[W*i+j] = par[1]; + for (int c = 0; c < cnt; ++c) + if (!wd[c]) + msg[lo[c].off] = rotate(mes[c], lo[c].shi); + repeat = false; + for (int c = 1; c < cnt; ++c) + if (wd[c] && !wd[c-1]) { + wd[c] = false; + repeat = true; + ++c; + } } - par[1] = pty[W*i+j]; - TYPE mes[cnt]; - for (int c = 0; c < cnt; ++c) - mes[c] = rotate(msg[lo[c].off], -lo[c].shi); - TYPE inp[deg], out[deg]; - for (int c = 0; c < cnt; ++c) - inp[c] = vqsub(mes[c], bl[c]); - inp[cnt] = vqsub(par[0], bl[cnt]); - inp[cnt+1] = vqsub(par[1], bl[cnt+1]); - cnp(out, inp, deg); - for (int d = 0; d < deg; ++d) - out[d] = vclamp(out[d], -32, 31); - for (int d = 0; d < deg; ++d) - out[d] = selfcorr(bl[d], out[d]); - for (int d = 0; d < deg; ++d) - bl[d] = out[d]; - for (int c = 0; c < cnt; ++c) - mes[c] = vqadd(inp[c], out[c]); - par[0] = vqadd(inp[cnt], out[cnt]); - par[1] = vqadd(inp[cnt+1], out[cnt+1]); - if (i) { - pty[W*(i-1)+j] = par[0]; - } else if (j) { - pty[W*(q-1)+j-1] = par[0]; - } else { - par[0].v[0] = pty[PTY-1].v[D-1]; - pty[PTY-1] = rotate(par[0], -1); - } - pty[W*i+j] = par[1]; - for (int c = 0; c < cnt; ++c) - msg[lo[c].off] = rotate(mes[c], lo[c].shi); bl += deg; } } diff --git a/ldpc_decoder2.hh b/ldpc_decoder2.hh index c262b62..48e578f 100644 --- a/ldpc_decoder2.hh +++ b/ldpc_decoder2.hh @@ -142,46 +142,63 @@ class LDPCDecoder int cnt = cnc[i]; int deg = cnt + 2; for (int j = 0; j < W; ++j) { - TYPE par[2]; - if (i) { - par[0] = pty[W*(i-1)+j]; - } else if (j) { - par[0] = pty[W*(q-1)+j-1]; - } else { - par[0] = rotate(pty[PTY-1], 1); - par[0].v[0] = 127; + bool wd[deg]; + for (int d = 0; d < deg; ++d) + wd[d] = false; + for (int c = 1; c < cnt; ++c) + if (lo[c].off == lo[c-1].off) + wd[c] = true; + for (bool repeat = true; repeat;) { + TYPE par[2]; + if (i) { + par[0] = pty[W*(i-1)+j]; + } else if (j) { + par[0] = pty[W*(q-1)+j-1]; + } else { + par[0] = rotate(pty[PTY-1], 1); + par[0].v[0] = 127; + } + par[1] = pty[W*i+j]; + TYPE mes[cnt]; + for (int c = 0; c < cnt; ++c) + mes[c] = rotate(msg[lo[c].off], -lo[c].shi); + TYPE inp[deg], out[deg]; + for (int c = 0; c < cnt; ++c) + inp[c] = vqsub(mes[c], bl[c]); + inp[cnt] = vqsub(par[0], bl[cnt]); + inp[cnt+1] = vqsub(par[1], bl[cnt+1]); + cnp(out, inp, deg); + for (int d = 0; d < deg; ++d) + out[d] = vclamp(out[d], -32, 31); + for (int d = 0; d < deg; ++d) + out[d] = selfcorr(bl[d], out[d]); + for (int d = 0; d < deg; ++d) + if (!wd[d]) + bl[d] = out[d]; + for (int c = 0; c < cnt; ++c) + mes[c] = vqadd(inp[c], out[c]); + par[0] = vqadd(inp[cnt], out[cnt]); + par[1] = vqadd(inp[cnt+1], out[cnt+1]); + if (i) { + pty[W*(i-1)+j] = par[0]; + } else if (j) { + pty[W*(q-1)+j-1] = par[0]; + } else { + par[0].v[0] = pty[PTY-1].v[D-1]; + pty[PTY-1] = rotate(par[0], -1); + } + pty[W*i+j] = par[1]; + for (int c = 0; c < cnt; ++c) + if (!wd[c]) + msg[lo[c].off] = rotate(mes[c], lo[c].shi); + repeat = false; + for (int c = 1; c < cnt; ++c) + if (wd[c] && !wd[c-1]) { + wd[c] = false; + repeat = true; + ++c; + } } - par[1] = pty[W*i+j]; - TYPE mes[cnt]; - for (int c = 0; c < cnt; ++c) - mes[c] = rotate(msg[lo[c].off], -lo[c].shi); - TYPE inp[deg], out[deg]; - for (int c = 0; c < cnt; ++c) - inp[c] = vqsub(mes[c], bl[c]); - inp[cnt] = vqsub(par[0], bl[cnt]); - inp[cnt+1] = vqsub(par[1], bl[cnt+1]); - cnp(out, inp, deg); - for (int d = 0; d < deg; ++d) - out[d] = vclamp(out[d], -32, 31); - for (int d = 0; d < deg; ++d) - out[d] = selfcorr(bl[d], out[d]); - for (int d = 0; d < deg; ++d) - bl[d] = out[d]; - for (int c = 0; c < cnt; ++c) - mes[c] = vqadd(inp[c], out[c]); - par[0] = vqadd(inp[cnt], out[cnt]); - par[1] = vqadd(inp[cnt+1], out[cnt+1]); - if (i) { - pty[W*(i-1)+j] = par[0]; - } else if (j) { - pty[W*(q-1)+j-1] = par[0]; - } else { - par[0].v[0] = pty[PTY-1].v[D-1]; - pty[PTY-1] = rotate(par[0], -1); - } - pty[W*i+j] = par[1]; - for (int c = 0; c < cnt; ++c) - msg[lo[c].off] = rotate(mes[c], lo[c].shi); lo += cnt; bl += deg; }