news 2026/10/27 8:05:40

5G LDPC MATLAB实现:从基图选择到链路级仿真

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5G LDPC MATLAB实现:从基图选择到链路级仿真

简介:这份资源面向通信工程、信号处理方向的学习者与开发者,聚焦5G NR标准下LDPC码的MATLAB实现,帮助读者理解校验矩阵构造、编码流程与迭代解码算法,适合具备一定通信原理与MATLAB基础的中高级读者用于课程设计或算法验证。压缩包共9个文件,以7个m脚本和2个mat数据文件为主,脚本覆盖基图选择、提升尺寸计算、校验矩阵生成、打孔与仿真主流程,mat文件则保存协议对应的校验矩阵数据,整体约20KB,结构紧凑便于按模块研读。目前已有1361人学习下载。通过阅读代码,读者可掌握3GPP两套协议下H矩阵的生成方式、信息列与打孔处理逻辑,并借助仿真脚本观察不同码率与码族下的编解码表现,为后续算法优化与硬件移植提供可复用的参考实现。

1. 5G LDPC 码的 MATLAB 实现:从标准到可跑通的链路级仿真

做 5G 物理层的人迟早会撞上 LDPC。协议里 eLDPC 编码链路看起来只是几张表加几个公式,真动手写 MATLAB 才发现坑全在细节里:基图怎么选、提升因子 Zc 怎么定、速率匹配的比特选择怎么和 HARQ 冗余版本对齐,任何一处对不上,误码率曲线就是一条平的。这个标题指向的正是这条链路——在 MATLAB 里把 3GPP 38.212 定义的 5G LDPC 编码从基图、循环系数、编码矩阵一路搭到速率匹配和译码验证。它适合两类人:一类是要做链路级仿真、验证自己算法性能的通信研究生和工程师;另一类是基站或终端侧做 LDPC 实现、需要一份 MATLAB 参考模型来对拍 C 代码的开发者。下面按我实际搭这套东西的顺序讲,能直接抄去改。

2. 5G LDPC 和 4G Turbo 的差别:为什么基图要分 BG1 和 BG2

2.1 准循环结构和双基图设计

5G 选 LDPC 而不是继续用 Turbo,核心原因是高码率、大码块下的译码吞吐和错误平层。NR LDPC 用的是准循环结构:整个奇偶校验矩阵由若干个 Zc×Zc 的循环置换矩阵和全零矩阵拼成,Zc 叫提升因子。这样做的好处是编码和译码都能按块并行,硬件友好,MATLAB 里也能用稀疏矩阵加循环移位高效表示,不用真的展开成一个上万维的稠密矩阵。

协议定义了两张基图。BG1 是 46×68,信息列 22 列,适合码率较高、信息块较大的场景,比如 eMBB 的下行数据;BG2 是 42×52,信息列 10 列,适合低码率、小块或高可靠场景,比如控制信息和 URLLC。选哪张不是拍脑袋,38.212 给了明确规则:按信息比特数 A 和码率 R 查表。我一般直接按协议表格实现一个选择函数,而不是自己定阈值,否则和标准对不上,后面速率匹配全乱。

2.2 基图选择与提升因子的确定

选完基图,接下来定 Zc。协议给了一张提升因子候选表,Zc = a × 2^j,a 取 2、3、5、7、9、11、13、15,j 从 0 到 7,一共 51 个合法值。规则是:先根据信息块长度和码率算出需要的 Kb,再找最小的 Zc 使得 Kb × Zc 能容纳信息比特。这里最容易翻车的是把 Kb 记错——BG1 的 Kb 是 22,BG2 是 10,但 BG2 在信息比特很短时 Kb 会降到 9 或 6,这个细节不处理,短块场景直接对不上。

function [bgn, Zc] = selectBaseGraph(A, R) % A: 信息比特数, R: 目标码率 % 返回基图编号 bgn 和提升因子 Zc if A <= 292 || (A <= 3824 && R <= 0.67) || R <= 0.25 bgn = 2; else bgn = 1; end % 确定 Kb if bgn == 1 Kb = 22; else if A > 640 Kb = 10; elseif A > 560 Kb = 9; elseif A > 192 Kb = 8; else Kb = 6; end end % 提升因子候选表 a_list = [2 3 5 7 9 11 13 15]; Zc_list = []; for a = a_list for j = 0:7 Zc_list(end+1) = a * 2^j; end end Zc_list = sort(Zc_list); K = Kb * Zc_list; % 每个候选 Zc 对应的最大信息长度 idx = find(K >= A, 1, 'first'); Zc = Zc_list(idx); end

这段逻辑说明:先按协议规则定基图,再按 A 的大小定 Kb,最后在 51 个候选 Zc 里找第一个能满足 Kb×Zc ≥ A 的值。参数上要注意 A 是加完 CRC 之后的信息比特数,不是原始传输块大小,很多人在这里少加了 CRC 导致 Zc 选小了一档,编码直接报错。另外 Zc_list 排序后取 first,保证选到的是最小合法值,符合协议要求。

3. 在 MATLAB 里搭出编码核心:从基图矩阵到码字

3.1 用稀疏矩阵表示基图并做循环扩展

协议给的基图是以循环系数形式给出的,每个非 -1 的元素表示一个 Zc×Zc 的循环移位矩阵,移位量就是那个系数。MATLAB 里没必要真的构造大矩阵,我一般保留基图系数矩阵 H_BG,编码时按系数做循环移位和异或。这样内存占用小,速度也快。基图系数可以从协议表格录入,也可以从公开的参考实现里核对,但一定要自己验证几个已知向量,别直接信来源不明的表。

编码本身分两部分:前 Kb 列对应系统比特,直接放信息;后面是校验部分,5G LDPC 的校验结构是双对角加一个特殊列,可以用前向代入快速求解,不需要做矩阵求逆。这是 5G LDPC 编码能做得很快的关键,也是和一般 LDPC 随机矩阵最大的不同。

function cw = ldpcEncode(infoBits, H_BG, Zc, Kb) % infoBits: 信息比特(长度 Kb*Zc) % H_BG: 基图系数矩阵, -1 表示全零块 % 返回编码后码字(含系统位和校验位) [mb, nb] = size(H_BG); kb = nb - mb; % 重塑成 Kb 个长度为 Zc 的块 u = reshape(infoBits, Zc, kb).'; p = zeros(mb, Zc); % 前向代入求校验块, 利用双对角结构 for i = 1:mb acc = zeros(1, Zc); for j = 1:kb if H_BG(i,j) >= 0 acc = mod(acc + circshift(u(j,:), H_BG(i,j)), 2); end end for j = 1:i-1 if H_BG(i, kb+j) >= 0 acc = mod(acc + circshift(p(j,:), H_BG(i, kb+j)), 2); end end p(i,:) = acc; end cw = [reshape(u.', 1, []), reshape(p.', 1, [])]; end

逻辑说明:把信息比特按 Zc 分块,逐校验行累加对应循环移位后的块,再减去已求出的校验块贡献,得到当前校验块。参数上 H_BG 的维度决定 mb 和 kb,circshift 的移位量就是基图系数。注意这里用 mod 2 做二元运算,实际工程里会用位运算加速,但 MATLAB 验证阶段这样写最直观。跑通后拿一个全零信息块测试,输出应该也是全零,这是最基本的自检。

3.2 速率匹配与 HARQ 冗余版本

编码出来的是母码,长度是 nb×Zc,实际传输要经过速率匹配截取或重复到目标长度。5G 的速率匹配分三步:比特选择、交织、比特交织。比特选择按冗余版本 rv 从循环缓冲里取,rv0 到 rv3 对应不同的起始位置。这里最常见的坑是循环缓冲的构造顺序——系统比特和校验比特的排列顺序、以及被打孔的前 2×Zc 个比特,顺序错了,四个 rv 的起始位置全错,HARQ 合并增益直接消失。

function out = rateMatch(cw, Zc, Kb, E, rv) % cw: 母码, E: 目标输出长度, rv: 冗余版本 0~3 Ncb = length(cw); % 打孔前 2*Zc 个比特 buf = cw(2*Zc+1:end); % 按 rv 确定起始位置 switch rv case 0, k0 = 0; case 1, k0 = floor(17*Ncb/(66*Zc))*Zc; case 2, k0 = floor(33*Ncb/(66*Zc))*Zc; case 3, k0 = floor(56*Ncb/(66*Zc))*Zc; end out = zeros(1, E); for i = 1:E out(i) = buf(mod(k0 + i - 1, length(buf)) + 1); end end

逻辑说明:先按协议打孔掉前 2×Zc 个比特,再按 rv 算起始偏移 k0,然后循环读取到目标长度 E。参数上 k0 的公式里 Ncb 是循环缓冲长度,不同 rv 的系数 17、33、56 来自协议,别自己改。注意 E 可能大于缓冲长度,这时会重复读取,这是正常的,不是 bug。验证方法是把四个 rv 的输出拼起来看是否覆盖了缓冲的不同区段。

4. 译码与性能验证:把误码率曲线跑出来

4.1 置信传播译码的 MATLAB 实现要点

编码对了不代表链路对了,得用译码器把误码率跑出来才算数。5G LDPC 常用的是分层置信传播或最小和译码。MATLAB 里我一般先用最小和,因为实现简单、数值稳定,验证功能足够。核心是迭代地在变量节点和校验节点之间传对数似然比,每轮更新一次硬判决,达到最大迭代次数或校验通过就停。

实现时要注意两点:一是归一化最小和的归一化因子,取 0.75 到 0.8 之间通常性能接近置信传播;二是消息要用稀疏结构索引,别用全矩阵,否则一个码块几万次循环,MATLAB 跑一晚上都出不来一条曲线。我一般把基图系数转成稀疏邻接表,变量节点和校验节点的连接关系预先算好。

function [decBits, iter] = ldpcDecode(llr, H_BG, Zc, maxIter) % llr: 接收对数似然比 % 返回译码比特和实际迭代次数 [mb, nb] = size(H_BG); kb = nb - mb; L = reshape(llr, Zc, nb); % 初始化变量节点消息 Mv = L; for iter = 1:maxIter % 校验节点更新(最小和) Mc = zeros(mb, Zc); for i = 1:mb for j = 1:nb if H_BG(i,j) >= 0 % 取该行其他变量节点的最小值 tmp = Mv; tmp(j,:) = inf; Mc(i,:) = min(abs(tmp), [], 1) .* sign(prod(sign(tmp),1)); end end end % 变量节点更新 Mv = L; for i = 1:mb for j = 1:nb if H_BG(i,j) >= 0 Mv(j,:) = Mv(j,:) + circshift(Mc(i,:), -H_BG(i,j)); end end end % 硬判决与校验 decBits = reshape((Mv(1:kb,:) < 0).', 1, []); if checkParity(decBits, H_BG, Zc) break; end end end

逻辑说明:校验节点更新取该行其他变量节点消息的绝对值最小值和符号乘积,这是最小和的核心;变量节点更新把校验消息移回对应位置累加。参数上 maxIter 一般设 20 到 50,归一化因子可以乘在 Mc 上。注意这段是教学版,逐元素循环很慢,实际跑曲线要把内层循环向量化,或者用通信工具箱的 ldpcDecode 做对拍。

4.2 用误码率曲线判断实现是否正确

验证实现对不对,最直接的办法是跑 AWGN 下的误码率曲线,和协议或公开结果对比。如果曲线在低信噪比下正常下降,说明编码译码链路基本对;如果出现错误平层,通常是基图系数录错、Zc 选错或速率匹配顺序错。我一般先跑一个固定码率、固定码长的点,确认和参考差在 0.2 dB 以内,再铺开跑整条曲线。

验证项期望现象异常时的排查方向
全零输入编码输出全零基图系数或循环移位方向
无噪声译码一次迭代即通过校验矩阵与编码是否一致
低信噪比曲线随 SNR 单调下降速率匹配或 LLR 量化
高信噪比曲线无错误平层基图系数、Zc、迭代次数

5. 避坑与排查:5G LDPC MATLAB 实现里最容易翻车的五件事

现象:编码输出长度和预期对不上。原因多半是 Zc 选错或 Kb 用错,尤其是 BG2 短块场景 Kb 会降到 9 或 6,很多人固定用 10。解决是按 A 分段判断 Kb,并在选完 Zc 后打印 Kb×Zc 和 A 对比,确认能容纳。

现象:译码在无噪声下也不收敛。原因是编码用的基图和译码用的基图不是同一份,或者循环移位方向反了。解决是统一基图来源,编码和译码共用同一个 H_BG,并检查 circshift 的正负号是否一致。

现象:HARQ 合并后没有增益。原因是四个 rv 的起始位置算错,或者循环缓冲构造时打孔位置不对。解决是核对 k0 公式里的系数,并打印四个 rv 的输出区间,确认它们落在缓冲的不同位置。

现象:误码率曲线出现错误平层。原因是基图系数录入有误,或者最小和译码的归一化因子没调。解决是逐行核对基图系数,把归一化因子从 1.0 往 0.75 调,看平层是否下降。

现象:MATLAB 跑一条曲线要几个小时。原因是译码用了全矩阵和逐元素循环。解决是把基图转稀疏邻接表,内层循环向量化,或者直接用通信工具箱的 ldpcEncode/ldpcDecode 做性能基准,自己实现只用于理解和对拍。

6. 进阶技巧:用对拍和定点量化把 MATLAB 模型推向工程

功能跑通只是第一步,真正要拿去指导实现,还得做两件事:对拍和量化。对拍就是拿 MATLAB 自写实现和通信工具箱的 ldpcEncode/ldpcDecode 逐比特比对,随机生成几百组信息比特,确认编码输出完全一致、译码输出在相同 LLR 下一致。这一步能抓出绝大多数隐藏 bug,比看曲线快得多。

% 与通信工具箱对拍 for trial = 1:200 A = randi([100, 8000]); info = randi([0 1], 1, A); % 自写实现 [bgn, Zc] = selectBaseGraph(A, 0.5); H_BG = loadBaseGraph(bgn); infoPad = [info, zeros(1, 22*Zc - A)]; cw1 = ldpcEncode(infoPad, H_BG, Zc, 22); % 工具箱实现 cfg = ldpcEncoderConfig(H_BG); cw2 = ldpcEncode(info.', cfg).'; assert(isequal(cw1, cw2), '第 %d 组编码不一致', trial); end

逻辑说明:随机生成不同长度的信息块,分别用自写函数和工具箱编码,断言输出一致。参数上注意工具箱的输入输出方向和信息补齐方式,补齐位数要和自写实现一致。这一步过了,说明编码核心没问题,再去做译码对拍。

定点量化是另一个分水岭。MATLAB 默认双精度,实际硬件是定点,LLR 位宽、消息饱和、归一化因子都会影响性能。我一般把 LLR 量化到 4 到 6 比特,消息位宽 6 到 8 比特,跑一遍曲线看和浮点差多少。差 0.3 dB 以内可以接受,差太多就要调饱和门限。这个环节没有捷径,只能一点点试,但试出来的参数就是后面写 RTL 或 C 的直接输入。

我自己踩过最深的一个坑,是早期图省事直接用了网上抄来的基图系数,结果曲线怎么调都不对,查了三天才发现有一行的移位量抄错了一个数。从那以后我养成的习惯是:任何基图、任何系数表,进代码前先用全零和全一向量各跑一遍自检,再和工具箱对拍。这个习惯帮我省下的时间,远比多写几行验证代码多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 8:05:21

电赛H题自动驾驶小车:从原理图到PID调参的完整实战指南

简介&#xff1a;这份资源是2024年全国大学生电子设计竞赛H题自动驾驶小车系统的完整工程包&#xff0c;面向备战电赛的高校学生、计算机与自动化相关专业做课程设计或毕业设计的学习者&#xff0c;以及需要嵌入式项目实战练手的开发者。包内共144个文件&#xff0c;以84个h头文…

作者头像 李华
网站建设 2026/10/27 8:04:28

SSH公钥认证原理与Ed25519密钥实践指南

1. SSH公钥认证机制解析SSH公钥认证是远程登录的主流方案&#xff0c;相比传统密码认证具有三大核心优势&#xff1a;安全性&#xff1a;采用非对称加密体系&#xff0c;私钥永不传输便捷性&#xff1a;配置后无需重复输入密码自动化&#xff1a;支持脚本和CI/CD流程的无交互操…

作者头像 李华
网站建设 2026/10/27 8:04:12

K8s节点DiskPressure治理:kubelet回收、日志轮转与常驻清理

1. 磁盘告警总在凌晨三点响&#xff1a;先把清理这件事想明白集群跑得好好的&#xff0c;突然一条告警弹出来&#xff1a;某节点 DiskPressure&#xff0c;Pod 开始被驱逐&#xff0c;业务方在群里问为什么服务飘了。登上机器df -h一看&#xff0c;根分区 100%&#xff0c;du -…

作者头像 李华
网站建设 2026/10/27 8:04:08

RoboRefer:机器人空间指代与自然语言理解技术解析

1. 项目概述&#xff1a;RoboRefer的定位与核心价值RoboRefer是2025年NIPS会议上提出的一个前沿研究项目&#xff0c;它试图解决机器人领域中一个长期存在的关键问题——如何让机器人像人类一样理解并执行包含空间指代和复杂推理的自然语言指令。想象一下&#xff0c;当你对家用…

作者头像 李华
网站建设 2026/10/27 8:04:07

Matlab/Simulink配电网仿真资源包:从零跑通到批量仿真避坑指南

简介&#xff1a;这份资源围绕Matlab与Simulink环境下的配电网仿真展开&#xff0c;面向计算机、电子信息工程、数学等专业的大学生&#xff0c;可用于课程设计、期末大作业或毕业设计的参考资料&#xff0c;帮助读者理解配电网建模、潮流计算与仿真验证的基本流程。压缩包为ra…

作者头像 李华
网站建设 2026/10/27 8:03:38

一维河道水动力模型MATLAB代码:从Saint-Venant方程到洪水演进实战

简介&#xff1a;这份资源面向水文学、水利工程方向的研究人员与工程技术人员&#xff0c;提供一套基于Matlab实现的一维河道水动力计算代码&#xff0c;用于模拟矩形河道内流速与水深变化&#xff0c;可服务于河流管理、洪水预警与水利工程设计等场景。模型以圣维南方程组为核…

作者头像 李华