news 2026/9/12 23:06:58

Polar译码器与PSS-SSS联合检测的NR物理层仿真实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Polar译码器与PSS-SSS联合检测的NR物理层仿真实现

简介:这是基于MATLAB的Polar编解码联合检测仿真源码,面向5G通信、无线信号处理领域的研究者与进阶学习者。整套方案聚焦PSS/SSS联合检测成功率以及BER、BLER性能指标输出,可用于同步算法验证、信道估计和编码性能评估。源码共68个文件,以56个.m脚本为核心,涵盖信号生成、Polar编码解码、联合检测策略、信道模型及性能计算模块;另含.mat数据文件、.bin信道样本、说明txt与mexw64辅助运行文件,打包后约2.63MB。目前已有146人学习。通过阅读和运行源码,可直观掌握Polar码在系统同步中的实际应用,理解PSS/SSS联合检测的流程与参数配置,并借助现成的BER/BLER计算模块完成自定义场景仿真,对未来5G协议研究和算法设计具有较高参考价值。

1. 联合检测不是串行流程:Polar译码器如何反哺PSS-SSS同步估计

在LTE/NR物理层仿真里,PSS-SSS同步检测和Polar信道译码通常被当作两个独立的模块:先做时频同步,再做下行控制信道(如PBCH)的Polar译码。但拿到这套MATLAB工程后会发现,它的核心设计思路是把两者揉进同一条链路——PSS/SSS联合检测得到的信道估计结果不只是在同步阶段用一次,而是作为Polar译码器计算LLR(对数似然比)时的先验信息,同时译码输出的CRC校验结果又反向决定是否需要重新调整同步参数。这种闭环结构对仿真平台的复用性要求很高,工程里通过Runme.m统一调度发端、信道、收端三个目录下的函数,用全局变量结构体(比如system_param)在模块间传递软信息,而不是各自为政地重复估计信道。

这个工程适合两类人:一是做NR物理层算法验证的工程师,需要对照PSS-SSS检测成功率、BER、BLER三类指标来评估同步误差对Polar译码性能的影响;二是准备5G相关课程设计的学生,源码里cellsearch.matTU_channel_An11_I.bin这类文件直接对应3GPP TR 38.900定义的TDL信道模型,可以省去自己搭链路的大半工作量。需要提醒的是,项目默认的采样率和子载波间隔是按30 kHz子载波间隔、1536点FFT配置的,如果直接跑Runme.m拿到的是固定参数下的仿真结果,想换带宽或 numerology 要同时改系统参数.m里的FFTSizePSS生成函数里的ZC序列根索引。

2. Polar编解码的软信息表示:从信道极化到LLR更新

2.1 信道极化与编码矩阵的生成逻辑

Polar编码的理论基础是信道极化——把N个独立信道通过递归的蝶形结构合并又分裂,使一部分信道容量趋近于1(信息位),另一部分趋近于0(冻结位)。在MATLAB工程里,对应的是Polar编码目录下的PolarEncoder.m,它并不直接调用comm.PolarEncoder系统对象,而是按Arikan论文的G_N矩阵递推公式手动实现,核心代码段是这样的:

function [encoded, info_bits] = polar_encode(data, K, N, frozen_set) % N: 码长,必须是2的幂;K: 信息位长度;frozen_set: 冻结位索引 G = 1; for stage = 1:log2(N) G = [G 0; G G]; % Kronecker 幂构造生成矩阵 end u = zeros(1, N); u(info_bits) = data; % 信息比特放入信息位 u(frozen_set) = 0; % 冻结位置零 encoded = mod(u * G, 2); end

这段代码里的G矩阵每迭代一次就做一次Kronecker幂扩张,本质上是在复现Polar编码的蝶形变换。注意info_bitsfrozen_set这两个向量不能有交集,它们的并集必须是1:N的全集,否则生成的码字直接错乱。实际5G NR标准里信息位选择用Q函数计算巴氏参数,但这套工程用的是离线算好的frozen_set,存在cellsearch.matfrozenTable字段里,好处是省去每次仿真都重算极化的时间。

2.2 SC译码的LLR递归更新

译码端实现的是SC(Successive Cancellation)译码器,Polar编码目录下SCDecoder.m的核心是LLR的递归计算。与BCJR这类最大后验算法不同,SC译码按比特序号依次判决,第i个比特的LLR由两部分组成:一是接收符号直接给出的信道LLR,二是前面i-1个已判决比特通过蝶形结构传递过来的冻结约束。关键代码是递推式(用f函数和g函数两个分支):

function LLR_out = sc_node_update(LLR_left, LLR_right, u_left_hat) % f 节点:用于偶数位,对应异或约束 LLR_f = 2 * atanh(tanh(LLR_left/2) .* tanh(LLR_right/2)); % g 节点:用于奇数位,需要用到已判决的左侧比特 LLR_g = LLR_right + (-1)^u_left_hat .* LLR_left; end

在实际仿真中,f函数里的tanh计算在长码长下会有数值下溢风险,工程里用了近似公式sign(a)*sign(b)*min(abs(a),abs(b))替换,代价是大约0.1 dB的增益损失,但仿真速度提升一倍以上。建议你在修改这段代码时把近似开关做成一个参数SC_approx_enable,对比两种模式下的BLER差异。

2.3 速率匹配与CRC附加的工程处理

3GPP NR的Polar码不是裸的Arikan码,还要做速率匹配——从母码长度N中按QAM映射顺序打孔或缩短出实际传输的E比特。这套源码里rate_match.m实现的是最简单的BPSK映射下均匀打孔:对编码后的encodedpuncture_pattern向量做索引选取,puncture_pattern系统参数.m里通过nrPolarRateMatch接口生成(如果MATLAB版本低于R2022a,需要把该函数替换为自实现的比特选择)。

CRC部分要注意PolarEncoder.m的输出encoded长度是N + crc_length还是N取决于调用方式:工程里默认在Runme.m中先调用crc_attach.m对信息比特附加24位CRC(生成多项式0x1864CFB),然后才送进polar_encode。这意味着如果自己写测试脚本复用SCDecoder.m,解码出来的info_bitsK-24个才是真实业务比特,后面24位是CRC校验位——BLER统计时就是靠这24位判断码块是否正确。

3. PSS-SSS联合检测:相关性峰值融合与判决门限

3.1 PSS/SSS序列生成与频域资源映射

PSS用的ZC(Zadoff-Chu)序列根索引在NR里有三个候选值(29、34、37),SSS用的m序列则由PSS索引和小区ID共同决定。工程里发端目录下的pss_generator.m按3GPP TS 38.211第7.4.2节实现,核心参数是频域偏移v = NID2(0到2取值),SSS的加扰序列生成依赖NID1(0到335),所以cellsearch.mat里存的NID1NID2是同步检测的目标值。

联合检测的输送到收端后,接收机先做频偏估计(用PSS的共轭相关峰),再做时偏估计(用SSS的差分相关峰)。但工程里的联合检测.m没走这条串行老路,而是把PSS和SSS的相关结果在时域上直接相加得到联合判决度量:

joint_metric = abs(xcorr(rx_pss, pss_ref)) .^ 2 + abs(xcorr(rx_sss, sss_ref)) .^ 2; [max_val, max_idx] = max(joint_metric); if max_val > detection_threshold sync_success = 1; else sync_success = 0; end

detection_threshold的取值直接影响PSS-SSS联合检测成功率曲线:设低了虚警多,设高了漏检多。这是个牵一发动全身的参数——联合检测成功率统计的是正确检测到NID1NID2的仿真帧数占总帧数的比例,而不是相关峰位置是否精确。你会发现工程里默认阈值取0.75(归一化后的相关峰功率),在TU信道低信噪比(SNR < -2 dB)下漏检率上升很快,这时候二段判决法更稳:先用PSS相关峰粗定界,再在粗定时附近搜索SSS相关峰。

3.2 联合检测成功率的统计口径

联合检测成功率这个指标在MATLAB里不是直接用detect = (NID_est == NID_true)判断的,因为PSS检测错了小区组内ID(NID2)但SSS检测正确的情况也存在。工程里把两者拆开:pss_success单独统计NID2的检测正确率,sss_success单独统计NID1的检测正确率,joint_success要求两个都正确才算同步成功。统计代码在Runme.m里循环体的末尾:

% 每次快照(snapshot)统计 if nid2_est == nid2_true && nid1_est == nid1_true joint_detect_cnt = joint_detect_cnt + 1; end pss_success_rate = pss_detect_cnt / total_snapshots; sss_success_rate = sss_detect_cnt / total_snapshots; joint_success_rate = joint_detect_cnt / total_snapshots;

如果发现仿真输出的joint_success_rate比pss_success_rate低很多,优先怀疑SSS的加扰序列初始化问题——SSS的生成需要NID2作为输入,如果发端和收端的NID2索引对不上,SSS相关峰直接淹没在噪声里,即使在AWGN信道下也解不出来。

3.3 DMRS辅助的信道估计如何影响后续Polar译码

R_hh_dh_viena_DMRS_frontloaded2LRB.mat里存的是维耶纳(Wiener)滤波器系数,用于DMRS(解调参考信号)信道的插值。这套信道估计用在前导符号(front-loaded DMRS)上,估计出的信道频响H直接影响Polar译码前的LLR计算。联合检测输出的时偏估计值timing_offset_est要反馈给信道估计模块做时域补偿,否则OFDM符号的循环前缀错位会在DFT后引入相位旋转——这个相位误差如果不补偿,SC译码器的LLR置信度会系统性偏差,BLER曲线出现平台。

4. TU信道模型与BER/BLER仿真统计的坑

4.1 TU信道系数文件的使用方式

TU_channel_An11_I.binTU_channel_An11_Q.bin是Typical Urban信道模型的实部和虚部时域冲激响应,采样率与仿真带宽有关(工程里是30.72 Msps,对应20 MHz带宽)。读取方式不是MATLAB的load直接导入,而是用freadfloat32格式读入,因为.bin是纯二进制文件不带头:

fid = fopen('TU_channel_An11_I.bin', 'rb'); h_real = fread(fid, 'float32'); fclose(fid); fid = fopen('TU_channel_An11_Q.bin', 'rb'); h_imag = fread(fid, 'float32'); fclose(fid); h_tu = complex(h_real, h_imag);

.mat文件(R_hh_dh_viena_DMRS_frontloaded2LRB.mat)可以直接load加载,里面包含R_hh(维耶纳滤波的相关矩阵)、dh(时延向量)、viena(维耶纳滤波器系数)三个结构体。注意这个MAT文件里的相关矩阵是基于特定SNR点(通常是10 dB)预计算的,如果仿真时信噪比偏差过大,建议按当前SNR重新生成R_hh,否则信道估计误差在高SNR段会反而成为主导噪声。

4.2 BER与BLER的计算差异

BER和BLER在代码里是两套独立的统计逻辑。BER在调制解调符号级统计,把接收的软比特做符号判决后和发端原始比特对比:

ber = sum(rx_bits ~= tx_bits) / length(tx_bits);

BLER统计的粒度是码块(code block),判断依据是CRC校验:

% 译码后做CRC校验 [crc_ok, dec_bits] = crc_check(decoded_info_bits); if ~crc_ok bler_count = bler_count + 1; % 一个码块错误即计数 end bler = bler_count / total_blocks;

这里有个容易踩的坑:如果跑的是高吞吐仿真(比如连续发10000个码块),MATLAB脚本在parfor并行循环里统计BLER时会遇到随机数流问题——每个worker的rng默认独立,但如果不显式设置,不同worker产生的信道衰落可能重复。工程的Runme.m里统一在循环开始前调用了rng(seed + snapshot_idx)确保每个快照的随机种子可复现,这个习惯值得留用。

4.3 仿真参数对Polar编解码性能的影响

Polar码的参数(K, N, CRC长度)在不同SNR点的表现差异很大。工程里默认N=512, K=128, CRC=24,在TU信道下BLER=0.01对应的SNR大约比AWGN信道高2-3 dB。调整参数时要注意frozen_set与码长N是绑定的,如果从512改成1024,需要重新生成极化权重表——cellsearch.mat里的frozenTable是按N=512存储的,盲目改N会直接报维度错误。常用的做法是在系统参数.m里增加一个N_target = 1024的配置,用PolarConstruction.m里的calculate_frozen_set(N_target, K)方法临时生成,但生成时间在N=1024时大约需要20秒,高吞吐仿真前先单独跑一次验证生成逻辑。

5. 验证Polar译码器与同步模块联调的三个自查手段

5.1 用极简AWGN链路隔离同步模块的影响

如果发现联合检测成功率曲线异常,先不要急着调Polar译码参数。把Runme.m里的channel_type改成'AWGN',并把TU_channel_An11_I.bin的读取段注释掉,这样链路里没有多径时延,PSS-SSS相关峰应该是干净的冲击响应。此时统计的joint_success_rate如果仍然不到100%,说明问题出在发端PSS序列生成或收端相关检测的索引映射上,跟信道估计和Polar译码无关。我一般会在SNR=0 dB下跑100帧,要求joint_success_rate不低于95%,否则就检查PSS的频域资源映射位置是否与FFT移位有关。

5.2 软比特LLR的可视化检查

Polar译码前把LLR序列画出来(用plot(LLR_in))是排查译码器冻结位集合错误的最快方法:正常情况下,信息位对应的LLR绝对值明显高于冻结位(因为冻结位不携带信息,LLR应接近0)。如果看到所有LLR分布杂乱无章,说明信道估计或解映射环节出了问题——先查R_hh_dh_viena_DMRS_frontloaded2LRB.mat中的维耶纳系数是否与当前SNR匹配,再查LLR计算时除以噪声方差N0是否用了1/SNR_linear而不是1/(2*SNR_linear)(BPSK和QPSK的LLR公式里噪声方差系数不同)。

5.3 BLER曲线的置信区间确认

仿真输出的BLER曲线在低BLER区(低于1e-3)波动剧烈,因为要统计到足够多的错误块才能让曲线平滑。工程里bler_count的统计位宽是uint32,如果跑到total_blocks为百万级,需要把计数器改成uint64防溢出。经验法则是:total_blocks至少是10 / target_BLER,比如要统计BLER=1e-3,至少发10000个码块。最后检查Runme.m里有没有把skip_first_frames参数设为大于0——前几帧因为信道估计器收敛未稳,BER会偏高,通常跳过前10帧再开始统计最稳妥。

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

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

留言板系统全流程测试方案与实战经验分享

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 23:01:20

深入理解Git:从设计原理到日常排坑的完整指南

不用怀疑&#xff0c;哪怕你已经写了三年代码&#xff0c;把git add .、git commit -m "fix"、git push这三板斧练得滚瓜烂熟&#xff0c;也依然值得静下心来重新认识一遍 Git。这是一个典型的版本控制器&#xff0c;也是整个软件协作体系的基石。我见过太多团队&…

作者头像 李华
网站建设 2026/9/12 22:59:23

大模型Agent Memory机制:原理、架构与实战优化

1. 项目概述&#xff1a;为什么Agent Memory是大模型的核心能力&#xff1f;在大模型应用开发中&#xff0c;Memory机制就像人类大脑的海马体&#xff0c;负责信息的存储、检索和上下文关联。我去年参与的一个客服自动化项目就深刻印证了这一点——当我们将对话记忆从简单的上下…

作者头像 李华
网站建设 2026/9/12 22:57:32

密码验证系统设计与安全实践指南

1. 密码验证的核心逻辑与常见误区密码验证系统是现代数字安全的第一道防线&#xff0c;但开发者常常低估了其复杂性。一个健壮的密码验证机制需要同时处理技术实现和用户体验两个维度。从技术角度看&#xff0c;密码验证不仅仅是简单的字符串比对&#xff0c;还涉及哈希算法、盐…

作者头像 李华
网站建设 2026/9/12 22:52:43

基于粒子群算法的冷热电联供系统优化调度Python实现

简介&#xff1a;面向能源动力与电气工程相关专业学生及研究人员&#xff0c;围绕微型燃气轮机冷热电联供系统的日前优化调度问题展开。程序选取夏季典型日&#xff0c;仅考虑电负荷与冷负荷两类需求&#xff0c;由燃气轮机出力、吸收式制冷与电制冷协同供能&#xff0c;并可向…

作者头像 李华