ARTICLE DETAIL

资讯详情

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

LDPC与64QAM联合仿真:从编码交织到软解调误码率验证

LDPC与64QAM联合仿真:从编码交织到软解调误码率验证 简介一份面向无线通信与卫星通信研究者的LDPC编码与64-QAM调制联合仿真项目完整覆盖了从稀疏校验矩阵构造、LDPC编码、64阶正交幅度调制、QAM符号映射到软判决译码的闭环流程适合通信专业学生与工程师借助MATLAB快速掌握接近香农极限的纠错编码与高阶调制结合原理。压缩包共8个文件以5个m脚本为主包含LDPC仿真主程序、QAM64d/QAM64m调制解调函数、log_ldpc_decode日志域译码函数等辅以2个mat数据文件存放1152H/G校验矩阵另有1个txt说明文件整体仅13KB代码结构紧凑便于逐行调试与二次开发。目前已有304人学习下载。通过它读者可实际运行完整仿真观察LDPC码在不同信噪比下的纠错性能理解64-QAM符号映射与解映射细节还可参考消息传递算法的实现思路为教学演示或课题验证提供可直接复用的基础代码。1. LDPC 64QAM把纠错编码和高阶调制放在一条链路里验证什么做物理层算法验证的朋友迟早会撞上 LDPC 和 64QAM 这对组合。5G NR 的下行共享信道、Wi-Fi 6/7 的高速率档用的都是 LDPC 外码配 64QAM 调制。这个标题里的 LDPC_64QAM 是一套把编码和调制放在一条链路里验证的仿真工程从比特流进编码器开始经历 QAM 映射、AWGN 信道、软解调出 LLR再交给 LDPC 迭代译码器最后统计误码率。它能回答的问题只有一个在某个信噪比下LDPC 能把 64QAM 的误码率压到多低。这个答案直接决定链路预算里的编码余量。适合正在评估编码调制方案的系统工程师、复现论文算法的研究生以及想在手边留一套可改可跑的参考链路的物理层开发者。2. 从编码到星座映射LDPC64QAM 链路每一级到底在干什么2.1 LDPC 为什么适合配 64QAM稀疏校验矩阵与软信息迭代LDPC 的核心是稀疏校验矩阵 H每一行是一个校验约束每一列对应一个编码比特。译码时变量节点和校验节点之间来回传递置信度也就是 BP 算法每迭代一轮每个比特就被相邻的校验约束拉一次。64QAM 的问题是星座点间距小同一个符号里 6 个比特的可靠性还不一样——靠近原点的内圈比特容易被噪声翻掉外圈比特相对稳定。LDPC 恰好不挑比特它只看校验关系能把那些软信息弱的比特用强比特的约束拉回来。这就是 LDPC 和 64QAM 配在一起时最核心的互补性。如果换成 BCH 或 RS 这类硬判决码效果会差不少。它们在高码率下的编码增益有限而且译码输入只需要 0/1 判决64QAM 软解调出来的那个“这个比特像 1 的可信度有多大”的信息就全浪费了。LDPC 的 BP 译码天然吃软信息你喂给它的 LLR 越准迭代收敛越快。这也是为什么 5G LDPC 最终被选为 NR 数据信道的编码方案它在高码率下没有 Turbo 码那种错误平台配合高阶调制时曲线能一路压到 1e-6 以下。实际仿真时你可以直接用 dvbs2ldpc 生成 DVB-S2 标准里的校验矩阵码长 64800、码率 2/3 是常见配置。换到 5G 场景则是另一套基矩阵 BG1/BG2这个我们后面在参数章节细说。现在只需要记住一个判断LDPC 的列重分布决定了它对软信息质量的敏感度列重大的比特给了校验节点更多信息但列重太大会在迭代时形成环降低收敛速度。所以 64QAM 链路里那个交织器就是为了把 LDPC 码字里不同可靠度的比特重新排列让每个 64QAM 符号承载的 6 个比特尽量来自不同的校验约束。2.2 BICM 结构交织器为什么是 64QAM 链路里的一等公民这套链路的完整结构是LDPC 编码 → 比特交织 → 64QAM 符号映射 → AWGN 信道 → 软解调出每比特 LLR → 解交织 → LDPC 迭代译码 → 统计误码。这种编码和调制之间隔一个比特交织器的结构就是比特交织编码调制简称 BICM。BICM 的好处是把调制和编码彻底解耦你可以随便换码率、换调制阶数交织器只需要按新参数的比特数重新生成一张置换表。交织器的作用是打散 64QAM 符号内 6 个比特的可靠度差异。以 Gray 映射为例符号内高位比特抗噪声能力天然比低位比特强如果不打散LDPC 某个校验节点恰好连着好几个低位比特这个节点拿到的一堆软信息都是弱信号迭代收敛就慢。交织器把相邻编码比特映射到不同符号的不同比特位让译码器每次迭代看到的信息在统计上均匀。这也是为什么有人直接把编码比特送进 qammod、不收交织器时瀑布区会明显右移——这不是编码的锅是信息分布不均匀的锅。交织深度建议按 LDPC 提升因子的整数倍来取。5G NR 的准循环 LDPC 基矩阵扩展后一个码块的行重和列重都按提升因子 Z 的倍数排列交织表如果也按 Z 对齐硬件上就是简单的循环移位软件仿真也能减少随机交织带来的性能方差。DVB-S2 的 64800 码长没有严格意义的 Z 因子但你可以按 360 的整数倍取交织深度这是 DVB 标准的子块大小效果最好。2.3 软解调 LLR 的计算64QAM 仿真的第一道门槛64QAM 每个符号 6 个比特接收端要算的是每个比特的对数似然比 LLR。精确 MAP 计算要遍历 64 个星座点对每个比特把所有为 0 和为 1 的星座点做指数和对数运算速度慢且数值容易溢出。工程上几乎都用 max-log 近似对某个比特分别找接收点到“该比特为 0 的星座点子集”和“该比特为 1 的星座点子集”的最小欧氏距离两个最小距离的差再除以噪声方差就是这个比特的 LLR。公式写出来就是 LLR(k) ≈ (min_d1 - min_d0) / σ²其中 σ² 是噪声方差。这里有一个新手最爱踩的坑直接用 MATLAB 的 qamdemod 软输出。qamdemod 确实能输出 LLR但它内部做的是精确 MAP 计算速度比 max-log 慢一个数量级而且不同版本对输出符号的约定不完全一致正数到底代表比特 0 还是比特 1 容易搞反。后面接 LDPC 译码器时LLR 符号反了整条曲线直接翻车。我自己写链路时一般手写简化 LLR理由就是符号和缩放因子都要握在自己手里。这个习惯在后面换码率、换调制阶数、换译码器时都能省事。噪声方差 σ² 的口径也要统一。如果做星座功率归一化让 64QAM 平均符号能量 Es 1那么 AWGN 信道的噪声方差就等于 1 / (Es/N0)也就是 10^(-EsN0_dB/10)。只要你把星座功率归一化了这条换算就永远成立。忘记除噪声方差等于告诉译码器信道完全可靠BP 迭代会被虚假信息锁死这是后面避坑章节第一个要讲的问题。3. 从零复现一条能跑的 LDPC 64QAM 链路MATLAB 逐步实现3.1 编码与 QAM 映射先让发送端把比特变成符号常见做法是选 DVB-S2 的 LDPC 标准矩阵因为 MATLAB 自带的 dvbs2ldpc 函数可以直接生成校验矩阵不用自己构造稀疏 H 矩阵。下面的代码把编码、交织、映射三步拼起来% 参数码长 64800码率 2/3调制阶数 64 N 64800; R 2/3; M 64; k N * R; % 生成随机信息比特 infoBits randi([0 1], k, 1); % LDPC 编码dvbs2ldpc 生成 DVB-S2 标准稀疏校验矩阵 pcMatrix dvbs2ldpc(R); hEnc comm.LDPCEncoder(ParityCheckMatrix, pcMatrix); codeword hEnc(infoBits); % 比特交织随机置换表长度取 6 的整数倍 interleaver randperm(N); interleaver interleaver(1:floor(N/6)*6); txBits codeword(interleaver); % 64QAM 映射输入比特输出归一化星座符号 symbols qammod(txBits, M, InputType, bit, UnitAveragePower, true);dvbs2ldpc(2/3) 返回的是 21600 行 64800 列的稀疏校验矩阵comm.LDPCEncoder 内部用背代换做编码复杂度是线性阶比直接拿 H 矩阵做高斯消元快得多。交织器用 randperm 生成随机置换表截断到 6 的整数倍是为了让比特能完整填满整数个 64QAM 符号不会出现尾部比特凑不满一个符号的情况。qammod 这里的两个参数是关键。InputType 设为 bit告诉函数输入是比特向量函数会把每 6 个 bit 映射成一个符号UnitAveragePower 设为 true星座平均功率归一化为 1这对后面 awgn 叠加噪声非常省事因为 SNR 的参考功率就是 1。如果漏了这个参数64QAM 星座平均功率是 42算 EsN0 的时候少除一个功率因子信噪比会整体飘移 1.6 dB 左右。这个坑很隐蔽因为曲线形状一样只是整体平移。3.2 AWGN 信道与软解调写出可控的 LLR信道部分要按符号信噪比叠加高斯白噪声。这里注意区分 Es/N0 和 Eb/N064QAM 的换算关系是 EsN0_dB EbN0_dB 10log10(6) 10log10(R)其中 6 是每符号比特数R 是码率。这一步错了后面的横轴标注和理论间隙全部对不上。% 工作信噪比点信息比特 Eb/N0 12 dB EbN0_dB 12; EsN0_dB EbN0_dB 10*log10(log2(M)) 10*log10(R); % 过 AWGN 信道awgn 的输入是符号输出是带噪符号 rxSignal awgn(symbols, EsN0_dB, measured); % 软解调max-log LLR正数代表比特 1负数代表比特 0 noiseVar 10^(-EsN0_dB/10); constellation qammod(0:M-1, M, UnitAveragePower, true); bitMap de2bi(0:M-1, log2(M), left-msb); LLR zeros(N, 1); for idx 1:length(rxSignal) r rxSignal(idx); for b 1:log2(M) d0 min(abs(r - constellation(bitMap(:,b)0)).^2); d1 min(abs(r - constellation(bitMap(:,b)1)).^2); LLR((idx-1)*log2(M)b) (d1 - d0) / noiseVar; end end % 解交织把 LLR 按交织表还原回编码比特顺序 rxLLR zeros(N, 1); rxLLR(interleaver) LLR;awgn 函数里的 measured 选项会先测一次信号功率再叠加噪声配合星座功率归一化时EsN0 直接等于信噪比 SNR 的 dB 值不需要额外换算。噪声方差 noiseVar 10^(-EsN0_dB/10)因为 Es1所以噪声功率就是 1/SNR。这个口径要和 awgn 严格一致软解调算出来的 LLR 才可信。LLR 计算里constellation 和 bitMap 必须来自同一个映射规则。qammod(0:63, 64) 返回的是按 Gray 序排列的星座点de2bi(0:63, 6, left-msb) 生成的是自然二进制序这两者对应关系正好是 MATLAB 定义的星座映射表。千万不要自己在循环里按手写的二进制表去猜映射一旦星座点序号对不上LLR 绝对值会被严重低估误码率曲线右移 1 dB 以上。解交织这里用的是索引数组赋值rxLLR(interleaver) LLR意思是把解调输出的 LLR 按交织表放回原位置。这是 MATLAB 里最干净的写法比 for 循环快一个量级。译码器输入 rxLLR 就恢复了编码比特的原始顺序。3.3 LDPC 译码与误码率统计闭环算瀑布区译码这一级要指定迭代终止条件。comm.LDPCDecoder 可以固定迭代次数也可以在校验和满足时提前停。调试阶段固定 30 次对比曲线时不要中途改迭代次数否则不同信噪比点的收敛快慢不一样曲线会出现假抖动。% 译码BP 迭代最多 30 次 hDec comm.LDPCDecoder(ParityCheckMatrix, pcMatrix, ... IterationTerminationCondition, MAX, ... MaximumIterationCount, 30); decBits hDec(rxLLR); % 误码统计译码输出是完整码字取前 k 个信息比特对比 decInfo decBits(1:k); ber sum(decInfo ~ infoBits) / k;comm.LDPCDecoder 的输入是软 LLR 值输出是硬判决比特。注意它的输出长度是 64800对应完整码字和编码器输出对齐。因为交织和解交织只在 LLR 域做了一次重排译码后直接取前 k 位就是信息比特不需要再做一次解交织。单个信噪比点的 BER 没有意义要扫一段 Eb/N0。实操时我会写一个外层循环从 8 dB 扫到 18 dB步长 2 dB每个点统计 200 到 500 帧的累积误码。帧数要按目标误码率动态调整统计到的错误比特不足 100 个时这个点的 BER 没有置信度。一个常见做法是先跑一遍快速扫描找瀑布区位置再在瀑布区加密布点每个点加大帧数。这一步不需要额外代码块理解了统计口径就能自己改循环。4. 四个决定曲线走向的参数码率、迭代次数、交织深度与信噪比口径4.1 码率选择1/2 与 3/4 背后的频谱效率取舍64QAM 调制下每个符号携带 6 个比特码率 R 决定其中有多少是信息比特。系统频谱效率等于 6×R单位是比特/符号。从 1/2 提到 3/4频谱效率从 3 升到 4.5但代价是每个信息比特的能量被摊薄达到同样误码率需要的 Eb/N0 明显抬高。这组参数是做链路预算时最先要定下来的。码率 R信息比特/符号64QAM 下瀑布区大致位置码长 64800典型场景1/23 bit/symbolEb/N0 约 8.5-9.5 dB低信噪比可靠传输2/34 bit/symbolEb/N0 约 10.5-11.5 dB移动通信下行共享信道3/44.5 bit/symbolEb/N0 约 12.5-13.5 dB固定无线接入5/65 bit/symbolEb/N0 约 14.5 dB 以上视距高速传输这个表是量级参考具体位置取决于码长、迭代次数和交织策略但趋势很明确。选码率不是越高越好高码率对 64QAM 来说每符号只多 0.5-1 个信息比特却要把信噪比抬 2-3 dB。做 5G LDPC 仿真时还要注意基矩阵选择BG1 适合码率 1/3 到 8/9BG2 适合码率低至 1/5 的极低码率场景两者支持的码长范围不同。你拿到一个别人的仿真脚本第一件事就是看它用的是哪张基矩阵、码率设多少这会直接影响你后面改参数的边界。4.2 迭代次数瀑布区与错误平台之间的拉扯迭代次数是 LDPC 仿真里最玄学的参数之一。迭代太少BP 算法还没收敛瀑布区提前出现但底部踩不死误码率停在 1e-4 到 1e-5 之间形成错误平台。迭代太多高信噪比下每次迭代只换来 0.05 dB 的改善仿真时间却成倍上涨。经验值如下码长 64800、码率 2/3 时30 次迭代足够完全收敛码长 1944 的短码5G NR 控制信道常用50 次内一定收敛超过 50 次几乎看不到曲线变化。关键是要理解 BP 迭代的收敛特性低信噪比时迭代很多次还在挣扎高信噪比时十几次就校验通过。所以你固定最大迭代次数跑整个扫描低信噪比点全跑满、高信噪比点也有大量空转。标准优化是把终止条件从 MAX 改成 PARITY让译码器在校验和满足时提前停止。这不会改变曲线位置只改变运行时间实测能快 3-5 倍。唯一要注意的是对比不同算法性能时迭代次数要对齐否则一个算法多迭代 20 次赢下的曲线没有说服力。4.3 交织深度怎么和 LDPC 的准循环结构对齐交织深度这个词包含两层意思一是交织表长度二是置换粒度。长度方面64QAM 下必须是 6 的整数倍这是硬约束。更讲究的做法是按 LDPC 的准循环子块大小取。DVB-S2 的 LDPC 是用 360×360 的子矩阵扩展的交织表按 360 取整能保证同一子块的比特被均匀散到不同符号5G NR 的 LDPC 按提升因子 Z 扩展Z 从 2 到 384 不等交织深度按 Z 对齐后硬件上就是循环移位寄存器软件里也能避免随机交织导致的 LLR 局部集中。我见过一个反面案例有人直接用 randperm(N) 做全随机交织某次仿真出来的瀑布区比按 360 对齐的版本右移了 0.4 dB。原因是随机交织偶尔会让某个校验节点连到的比特恰好集中在同一批 64QAM 符号的低位比特上这些比特的 LLR 整体偏小校验节点拿到的全是弱信息。改成交织深度按子块大小对齐后同一校验节点的邻居比特分散在不同符号的不同比特位软信息质量均匀曲线就回来了。做交织器验证时建议至少对比三种配置无交织、全随机交织、按子块对齐交织看瀑布区差异。这也是一篇论文里能放进去的增量内容。4.4 Eb/N0 与 Es/N0 的换算扫信噪比时最容易被带偏的地方这条换算关系是 EsN0_dB EbN0_dB 10log10(log2(M)) 10log10(R)。64QAM 时 log2(M) 等于 6所以调制增益是 7.78 dB码率 2/3 时编码增益是 1.76 dB加一起 EsN0 比 EbN0 高 9.54 dB。如果你跳过码率项只按 10*log10(6) 换算等于把编码带来的冗余当成白送的横轴口径就错了 1.76 dB。这里分享一个血泪经验。有一次我从网上下了一套 LDPC_64QAM 脚本跑出来的曲线怎么都对不上文献。检查了星座映射、LLR 符号、噪声方差都没问题最后发现脚本里 awgn 填的是 EsN0但误码率统计时又按 EbN0 画横轴整条曲线往右漂了 9.5 dB。这种错不报错、不警告就是静悄悄地把你的结果变成废数。我的习惯是每个脚本的第一件事就是把 EsN0 和 EbN0 的换算写死在注释里跑之前先算一个点人工核对。功率归一化也要同时检查UnitAveragePower 设为 true 时 Es1噪声方差 1/SNR没归一化时噪声方差要除以星座平均功率否则 awgn 和噪声方差的参考口径不一致LLR 又错一层。5. LDPC 64QAM 仿真最容易翻车的 5 个点现象、原因与解决5.1 星座映射顺序错了整条曲线往右移 1 dB现象误码率曲线形态完全正常瀑布区斜率也对但整体比标准结果右移约 1 dB。低信噪比段几乎重合越往高信噪比偏移越明显。原因qammod 的星座索引默认按 Gray 序排列而你手写 LLR 时如果用了自然二进制顺序生成 bitMap两者错位后解调器算出来的软信息全是错的。Gray 映射下相邻星座只差 1 个比特硬判决错误还是单比特错误偏多映射错位后本来该差 1 bit 的相邻星座在 bitMap 里可能差 3-4 bitLLR 绝对值被系统性低估译码器拿到的信息可信度全部偏低。解决用 constellation qammod(0:M-1, M) 拿到星座点再用 bitMap de2bi(0:M-1, log2(M), left-msb) 生成对应的比特映射表两者顺序天然一致。不要自己写映射表也不要从网上拷贝一段看起来对的二进制表直接套用。5.2 LLR 忘了除噪声方差误码率永远停在 1e-3现象低信噪比段曲线还能下降但从 12 dB 往上几乎不再动误码率停在 1e-3 到 1e-4 之间怎么加大迭代次数都没用。原因LLR 公式里少了 1/σ² 因子。LDPC 的 BP 迭代依赖信道可靠性权重这个权重就是噪声方差的倒数。LLR 整体被放大或缩小时迭代行为完全不同。忘了除噪声方差等于告诉译码器信道完全可靠所有校验消息都被当成高置信度消息传递迭代被虚假信息锁死收敛不到真实的最大后验判决。解决把 (d1 - d0) 除以 noiseVar。noiseVar 要和 awgn 的口径严格对应星座功率归一化时就是 10^(-EsN0_dB/10)。有一个自检技巧把某几个信噪比点的 LLR 直方图画出来正常时 LLR 的分布宽度应该随 EsN0 增大而变宽如果 EsN0 变了 LLR 分布不变就是漏了噪声方差因子。5.3 编码前后的 Eb/N0 混用横轴标注对不上理论间隙现象误码率曲线比香农限高 3 dB 或低 3 dB周围人怎么看都觉得别扭但代码里找不到明显错误。原因编码后每个符号携带的比特数是 log2(M)×R有人用同一套 Eb/N0 去算编码前后的 EsN0横轴画的信息比特 Eb/N0纵轴统计的却包含校验比特。1/2 码率下这个错误正好差 3 dB因为编码冗余占了一半。解决固定用信息比特口径。发端生成的是信息比特误码统计也只比信息比特EsN0 EbN0 10log10(6) 10log10(R) 里的 R 就必须是真实码率。画图时横轴标注 Eb/N0与理论间隙比较才有意义。一个简单的交叉验证把码率改成 1此时编码增益项为 0曲线应该回到 64QAM 无编码的性能如果对不上说明口径还有问题。5.4 帧数太少瀑布区出现阶梯状假曲线现象BER 曲线在 1e-4 到 1e-6 段呈台阶状几个相邻信噪比点的误码率一模一样然后又突然跳变曲线不光滑。原因误码率是统计量。单帧 64800 码字在 1e-5 误码率下期望错误数只有约 0.65 比特/帧一帧里可能一个错误都没有。每个信噪比点只跑几十帧时抓到几个错误算几个曲线就是量化噪声不是真实性能。解决每个信噪比点至少统计到 100 个错误比特再停或者固定发 500 帧取累积误码。扫瀑布区时把帧数提到 1000 以上。另一个方案是自适应停止先跑 100 帧如果错误比特数不足 100继续跑直到错误数达标或达到帧数上限。这样高信噪比点不用白跑几千帧低信噪比点也能保证统计置信度。5.5 每帧都跑满迭代次数一晚上扫不完一条曲线现象仿真脚本写得很稳妥每帧固定 50 次迭代每个信噪比点 500 帧结果一晚上过去只扫了一半曲线瀑布区还没扫到。原因BP 译码在低信噪比时可能跑满 50 次都不收敛高信噪比时十几次就校验通过固定迭代次数让高信噪比点大量空转。64800 码长、2/3 码率一次迭代的复杂度约是 O(N×d)每帧 50 次迭代 × 500 帧 × 6 个信噪比点算下来是上亿次节点更新MATLAB 跑一夜很正常。解决把 IterationTerminationCondition 改成 PARITY译码器在校验和满足时提前停。这是最直接的提速手段实测快 3-5 倍。另外曲线形态出来后就别再加密布点瀑布区步长 0.5 dB、平台区步长 2 dB减少三分之一没必要跑的点。迭代次数对比实验单独跑不要和整条扫描混在一起。6. 验证与进阶用 EXIT 图量一量 LDPC 和 64QAM 的匹配度误码率曲线能跑通只是第一步怎么判断这个 LDPC 码和 64QAM 组在一起是不是最优组合我一般会补一张 EXIT 图。EXIT 图的横轴是译码器输入的先验互信息 I_A纵轴是译码器输出的外信息 I_E64QAM 软解调器也画一条 EXIT 曲线。两条曲线之间如果能形成一条从 (0,0) 到 (1,1) 的开放通道说明码和调制能互相喂饱瀑布区就会出现在理论预测的位置如果两条曲线在中途就相交通道被截断瀑布区就会推迟错误平台提前出现。这个验证能提前暴露码字结构和高阶调制不匹配的问题不用等整条误码率曲线扫完再后悔。具体做法不复杂对 64QAM 解调器按高斯分布注入带先验信息的 LLR统计输出 LLR 的互信息量得到解调器 EXIT 曲线对 LDPC 译码器做同样的先验注入得到译码器 EXIT 曲线。两条曲线叠加后通道越宽说明该码率下还有进一步降低信噪比门槛的空间。做 5G NR LDPC 仿真时EXIT 图能直接帮你判断 BG1 和 BG2 在 64QAM 下的适用边界——同一调制下BG2 在高码率区间的通道明显比 BG1 窄这也解释了为什么 NR 规范里 BG2 不用于高码率传输。如果你继续往 5G ldpc 方向深入下一步值得试的是把 DVB-S2 的 64800 码长换成 5G NR 的基矩阵码长按提升因子 Z 扩展。这里第一个坑是 Z 必须能整除信息位长度否则编码器直接报错第二个坑是 5G LDPC 的速率匹配包含打孔和缩短仿真的实际码率和名义码率不一定一致误码统计口径要按传输块算而不是按母码算。以往我在 LLR 符号约定上栽过跟头调了一整天才发现是正负号反了从此养成了一个习惯无论从哪个渠道拿到 LDPC_64QAM 脚本第一件事永远是造一个已知比特的短帧把编码、映射、解调、译码四个模块的中间量逐个比对确认无误再做整条曲线。这个习惯帮我省下了大量返工时间希望帮到你。本文还有配套的精品资源点击获取
返回列表