ARTICLE DETAIL

资讯详情

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

Polar码与PSS-SSS联合检测的5G NR链路BER/BLER仿真

Polar码与PSS-SSS联合检测的5G NR链路BER/BLER仿真 简介基于Polar编解码的PSS-SSS联合检测MATLAB仿真源码面向5G/LTE物理层算法研究人员、通信工程专业学生及无线通信仿真工程师解决同步信号检测成功率、误比特率BER与块误码率BLER联合评估问题。资源共68个文件以56个m脚本为主体覆盖编码、检测与性能计算流程5个mat文件保存信道与中间结果4个bin二进制文件及mexw64动态库、h头文件、txt说明作为补充整体仅2.63MB。目前已有146人学习浏览。内容包含PSS与SSS生成及检测、Polar编译码、联合检测策略、信道模型、BER/BLER计算模块并配有Runme.m可直接运行的仿真控制流程可按发端、信道、收端、常用函数、系统参数等目录模块展开学习。适合用于理解5G同步信号设计与Polar码性能验证也可作为进一步修改参数、扩展信道模型的起点。1. 从一次同步失败说起polar 与 PSS-SSS 为什么值得放在同一套仿真里很多人跑 5G NR 链路仿真时习惯把同步和信道译码拆成两段先用 PSS-SSS 验证定时和小区 ID再单独评估 Polar 码的 BER/BLER。这样分工的坏处是同步模块的残差会被“理想同步”掩盖等跑到整机联调才发现定时偏差早就把译码的 LLR 搅坏了。这个标题真正想让你回答的问题是当 PSS-SSS 联合检测成功率达到某个数值时Polar 链路还能保住多低的 BER 和 BLER以及反过来同步开始出错的时候译码指标会比理想同步恶化多少。这里要强调一下标题里的“联合检测”不是多用户检测里的那个 JD而是 PSS 与 SSS 两个同步信号作为一个整体来判成功。这篇博文按做链路级仿真最常见的方法展开先立 polar 编解码的最小链路再写 PSS-SSS 检测与成功率统计最后把两者挂进同一套蒙特卡洛框架下输出 BER 和 BLER。适合正在搭 NR 控制信道链路、或者想给自己的收发机模型补一块同步评估的人。整套方案用 MATLAB 实现脚本化批量跑不依赖 Simulink。2. 搭 polar 编解码链路参数选型、编码矩阵与 SC List 译码骨架2.1 Polar 码的可靠性计算与参数表Polar 码在 5G NR 里主要用于控制信道信息位从几十到几百 bit 不等。仿真里不要一上来就套一个很大的 N先把 N512、K184 这类控制信道典型配置跑通再放大到 N1024 看趋势。可靠性度量常见选择是巴氏参数 Z(W)也可以用高斯近似MATLAB 里自己算 Z 值并不难。信道合并拆分后每个子信道的可靠性排序在加性高斯白噪声信道下基本固定所以仿真中通常会预生成一张 frozen 位表而不是每帧重新算。一张可以直接入手的参数表如下参数项建议取值备注母码长度 N512 / 1024N 必须为 2 的幂信息位 K184 / 360按控制信道 DCI 常见负载量CRC 长度11 / 24先用 11 调通再换 24 回归调制方式QPSK先不看 16QAM便于定位同步误差SC-List 大小 L8折中也够用32 收益小于开销信道模型AWGN 固定频偏先不要上 TDL 多径代码里我用 frozenBits 向量表示冻结位true 为冻结按可靠性升序取前 K 个作为信息位。这个顺序决定了编码矩阵里哪些比特是实际数据。2.2 用 MATLAB 写一个最小 polar 编码函数function cw polarEncode(infoBits, frozenBits) % polarEncode: 极化码编码基于 Arikan 核的 Kronecker 变换 % infoBits : 行向量长度为 K % frozenBits : 逻辑行向量长度为 Ntrue 表示冻结位 N numel(frozenBits); if mod(N, 2) ~ 0 error(N 必须是 2 的幂); end % 生成 N 阶生成矩阵 G F2^(⊗log2(N)) F2 [1 0; 1 1]; G F2; while size(G,1) N G kron(G, F2); end u zeros(1, N); infoIdx find(~frozenBits); u(infoIdx) infoBits; % 信息位放入非冻结位置 cw mod(u * G, 2); end这段代码里的生成矩阵用kron逐级扩张N512 时矩阵是 512×512MATLAB 能扛住N4096 以上内存和计算量会明显变大需要用递归编码替代。frozenBits的逻辑方向要和译码端严格一致否则解出来的比特全错。日常调试时我会在函数开头加一个断言sum(~frozenBits) length(infoBits)提前拦截长度不匹配。2.3 SC List 译码的调用参数与 LLR 接口完整实现一个 SC List 译码器代码量不小常用做法是自己维护路径分裂和路径度量或者按 5G Toolbox 的思路封装。仿真脚本中真正重要的是把接口和参数定义清楚保证调用侧不被实现细节干扰。下面是一个调用骨架假定sclDecodeCrcSoft返回译码结果、CRC 校验结果和最终路径度量listSize 8; crcPoly 11; [decBits, crcOk, ~] sclDecodeCrcSoft(softLLR, G, frozenBits, ... listSize, crcPoly); if crcOk infoBitsHat decBits(1:K); else blockFailCount blockFailCount 1; endsoftLLR的格式建议固定为“正数代表 1、负数代表 0”的对数似然比这一约定在 BPSK/QPSK 解调端生成 LLR 时保持一致。listSize 从 8 升到 16 时BLER 收益通常只有零点几个百分点但译码耗时接近翻倍所以批量扫 SNR 时尽量别用大 list。3. PSS-SSS 联合检测的实现本地序列、滑动相关与成功率判定3.1 PSS 本地序列生成与互相关峰值搜索5G NR 的 PSS 用长度为 127 的 ZC 序列根指数 u 取 25、29、34分别对应 NID2 的 0、1、2。接收端拿到频域资源后用本地 3 组序列分别做互相关找峰。简化链路仿真里可以直接对时域接收信号做滑动相关但更接近真实接收机的做法是完成 FFT 和子载波提取后在频域做相关再跨符号累加。下面的代码实现了本地序列生成与一次相关峰值查找function pssLocal generatePssLocal(u) % 5G NR PSS 序列N_ZC127 n (0:126).; zp exp(-1j * pi * u * n .* (n1) / 127); pssLocal zp; end function [peakVal, peakIdx] searchPss(rxGrid, u) pssLocal generatePssLocal(u); corrLen size(rxGrid, 2) - 127 1; corrOut zeros(1, corrLen); for idx 1:corrLen seg rxGrid(:, idx:idx126); corrOut(idx) abs(sum(sum(seg .* conj(pssLocal)))); end [peakVal, peakIdx] max(corrOut); endrxGrid是按符号和子载波排列的频域矩阵纵轴是子载波横轴是符号索引。相关结果不除以功率归一化也能用但在低信噪比下容易冒虚假峰因此后面统计成功率时不用固定幅度门限而是用“峰均比”判定。峰值位置peakIdx就是 PSS 符号的起始位置也是后续 SSS 搜索窗口的锚点。3.2 SSS 序列生成与联合 ID 判定SSS 在 NR 里由两个 m 序列交织生成携带 NID1。利用 PSS 给出的定时和 NID2接收机可以在一个窄窗口内搜索 SSS不需要全帧扫描。这里给出一个功能等价的简化实现重点是把“联合判定”的流程写清楚PSS 先把候选 NID2 和定时定下来SSS 只在 PSS 峰值附近搜索最终输出完整 PCI。判定条件通过标准PSS 定时误差小于 0.5 个采样点NID2 检测与发送端一致SSS 检测与发送端 NID1 一致联合成功率上述三项同时成立联合成功率的统计不是把 PSS 成功率与 SSS 成功率相乘就完了。实际跑的时候会发现两件事情第一PSS 峰值位置偏了几十毫微秒不至于让 SSS 错但会让解调 LLR 变差第二SSS 错误的帧里大约有一半 PSS 是正确的所以只有把两者放一起判定才能体现真实接收机的同步打开概率。3.3 联合成功率的蒙特卡洛统计脚本numFrames 500; jointOk 0; for fIdx 1:numFrames txPci randi([0 1007]); % 发送端真实 PCI nid2 mod(txPci, 3); nid1 floor(txPci / 3); % 经过信道、频偏、加噪后的 rxGrid 已生成 [~, pssPeak] searchPss(rxGrid, nid2); [sssId, sssOk] searchSss(rxGrid, pssPeak, nid2); timeErr abs(pssPeak - txPssPos); if sssOk true sssId nid1 timeErr 0.5 jointOk jointOk 1; end end jointRate jointOk / numFrames;searchSss内部只在一个宽度为 14 个符号的窗口内做相关这是 PSS-SSS 联合检测最常见的工程简化。反过来如果某帧 SSS 没找对排查时最先看窗口位置是否被 PSS 峰值带偏。联合成功率低于 0.8 时大概率不是 SSS 序列本身的问题而是 PSS 定时误差把搜索窗口切错了位置。4. 联合 BER/BLER 的蒙特卡洛仿真框架与统计口径4.1 BER 与 BLER 在这一链路里分别统计什么BER 统计的是所有传输比特中错误比特的比例BLER 统计的是所有传输块中校验失败的块比例。在带 CRC 的 Polar 链路里BLER 以 CRC 结果为准BER 则按译码比特与发送比特逐位比对。两者要分开记录因为 CRC 通过但部分比特错误的情况极罕见而 CRC 失败时 BER 可能仍然很低这种帧在 BLER 曲线里才真正暴露译码器性能。联合检测对这两个指标的影响体现在一个很容易被忽略的环节同步残差会导致相位旋转和符号定时偏差解调输出的 LLR 从质量上整体变差。Polar 译码对 LLR 绝对值的大小并不敏感但 LLR 的符号错误率只要提高几个百分点BLER 就可能从 1% 飘到 20%。所以不要只在“同步成功”的帧里数 BER那样相当于把同步失败帧从样本里剔除了得到的是一个虚高的性能曲线。4.2 MATLAB 主循环脚本与参数表下面的脚本骨架把前两章的模块都串起来逐帧统计三组结果联合检测成功率、BER、BLER。每帧先做同步检测再做解调译码并且分别记录“联合链路”和“理想同步链路”两套指标方便事后对比。snrVec -6:2:6; numFrames 200; result struct(snr, [], jointOk, [], ber, [], bler, []); for sIdx 1:numel(snrVec) snr snrVec(sIdx); berAcc 0; bitAcc 0; frameFail 0; jointOk 0; for fIdx 1:numFrames % 发送端 infoBit randi([0 1], 1, K); cw polarEncode(infoBit, frozenBits); modSym qpskMod(cw); % 信道与同步模块略rxSym 为接收符号 [pssOk, sssOk, timeErr] detectPssSss(rxSym, txPci); if pssOk sssOk timeErr 0.5 jointOk jointOk 1; end % 解调与译码这里用理想同步位置做对比项 softLlr qpskSoftDemod(rxSym, snr); [decBits, crcOk] sclDecodeCrcSoft(softLlr, G, frozenBits, listSize, crcPoly); bitErr sum(decBits ~ cw); berAcc berAcc bitErr; bitAcc bitAcc length(cw); if crcOk false frameFail frameFail 1; end end result(sIdx).snr snr; result(sIdx).jointOk jointOk / numFrames; result(sIdx).ber berAcc / bitAcc; result(sIdx).bler frameFail / numFrames; end仿真参数集中在脚本头部方便批量扫点参数值作用N512Polar 母码长度K184信息位长度listSize8SC List 路径数numFrames200 / 2000先 200 帧调通再加大到 2000snrVec-6:2:6低信噪比关注 BLEr高信噪比关注地板每信噪比帧数直接决定 BLER 曲线的最低可观察值。如果目标 BLER 是 1%至少需要统计 100 个错误块也就是约 1 万帧否则最后几个点的误差会超过曲线本身的变化。4.3 联合链路与理想同步的对比画法figure; semilogy(snrVec, [result.ber], o-); hold on; semilogy(snrVec, [result.bler], s-); xlabel(SNR (dB)); ylabel(BER / BLER); legend(BER, BLER); title(Polar 512/184 on AWGN with PSS-SSS front-end); grid on;对比理想同步链路时只需把detectPssSss的判定结果强制置为成功。两套曲线的差距就是同步模块付出的信噪比代价。常见情况下联合链路的 BLER 曲线会比理想同步右移 0.5~1.5 dB如果差距超过 3 dB优先检查频偏补偿而不是 Polar 译码器本身。5. 三个值得盯住的细节归因方式、门限写法与样本量把握仿真收尾阶段不要急着贴曲线先做三件事。第一次跑出来的联合成功率很低时把 PSS 单独成功和 SSS 单独成功也分别计数用三列日志输出。PSS 对而 SSS 错说明窗口或 NID1 映射出问题两者都错先怀疑频偏只有定时误差超标才回头查符号定时估计模块。归因不清时加日志比加算法改动更有效。PSS 检测门限不要写死成某个幅度值。接收机增益不同、信道衰减不同同一门限在两组仿真里表现完全不同。实际做法是用峰值除以相关输出均值峰均比超过 4 判定为有信号再配合连续 3 个子帧峰值位置抖动小于 1 个采样点可以显著降低虚检。这个峰均比门限对频偏敏感扫频偏时先把它放松到 3 再看曲线趋势。最后是老生常谈的样本量问题。BLER 在没有错误帧时显示为 0画半对数坐标时会被直接丢弃很多人误以为性能已经到零。正确做法是固定每信噪比至少跑 2000 帧并且设置一个“连续 50 帧全对则提前结束”的判据省时又不至于把曲线下界推到不合理的区域。Polar 译码的 list 大小最后再调先用 list8 跑全量信噪比只在 BLER 进入 1% 附近的点补跑 list32这样仿真时间至少省一半结论不会变。本文还有配套的精品资源点击获取
返回列表