5G NR PRACH 完整收发收发链路搭建MATLAB对应理论和协议完全手搓前言在5G NR系统中随机接入是终端与基站建立连接的第一步而PRACH物理随机接入信道则是承载前导序列的关键物理信道。为了深入理解PRACH的物理层处理流程我利用MATLAB搭建了一套完整的PRACH收发链路仿真。本文将结合代码详细解读从ZC序列生成、资源映射、时域信号生成到接收端同步、滤波、检测的完整过程并对一些容易被忽视的关键细节进行剖析。一、 参数配置与初始化代码的开头部分定义了仿真所需的核心参数。这里不仅是简单的变量赋值背后反映了5G NR的频域结构。子载波间隔与FFT点数scs 15表示常规数据信道的子载波间隔为15kHzfft_num 2048对应20MHz带宽2048个采样点。这决定了整个系统的时频资源网格的粒度。PRACH专用参数prach_scs 1.25是PRACH前导序列的子载波间隔。注意PRACH的子载波间隔与数据信道不同这是为了支持更远的覆盖距离较窄的子载波意味着更长的符号长度对抗多径时延扩展的能力更强。资源块映射prball 106表示20MHz带宽下可用的RB总数Nrb 6表示PRACH占用了6个RB即72个数据子载波但实际上ZC序列长度为839远远大于72。这里的映射逻辑将在后续章节重点分析。二、 PRACH发端处理1. ZC序列生成与循环移位在之前的博客详细介绍过如下链接PRACH 前导序列生成详解与Matlab实现PRACH前导的核心是ZCZadoff-Chu序列它具有良好的恒幅零自相关特性。x_root exp(-j*pi*u(u_idx)*i_u.*(i_u 1)/L_RA); preamble_zc x_root(mod(nCv(m),L_RA)1);根序列根据协议选择的根索引u生成基础ZC序列。循环移位通过Cv v*Ncs生成不同的前导序列。不同的Preamble_ID对应不同的循环移位量。本例中m5对应ID4相当于给基础序列施加了一个循环移位。这种设计使得同一个根序列可以通过不同的循环移位生成多个正交的前导序列从而在同一时频资源上区分不同的用户。2. DFT预编码代码中有一个容易被忽略但非常重要的步骤fprintf(3 preamble_zc 做DFT处理\n); preamble_zcdft fft(preamble_zc);在5G NR中PRACH的频域信号并非直接将ZC序列映射到子载波而是先对ZC序列做一次DFT。这里需要结合“资源映射”来理解输入时域的ZC序列长度839。输出频域的preamble_zcdft也是长度839。目的实际上这相当于将时域ZC序列变换到频域形成一种“频域”前导序列。后续的资源映射实际上是将这个“频域”序列长度为839的复数序列映射到839个PRACH子载波上。这与LTE中PRACH的处理逻辑类似本质上是将前导序列定义在PRACH的频域上。3. PRACH资源映射核心难点这是整个代码中最具技巧性的部分也是理解PRACH频域结构的关键。由于数据子载波间隔15kHz与PRACH子载波间隔1.25kHz不同两者之间存在12倍的整数倍关系sc_vs_rachsc 12。这意味着在20MHz的带宽中PRACH子载波的密度是数据子载波的12倍。% 计算prach占用的首个rb距离中心频点的距离单位是sc k1 (PRBSet(1)-prball/2)*rb_sc; % 协议规定可以对照38.211协议,注意这里的kbar的单位是rach_sc kbar 7; % 计算在全带宽都当作rach的情况下第一个子载波距离中心频点的位置 frist sc_vs_rachsc * k1 kbar; % 计算在全带宽都当作rach的情况下中心频点的位置 all_band_prachsc_cen (prball * rb_sc * sc_vs_rachsc) /2; % 这样就计算出来实际的prach频域的位置索引 k n all_band_prachsc_cen frist;映射原理假设整个带宽106个RB都是由PRACH子载波组成的。那么总的PRACH子载波数为 106 * 12 * 12 15264 个。代码先计算出PRACH实际占用的起始位置frist然后计算出中心频点位置all_band_prachsc_cen最后计算出长度为839的序列在15264个PRACH子载波中的绝对位置索引 k。零填充最后通过 insert0 左右补零得到长度 fft_num * sc_vs_rachsc 2048 * 12 24576 的频域信号。这个长度恰好等于1ms1个子帧内采样点数24576为后续的IFFT奠定了基础。4. OFDM调制与添加CP/GPprach_time ifft(ifftshift(all_prach_freq_data)); preamble_cp [prach_time(end-prach_1ms_cp1:end), prach_time, zeros(1,prach_1ms_gp)];IFFT将频域数据变换回时域。ifftshift用于将频域数据从双边带表示调整为IFFT输入所需的顺序。添加CP循环前缀用于抵抗多径时延造成的符号间干扰。添加GP保护间隔GP用于对抗信号传播时延确保不同距离的用户的前导序列不会互相干扰。三、 信道与接收端处理1. 频谱搬移核心难点接收端首先要去除CP。但此时的数据还包含整个带宽的信号。PRACH只占用了带宽中的一小部分。为了后续处理需要将PRACH占用的频段搬移到零中频。dist start_rb_offset*12 - prball*6 Nrb * 6 ; nn 0:1:length(data_complex_removecp)-1; phase exp(-j*2*pi*dist*nn/fft_num); data_complex_removecp data_complex_removecp .* phase;为什么需要搬移如果不做搬移PRACH信号位于高频段而后续需要对其进行低通滤波和降采样。将信号搬移到零中频是为了让PRACH信号“落”在滤波器的通带内方便滤波器将其提取出来同时滤除数据信道带来的干扰。搬移原理通过乘以一个复指数信号相当于在频域上对信号进行平移使得PRACH的中心频率移动到0Hz。2. 抗混叠滤波关键步骤降采样之前为什么要经过低通滤波coef fir1(norder, cutoff/Fs, low); prach_filtered filter(coef, 1, data_complex_removecp); time_down resample(prach_filtered, 1, downsampled);采样定理的约束接收端的初始采样率是30.72MHz对应20MHz带宽。而PRACH的带宽远小于此。如果我们直接将采样率降低24倍根据奈奎斯特采样定理采样率降低后频域信号会发生周期延拓。如果原信号中高于降采样后奈奎斯特频率Fs_new/2的成分存在就会发生频谱混叠导致信号失真。滤波的作用低通滤波器的作用是“抗混叠”。它的截止频率设置为降采样后的奈奎斯特频率0.64MHz确保只保留PRACH信号所在的低频部分将高频的数据信道信号和噪声滤除。然后进行降采样就能在不发生混叠的情况下将采样率降低到1.28MHz大大减少了后续FFT的计算量。3. 频域数据提取降采样后采样点数为1024。而我们的ZC序列长度是839。需要从1024个点中正确提取出这839个频域样点。N 1024; k 7; % 协议规定的偏移 N_zchalf Nrb*12*K/2; prach_freq downfft(kN-N_zchalf1:N); prach_freq(len1:L_RA) downfft(1:kL_RA-N_zchalf);4. 相关检测与Preamble_ID识别在之前的博客中想写介绍过如下链接PRACH前导序列检测详解与Matlab实现简易版接收端将提取出的频域序列与本地根序列的DFT共轭相乘然后进行IFFT得到时域相关峰。re prach_freq .* conj(x_root_fft); re_idft ifft(re);相关检测原理这实际上是一个频域匹配滤波的过程。由于ZC序列具有良好的自相关特性当接收信号与本地序列匹配时相关峰会出现。窗检测代码最后绘制了相关峰图并画出了不同循环移位窗的边界。由于我们发送的是m5即第5个循环移位所以相关峰应该出现在第5个窗内对应Preamble_ID4。通过寻找峰值所在窗基站就能判断出终端使用了哪个前导序列。四、 相关仿真结果五、 总结通过这次仿真我们完整地复现了5G NR PRACH的物理层处理流程。其中几个关键点值得再次强调多采样率转换PRACH子载波1.25kHz与数据子载波15kHz之间的12倍关系是资源映射和降采样的根源。频域资源映射先进行DFT预编码再将长度为839的频域序列精确映射到15264个PRACH子载波中的特定位置并通过零填充扩展到24576点完成IFFT。接收端抗混叠降采样前的低通滤波是确保信号无失真还原的必要步骤它基于奈奎斯特采样定理防止了频谱混叠对PRACH前导检测的干扰。循环移位的正交性通过不同的循环移位生成多个正交的前导序列这是5G NR在同一时频资源上支持多用户随机接入的关键机制。通过代码仿真可以将抽象的协议文本转化为直观的波形和频谱图这对于理解5G NR物理层的设计思想和工程实现有着极大的帮助。希望这篇博客能对大家理解PRACH有所帮助。 如果本文对你有帮助欢迎✅ 关注我的CSDN第一时间收到系列更新✅ 关注公众号「手搓物理层」回复“PRACH”获取本文完整MATLAB 代码包调试脚本
5G NR PRACH 完整收发收发链路搭建:MATLAB对应理论和协议完全手搓
5G NR PRACH 完整收发收发链路搭建MATLAB对应理论和协议完全手搓前言在5G NR系统中随机接入是终端与基站建立连接的第一步而PRACH物理随机接入信道则是承载前导序列的关键物理信道。为了深入理解PRACH的物理层处理流程我利用MATLAB搭建了一套完整的PRACH收发链路仿真。本文将结合代码详细解读从ZC序列生成、资源映射、时域信号生成到接收端同步、滤波、检测的完整过程并对一些容易被忽视的关键细节进行剖析。一、 参数配置与初始化代码的开头部分定义了仿真所需的核心参数。这里不仅是简单的变量赋值背后反映了5G NR的频域结构。子载波间隔与FFT点数scs 15表示常规数据信道的子载波间隔为15kHzfft_num 2048对应20MHz带宽2048个采样点。这决定了整个系统的时频资源网格的粒度。PRACH专用参数prach_scs 1.25是PRACH前导序列的子载波间隔。注意PRACH的子载波间隔与数据信道不同这是为了支持更远的覆盖距离较窄的子载波意味着更长的符号长度对抗多径时延扩展的能力更强。资源块映射prball 106表示20MHz带宽下可用的RB总数Nrb 6表示PRACH占用了6个RB即72个数据子载波但实际上ZC序列长度为839远远大于72。这里的映射逻辑将在后续章节重点分析。二、 PRACH发端处理1. ZC序列生成与循环移位在之前的博客详细介绍过如下链接PRACH 前导序列生成详解与Matlab实现PRACH前导的核心是ZCZadoff-Chu序列它具有良好的恒幅零自相关特性。x_root exp(-j*pi*u(u_idx)*i_u.*(i_u 1)/L_RA); preamble_zc x_root(mod(nCv(m),L_RA)1);根序列根据协议选择的根索引u生成基础ZC序列。循环移位通过Cv v*Ncs生成不同的前导序列。不同的Preamble_ID对应不同的循环移位量。本例中m5对应ID4相当于给基础序列施加了一个循环移位。这种设计使得同一个根序列可以通过不同的循环移位生成多个正交的前导序列从而在同一时频资源上区分不同的用户。2. DFT预编码代码中有一个容易被忽略但非常重要的步骤fprintf(3 preamble_zc 做DFT处理\n); preamble_zcdft fft(preamble_zc);在5G NR中PRACH的频域信号并非直接将ZC序列映射到子载波而是先对ZC序列做一次DFT。这里需要结合“资源映射”来理解输入时域的ZC序列长度839。输出频域的preamble_zcdft也是长度839。目的实际上这相当于将时域ZC序列变换到频域形成一种“频域”前导序列。后续的资源映射实际上是将这个“频域”序列长度为839的复数序列映射到839个PRACH子载波上。这与LTE中PRACH的处理逻辑类似本质上是将前导序列定义在PRACH的频域上。3. PRACH资源映射核心难点这是整个代码中最具技巧性的部分也是理解PRACH频域结构的关键。由于数据子载波间隔15kHz与PRACH子载波间隔1.25kHz不同两者之间存在12倍的整数倍关系sc_vs_rachsc 12。这意味着在20MHz的带宽中PRACH子载波的密度是数据子载波的12倍。% 计算prach占用的首个rb距离中心频点的距离单位是sc k1 (PRBSet(1)-prball/2)*rb_sc; % 协议规定可以对照38.211协议,注意这里的kbar的单位是rach_sc kbar 7; % 计算在全带宽都当作rach的情况下第一个子载波距离中心频点的位置 frist sc_vs_rachsc * k1 kbar; % 计算在全带宽都当作rach的情况下中心频点的位置 all_band_prachsc_cen (prball * rb_sc * sc_vs_rachsc) /2; % 这样就计算出来实际的prach频域的位置索引 k n all_band_prachsc_cen frist;映射原理假设整个带宽106个RB都是由PRACH子载波组成的。那么总的PRACH子载波数为 106 * 12 * 12 15264 个。代码先计算出PRACH实际占用的起始位置frist然后计算出中心频点位置all_band_prachsc_cen最后计算出长度为839的序列在15264个PRACH子载波中的绝对位置索引 k。零填充最后通过 insert0 左右补零得到长度 fft_num * sc_vs_rachsc 2048 * 12 24576 的频域信号。这个长度恰好等于1ms1个子帧内采样点数24576为后续的IFFT奠定了基础。4. OFDM调制与添加CP/GPprach_time ifft(ifftshift(all_prach_freq_data)); preamble_cp [prach_time(end-prach_1ms_cp1:end), prach_time, zeros(1,prach_1ms_gp)];IFFT将频域数据变换回时域。ifftshift用于将频域数据从双边带表示调整为IFFT输入所需的顺序。添加CP循环前缀用于抵抗多径时延造成的符号间干扰。添加GP保护间隔GP用于对抗信号传播时延确保不同距离的用户的前导序列不会互相干扰。三、 信道与接收端处理1. 频谱搬移核心难点接收端首先要去除CP。但此时的数据还包含整个带宽的信号。PRACH只占用了带宽中的一小部分。为了后续处理需要将PRACH占用的频段搬移到零中频。dist start_rb_offset*12 - prball*6 Nrb * 6 ; nn 0:1:length(data_complex_removecp)-1; phase exp(-j*2*pi*dist*nn/fft_num); data_complex_removecp data_complex_removecp .* phase;为什么需要搬移如果不做搬移PRACH信号位于高频段而后续需要对其进行低通滤波和降采样。将信号搬移到零中频是为了让PRACH信号“落”在滤波器的通带内方便滤波器将其提取出来同时滤除数据信道带来的干扰。搬移原理通过乘以一个复指数信号相当于在频域上对信号进行平移使得PRACH的中心频率移动到0Hz。2. 抗混叠滤波关键步骤降采样之前为什么要经过低通滤波coef fir1(norder, cutoff/Fs, low); prach_filtered filter(coef, 1, data_complex_removecp); time_down resample(prach_filtered, 1, downsampled);采样定理的约束接收端的初始采样率是30.72MHz对应20MHz带宽。而PRACH的带宽远小于此。如果我们直接将采样率降低24倍根据奈奎斯特采样定理采样率降低后频域信号会发生周期延拓。如果原信号中高于降采样后奈奎斯特频率Fs_new/2的成分存在就会发生频谱混叠导致信号失真。滤波的作用低通滤波器的作用是“抗混叠”。它的截止频率设置为降采样后的奈奎斯特频率0.64MHz确保只保留PRACH信号所在的低频部分将高频的数据信道信号和噪声滤除。然后进行降采样就能在不发生混叠的情况下将采样率降低到1.28MHz大大减少了后续FFT的计算量。3. 频域数据提取降采样后采样点数为1024。而我们的ZC序列长度是839。需要从1024个点中正确提取出这839个频域样点。N 1024; k 7; % 协议规定的偏移 N_zchalf Nrb*12*K/2; prach_freq downfft(kN-N_zchalf1:N); prach_freq(len1:L_RA) downfft(1:kL_RA-N_zchalf);4. 相关检测与Preamble_ID识别在之前的博客中想写介绍过如下链接PRACH前导序列检测详解与Matlab实现简易版接收端将提取出的频域序列与本地根序列的DFT共轭相乘然后进行IFFT得到时域相关峰。re prach_freq .* conj(x_root_fft); re_idft ifft(re);相关检测原理这实际上是一个频域匹配滤波的过程。由于ZC序列具有良好的自相关特性当接收信号与本地序列匹配时相关峰会出现。窗检测代码最后绘制了相关峰图并画出了不同循环移位窗的边界。由于我们发送的是m5即第5个循环移位所以相关峰应该出现在第5个窗内对应Preamble_ID4。通过寻找峰值所在窗基站就能判断出终端使用了哪个前导序列。四、 相关仿真结果五、 总结通过这次仿真我们完整地复现了5G NR PRACH的物理层处理流程。其中几个关键点值得再次强调多采样率转换PRACH子载波1.25kHz与数据子载波15kHz之间的12倍关系是资源映射和降采样的根源。频域资源映射先进行DFT预编码再将长度为839的频域序列精确映射到15264个PRACH子载波中的特定位置并通过零填充扩展到24576点完成IFFT。接收端抗混叠降采样前的低通滤波是确保信号无失真还原的必要步骤它基于奈奎斯特采样定理防止了频谱混叠对PRACH前导检测的干扰。循环移位的正交性通过不同的循环移位生成多个正交的前导序列这是5G NR在同一时频资源上支持多用户随机接入的关键机制。通过代码仿真可以将抽象的协议文本转化为直观的波形和频谱图这对于理解5G NR物理层的设计思想和工程实现有着极大的帮助。希望这篇博客能对大家理解PRACH有所帮助。 如果本文对你有帮助欢迎✅ 关注我的CSDN第一时间收到系列更新✅ 关注公众号「手搓物理层」回复“PRACH”获取本文完整MATLAB 代码包调试脚本