diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m index cc0a700fb..9ca47f7a2 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 @@ -217,13 +217,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/pdcch_bler.m b/matlab/tests/pdcch_bler.m index 1843d9e8c..d63883b7d 100644 --- a/matlab/tests/pdcch_bler.m +++ b/matlab/tests/pdcch_bler.m @@ -11,7 +11,7 @@ SNR_values = linspace(2,6,6); txCFI = 3; enbConfig.NDLRB = 15; % No of Downlink RBs in total BW enbConfig.CyclicPrefix = 'Normal'; % CP length -enbConfig.CFI = txCFI; ; % 4 PDCCH symbols as NDLRB <= 10 +enbConfig.CFI = txCFI; % 4 PDCCH symbols as NDLRB <= 10 enbConfig.Ng = 'One'; % HICH groups enbConfig.CellRefP = 1; % 1-antenna ports enbConfig.NCellID = 0; % Physical layer cell identity @@ -23,7 +23,7 @@ C_RNTI = 1; % 16-bit UE-specific mask %% Setup Fading channel model cfg.Seed = 8; % Random channel seed cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'EVA'; % EVA delay spread +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 @@ -56,7 +56,7 @@ dciConfig.Allocation.RIV = 26; % Resource indication value if C_RNTI<65535 pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier end -pdcchConfig.PDCCHFormat = 0; % PDCCH format +pdcchConfig.PDCCHFormat = 3; % PDCCH format ueConfig.RNTI = C_RNTI; candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'}); @@ -153,7 +153,7 @@ for snr_idx=1:length(SNR_values) %% Same with srsLTE [rxCFI_srslte, pcfichRx2, pcfichSymbols2] = srslte_pcfich(enbConfigRx, subframe_rx); decoded_cfi_srslte(snr_idx) = decoded_cfi_srslte(snr_idx) + (rxCFI_srslte == txCFI); - enbConfigRx.CFI = rxCFI; + enbConfigRx.CFI = txCFI; [found_srslte, pdcchBits2, pdcchRx2, pdcchSymbols2, hest2] = srslte_pdcch(enbConfigRx, ueConfig.RNTI, subframe_rx, hest, nest); decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+found_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/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 4249137d8..665ff8047 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -8,13 +8,38 @@ recordedSignal=[]; Npackets = 1; -SNR_values = 10;%linspace(2,6,10); +SNR_values = 56;%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,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'; @@ -28,7 +53,7 @@ end flen=rmccFgOut.SamplingRate/1000; -Nsf = 9; +Nsf = 2; %% Setup Fading channel model cfg.Seed = 0; % Random channel seed @@ -46,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 @@ -70,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 @@ -129,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/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index 456b2af95..9e5762701 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -66,7 +66,7 @@ srslte_cell_t cell = { int net_port = -1; // -1 generates random dataThat means there is some problem sending samples to the device -uint32_t cfi=2; +uint32_t cfi=3; uint32_t mcs_idx = 1, last_mcs_idx = 1; int nof_frames = -1; @@ -597,7 +597,12 @@ int main(int argc, char **argv) { for (i=0;inoise_alg = SRSLTE_NOISE_ALG_PSS; + q->smooth_filter_len = 3; srslte_chest_dl_set_smooth_filter3_coeff(q, 0.1); @@ -139,14 +163,21 @@ void srslte_chest_dl_free(srslte_chest_dl_t *q) } /* Uses the difference between the averaged and non-averaged pilot estimates */ -float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) +static float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) { int nref=SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id); - float power = srslte_chest_estimate_noise_pilots(q->pilot_estimates, - q->pilot_estimates_average, - q->tmp_noise, - nref); - + /* Substract noisy pilot estimates */ + srslte_vec_sub_ccc(q->pilot_estimates_average, q->pilot_estimates, q->tmp_noise, nref); + +#ifdef FREQ_SEL_SNR + /* Compute frequency-selective SNR */ + srslte_vec_abs_square_cf(q->tmp_noise, q->snr_vector, nref); + srslte_vec_abs_square_cf(q->pilot_estimates, q->pilot_power, nref); + srslte_vec_div_fff(q->pilot_power, q->snr_vector, q->snr_vector, nref); + + srslte_vec_fprint_f(stdout, q->snr_vector, nref); +#endif + /* Compute average power. Normalized for filter len 3 using matlab */ float norm = 1; if (q->smooth_filter_len == 3) { @@ -154,10 +185,10 @@ float estimate_noise_pilots(srslte_chest_dl_t *q, uint32_t port_id) float norm3 = 6.143*a*a+0.04859*a-0.002774; norm /= norm3; } - return norm*q->cell.nof_ports*power; + float power = norm*q->cell.nof_ports*srslte_vec_avg_power_cf(q->tmp_noise, nref); + 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 */ @@ -177,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; @@ -192,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)] @@ -251,16 +277,25 @@ void srslte_chest_dl_set_smooth_filter(srslte_chest_dl_t *q, float *filter, uint } } -void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) { - srslte_chest_set_smooth_filter3_coeff(q->smooth_filter, w); - q->smooth_filter_len = 3; +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; } -static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) +void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, float w) { + q->smooth_filter_len = 3; + q->smooth_filter[0] = w; + q->smooth_filter[2] = w; + q->smooth_filter[1] = 1-2*w; +} + +static void average_pilots(srslte_chest_dl_t *q, cf_t *input, cf_t *output, uint32_t port_id) { uint32_t nsymbols = srslte_refsignal_cs_nof_symbols(port_id); uint32_t nref = 2*q->cell.nof_prb; - srslte_chest_average_pilots(input, output, q->smooth_filter, nref, nsymbols, q->smooth_filter_len); + + for (int l=0;lsmooth_filter, &output[l*nref], nref, q->smooth_filter_len); + } } float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) { @@ -283,26 +318,29 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u /* Use the known CSR signal to compute Least-squares estimates */ 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 */ @@ -338,8 +376,6 @@ float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { #endif } - - float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) { return 4*q->rssi[0]/q->cell.nof_prb/SRSLTE_NRE; } diff --git a/srslte/lib/fec/test/viterbi_test_mex.c b/srslte/lib/fec/test/viterbi_test_mex.c index dfec6a533..9d1862ae5 100644 --- a/srslte/lib/fec/test/viterbi_test_mex.c +++ b/srslte/lib/fec/test/viterbi_test_mex.c @@ -60,7 +60,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) output_data = srslte_vec_malloc(nof_bits * sizeof(uint8_t)); - uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; + int poly[3] = { 0x6D, 0x4F, 0x57 }; if (srslte_viterbi_init(&viterbi, SRSLTE_VITERBI_37, poly, nof_bits/3, true)) { return; } diff --git a/srslte/lib/fec/viterbi.c b/srslte/lib/fec/viterbi.c index 08356e57a..11a3d2c1e 100644 --- a/srslte/lib/fec/viterbi.c +++ b/srslte/lib/fec/viterbi.c @@ -40,6 +40,8 @@ #define TB_ITER 3 +#define DEFAULT_GAIN 16 + //#undef LV_HAVE_SSE int decode37(void *o, uint8_t *symbols, uint8_t *data, uint32_t frame_length) { @@ -128,12 +130,12 @@ void free37(void *o) { delete_viterbi37_port(q->ptr); } -int init37(srslte_viterbi_t *q, uint32_t poly[3], uint32_t framebits, bool tail_biting) { +int init37(srslte_viterbi_t *q, int poly[3], uint32_t framebits, bool tail_biting) { q->K = 7; q->R = 3; q->framebits = framebits; - q->gain_quant = 32; q->gain_quant_s = 4; + q->gain_quant = DEFAULT_GAIN; q->tail_biting = tail_biting; q->decode = decode37; q->free = free37; @@ -165,12 +167,12 @@ int init37(srslte_viterbi_t *q, uint32_t poly[3], uint32_t framebits, bool tail_ } #ifdef LV_HAVE_SSE -int init37_sse(srslte_viterbi_t *q, uint32_t poly[3], uint32_t framebits, bool tail_biting) { +int init37_sse(srslte_viterbi_t *q, int poly[3], uint32_t framebits, bool tail_biting) { q->K = 7; q->R = 3; q->framebits = framebits; - q->gain_quant = 20; q->gain_quant_s = 4; + q->gain_quant = DEFAULT_GAIN; q->tail_biting = tail_biting; q->decode = decode37_sse; q->free = free37_sse; @@ -209,7 +211,7 @@ void srslte_viterbi_set_gain_quant_s(srslte_viterbi_t *q, int16_t gain_quant) { q->gain_quant_s = gain_quant; } -int srslte_viterbi_init(srslte_viterbi_t *q, srslte_viterbi_type_t type, uint32_t poly[3], uint32_t max_frame_length, bool tail_bitting) +int srslte_viterbi_init(srslte_viterbi_t *q, srslte_viterbi_type_t type, int poly[3], uint32_t max_frame_length, bool tail_bitting) { switch (type) { case SRSLTE_VITERBI_37: @@ -225,7 +227,7 @@ int srslte_viterbi_init(srslte_viterbi_t *q, srslte_viterbi_type_t type, uint32_ } #ifdef LV_HAVE_SSE -int srslte_viterbi_init_sse(srslte_viterbi_t *q, srslte_viterbi_type_t type, uint32_t poly[3], uint32_t max_frame_length, bool tail_bitting) +int srslte_viterbi_init_sse(srslte_viterbi_t *q, srslte_viterbi_type_t type, int poly[3], uint32_t max_frame_length, bool tail_bitting) { return init37_sse(q, poly, max_frame_length, tail_bitting); } @@ -252,7 +254,7 @@ int srslte_viterbi_decode_f(srslte_viterbi_t *q, float *symbols, uint8_t *data, } else { len = 3 * (frame_length + q->K - 1); } - if (!q->decode_f) { + if (!q->decode_f) { srslte_vec_quant_fuc(symbols, q->symbols_uc, q->gain_quant, 127.5, 255, len); return srslte_viterbi_decode_uc(q, q->symbols_uc, data, frame_length); } else { diff --git a/srslte/lib/fec/viterbi37.h b/srslte/lib/fec/viterbi37.h index 36585daff..f5f304858 100644 --- a/srslte/lib/fec/viterbi37.h +++ b/srslte/lib/fec/viterbi37.h @@ -26,7 +26,7 @@ #include -void *create_viterbi37_port(uint32_t polys[3], +void *create_viterbi37_port(int polys[3], uint32_t len); int init_viterbi37_port(void *p, @@ -45,7 +45,7 @@ int update_viterbi37_blk_port(void *p, uint32_t *best_state); -void *create_viterbi37_sse(uint32_t polys[3], +void *create_viterbi37_sse(int polys[3], uint32_t len); int init_viterbi37_sse(void *p, diff --git a/srslte/lib/fec/viterbi37_port.c b/srslte/lib/fec/viterbi37_port.c index c55d95b4e..cf05b3c53 100644 --- a/srslte/lib/fec/viterbi37_port.c +++ b/srslte/lib/fec/viterbi37_port.c @@ -54,8 +54,8 @@ int init_viterbi37_port(void *p, int starting_state) { return 0; } -void set_viterbi37_polynomial_port(uint32_t polys[3]) { - uint32_t state; +void set_viterbi37_polynomial_port(int polys[3]) { + int state; for (state = 0; state < 32; state++) { Branchtab37[0].c[state] = @@ -68,7 +68,7 @@ void set_viterbi37_polynomial_port(uint32_t polys[3]) { } /* Create a new instance of a Viterbi decoder */ -void *create_viterbi37_port(uint32_t polys[3], uint32_t len) { +void *create_viterbi37_port(int polys[3], uint32_t len) { struct v37 *vp; set_viterbi37_polynomial_port(polys); diff --git a/srslte/lib/fec/viterbi37_sse.c b/srslte/lib/fec/viterbi37_sse.c index ffafd693d..3ecbfeefc 100644 --- a/srslte/lib/fec/viterbi37_sse.c +++ b/srslte/lib/fec/viterbi37_sse.c @@ -44,7 +44,7 @@ struct v37 { decision_t *decisions; /* Beginning of decisions for block */ }; -void set_viterbi37_polynomial_sse(uint32_t polys[3]) { +void set_viterbi37_polynomial_sse(int polys[3]) { int state; for(state=0;state < 32;state++){ @@ -73,7 +73,7 @@ int init_viterbi37_sse(void *p, int starting_state) { } /* Create a new instance of a Viterbi decoder */ -void *create_viterbi37_sse(uint32_t polys[3], uint32_t len) { +void *create_viterbi37_sse(int polys[3], uint32_t len) { void *p; struct v37 *vp; diff --git a/srslte/lib/phch/cqi.c b/srslte/lib/phch/cqi.c index 175065fcd..99345968e 100644 --- a/srslte/lib/phch/cqi.c +++ b/srslte/lib/phch/cqi.c @@ -71,7 +71,7 @@ int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg, uint8_t b uint8_t *body_ptr = buff; srslte_bit_unpack(msg->subband_cqi, &body_ptr, 4); srslte_bit_unpack(msg->subband_label, &body_ptr, msg->subband_label_2_bits?2:1); - return 4+msg->subband_label_2_bits?2:1; + return 4+(msg->subband_label_2_bits)?2:1; } int srslte_cqi_value_pack(srslte_cqi_value_t *value, uint8_t buff[SRSLTE_CQI_MAX_BITS]) @@ -141,7 +141,11 @@ bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) { /* SNR-to-CQI conversion, got from "Downlink SNR to CQI Mapping for Different Multiple Antenna Techniques in LTE" * Table III. */ -static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 23.45, 25.0, 27.30, 29}; +// Original version +//static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 23.45, 25.0, 27.30, 29}; + +// From experimental measurements @ 5 MHz +static float cqi_to_snr_table[15] = { 1, 1.75, 3, 4, 5, 6, 7.5, 9, 11.5, 13.0, 15.0, 18, 20, 22.5, 26.5}; uint8_t srslte_cqi_from_snr(float snr) { diff --git a/srslte/lib/phch/pbch.c b/srslte/lib/phch/pbch.c index 3dfaa07f1..40f9d4b5b 100644 --- a/srslte/lib/phch/pbch.c +++ b/srslte/lib/phch/pbch.c @@ -158,7 +158,7 @@ int srslte_pbch_init(srslte_pbch_t *q, srslte_cell_t cell) { goto clean; } - uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; + int poly[3] = { 0x6D, 0x4F, 0x57 }; if (srslte_viterbi_init(&q->decoder, SRSLTE_VITERBI_37, poly, 40, true)) { goto clean; } diff --git a/srslte/lib/phch/pcfich.c b/srslte/lib/phch/pcfich.c index b24119b42..e1fc400a3 100644 --- a/srslte/lib/phch/pcfich.c +++ b/srslte/lib/phch/pcfich.c @@ -117,14 +117,16 @@ float srslte_pcfich_cfi_decode(srslte_pcfich_t *q, uint32_t *cfi) { int i; int index = 0; float max_corr = 0; + float corr[3]; for (i = 0; i < 3; i++) { - float corr = fabsf(srslte_vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN)); - if (corr > max_corr) { - max_corr = corr; + corr[i] = srslte_vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN); + if (corr[i] > max_corr) { + max_corr = corr[i]; index = i; } } + if (cfi) { *cfi = index + 1; } @@ -134,7 +136,7 @@ float srslte_pcfich_cfi_decode(srslte_pcfich_t *q, uint32_t *cfi) { /** Encodes the CFI producing a vector of 32 bits. * 36.211 10.3 section 5.3.4 */ -int srslte_pcfich_cfi_encode(int cfi, uint8_t bits[PCFICH_CFI_LEN]) { +int srslte_pcfich_cfi_encode(uint32_t cfi, uint8_t bits[PCFICH_CFI_LEN]) { if (cfi < 1 || cfi > 3) { return SRSLTE_ERROR_INVALID_INPUTS; } else{ @@ -220,8 +222,7 @@ int srslte_pcfich_encode(srslte_pcfich_t *q, uint32_t cfi, cf_t *slot_symbols[SR int i; if (q != NULL && - cfi <= 3 && - cfi > 0 && + cfi <= 3 && slot_symbols != NULL && subframe < SRSLTE_NSUBFRAMES_X_FRAME) { diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index a218a1445..06dde712a 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -88,7 +88,7 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell } } - uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; + int poly[3] = { 0x6D, 0x4F, 0x57 }; if (srslte_viterbi_init(&q->decoder, SRSLTE_VITERBI_37, poly, SRSLTE_DCI_MAX_BITS + 16, true)) { goto clean; } @@ -192,7 +192,7 @@ uint32_t srslte_pdcch_ue_locations(srslte_pdcch_t *q, srslte_dci_location_t *c, k = 0; // All aggregation levels from 8 to 1 - for (l = 0; l < 3; l++) { + for (l = 3; l >= 0; l--) { L = (1 << l); // For all possible ncce offset for (i = 0; i < SRSLTE_MIN(q->nof_cce / L, S[l]/PDCCH_FORMAT_NOF_CCE(l)); i++) { @@ -277,8 +277,10 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui { bzero(q->rm_f, sizeof(float)*3 * (SRSLTE_DCI_MAX_BITS + 16)); + uint32_t coded_len = 3 * (nof_bits + 16); + /* unrate matching */ - srslte_rm_conv_rx(e, E, q->rm_f, 3 * (nof_bits + 16)); + srslte_rm_conv_rx(e, E, q->rm_f, coded_len); /* viterbi decoder */ srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16); @@ -290,6 +292,7 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui if (crc) { *crc = p_bits ^ crc_res; } + return SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parameters: E: %d, max_bits: %d, nof_bits: %d\n", E, q->max_bits, nof_bits); @@ -403,7 +406,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT /* in control channels, only diversity is supported */ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ - srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, nof_symbols, noise_estimate); + srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, nof_symbols, noise_estimate/2); } else { srslte_predecoding_diversity(q->symbols[0], q->ce, x, q->cell.nof_ports, nof_symbols); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 91b1286d4..721e568fa 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -235,7 +235,7 @@ int srslte_prach_gen_seqs(srslte_prach_t *p) uint32_t d_u = 0; uint32_t d_start = 0; uint32_t N_shift = 0; - uint32_t N_neg_shift = 0; + int N_neg_shift = 0; uint32_t N_group = 0; uint32_t C_v = 0; cf_t root[839]; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index cbc28d09a..2400c6a81 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -194,16 +194,12 @@ int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf /* Correct SFO multiplying by complex exponential in the time domain */ if (q->sample_offset) { - struct timeval t[3]; - gettimeofday(&t[1], NULL); for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { srslte_cfo_correct(&q->sfo_correct, &q->sf_symbols[i*q->cell.nof_prb*SRSLTE_NRE], &q->sf_symbols[i*q->cell.nof_prb*SRSLTE_NRE], q->sample_offset / q->fft.symbol_sz); } - gettimeofday(&t[2], NULL); - get_time_interval(t); } return srslte_ue_dl_decode_estimate(q, sf_idx, cfi); @@ -221,7 +217,8 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c /* First decode PCFICH and obtain CFI */ if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, - srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { + srslte_chest_dl_get_noise_estimate(&q->chest), + sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); return SRSLTE_ERROR; } @@ -405,7 +402,7 @@ int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, u return ret; } - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, 0, sf_idx, q->cfi)) { + if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, q->cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; }