该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
3、STR_parallel_OMwithPF_delay
%---本程序为增加频域滤波的O&M并行定时恢复环路----------------%
%---采样点的调整可以参考论文3.1.2节。
%---定时相偏校正原理:在频域匹配滤波之后乘以相应的对消旋转因子纠正----%
%---定时频偏校正原理:根据mNCO输出的控制信号进行采样点的删除或保持:
%-----需要注意的是,不仅需要对输入并行数据进行删除或保持,而且对重叠数据也需要删除或保持----%
%-----其中,skew_withPF用于控制对输入并行数据进行采样点的删除或保持,skew_withPF>0表示向后偏移,删除一个输入数据;skew_withPF<0表示向前偏移,将上一时刻最后一个数据保持一个时刻;
%-----sortInd_withPF用于控制对重叠数据进行删除或保持,若sortInd_withPF=-1,则需要删除重叠数据中的第一个数据;sortInd_withPF=1,则保持上一时刻240路重叠数据的前一个数据,dataKeep_withPF用于存储改值;
%---输入参数说明:---------------%
%---dataIn: 串行数据输入--------%
%---rxSRRC_fk: SRRC的频域系数--------%
%---preFilter_fk: 预滤波器的频域系数--------%
%---coefNum: SRRC系数个数--------%
%---prefilter_work:预滤波器是否工作------%
function [rxSTR,timingPhase_observation]= test_delay(dataIn,FFTNum,parallelNum,estLen,upSamping,rxSRRC_fk,preFilter_fk,coefNum,prefilter_work)
global g_STATE
persistent ReservedData_withPF dataKeep_withPF timingPhase_withPF;
persistent timing_err_withPF skew_withPF sortInd_withPF;
persistent delayPhase_reg delay_timingPhase delayM_reg delaySkew_reg delayM delaySkew;
persistent exp_func1 exp_func2;
persistent delay_reg1 delay_reg2 delay_reg3 delay_reg4;
persistent reg1_out reg2_out reg3_out reg4_out;
g_STATE = 0;
if g_STATE == 0
timing_err_withPF = 0; % 定时误差估计值初始化
skew_withPF = 0; % 串行数据读取偏移值,skew_withPF>0表示向后偏移一个点,skew_withPF>0表示向前偏移一个点
sortInd_withPF = 0; % 0--正常读取,1--保持一个采样点,-1--删除一个采样点
ReservedLen = FFTNum-parallelNum; % 重叠长度
ReservedData_withPF = zeros(ReservedLen,1); % 重叠保留数组初始化
dataKeep_withPF = 0; % 寄存上一时刻重叠数据的最后一个值
timingPhase_withPF = 0; % 定时相位跟踪值
STR_lpf_OMwithPF([]);
mNCO_OMwithPF([]);
% test:纠正定时相偏延迟一拍-----block
delayblock = 2;
delayPhase_reg = zeros(1,delayblock);
delayM_reg = zeros(1,delayblock);
delaySkew_reg = zeros(1,delayblock);
delay_timingPhase = 0;
delayM = 0;
delaySkew = 0;
exp_func1 = zeros(FFTNum/2,1);
exp_func2 = zeros(FFTNum/2,1);
% LPF and mNCO deay
delayClk = 6;
delay_reg1 = zeros(1,delayClk);
delay_reg2 = zeros(1,delayClk);
delay_reg3 = zeros(FFTNum/2,delayClk);
delay_reg4 = zeros(FFTNum/2,delayClk);
reg1_out = 0;
reg2_out = 0;
reg3_out = zeros(FFTNum/2,1);
reg4_out = zeros(FFTNum/2,1);
end
g_STATE = 1;
%% 参数初始化
interval = estLen/(parallelNum); % O&M算法在并行结构下进行一次估计需要的符号数
rxSTR_parallel = zeros(FFTNum,1); % 经过保持、删除或正常读取的16路并行数据
rxpreFilter = zeros(parallelNum,round(length(dataIn)/parallelNum)); % 预滤波器并行输出
for idx = 1:round(length(dataIn)/parallelNum)-10
%% 根据mNCO输出的控制信号进行采样点的删除、保持
% mod(idx,interval)的原因: O&M算法每进行一次定时误差估计需要interval个并行数据,而数据点的删除 或 保持只在跳变的第一个时刻
% sortInd_withPF用于控制对重叠数据的删除或保持
% skew_withPF用于控制对输入数据进行删除或保持
if(reg1_out == -1 && mod(idx,interval)== delayClk) %删除多余采样点,删除循环前缀的第一个,
ReservedData_withPF = [ReservedData_withPF(2:end);dataIn((idx-1)*parallelNum + reg2_out)];
elseif((reg1_out == 1 && mod(idx,interval)== delayClk))
ReservedData_withPF = [dataKeep_withPF;ReservedData_withPF(1:end-1)]; %保持保留数据的最后一个
end
% 叠加循环前缀
rxData_parallel = [ReservedData_withPF;dataIn((idx-1)*parallelNum+1+reg2_out:idx*parallelNum+reg2_out).'];
% 计算当前时刻循环前缀
dataKeep_withPF = rxData_parallel(FFTNum-parallelNum);
ReservedData_withPF = rxData_parallel(parallelNum+1:FFTNum);
% FFT变换到频域
rxData_FFT = fft(rxData_parallel,FFTNum);
%% 并行匹配滤波器
rxSRRC_parallel = rxData_FFT.*rxSRRC_fk.';
%% 频域纠正定时相偏---见论文3.1.1节中的公式
rxSTR_parallel(1:FFTNum/2) = rxSRRC_parallel(1:FFTNum/2).*reg3_out;
rxSTR_parallel(FFTNum/2+1:FFTNum) = rxSRRC_parallel(FFTNum/2+1:FFTNum).*reg4_out;
%% 频域预滤波
rxpreFilter_parallel = rxSTR_parallel.*preFilter_fk.';
%% 预滤波输出进行IFFT用于定时误差估计
rxpreFilter_parallel_tmp = ifft(rxpreFilter_parallel,FFTNum);
rxpreFilter(:,idx) = rxpreFilter_parallel_tmp(FFTNum+1-parallelNum-(coefNum-1)/2:FFTNum-(coefNum-1)/2);
%% 定时相位校正后进行IFFT得到解调数据
% STR输出
rxSTR_parallel_tmp = ifft(rxSTR_parallel,FFTNum);
rxSTR(:,idx) = rxSTR_parallel_tmp(FFTNum+1-parallelNum-(coefNum-1)/2:FFTNum-(coefNum-1)/2); % 取中间数据作为输出
%% O&M算法--每interval次估计一次
if(mod(idx,interval) == 0)
% O&M 算法用于定时误差估计
if(prefilter_work == 1)
timingErr_dataIn = rxpreFilter(:,idx-interval+1:idx); % 预滤波器输出--->估计定数误差
else
timingErr_dataIn = rxSTR(:,idx-interval+1:idx); % 无预滤波
end
% O&M算法的并行结构
timing_err_withPF = timingErrEst_OM_block(timingErr_dataIn,upSamping);
% 环路滤波器
STR_lpfOut = STR_lpf_OMwithPF(timing_err_withPF);
% mNCO
[timingPhase_withPF,skew_withPF,sortInd_withPF] = mNCO_OMwithPF(STR_lpfOut);
timingPhase_observation(idx) = timingPhase_withPF;
% delta 延迟一拍
delayPhase_reg = [delayPhase_reg(2:end) timingPhase_withPF];
delay_timingPhase = delayPhase_reg(1);
% 计算 exp 指数
exp_func1 = exp(1i*2*pi*delay_timingPhase*(0:FFTNum/2-1)/FFTNum).';
exp_func2 = exp(-1i*2*pi*delay_timingPhase*(FFTNum/2:-1:1)/FFTNum).';
% 为了保证跳点指示信号与exp指数对齐,将跳点指示信号打一拍
delayM_reg = [delayM_reg(2:end) sortInd_withPF];
delayM = delayM_reg(1);
delaySkew_reg = [delaySkew_reg(2:end) skew_withPF];
delaySkew = delaySkew_reg(1);
end
% LPF and mNCO delay : reg1->sortInd,reg2->skew_withPF,reg3->exp_func1,reg4->exp_func2
delay_reg1 = [delay_reg1(2:end) delayM];
reg1_out = delay_reg1(1);
% if(delayM == -1)
% disp('x');
% end
delay_reg2 = [delay_reg2(2:end) delaySkew];
reg2_out = delay_reg2(1);
delay_reg3 = [delay_reg3(:,2:end) exp_func1];
reg3_out = delay_reg3(:,1);
delay_reg4 = [delay_reg4(:,2:end) exp_func2];
reg4_out = delay_reg4(:,1);
end
timingPhase_observation = nonzeros(timingPhase_observation);
end
3、testbench-om
clear all;
load srrc_prefilter_coef.mat
load channel.mat
% 增加预滤波----O&M算法
FFTNum = 128; % FFT点数=128
upSamping = 4; % 上采样倍数=4
parallelNum = 8; % 并行路数,可选择
estLen = 256; % 并行O&M算法分段长度
channel_select = 1; %选择testbench的仿真信道:信道1:EsNo=100dB,ppm=20:信道2:EsNo=5dB,ppm=20;
% STR输入选择
if(channel_select == 1)
dataIn = chOut_100dB_20ppm;
else
dataIn = chOut_5dB_20ppm;
end
%% 并行STR
prefilter_work = 1; % 预滤波器工作指示:1表示预滤波工作,0表示预滤波不工作
[rxSTR_withPF,timingPhase_withPF] = STR_parallel_OMwithPF(dataIn,FFTNum,parallelNum,estLen,upSamping,srrc_fk,prefilter_fk,coefNum,prefilter_work);
%% When FPGA delay is considered
[rxSTR_withPF_delay,timingPhase_withPF_delay] = STR_parallel_OMwithPF_delay(dataIn,FFTNum,parallelNum,estLen,upSamping,srrc_fk,prefilter_fk,coefNum,prefilter_work);
%% 输出结果观测
% 输出定时误差跟踪值
figure;plot(timingPhase_withPF,'r.'); hold on; plot(timingPhase_withPF_delay,'b.');
xlabel('估计块');ylabel('定时偏差 \mu');
% 输出眼图
figure;
plot(real(rxSTR_withPF(1:4:end)),'r.');hold on;plot(real(rxSTR_withPF_delay(1:4:end)),'b.');
xlabel('并行符号数');ylabel('实部');
4、timingErrEst_OM_block
function [timing_err] = timingErrEst_OM_block(dataIn,upSamping)
% 计算模平方
[raw,line] = size(dataIn);
sqrd_data = abs(dataIn).^2;
dataTmp = sqrd_data;
dataTmp_1 = sum(sum(dataTmp(1:upSamping:raw-3,:)));
dataTmp_3 = sum(sum(dataTmp(3:upSamping:raw-1,:)));
dataTmp_2 = sum(sum(dataTmp(2:upSamping:raw-2,:)));
dataTmp_4 = sum(sum(dataTmp(4:upSamping:raw,:)));
Xm_re = dataTmp_1 - dataTmp_3;
Xm_im = dataTmp_2 - dataTmp_4;
Xm = Xm_re + 1i*Xm_im;
timing_err = (angle(Xm)/2/pi) * 4;