diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index a8fa65edc..0d51c372e 100644 --- a/matlab/tests/equalizer_test.m +++ b/matlab/tests/equalizer_test.m @@ -6,8 +6,8 @@ clear plot_noise_estimation_only=false; -SNR_values_db=linspace(0,10,5); -Nrealizations=10; +SNR_values_db=100;%linspace(20,35,8); +Nrealizations=1; w1=0.1; w2=0.3; @@ -26,11 +26,11 @@ P=K/6; cfg.Seed = 0; % Random channel seed cfg.InitTime = 0; cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'ETU'; +cfg.DelayProfile = 'EPA'; % doppler 5, 70 300 -cfg.DopplerFreq = 70; % 120Hz Doppler frequency +cfg.DopplerFreq = 5; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation cfg.NTerms = 16; % Oscillators used in fading model cfg.ModelType = 'GMEDS'; % Rayleigh fading model type @@ -211,13 +211,14 @@ if (length(SNR_values_db) == 1) plot(n,abs(reshape(hest{i}(:,sym),1,[])),colors2{i}); hold on; end - plot(ref_idx_x,abs(hls(3,ref_idx)),'ro'); + plot(n, abs(h(:,sym)),'g-') +% plot(ref_idx_x,real(hls(3,ref_idx)),'ro'); hold off; tmp=cell(Ntests+1,1); for i=1:Ntests tmp{i}=legends{i}; end - tmp{Ntests+1}='LS'; + tmp{Ntests+1}='Real'; legend(tmp) xlabel('SNR (dB)') diff --git a/matlab/tests/pdsch_bler_equal.m b/matlab/tests/pdsch_bler_equal.m index b9bda08ba..665ff8047 100644 --- a/matlab/tests/pdsch_bler_equal.m +++ b/matlab/tests/pdsch_bler_equal.m @@ -7,8 +7,8 @@ recordedSignal=[]; -Npackets = 20; -SNR_values = linspace(2,6,10); +Npackets = 1; +SNR_values = 56;%linspace(2,6,10); Lp=12; N=256; @@ -35,11 +35,11 @@ w2=reshape(transpose(W2),1,[]); %% Choose RMC -[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.0',[1;0;0;1]); +[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.5',[1;0;0;1]); waveform = sum(waveform,2); if ~isempty(recordedSignal) - rmccFgOut = struct('CellRefP',1,'NDLRB',100,'DuplexMode','FDD','CyclicPrefix','Normal'); + rmccFgOut = struct('CellRefP',1,'NDLRB',25,'DuplexMode','FDD','CyclicPrefix','Normal'); rmccFgOut.PDSCH.RNTI = 1234; rmccFgOut.PDSCH.PRBSet = repmat(transpose(0:rmccFgOut.NDLRB-1),1,2); rmccFgOut.PDSCH.TxScheme = 'Port0'; @@ -53,7 +53,7 @@ end flen=rmccFgOut.SamplingRate/1000; -Nsf = 9; +Nsf = 2; %% Setup Fading channel model cfg.Seed = 0; % Random channel seed @@ -71,8 +71,8 @@ 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.FreqWindow = 1; % Frequency window size +cec.TimeWindow = 1; % Time window size cec.InterpType = 'linear'; % 2D interpolation type cec.InterpWindow = 'Causal'; % Interpolation window type cec.InterpWinSize = 1; % Interpolation window size @@ -95,8 +95,9 @@ for snr_idx=1:length(SNR_values) if isempty(recordedSignal) %% Fading - %rxWaveform = lteFadingChannel(cfg,waveform); - rxWaveform = waveform; + [rxWaveform, chinfo] = lteFadingChannel(cfg,waveform); + rxWaveform = rxWaveform(chinfo.ChannelFilterDelay+1:end); + %rxWaveform = waveform; %% Noise Addition noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise @@ -154,6 +155,7 @@ if (length(SNR_values)>1) ylabel('BLER') axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else + scatter(real(symbols{1}),imag(symbols{1})) fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/matlab/tests/pdsch_decode_signal.m b/matlab/tests/pdsch_decode_signal.m index cf082ae46..29812f8f6 100644 --- a/matlab/tests/pdsch_decode_signal.m +++ b/matlab/tests/pdsch_decode_signal.m @@ -1,17 +1,17 @@ -enb=struct('NCellID',1,'NDLRB',50,'NSubframe',2,'CFI',2,'CyclicPrefix','Normal','CellRefP',1,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); +enb=struct('NCellID',0,'NDLRB',25,'NSubframe',4,'CFI',3,'CyclicPrefix','Normal','CellRefP',1,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); -RNTI=65535; +RNTI=62; 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.FreqWindow = 1; % Frequency window size +cec.TimeWindow = 1; % 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,y); +subframe_rx=lteOFDMDemodulate(enb,x); %subframe_rx=reshape(input,[],14); [hest,nest] = lteDLChannelEstimate(enb, cec, subframe_rx); @@ -30,9 +30,9 @@ if ~isempty(dci) % Get the PDSCH configuration from the DCI [pdsch, trblklen] = hPDSCHConfiguration(enb, dci, pdcch.RNTI); pdsch.NTurboDecIts = 10; - pdsch.Modulation = {'QPSK'}; + pdsch.Modulation = {'64QAM'}; pdsch.RV=0; - %trblklen=75376; + trblklen=14112; fprintf('PDSCH settings after DCI decoding:\n'); disp(pdsch); @@ -41,9 +41,10 @@ if ~isempty(dci) [pdschIndices,pdschIndicesInfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet); [pdschRx, pdschHest] = lteExtractResources(pdschIndices, subframe_rx, hest); % Decode PDSCH - [dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, pdschRx, pdschHest, nest); + [dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, pdschRx, pdschHest, 0); [sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits); + %[dec2, data, pdschRx2, pdschSymbols2, e_bits] = srslte_pdsch(enb, pdsch, ... % trblklen, ... % subframe_rx, hest, nest); diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index 95688b07c..165293bb9 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -52,6 +52,12 @@ #define SRSLTE_CHEST_DL_MAX_SMOOTH_FIL_LEN 65 +typedef enum { + SRSLTE_NOISE_ALG_REFS, + SRSLTE_NOISE_ALG_PSS, + SRSLTE_NOISE_ALG_EMPTY, +} srslte_chest_dl_noise_alg_t; + typedef struct { srslte_cell_t cell; srslte_refsignal_cs_t csr_signal; @@ -78,6 +84,9 @@ typedef struct { cf_t pss_signal[SRSLTE_PSS_LEN]; cf_t tmp_pss[SRSLTE_PSS_LEN]; cf_t tmp_pss_noisy[SRSLTE_PSS_LEN]; + + srslte_chest_dl_noise_alg_t noise_alg; + } srslte_chest_dl_t; @@ -93,6 +102,9 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w); +SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, + srslte_chest_dl_noise_alg_t noise_estimation_alg); + SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_MAX_PORTS], diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index e5963aac7..2d06c6fc1 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -39,8 +39,6 @@ #include "srslte/utils/vector.h" #include "srslte/utils/convolution.h" -#define ESTIMATE_NOISE_LS_PSS - //#define DEFAULT_FILTER_LEN 3 #ifdef DEFAULT_FILTER_LEN @@ -125,6 +123,8 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell) goto clean_exit; } + q->noise_alg = SRSLTE_NOISE_ALG_PSS; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); @@ -189,7 +189,6 @@ static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) return power; } -#ifdef ESTIMATE_NOISE_LS_PSS static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce) { /* Get PSS from received signal */ @@ -209,9 +208,6 @@ static float estimate_noise_pss(srslte_chest_dl_t *q, cf_t *input, cf_t *ce) return power; } - -#else - /* Uses the 5 empty transmitted SC before and after the SSS and PSS sequences for noise estimation */ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { int k_sss = (SRSLTE_CP_NSYMB(q->cell.cp) - 2) * q->cell.nof_prb * SRSLTE_NRE + q->cell.nof_prb * SRSLTE_NRE / 2 - 31; @@ -224,8 +220,6 @@ static float estimate_noise_empty_sc(srslte_chest_dl_t *q, cf_t *input) { return noise_power; } -#endif - #define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.nof_prb,i,0)] @@ -283,6 +277,10 @@ void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint } } +void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, srslte_chest_dl_noise_alg_t noise_estimation_alg) { + q->noise_alg = noise_estimation_alg; +} + void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) { q->smooth_filter_len = 3; @@ -321,24 +319,28 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u srslte_vec_prod_conj_ccc(q->pilot_recv_signal, q->csr_signal.pilots[port_id/2][sf_idx], q->pilot_estimates, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); if (ce != NULL) { - if (q->smooth_filter_len > 0) { - average_pilots(q, q->pilot_estimates, q->pilot_estimates_average, port_id); - interpolate_pilots(q, q->pilot_estimates_average, ce, port_id); - - /* If averaging, compute noise from difference between received and averaged estimates */ - q->noise_estimate[port_id] = estimate_noise_pilots(q, port_id); - } else { + + /* Smooth estimates (if applicable) and interpolate */ + if (q->smooth_filter_len == 0 || (q->smooth_filter_len == 3 && q->smooth_filter[0] == 0)) { interpolate_pilots(q, q->pilot_estimates, ce, port_id); - - /* If not averaging, compute noise from empty subcarriers */ -#ifdef ESTIMATE_NOISE_LS_PSS + } else { + average_pilots(q, q->pilot_estimates, q->pilot_estimates_average, port_id); + interpolate_pilots(q, q->pilot_estimates_average, ce, port_id); + } + + /* Estimate noise power */ + if (q->noise_alg == SRSLTE_NOISE_ALG_REFS && q->smooth_filter_len > 0) { + q->noise_estimate[port_id] = estimate_noise_pilots(q, port_id); + } else if (q->noise_alg == SRSLTE_NOISE_ALG_PSS) { if (sf_idx == 0 || sf_idx == 5) { q->noise_estimate[port_id] = estimate_noise_pss(q, input, ce); } -#else - q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input); -#endif + } else { + if (sf_idx == 0 || sf_idx == 5) { + q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input); + } } + } /* Compute RSRP for the channel estimates in this port */