From 92e0db231c02775f292080e88daf8dc437cfcb06 Mon Sep 17 00:00:00 2001 From: ismagom Date: Wed, 17 Dec 2014 08:26:58 +0000 Subject: [PATCH] Fixed issue in PBCH decoding N_id_2=2. Changed measurements average to exponential. Moved MMSE diversity equalizer to ZF. --- lte/examples/cell_measurement.c | 23 ++++++++------- lte/examples/cell_scanner/cell_scanner.c | 2 +- lte/examples/pdsch_ue.c | 22 +++++++-------- lte/phy/lib/ch_estimation/src/chest_dl.c | 3 +- lte/phy/lib/mimo/src/precoding.c | 6 ++-- lte/phy/lib/phch/src/pbch.c | 10 +++++-- lte/phy/lib/phch/src/prb.c | 7 +++-- lte/phy/lib/phch/test/pbch_test_mex.c | 36 +++++++++++++++++++++--- lte/phy/lib/sync/src/pss.c | 13 ++------- lte/phy/lib/ue/src/ue_sync.c | 2 +- matlab/tests/test_pbch.m | 30 +++++++++----------- mex/include/liblte/mex/mexutils.h | 5 ++++ mex/lib/mexutils.c | 11 ++++++++ 13 files changed, 108 insertions(+), 62 deletions(-) diff --git a/lte/examples/cell_measurement.c b/lte/examples/cell_measurement.c index c9f19a0c6..f1ba543c0 100644 --- a/lte/examples/cell_measurement.c +++ b/lte/examples/cell_measurement.c @@ -350,17 +350,20 @@ int main(int argc, char **argv) { } break; case MEASURE: - /* Run FFT for all subframe data */ - lte_fft_run_sf(&fft, sf_buffer, sf_symbols); - chest_dl_estimate(&chest, sf_symbols, ce, ue_sync_get_sfidx(&ue_sync)); - - rssi = VEC_CMA(vec_avg_power_cf(sf_buffer,SF_LEN(lte_symbol_sz(cell.nof_prb))),rssi,nframes); - rssi_utra = VEC_CMA(chest_dl_get_rssi(&chest),rssi_utra,nframes); - rsrq = VEC_EMA(chest_dl_get_rsrq(&chest),rsrq,0.001); - rsrp = VEC_CMA(chest_dl_get_rsrp(&chest),rsrp,nframes); - snr = VEC_CMA(chest_dl_get_snr(&chest),snr,nframes); - nframes++; + if (ue_sync_get_sfidx(&ue_sync) == 5) { + /* Run FFT for all subframe data */ + lte_fft_run_sf(&fft, sf_buffer, sf_symbols); + + chest_dl_estimate(&chest, sf_symbols, ce, ue_sync_get_sfidx(&ue_sync)); + + rssi = VEC_CMA(vec_avg_power_cf(sf_buffer,SF_LEN(lte_symbol_sz(cell.nof_prb))),rssi,nframes); + rssi_utra = VEC_CMA(chest_dl_get_rssi(&chest),rssi_utra,nframes); + rsrq = VEC_EMA(chest_dl_get_rsrq(&chest),rsrq,0.001); + rsrp = VEC_EMA(chest_dl_get_rsrp(&chest),rsrp,0.001); + snr = VEC_EMA(chest_dl_get_snr(&chest),snr,0.001); + nframes++; + } // Plot and Printf if ((nframes%10) == 0) { diff --git a/lte/examples/cell_scanner/cell_scanner.c b/lte/examples/cell_scanner/cell_scanner.c index 9c62c0900..ff5e5ffe1 100644 --- a/lte/examples/cell_scanner/cell_scanner.c +++ b/lte/examples/cell_scanner/cell_scanner.c @@ -241,7 +241,7 @@ int cell_scanner_cell(cell_scanner_t *q, float frequency, int N_id_2, cell_scann result->rssi,nframes_measure); result->rsrq = VEC_EMA(chest_dl_get_rsrq(chest_ptr),result->rsrq,0.01); result->rsrp = VEC_CMA(chest_dl_get_rsrp(chest_ptr),result->rsrp,nframes_measure); - result->snr = VEC_CMA(chest_dl_get_snr(chest_ptr),result->snr,nframes_measure); + result->snr = VEC_EMA(chest_dl_get_snr(chest_ptr),result->snr,0.01); nframes_measure++; // Plot and Printf diff --git a/lte/examples/pdsch_ue.c b/lte/examples/pdsch_ue.c index afa0dfed2..6a945a9a1 100644 --- a/lte/examples/pdsch_ue.c +++ b/lte/examples/pdsch_ue.c @@ -246,7 +246,7 @@ int main(int argc, char **argv) { // Variables for measurements uint32_t nframes=0; - float rsrp=1.0, rsrq=1.0, snr=1.0; + float rsrp=0.0, rsrq=0.0, snr=0.0; /* Main loop */ while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { @@ -276,6 +276,7 @@ int main(int argc, char **argv) { } break; case DECODE_SIB: + sfn=0; /* We are looking for SI Blocks, search only in appropiate places */ if ((ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync), @@ -285,19 +286,18 @@ int main(int argc, char **argv) { exit(-1); } nof_trials++; - } - - rsrq = VEC_EMA(chest_dl_get_rsrq(&ue_dl.chest),rsrq,0.001); - rsrp = VEC_CMA(chest_dl_get_rsrp(&ue_dl.chest),rsrp,nframes); - snr = VEC_CMA(chest_dl_get_snr(&ue_dl.chest),snr,nframes); - nframes++; - - if (isnan(rsrq)) { - rsrq = 0; + + rsrq = VEC_EMA(chest_dl_get_rsrq(&ue_dl.chest),rsrq,0.001); + rsrp = VEC_EMA(chest_dl_get_rsrp(&ue_dl.chest),rsrp,0.001); + snr = VEC_EMA(chest_dl_get_snr(&ue_dl.chest),snr,0.001); + nframes++; + if (isnan(rsrq)) { + rsrq = 0; + } } // Plot and Printf - if (ue_sync_get_sfidx(&ue_sync) == 0) { + if (ue_sync_get_sfidx(&ue_sync) == 5) { printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, " "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %4.1f dB, " "PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% (%d blocks)\r", diff --git a/lte/phy/lib/ch_estimation/src/chest_dl.c b/lte/phy/lib/ch_estimation/src/chest_dl.c index b8fed7838..213ba7dac 100644 --- a/lte/phy/lib/ch_estimation/src/chest_dl.c +++ b/lte/phy/lib/ch_estimation/src/chest_dl.c @@ -359,7 +359,8 @@ float chest_dl_get_snr(chest_dl_t *q) { float snr = 0.0; for (int i=0;icell.nof_ports;i++) { if (q->noise_estimate[i]) { - snr += q->rsrp[i]/(q->noise_estimate[i]*sqrtf(2*q->cell.nof_ports*lte_symbol_sz(q->cell.nof_prb))); + float snr_i = q->rsrp[i]/(q->noise_estimate[i]*sqrtf(2*q->cell.nof_ports*lte_symbol_sz(q->cell.nof_prb))); + snr += snr_i; } } return snr/q->cell.nof_ports; diff --git a/lte/phy/lib/mimo/src/precoding.c b/lte/phy/lib/mimo/src/precoding.c index 46c035ebc..e0725ecc6 100644 --- a/lte/phy/lib/mimo/src/precoding.c +++ b/lte/phy/lib/mimo/src/precoding.c @@ -169,10 +169,10 @@ int predecoding_diversity(precoding_t *q, cf_t *y, cf_t *h[MAX_PORTS], cf_t *x[M vec_abs_square_cf(h0, modh0, nof_symbols/2); vec_abs_square_cf(h1, modh1, nof_symbols/2); vec_sum_fff(modh0, modh1, modhh, nof_symbols/2); - if (noise_estimate > 0.0) { + //if (noise_estimate > 0.0) { // (H'H + n0) - vec_sc_add_fff(modhh, noise_estimate, modhh, nof_symbols/2); - } + //vec_sc_add_fff(modhh, noise_estimate, modhh, nof_symbols/2); + //} vec_sc_prod_fff(modhh, 1/sqrt(2), modhh, nof_symbols/2); diff --git a/lte/phy/lib/phch/src/pbch.c b/lte/phy/lib/phch/src/pbch.c index 5beaf56d8..579aea90b 100644 --- a/lte/phy/lib/phch/src/pbch.c +++ b/lte/phy/lib/phch/src/pbch.c @@ -50,10 +50,14 @@ bool pbch_exists(int nframe, int nslot) { return (!(nframe % 5) && nslot == 1); } +cf_t *offset_original; + int pbch_cp(cf_t *input, cf_t *output, lte_cell_t cell, bool put) { int i; cf_t *ptr; - + + offset_original = input; + if (put) { ptr = input; output += cell.nof_prb * RE_X_RB / 2 - 36; @@ -66,9 +70,9 @@ int pbch_cp(cf_t *input, cf_t *output, lte_cell_t cell, bool put) { for (i = 0; i < 2; i++) { prb_cp_ref(&input, &output, cell.id % 3, 4, 4*6, put); if (put) { - output += cell.nof_prb * RE_X_RB - 2*36; + output += cell.nof_prb * RE_X_RB - 2*36 + (cell.id%3==2?1:0); } else { - input += cell.nof_prb * RE_X_RB - 2*36; + input += cell.nof_prb * RE_X_RB - 2*36 + (cell.id%3==2?1:0); } } /* symbols 2 & 3 */ diff --git a/lte/phy/lib/phch/src/prb.c b/lte/phy/lib/phch/src/prb.c index 40bac2014..a1e0fd729 100644 --- a/lte/phy/lib/phch/src/prb.c +++ b/lte/phy/lib/phch/src/prb.c @@ -32,17 +32,20 @@ #include "prb.h" #include "liblte/phy/common/phy_common.h" -//#define DEBUG_IDX +#define DEBUG_IDX #ifdef DEBUG_IDX extern cf_t *offset_original; +LIBLTE_API int indices[2048]; +int indices_ptr=0; #endif void print_indexes(cf_t *offset, int len) { #ifdef DEBUG_IDX for (int i=0;i NOF_INPUTS) { + cf_t *cearray; + mexutils_read_cf(prhs[NOF_INPUTS], &cearray); + for (i=0;i NOF_INPUTS + 1) { + noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); + } else { + noise_power = chest_dl_get_noise_estimate(&chest); + } + for (int i=0;i= 1) { @@ -114,6 +133,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nlhs >= 5) { mexutils_write_cf(ce[1], &plhs[4], SF_LEN_RE(cell.nof_prb,cell.cp)/14, 14); } + if (nlhs >= 6) { + mexutils_write_cf(pbch.pbch_symbols[0], &plhs[5], pbch.nof_symbols, 1); + } + if (nlhs >= 7) { + mexutils_write_cf(pbch.ce[0], &plhs[6], pbch.nof_symbols, 1); + } + if (nlhs >= 7) { + mexutils_write_int(indices, &plhs[7], 2048, 1); + } chest_dl_free(&chest); lte_fft_free(&fft); diff --git a/lte/phy/lib/sync/src/pss.c b/lte/phy/lib/sync/src/pss.c index 22c8710b1..62e7f4e23 100644 --- a/lte/phy/lib/sync/src/pss.c +++ b/lte/phy/lib/sync/src/pss.c @@ -302,10 +302,10 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value) conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size); #endif } else { - for (int i=0;iframe_size-1;i++) { + for (int i=0;iframe_size;i++) { q->conv_output[i] = vec_dot_prod_ccc(q->pss_signal_freq[q->N_id_2], &input[i], q->fft_size); } - conv_output_len = q->frame_size-1; + conv_output_len = q->frame_size; } @@ -363,14 +363,7 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value) sl_left, 1000000*q->conv_output_avg[sl_left], 1000000*q->conv_output_avg[corr_peak_pos], 1000000*side_lobe_value,*corr_peak_value ); - } - - if (isnan(*corr_peak_value) || isinf(*corr_peak_value)) { - int i=0; - vec_save_file("corrout", q->conv_output_avg, conv_output_len*sizeof(float)); - exit(-1); - } - + } } #else if (corr_peak_value) { diff --git a/lte/phy/lib/ue/src/ue_sync.c b/lte/phy/lib/ue/src/ue_sync.c index 9a6ec8b0a..f38f5e4ce 100644 --- a/lte/phy/lib/ue/src/ue_sync.c +++ b/lte/phy/lib/ue/src/ue_sync.c @@ -103,7 +103,7 @@ int ue_sync_init(ue_sync_t *q, sync_set_threshold(&q->sfind, 1.1); sync_set_em_alpha(&q->sfind, 0.01); q->nof_avg_find_frames = FIND_NOF_AVG_FRAMES; - sync_set_threshold(&q->strack, 2.0); + sync_set_threshold(&q->strack, 1.2); } else { sync_set_N_id_2(&q->sfind, cell.id%3); diff --git a/matlab/tests/test_pbch.m b/matlab/tests/test_pbch.m index c15aa0a4b..47972e6c7 100644 --- a/matlab/tests/test_pbch.m +++ b/matlab/tests/test_pbch.m @@ -3,8 +3,9 @@ rmc = lteRMCDL('R.10'); NofPortsTx=2; -SNR_values_db=1;%linspace(-6,5,8); -Nrealizations=1; +SNR_values_db=linspace(-6,0,4); +Nrealizations=50; +enb = struct('NCellID',0,'NDLRB',50,'CellRefP',NofPortsTx,'CyclicPrefix','Normal','DuplexMode','FDD','NSubframe',0); cfg.Seed = 8; % Random channel seed @@ -42,22 +43,20 @@ for snr_idx=1:length(SNR_values_db) errorReal = zeros(Nrealizations,2); for i=1:Nrealizations - enb = struct('NCellID',311,'NDLRB',6,'CellRefP',NofPortsTx,'CyclicPrefix','Normal','DuplexMode','FDD','NSubframe',0); griddims = lteResourceGridSize(enb); % Resource grid dimensions L = griddims(2); - %rxWaveform = lteFadingChannel(cfg,waveform(:,1)); - %rxWaveform = waveform(:,1); + rxWaveform = lteFadingChannel(cfg,waveform(:,1)); %% Additive Noise - %N0 = 1/(sqrt(2.0*double(enb.CellRefP)*double(info.Nfft))*SNR); + N0 = 1/(sqrt(2.0*double(enb.CellRefP)*double(info.Nfft))*SNR); % Create additive white Gaussian noise - %noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))); + noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))); - %rxWaveform = noise + rxWaveform; + rxWaveform = noise + rxWaveform; - rxWaveform = downsampled; + % rxWaveform = downsampled; % Number of OFDM symbols in a subframe % OFDM demodulate signal @@ -71,17 +70,16 @@ for snr_idx=1:length(SNR_values_db) pbchIndices, rxgrid(:,1:L,:), hest(:,1:L,:,:)); % Decode PBCH - [bchBits, pbchSymbols, nfmod4, mib, enb.CellRefP] = ltePBCHDecode( ... + [bchBits, pbchSymbols, nfmod4, mib, nof_ports] = ltePBCHDecode( ... enb, pbchRx, pbchHest, nest); - % Parse MIB bits - enb = lteMIB(mib, enb); - if (enb.CellRefP ~= NofPortsTx) + if (nof_ports ~= NofPortsTx) errorReal(i,1)=1; end - enb = struct('NCellID',311,'NDLRB',6,'CellRefP',NofPortsTx,'CyclicPrefix','Normal','DuplexMode','FDD','NSubframe',0); - [nof_ports, pbchSymbols2, pbchBits, ce, ce2]=liblte_pbch(enb, rxWaveform); - if (nof_ports ~= NofPortsTx) + + [nof_ports2, pbchSymbols2, pbchBits, ce, ce2, pbchRx2, pbchHest2,indices]=... + liblte_pbch(enb, rxWaveform, hest, nest); + if (nof_ports2 ~= NofPortsTx) errorReal(i,2)=1; end % if (errorReal(i,1) ~= errorReal(i,2)) diff --git a/mex/include/liblte/mex/mexutils.h b/mex/include/liblte/mex/mexutils.h index 0c2aef266..c3cccda56 100644 --- a/mex/include/liblte/mex/mexutils.h +++ b/mex/include/liblte/mex/mexutils.h @@ -66,6 +66,11 @@ LIBLTE_API int mexutils_write_uint8(uint8_t *buffer, uint32_t nr, uint32_t nc); +LIBLTE_API int mexutils_write_int(int *buffer, + mxArray **ptr, + uint32_t nr, + uint32_t nc); + LIBLTE_API int mexutils_read_f(const mxArray *ptr, float **buffer); diff --git a/mex/lib/mexutils.c b/mex/lib/mexutils.c index 7706917a4..6297e4c60 100644 --- a/mex/lib/mexutils.c +++ b/mex/lib/mexutils.c @@ -138,3 +138,14 @@ int mexutils_write_uint8(uint8_t *buffer, mxArray **ptr, uint32_t nr, uint32_t n return -1; } } + +int mexutils_write_int(int *buffer, mxArray **ptr, uint32_t nr, uint32_t nc) { + *ptr = mxCreateNumericMatrix(nr, nc, mxINT32_CLASS, mxREAL); + if (*ptr) { + int *outr = (int*) mxGetPr(*ptr); + memcpy(outr, buffer, nr*nc*sizeof(int)); + return nc*nr; + } else { + return -1; + } +}