mirror of https://github.com/pvnis/srsRAN_4G.git
Added matlab files to test synchronization
parent
dd396c0562
commit
f31922f5f5
@ -0,0 +1,7 @@
|
|||||||
|
function fs = find_pss_ac( x)
|
||||||
|
|
||||||
|
w2=xcorr(x,x);
|
||||||
|
[m, fs]=max(abs(w2));
|
||||||
|
fs=fs-1920;
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,159 @@
|
|||||||
|
|
||||||
|
%% PDSCH decoding based on RMC channels
|
||||||
|
|
||||||
|
%% Cell-Wide Settings
|
||||||
|
% A structure |enbConfig| is used to configure the eNodeB.
|
||||||
|
%clear12
|
||||||
|
|
||||||
|
recordedSignal=[];
|
||||||
|
|
||||||
|
Npackets = 20;
|
||||||
|
SNR_values = linspace(2,6,10);
|
||||||
|
|
||||||
|
Lp=12;
|
||||||
|
N=256;
|
||||||
|
K=180;
|
||||||
|
rstart=(N-K)/2;
|
||||||
|
P=K/6;
|
||||||
|
Rhphp=zeros(P,P);
|
||||||
|
Rhhp=zeros(K,P);
|
||||||
|
Rhh=zeros(K,K);
|
||||||
|
|
||||||
|
t=0:Lp-1;
|
||||||
|
alfa=log(2*Lp)/Lp;
|
||||||
|
c_l=exp(-t*alfa);
|
||||||
|
c_l=c_l/sum(c_l);
|
||||||
|
C_l=diag(1./c_l);
|
||||||
|
prows=rstart+(1:6:K);
|
||||||
|
|
||||||
|
F=dftmtx(N);
|
||||||
|
F_p=F(prows,1:Lp);
|
||||||
|
F_l=F((rstart+1):(K+rstart),1:Lp);
|
||||||
|
Wi=(F_p'*F_p+C_l*0.01)^(-1);
|
||||||
|
W2=F_l*Wi*F_p';
|
||||||
|
w2=reshape(transpose(W2),1,[]);
|
||||||
|
|
||||||
|
|
||||||
|
%% Choose RMC
|
||||||
|
[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.0',[1;0;0;1]);
|
||||||
|
waveform = sum(waveform,2);
|
||||||
|
|
||||||
|
if ~isempty(recordedSignal)
|
||||||
|
rmccFgOut = struct('CellRefP',1,'NDLRB',100,'DuplexMode','FDD','CyclicPrefix','Normal');
|
||||||
|
rmccFgOut.PDSCH.RNTI = 1234;
|
||||||
|
rmccFgOut.PDSCH.PRBSet = repmat(transpose(0:rmccFgOut.NDLRB-1),1,2);
|
||||||
|
rmccFgOut.PDSCH.TxScheme = 'Port0';
|
||||||
|
rmccFgOut.PDSCH.NLayers = 1;
|
||||||
|
rmccFgOut.PDSCH.NTurboDecIts = 5;
|
||||||
|
rmccFgOut.PDSCH.Modulation = {'64QAM'};
|
||||||
|
trblklen=75376;
|
||||||
|
rmccFgOut.PDSCH.TrBlkSizes = trblklen*ones(10,1);
|
||||||
|
rmccFgOut.PDSCH.RV = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
flen=rmccFgOut.SamplingRate/1000;
|
||||||
|
|
||||||
|
Nsf = 9;
|
||||||
|
|
||||||
|
%% Setup Fading channel model
|
||||||
|
cfg.Seed = 0; % Random channel seed
|
||||||
|
cfg.NRxAnts = 1; % 1 receive antenna
|
||||||
|
cfg.DelayProfile = 'EPA'; % EVA delay spread
|
||||||
|
cfg.DopplerFreq = 5; % 120Hz Doppler frequency
|
||||||
|
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
|
||||||
|
cfg.InitTime = 0; % Initialize at time zero
|
||||||
|
cfg.NTerms = 16; % Oscillators used in fading model
|
||||||
|
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
|
||||||
|
cfg.InitPhase = 'Random'; % Random initial phases
|
||||||
|
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
|
||||||
|
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
|
||||||
|
cfg.SamplingRate = rmccFgOut.SamplingRate;
|
||||||
|
|
||||||
|
% Setup channel equalizer
|
||||||
|
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
|
||||||
|
cec.FreqWindow = 9; % Frequency window size
|
||||||
|
cec.TimeWindow = 9; % Time window size
|
||||||
|
cec.InterpType = 'linear'; % 2D interpolation type
|
||||||
|
cec.InterpWindow = 'Causal'; % Interpolation window type
|
||||||
|
cec.InterpWinSize = 1; % Interpolation window size
|
||||||
|
|
||||||
|
addpath('../../build/srslte/lib/phch/test')
|
||||||
|
|
||||||
|
decoded = zeros(size(SNR_values));
|
||||||
|
decoded_srslte = zeros(size(SNR_values));
|
||||||
|
|
||||||
|
for snr_idx=1:length(SNR_values)
|
||||||
|
SNRdB = SNR_values(snr_idx);
|
||||||
|
SNR = 10^(SNRdB/10); % Linear SNR
|
||||||
|
N0 = 1/(sqrt(2.0*rmccFgOut.CellRefP*double(rmccFgOut.Nfft))*SNR);
|
||||||
|
|
||||||
|
Rhphp=zeros(30,30);
|
||||||
|
Rhhp=zeros(180,30);
|
||||||
|
|
||||||
|
for i=1:Npackets
|
||||||
|
|
||||||
|
if isempty(recordedSignal)
|
||||||
|
|
||||||
|
%% Fading
|
||||||
|
%rxWaveform = lteFadingChannel(cfg,waveform);
|
||||||
|
rxWaveform = waveform;
|
||||||
|
|
||||||
|
%% Noise Addition
|
||||||
|
noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise
|
||||||
|
rxWaveform = rxWaveform + noise;
|
||||||
|
else
|
||||||
|
rxWaveform = recordedSignal;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Demodulate
|
||||||
|
frame_rx = lteOFDMDemodulate(rmccFgOut, rxWaveform);
|
||||||
|
|
||||||
|
for sf_idx=0:Nsf-1
|
||||||
|
% sf_idx=9;
|
||||||
|
subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14);
|
||||||
|
rmccFgOut.NSubframe=sf_idx;
|
||||||
|
rmccFgOut.TotSubframes=1;
|
||||||
|
|
||||||
|
% Perform channel estimation
|
||||||
|
[hest, nest,estimates] = lteDLChannelEstimate2(rmccFgOut, cec, subframe_rx);
|
||||||
|
|
||||||
|
[cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest);
|
||||||
|
[trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ...
|
||||||
|
rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1),cws);
|
||||||
|
|
||||||
|
decoded(snr_idx) = decoded(snr_idx) + ~blkcrc;
|
||||||
|
|
||||||
|
|
||||||
|
%% Same with srsLTE
|
||||||
|
if (rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1) > 0)
|
||||||
|
[dec2, data, pdschRx, pdschSymbols2, cws2] = srslte_pdsch(rmccFgOut, rmccFgOut.PDSCH, ...
|
||||||
|
rmccFgOut.PDSCH.TrBlkSizes(sf_idx+1), ...
|
||||||
|
subframe_rx);
|
||||||
|
else
|
||||||
|
dec2 = 1;
|
||||||
|
end
|
||||||
|
if (~dec2)
|
||||||
|
fprintf('Error in sf=%d\n',sf_idx);
|
||||||
|
end
|
||||||
|
decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+dec2;
|
||||||
|
end
|
||||||
|
|
||||||
|
if ~isempty(recordedSignal)
|
||||||
|
recordedSignal = recordedSignal(flen*10+1:end);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fprintf('SNR: %.1f. Decoded: %d-%d\n',SNRdB, decoded(snr_idx), decoded_srslte(snr_idx))
|
||||||
|
end
|
||||||
|
|
||||||
|
if (length(SNR_values)>1)
|
||||||
|
semilogy(SNR_values,1-decoded/Npackets/(Nsf),'bo-',...
|
||||||
|
SNR_values,1-decoded_srslte/Npackets/(Nsf), 'ro-')
|
||||||
|
grid on;
|
||||||
|
legend('Matlab','srsLTE')
|
||||||
|
xlabel('SNR (dB)')
|
||||||
|
ylabel('BLER')
|
||||||
|
axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1])
|
||||||
|
else
|
||||||
|
fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte);
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
enb=struct('NCellID',0,'NDLRB',100,'NSubframe',9,'CFI',1,'CyclicPrefix','Normal','CellRefP',1,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD');
|
||||||
|
|
||||||
|
RNTI=73;
|
||||||
|
|
||||||
|
addpath('../../build/srslte/lib/phch/test')
|
||||||
|
|
||||||
|
cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
|
||||||
|
cec.FreqWindow = 9; % Frequency window size
|
||||||
|
cec.TimeWindow = 9; % Time window size
|
||||||
|
cec.InterpType = 'linear'; % 2D interpolation type
|
||||||
|
cec.InterpWindow = 'Causal'; % Interpolation window type
|
||||||
|
cec.InterpWinSize = 1; % Interpolation window size
|
||||||
|
|
||||||
|
%subframe_rx=lteOFDMDemodulate(enb,inputSignal);
|
||||||
|
subframe_rx=reshape(input,[],14);
|
||||||
|
[hest,nest] = lteDLChannelEstimate(enb, cec, subframe_rx);
|
||||||
|
|
||||||
|
% Search PDCCH
|
||||||
|
pdcchIndices = ltePDCCHIndices(enb);
|
||||||
|
[pdcchRx, pdcchHest] = lteExtractResources(pdcchIndices, subframe_rx, hest);
|
||||||
|
[dciBits, pdcchSymbols] = ltePDCCHDecode(enb, pdcchRx, pdcchHest, nest);
|
||||||
|
pdcch = struct('RNTI', RNTI);
|
||||||
|
dci = ltePDCCHSearch(enb, pdcch, dciBits); % Search PDCCH for DCI
|
||||||
|
|
||||||
|
if ~isempty(dci)
|
||||||
|
|
||||||
|
dci = dci{1};
|
||||||
|
disp(dci);
|
||||||
|
|
||||||
|
% Get the PDSCH configuration from the DCI
|
||||||
|
[pdsch, trblklen] = hPDSCHConfiguration(enb, dci, pdcch.RNTI);
|
||||||
|
pdsch.NTurboDecIts = 10;
|
||||||
|
pdsch.Modulation = {'64QAM'};
|
||||||
|
trblklen=75376;
|
||||||
|
fprintf('PDSCH settings after DCI decoding:\n');
|
||||||
|
disp(pdsch);
|
||||||
|
|
||||||
|
fprintf('Decoding PDSCH...\n\n');
|
||||||
|
% Get PDSCH indices
|
||||||
|
[pdschIndices,pdschIndicesInfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet);
|
||||||
|
[pdschRx, pdschHest] = lteExtractResources(pdschIndices, subframe_rx, hest);
|
||||||
|
% Decode PDSCH
|
||||||
|
[dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, d);
|
||||||
|
[sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits);
|
||||||
|
|
||||||
|
% [dec2, data, pdschRx2, pdschSymbols2, e_bits, indices] = srslte_pdsch(enb, pdsch, ...
|
||||||
|
% trblklen, ...
|
||||||
|
% subframe_rx);
|
||||||
|
|
||||||
|
|
||||||
|
scatter(real(pdschSymbols{1}),imag(pdschSymbols{1}))
|
||||||
|
|
||||||
|
if crc == 0
|
||||||
|
fprintf('PDSCH OK.\n\n');
|
||||||
|
else
|
||||||
|
fprintf('PDSCH ERROR.\n\n');
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
% indicate that DCI decoding failed
|
||||||
|
fprintf('DCI decoding failed.\n\n');
|
||||||
|
end
|
||||||
|
|
||||||
|
%indices=indices+1;
|
||||||
|
%plot(t,indices(t),t,pdschIndices(t))
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
clear
|
||||||
|
|
||||||
|
% Run pdsch_test with -vv to generate files. Then run this script to check
|
||||||
|
% rate matching and demodulation
|
||||||
|
% Need to change soft demodulator output to +-10
|
||||||
|
|
||||||
|
enbConfig=struct('NCellID',0,'CyclicPrefix','Normal','CellRefP',1,'DuplexMode','FDD');
|
||||||
|
pdschConfig=struct('Modulation','64QAM','RV',3,'TxScheme','Port0','NTurboDecIts',10,...
|
||||||
|
'NSoftbits',0,'DuplexMode','FDD');
|
||||||
|
|
||||||
|
addpath('../../build/srslte/lib/phch/test')
|
||||||
|
|
||||||
|
cbidx_v=0:12;
|
||||||
|
e_bits=90000;
|
||||||
|
|
||||||
|
trblkin=read_uchar('../../build/data_in');
|
||||||
|
[mat, info]=lteDLSCH(enbConfig,pdschConfig,e_bits,trblkin);
|
||||||
|
mat(mat==0)=-1;
|
||||||
|
mat=mat*10;
|
||||||
|
rec = lteRateRecoverTurbo(mat,length(trblkin),pdschConfig.RV,pdschConfig);
|
||||||
|
|
||||||
|
rec2=cell(size(rec));
|
||||||
|
srs=cell(size(rec));
|
||||||
|
for cbidx=cbidx_v
|
||||||
|
rec2{cbidx+1} = reshape(reshape(rec{cbidx+1},[],3)',[],1);
|
||||||
|
srs{cbidx+1}=read_int16(sprintf('../../build/rmout_%d.dat',cbidx));
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
subplot(2,1,1)
|
||||||
|
plot(abs(double(reshape(cell2mat(srs),1,[]))-double(reshape(cell2mat(rec2),1,[]))));
|
||||||
|
|
||||||
|
subplot(2,1,2)
|
||||||
|
llr=read_int16('../../build/llr.dat');
|
||||||
|
plot(abs(double(mat)-double(llr)))
|
||||||
|
|
||||||
|
[data, crc,state] = lteDLSCHDecode(enbConfig, pdschConfig, length(trblkin), mat);
|
||||||
|
disp(crc)
|
||||||
|
|
@ -1,44 +1,83 @@
|
|||||||
enb = lteTestModel('1.1','5MHz');
|
clear
|
||||||
|
enb = lteTestModel('1.1','1.4MHz');
|
||||||
Ntrials = 1;
|
Ntrials = 1;
|
||||||
SNR_values =-20;%linspace(-18,-10,8);
|
SNR_values = 100;%linspace(0,10,6);
|
||||||
|
flen=1920;
|
||||||
|
fft_size=128;
|
||||||
|
|
||||||
tx_offset = randi(50,Ntrials,1);
|
tx_offset = 0;%randi(50,1,Ntrials);
|
||||||
diff=zeros(size(SNR_values));
|
cfo_offset = 0;%2*rand(1,Ntrials)-1;
|
||||||
diff_lt=zeros(size(SNR_values));
|
|
||||||
|
|
||||||
tx_signal = lteTestModelTool(enb);
|
tx_signal = lteTestModelTool(enb);
|
||||||
tx_power = mean(tx_signal.*conj(tx_signal));
|
pss_idx = flen/2-fft_size+1:flen/2;
|
||||||
|
pss_signal=tx_signal(pss_idx);
|
||||||
|
tx_power = mean(pss_signal.*conj(pss_signal));
|
||||||
|
|
||||||
corrcfg.PSS='On';
|
corrcfg.PSS='On';
|
||||||
corrcfg.SSS='On';
|
corrcfg.SSS='On';
|
||||||
corrcfg.CellRS='Off';
|
corrcfg.CellRS='Off';
|
||||||
|
|
||||||
addpath('../../debug/lte/phy/lib/sync/test')
|
cfg.Seed = 0; % Random channel seed
|
||||||
|
cfg.NRxAnts = 1; % 1 receive antenna
|
||||||
|
cfg.DelayProfile = 'ETU'; % EVA delay spread
|
||||||
|
cfg.DopplerFreq = 120; % 120Hz Doppler frequency
|
||||||
|
cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation
|
||||||
|
cfg.InitTime = 0; % Initialize at time zero
|
||||||
|
cfg.NTerms = 16; % Oscillators used in fading model
|
||||||
|
cfg.ModelType = 'GMEDS'; % Rayleigh fading model type
|
||||||
|
cfg.InitPhase = 'Random'; % Random initial phases
|
||||||
|
cfg.NormalizePathGains = 'On'; % Normalize delay profile power
|
||||||
|
cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas
|
||||||
|
cfg.SamplingRate = flen*1000;
|
||||||
|
|
||||||
|
addpath('../../build/srslte/lib/sync/test')
|
||||||
|
addpath('../sync/')
|
||||||
|
|
||||||
|
t = (0:length(tx_signal)-1).'/fft_size;
|
||||||
|
|
||||||
|
L=16;
|
||||||
|
M=3;
|
||||||
|
diff=zeros(length(SNR_values),M);
|
||||||
for snr_idx=1:length(SNR_values)
|
for snr_idx=1:length(SNR_values)
|
||||||
|
fprintf('SNR=%.1f dB\n', SNR_values(snr_idx));
|
||||||
SNRdB = SNR_values(snr_idx);
|
SNRdB = SNR_values(snr_idx);
|
||||||
rx_offset = zeros(size(tx_offset));
|
rx_offset = zeros(M,length(tx_offset));
|
||||||
rx_offset_lt = zeros(size(tx_offset));
|
|
||||||
for i=1:Ntrials
|
for i=1:Ntrials
|
||||||
|
[rx_signal, chinfo] = lteFadingChannel(cfg,tx_signal);
|
||||||
|
% rx_signal = rx_signal.*exp(-1i*cfo_offset(i)*2*pi.*t);
|
||||||
|
%rx_signal = tx_signal;
|
||||||
SNR = 10^(SNRdB/10); % Linear SNR
|
SNR = 10^(SNRdB/10); % Linear SNR
|
||||||
tx = [zeros(tx_offset(i),1); tx_signal];
|
rx = [zeros(tx_offset(i),1); rx_signal];
|
||||||
N0 = tx_power/(sqrt(2.0)*SNR);
|
N0 = tx_power/(sqrt(2.0)*SNR);
|
||||||
noise = N0*complex(randn(size(tx)), randn(size(tx))); % Generate noise
|
noise = N0*complex(randn(size(rx)), randn(size(rx))); % Generate noise
|
||||||
rx=noise+tx;
|
rx=noise+rx;
|
||||||
[rx_offset(i),corr] = lteDLFrameOffset(enb,rx,corrcfg);
|
[rx_offset(1,i),corr_res] = lteDLFrameOffset(enb,rx(1:flen),corrcfg);
|
||||||
[rx_offset_lt(i),corr_lt] = srslte_pss(enb,rx);
|
|
||||||
|
% srsLTE in find mode
|
||||||
|
[rx_offset(2,i),corr_lt] = srslte_pss(enb,rx(1:flen));
|
||||||
|
rx_offset(2,i) = rx_offset(2,i) - flen/2;
|
||||||
|
|
||||||
|
% srsLTE in tracking mode
|
||||||
|
track_offset=2+rx_offset(2,i)+flen/2-fft_size-L/2;
|
||||||
|
[rx_offset(3,i),corr_lt_track] = srslte_pss(enb,rx(track_offset:end),L);
|
||||||
|
rx_offset(3,i) = rx_offset(2,i) + (rx_offset(3,i) - fft_size - L/2);
|
||||||
end
|
end
|
||||||
diff(snr_idx)=sum(abs(rx_offset-tx_offset));
|
diff(snr_idx,:)=mean(abs(rx_offset-repmat(tx_offset,M,1)),2);
|
||||||
diff_lt(snr_idx)=sum(abs(rx_offset_lt-tx_offset));
|
|
||||||
disp(SNRdB)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if (Ntrials == 1)
|
if (Ntrials == 1)
|
||||||
len=1:length(corr)-rx_offset(i)-3840;
|
disp(diff)
|
||||||
len2=rx_offset(i)+1+3840:length(corr);
|
%plot(1:flen,abs(corr_res(1:flen)),1:flen,abs(corr_lt(1:flen)));
|
||||||
plot(len,corr(len)/max(corr(len)),...
|
t=940:1000;
|
||||||
len,abs(corr_lt(len2))/max(abs(corr_lt(len2))));
|
plot(t,abs(corr_lt(t)));
|
||||||
|
%plot(1:L,abs(corr_lt_track),[L/2, L/2], [0 max(abs(corr_lt_track))])
|
||||||
|
grid on
|
||||||
|
|
||||||
else
|
else
|
||||||
plot(SNR_values,diff,SNR_values,diff_lt);
|
plot(SNR_values,diff);
|
||||||
|
legend('Matlab','srs find','srs tracking 16','srs tracking 64')
|
||||||
|
grid on
|
||||||
|
xlabel('SNR (dB)')
|
||||||
|
ylabel('Avg time offset')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue