1. 为什么5G控制信道最终选了Polar码信道极化不是玄学先聊个有意思的背景。3GPP在2016年确定5G eMBB场景编码方案时数据信道选了LDPC控制信道选了Polar码。当时不少人觉得Polar码是不是捡了控制信道的漏但真正做过仿真的人都知道控制信道码长短、时延要求高、误报率要求极其苛刻这个场景恰恰是Polar码的主场。Polar码的理论基础是Erdal Arikan在2008年提出的信道极化Channel Polarization现象它是目前唯一被严格证明可以达到二进制输入对称离散无记忆信道容量的构造性编码方案。这句话听起来很学术翻译成大白话就是在理论上Polar码有底气逼近香农极限而且复杂度可控。我在实际仿真里最大的感受是Polar码牛不牛一半靠编码构造另一半完全靠译码算法。SCSuccessive Cancellation连续消除译码在码长足够长时表现不错但中等码长下错误平层偏高而SCLSuccessive Cancellation List连续消除列表引入路径列表之后性能直接上一个台阶。这篇文章我把我自己搭的上行、下行链路仿真经验完整拆开讲包括为什么上下行分开建模、SCL的列表管理怎么做、BLER曲线怎么解读、参数怎么调以及最容易让新手翻车的几个细节。先说清楚读者范围。这篇文章适合三类人正在做通信物理层仿真课题的研究生、需要评估Polar码链路性能的工程师、以及对5G信道编码好奇想亲手跑通仿真的人。我会把原理部分压缩到够用的程度重点放在仿真链路搭建和结果分析的方法论上因为网上讲Polar码原理的文章很多但从零搭一条带SCL译码的完整链路并分析上下行性能差异的实操型内容其实很少。1.1 从Arikan的论文到3GPP标准落地Arikan最初的构造基于巴氏参数Bhattacharyya Parameter选择冻结比特位置后来的研究者陆续提出了密度进化Density Evolution, DE、高斯近似Gaussian Approximation, GA等更实用的可靠性度量方法。在5G标准落地时Polar码的构造方案是CRC循环冗余校验比特参与极化编码信息比特位置按可靠度从高到低选取冻结比特填充在不可靠位置。这里有一个关键认知Polar码的性能本质上是由比特信道的可靠性分化程度决定的。码长越长极化越彻底但控制信道不可能给你特别长的码所以短块下的Polar码要靠CRC辅助做路径选择这也就是CA-SCLCRC-Aided SCL成为5G控制信道主流方案的原因。1.2 信道极化是怎么发生的合并与分裂信道极化的过程可以用一个简单例子理解。假设你有两个独立的二进制对称信道W每个信道的错误概率都是p。把两个信道通过一个异或合并成一个等效的双比特信道其中第一个比特经过劣化变成错误概率更高的信道W⁻第二个比特经过强化变成错误概率更低的信道W⁺。递归做下去N个独立信道会变成N个可靠性极不相同的比特信道一部分信道容量趋近于1一部分趋近于0。仿真的第一步就是构造生成矩阵G_N它满足G_N B_N F^{⊗n}其中F是2×2的极化核矩阵[[1,0],[1,1]]B_N是比特反转排列矩阵⊗n表示n次Kronecker积。这个矩阵决定了编码时的线性变换关系。我刚开始写代码时直接用了循环嵌套生成Kronecker积码长到2048时速度还能接受但再往上就明显吃力了后来改成按递归结构生成速度和内存都有改善。1.3 可靠性排序高斯近似用的就是你熟悉的LLR均值仿真里最影响性能准确度的环节是信息位集合的选取。5G标准里不同码率有固定的可靠度序列Q序列但自己做仿真时未必能拿到标准序列的完整实现所以通常用GA近似自己算。GA近似的思路是对每个比特信道用高斯分布近似其对数似然比LLR的分布通过迭代更新每个信道的均值和方差。初始时全零码字在AWGN信道下的LLR均值为2/σ²σ²是噪声方差方差为4/σ²。迭代公式其实不复杂——对于长度N的极化码每个极化阶段的均值和方差按以下规则更新合并节点对应极化核的上支路μ⁻ φ⁻¹(1 - (1-φ(μ₁))(1-φ(μ₂)))这个计算较慢实际工程中通常查表。分裂节点对应极化核的下支路μ⁺ μ₁ μ₂。方差则按σ² 2μ的关系简化处理。这样算完之后把N个信道的μ值从大到小排序选前K个作为信息位。这一步看起来简单但实操时有个坑GA近似的精度依赖信噪比设定如果你在低信噪比环境下用高信噪比算出来的信息位集合性能会明显下降。所以我在仿真时一般会按工作点附近的目标Eb/N0比如2dB到3dB来生成信息位集合而不是随便取一个值算完就固定下来。2. SCL译码到底多复杂列表路径管理与度量排序的门道SCL译码是SC译码的自然扩展SC译码在每一层只保留一条幸存路径而SCL保留L条L是列表大小最后从L条候选路径中选出最可靠的一条。这个改动看起来只是多留了几条路但实际实现里涉及路径分裂、路径剪枝、度量计算、排序操作四个核心模块每一步都有优化空间。2.1 SC译码的局限连续消除的串行纠错压力SC译码的致命问题是决策的不可逆性。译码从第一个比特到第N个比特依次进行每遇到一个信息比特就做一次硬判决一旦决策错误错误会沿着后续的所有比特传播——这和Turbo码或LDPC码的迭代译码思路完全不同。SC译码的错误传播导致它在中等码长下的错误平层比较明显而控制信道恰恰是按错误平层必须极低来设计的所以直接上SC是不行的。从信息论角度看SC译码是逐个比特做最大后验概率MAP判决但没有利用未来比特的信息而最优的MAP译码需要遍历所有可能的码字。SCL就是在性能和复杂度之间找了个中间点保留L条最可能的路径等效于做了广度优先的树搜索L越大越接近最优MAP译码。2.2 路径分裂与剪枝列表是怎么维护的SCL译码的关键数据结构是一个大小为L的路径列表。每解码一个信息比特时每个路径都可能分裂成两条判决为0或1所以瞬时路径数可能达到2L此时需要按路径度量Path Metric, PM排序只保留最小的L条。冻结比特不分裂直接按已知值更新路径度量。这里要特别注意路径度量不是加法而是惩罚项累加。标准的对数域PM定义为当前比特LLR的符号方向与实际判决方向一致则PM不变不一致则PM加上该比特LLR的绝对值。直观理解就是你越背离信道给出的软信息路径的累积惩罚就越大PM越小表示路径越可靠。2.3 PM度量的计算与排序实现实现时最影响性能的是排序算法。朴素做法是每层对2L条路径做一次全排序复杂度O(L log L)列表大了之后非常拖速度。我实测N1024、L32时排序操作大概占整个译码时间的40%以上。工程上的优化思路利用上一轮列表已经是排序完成的特性新的2L条路径是由L条父路径各产生两条子路径可以采用局部插入排序或败者树结构。使用比特onic排序网络在GPU实现中特别有效。对PM值做定点量化降低比较开销。我的经验是如果只是做链路性能评估用MATLAB的sort函数完全够用重点在于把路径分裂和剪枝的逻辑写对而不是过度优化排序。等你要做实时性评估时再考虑C/C或GPU优化。此外CA-SCL引入CRC校验来选择最终路径。具体做法是译码结束后从L条候选路径中按PM从小到大依次检查CRC是否通过选第一个通过的路径输出。如果所有路径都失败就选PM最小的路径输出。这种CRC辅助选路机制对整个性能提升非常显著——表面上是多加了一组CRC比特实际上是利用CRC的检错能力把错误路径剔除掉了。我下面会专门用一节讲CRC长度对性能的影响。3. 上下行链路仿真的建模差异基站侧和终端侧谁更难很多第一次做Polar码链路仿真的人会把上下行混在一起直接用同一个模型改改信噪比。这种做法不是不行但会丢失现实中关键差异。上行链路的典型特征是发射端是手机功率受限接收端是基站有更好的接收处理能力和更大规模天线。下行链路则反过来基站发射功率大但终端的接收处理能力相对有限。这些物理差异在仿真里反映为SNR定义不同、功控模型不同、天线增益和接收噪声系数不同。3.1 信噪比的定义差异上行和下行仿真中我习惯于区分两种信噪比口径Eb/N0每比特能量与噪声功率谱密度之比用于纯编码性能比较传输速率不同的方案用它做对齐最公平。接收SNR或SINR信干噪比用于链路预算评估因为接收信号的实际强度取决于发射功率、路损、收发天线增益和噪声带宽。编解码性能分析用Eb/N0系统级评估用SNR。两者换算关系是SNR Eb/N0 × (编码前比特数/符号数)。也就是说调制阶数和编码码率直接影响SNR和Eb/N0之间的换算关系。我做链路仿真时一般给两套结果Eb/N0下的BLER曲线用于和文献对比SNR下的吞吐量曲线用于直观评估实际覆盖。3.2 发射功率与天线配置下行仿真中基站发射功率通常是43dBm20W左右终端接收噪声系数7~9dB基站天线增益可以有几十dBi的波束赋形增益。上行仿真中手机最大发射功率一般是23dBm约0.2W基站接收机噪声系数2~3dB终端天线增益通常只有0dBi。这个不对称意味着同样是1dB的链路损耗变化上行覆盖范围的变化更敏感。我的做法是上下行链路用相同的信道编码器和译码器但信道模型和信噪比映射关系分开配置。具体参数可以按需求灵活设置下行用基站侧发射功率43dBm、接收端终端噪声系数7dB、天线增益0dBi上行用终端发射功率23dBm、接收端基站噪声系数3dB、天线增益25dBi。这样跑出来的BLER曲线虽然形状类似但落到实际覆盖距离时上下行的性能差异会非常直观。3.3 信道模型的选择AWGN、Rayleigh和TDL模型纯AWGN信道只适合验证译码算法的理论性能不适合评估真实链路。工程上常用两种平衰落Rayleigh信道每条路径经历独立的复高斯衰落反映无频率选择性衰落场景适合CDL/TDL模型之前的快速验证。5G标准TDL模型如TDL-A、TDL-C带时延扩展和功率分布需要配合OFDM做频域均衡仿真复杂度高一个量级。我第一版仿真只在AWGN下验证了SCL和CA-SCL性能曲线非常漂亮。但后来加上Rayleigh衰落信道后问题立刻暴露信息位集合在衰落信道下是否还可靠答案是需要重新计算。GA近似中LLR均值依赖信道状态衰落信道下信道状态随时间变化最简单的处理是用信道状态信息的统计平均来重新生成信息位集合或者直接采用5G标准中基于可靠度序列的固定方案。这一节后面我会再细说。4. 从BLER曲线看性能蒙特卡洛仿真的参数配比与结果解读仿真链路的关键模块包括Polar编码、调制映射、信道加噪、解调软信息计算、SCL/CA-SCL译码、BER/BLER统计。我用的工具链是MATLAB为主部分耗时模块用C MEX加速。下面按模块拆解并把关键参数配比讲清楚。4.1 仿真代码架构从编码到译码的主循环设计主循环的伪代码逻辑如下for each EbN0_dB in EbN0_set: for each block in num_blocks: u_info randi([0 1], K, 1) u polar_encode(u_info, info_pos, frozen_pos) % 信息位冻结位 x_mod modulate(u, mod_order) % BPSK/QPSK/16QAM... y awgn_channel(x_mod, snr_lin) llr demodulate(y, snr_lin, mod_order, noise_var) est_u scl_decode(llr, N, K, L, crc_poly, info_pos, frozen_pos) count_block_errors ~isequal(u_info(1:K), est_u(1:K)) count_bit_errors sum(xor(u_info(1:K), est_u(1:K))) BLER count_block_errors / num_blocks BER count_bit_errors / (num_blocks * K)有几个细节要提醒每次仿真各个信噪比点独立统计块数。BLER目标越低需要的块数越多否则置信区间太宽曲线抖动严重。我的经验是目标BLER1e-2时至少统计200个错误块目标1e-3时至少统计100个错误块这样才能让曲线末端稳定。调制阶数不同LLR计算方式不同。BPSK/QPSK的LLR可以直接写解析式16QAM/64QAM用Max-Log MAP近似计算核心是计算每个符号到星座点的最小欧氏距离。随机数种子要固定否则每次跑的结果都略有差异不利于对比调参。我通常按信噪比点列表大小CRC长度组合设置种子。4.2 参数配置表N、K、L、CRC怎么选我常用的几组参数如下参数典型值说明码长N512 / 1024 / 2048控制信道一般256~1024数据信道仿真可加大信息位KN × 码率码率常取1/3、1/2、3/4列表大小L8 / 16 / 32L8是基础L32性能饱和再大收益递减CRC长度8 / 16 / 245G控制信道一般8或16数据信道可更大调制方式BPSK / QPSK / 16QAM控制信道QPSK为主数据信道可上16QAM/64QAM信道类型AWGN / Rayleigh / TDL-C验证算法用AWGN系统评估用TDL举例来说N1024、R1/2K512、L8时BPSK调制AWGN信道下CA-SCL译码CRC-8的BLER1e-2对应Eb/N0大约在1.6dB到1.9dB区间换成L32大约能再省0.3dB左右。具体数值需要以你的实现为准但趋势是稳定的L增大、CRC变长都带来增益只是增益在递减。4.3 BLER曲线的解读增益到底花在了哪有一个常见误区是把SCL的增益简单归结为译码算法更强。从仿真结果看L从1即SC增加到8时BLER曲线在1e-2附近大约能带来0.5~0.8dB增益L从8增加到32增益不到0.3dBL超过32之后基本进入平台期。这说明SCL的增益主要来自路径分集和选择——SC一条路走到底一旦方向错就回不来SCL保留8条路径时大部分错误决策已经能被纠正再增加路径的边际收益就不明显了。还有CA-SCL带来的深邃曲线下滑——CRC强制校验路径合法性的能力是关键。具体看同样L16带CRC-8的CA-SCL比纯SCL在BLER1e-3处的增益可以多0.3~0.5dB而且有效消灭了错误平层。原因在于SCL选出的是PM最小的路径PM最小并不代表译码正确CRC把码字合法性作为硬约束后错判概率大幅下降。5. 仿真调优经验列表长度、CRC长度和信道模型的选择这一节是我个人踩坑最多的地方。很多问题不是原理不懂而是参数组合选得不对导致仿真结果要么不收敛要么和理论对不上。5.1 列表长度L的取舍与排序瓶颈L的选取原则是在目标BLER达到之前尽量增大L在目标BLER满足之后再考虑减L降复杂度。如果只是对比算法性能L32完全够用如果要模拟实际控制信道L8或16更接近工程可实现的范围。L变大之后最直接的问题是译码时间线性增长排序开销甚至超线性增长。我在N2048、L32、跑10万块时纯MATLAB实现要跑两个多小时换用C MEX加速译码核心后压缩到二十分钟以内。如果你的目标是批量扫参数建议把译码函数做成C MEX或Python/Cython混合实现纯脚本语言做大规模蒙特卡洛仿真会很痛苦。5.2 CRC长度和分段CRC的微妙影响CRC长度不是越长越好。CRC越长信息位中被CRC占用的比特越多等效码率下降但CRC的检错能力更强路径筛选更可靠。折中下来N512时CRC-8比较合适N1024时CRC-16更好。我做了一组对比仿真结果很有意思CRC配置BLER Eb/N02.0dBL16无CRC纯SCL约4.8e-3CRC-8约1.5e-3CRC-16约9e-4可以看到CRC-16确实更好但代价是K少了8比特的有效载荷。实际系统设计时要考虑有效吞吐率不是无脑上长CRC。另外5G标准里有一种分段CRC的思路——把信息比特分段每段各加CRC逐段做校验这样不但能加速路径剪枝还能降低错误传播。我在仿真中试过将总长度16的CRC拆成两段各8放在前后两段信息上发现BLER无明显恶化但早期剪枝效果提升了约15%的译码速度。5.3 信道模型扩展从AWGN到TDL-C的演进如果你只是做Polar码性能和SCL算法对比AWGN信道足够。但如果你需要评估真实链路的上下行性能TDL-C这类多径信道是少不了的。TDL-C有典型的时延扩展频率选择性衰落明显要配合OFDM做子载波级处理才能正确解调。我发现一个意外的情况基于GA近似在AWGN下最优选出的信息位集合在TDL-C信道下并不是最优的。TDL-C下信道的瞬时SNR波动大固定信息位集合有时会把信息放在深度衰落的子载波对应的比特信道上导致错误平层。传统做法有两种对每帧做动态资源分配要求信道估计可靠实际下行可以靠导频实现。使用更保守的信息位集合——把可靠度排名略低但更稳的位子也纳入信息位选择。不过如果只是评估SCL算法的上下行性能对比我建议第一版仿真还是用AWGN加平衰落Rayleigh先把算法行为摸清楚再上TDL-C。否则你很难分清性能损失到底是编码/译码带来的还是信道均衡和OFDM同步带来的。5.4 浮点转定点一个容易被忽视的性能陷阱Polar码译码的LLR在硬件实现里一般用定点数表示位数不够会直接影响性能。仿真时如果全用浮点没问题但想做工程可行性评估时建议加一步定点仿真。我试过把LLR量化成6比特和8比特发现8比特和浮点几乎无差异6比特在低信噪比下会有约0.1dB的损失。这个数据可以给做硬件实现的同学一个初始参考。另外PM值的更新公式在定点实现时要注意溢出。路径度量累加的是LLR绝对值的和N1024时动态范围可能到上百用Q8格式要小心。建议所有定点仿真在浮点基线稳定后再做不要一开始就混着搞否则出了问题很难定位是算法问题还是量化问题。最后说一个我实际工作中经常用来快速验证SCL实现正确性的方法把L设为1此时SCL退化为SC译码把译码结果和标准的SC译码实现做逐比特对比。如果两者完全一致说明你的列表管理框架没写错如果出现不一致大概率是路径分裂时冻结比特处理或者PM更新逻辑有bug。这个小技巧帮我省了非常多调试时间建议你上手时先做这一步验证。
