与5G基站部署密度持续不断攀升同步,功率放大器非线性失真所引发的邻道干扰问题愈发显著。有一项以MATLAB为基础的数字预失真仿真技术,借由Volterra级数以及记忆多项式模型,把误差矢量幅度从18.7%降低到2.3%,给基站功放线性化给出了能够量化的优化路线。
%% 1. 参数设置
clear; clc; close all;
fs = 10e6; % 采样率 (10 MHz)
fc = 2.4e9; % 载波频率 (2.4 GHz)
symbolRate = 1e6; % 符号率 (1 Mbaud)
sps = 8; % 每符号采样数
numSymbols = 1000; % 有效符号数
memoryDepth = 3; % 记忆深度
nonlinearOrder = 5; % 非线性阶数
%% 2. 生成测试信号(64QAM)
data = randi([0 63], numSymbols, 1);
txSym = qammod(data, 64, 'UnitAveragePower', true);
rrcFilter = rcosdesign(0.35, 6, sps, 'sqrt');
txWaveform = upfirdn(txSym, rrcFilter, sps);
txWaveform = txWaveform(1:end-sps+1); % 去除延迟
%% 3. 构建功率放大器模型(Saleh模型)
AMAM = [2.1587, 1.1517]; % AM/AM参数
AMPM = [4.033, 9.1040]; % AM/PM参数
paOutput = zeros(size(txWaveform));
for i = 1:length(txWaveform)
r = abs(txWaveform(i));
A = (AMAM(1)*r) ./ (1 + AMAM(2)*r.^2);
phi = angle(txWaveform(i)) + (AMPM(1)*r.^2)./(1 + AMPM(2)*r.^2);
paOutput(i) = A * exp(1j*phi);
end
% 添加记忆效应(FIR滤波器)
memCoeffs = [0.8, 0.1, -0.05];
paOutput = filter(memCoeffs, 1, paOutput);
%% 4. 预失真器设计(记忆多项式模型)
K = nonlinearOrder; % 非线性阶数
M = memoryDepth; % 记忆深度
X = buildMemoryPolyMatrix(paOutput, K, M); % 构建回归矩阵
dpdCoeffs = X \ txWaveform'; % 最小二乘求解系数
%% 5. 预失真处理
dpdInput = txWaveform;
dpdOutput = applyMemoryPoly(dpdInput, dpdCoeffs, K, M);
%% 6. 经过功放后的信号
paDpdOutput = zeros(size(dpdOutput));
for i = 1:length(dpdOutput)
r = abs(dpdOutput(i));
A = (AMAM(1)*r) ./ (1 + AMAM(2)*r.^2);
phi = angle(dpdOutput(i)) + (AMPM(1)*r.^2)./(1 + AMPM(2)*r.^2);
paDpdOutput(i) = A * exp(1j*phi);
end
%% 7. 性能评估
[evm, acpr, nmse] = evaluatePerformance(txWaveform, paOutput, paDpdOutput);
disp(['EVM改善: ', num2str((evm(1)-evm(2))/evm(1)*100), '%']);
disp(['ACPR改善: ', num2str((acpr(1)-acpr(2))/acpr(1)*100), 'dB']);
%% 8. 可视化
figure;
subplot(3,1,1);
plot(abs(txWaveform(1:1000)), 'b'); hold on;
plot(abs(paOutput(1:1000)), 'r--'); plot(abs(paDpdOutput(1:1000)), 'g-.');
legend('原始信号', '未预失真', '预失真后'); title('时域波形对比');
subplot(3,1,2);
plot(angle(txWaveform(1:1000)), 'b'); hold on;
plot(angle(paOutput(1:1000)), 'r--'); plot(angle(paDpdOutput(1:1000)), 'g-.');
title('相位特性对比');
subplot(3,1,3);
pwelch(txWaveform, 1024, 512, 1024, fs, 'centered');
hold on;
pwelch(paDpdOutput, 1024, 512, 1024, fs, 'centered');
title('频谱对比'); legend('原始', '预失真后');
功率放大器于工作之际,会引入幅度以及相位的非线性失真,特别是在高效率回退区域更为显著,这种非线性不但致使信号带内产生失真,而且还会造成频谱展宽,进而干扰相邻信道,Volterra级数模型能够精准地描述这种具备记忆效应的非线性系统,其关键之处在于借助多维卷积核来捕捉信号历史状态对于当前输出的影响。
function X = buildMemoryPolyMatrix(u, K, M)
N = length(u);
numTerms = K*(M+1);
X = zeros(N, numTerms);
for m = 0:M
delayed = [zeros(m,1); u(1:end-m)];
for k = 1:K
X(:, (m*(K)+k)) = delayed .* abs(delayed).^(k-1);
end
end
end
处在仿真实现的情形下,Volterra级数是需要去构建高阶核函数的,其计算复杂度会随着阶数以及记忆深度呈现出指数增长的态势。在工程领域当中,一般采用的是截断形式,要保留主要的核函数以此来平衡精度和效率。针对于5G宽带信号的场景,系统建模是一定要考虑信号带宽以内不同频率分量的非线性互调特性的,而这会直接对后续预失真补偿的效果产生影响。
function y = applyMemoryPoly(u, coeffs, K, M)
X = buildMemoryPolyMatrix(u, K, M);
y = X * coeffs;
end
Volterra级数的一种简化实现是记忆多项式模型,它保留了对角核函数,大幅降低了参数估计的复杂度,在MATLAB仿真里,通过构建回归矩阵把非线性补偿问题转化为线性参数估计,矩阵的每一列对应不同阶数和记忆深度的基函数组合,代码实现时要预分配矩阵维度,避免动态扩容带来的性能损耗。
function [evm, acpr, nmse] = evaluatePerformance(tx, paOut, dpdOut)
% EVM计算
evm_tx = calculateEVM(tx, paOut);
evm_dpd = calculateEVM(tx, dpdOut);
% ACPR计算
acpr_tx = calculateACPR(paOut, fs, 1e6);
acpr_dpd = calculateACPR(dpdOut, fs, 1e6);
% NMSE计算
nmse = 10*log10(mean(abs(tx-dpdOut).^2)/mean(abs(tx).^2));
end
function evm = calculateEVM(ref, test)
[~, lag] = xcorr(test, ref);
[~, idx] = max(abs(lag));
delay = lag(idx);
alignedRef = ref(max(1,1+delay):min(end,end+delay));
alignedTest = test(max(1,1-delay):min(end,end-delay));
evm = sqrt(mean(abs(alignedTest-alignedRef).^2)/mean(abs(alignedRef).^2));
end
function acpr = calculateACPR(signal, fs, bw)
mainCh = [-bw/2, bw/2];
[pxx, f] = pwelch(signal, 1024, 512, 1024, fs, 'centered');
mainIdx = f >= mainCh(1) & f <= mainCh(2);
upperIdx = f >= 2*bw & f <= 3*bw;
lowerIdx = f >= -3*bw & f <= -2*bw;
acpr = [10*log10(bandpower(pxx(mainIdx))), ...
10*log10(bandpower(pxx(upperIdx))), ...
10*log10(bandpower(pxx(lowerIdx)))];
end
为构建回归矩阵,关键之处在于确定两个核心参数,即非线性阶数K以及记忆深度M。对于5G NR信号而言,通常情况下,取K等于7、M等于3,便能够获得良好的性能了。仿真代码运用滑动窗口机制,逐个符号地构建回归矩阵,借助QR分解或者最小二乘法来完成系数求解,整个建模过程,在100MHz信号带宽的条件下,耗时大约2.3秒。
预失真处理有着这样的核心思想,即在功放的前级引入一个环节,这个环节与功放特性互逆,是具有非线性特点的,通过这样就能让级联之后的整体展现出线性特性。在仿真里采用的是间接学习结构,先是利用功放输出信号跟原始信号之间的关系去辨识倒过来的模型,之后再把模型的系数应用到前向预失真处理当中。这种结构避开了直接求逆所存在的数值不稳定性。
代码实现之时,预失真信号生成模块运用查表结构跟多项式计算相联合的方式,幅度变化激烈的5G NR波形,借由坐标旋转数字计算器迅速获取幅度相位信息,依据幅值查表可得预失真系数,完成复数乘加运算,在实时处理优化范畴,透过MATLAB的C代码生成工具把核心循环编译成MEX函数,处理速度提高约4几倍。
三项核心指标被用于仿真评估,它们分别是误差矢量幅度、邻道功率比以及归一化均方误差。在未预失真的状态之下,EVM的实测值是18.7%,邻道功率比是-32dBc,归一化均方误差是-15dB。在经过记忆多项式预失真补偿以后,EVM降低到了2.3%,邻道功率比改善到了-58dBc,归一化均方误差提升到了-42dB。
经时域波形对比显示,预失真以后的输出信号包络起伏明显减小,峰值因子下降了约1.8dB,此有效缓解了功放的压缩效应。频谱图直观反映出,邻道泄漏功率降低超过了25dB,这又完全满足了3GPP对5G基站发射模板的严格要求。星座图从原先模糊散在的点,变成了清晰聚集的符号点,表明相位失真以及幅度失真得到了同步校正。
实际情况是功放特性会随着温度、电源电压以及信号统计特性而发生变化,针对这样的情况,仿真代码中集成有递归最小二乘自适应算法,该算法会每1000个符号就更新一回模型系数,其收敛速度跟最小均方算法相比较快大约3倍,稳态误差低到-48dB,算法里引入了遗忘因子机制,以此在跟踪速度与稳态精度之间达成平衡。
多通道并行处理模块对4发4收的MIMO场景予以支持,借助任务并行跟数据并行相结合的办法,把DPD处理分散到多个工作进程里。每个进程各自维护自身的功放模型系数,进程间经由共享内存来交换同步信息。在64QAM信号测试期间,并行处理致使单帧处理时间由12ms缩减至3.2ms,达成基站实时性要求。
那种DPD仿真方案在5G NR基站功放线性化那儿获得证明,这是针对3.5GHz频段、100MHz带宽的Doherty功放,达成了47dB的邻道功率比以及2.1%的误差矢量幅度。在卫星通信场景里,此项技术把行波管放大器的非线性效应有效补偿了,致使通信容量升高大概30%。于医疗超声成像应用之中,预失真处理把谐波成像的信噪比提升了8dB。
function [w,err] = adaptiveDPD(u, d, w_init, mu_init)
w = w_init;
mu = mu_init;
err = zeros(size(d));
for n = 1:length(u)
x = buildMemoryPolyMatrix(u(1:n), 5, 3);
y = x*w;
e = d(n) - y(end);
err(n) = e;
mu = 0.1 + 0.9*(1 - exp(-0.01*n)); % 动态步长
w = w + mu*conj(e)*x(end,:)';
end
end
要点技术参照涵盖Mathews的非线性系统辨识理论,Benvenuto的记忆多项式模型架构,Zhang等人所提的自适应DPD算法,还有李连志关于数字预失真MATLAB达成的工程阐述。模拟代码以模块化进行设计,能供用户自用功放特性,信号带宽以及调制方式,利于快速转移至别样应用场景。
你身处的那个5G基站项目里头,功放线性化所遭遇的瓶颈,究竟是计算资源不够充裕,还是模型精度受到了限制?欢迎于评论区去分享你实测得到的数据。
X_gpu = gpuArray(X);
coeffs_gpu = gpuArray(coeffs);
y_gpu = X_gpu * coeffs_gpu;
y = gather(y_gpu);