十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Polar码译码选型:SCL与BP的对比与工程实现指南

Polar码译码选型:SCL与BP的对比与工程实现指南 简介本资源是一套面向通信工程专业高年级本科生及研究生的Polar码译码算法MATLAB实现代码包聚焦5G信道编码核心问题系统覆盖SC、BP与SCL三类主流译码策略及其CRC辅助校验机制。包内共31个.m文件涵盖polar_SCL_decode、polar_BP_decode、polar_SC_decode等主译码函数以及LLR更新updateL、updateLLRMap、路径管理clonePath、killPath、findMostProbablePath、CRC校验crc_check和极化矩阵初始化intial_tree_G等关键模块全部为可直接运行的函数级脚本总大小仅16KB轻量高效。已有765人学习下载适合用于课程设计、毕设仿真或算法原理验证。读者可完整复现三种译码器在BPSK调制下的误码率性能对比深入理解消息传递机制、列表剪枝策略与循环冗余校验协同增益掌握从理论推导到工程实现的关键技术链路。 做通信物理层的人应该都有这种体验Polar码的理论增益在仿真里非常亮眼但一到实现阶段SCL译码和BP译码的差距立马见真章。SCL靠路径搜索逼近最大似然BP靠并行迭代换取吞吐两者代表了译码器设计的两条完全不同的技术路线。这篇文章会结合我在Polar码译码器实现上的经验把这两种算法从原理到工程选型一次讲清楚顺便把调试时容易踩的坑也列出来给正在做Polar码仿真或者硬件实现的朋友一个参考。1. Polar码译码问题的起点为什么SC不够用1.1 先回顾一下Polar码的结构Polar码是Arikan在2009年提出的信道编码方案核心思想是利用信道极化现象把多个独立信道组合、拆分最后在等效信道上形成容量接近香农极限的“好信道”和容量接近0的“坏信道”。编码时我们在好信道上放信息比特在坏信道上放冻结比特这样信息就可以通过好信道可靠传输。Polar码的编码结构是递归的常见的是Kronecker矩阵变换。码长N一般取2的幂次比如N256、512、1024。实际系统里还需要做速率匹配来适配不同的传输块大小。所以实现Polar码第一步就是确定码长N、信息比特数K、冻结比特的位置以及对应的极化权重。这些参数决定了后续译码器看到的码字结构。1.2 SC译码是怎么一步步做判决的串行消除Successive Cancellation, SC译码是Polar码最基础的译码算法。它的思路很直观按照比特索引的顺序一个一个地估计信息比特。每估计一个比特时计算这个比特在已知前面所有比特估计值条件下的对数似然比LLR然后根据LLR符号做硬判决。如果是冻结比特直接置为预设值不参与判决。SC译码的好处是复杂度低只有O(N log N)量级逻辑简单适合硬件实现。但它的缺点也明显一旦某个比特判决错了后续所有比特的对数似然比都基于这个错误值错误就会像滚雪球一样传播。而且SC译码没有全局视角它本质上是逐比特的贪心算法并不是最优译码。1.3 SC译码的瓶颈在哪里我在做仿真时发现一个典型的场景在中等码长N1024、码率R0.5的情况下SC译码的性能比最大似然译码差不少。原因就是硬判决带来的信息损失。SC译码在每一个比特位置只保留一个候选结果相当于把概率信息“拍扁”成了0/1。这个信息一旦丢失后面再多的计算也补不回来。所以工程上很少直接用SC译码。它更像一个理论基线SC等价于列表大小L1的SCL译码也是BP译码的一种极端收敛情况。理解了SC的局限你就知道SCL和BP分别是在“补什么课”了。2. SCL译码用“候选路径”换取纠错余量2.1 SCL的核心思想一次保留L条路径SCLSuccessive Cancellation List译码名字里多了个List列表本质就是把SC的单路径搜索改成了多路径搜索。在每一个信息比特位置SCL不像SC那样只做一次硬判决而是同时保留L条当前概率最高的部分估计序列称为候选路径。到了下一步每条路径再分裂成“估计为0”和“估计为1”两个分支然后从2L条路径里选出L条保留。这里有个关键点路径分裂和剪枝是一个动态规划过程。路径的优劣通过路径度量Path Metric, PM来评价PM越小代表这条路径越可靠。SCL的最终输出就是最后一步PM最小的那条路径。2.2 路径度量PM的计算与剪枝逻辑路径度量的计算和LLR符号是绑定在一起的。假设当前比特位置的LLR值为λ它的符号表示硬判决倾向。如果硬判决结果和LLR符号一致PM保持不变如果不一致PM会加上一个惩罚项|λ|。这个惩罚项的本质是这条路径违背了当前观测给出的置信度所以它的可靠性要打折扣。实际计算时为了让PM始终是非负数通常用累加的方式。每出现一次不一致的判决就把|λ|累加到PM上。这样PM最小路径就是全局最可靠路径。这个计算在硬件上就是几个加法器和比较器并不复杂。真正复杂的是路径排序在每一级比特判决后要保留PM最小的L条路径。如果直接用全排序复杂度是O(L log L)甚至更高硬件上一般会做成比较器网络或者局部排序结构这里容易成为吞吐率瓶颈。2.3 CRC辅助的SCLCA-SCL为什么性能提升明显纯SCL译码到L32时性能已经比SC好很多但还有一个痛点是列表末尾选择的PM最小路径不一定就是正确的码字因为有些错误码字也能恰好获得较小PM。为了进一步降低误码率在实际系统中会把CRC比特也编码进信息位译码时先对每条候选路径做CRC校验只有通过校验的路径才被认为是合法候选。这就是CRC辅助的SCL译码也叫CA-SCL。它在每步保留路径的基础上最后不再单纯选PM最小而是优先选“能通过CRC校验”的路径中PM最小的。这个改动带来的增益相当可观尤其在码率较高时。5G NR的Polar码方案就是用CA-SCL作为译码基线这也是它能在短码和中长码场景下逼近香农限的重要原因。2.4 实现要点排序、存储和时延SCL实现时最容易忽略的是存储问题。每条路径都要保存对应的部分估计序列也就是L条路径都要维护一个长度N的比特序列遇到回溯时需要完整路径。这个存储量是L×N比特。如果N1024、L16就需要16Kbit的路径存储这还不包含LLR中间变量。所以在硬件设计里列表大小L不是越大越好而是要在性能和面积之间找平衡。另外SCL是串行结构的天然导致译码时延较大。虽然每步内部有一些并行度但整体上它是逐比特推进。为了缩短时延业界有“分裂SCL”或“多比特SCL”的优化方案一次处理多个比特可以降低迭代次数但实现复杂度也跟着上去。如果你只是在做软件仿真那直接用标准SCL就行如果要做硬件我建议先跑通L4或L8的版本再逐步加大。3. BP译码把译码变成并行置信传播3.1 BP译码的因子图模型与SCL完全不同BPBelief Propagation译码把人看成一个迭代译码问题。Polar码的编码结构可以展开成一张因子图图中每个节点对应一个编码关系节点或变量节点节点之间有边相连。译码过程就是在这张因子图上反复传递“左右消息”让信息在整个图中扩散。具体来说Polar码的因子图是一个nlog2(N)级的蝶形结构。每一级有N/2个处理单元每个处理单元执行一次“f函数”和“g函数”的更新。左边传进来的消息称为右消息右边传进来的称为左消息。每轮迭代中消息从右往左传再从左往右传算是一轮完整更新。迭代若干轮后利用最左边的LLR做硬判决。3.2 左消息右消息的迭代更新公式用稍微简单的方式来表达。假设有两个输入消息L1和L2f函数是L_out sign(L1) * sign(L2) * min(|L1|, |L2|)这其实就是最小和近似的置信传播更新硬件实现最常用。g函数则是L_out L1 (-1)^u * L2其中u是对应比特的已知值或者硬判决值。这两组公式基本就是BP译码的全部核心计算了。f函数处理“异或”结构节点g函数处理“复制”结构节点。整个BP译码就是把这些基本运算在因子图上铺开反复执行。实现时要注意数值范围。LLR初始值来自信道观测可能在几十到几百之间经过多轮迭代后如果数据位宽不够很容易饱和。所以量化方案很关键硬件里常见的是8比特或12比特定点表示需要根据仿真结果调整。3.3 提前终止与调度策略BP译码的迭代次数直接影响吞吐量。如果固定迭代50轮有些帧可能在20轮就已经收敛了继续迭代就是浪费。因此工程上一般会加入提前终止机制每轮迭代后对硬判决结果做一次CRC校验如果校验通过就提前停止迭代。这个策略在低信噪比区间能省下不少平均迭代次数。调度策略也很重要。最基本的BP是“全并行”更新所有节点每一轮迭代中所有处理单元同时计算。这个方案吞吐高但资源开销大。还有一种“渐进式”调度按照蝶形结构的层级顺序依次更新收敛速度会更快但并行度下降。具体选哪种取决于你的FPGA或ASIC目标时钟频率和面积预算。3.4 硬件实现中的并行化和量化BP译码最大的优势是并行化。因为因子图中的更新规则在每一级内部是完全独立的理论上在一个周期内可以同时更新N/2个处理单元。这让BP译码的吞吐潜力远超SCL。代价是连线复杂度和存储量。N1024时全并行处理需要上千个运算单元这种设计通常只适合低时延、高吞吐的场景。量化深度是我在调试BP译码时最头疼的部分。定点位宽太小误差会累积导致错误平层位宽太大逻辑资源翻倍。比较好的做法是先做浮点仿真得到LLR动态范围然后用8比特有符号数做定点仿真对比误块率BLER曲线找到性能损失小于0.05dB的最低位宽。这个步骤不能偷懒否则直接上板后你会被各种“有规律的翻转错误”折磨到崩溃。4. SCL与BP的对比和选型建议4.1 性能、复杂度和时延的横向对比维度SCL/CA-SCLBP译码性能高L增大逼近ML中高迭代充分时接近SCL但有限迭代有损计算复杂度O(L·N·logN)O(I·N·logN)I为迭代次数并行度低串行判决为主高可全并行译码时延较高和N线性相关可低取决于迭代次数和并行度硬件资源路径存储和排序网络大量处理单元和连线适应性适合中短码长、控制信道适合长码块、高吞吐场景从我的仿测结果看在N1024、R0.5条件下L32的CA-SCL性能大约比BP迭代50轮好0.2-0.3dB。但如果把BP迭代次数提高到100以上差距会缩小。问题在于迭代次数越大时延和功耗越高。所以BP并不是“性能更高”只是“换性能的方式不同”。4.2 场景决定选型控制信道和高速数据信道5G NR的标准里Polar码用于控制信道通常码长在512到1024之间对误码率要求极其苛刻所以选择CA-SCL译码是合理的。SCL虽然慢但控制信道传输的信息量小对吞吐要求不像数据信道那么极端。在这个场景下SCL的“慢”可以被接受性能优势却不可替代。反过来如果Polar码被用在高速数据信道上比如卫星通信或者未来的6G数据平面那SCL的串行时延可能就不是最优解。这时候BP译码的并行特性更有吸引力。还有一些场景会做混合设计第一轮用BP粗译如果CRC不过再调用SCL做终极纠错。这种“BPSCL”方案在实测定点仿真中确实能兼顾平均时延和极限性能。4.3 除了SCL和BP还有什么值得注意除了SCL和BP现在还有很多改进算法。比如用神经网络辅助路径度量或者用深度学习预测BP迭代后的错误位。但这些方案更多是学术前沿工程落地还比较远。我更关注的是SCL的“自适应列表”和BP的“动态调度”它们不需要增加太多硬件资源却能实打实地降低平均复杂度。如果你在做算法预研可以从这两个方向切入。5. 实际调试中的常见问题与排错经验5.1 SCL路径度量溢出怎么办我在仿真早期遇到过一个非常典型的bug路径度量计算用int16存储当LLR绝对值很大时PM累加会溢出导致原本可靠的路径PM变成负数排序结果彻底乱掉。这个问题在高信噪比时特别容易出现因为LLR的值很大。解决方法是先统计不同信噪比下PM的动态范围然后给PM有符号整数位宽留出余量。更稳妥的做法是在计算PM时做饱和处理不让它溢出成错误符号。另外要特别注意不要把路径存储和PM存储混在一起否则路径回溯时会出现莫名其妙的跳变。5.2 BP译码迭代不收敛或振荡BP译码不收敛的常见原因是因子图里有环。Polar码的因子图是有环的消息在循环中反复更新有时会在两个状态之间震荡。处理办法之一是使用衰减因子在每次消息更新后乘一个小于1的系数强制系统趋于稳定。另一个办法是加入乱序调度打破震荡模式。我在一个N2048的测试用例中遇到过固定迭代50轮误码率曲线在中信噪比区域不降反升。排查后发现是量化导致的消息过大饱和在迭代过程中数值溢出到负数进而把后续更新全部污染。后来把LLR的限幅范围从±64改成±32曲线立刻正常了。所以BP调试遇到性能拐点时先查数值范围不要急着改算法。5.3 如何验证译码器实现是否正确这是所有译码器调试中最重要的一步。我的习惯是先用浮点算法在Python或MATLAB里建立参考译码器输出每个比特的LLR或判决结果。然后在硬件或定点模型里实现同样的算法用同一组输入数据比对逐步定位不一致的位置。具体做法是先做零噪声下的编码译码比对确认链路无误再加入小噪声比对整数位置最后再做整帧的BLER蒙特卡洛仿真。如果你发现某个比特位置总是错误很可能是冻结比特位置表没对齐或者是编码矩阵的索引方向反了。这类问题在Polar码里非常常见因为不同论文的比特索引有0基和1基之分跨代码库移植时一定要统一。5.4 小技巧测试序列生成与回归管理译码器调试时我建议保存一批固定的信道输入样本作为回归向量每次改动算法后都跑一遍确认误码率和LLR分布没有退化。这样做的好处是当你优化排序网络或量化位宽后可以快速发现“改进”是否真的改进了而不是被随机噪声干扰。另外我会把每种配置的仿真参数、随机种子、信噪比、误帧数等都记录到一个表格里方便对比。别小看这个习惯调参的时候你会发现“上次那个0.3dB的增益到底是怎么跑出来的”这种问题没有记录基本只能靠猜。我个人在实现Polar码译码器的过程中最大的体会是SCL和BP没有绝对的优劣只有适不适合当前场景。如果你追求极限性能且不介意串行时延CA-SCL是首选如果你需要高吞吐且愿意接受迭代开销BP更合适。最后再分享一个小技巧在硬件实现之前先把定点仿真的LLR分布打出来看一遍这一步能帮你省下至少一半的调试时间。本文还有配套的精品资源点击获取
返回列表