From c8bc53e74953ba337216a86f20f915a281c61a7b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 23 Aug 2016 09:17:41 -0700 Subject: [PATCH 01/38] Initial changes --- matlab/tests/diversity_decode_test.m | 18 ++-- matlab/tests/pdsch_equal.m | 40 ++----- srslte/include/srslte/common/phy_common.h | 1 + srslte/include/srslte/mimo/precoding.h | 7 ++ srslte/lib/mimo/precoding.c | 121 +++++++++++++++++----- 5 files changed, 121 insertions(+), 66 deletions(-) diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m index 9f21a971b..536feebdc 100644 --- a/matlab/tests/diversity_decode_test.m +++ b/matlab/tests/diversity_decode_test.m @@ -10,7 +10,7 @@ cec.InterpWinSize = 1; cec.InterpWindow = 'Causal'; cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna +cfg.NRxAnts = 2; % 1 receive antenna cfg.DelayProfile = 'ETU'; % EVA delay spread cfg.DopplerFreq = 100; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation @@ -29,16 +29,20 @@ txWaveform = txWaveform+complex(randn(n,2),randn(n,2))*1e-3; rxWaveform = lteFadingChannel(cfg,txWaveform); -rxGrid = lteOFDMDemodulate(enb,sum(rxWaveform,2)); +rxGrid = lteOFDMDemodulate(enb,rxWaveform); [h,n0] = lteDLChannelEstimate(enb,cec,rxGrid); -signal=rxGrid(:,1); -hest(:,1,1)=reshape(h(:,1,1,1),[],1); -hest(:,1,2)=reshape(h(:,1,1,1),[],1); +s=size(h); +p=s(1); +Nt=s(4); +Nr=s(3); -output_mat = lteTransmitDiversityDecode(signal(, hest(1:598,1,:)); -output_srs = srslte_diversitydecode(signal(1:598), hest(1:598,1,:)); +rx=reshape(rxGrid(:,1,:),p,Nr); +hp=reshape(h(:,1,:,:),p,Nr,Nt); + +output_mat = lteTransmitDiversityDecode(rx, hp); +output_srs = srslte_diversitydecode(rx, hp); plot(abs(output_mat-output_srs)) mean(abs(output_mat-output_srs).^2) diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 665ff8047..d418f485a 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -10,30 +10,6 @@ recordedSignal=[]; Npackets = 1; 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.5',[1;0;0;1]); waveform = sum(waveform,2); @@ -53,11 +29,11 @@ end flen=rmccFgOut.SamplingRate/1000; -Nsf = 2; +Nsf = 1; %% Setup Fading channel model cfg.Seed = 0; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna +cfg.NRxAnts = 2; % 1 receive antenna cfg.DelayProfile = 'EPA'; % EVA delay spread cfg.DopplerFreq = 5; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation @@ -87,16 +63,13 @@ for snr_idx=1:length(SNR_values) 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, chinfo] = lteFadingChannel(cfg,waveform); - rxWaveform = rxWaveform(chinfo.ChannelFilterDelay+1:end); + rxWaveform = rxWaveform(chinfo.ChannelFilterDelay+1:end,:); %rxWaveform = waveform; %% Noise Addition @@ -111,12 +84,12 @@ for snr_idx=1:length(SNR_values) for sf_idx=0:Nsf-1 % sf_idx=9; - subframe_rx=frame_rx(:,sf_idx*14+1:(sf_idx+1)*14); + 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); + [hest, nest] = lteDLChannelEstimate(rmccFgOut, cec, subframe_rx); [cws,symbols] = ltePDSCHDecode(rmccFgOut,rmccFgOut.PDSCH,subframe_rx,hest,nest); [trblkout,blkcrc,dstate] = lteDLSCHDecode(rmccFgOut,rmccFgOut.PDSCH, ... @@ -155,7 +128,8 @@ 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})) + plot(abs(symbols{1}-pdschSymbols2)) + %scatter(real(symbols{1}),imag(symbols{1})) fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/srslte/include/srslte/common/phy_common.h b/srslte/include/srslte/common/phy_common.h index 81cce7b66..ec308ae8b 100644 --- a/srslte/include/srslte/common/phy_common.h +++ b/srslte/include/srslte/common/phy_common.h @@ -49,6 +49,7 @@ #define SRSLTE_PC_MAX 23 // Maximum TX power for Category 1 UE (in dBm) +#define SRSLTE_MAX_RXANT 2 #define SRSLTE_MAX_PORTS 4 #define SRSLTE_MAX_LAYERS 8 #define SRSLTE_MAX_CODEWORDS 2 diff --git a/srslte/include/srslte/mimo/precoding.h b/srslte/include/srslte/mimo/precoding.h index 3e95494b5..667e1d02b 100644 --- a/srslte/include/srslte/mimo/precoding.h +++ b/srslte/include/srslte/mimo/precoding.h @@ -70,6 +70,13 @@ SRSLTE_API int srslte_predecoding_single(cf_t *y, int nof_symbols, float noise_estimate); +SRSLTE_API int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], + cf_t *h[SRSLTE_MAX_RXANT], + cf_t *x, + int nof_rxant, + int nof_symbols, + float noise_estimate); + SRSLTE_API int srslte_predecoding_diversity(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 6a6dab7ff..3b1d9a649 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -37,13 +37,13 @@ #ifdef LV_HAVE_SSE #include #include -int srslte_predecoding_single_sse(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float noise_estimate); +int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); int srslte_predecoding_diversity2_sse(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_symbols); #endif #ifdef LV_HAVE_AVX #include -int srslte_predecoding_single_avx(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float noise_estimate); +int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); #endif @@ -58,40 +58,75 @@ int srslte_predecoding_single_avx(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, fl #define PROD(a,b) _mm_addsub_ps(_mm_mul_ps(a,_mm_moveldup_ps(b)),_mm_mul_ps(_mm_shuffle_ps(a,a,0xB1),_mm_movehdup_ps(b))) -int srslte_predecoding_single_sse(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { float *xPtr = (float*) x; - const float *hPtr = (const float*) h; - const float *yPtr = (const float*) y; + const float *hPtr1 = (const float*) h[0]; + const float *yPtr1 = (const float*) y[0]; + const float *hPtr2 = (const float*) h[1]; + const float *yPtr2 = (const float*) y[1]; __m128 conjugator = _mm_setr_ps(0, -0.f, 0, -0.f); __m128 noise = _mm_set1_ps(noise_estimate); - __m128 h1Val, h2Val, y1Val, y2Val, h12square, h1square, h2square, h1conj, h2conj, x1Val, x2Val; + __m128 h1Val1, h2Val1, y1Val1, y2Val1; + __m128 h1Val2, h2Val2, y1Val2, y2Val2; + __m128 h12square1, h1square1, h2square1, h1conj1, h2conj1, x1Val1, x2Val1; + __m128 h12square2, h1square2, h2square2, h1conj2, h2conj2, x1Val2, x2Val2; + for (int i=0;i 0) { - h12square = _mm_add_ps(h12square, noise); + y1Val1 = _mm_load_ps(yPtr1); yPtr1+=4; + y2Val1 = _mm_load_ps(yPtr1); yPtr1+=4; + h1Val1 = _mm_load_ps(hPtr1); hPtr1+=4; + h2Val1 = _mm_load_ps(hPtr1); hPtr1+=4; + + if (nof_rxant == 2) { + y1Val2 = _mm_load_ps(yPtr2); yPtr2+=4; + y2Val2 = _mm_load_ps(yPtr2); yPtr2+=4; + h1Val2 = _mm_load_ps(hPtr2); hPtr2+=4; + h2Val2 = _mm_load_ps(hPtr2); hPtr2+=4; } - h1square = _mm_shuffle_ps(h12square, h12square, _MM_SHUFFLE(1, 1, 0, 0)); - h2square = _mm_shuffle_ps(h12square, h12square, _MM_SHUFFLE(3, 3, 2, 2)); + h12square1 = _mm_hadd_ps(_mm_mul_ps(h1Val1, h1Val1), _mm_mul_ps(h2Val1, h2Val1)); + if (nof_rxant == 2) { + h12square2 = _mm_hadd_ps(_mm_mul_ps(h1Val2, h1Val2), _mm_mul_ps(h2Val2, h2Val2)); + h12square1 = _mm_add_ps(h12square1, h12square2); + } + if (noise_estimate > 0) { + h12square1 = _mm_add_ps(h12square1, noise); + } + + h1square1 = _mm_shuffle_ps(h12square1, h12square1, _MM_SHUFFLE(1, 1, 0, 0)); + h2square1 = _mm_shuffle_ps(h12square1, h12square1, _MM_SHUFFLE(3, 3, 2, 2)); + + if (nof_rxant == 2) { + h1square2 = _mm_shuffle_ps(h12square2, h12square2, _MM_SHUFFLE(1, 1, 0, 0)); + h2square2 = _mm_shuffle_ps(h12square2, h12square2, _MM_SHUFFLE(3, 3, 2, 2)); + + h1square1 = _mm_add_ps(h1square1, h1square2); + h2square1 = _mm_add_ps(h2square1, h2square2); + } /* Conjugate channel */ - h1conj = _mm_xor_ps(h1Val, conjugator); - h2conj = _mm_xor_ps(h2Val, conjugator); + h1conj1 = _mm_xor_ps(h1Val1, conjugator); + h2conj1 = _mm_xor_ps(h2Val1, conjugator); + if (nof_rxant == 2) { + h1conj2 = _mm_xor_ps(h1Val2, conjugator); + h2conj2 = _mm_xor_ps(h2Val2, conjugator); + } + /* Complex product */ - x1Val = PROD(y1Val, h1conj); - x2Val = PROD(y2Val, h2conj); + x1Val1 = PROD(y1Val1, h1conj1); + x2Val1 = PROD(y2Val1, h2conj1); - x1Val = _mm_div_ps(x1Val, h1square); - x2Val = _mm_div_ps(x2Val, h2square); + if (nof_rxant == 2) { + x1Val2 = PROD(y1Val2, h1conj2); + x2Val2 = PROD(y2Val2, h2conj2); + } + + x1Val1 = _mm_div_ps(x1Val1, h1square1); + x2Val1 = _mm_div_ps(x2Val1, h2square1); _mm_store_ps(xPtr, x1Val); xPtr+=4; _mm_store_ps(xPtr, x2Val); xPtr+=4; @@ -110,7 +145,7 @@ int srslte_predecoding_single_sse(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, fl -int srslte_predecoding_single_avx(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { float *xPtr = (float*) x; const float *hPtr = (const float*) h; @@ -160,15 +195,28 @@ int srslte_predecoding_single_avx(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, fl #endif -int srslte_predecoding_single_gen(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_gen(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { for (int i=0;i 32) { return srslte_predecoding_single_avx(y, h, x, nof_symbols, noise_estimate); @@ -183,7 +231,28 @@ int srslte_predecoding_single(cf_t *y, cf_t *h, cf_t *x, int nof_symbols, float return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); } #else + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); + #endif +#endif +} + +/* ZF/MMSE SISO equalizer x=y(h'h+no)^(-1)h' (ZF if n0=0.0)*/ +int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { +#ifdef LV_HAVE_AVX + if (nof_symbols > 32) { + return srslte_predecoding_single_avx(y, h, x, nof_symbols, noise_estimate); + } else { return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + } +#else + #ifdef LV_HAVE_SSE + if (nof_symbols > 32) { + return srslte_predecoding_single_sse(y, h, x, nof_symbols, noise_estimate); + } else { + return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + } + #else + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); #endif #endif } From 5fcb95d54dad28ae7325d0ec0587f44f8db7e9cf Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Sep 2016 09:47:31 -0400 Subject: [PATCH 02/38] 2rx equalizer working in matlab in gen/sse --- matlab/tests/diversity_decode_test.m | 46 +++++++++---- srslte/lib/mimo/precoding.c | 75 +++++++++++---------- srslte/lib/mimo/test/diversitydecode_mex.c | 77 +++++++++++++++------- 3 files changed, 127 insertions(+), 71 deletions(-) diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m index 536feebdc..75c29c2e3 100644 --- a/matlab/tests/diversity_decode_test.m +++ b/matlab/tests/diversity_decode_test.m @@ -1,8 +1,9 @@ clear -addpath('../../build/srslte/lib/mimo/test') +addpath('../../debug/srslte/lib/mimo/test') -enb = lteRMCDL('R.10'); +%enb = lteRMCDL('R.10'); % 2-ports +enb = lteRMCDL('R.0'); % 1-ports cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic'); cec.PilotAverage = 'UserDefined'; @@ -10,7 +11,7 @@ cec.InterpWinSize = 1; cec.InterpWindow = 'Causal'; cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 2; % 1 receive antenna +cfg.NRxAnts = 1; % 1 receive antenna cfg.DelayProfile = 'ETU'; % EVA delay spread cfg.DopplerFreq = 100; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation @@ -22,10 +23,9 @@ cfg.NormalizePathGains = 'On'; % Normalize delay profile power cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas [txWaveform, ~, info] = lteRMCDLTool(enb,[1;0;0;1]); -n = length(txWaveform); cfg.SamplingRate = info.SamplingRate; -txWaveform = txWaveform+complex(randn(n,2),randn(n,2))*1e-3; +txWaveform = txWaveform+complex(randn(size(txWaveform)),randn(size(txWaveform)))*1e-3; rxWaveform = lteFadingChannel(cfg,txWaveform); @@ -35,16 +35,36 @@ rxGrid = lteOFDMDemodulate(enb,rxWaveform); s=size(h); p=s(1); -Nt=s(4); -Nr=s(3); +n=s(2); +if (length(s)>2) + Nr=s(3); +else + Nr=1; +end +if (length(s)>3) + Nt=s(4); +else + Nt=1; +end -rx=reshape(rxGrid(:,1,:),p,Nr); -hp=reshape(h(:,1,:,:),p,Nr,Nt); +if (Nr > 1) + rx=reshape(rxGrid,p,n,Nr); + hp=reshape(h,p,n,Nr,Nt); +else + rx=rxGrid; + hp=h; +end -output_mat = lteTransmitDiversityDecode(rx, hp); -output_srs = srslte_diversitydecode(rx, hp); +if (Nt > 1) + output_mat = lteTransmitDiversityDecode(rx, hp); +else + output_mat = lteEqualizeMMSE(rx, hp, n0); +end +output_srs = srslte_diversitydecode(rx, hp, n0); -plot(abs(output_mat-output_srs)) -mean(abs(output_mat-output_srs).^2) +plot(abs(output_mat(:)-output_srs(:))) +mean(abs(output_mat(:)-output_srs(:)).^2) +t=1:10; +plot(t,real(output_mat(t)),t,real(output_srs(t))) diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 3b1d9a649..78cdaaecc 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -71,9 +71,9 @@ int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ __m128 noise = _mm_set1_ps(noise_estimate); __m128 h1Val1, h2Val1, y1Val1, y2Val1; __m128 h1Val2, h2Val2, y1Val2, y2Val2; - __m128 h12square1, h1square1, h2square1, h1conj1, h2conj1, x1Val1, x2Val1; - __m128 h12square2, h1square2, h2square2, h1conj2, h2conj2, x1Val2, x2Val2; - + __m128 hsquare, h1square, h2square, h1conj1, h2conj1, x1Val1, x2Val1; + __m128 hsquare2, h1conj2, h2conj2, x1Val2, x2Val2; + for (int i=0;i 0) { - h12square1 = _mm_add_ps(h12square1, noise); + hsquare = _mm_add_ps(hsquare, noise); } - h1square1 = _mm_shuffle_ps(h12square1, h12square1, _MM_SHUFFLE(1, 1, 0, 0)); - h2square1 = _mm_shuffle_ps(h12square1, h12square1, _MM_SHUFFLE(3, 3, 2, 2)); - - if (nof_rxant == 2) { - h1square2 = _mm_shuffle_ps(h12square2, h12square2, _MM_SHUFFLE(1, 1, 0, 0)); - h2square2 = _mm_shuffle_ps(h12square2, h12square2, _MM_SHUFFLE(3, 3, 2, 2)); - - h1square1 = _mm_add_ps(h1square1, h1square2); - h2square1 = _mm_add_ps(h2square1, h2square2); - } + h1square = _mm_shuffle_ps(hsquare, hsquare, _MM_SHUFFLE(1, 1, 0, 0)); + h2square = _mm_shuffle_ps(hsquare, hsquare, _MM_SHUFFLE(3, 3, 2, 2)); /* Conjugate channel */ h1conj1 = _mm_xor_ps(h1Val1, conjugator); @@ -122,17 +114,26 @@ int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ if (nof_rxant == 2) { x1Val2 = PROD(y1Val2, h1conj2); - x2Val2 = PROD(y2Val2, h2conj2); + x2Val2 = PROD(y2Val2, h2conj2); + x1Val1 = _mm_add_ps(x1Val1, x1Val2); + x2Val1 = _mm_add_ps(x2Val1, x2Val2); } - x1Val1 = _mm_div_ps(x1Val1, h1square1); - x2Val1 = _mm_div_ps(x2Val1, h2square1); + x1Val1 = _mm_div_ps(x1Val1, h1square); + x2Val1 = _mm_div_ps(x2Val1, h2square); + + _mm_store_ps(xPtr, x1Val1); xPtr+=4; + _mm_store_ps(xPtr, x2Val1); xPtr+=4; - _mm_store_ps(xPtr, x1Val); xPtr+=4; - _mm_store_ps(xPtr, x2Val); xPtr+=4; } for (int i=8*(nof_symbols/8);i 32) { - return srslte_predecoding_single_avx(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { - return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else #ifdef LV_HAVE_SSE if (nof_symbols > 32) { - return srslte_predecoding_single_sse(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_sse(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { - return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); @@ -240,16 +249,16 @@ int srslte_predecoding_single(cf_t *y_, cf_t *h_, cf_t *x, int nof_symbols, floa int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { #ifdef LV_HAVE_AVX if (nof_symbols > 32) { - return srslte_predecoding_single_avx(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { - return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else #ifdef LV_HAVE_SSE if (nof_symbols > 32) { - return srslte_predecoding_single_sse(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_sse(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { - return srslte_predecoding_single_gen(y, h, x, nof_symbols, noise_estimate); + return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); diff --git a/srslte/lib/mimo/test/diversitydecode_mex.c b/srslte/lib/mimo/test/diversitydecode_mex.c index bbc99416d..7c020c6b8 100644 --- a/srslte/lib/mimo/test/diversitydecode_mex.c +++ b/srslte/lib/mimo/test/diversitydecode_mex.c @@ -33,6 +33,7 @@ #define INPUT prhs[0] #define HEST prhs[1] +#define NEST prhs[2] #define NOF_INPUTS 2 @@ -56,44 +57,70 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } // Read input symbols - nof_symbols = mexutils_read_cf(INPUT, &input); - if (nof_symbols < 0) { + if (mexutils_read_cf(INPUT, &input) < 0) { mexErrMsgTxt("Error reading input\n"); return; } + uint32_t nof_tx_ports = 1; + uint32_t nof_rx_ants = 1; + const mwSize *dims = mxGetDimensions(INPUT); + mwSize ndims = mxGetNumberOfDimensions(INPUT); + nof_symbols = dims[0]*dims[1]; + + if (ndims >= 3) { + nof_rx_ants = dims[2]; + } + if (ndims >= 4) { + nof_tx_ports = dims[3]; + } + // Read channel estimates - uint32_t nof_symbols2 = mexutils_read_cf(HEST, &hest); - if (nof_symbols < 0) { + if (mexutils_read_cf(HEST, &hest) < 0) { mexErrMsgTxt("Error reading hest\n"); return; } - if ((nof_symbols2 % nof_symbols) != 0) { - mexErrMsgTxt("Hest size must be multiple of input size\n"); - return; - } - // Calculate number of ports - uint32_t nof_ports = nof_symbols2/nof_symbols; - cf_t *x[8]; - cf_t *h[4]; + // Read noise estimate + float noise_estimate = 0; + if (nrhs >= NOF_INPUTS) { + noise_estimate = mxGetScalar(NEST); + } + + cf_t *x[SRSLTE_MAX_LAYERS]; + cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + cf_t *y[SRSLTE_MAX_RXANT]; + + for (int i=0;i 1) { + //srslte_predecoding_diversity(input, h, x, nof_tx_ports, nof_symbols); + //srslte_layerdemap_diversity(x, output, nof_tx_ports, nof_symbols / nof_tx_ports); + } else { + srslte_predecoding_single_multi(y, h[0], output, nof_rx_ants, nof_symbols, noise_estimate); } - srslte_predecoding_diversity(input, h, x, nof_ports, nof_symbols); - srslte_layerdemap_diversity(x, output, nof_ports, nof_symbols / nof_ports); - if (nlhs >= 1) { mexutils_write_cf(output, &plhs[0], nof_symbols, 1); @@ -105,7 +132,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (output) { free(output); } - for (i=0;i<8;i++) { + for (int i=0;i Date: Mon, 12 Sep 2016 09:57:20 -0400 Subject: [PATCH 03/38] 2rx equalizer working in matlab in gen/sse/avx --- srslte/lib/mimo/precoding.c | 54 ++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 78cdaaecc..22e2bdc5f 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -149,41 +149,69 @@ int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { float *xPtr = (float*) x; - const float *hPtr = (const float*) h; - const float *yPtr = (const float*) y; + const float *hPtr1 = (const float*) h[0]; + const float *yPtr1 = (const float*) y[0]; + const float *hPtr2 = (const float*) h[1]; + const float *yPtr2 = (const float*) y[1]; __m256 conjugator = _mm256_setr_ps(0, -0.f, 0, -0.f, 0, -0.f, 0, -0.f); __m256 noise = _mm256_set1_ps(noise_estimate); - __m256 h1Val, h2Val, y1Val, y2Val, h12square, h1square, h2square, h1_p, h2_p, h1conj, h2conj, x1Val, x2Val; + __m256 h1Val1, h2Val1, y1Val1, y2Val1, h12square, h1square, h2square, h1_p, h2_p, h1conj1, h2conj1, x1Val, x2Val; + __m256 h1Val2, h2Val2, y1Val2, y2Val2, h1conj2, h2conj2; printf("using avx\n"); for (int i=0;i 0) { h12square = _mm256_add_ps(h12square, noise); } + h1_p = _mm256_permute_ps(h12square, _MM_SHUFFLE(1, 1, 0, 0)); h2_p = _mm256_permute_ps(h12square, _MM_SHUFFLE(3, 3, 2, 2)); h1square = _mm256_permute2f128_ps(h1_p, h2_p, 2<<4); h2square = _mm256_permute2f128_ps(h1_p, h2_p, 3<<4 | 1); /* Conjugate channel */ - h1conj = _mm256_xor_ps(h1Val, conjugator); - h2conj = _mm256_xor_ps(h2Val, conjugator); + h1conj1 = _mm256_xor_ps(h1Val1, conjugator); + h2conj1 = _mm256_xor_ps(h2Val1, conjugator); + if (nof_rxant == 2) { + h1conj2 = _mm256_xor_ps(h1Val2, conjugator); + h2conj2 = _mm256_xor_ps(h2Val2, conjugator); + } + /* Complex product */ - x1Val = PROD_AVX(y1Val, h1conj); - x2Val = PROD_AVX(y2Val, h2conj); + x1Val = PROD_AVX(y1Val1, h1conj1); + x2Val = PROD_AVX(y2Val1, h2conj1); + if (nof_rxant == 2) { + x1Val = _mm256_add_ps(x1Val, PROD_AVX(y1Val2, h1conj2)); + x2Val = _mm256_add_ps(x2Val, PROD_AVX(y2Val2, h2conj2)); + } + x1Val = _mm256_div_ps(x1Val, h1square); x2Val = _mm256_div_ps(x2Val, h2square); From e4a94bcf33f6a25f48268b7bf86dffd613175dc3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Sep 2016 12:33:22 -0400 Subject: [PATCH 04/38] 2rx diversity equalizer working in matlab in gen/sse/avx --- matlab/tests/diversity_decode_test.m | 15 +- srslte/include/srslte/mimo/precoding.h | 7 + srslte/lib/mimo/precoding.c | 229 ++++++++++++++------- srslte/lib/mimo/test/diversitydecode_mex.c | 25 ++- 4 files changed, 183 insertions(+), 93 deletions(-) diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m index 75c29c2e3..24ad28ca7 100644 --- a/matlab/tests/diversity_decode_test.m +++ b/matlab/tests/diversity_decode_test.m @@ -1,6 +1,6 @@ clear -addpath('../../debug/srslte/lib/mimo/test') +addpath('../../build/srslte/lib/mimo/test') %enb = lteRMCDL('R.10'); % 2-ports enb = lteRMCDL('R.0'); % 1-ports @@ -11,7 +11,7 @@ cec.InterpWinSize = 1; cec.InterpWindow = 'Causal'; cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna +cfg.NRxAnts = 2; % 1 receive antenna cfg.DelayProfile = 'ETU'; % EVA delay spread cfg.DopplerFreq = 100; % 120Hz Doppler frequency cfg.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation @@ -47,13 +47,8 @@ else Nt=1; end -if (Nr > 1) - rx=reshape(rxGrid,p,n,Nr); - hp=reshape(h,p,n,Nr,Nt); -else - rx=rxGrid; - hp=h; -end +rx=reshape(rxGrid,p*n,Nr); +hp=reshape(h,p*n,Nr,Nt); if (Nt > 1) output_mat = lteTransmitDiversityDecode(rx, hp); @@ -65,6 +60,6 @@ output_srs = srslte_diversitydecode(rx, hp, n0); plot(abs(output_mat(:)-output_srs(:))) mean(abs(output_mat(:)-output_srs(:)).^2) -t=1:10; +t=1:100; plot(t,real(output_mat(t)),t,real(output_srs(t))) diff --git a/srslte/include/srslte/mimo/precoding.h b/srslte/include/srslte/mimo/precoding.h index 667e1d02b..b71a38603 100644 --- a/srslte/include/srslte/mimo/precoding.h +++ b/srslte/include/srslte/mimo/precoding.h @@ -83,6 +83,13 @@ SRSLTE_API int srslte_predecoding_diversity(cf_t *y, int nof_ports, int nof_symbols); +SRSLTE_API int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_RXANT], + cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, + int nof_ports, + int nof_symbols); + SRSLTE_API int srslte_predecoding_type(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 22e2bdc5f..1b9183485 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -38,7 +38,7 @@ #include #include int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); -int srslte_predecoding_diversity2_sse(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_symbols); +int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_symbols); #endif #ifdef LV_HAVE_AVX @@ -160,8 +160,6 @@ int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ __m256 h1Val1, h2Val1, y1Val1, y2Val1, h12square, h1square, h2square, h1_p, h2_p, h1conj1, h2conj1, x1Val, x2Val; __m256 h1Val2, h2Val2, y1Val2, y2Val2, h1conj2, h2conj2; - printf("using avx\n"); - for (int i=0;i 32) { + if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); } #else #ifdef LV_HAVE_SSE - if (nof_symbols > 32) { + if (nof_symbols > 32 && nof_rxant <= 2) { return srslte_predecoding_single_sse(y, h, x, nof_rxant, nof_symbols, noise_estimate); } else { return srslte_predecoding_single_gen(y, h, x, nof_rxant, nof_symbols, noise_estimate); @@ -295,54 +293,67 @@ int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MA } /* C implementatino of the SFBC equalizer */ -int srslte_predecoding_diversity_gen_(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], - int nof_ports, int nof_symbols, int symbol_start) +int srslte_predecoding_diversity_gen_(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, int nof_ports, int nof_symbols, int symbol_start) { int i; if (nof_ports == 2) { cf_t h00, h01, h10, h11, r0, r1; - float hh; for (i = symbol_start/2; i < nof_symbols / 2; i++) { - h00 = h[0][2 * i]; - h01 = h[0][2 * i+1]; - h10 = h[1][2 * i]; - h11 = h[1][2 * i+1]; - hh = crealf(h00) * crealf(h00) + cimagf(h00) * cimagf(h00) - + crealf(h11) * crealf(h11) + cimagf(h11) * cimagf(h11); - r0 = y[2 * i]; - r1 = y[2 * i + 1]; - if (hh == 0) { - hh = 1e-4; + float hh = 0; + cf_t x0 = 0; + cf_t x1 = 0; + for (int p=0;p 32 && nof_ports == 2) { + return srslte_predecoding_diversity2_sse(y, h, x, nof_rxant, nof_symbols); + } else { + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); + } +#else + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); +#endif +} + +int srslte_predecoding_diversity_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], cf_t *x[SRSLTE_MAX_LAYERS], + int nof_rxant, int nof_ports, int nof_symbols) { #ifdef LV_HAVE_SSE if (nof_symbols > 32 && nof_ports == 2) { - return srslte_predecoding_diversity2_sse(y, h, x, nof_symbols); + return srslte_predecoding_diversity2_sse(y, h, x, nof_rxant, nof_symbols); } else { - return srslte_predecoding_diversity_gen(y, h, x, nof_ports, nof_symbols); + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); } #else - return srslte_predecoding_diversity_gen(y, h, x, nof_ports, nof_symbols); + return srslte_predecoding_diversity_gen(y, h, x, nof_rxant, nof_ports, nof_symbols); #endif } + /* 36.211 v10.3.0 Section 6.3.4 */ int srslte_predecoding_type(cf_t *y, cf_t *h[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_ports, int nof_layers, int nof_symbols, srslte_mimo_type_t type, float noise_estimate) { diff --git a/srslte/lib/mimo/test/diversitydecode_mex.c b/srslte/lib/mimo/test/diversitydecode_mex.c index 7c020c6b8..4e2859acc 100644 --- a/srslte/lib/mimo/test/diversitydecode_mex.c +++ b/srslte/lib/mimo/test/diversitydecode_mex.c @@ -65,13 +65,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) uint32_t nof_rx_ants = 1; const mwSize *dims = mxGetDimensions(INPUT); mwSize ndims = mxGetNumberOfDimensions(INPUT); - nof_symbols = dims[0]*dims[1]; + nof_symbols = dims[0]; - if (ndims >= 3) { - nof_rx_ants = dims[2]; - } - if (ndims >= 4) { - nof_tx_ports = dims[3]; + if (ndims >= 2) { + nof_rx_ants = dims[1]; } // Read channel estimates @@ -79,7 +76,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error reading hest\n"); return; } + dims = mxGetDimensions(HEST); + ndims = mxGetNumberOfDimensions(HEST); + + if (ndims == 3) { + nof_tx_ports = dims[2]; + } + mexPrintf("nof_tx_ports=%d, nof_rx_ants=%d, nof_symbols=%d\n", nof_tx_ports, nof_rx_ants, nof_symbols); + // Read noise estimate float noise_estimate = 0; if (nrhs >= NOF_INPUTS) { @@ -111,12 +116,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) for (int j=0;j 1) { - //srslte_predecoding_diversity(input, h, x, nof_tx_ports, nof_symbols); - //srslte_layerdemap_diversity(x, output, nof_tx_ports, nof_symbols / nof_tx_ports); + srslte_predecoding_diversity_multi(y, h, x, nof_rx_ants, nof_tx_ports, nof_symbols); + srslte_layerdemap_diversity(x, output, nof_tx_ports, nof_symbols / nof_tx_ports); } else { srslte_predecoding_single_multi(y, h[0], output, nof_rx_ants, nof_symbols, noise_estimate); } From 4d77eb9fa131f348fa5dbd51fe8cc71eeda33a1a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 12 Sep 2016 14:24:16 -0400 Subject: [PATCH 05/38] Working on CDD precoder (matlab) --- matlab/tests/diversity_decode_test.m | 65 --------- matlab/tests/mimo_test.m | 84 ++++++++++++ srslte/include/srslte/common/phy_common.h | 5 +- srslte/lib/mimo/layermap.c | 6 + srslte/lib/mimo/test/CMakeLists.txt | 5 +- srslte/lib/mimo/test/precoder_mex.c | 128 ++++++++++++++++++ .../{precoding_test.c => precoder_test.c} | 0 ...diversitydecode_mex.c => predecoder_mex.c} | 0 8 files changed, 224 insertions(+), 69 deletions(-) delete mode 100644 matlab/tests/diversity_decode_test.m create mode 100644 matlab/tests/mimo_test.m create mode 100644 srslte/lib/mimo/test/precoder_mex.c rename srslte/lib/mimo/test/{precoding_test.c => precoder_test.c} (100%) rename srslte/lib/mimo/test/{diversitydecode_mex.c => predecoder_mex.c} (100%) diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m deleted file mode 100644 index 24ad28ca7..000000000 --- a/matlab/tests/diversity_decode_test.m +++ /dev/null @@ -1,65 +0,0 @@ -clear - -addpath('../../build/srslte/lib/mimo/test') - -%enb = lteRMCDL('R.10'); % 2-ports -enb = lteRMCDL('R.0'); % 1-ports - -cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic'); -cec.PilotAverage = 'UserDefined'; -cec.InterpWinSize = 1; -cec.InterpWindow = 'Causal'; - -cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 2; % 1 receive antenna -cfg.DelayProfile = 'ETU'; % EVA delay spread -cfg.DopplerFreq = 100; % 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 - -[txWaveform, ~, info] = lteRMCDLTool(enb,[1;0;0;1]); -cfg.SamplingRate = info.SamplingRate; - -txWaveform = txWaveform+complex(randn(size(txWaveform)),randn(size(txWaveform)))*1e-3; - -rxWaveform = lteFadingChannel(cfg,txWaveform); - -rxGrid = lteOFDMDemodulate(enb,rxWaveform); - -[h,n0] = lteDLChannelEstimate(enb,cec,rxGrid); - -s=size(h); -p=s(1); -n=s(2); -if (length(s)>2) - Nr=s(3); -else - Nr=1; -end -if (length(s)>3) - Nt=s(4); -else - Nt=1; -end - -rx=reshape(rxGrid,p*n,Nr); -hp=reshape(h,p*n,Nr,Nt); - -if (Nt > 1) - output_mat = lteTransmitDiversityDecode(rx, hp); -else - output_mat = lteEqualizeMMSE(rx, hp, n0); -end -output_srs = srslte_diversitydecode(rx, hp, n0); - -plot(abs(output_mat(:)-output_srs(:))) -mean(abs(output_mat(:)-output_srs(:)).^2) - -t=1:100; -plot(t,real(output_mat(t)),t,real(output_srs(t))) - diff --git a/matlab/tests/mimo_test.m b/matlab/tests/mimo_test.m new file mode 100644 index 000000000..1ee00d652 --- /dev/null +++ b/matlab/tests/mimo_test.m @@ -0,0 +1,84 @@ +clear + +addpath('../../debug/srslte/lib/mimo/test') + +Nt=1; +Nr=1; +Nl=1; +Ncw=1; +txscheme='Port0'; +codebook=0; +enb.NDLRB=6; + +Ns=enb.NDLRB*12*14; +enb.CyclicPrefix='Normal'; +enb.CellRefP=Nt; +enb.TotSubframes=1; + +cfg.Seed = 1; % Random channel seed +cfg.NRxAnts = Nr; % 1 receive antenna +cfg.DelayProfile = 'ETU'; % EVA delay spread +cfg.DopplerFreq = 100; % 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 + +cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic'); +cec.PilotAverage = 'UserDefined'; +cec.InterpWinSize = 1; +cec.InterpWindow = 'Causal'; + +sym = 2*rand(Ns*Nl,1)-1; + +layermap = lteLayerMap(sym, Nl, txscheme); +tx = lteDLPrecode(layermap, Nt, txscheme, codebook); + +tx_srs = srslte_precoder(sym, Nl, Nt, txscheme); + +err_tx=mean(abs(tx_srs-tx).^2) + +[txwaveform, info] = lteOFDMModulate(enb, reshape(tx,enb.NDLRB*12,[],Nt)); +cfg.SamplingRate = info.SamplingRate; + +rxwaveform = lteFadingChannel(cfg, txwaveform); + +rxGrid = lteOFDMDemodulate(enb, rxwaveform); +h=lteDLPerfectChannelEstimate(enb, cfg); + +hp=reshape(h,Ns,Nr,Nt); +rx=reshape(rxGrid,Ns,Nr); + +if (Nt > 1) + if (strcmp(txscheme,'TxDiversity')==1) + output_mat = lteTransmitDiversityDecode(rx, hp); + elseif (strcmp(txscheme,'CDD')==1 || strcmp(txscheme,'SpatialMux')==1) + pdsch.NLayers=Nl; + pdsch.RNTI=0; + pdsch.TxScheme=txscheme; + pdsch.PMISet=codebook; + pdsch.NCodewords=Ncw; + deprecoded = lteEqualizeMIMO(enb,pdsch,rx,hp,0); + out_cw = lteLayerDemap(pdsch,deprecoded); + output_mat = []; + for i=1:Ncw + output_mat = [output_mat out_cw{i}]; + end + else + error('Unsupported txscheme') + end +else + output_mat = lteEqualizeMMSE(rx, hp, 0); +end + +output_srs = srslte_predecoder(rx, hp, 0, txscheme); + +plot(abs(output_mat(:)-output_srs(:))) +mean(abs(output_mat(:)-output_srs(:)).^2) + +t=1:100; +plot(t,real(output_mat(t)),t,real(output_srs(t))) + diff --git a/srslte/include/srslte/common/phy_common.h b/srslte/include/srslte/common/phy_common.h index ec308ae8b..23f9a9930 100644 --- a/srslte/include/srslte/common/phy_common.h +++ b/srslte/include/srslte/common/phy_common.h @@ -51,7 +51,7 @@ #define SRSLTE_MAX_RXANT 2 #define SRSLTE_MAX_PORTS 4 -#define SRSLTE_MAX_LAYERS 8 +#define SRSLTE_MAX_LAYERS 4 #define SRSLTE_MAX_CODEWORDS 2 #define SRSLTE_LTE_CRC24A 0x1864CFB @@ -169,7 +169,8 @@ typedef struct SRSLTE_API { typedef enum SRSLTE_API { SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, SRSLTE_MIMO_TYPE_TX_DIVERSITY, - SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX + SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX, + SRSLTE_MIMO_TYPE_CDD } srslte_mimo_type_t; typedef enum SRSLTE_API { diff --git a/srslte/lib/mimo/layermap.c b/srslte/lib/mimo/layermap.c index d4bbd5787..1a9058658 100644 --- a/srslte/lib/mimo/layermap.c +++ b/srslte/lib/mimo/layermap.c @@ -117,6 +117,9 @@ int srslte_layermap_type(cf_t *d[SRSLTE_MAX_CODEWORDS], cf_t *x[SRSLTE_MAX_LAYER case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: return srslte_layermap_multiplex(d, x, nof_cw, nof_layers, nof_symbols); break; + case SRSLTE_MIMO_TYPE_CDD: + fprintf(stderr, "CDD Not implemented\n"); + return -1; } return 0; } @@ -208,6 +211,9 @@ int srslte_layerdemap_type(cf_t *x[SRSLTE_MAX_LAYERS], cf_t *d[SRSLTE_MAX_CODEWO case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: return srslte_layerdemap_multiplex(x, d, nof_layers, nof_cw, nof_layer_symbols, nof_symbols); break; + case SRSLTE_MIMO_TYPE_CDD: + fprintf(stderr, "CDD Not implemented\n"); + return -1; } return 0; } diff --git a/srslte/lib/mimo/test/CMakeLists.txt b/srslte/lib/mimo/test/CMakeLists.txt index b0fc0a78d..e942d731e 100644 --- a/srslte/lib/mimo/test/CMakeLists.txt +++ b/srslte/lib/mimo/test/CMakeLists.txt @@ -53,7 +53,7 @@ add_test(layermap_multiplex_28 layermap_test -n 1000 -m multiplex -c 2 -l 8) # LAYER MAPPING TEST ######################################################################## -add_executable(precoding_test precoding_test.c) +add_executable(precoding_test precoder_test.c) target_link_libraries(precoding_test srslte) add_test(precoding_single precoding_test -n 1000 -m single) @@ -62,7 +62,8 @@ add_test(precoding_diversity4 precoding_test -n 1024 -m diversity -l 4 -p 4) # MEX file for predecoding and layer demapping test -BuildMex(MEXNAME diversitydecode SOURCES diversitydecode_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME predecoder SOURCES predecoder_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME precoder SOURCES precoder_mex.c LIBRARIES srslte_static srslte_mex) diff --git a/srslte/lib/mimo/test/precoder_mex.c b/srslte/lib/mimo/test/precoder_mex.c new file mode 100644 index 000000000..958f06262 --- /dev/null +++ b/srslte/lib/mimo/test/precoder_mex.c @@ -0,0 +1,128 @@ +/** + * + * \section COPYRIGHT + * +* Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsLTE library. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include +#include "srslte/srslte.h" +#include "srslte/mex/mexutils.h" + +/** MEX function to be called from MATLAB to test the predecoder + */ + +#define INPUT prhs[0] +#define NLAYERS prhs[1] +#define NPORTS prhs[2] +#define TXSCHEME prhs[3] +#define NOF_INPUTS 3 + + +void help() +{ + mexErrMsgTxt + ("[output] = srslte_decoder(input, NLayers, NCellRefP, TxScheme)\n\n"); +} + +/* the gateway function */ +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + cf_t *input = NULL; + cf_t *output = NULL; + + if (nrhs < NOF_INPUTS) { + help(); + return; + } + + // Read input symbols + int nof_symbols = mexutils_read_cf(INPUT, &input); + if (nof_symbols < 0) { + mexErrMsgTxt("Error reading input\n"); + return; + } + uint32_t nof_layers = mxGetScalar(NLAYERS); + uint32_t nof_tx_ports = mxGetScalar(NPORTS); + uint32_t nof_codewords = 1; + + mexPrintf("nof_tx_ports=%d, nof_layers=%d, nof_symbols=%d\n", nof_tx_ports, nof_layers, nof_symbols); + + cf_t *y[SRSLTE_MAX_PORTS]; + cf_t *x[SRSLTE_MAX_LAYERS]; + cf_t *d[SRSLTE_MAX_CODEWORDS]; + + d[0] = input; // Single codeword supported only + + /* Allocate memory */ + for (int i = 0; i < nof_layers; i++) { + x[i] = srslte_vec_malloc(sizeof(cf_t)*nof_symbols/nof_layers); + } + + output = srslte_vec_malloc(sizeof(cf_t)*nof_symbols*nof_tx_ports/nof_layers); + for (int i=0;i= NOF_INPUTS) { + txscheme = mxArrayToString(TXSCHEME); + } + srslte_mimo_type_t type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; + if (!strcmp(txscheme, "Port0")) { + type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; + } else if (!strcmp(txscheme, "TxDiversity")) { + type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; + } else if (!strcmp(txscheme, "CDD")) { + type = SRSLTE_MIMO_TYPE_CDD; + } else if (!strcmp(txscheme, "SpatialMux")) { + type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; + } else { + mexPrintf("Unsupported TxScheme=%s\n", txscheme); + return; + } + int symbols_layers[SRSLTE_MAX_LAYERS]; + for (int i=0;i= 1) { + mexutils_write_cf(output, &plhs[0], nof_symbols/nof_layers, nof_tx_ports); + } + + if (input) { + free(input); + } + if (output) { + free(output); + } + for (int i=0;i Date: Thu, 24 Nov 2016 19:51:17 +0100 Subject: [PATCH 06/38] Do not demote timeval members to int ; fix elapsed time unit in modem test --- srslte/examples/synch_file.c | 2 +- srslte/lib/modem/test/modem_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/examples/synch_file.c b/srslte/examples/synch_file.c index a9e3e7146..178e56e99 100644 --- a/srslte/examples/synch_file.c +++ b/srslte/examples/synch_file.c @@ -182,7 +182,7 @@ int main(int argc, char **argv) { } gettimeofday(&tdata[2], NULL); get_time_interval(tdata); - printf("done in %ld s %ld ms\n", (int) tdata[0].tv_sec, (int) tdata[0].tv_usec/1000); + printf("done in %ld s %ld ms\n", tdata[0].tv_sec, tdata[0].tv_usec/1000); printf("\n\tFr.Cnt\tN_id_2\tN_id_1\tSubf\tPSS Peak/Avg\tIdx\tm0\tm1\tCFO\n"); printf("\t===============================================================================\n"); diff --git a/srslte/lib/modem/test/modem_test.c b/srslte/lib/modem/test/modem_test.c index d233f7418..600115386 100644 --- a/srslte/lib/modem/test/modem_test.c +++ b/srslte/lib/modem/test/modem_test.c @@ -184,7 +184,7 @@ int main(int argc, char **argv) { srslte_demod_soft_demodulate(modulation, symbols, llr, num_bits / mod.nbits_x_symbol); gettimeofday(&y, NULL); - printf("\nElapsed time [ns]: %ld\n", (int) y.tv_usec - (int) x.tv_usec); + printf("\nElapsed time [us]: %ld\n", y.tv_usec - x.tv_usec); for (i=0;i=0 ? 1 : 0; } From f3b87ca95569bf9c3c5bbac34810d24c5a78ed6d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 30 Nov 2016 14:51:09 -0500 Subject: [PATCH 07/38] fixed missing SO_REUSE* in old kernels --- srslte/lib/io/netsink.c | 4 ++++ srslte/lib/io/netsource.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/srslte/lib/io/netsink.c b/srslte/lib/io/netsink.c index bedb5fc92..39bd885a9 100644 --- a/srslte/lib/io/netsink.c +++ b/srslte/lib/io/netsink.c @@ -48,10 +48,14 @@ int srslte_netsink_init(srslte_netsink_t *q, char *address, int port, srslte_net } int enable = 1; +#if defined (SO_REUSEADDR) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEADDR) failed"); +#endif +#if defined (SO_REUSEPORT) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEPORT) failed"); +#endif q->servaddr.sin_family = AF_INET; q->servaddr.sin_addr.s_addr=inet_addr(address); diff --git a/srslte/lib/io/netsource.c b/srslte/lib/io/netsource.c index f41296c3c..0e9c804c0 100644 --- a/srslte/lib/io/netsource.c +++ b/srslte/lib/io/netsource.c @@ -48,11 +48,14 @@ int srslte_netsource_init(srslte_netsource_t *q, char *address, int port, srslte // Make sockets reusable int enable = 1; +#if defined (SO_REUSEADDR) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEADDR) failed"); +#endif +#if defined (SO_REUSEPORT) if (setsockopt(q->sockfd, SOL_SOCKET, SO_REUSEPORT, &enable, sizeof(int)) < 0) perror("setsockopt(SO_REUSEPORT) failed"); - +#endif q->type = type; q->servaddr.sin_family = AF_INET; From 462d222fd272251f40c5b2638668e55b05e6c2e1 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 7 Feb 2017 17:26:40 +0000 Subject: [PATCH 08/38] chest dl to support multiple rx antennas --- matlab/tests/pdsch_equal.m | 4 ++-- srslte/include/srslte/ch_estimation/chest_dl.h | 5 +++++ srslte/lib/ch_estimation/chest_dl.c | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index 1bd949532..f58920f14 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -128,8 +128,8 @@ if (length(SNR_values)>1) ylabel('BLER') axis([min(SNR_values) max(SNR_values) 1/Npackets/(Nsf+1) 1]) else - plot(abs(symbols{1}-pdschSymbols2)) - %scatter(real(symbols{1}),imag(symbols{1})) + %plot(abs(symbols{1}-pdschSymbols2)) + scatter(real(pdschSymbols2),imag(pdschSymbols2)) fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); end diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index a4afa1d84..7d20ecb45 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -105,6 +105,11 @@ SRSLTE_API void srslte_chest_dl_set_smooth_filter3_coeff(srslte_chest_dl_t* q, 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_multi(srslte_chest_dl_t *q, + cf_t *input[SRSLTE_MAX_RXANT], + cf_t *ce[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS], + uint32_t sf_idx); + 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 541f98646..5a1da4736 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -354,12 +354,26 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u return 0; } +int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t nof_rx_antennas) +{ + for (uint32_t rxant=0;rxantcell.nof_ports;port_id++) { + if (srslte_chest_dl_estimate_port(q, input[rxant], ce[rxant][port_id], sf_idx, port_id)) { + return SRSLTE_ERROR; + } + } + } + return SRSLTE_SUCCESS; +} + int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_MAX_PORTS], uint32_t sf_idx) { uint32_t port_id; for (port_id=0;port_idcell.nof_ports;port_id++) { - srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id); + if (srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id)) { + return SRSLTE_ERROR; + } } return SRSLTE_SUCCESS; } From 0bd749aa29a80e1358e92d3d7a705793ddf32ebb Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 7 Feb 2017 19:04:15 +0000 Subject: [PATCH 09/38] added support for multiple rx antennas to pdsch. Working in matlab for 1/2 ports tx diversity --- matlab/tests/pdsch_equal.m | 7 +- .../include/srslte/ch_estimation/chest_dl.h | 5 +- srslte/include/srslte/phch/pdsch.h | 19 +++- srslte/lib/ch_estimation/chest_dl.c | 5 +- srslte/lib/phch/pdsch.c | 98 ++++++++++++------- srslte/lib/phch/test/pdsch_test_mex.c | 91 ++++++++++++----- 6 files changed, 153 insertions(+), 72 deletions(-) diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m index f58920f14..e5daaf5cb 100644 --- a/matlab/tests/pdsch_equal.m +++ b/matlab/tests/pdsch_equal.m @@ -8,10 +8,10 @@ recordedSignal=[]; Npackets = 1; -SNR_values = 56;%linspace(2,6,10); +SNR_values = 50;%linspace(8,11,5); %% Choose RMC -[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.5',[1;0;0;1]); +[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.12',[1;0;0;1]); waveform = sum(waveform,2); if ~isempty(recordedSignal) @@ -105,9 +105,6 @@ for snr_idx=1:length(SNR_values) 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 diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index 7d20ecb45..1d37b3aad 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -107,8 +107,9 @@ SRSLTE_API void srslte_chest_dl_set_noise_alg(srslte_chest_dl_t *q, SRSLTE_API int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], - cf_t *ce[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS], - uint32_t sf_idx); + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + uint32_t sf_idx, + uint32_t nof_rx_antennas); SRSLTE_API int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, diff --git a/srslte/include/srslte/phch/pdsch.h b/srslte/include/srslte/phch/pdsch.h index 305402de5..dae5f2ec2 100644 --- a/srslte/include/srslte/phch/pdsch.h +++ b/srslte/include/srslte/phch/pdsch.h @@ -55,12 +55,14 @@ typedef struct { typedef struct SRSLTE_API { srslte_cell_t cell; + uint32_t nof_rx_antennas; + uint32_t max_re; /* buffers */ // void buffers are shared for tx and rx - cf_t *ce[SRSLTE_MAX_PORTS]; - cf_t *symbols[SRSLTE_MAX_PORTS]; + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + cf_t *symbols[SRSLTE_MAX_RXANT]; cf_t *x[SRSLTE_MAX_PORTS]; cf_t *d; void *e; @@ -78,6 +80,10 @@ typedef struct SRSLTE_API { SRSLTE_API int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell); +SRSLTE_API int srslte_pdsch_init_multi(srslte_pdsch_t *q, + srslte_cell_t cell, + uint32_t nof_rx_antennas); + SRSLTE_API void srslte_pdsch_free(srslte_pdsch_t *q); SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q, @@ -112,6 +118,15 @@ SRSLTE_API int srslte_pdsch_decode(srslte_pdsch_t *q, uint16_t rnti, uint8_t *data); +SRSLTE_API int srslte_pdsch_decode_multi(srslte_pdsch_t *q, + srslte_pdsch_cfg_t *cfg, + srslte_softbuffer_rx_t *softbuffer, + cf_t *sf_symbols[SRSLTE_MAX_RXANT], + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + float noise_estimate, + uint16_t rnti, + uint8_t *data); + SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q); SRSLTE_API uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q); diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index 5a1da4736..47e169364 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -354,11 +354,12 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u return 0; } -int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t nof_rx_antennas) +int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], uint32_t sf_idx, uint32_t nof_rx_antennas) { for (uint32_t rxant=0;rxantcell.nof_ports;port_id++) { - if (srslte_chest_dl_estimate_port(q, input[rxant], ce[rxant][port_id], sf_idx, port_id)) { + printf("rxant=%d, port=%d, input=0x%x, ce=0x%x\n", rxant, port_id, input[rxant], ce[port_id][rxant]); + if (srslte_chest_dl_estimate_port(q, input[rxant], ce[port_id][rxant], sf_idx, port_id)) { return SRSLTE_ERROR; } } diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index b4ae7621f..02f85c5d3 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -202,13 +202,20 @@ int srslte_pdsch_get(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *symbols, return srslte_pdsch_cp(q, sf_symbols, symbols, grant, lstart, subframe, false); } +int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) +{ + return srslte_pdsch_init_multi(q, cell, 1); +} + /** Initializes the PDCCH transmitter and receiver */ -int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { +int srslte_pdsch_init_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_rx_antennas) +{ int ret = SRSLTE_ERROR_INVALID_INPUTS; int i; - if (q != NULL && - srslte_cell_isvalid(&cell)) + if (q != NULL && + srslte_cell_isvalid(&cell) && + nof_rx_antennas <= SRSLTE_MAX_RXANT) { bzero(q, sizeof(srslte_pdsch_t)); @@ -216,7 +223,8 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { q->cell = cell; q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); - + q->nof_rx_antennas = nof_rx_antennas; + INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, q->cell.nof_prb, q->max_re); @@ -241,19 +249,23 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { } for (i = 0; i < q->cell.nof_ports; i++) { - q->ce[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); - if (!q->ce[i]) { - goto clean; - } q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; } - q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); - if (!q->symbols[i]) { - goto clean; + for (int j=0;jnof_rx_antennas;j++) { + q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); + if (!q->ce[i][j]) { + goto clean; + } } } + for (int j=0;jnof_rx_antennas;j++) { + q->symbols[j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); + if (!q->symbols[j]) { + goto clean; + } + } q->users = calloc(sizeof(srslte_pdsch_user_t*), 1+SRSLTE_SIRNTI); if (!q->users) { @@ -280,17 +292,20 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { free(q->d); } for (i = 0; i < q->cell.nof_ports; i++) { - if (q->ce[i]) { - free(q->ce[i]); - } if (q->x[i]) { free(q->x[i]); } - if (q->symbols[i]) { - free(q->symbols[i]); + for (int j=0;jnof_rx_antennas;j++) { + if (q->ce[i][j]) { + free(q->ce[i][j]); + } } } - + for (int j=0;jnof_rx_antennas;j++) { + if (q->symbols[j]) { + free(q->symbols[j]); + } + } if (q->users) { for (uint16_t u=0;uusers[u]) { @@ -363,13 +378,28 @@ void srslte_pdsch_free_rnti(srslte_pdsch_t* q, uint16_t rnti) } } -/** Decodes the PDSCH from the received symbols - */ int srslte_pdsch_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, uint16_t rnti, uint8_t *data) { + cf_t *_sf_symbols[SRSLTE_MAX_RXANT]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + + _sf_symbols[0] = sf_symbols; + for (int i=0;icell.nof_ports;i++) { + _ce[i][0] = ce[i]; + } + return srslte_pdsch_decode_multi(q, cfg, softbuffer, _sf_symbols, _ce, noise_estimate, rnti, data); +} + +/** Decodes the PDSCH from the received symbols + */ +int srslte_pdsch_decode_multi(srslte_pdsch_t *q, + srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, + cf_t *sf_symbols[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], float noise_estimate, + uint16_t rnti, uint8_t *data) +{ /* Set pointers for layermapping & precoding */ uint32_t i, n; @@ -391,31 +421,31 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, } memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports)); - /* extract symbols */ - n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx); - if (n != cfg->nbits.nof_re) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); - return SRSLTE_ERROR; - } - - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - n = srslte_pdsch_get(q, ce[i], q->ce[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx); + for (int j=0;jnof_rx_antennas;j++) { + /* extract symbols */ + n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx); if (n != cfg->nbits.nof_re) { fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); return SRSLTE_ERROR; } + + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx); + if (n != cfg->nbits.nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n); + return SRSLTE_ERROR; + } + } } /* TODO: 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, cfg->nbits.nof_re, noise_estimate); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, cfg->nbits.nof_re, noise_estimate); } else { - srslte_predecoding_diversity(q->symbols[0], q->ce, x, q->cell.nof_ports, - cfg->nbits.nof_re); - srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, - cfg->nbits.nof_re / q->cell.nof_ports); + srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->cell.nof_ports, q->nof_rx_antennas, cfg->nbits.nof_re); + srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, cfg->nbits.nof_re / q->cell.nof_ports); } if (SRSLTE_VERBOSE_ISDEBUG()) { diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index 45bd1ae09..869a4829c 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -55,7 +55,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) srslte_ofdm_t ofdm_rx; srslte_pdsch_t pdsch; srslte_chest_dl_t chest; - cf_t *input_fft; + cf_t *input_fft[SRSLTE_MAX_RXANT]; srslte_pdsch_cfg_t cfg; srslte_softbuffer_rx_t softbuffer; uint32_t rnti32; @@ -92,8 +92,16 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) fprintf(stderr, "Error initializing FFT\n"); return; } - - if (srslte_pdsch_init(&pdsch, cell)) { + + + const size_t ndims = mxGetNumberOfDimensions(INPUT); + uint32_t nof_antennas = 1; + if (ndims >= 3) { + const mwSize *dims = mxGetDimensions(INPUT); + nof_antennas = dims[2]; + } + + if (srslte_pdsch_init_multi(&pdsch, cell, nof_antennas)) { mexErrMsgTxt("Error initiating PDSCH\n"); return; } @@ -188,18 +196,19 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) nof_retx = mexutils_getLength(INPUT); } - cf_t *ce[SRSLTE_MAX_PORTS]; - for (i=0;i= 6) { - mexutils_write_cf(ce[0], &plhs[5], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1); + uint32_t len = nof_antennas*cell.nof_ports*SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); + cf_t *cearray_ptr = srslte_vec_malloc(len*sizeof(cf_t)); + int n=0; + for (int k=0;k Date: Tue, 7 Feb 2017 19:10:48 +0000 Subject: [PATCH 10/38] Working in matlab for 1/2/4 ports tx diversity --- srslte/lib/phch/pdsch.c | 2 +- srslte/lib/phch/test/pdsch_test_mex.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index 02f85c5d3..ccaea5282 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -444,7 +444,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, /* no need for layer demapping */ srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, cfg->nbits.nof_re, noise_estimate); } else { - srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->cell.nof_ports, q->nof_rx_antennas, cfg->nbits.nof_re); + srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nbits.nof_re); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, cfg->nbits.nof_re / q->cell.nof_ports); } diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index 869a4829c..fa455809b 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -245,7 +245,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) cf_t *cearray = NULL; mexutils_read_cf(prhs[NOF_INPUTS], &cearray); cf_t *cearray_ptr = cearray; - for (int k=0;k Date: Wed, 8 Feb 2017 23:21:07 +0100 Subject: [PATCH 11/38] added uhd option to receive 2 antennas --- srslte/include/srslte/rf/rf.h | 10 ++++- srslte/lib/rf/rf_blade_imp.c | 16 ++++++++ srslte/lib/rf/rf_blade_imp.h | 9 +++++ srslte/lib/rf/rf_dev.h | 7 ++++ srslte/lib/rf/rf_imp.c | 26 +++++++++++-- srslte/lib/rf/rf_uhd_imp.c | 69 ++++++++++++++++++++++++++--------- srslte/lib/rf/rf_uhd_imp.h | 11 ++++++ 7 files changed, 126 insertions(+), 22 deletions(-) diff --git a/srslte/include/srslte/rf/rf.h b/srslte/include/srslte/rf/rf.h index fd49f7d8d..4ae3cd82e 100644 --- a/srslte/include/srslte/rf/rf.h +++ b/srslte/include/srslte/rf/rf.h @@ -73,7 +73,8 @@ SRSLTE_API int srslte_rf_open(srslte_rf_t *h, SRSLTE_API int srslte_rf_open_devname(srslte_rf_t *h, char *devname, - char *args); + char *args, + uint32_t nof_rx_antennas); SRSLTE_API const char *srslte_rf_name(srslte_rf_t *h); @@ -139,6 +140,13 @@ SRSLTE_API int srslte_rf_recv_with_time(srslte_rf_t *h, time_t *secs, double *frac_secs); +SRSLTE_API int srslte_rf_recv_with_time_multi(srslte_rf_t *h, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs); + SRSLTE_API double srslte_rf_set_tx_srate(srslte_rf_t *h, double freq); diff --git a/srslte/lib/rf/rf_blade_imp.c b/srslte/lib/rf/rf_blade_imp.c index fbe9b3fc6..8cc19c881 100644 --- a/srslte/lib/rf/rf_blade_imp.c +++ b/srslte/lib/rf/rf_blade_imp.c @@ -178,6 +178,11 @@ float rf_blade_get_rssi(void *h) return 0; } +int rf_blade_open_multi(char *args, void **h, uint32_t nof_rx_antennas) +{ + return rf_blade_open(args, h); +} + int rf_blade_open(char *args, void **h) { *h = NULL; @@ -413,6 +418,17 @@ void rf_blade_get_time(void *h, time_t *secs, double *frac_secs) timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); } + +int rf_blade_recv_with_time_multi(void *h, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) +{ + return rf_blade_recv_with_time(h, *data, nsamples, blocking, secs, frac_secs); +} + int rf_blade_recv_with_time(void *h, void *data, uint32_t nsamples, diff --git a/srslte/lib/rf/rf_blade_imp.h b/srslte/lib/rf/rf_blade_imp.h index 552564620..f40ee374e 100644 --- a/srslte/lib/rf/rf_blade_imp.h +++ b/srslte/lib/rf/rf_blade_imp.h @@ -33,6 +33,8 @@ SRSLTE_API int rf_blade_open(char *args, void **handler); +SRSLTE_API int rf_blade_open_multi(char *args, + void **handler, uint32_t nof_rx_antennas); SRSLTE_API char* rf_blade_devname(void *h); @@ -82,6 +84,13 @@ SRSLTE_API void rf_blade_register_error_handler(void *h, SRSLTE_API double rf_blade_set_rx_freq(void *h, double freq); +SRSLTE_API int rf_blade_recv_with_time_multi(void *h, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs); + SRSLTE_API int rf_blade_recv_with_time(void *h, void *data, uint32_t nsamples, diff --git a/srslte/lib/rf/rf_dev.h b/srslte/lib/rf/rf_dev.h index 2dd65552c..293f158b1 100644 --- a/srslte/lib/rf/rf_dev.h +++ b/srslte/lib/rf/rf_dev.h @@ -38,6 +38,7 @@ typedef struct { void (*srslte_rf_suppress_stdout)(void *h); void (*srslte_rf_register_error_handler)(void *h, srslte_rf_error_handler_t error_handler); int (*srslte_rf_open)(char *args, void **h); + int (*srslte_rf_open_multi)(char *args, void **h, uint32_t nof_rx_antennas); int (*srslte_rf_close)(void *h); void (*srslte_rf_set_master_clock_rate)(void *h, double rate); bool (*srslte_rf_is_master_clock_dynamic)(void *h); @@ -52,6 +53,8 @@ typedef struct { void (*srslte_rf_get_time)(void *h, time_t *secs, double *frac_secs); int (*srslte_rf_recv_with_time)(void *h, void *data, uint32_t nsamples, bool blocking, time_t *secs,double *frac_secs); + int (*srslte_rf_recv_with_time_multi)(void *h, void **data, uint32_t nsamples, + bool blocking, time_t *secs,double *frac_secs); int (*srslte_rf_send_timed)(void *h, void *data, int nsamples, time_t secs, double frac_secs, bool has_time_spec, bool blocking, bool is_start_of_burst, bool is_end_of_burst); @@ -78,6 +81,7 @@ static rf_dev_t dev_uhd = { rf_uhd_suppress_stdout, rf_uhd_register_error_handler, rf_uhd_open, + rf_uhd_open_multi, rf_uhd_close, rf_uhd_set_master_clock_rate, rf_uhd_is_master_clock_dynamic, @@ -91,6 +95,7 @@ static rf_dev_t dev_uhd = { rf_uhd_set_tx_freq, rf_uhd_get_time, rf_uhd_recv_with_time, + rf_uhd_recv_with_time_multi, rf_uhd_send_timed, rf_uhd_set_tx_cal, rf_uhd_set_rx_cal @@ -114,6 +119,7 @@ static rf_dev_t dev_blade = { rf_blade_suppress_stdout, rf_blade_register_error_handler, rf_blade_open, + rf_blade_open_multi, rf_blade_close, rf_blade_set_master_clock_rate, rf_blade_is_master_clock_dynamic, @@ -127,6 +133,7 @@ static rf_dev_t dev_blade = { rf_blade_set_tx_freq, rf_blade_get_time, rf_blade_recv_with_time, + rf_blade_recv_with_time_multi, rf_blade_send_timed, rf_blade_set_tx_cal, rf_blade_set_rx_cal diff --git a/srslte/lib/rf/rf_imp.c b/srslte/lib/rf/rf_imp.c index fe93d0e93..48d0db924 100644 --- a/srslte/lib/rf/rf_imp.c +++ b/srslte/lib/rf/rf_imp.c @@ -98,7 +98,7 @@ const char* srslte_rf_get_devname(srslte_rf_t *rf) { return ((rf_dev_t*) rf->dev)->name; } -int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) { +int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args, uint32_t nof_rx_antennas) { /* Try to open the device if name is provided */ if (devname) { if (devname[0] != '\0') { @@ -106,7 +106,7 @@ int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) { while(available_devices[i] != NULL) { if (!strcmp(available_devices[i]->name, devname)) { rf->dev = available_devices[i]; - return available_devices[i]->srslte_rf_open(args, &rf->handler); + return available_devices[i]->srslte_rf_open_multi(args, &rf->handler, nof_rx_antennas); } i++; } @@ -182,7 +182,12 @@ void srslte_rf_register_error_handler(srslte_rf_t *rf, srslte_rf_error_handler_t int srslte_rf_open(srslte_rf_t *h, char *args) { - return srslte_rf_open_devname(h, NULL, args); + return srslte_rf_open_devname(h, NULL, args, 1); +} + +int srslte_rf_open_multi(srslte_rf_t *h, char *args, uint32_t nof_rx_antennas) +{ + return srslte_rf_open_devname(h, NULL, args, nof_rx_antennas); } int srslte_rf_close(srslte_rf_t *rf) @@ -231,6 +236,11 @@ int srslte_rf_recv(srslte_rf_t *rf, void *data, uint32_t nsamples, bool blocking return srslte_rf_recv_with_time(rf, data, nsamples, blocking, NULL, NULL); } +int srslte_rf_recv_multi(srslte_rf_t *rf, void **data, uint32_t nsamples, bool blocking) +{ + return srslte_rf_recv_with_time_multi(rf, data, nsamples, blocking, NULL, NULL); +} + int srslte_rf_recv_with_time(srslte_rf_t *rf, void *data, uint32_t nsamples, @@ -241,6 +251,16 @@ int srslte_rf_recv_with_time(srslte_rf_t *rf, return ((rf_dev_t*) rf->dev)->srslte_rf_recv_with_time(rf->handler, data, nsamples, blocking, secs, frac_secs); } +int srslte_rf_recv_with_time_multi(srslte_rf_t *rf, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_recv_with_time_multi(rf->handler, data, nsamples, blocking, secs, frac_secs); +} + double srslte_rf_set_tx_gain(srslte_rf_t *rf, double gain) { return ((rf_dev_t*) rf->dev)->srslte_rf_set_tx_gain(rf->handler, gain); diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index d16382f52..ba02db6c8 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -51,6 +51,8 @@ typedef struct { bool dynamic_rate; bool has_rssi; uhd_sensor_value_handle rssi_value; + uint32_t nof_rx_channels; + int nof_tx_channels; } rf_uhd_handler_t; void suppress_handler(const char *x) @@ -231,6 +233,11 @@ float rf_uhd_get_rssi(void *h) { } int rf_uhd_open(char *args, void **h) +{ + return rf_uhd_open_multi(args, h, 1); +} + +int rf_uhd_open_multi(char *args, void **h, uint32_t nof_rx_antennas) { if (h) { *h = NULL; @@ -306,14 +313,17 @@ int rf_uhd_open(char *args, void **h) if (!handler->devname) { handler->devname = "uhd_unknown"; } - size_t channel = 0; + size_t channel[4] = {0, 1, 2, 3}; uhd_stream_args_t stream_args = { .cpu_format = "fc32", .otw_format = "sc16", .args = "", - .channel_list = &channel, - .n_channels = 1 + .channel_list = channel, + .n_channels = nof_rx_antennas }; + + handler->nof_rx_channels = nof_rx_antennas; + handler->nof_tx_channels = 1; // Set external clock reference if (strstr(args, "clock=external")) { @@ -393,7 +403,9 @@ bool rf_uhd_is_master_clock_dynamic(void *h) { double rf_uhd_set_rx_srate(void *h, double freq) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_rx_rate(handler->usrp, freq, 0); + for (int i=0;inof_rx_channels;i++) { + uhd_usrp_set_rx_rate(handler->usrp, freq, i); + } uhd_usrp_get_rx_rate(handler->usrp, 0, &freq); return freq; } @@ -401,7 +413,9 @@ double rf_uhd_set_rx_srate(void *h, double freq) double rf_uhd_set_tx_srate(void *h, double freq) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_tx_rate(handler->usrp, freq, 0); + for (int i=0;inof_tx_channels;i++) { + uhd_usrp_set_tx_rate(handler->usrp, freq, i); + } uhd_usrp_get_tx_rate(handler->usrp, 0, &freq); handler->tx_rate = freq; return freq; @@ -410,7 +424,9 @@ double rf_uhd_set_tx_srate(void *h, double freq) double rf_uhd_set_rx_gain(void *h, double gain) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_rx_gain(handler->usrp, gain, 0, ""); + for (int i=0;inof_rx_channels;i++) { + uhd_usrp_set_rx_gain(handler->usrp, gain, i, ""); + } uhd_usrp_get_rx_gain(handler->usrp, 0, "", &gain); return gain; } @@ -418,7 +434,9 @@ double rf_uhd_set_rx_gain(void *h, double gain) double rf_uhd_set_tx_gain(void *h, double gain) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_tx_gain(handler->usrp, gain, 0, ""); + for (int i=0;inof_tx_channels;i++) { + uhd_usrp_set_tx_gain(handler->usrp, gain, i, ""); + } uhd_usrp_get_tx_gain(handler->usrp, 0, "", &gain); return gain; } @@ -448,7 +466,9 @@ double rf_uhd_set_rx_freq(void *h, double freq) }; uhd_tune_result_t tune_result; rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_rx_freq(handler->usrp, &tune_request, 0, &tune_result); + for (int i=0;inof_rx_channels;i++) { + uhd_usrp_set_rx_freq(handler->usrp, &tune_request, i, &tune_result); + } uhd_usrp_get_rx_freq(handler->usrp, 0, &freq); return freq; } @@ -462,7 +482,9 @@ double rf_uhd_set_tx_freq(void *h, double freq) }; uhd_tune_result_t tune_result; rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_usrp_set_tx_freq(handler->usrp, &tune_request, 0, &tune_result); + for (int i=0;inof_tx_channels;i++) { + uhd_usrp_set_tx_freq(handler->usrp, &tune_request, i, &tune_result); + } uhd_usrp_get_tx_freq(handler->usrp, 0, &freq); return freq; } @@ -480,37 +502,48 @@ int rf_uhd_recv_with_time(void *h, time_t *secs, double *frac_secs) { + return rf_uhd_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); +} + +int rf_uhd_recv_with_time_multi(void *h, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) +{ rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - size_t rxd_samples; + size_t rxd_samples[4]; uhd_rx_metadata_handle *md = &handler->rx_md_first; int trials = 0; if (blocking) { int n = 0; - cf_t *data_c = (cf_t*) data; do { size_t rx_samples = handler->rx_nof_samples; if (rx_samples > nsamples - n) { rx_samples = nsamples - n; } - void *buff = (void*) &data_c[n]; - void **buffs_ptr = (void**) &buff; + void *buffs_ptr[4]; + for (int i=0;inof_rx_channels;i++) { + cf_t *data_c = (cf_t*) data[i]; + buffs_ptr[i] = &data_c[n]; + } uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr, - rx_samples, md, 5.0, false, &rxd_samples); + rx_samples, md, 1.0, false, rxd_samples); if (error) { fprintf(stderr, "Error receiving from UHD: %d\n", error); return -1; } md = &handler->rx_md; - n += rxd_samples; + n += rxd_samples[0]; trials++; } while (n < nsamples && trials < 100); } else { - void **buffs_ptr = (void**) &data; - return uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr, - nsamples, md, 0.0, false, &rxd_samples); + return uhd_rx_streamer_recv(handler->rx_stream, data, + nsamples, md, 0.0, false, rxd_samples); } if (secs && frac_secs) { uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs); diff --git a/srslte/lib/rf/rf_uhd_imp.h b/srslte/lib/rf/rf_uhd_imp.h index ee13ea36e..edab6ea51 100644 --- a/srslte/lib/rf/rf_uhd_imp.h +++ b/srslte/lib/rf/rf_uhd_imp.h @@ -37,6 +37,10 @@ SRSLTE_API int rf_uhd_open(char *args, void **handler); +SRSLTE_API int rf_uhd_open_multi(char *args, + void **handler, + uint32_t nof_rx_antennas); + SRSLTE_API char* rf_uhd_devname(void *h); SRSLTE_API int rf_uhd_close(void *h); @@ -89,6 +93,13 @@ SRSLTE_API int rf_uhd_recv_with_time(void *h, time_t *secs, double *frac_secs); +SRSLTE_API int rf_uhd_recv_with_time_multi(void *h, + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs); + SRSLTE_API double rf_uhd_set_tx_srate(void *h, double freq); From b2389efe47154616ca6148873f304c4b13ceeef1 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Feb 2017 14:06:58 +0100 Subject: [PATCH 12/38] start_rx_stream delays the start to avoid filling buffers. Started adapting pdsch_ue to 2 antennas --- srslte/examples/pdsch_ue.c | 37 +++++++++++++++++++++++------------ srslte/include/srslte/rf/rf.h | 14 ++++++++++--- srslte/lib/rf/rf_imp.c | 12 ++++++++---- srslte/lib/rf/rf_uhd_imp.c | 34 +++++++++++++++++++++----------- srslte/lib/rf/rf_utils.c | 5 +++-- 5 files changed, 70 insertions(+), 32 deletions(-) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index a9f48b941..24ffc50a5 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -89,6 +89,7 @@ typedef struct { uint32_t file_nof_ports; uint32_t file_cell_id; char *rf_args; + uint32_t rf_nof_rx_ant; double rf_freq; float rf_gain; int net_port; @@ -113,6 +114,7 @@ void args_default(prog_args_t *args) { args->file_offset_freq = 0; args->rf_args = ""; args->rf_freq = -1.0; + args->rf_nof_rx_ant = 1; #ifdef ENABLE_AGC_DEFAULT args->rf_gain = -1.0; #else @@ -163,7 +165,7 @@ void usage(prog_args_t *args, char *prog) { void parse_args(prog_args_t *args, int argc, char **argv) { int opt; args_default(args); - while ((opt = getopt(argc, argv, "aoglipPcOCtdDnvrfuUsS")) != -1) { + while ((opt = getopt(argc, argv, "aAoglipPcOCtdDnvrfuUsS")) != -1) { switch (opt) { case 'i': args->input_file_name = argv[optind]; @@ -186,6 +188,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) { case 'a': args->rf_args = argv[optind]; break; + case 'A': + args->rf_nof_rx_ant = atoi(argv[optind]); + break; case 'g': args->rf_gain = atof(argv[optind]); break; @@ -252,10 +257,13 @@ void sig_int_handler(int signo) } } +cf_t *sf_buffer[2] = {NULL, NULL}; + #ifndef DISABLE_RF int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv(h, data, nsamples, 1); + void *d[2] = {data, sf_buffer[1]}; + return srslte_rf_recv_with_time_multi(h, d, nsamples, true, NULL, NULL); } double srslte_rf_set_rx_gain_th_wrapper_(void *h, double f) { @@ -273,7 +281,6 @@ srslte_ue_sync_t ue_sync; prog_args_t prog_args; uint32_t sfn = 0; // system frame number -cf_t *sf_buffer = NULL; srslte_netsink_t net_sink, net_sink_signal; int main(int argc, char **argv) { @@ -311,8 +318,8 @@ int main(int argc, char **argv) { #ifndef DISABLE_RF if (!prog_args.input_file_name) { - printf("Opening RF device...\n"); - if (srslte_rf_open(&rf, prog_args.rf_args)) { + printf("Opening RF device with %d RX antennas...\n", prog_args.rf_nof_rx_ant); + if (srslte_rf_open_multi(&rf, prog_args.rf_args, prog_args.rf_nof_rx_ant)) { fprintf(stderr, "Error opening rf\n"); exit(-1); } @@ -356,6 +363,10 @@ int main(int argc, char **argv) { if (go_exit) { exit(0); } + + srslte_rf_stop_rx_stream(&rf); + srslte_rf_flush_buffer(&rf); + /* set sampling frequency */ int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { @@ -375,9 +386,7 @@ int main(int argc, char **argv) { exit(-1); } - INFO("Stopping RF and flushing buffer...\r",0); - srslte_rf_stop_rx_stream(&rf); - srslte_rf_flush_buffer(&rf); + printf("Stopping RF and flushing buffer...\r",0); } #endif @@ -416,6 +425,10 @@ int main(int argc, char **argv) { exit(-1); } + for (int i=0;idev)->name; } -int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args, uint32_t nof_rx_antennas) { +int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args) { + return srslte_rf_open_devname_multi(rf, devname, args, 1); +} + +int srslte_rf_open_devname_multi(srslte_rf_t *rf, char *devname, char *args, uint32_t nof_rx_antennas) { /* Try to open the device if name is provided */ if (devname) { if (devname[0] != '\0') { @@ -117,7 +121,7 @@ int srslte_rf_open_devname(srslte_rf_t *rf, char *devname, char *args, uint32_t /* If in auto mode or provided device not found, try to open in order of apperance in available_devices[] array */ int i=0; while(available_devices[i] != NULL) { - if (!available_devices[i]->srslte_rf_open(args, &rf->handler)) { + if (!available_devices[i]->srslte_rf_open_multi(args, &rf->handler, nof_rx_antennas)) { rf->dev = available_devices[i]; return 0; } @@ -182,12 +186,12 @@ void srslte_rf_register_error_handler(srslte_rf_t *rf, srslte_rf_error_handler_t int srslte_rf_open(srslte_rf_t *h, char *args) { - return srslte_rf_open_devname(h, NULL, args, 1); + return srslte_rf_open_devname_multi(h, NULL, args, 1); } int srslte_rf_open_multi(srslte_rf_t *h, char *args, uint32_t nof_rx_antennas) { - return srslte_rf_open_devname(h, NULL, args, nof_rx_antennas); + return srslte_rf_open_devname_multi(h, NULL, args, nof_rx_antennas); } int srslte_rf_close(srslte_rf_t *rf) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index ba02db6c8..cc237370a 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -177,10 +177,17 @@ void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) int rf_uhd_start_rx_stream(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; + uhd_stream_cmd_t stream_cmd = { .stream_mode = UHD_STREAM_MODE_START_CONTINUOUS, - .stream_now = true - }; + .stream_now = false + }; + uhd_usrp_get_time_now(handler->usrp, 0, &stream_cmd.time_spec_full_secs, &stream_cmd.time_spec_frac_secs); + stream_cmd.time_spec_frac_secs += 0.5; + if (stream_cmd.time_spec_frac_secs > 1) { + stream_cmd.time_spec_frac_secs -= 1; + stream_cmd.time_spec_full_secs += 1; + } uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); return 0; } @@ -199,9 +206,11 @@ int rf_uhd_stop_rx_stream(void *h) void rf_uhd_flush_buffer(void *h) { int n; - cf_t tmp[1024]; + cf_t tmp1[1024]; + cf_t tmp2[1024]; + void *data[2] = {tmp1, tmp2}; do { - n = rf_uhd_recv_with_time(h, tmp, 1024, 0, NULL, NULL); + n = rf_uhd_recv_with_time_multi(h, data, 1024, 0, NULL, NULL); } while (n > 0); } @@ -505,6 +514,9 @@ int rf_uhd_recv_with_time(void *h, return rf_uhd_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); } +cf_t data1[1024*100]; +cf_t data2[1024*100]; + int rf_uhd_recv_with_time_multi(void *h, void **data, uint32_t nsamples, @@ -514,13 +526,13 @@ int rf_uhd_recv_with_time_multi(void *h, { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - size_t rxd_samples[4]; + size_t rxd_samples; uhd_rx_metadata_handle *md = &handler->rx_md_first; int trials = 0; if (blocking) { int n = 0; do { - size_t rx_samples = handler->rx_nof_samples; + size_t rx_samples = nsamples; if (rx_samples > nsamples - n) { rx_samples = nsamples - n; @@ -528,22 +540,22 @@ int rf_uhd_recv_with_time_multi(void *h, void *buffs_ptr[4]; for (int i=0;inof_rx_channels;i++) { cf_t *data_c = (cf_t*) data[i]; - buffs_ptr[i] = &data_c[n]; + buffs_ptr[i] = &data_c[n]; } + uhd_error error = uhd_rx_streamer_recv(handler->rx_stream, buffs_ptr, - rx_samples, md, 1.0, false, rxd_samples); - + rx_samples, md, 1.0, false, &rxd_samples); if (error) { fprintf(stderr, "Error receiving from UHD: %d\n", error); return -1; } md = &handler->rx_md; - n += rxd_samples[0]; + n += rxd_samples; trials++; } while (n < nsamples && trials < 100); } else { return uhd_rx_streamer_recv(handler->rx_stream, data, - nsamples, md, 0.0, false, rxd_samples); + nsamples, md, 0.0, false, &rxd_samples); } if (secs && frac_secs) { uhd_rx_metadata_time_spec(handler->rx_md_first, secs, frac_secs); diff --git a/srslte/lib/rf/rf_utils.c b/srslte/lib/rf/rf_utils.c index 066b9a2b3..0d5c8a529 100644 --- a/srslte/lib/rf/rf_utils.c +++ b/srslte/lib/rf/rf_utils.c @@ -82,10 +82,11 @@ free_and_exit: return ret; } - +cf_t data2[1920*160]; int srslte_rf_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv(h, data, nsamples, 1); + void *d[2] = {data, data2}; + return srslte_rf_recv_with_time_multi(h, d, nsamples, 1, NULL, NULL); } double srslte_rf_set_rx_gain_th_wrapper(void *h, double f) { From e5e07e8fe621ea81c48309a3a4a95eabaa310a5a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Feb 2017 14:28:11 +0100 Subject: [PATCH 13/38] restored start stream --- srslte/lib/rf/rf_uhd_imp.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index cc237370a..5f6ba5815 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -177,17 +177,10 @@ void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) int rf_uhd_start_rx_stream(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; - uhd_stream_cmd_t stream_cmd = { - .stream_mode = UHD_STREAM_MODE_START_CONTINUOUS, - .stream_now = false - }; - uhd_usrp_get_time_now(handler->usrp, 0, &stream_cmd.time_spec_full_secs, &stream_cmd.time_spec_frac_secs); - stream_cmd.time_spec_frac_secs += 0.5; - if (stream_cmd.time_spec_frac_secs > 1) { - stream_cmd.time_spec_frac_secs -= 1; - stream_cmd.time_spec_full_secs += 1; - } + .stream_mode = UHD_STREAM_MODE_STOP_CONTINUOUS, + .stream_now = true + }; uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); return 0; } From 8f9f6ee922d14947611ac87d26803bde0b052c4e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Feb 2017 14:28:40 +0100 Subject: [PATCH 14/38] start stream with 0.5s offset to avoid overflows --- srslte/lib/rf/rf_uhd_imp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index d16382f52..f6ed03b2e 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -174,13 +174,19 @@ void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal) int rf_uhd_start_rx_stream(void *h) { - rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; + rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; + uhd_stream_cmd_t stream_cmd = { .stream_mode = UHD_STREAM_MODE_START_CONTINUOUS, - .stream_now = true - }; - uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); - return 0; + .stream_now = false + }; + uhd_usrp_get_time_now(handler->usrp, 0, &stream_cmd.time_spec_full_secs, &stream_cmd.time_spec_frac_secs); + stream_cmd.time_spec_frac_secs += 0.5; + if (stream_cmd.time_spec_frac_secs > 1) { + stream_cmd.time_spec_frac_secs -= 1; + stream_cmd.time_spec_full_secs += 1; + } + uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); return 0; } int rf_uhd_stop_rx_stream(void *h) From 9b04b6ee8885eb9a7dbc231dc7f1ec8aff053ae7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Feb 2017 18:22:10 +0100 Subject: [PATCH 15/38] forgot return 0 --- srslte/lib/rf/rf_uhd_imp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index f6ed03b2e..e0a1c61d0 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -187,6 +187,7 @@ int rf_uhd_start_rx_stream(void *h) stream_cmd.time_spec_full_secs += 1; } uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); return 0; + return 0; } int rf_uhd_stop_rx_stream(void *h) From 57e7898bd8a2f0cb3e5aab213d2179412bb71b1b Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Feb 2017 18:23:09 +0100 Subject: [PATCH 16/38] forgot return 0 --- srslte/lib/rf/rf_uhd_imp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index e0a1c61d0..0052e801b 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -186,8 +186,8 @@ int rf_uhd_start_rx_stream(void *h) stream_cmd.time_spec_frac_secs -= 1; stream_cmd.time_spec_full_secs += 1; } - uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); return 0; - return 0; + uhd_rx_streamer_issue_stream_cmd(handler->rx_stream, &stream_cmd); + return 0; } int rf_uhd_stop_rx_stream(void *h) From 0a5a6245f167e8fbcb9a02fa1f55ffe64fa07be5 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 13 Feb 2017 13:29:20 +0100 Subject: [PATCH 17/38] pdsch ue working with 1 and 2 antennas --- srslte/examples/cell_measurement.c | 23 ++--- srslte/examples/cell_search.c | 12 ++- srslte/examples/pdsch_ue.c | 27 +++--- srslte/examples/usrp_capture_sync.c | 14 +-- srslte/include/srslte/rf/rf_utils.h | 3 + srslte/include/srslte/ue/ue_cell_search.h | 6 +- srslte/include/srslte/ue/ue_dl.h | 15 ++-- srslte/include/srslte/ue/ue_mib.h | 5 +- srslte/include/srslte/ue/ue_sync.h | 14 ++- srslte/lib/ch_estimation/chest_dl.c | 1 - srslte/lib/phch/test/pdsch_pdcch_file_test.c | 4 +- srslte/lib/rf/rf_utils.c | 27 +++--- srslte/lib/ue/ue_cell_search.c | 19 +++- srslte/lib/ue/ue_dl.c | 92 ++++++++++++-------- srslte/lib/ue/ue_mib.c | 26 ++++-- srslte/lib/ue/ue_sync.c | 77 +++++++--------- 16 files changed, 211 insertions(+), 154 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index de9962513..9794f04c7 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -129,9 +129,10 @@ void sig_int_handler(int signo) } } -int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *q) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *q) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv(h, data, nsamples, 1); + + return srslte_rf_recv(h, data[0], nsamples, 1); } enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; @@ -141,7 +142,7 @@ enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; int main(int argc, char **argv) { int ret; - cf_t *sf_buffer; + cf_t *sf_buffer[SRSLTE_MAX_RXANT] = {NULL, NULL}; prog_args_t prog_args; srslte_cell_t cell; int64_t sf_cnt; @@ -180,6 +181,8 @@ int main(int argc, char **argv) { } srslte_rf_set_rx_gain(&rf, 50); } + + sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); sigset_t sigset; sigemptyset(&sigset); @@ -198,7 +201,7 @@ int main(int argc, char **argv) { uint32_t ntrial=0; do { - ret = rf_search_and_decode_mib(&rf, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); + ret = rf_search_and_decode_mib(&rf, 1, &cell_detect_config, prog_args.force_N_id_2, &cell, &cfo); if (ret < 0) { fprintf(stderr, "Error searching for cell\n"); exit(-1); @@ -234,11 +237,11 @@ int main(int argc, char **argv) { srslte_rf_stop_rx_stream(&rf); srslte_rf_flush_buffer(&rf); - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { + if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } - if (srslte_ue_dl_init(&ue_dl, cell)) { + if (srslte_ue_dl_init(&ue_dl, cell, 1)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); return -1; } @@ -280,7 +283,7 @@ int main(int argc, char **argv) { /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { - ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -292,7 +295,7 @@ int main(int argc, char **argv) { case DECODE_MIB: if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { srslte_pbch_decode_reset(&ue_mib.pbch); - n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); + n = srslte_ue_mib_decode(&ue_mib, sf_buffer[0], bch_payload, NULL, &sfn_offset); if (n < 0) { fprintf(stderr, "Error decoding UE MIB\n"); return -1; @@ -329,11 +332,11 @@ int main(int argc, char **argv) { if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { /* Run FFT for all subframe data */ - srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols); + srslte_ofdm_rx_sf(&fft, sf_buffer[0], sf_symbols); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); - rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); + rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer[0],SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05); rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05); diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index 02c3d8ada..a15d5be8e 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -120,9 +120,13 @@ void parse_args(int argc, char **argv) { } } -int srslte_rf_recv_wrapper(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return srslte_rf_recv((srslte_rf_t*) h, data, nsamples, 1); + void *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;icell.nof_ports;port_id++) { - printf("rxant=%d, port=%d, input=0x%x, ce=0x%x\n", rxant, port_id, input[rxant], ce[port_id][rxant]); if (srslte_chest_dl_estimate_port(q, input[rxant], ce[port_id][rxant], sf_idx, port_id)) { return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index 33ad2c58d..f31cc38da 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -137,7 +137,7 @@ int base_init() { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell)) { + if (srslte_ue_dl_init(&ue_dl, cell, 1)) { fprintf(stderr, "Error initializing UE DL\n"); return -1; } @@ -177,7 +177,7 @@ int main(int argc, char **argv) { srslte_filesource_read(&fsrc, input_buffer, flen); INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); - ret = srslte_ue_dl_decode(&ue_dl, input_buffer, data, sf_idx); + ret = srslte_ue_dl_decode(&ue_dl, &input_buffer, data, sf_idx); if(ret > 0) { printf("PDSCH Decoded OK!\n"); } else if (ret == 0) { diff --git a/srslte/lib/rf/rf_utils.c b/srslte/lib/rf/rf_utils.c index 0d5c8a529..935425b16 100644 --- a/srslte/lib/rf/rf_utils.c +++ b/srslte/lib/rf/rf_utils.c @@ -82,11 +82,13 @@ free_and_exit: return ret; } -cf_t data2[1920*160]; -int srslte_rf_recv_wrapper_cs(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper_cs(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - void *d[2] = {data, data2}; - return srslte_rf_recv_with_time_multi(h, d, nsamples, 1, NULL, NULL); + void *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;iid, cell->cp, srslte_rf_recv_wrapper_cs, (void*) rf)) { + if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } @@ -152,8 +154,9 @@ clean_exit: /** This function is simply a wrapper to the ue_cell_search module for rf devices */ -int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, - int force_N_id_2, srslte_cell_t *cell, float *cfo) +int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, + cell_search_cfg_t *config, + int force_N_id_2, srslte_cell_t *cell, float *cfo) { int ret = SRSLTE_ERROR; srslte_ue_cellsearch_t cs; @@ -161,7 +164,7 @@ int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, (void*) rf)) { + if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } @@ -235,15 +238,15 @@ int rf_cell_search(srslte_rf_t *rf, cell_search_cfg_t *config, * 0 if no cell was found or MIB could not be decoded, * -1 on error */ -int rf_search_and_decode_mib(srslte_rf_t *rf, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell, float *cfo) +int rf_search_and_decode_mib(srslte_rf_t *rf, uint32_t nof_rx_antennas, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell, float *cfo) { int ret = SRSLTE_ERROR; printf("Searching for cell...\n"); - ret = rf_cell_search(rf, config, force_N_id_2, cell, cfo); + ret = rf_cell_search(rf, nof_rx_antennas, config, force_N_id_2, cell, cfo); if (ret > 0) { printf("Decoding PBCH for cell %d (N_id_2=%d)\n", cell->id, cell->id%3); - ret = rf_mib_decoder(rf, config, cell, cfo); + ret = rf_mib_decoder(rf, nof_rx_antennas, config, cell, cfo); if (ret < 0) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", cell->id); return SRSLTE_ERROR; diff --git a/srslte/lib/ue/ue_cell_search.c b/srslte/lib/ue/ue_cell_search.c index 018f20a8a..a535b7c64 100644 --- a/srslte/lib/ue/ue_cell_search.c +++ b/srslte/lib/ue/ue_cell_search.c @@ -36,7 +36,9 @@ #include "srslte/utils/vector.h" int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, - int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler) + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -50,11 +52,16 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, cell.id = SRSLTE_CELL_ID_UNKNOWN; cell.nof_prb = SRSLTE_CS_NOF_PRB; - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); goto clean_exit; } + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); + } + q->nof_rx_antennas = nof_rx_antennas; + q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames); if (!q->candidates) { perror("malloc"); @@ -86,6 +93,11 @@ clean_exit: void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t * q) { + for (int i=0;inof_rx_antennas;i++) { + if (q->sf_buffer[i]) { + free(q->sf_buffer[i]); + } + } if (q->candidates) { free(q->candidates); } @@ -203,7 +215,6 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_cellsearch_result_t *found_cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - cf_t *sf_buffer = NULL; uint32_t nof_detected_frames = 0; uint32_t nof_scanned_frames = 0; @@ -215,7 +226,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_sync_reset(&q->ue_sync); do { - ret = srslte_ue_sync_get_buffer(&q->ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index d1a19620a..6f326b114 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -46,11 +46,13 @@ const uint32_t nof_common_formats = 2; int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell) + srslte_cell_t cell, + uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; - if (q != NULL && + if (q != NULL && + nof_rx_antennas <= SRSLTE_MAX_RXANT && srslte_cell_isvalid(&cell)) { ret = SRSLTE_ERROR; @@ -62,6 +64,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, q->pkts_total = 0; q->pending_ul_dci_rnti = 0; q->sample_offset = 0; + q->nof_rx_antennas = nof_rx_antennas; if (srslte_ofdm_rx_init(&q->fft, q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); @@ -89,7 +92,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, goto clean_exit; } - if (srslte_pdsch_init(&q->pdsch, q->cell)) { + if (srslte_pdsch_init_multi(&q->pdsch, q->cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PDSCH object\n"); goto clean_exit; } @@ -103,17 +106,19 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, } srslte_cfo_set_tol(&q->sfo_correct, 1e-5/q->fft.symbol_sz); - q->sf_symbols = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->sf_symbols) { - perror("malloc"); - goto clean_exit; - } - for (uint32_t i=0;icell.nof_ports;i++) { - q->ce[i] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->ce[i]) { + for (int j=0;jsf_symbols[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->sf_symbols[j]) { perror("malloc"); goto clean_exit; } + for (uint32_t i=0;icell.nof_ports;i++) { + q->ce[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->ce[i][j]) { + perror("malloc"); + goto clean_exit; + } + } } ret = SRSLTE_SUCCESS; @@ -140,12 +145,14 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_pdsch_free(&q->pdsch); srslte_cfo_free(&q->sfo_correct); srslte_softbuffer_rx_free(&q->softbuffer); - if (q->sf_symbols) { - free(q->sf_symbols); - } - for (uint32_t i=0;icell.nof_ports;i++) { - if (q->ce[i]) { - free(q->ce[i]); + for (int j=0;jnof_rx_antennas;j++) { + if (q->sf_symbols[j]) { + free(q->sf_symbols[j]); + } + for (uint32_t i=0;icell.nof_ports;i++) { + if (q->ce[i][j]) { + free(q->ce[i][j]); + } } } bzero(q, sizeof(srslte_ue_dl_t)); @@ -186,23 +193,25 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti) { +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti) { return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); } -int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t *cfi) { +int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint32_t sf_idx, uint32_t *cfi) { if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Run FFT for all subframe data */ - srslte_ofdm_rx_sf(&q->fft, input, q->sf_symbols); - - /* Correct SFO multiplying by complex exponential in the time domain */ - if (q->sample_offset) { - 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); + for (int j=0;jnof_rx_antennas;j++) { + srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols[j]); + + /* Correct SFO multiplying by complex exponential in the time domain */ + if (q->sample_offset) { + for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { + srslte_cfo_correct(&q->sfo_correct, + &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + q->sample_offset / q->fft.symbol_sz); + } } } return srslte_ue_dl_decode_estimate(q, sf_idx, cfi); @@ -216,10 +225,14 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c if (q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Get channel estimates for each port */ - srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); + srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols, q->ce, sf_idx, q->nof_rx_antennas); /* First decode PCFICH and obtain CFI */ - if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols[0], ce0, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); @@ -245,7 +258,7 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti, uint16_t rnti) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; @@ -259,7 +272,11 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint return ret; } - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols[0], ce0, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } @@ -299,7 +316,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { - ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, + ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, q->sf_symbols, q->ce, noise_estimate, rnti, data); @@ -502,7 +519,14 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr INFO("Decoding PHICH sf_idx=%d, n_prb_lowest=%d, n_dmrs=%d, n_group=%d, n_seq=%d, Ngroups=%d, Nsf=%d\n", sf_idx, n_prb_lowest, n_dmrs, ngroup, nseq, srslte_phich_ngroups(&q->phich), srslte_phich_nsf(&q->phich)); - if (!srslte_phich_decode(&q->phich, q->sf_symbols, q->ce, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { + + cf_t *ce0[SRSLTE_MAX_PORTS]; + for (int i=0;ice[i][0]; + } + + + if (!srslte_phich_decode(&q->phich, q->sf_symbols[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { fprintf(stderr, "Error decoding PHICH\n"); diff --git a/srslte/lib/ue/ue_mib.c b/srslte/lib/ue/ue_mib.c index 5cfeaaadd..7e178161b 100644 --- a/srslte/lib/ue/ue_mib.c +++ b/srslte/lib/ue/ue_mib.c @@ -164,10 +164,11 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, - uint32_t cell_id, - srslte_cp_t cp, - int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), - void *stream_handler) + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { srslte_cell_t cell; // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports @@ -176,11 +177,16 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); + } + q->nof_rx_antennas = nof_rx_antennas; + if (srslte_ue_mib_init(&q->ue_mib, cell)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; @@ -190,6 +196,11 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, } void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q) { + for (int i=0;inof_rx_antennas;i++) { + if (q->sf_buffer[i]) { + free(q->sf_buffer[i]); + } + } srslte_ue_mib_free(&q->ue_mib); srslte_ue_sync_free(&q->ue_sync); } @@ -207,7 +218,6 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, { int ret = SRSLTE_ERROR_INVALID_INPUTS; - cf_t *sf_buffer = NULL; uint32_t nof_frames = 0; int mib_ret = SRSLTE_UE_MIB_NOTFOUND; @@ -216,13 +226,13 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, ret = SRSLTE_SUCCESS; do { mib_ret = SRSLTE_UE_MIB_NOTFOUND; - ret = srslte_ue_sync_get_buffer(&q->ue_sync, &sf_buffer); + ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; } else if (srslte_ue_sync_get_sfidx(&q->ue_sync) == 0) { if (ret == 1) { - mib_ret = srslte_ue_mib_decode(&q->ue_mib, sf_buffer, bch_payload, nof_tx_ports, sfn_offset); + mib_ret = srslte_ue_mib_decode(&q->ue_mib, q->sf_buffer[0], bch_payload, nof_tx_ports, sfn_offset); } else { DEBUG("Resetting PBCH decoder after %d frames\n", q->ue_mib.frame_cnt); srslte_ue_mib_reset(&q->ue_mib); diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 6ef05daff..bc045eb57 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -39,7 +39,6 @@ #define MAX_TIME_OFFSET 128 -cf_t dummy[MAX_TIME_OFFSET]; #define TRACK_MAX_LOST 4 #define TRACK_FRAME_SIZE 32 @@ -47,7 +46,11 @@ cf_t dummy[MAX_TIME_OFFSET]; #define DEFAULT_SAMPLE_OFFSET_CORRECT_PERIOD 0 #define DEFAULT_SFO_EMA_COEFF 0.1 -cf_t dummy_offset_buffer[1024*1024]; +cf_t dummy_buffer0[15*2048/2]; +cf_t dummy_buffer1[15*2048/2]; + +// FIXME: this will break for 4 antennas!! +cf_t *dummy_offset_buffer[SRSLTE_MAX_RXANT] = {dummy_buffer0, dummy_buffer1}; int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset_time, float offset_freq) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -74,12 +77,6 @@ int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_n goto clean_exit; } - q->input_buffer = srslte_vec_malloc(2 * q->sf_len * sizeof(cf_t)); - if (!q->input_buffer) { - perror("malloc"); - goto clean_exit; - } - INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq/1000); srslte_filesource_read(&q->file_source, dummy_offset_buffer, offset_time); @@ -111,14 +108,16 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && stream_handler != NULL && - srslte_nofprb_isvalid(cell.nof_prb) && + srslte_nofprb_isvalid(cell.nof_prb) && + nof_rx_antennas <= SRSLTE_MAX_RXANT && recv_callback != NULL) { ret = SRSLTE_ERROR; @@ -127,6 +126,7 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, q->stream = stream_handler; q->recv_callback = recv_callback; + q->nof_rx_antennas = nof_rx_antennas; q->cell = cell; q->fft_size = srslte_symbol_sz(q->cell.nof_prb); q->sf_len = SRSLTE_SF_LEN(q->fft_size); @@ -209,13 +209,6 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, } - /* FIXME: Go for zerocopy only and eliminate this allocation */ - q->input_buffer = srslte_vec_malloc(2*q->frame_len * sizeof(cf_t)); - if (!q->input_buffer) { - perror("malloc"); - goto clean_exit; - } - srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; @@ -233,9 +226,6 @@ uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q) { } void srslte_ue_sync_free(srslte_ue_sync_t *q) { - if (q->input_buffer) { - free(q->input_buffer); - } if (q->do_agc) { srslte_agc_free(&q->agc); } @@ -309,7 +299,7 @@ void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, uint32_t period) { q->agc_period = period; } -static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer) { +static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { if (srslte_sync_sss_detected(&q->sfind)) { @@ -408,7 +398,7 @@ static int track_peak_ok(srslte_ue_sync_t *q, uint32_t track_idx) { discard the offseted samples to align next frame */ if (q->next_rf_sample_offset > 0 && q->next_rf_sample_offset < MAX_TIME_OFFSET) { DEBUG("Positive time offset %d samples.\n", q->next_rf_sample_offset); - if (q->recv_callback(q->stream, dummy, (uint32_t) q->next_rf_sample_offset, &q->last_timestamp) < 0) { + if (q->recv_callback(q->stream, dummy_offset_buffer, (uint32_t) q->next_rf_sample_offset, &q->last_timestamp) < 0) { fprintf(stderr, "Error receiving from USRP\n"); return SRSLTE_ERROR; } @@ -443,7 +433,7 @@ static int track_peak_no(srslte_ue_sync_t *q) { } -static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { +static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { /* A negative time offset means there are samples in our buffer for the next subframe, because we are sampling too fast. @@ -453,7 +443,11 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { } /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ - if (q->recv_callback(q->stream, &input_buffer[q->next_rf_sample_offset], q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { + cf_t *ptr[SRSLTE_MAX_RXANT]; + for (int i=0;inext_rf_sample_offset]; + } + if (q->recv_callback(q->stream, ptr, q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } @@ -465,17 +459,8 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer) { bool first_track = true; -int srslte_ue_sync_get_buffer(srslte_ue_sync_t *q, cf_t **sf_symbols) { - int ret = srslte_ue_sync_zerocopy(q, q->input_buffer); - if (sf_symbols) { - *sf_symbols = q->input_buffer; - } - return ret; - -} - /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ -int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; @@ -484,7 +469,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { { if (q->file_mode) { - int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer[0], q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -492,7 +477,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { if (n == 0) { srslte_filesource_seek(&q->file_source, 0); q->sf_idx = 9; - int n = srslte_filesource_read(&q->file_source, input_buffer, q->sf_len); + int n = srslte_filesource_read(&q->file_source, input_buffer[0], q->sf_len); if (n < 0) { fprintf(stderr, "Error reading input file\n"); return SRSLTE_ERROR; @@ -500,8 +485,8 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { } if (q->correct_cfo) { srslte_cfo_correct(&q->file_cfo_correct, - input_buffer, - input_buffer, + input_buffer[0], + input_buffer[0], q->file_cfo / 15000 / q->fft_size); } @@ -519,7 +504,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { switch (q->state) { case SF_FIND: - switch(srslte_sync_find(&q->sfind, input_buffer, 0, &q->peak_idx)) { + switch(srslte_sync_find(&q->sfind, input_buffer[0], 0, &q->peak_idx)) { case SRSLTE_SYNC_ERROR: ret = SRSLTE_ERROR; fprintf(stderr, "Error finding correlation peak (%d)\n", ret); @@ -539,7 +524,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { break; } if (q->do_agc) { - srslte_agc_process(&q->agc, input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } break; @@ -557,7 +542,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { if (q->do_agc && (q->agc_period == 0 || (q->agc_period && (q->frame_total_cnt%q->agc_period) == 0))) { - srslte_agc_process(&q->agc, input_buffer, q->sf_len); + srslte_agc_process(&q->agc, input_buffer[0], q->sf_len); } #ifdef MEASURE_EXEC_TIME @@ -570,7 +555,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { /* Track PSS/SSS around the expected PSS position * In tracking phase, the subframe carrying the PSS is always the last one of the frame */ - switch(srslte_sync_find(&q->strack, input_buffer, + switch(srslte_sync_find(&q->strack, input_buffer[0], q->frame_len - q->sf_len/2 - q->fft_size - q->strack.max_offset/2, &track_idx)) { @@ -607,10 +592,12 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { q->frame_total_cnt++; } if (q->correct_cfo) { - srslte_cfo_correct(&q->sfind.cfocorr, - input_buffer, - input_buffer, + for (int i=0;inof_rx_antennas;i++) { + srslte_cfo_correct(&q->sfind.cfocorr, + input_buffer[i], + input_buffer[i], -srslte_sync_get_cfo(&q->strack) / q->fft_size); + } } break; } From 5a6126aea0e76114cf5596b25481f8dec2cd7179 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 14 Feb 2017 11:59:37 +0100 Subject: [PATCH 18/38] added missing dotprod_cfc definition --- cmake/modules/FindVolk.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/FindVolk.cmake b/cmake/modules/FindVolk.cmake index 5dbe17cd5..cdb8b8ed8 100644 --- a/cmake/modules/FindVolk.cmake +++ b/cmake/modules/FindVolk.cmake @@ -135,6 +135,9 @@ IF(VOLK_FOUND) IF(${HAVE_VOLK_DOTPROD_FC_FUNCTION}) SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_FC_FUNCTION") ENDIF() + IF(${HAVE_VOLK_DOTPROD_CFC_FUNCTION}) + SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CFC_FUNCTION") + ENDIF() IF(${HAVE_VOLK_DOTPROD_F_FUNCTION}) SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_F_FUNCTION") ENDIF() From 6d9770afca4537f9697c66477c265947d233f0e7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 14 Feb 2017 12:09:06 +0100 Subject: [PATCH 19/38] added missing volk definitions --- cmake/modules/FindVolk.cmake | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindVolk.cmake b/cmake/modules/FindVolk.cmake index cdb8b8ed8..92b2b91ea 100644 --- a/cmake/modules/FindVolk.cmake +++ b/cmake/modules/FindVolk.cmake @@ -54,7 +54,7 @@ IF(VOLK_FOUND) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_add_32f HAVE_VOLK_ADD_FLOAT_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_x2_square_dist_32f HAVE_VOLK_SQUARE_DIST_FUNCTION) - CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_FUNCTION) + CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32fc_index_max_16u HAVE_VOLK_MAX_ABS_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_multiply_32f HAVE_VOLK_MULT_REAL2_FUNCTION) CHECK_FUNCTION_EXISTS_MATH(volk_16i_max_star_16i HAVE_VOLK_MAX_STAR_S_FUNCTION) @@ -63,6 +63,12 @@ IF(VOLK_FOUND) SET(VOLK_DEFINITIONS "HAVE_VOLK") + IF(${HAVE_VOLK_CONVERT_IF_FUNCTION}) + SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_IF_FUNCTION") + ENDIF() + IF(${HAVE_VOLK_MULT_REAL2_FUNCTION}) + SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_MULT_REAL2_FUNCTION") + ENDIF() IF(${HAVE_VOLK_CONVERT_CI_FUNCTION}) SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_CI_FUNCTION") ENDIF() @@ -99,8 +105,8 @@ IF(VOLK_FOUND) IF(${HAVE_VOLK_MULT2_CONJ_FUNCTION}) SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_MULT2_CONJ_FUNCTION") ENDIF() - IF(${HAVE_VOLK_DEINTERLEAVE_FUNCTION}) - SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_FUNCTION") + IF(${HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION}) + SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION") ENDIF() IF(${HAVE_VOLK_CONVERT_FI_FUNCTION}) SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_CONVERT_FI_FUNCTION") From 7c30d85536489863aa69a1d7694a83180be7df66 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 15 Feb 2017 11:47:45 +0000 Subject: [PATCH 20/38] fixing errors with compiler flags --- CMakeLists.txt | 9 ++++++++- cmake/modules/FindSSE.cmake | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae8e9c532..de2991136 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,14 @@ if(CMAKE_COMPILER_IS_GNUCC) endif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - + IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon -march=native -DIS_ARM -DHAVE_NEON") +message(STATUS "have ARM") +ELSE(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") +ENDIF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") + +set(CMAKE_REQUIRED_FLAGS ${CMAKE_C_FLAGS}) + if(NOT WIN32) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) endif(NOT WIN32) diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index 7b258f70f..959022fa7 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -1,3 +1,6 @@ +#if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|^i[3,9]86$") +# return() +#endif() include(CheckCSourceRuns) @@ -96,4 +99,4 @@ if (ENABLE_SSE) endif() -mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2) \ No newline at end of file +mark_as_advanced(HAVE_SSE, HAVE_AVX, HAVE_AVX2) From 54d4d48f96eabca56ca69ca07460842513a2558f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 17 Feb 2017 09:34:55 +0100 Subject: [PATCH 21/38] added multi antenna to pdcch --- .../include/srslte/ch_estimation/chest_dl.h | 10 ++- srslte/include/srslte/phch/pdcch.h | 19 +++- srslte/lib/ch_estimation/chest_dl.c | 47 ++++++---- srslte/lib/ch_estimation/test/chest_test_dl.c | 2 +- srslte/lib/phch/pdcch.c | 87 ++++++++++++------- srslte/lib/ue/ue_dl.c | 15 ++-- 6 files changed, 118 insertions(+), 62 deletions(-) diff --git a/srslte/include/srslte/ch_estimation/chest_dl.h b/srslte/include/srslte/ch_estimation/chest_dl.h index 1d37b3aad..50a083dae 100644 --- a/srslte/include/srslte/ch_estimation/chest_dl.h +++ b/srslte/include/srslte/ch_estimation/chest_dl.h @@ -76,9 +76,9 @@ typedef struct { srslte_interp_linsrslte_vec_t srslte_interp_linvec; srslte_interp_lin_t srslte_interp_lin; - float rssi[SRSLTE_MAX_PORTS]; - float rsrp[SRSLTE_MAX_PORTS]; - float noise_estimate[SRSLTE_MAX_PORTS]; + float rssi[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS]; + float rsrp[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS]; + float noise_estimate[SRSLTE_MAX_RXANT][SRSLTE_MAX_PORTS]; /* Use PSS for noise estimation in LS linear interpolation mode */ cf_t pss_signal[SRSLTE_PSS_LEN]; @@ -86,6 +86,7 @@ typedef struct { cf_t tmp_pss_noisy[SRSLTE_PSS_LEN]; srslte_chest_dl_noise_alg_t noise_alg; + int last_nof_antennas; } srslte_chest_dl_t; @@ -120,7 +121,8 @@ SRSLTE_API int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, - uint32_t port_id); + uint32_t port_id, + uint32_t rxant_id); SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q); diff --git a/srslte/include/srslte/phch/pdcch.h b/srslte/include/srslte/phch/pdcch.h index 5f080cbd8..ba538ba98 100644 --- a/srslte/include/srslte/phch/pdcch.h +++ b/srslte/include/srslte/phch/pdcch.h @@ -63,12 +63,13 @@ typedef struct SRSLTE_API { uint32_t nof_regs; uint32_t nof_cce; uint32_t max_bits; - + uint32_t nof_rx_antennas; + srslte_regs_t *regs; /* buffers */ - cf_t *ce[SRSLTE_MAX_PORTS]; - cf_t *symbols[SRSLTE_MAX_PORTS]; + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + cf_t *symbols[SRSLTE_MAX_RXANT]; cf_t *x[SRSLTE_MAX_PORTS]; cf_t *d; uint8_t *e; @@ -87,6 +88,11 @@ SRSLTE_API int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell); +SRSLTE_API int srslte_pdcch_init_multi(srslte_pdcch_t *q, + srslte_regs_t *regs, + srslte_cell_t cell, + uint32_t nof_rx_antennas); + SRSLTE_API void srslte_pdcch_free(srslte_pdcch_t *q); @@ -113,6 +119,13 @@ SRSLTE_API int srslte_pdcch_extract_llr(srslte_pdcch_t *q, uint32_t nsubframe, uint32_t cfi); +SRSLTE_API int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, + cf_t *sf_symbols[SRSLTE_MAX_RXANT], + cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], + float noise_estimate, + uint32_t nsubframe, + uint32_t cfi); + /* Decoding functions: Try to decode a DCI message after calling srslte_pdcch_extract_llr */ SRSLTE_API int srslte_pdcch_decode_msg(srslte_pdcch_t *q, srslte_dci_msg_t *msg, diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index 7145c9fd6..d6b6a0480 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -311,7 +311,7 @@ float srslte_chest_dl_rssi(srslte_chest_dl_t *q, cf_t *input, uint32_t port_id) return rssi/nsymbols; } -int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id) +int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, uint32_t sf_idx, uint32_t port_id, uint32_t rxant_id) { /* Get references from the input signal */ srslte_refsignal_cs_get_sf(q->cell, port_id, input, q->pilot_recv_signal); @@ -331,24 +331,24 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u /* 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); + q->noise_estimate[rxant_id][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); + q->noise_estimate[rxant_id][port_id] = estimate_noise_pss(q, input, ce); } } else { if (sf_idx == 0 || sf_idx == 5) { - q->noise_estimate[port_id] = estimate_noise_empty_sc(q, input); + q->noise_estimate[rxant_id][port_id] = estimate_noise_empty_sc(q, input); } } } /* Compute RSRP for the channel estimates in this port */ - q->rsrp[port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); + q->rsrp[rxant_id][port_id] = srslte_vec_avg_power_cf(q->pilot_recv_signal, SRSLTE_REFSIGNAL_NUM_SF(q->cell.nof_prb, port_id)); if (port_id == 0) { /* compute rssi only for port 0 */ - q->rssi[port_id] = srslte_chest_dl_rssi(q, input, port_id); + q->rssi[rxant_id][port_id] = srslte_chest_dl_rssi(q, input, port_id); } return 0; @@ -356,13 +356,14 @@ int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q, cf_t *input, cf_t *ce, u int srslte_chest_dl_estimate_multi(srslte_chest_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], uint32_t sf_idx, uint32_t nof_rx_antennas) { - for (uint32_t rxant=0;rxantcell.nof_ports;port_id++) { - if (srslte_chest_dl_estimate_port(q, input[rxant], ce[port_id][rxant], sf_idx, port_id)) { + if (srslte_chest_dl_estimate_port(q, input[rxant_id], ce[port_id][rxant_id], sf_idx, port_id, rxant_id)) { return SRSLTE_ERROR; } } } + q->last_nof_antennas = nof_rx_antennas; return SRSLTE_SUCCESS; } @@ -371,15 +372,20 @@ int srslte_chest_dl_estimate(srslte_chest_dl_t *q, cf_t *input, cf_t *ce[SRSLTE_ uint32_t port_id; for (port_id=0;port_idcell.nof_ports;port_id++) { - if (srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id)) { + if (srslte_chest_dl_estimate_port(q, input, ce[port_id], sf_idx, port_id, 0)) { return SRSLTE_ERROR; } } + q->last_nof_antennas = 1; return SRSLTE_SUCCESS; } float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) { - return srslte_vec_acc_ff(q->noise_estimate, q->cell.nof_ports)/q->cell.nof_ports; + float n = 0; + for (int i=0;ilast_nof_antennas;i++) { + n += srslte_vec_acc_ff(q->noise_estimate[i], q->cell.nof_ports)/q->cell.nof_ports; + } + return n/q->last_nof_antennas; } float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { @@ -392,20 +398,31 @@ float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) { } float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) { - return 4*q->rssi[0]/q->cell.nof_prb/SRSLTE_NRE; + float n = 0; + for (int i=0;ilast_nof_antennas;i++) { + n += 4*q->rssi[i][0]/q->cell.nof_prb/SRSLTE_NRE; + } + return n/q->last_nof_antennas; } /* q->rssi[0] is the average power in all RE in all symbol containing references for port 0 . q->rssi[0]/q->cell.nof_prb is the average power per PRB * q->rsrp[0] is the average power of RE containing references only (for port 0). */ float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q) { - return q->cell.nof_prb*q->rsrp[0] / q->rssi[0]; + float n = 0; + for (int i=0;ilast_nof_antennas;i++) { + n += q->cell.nof_prb*q->rsrp[i][0] / q->rssi[i][0]; + } + return n/q->last_nof_antennas; } -float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { - +float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { // return sum of power received from all tx ports - return srslte_vec_acc_ff(q->rsrp, q->cell.nof_ports); + float n = 0; + for (int i=0;ilast_nof_antennas;i++) { + n += srslte_vec_acc_ff(q->rsrp[i], q->cell.nof_ports)/q->cell.nof_ports; + } + return n/q->last_nof_antennas; } diff --git a/srslte/lib/ch_estimation/test/chest_test_dl.c b/srslte/lib/ch_estimation/test/chest_test_dl.c index d296ccc18..c60e94d96 100644 --- a/srslte/lib/ch_estimation/test/chest_test_dl.c +++ b/srslte/lib/ch_estimation/test/chest_test_dl.c @@ -161,7 +161,7 @@ int main(int argc, char **argv) { struct timeval t[3]; gettimeofday(&t[1], NULL); for (int j=0;j<100;j++) { - srslte_chest_dl_estimate_port(&est, input, ce, sf_idx, n_port); + srslte_chest_dl_estimate_port(&est, input, ce, sf_idx, n_port, 0); } gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 9cf610c01..4b40e5a06 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -62,8 +62,12 @@ float srslte_pdcch_coderate(uint32_t nof_bits, uint32_t l) { /** Initializes the PDCCH transmitter and receiver */ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell) { + return srslte_pdcch_init_multi(q, regs, cell, 1); +} + +int srslte_pdcch_init_multi(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell, uint32_t nof_rx_antennas) +{ int ret = SRSLTE_ERROR_INVALID_INPUTS; - uint32_t i; if (q != NULL && regs != NULL && @@ -73,6 +77,7 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell bzero(q, sizeof(srslte_pdcch_t)); q->cell = cell; q->regs = regs; + q->nof_rx_antennas = nof_rx_antennas; /* Allocate memory for the maximum number of PDCCH bits (CFI=3) */ q->max_bits = (srslte_regs_pdcch_nregs(q->regs, 3) / 9) * 72; @@ -87,7 +92,7 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell goto clean; } - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { // we need to pregenerate the sequence for the maximum number of bits, which is 8 times // the maximum number of REGs (for CFI=3) if (srslte_sequence_pdcch(&q->seq[i], 2 * i, q->cell.id, 8*srslte_regs_pdcch_nregs(q->regs, 3))) { @@ -117,17 +122,21 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell goto clean; } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - q->ce[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_bits / 2); - if (!q->ce[i]) { - goto clean; + for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { + for (int j=0;jnof_rx_antennas;j++) { + q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_bits / 2); + if (!q->ce[i][j]) { + goto clean; + } } q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_bits / 2); if (!q->x[i]) { goto clean; } - q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_bits / 2); - if (!q->symbols[i]) { + } + for (int j=0;jnof_rx_antennas;j++) { + q->symbols[j] = srslte_vec_malloc(sizeof(cf_t) * q->max_bits / 2); + if (!q->symbols[j]) { goto clean; } } @@ -142,7 +151,6 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell } void srslte_pdcch_free(srslte_pdcch_t *q) { - int i; if (q->e) { free(q->e); @@ -153,19 +161,22 @@ void srslte_pdcch_free(srslte_pdcch_t *q) { if (q->d) { free(q->d); } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - if (q->ce[i]) { - free(q->ce[i]); + for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { + for (int j=0;jnof_rx_antennas;j++) { + if (q->ce[i][j]) { + free(q->ce[i][j]); + } } if (q->x[i]) { free(q->x[i]); } - if (q->symbols[i]) { - free(q->symbols[i]); + } + for (int j=0;jnof_rx_antennas;j++) { + if (q->symbols[j]) { + free(q->symbols[j]); } } - - for (i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { + for (int i = 0; i < SRSLTE_NSUBFRAMES_X_FRAME; i++) { srslte_sequence_free(&q->seq[i]); } @@ -379,13 +390,27 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q, int cnt=0; +int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t nsubframe, uint32_t cfi) +{ + cf_t *_sf_symbols[SRSLTE_MAX_RXANT]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + + _sf_symbols[0] = sf_symbols; + for (int i=0;icell.nof_ports;i++) { + _ce[i][0] = ce[i]; + } + return srslte_pdcch_extract_llr_multi(q, _sf_symbols, _ce, noise_estimate, nsubframe, cfi); +} + /** Extracts the LLRs from srslte_dci_location_t location of the subframe and stores them in the srslte_pdcch_t structure. * DCI messages can be extracted from this location calling the function srslte_pdcch_decode_msg(). * Every time this function is called (with a different location), the last demodulated symbols are overwritten and * new messages from other locations can be decoded */ -int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint32_t nsubframe, uint32_t cfi) { +int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, cf_t *sf_symbols[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], float noise_estimate, + uint32_t nsubframe, uint32_t cfi) +{ int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -415,27 +440,29 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports)); /* extract symbols */ - int n = srslte_regs_pdcch_get(q->regs, sf_symbols, q->symbols[0]); - if (nof_symbols != n) { - fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); - return ret; - } - - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - n = srslte_regs_pdcch_get(q->regs, ce[i], q->ce[i]); + for (int j=0;jnof_rx_antennas;j++) { + int n = srslte_regs_pdcch_get(q->regs, sf_symbols[j], q->symbols[j]); if (nof_symbols != n) { fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); return ret; } - } + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + n = srslte_regs_pdcch_get(q->regs, ce[i][j], q->ce[i][j]); + if (nof_symbols != n) { + fprintf(stderr, "Expected %d PDCCH symbols but got %d symbols\n", nof_symbols, n); + return ret; + } + } + } + /* 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/2); + srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, q->nof_rx_antennas, nof_symbols, noise_estimate/2); } else { - srslte_predecoding_diversity(q->symbols[0], q->ce, x, q->cell.nof_ports, nof_symbols); + srslte_predecoding_diversity_multi(q->symbols, q->ce, x, q->nof_rx_antennas, 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/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 6f326b114..c12ce8889 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -87,7 +87,7 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, goto clean_exit; } - if (srslte_pdcch_init(&q->pdcch, &q->regs, q->cell)) { + if (srslte_pdcch_init_multi(&q->pdcch, &q->regs, q->cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PDCCH object\n"); goto clean_exit; } @@ -272,11 +272,11 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], u return ret; } - cf_t *ce0[SRSLTE_MAX_PORTS]; - for (int i=0;ice[i][0]; - } - if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols[0], ce0, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi)) { + float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); + // Uncoment next line to do ZF by default in pdsch_ue example + //float noise_estimate = 0; + + if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols, q->ce, noise_estimate, sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } @@ -311,9 +311,6 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], u q->nof_detected++; - // Uncoment next line to do ZF by default in pdsch_ue example - //float noise_estimate = 0; - float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, From 5de9fa6a462760205d142a351d02134c37f61558 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 17 Feb 2017 09:58:37 +0100 Subject: [PATCH 22/38] added multi antenna to phich, pcfich, set rxant constant tto max ports --- srslte/examples/cell_measurement.c | 4 +- srslte/examples/cell_search.c | 6 +- srslte/examples/pdsch_ue.c | 6 +- srslte/examples/usrp_capture_sync.c | 4 +- .../include/srslte/ch_estimation/chest_dl.h | 10 +-- srslte/include/srslte/common/phy_common.h | 1 - srslte/include/srslte/mimo/precoding.h | 8 +- srslte/include/srslte/phch/pcfich.h | 17 +++- srslte/include/srslte/phch/pdcch.h | 8 +- srslte/include/srslte/phch/pdsch.h | 8 +- srslte/include/srslte/phch/phich.h | 21 ++++- srslte/include/srslte/ue/ue_cell_search.h | 4 +- srslte/include/srslte/ue/ue_dl.h | 10 +-- srslte/include/srslte/ue/ue_mib.h | 4 +- srslte/include/srslte/ue/ue_sync.h | 6 +- srslte/lib/ch_estimation/chest_dl.c | 2 +- srslte/lib/mimo/precoding.c | 30 ++++---- srslte/lib/mimo/test/predecoder_mex.c | 6 +- srslte/lib/phch/pcfich.c | 77 ++++++++++++------- srslte/lib/phch/pdcch.c | 6 +- srslte/lib/phch/pdsch.c | 8 +- srslte/lib/phch/phich.c | 73 ++++++++++++------ srslte/lib/phch/test/pdsch_test_mex.c | 6 +- srslte/lib/rf/rf_utils.c | 6 +- srslte/lib/ue/ue_cell_search.c | 2 +- srslte/lib/ue/ue_dl.c | 16 ++-- srslte/lib/ue/ue_mib.c | 2 +- srslte/lib/ue/ue_sync.c | 16 ++-- 28 files changed, 218 insertions(+), 149 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 9794f04c7..493bbd606 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -129,7 +129,7 @@ void sig_int_handler(int signo) } } -int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *q) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *q) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); return srslte_rf_recv(h, data[0], nsamples, 1); @@ -142,7 +142,7 @@ enum receiver_state { DECODE_MIB, DECODE_SIB, MEASURE} state; int main(int argc, char **argv) { int ret; - cf_t *sf_buffer[SRSLTE_MAX_RXANT] = {NULL, NULL}; + cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL, NULL}; prog_args_t prog_args; srslte_cell_t cell; int64_t sf_cnt; diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index a15d5be8e..ee5704e5a 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -120,10 +120,10 @@ void parse_args(int argc, char **argv) { } } -int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_RXANT], uint32_t nsamples, srslte_timestamp_t *t) { +int srslte_rf_recv_wrapper(void *h, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *t) { DEBUG(" ---- Receive %d samples ---- \n", nsamples); - void *ptr[SRSLTE_MAX_RXANT]; - for (int i=0;icell.nof_ports;port_id++) { diff --git a/srslte/lib/mimo/precoding.c b/srslte/lib/mimo/precoding.c index 1b9183485..fe9befe3c 100644 --- a/srslte/lib/mimo/precoding.c +++ b/srslte/lib/mimo/precoding.c @@ -37,13 +37,13 @@ #ifdef LV_HAVE_SSE #include #include -int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); -int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_symbols); +int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); +int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_symbols); #endif #ifdef LV_HAVE_AVX #include -int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); +int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate); #endif @@ -58,7 +58,7 @@ int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ #define PROD(a,b) _mm_addsub_ps(_mm_mul_ps(a,_mm_moveldup_ps(b)),_mm_mul_ps(_mm_shuffle_ps(a,a,0xB1),_mm_movehdup_ps(b))) -int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { float *xPtr = (float*) x; const float *hPtr1 = (const float*) h[0]; @@ -146,7 +146,7 @@ int srslte_predecoding_single_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ -int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { float *xPtr = (float*) x; const float *hPtr1 = (const float*) h[0]; @@ -230,7 +230,7 @@ int srslte_predecoding_single_avx(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_ #endif -int srslte_predecoding_single_gen(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_RXANT], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { +int srslte_predecoding_single_gen(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS], cf_t *x, int nof_rxant, int nof_symbols, float noise_estimate) { for (int i=0;i 32) { return srslte_predecoding_single_avx(y, h, x, nof_rxant, nof_symbols, noise_estimate); @@ -293,7 +293,7 @@ int srslte_predecoding_single_multi(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MA } /* C implementatino of the SFBC equalizer */ -int srslte_predecoding_diversity_gen_(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], +int srslte_predecoding_diversity_gen_(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_ports, int nof_symbols, int symbol_start) { @@ -362,7 +362,7 @@ int srslte_predecoding_diversity_gen_(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_ } } -int srslte_predecoding_diversity_gen(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], +int srslte_predecoding_diversity_gen(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_ports, int nof_symbols) { return srslte_predecoding_diversity_gen_(y, h, x, nof_rxant, nof_ports, nof_symbols, 0); @@ -370,7 +370,7 @@ int srslte_predecoding_diversity_gen(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_M /* SSE implementation of the 2-port SFBC equalizer */ #ifdef LV_HAVE_SSE -int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], +int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_PORTS], cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_rxant, int nof_symbols) { @@ -481,8 +481,8 @@ int srslte_predecoding_diversity2_sse(cf_t *y[SRSLTE_MAX_RXANT], cf_t *h[SRSLTE_ int srslte_predecoding_diversity(cf_t *y_, cf_t *h_[SRSLTE_MAX_PORTS], cf_t *x[SRSLTE_MAX_LAYERS], int nof_ports, int nof_symbols) { - cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; - cf_t *y[SRSLTE_MAX_RXANT]; + cf_t *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + cf_t *y[SRSLTE_MAX_PORTS]; uint32_t nof_rxant = 1; for (int i=0;icell = cell; q->regs = regs; q->nof_symbols = PCFICH_RE; + q->nof_rx_antennas = nof_rx_antennas; if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; @@ -145,21 +150,33 @@ int srslte_pcfich_cfi_encode(uint32_t cfi, uint8_t bits[PCFICH_CFI_LEN]) { } } +int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t nsubframe, uint32_t *cfi, float *corr_result) +{ + cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + + _sf_symbols[0] = sf_symbols; + for (int i=0;icell.nof_ports;i++) { + _ce[i][0] = ce[i]; + } + return srslte_pcfich_decode_multi(q, _sf_symbols, _ce, noise_estimate, nsubframe, cfi, corr_result); +} + /* Decodes the PCFICH channel and saves the CFI in the cfi pointer. * * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error */ -int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint32_t nsubframe, uint32_t *cfi, float *corr_result) +int srslte_pcfich_decode_multi(srslte_pcfich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t nsubframe, uint32_t *cfi, float *corr_result) { /* Set pointers for layermapping & precoding */ int i; cf_t *x[SRSLTE_MAX_LAYERS]; - cf_t *ce_precoding[SRSLTE_MAX_PORTS]; - + if (q != NULL && - slot_symbols != NULL && + sf_symbols != NULL && nsubframe < SRSLTE_NSUBFRAMES_X_FRAME) { @@ -167,34 +184,37 @@ int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE for (i = 0; i < SRSLTE_MAX_PORTS; i++) { x[i] = q->x[i]; } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - ce_precoding[i] = q->ce[i]; - } - + + cf_t *q_symbols[SRSLTE_MAX_PORTS]; + cf_t *q_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + /* extract symbols */ - if (q->nof_symbols - != srslte_regs_pcfich_get(q->regs, slot_symbols, q->symbols[0])) { - fprintf(stderr, "There was an error getting the PCFICH symbols\n"); - return SRSLTE_ERROR; - } - - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, ce[i], q->ce[i])) { + for (int j=0;jnof_rx_antennas;j++) { + if (q->nof_symbols + != srslte_regs_pcfich_get(q->regs, sf_symbols[j], q->symbols[j])) { fprintf(stderr, "There was an error getting the PCFICH symbols\n"); return SRSLTE_ERROR; } - } + q_symbols[j] = q->symbols[j]; + + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, ce[i][j], q->ce[i][j])) { + fprintf(stderr, "There was an error getting the PCFICH symbols\n"); + return SRSLTE_ERROR; + } + q_ce[i][j] = q->ce[i][j]; + } + } + /* 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, q->nof_symbols, noise_estimate); + srslte_predecoding_single_multi(q_symbols, q_ce[0], q->d, q->nof_rx_antennas, q->nof_symbols, noise_estimate); } else { - srslte_predecoding_diversity(q->symbols[0], ce_precoding, x, - q->cell.nof_ports, q->nof_symbols); - srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, - q->nof_symbols / q->cell.nof_ports); + srslte_predecoding_diversity_multi(q_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, q->nof_symbols); + srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); } /* demodulate symbols */ @@ -229,14 +249,14 @@ int srslte_pcfich_encode(srslte_pcfich_t *q, uint32_t cfi, cf_t *slot_symbols[SR /* Set pointers for layermapping & precoding */ cf_t *x[SRSLTE_MAX_LAYERS]; - cf_t *symbols_precoding[SRSLTE_MAX_PORTS]; + cf_t *q_symbols[SRSLTE_MAX_PORTS]; /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { x[i] = q->x[i]; } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - symbols_precoding[i] = q->symbols[i]; + q_symbols[i] = q->symbols[i]; } /* pack CFI */ @@ -250,8 +270,7 @@ int srslte_pcfich_encode(srslte_pcfich_t *q, uint32_t cfi, cf_t *slot_symbols[SR /* layer mapping & precoding */ if (q->cell.nof_ports > 1) { srslte_layermap_diversity(q->d, x, q->cell.nof_ports, q->nof_symbols); - srslte_precoding_diversity(x, symbols_precoding, q->cell.nof_ports, - q->nof_symbols / q->cell.nof_ports); + srslte_precoding_diversity(x, q_symbols, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); } else { memcpy(q->symbols[0], q->d, q->nof_symbols * sizeof(cf_t)); } diff --git a/srslte/lib/phch/pdcch.c b/srslte/lib/phch/pdcch.c index 4b40e5a06..702a5440f 100644 --- a/srslte/lib/phch/pdcch.c +++ b/srslte/lib/phch/pdcch.c @@ -393,8 +393,8 @@ int cnt=0; int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, uint32_t nsubframe, uint32_t cfi) { - cf_t *_sf_symbols[SRSLTE_MAX_RXANT]; - cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; _sf_symbols[0] = sf_symbols; for (int i=0;icell.nof_ports;i++) { @@ -408,7 +408,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT * Every time this function is called (with a different location), the last demodulated symbols are overwritten and * new messages from other locations can be decoded */ -int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, cf_t *sf_symbols[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], float noise_estimate, +int srslte_pdcch_extract_llr_multi(srslte_pdcch_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, uint32_t nsubframe, uint32_t cfi) { diff --git a/srslte/lib/phch/pdsch.c b/srslte/lib/phch/pdsch.c index ccaea5282..9a2281753 100644 --- a/srslte/lib/phch/pdsch.c +++ b/srslte/lib/phch/pdsch.c @@ -215,7 +215,7 @@ int srslte_pdsch_init_multi(srslte_pdsch_t *q, srslte_cell_t cell, uint32_t nof_ if (q != NULL && srslte_cell_isvalid(&cell) && - nof_rx_antennas <= SRSLTE_MAX_RXANT) + nof_rx_antennas <= SRSLTE_MAX_PORTS) { bzero(q, sizeof(srslte_pdsch_t)); @@ -383,8 +383,8 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, uint16_t rnti, uint8_t *data) { - cf_t *_sf_symbols[SRSLTE_MAX_RXANT]; - cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; + cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; _sf_symbols[0] = sf_symbols; for (int i=0;icell.nof_ports;i++) { @@ -397,7 +397,7 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, */ int srslte_pdsch_decode_multi(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer, - cf_t *sf_symbols[SRSLTE_MAX_RXANT], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT], float noise_estimate, + cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, uint16_t rnti, uint8_t *data) { diff --git a/srslte/lib/phch/phich.c b/srslte/lib/phch/phich.c index ae5b6aa67..f7e6d7d29 100644 --- a/srslte/lib/phch/phich.c +++ b/srslte/lib/phch/phich.c @@ -67,8 +67,14 @@ void srslte_phich_reset(srslte_phich_t *q, cf_t *slot_symbols[SRSLTE_MAX_PORTS]) } } +int srslte_phich_init(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell) +{ + return srslte_phich_init_multi(q, regs, cell, 1); +} + /** Initializes the phich channel receiver */ -int srslte_phich_init(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell) { +int srslte_phich_init_multi(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell, uint32_t nof_rx_antennas) +{ int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && @@ -81,6 +87,7 @@ int srslte_phich_init(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell q->cell = cell; q->regs = regs; + q->nof_rx_antennas = nof_rx_antennas; if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_BPSK)) { goto clean; @@ -155,19 +162,32 @@ void srslte_phich_ack_encode(uint8_t ack, uint8_t bits[SRSLTE_PHICH_NBITS]) { memset(bits, ack, 3 * sizeof(uint8_t)); } +int srslte_phich_decode(srslte_phich_t *q, cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) +{ + cf_t *_sf_symbols[SRSLTE_MAX_PORTS]; + cf_t *_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + + _sf_symbols[0] = sf_symbols; + for (int i=0;icell.nof_ports;i++) { + _ce[i][0] = ce[i]; + } + + return srslte_phich_decode_multi(q, _sf_symbols, _ce, noise_estimate, ngroup, nseq, subframe, ack, distance); +} /* Decodes the phich channel and saves the CFI in the cfi pointer. * * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error */ -int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate, - uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) { +int srslte_phich_decode_multi(srslte_phich_t *q, cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate, + uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) +{ /* Set pointers for layermapping & precoding */ int i, j; cf_t *x[SRSLTE_MAX_LAYERS]; - cf_t *ce_precoding[SRSLTE_MAX_PORTS]; - if (q == NULL || slot_symbols == NULL) { + if (q == NULL || sf_symbols == NULL) { return SRSLTE_ERROR_INVALID_INPUTS; } @@ -198,34 +218,37 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_M for (i = 0; i < SRSLTE_MAX_PORTS; i++) { x[i] = q->x[i]; } - for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - ce_precoding[i] = q->ce[i]; - } + cf_t *q_ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + cf_t *q_sf_symbols[SRSLTE_MAX_PORTS]; + /* extract symbols */ - if (SRSLTE_PHICH_MAX_NSYMB - != srslte_regs_phich_get(q->regs, slot_symbols, q->symbols[0], ngroup)) { - fprintf(stderr, "There was an error getting the phich symbols\n"); - return SRSLTE_ERROR; - } - - /* extract channel estimates */ - for (i = 0; i < q->cell.nof_ports; i++) { - if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i], q->ce[i], ngroup)) { + for (int j=0;jnof_rx_antennas;j++) { + if (SRSLTE_PHICH_MAX_NSYMB + != srslte_regs_phich_get(q->regs, sf_symbols[j], q->sf_symbols[j], ngroup)) { fprintf(stderr, "There was an error getting the phich symbols\n"); return SRSLTE_ERROR; + } + q_sf_symbols[j] = q->sf_symbols[j]; + + /* extract channel estimates */ + for (i = 0; i < q->cell.nof_ports; i++) { + if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i][j], q->ce[i][j], ngroup)) { + fprintf(stderr, "There was an error getting the phich symbols\n"); + return SRSLTE_ERROR; + } + q_ce[i][j] = q->ce[i][j]; } + } /* 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->d0, SRSLTE_PHICH_MAX_NSYMB, noise_estimate); + srslte_predecoding_single_multi(q_sf_symbols, q_ce[0], q->d0, q->nof_rx_antennas, SRSLTE_PHICH_MAX_NSYMB, noise_estimate); } else { - srslte_predecoding_diversity(q->symbols[0], ce_precoding, x, - q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB); - srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, - SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); + srslte_predecoding_diversity_multi(q_sf_symbols, q_ce, x, q->nof_rx_antennas, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB); + srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); } DEBUG("Recv!!: \n", 0); DEBUG("d0: ", 0); @@ -328,7 +351,7 @@ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_ x[i] = q->x[i]; } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { - symbols_precoding[i] = q->symbols[i]; + symbols_precoding[i] = q->sf_symbols[i]; } /* encode ACK/NACK bit */ @@ -391,12 +414,12 @@ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_ SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); /**FIXME: According to 6.9.2, Precoding for 4 tx ports is different! */ } else { - memcpy(q->symbols[0], q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); + memcpy(q->sf_symbols[0], q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { - if (srslte_regs_phich_add(q->regs, q->symbols[i], ngroup, slot_symbols[i]) + if (srslte_regs_phich_add(q->regs, q->sf_symbols[i], ngroup, slot_symbols[i]) < 0) { fprintf(stderr, "Error putting PCHICH resource elements\n"); return SRSLTE_ERROR; diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index fa455809b..c2273916a 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -55,7 +55,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) srslte_ofdm_t ofdm_rx; srslte_pdsch_t pdsch; srslte_chest_dl_t chest; - cf_t *input_fft[SRSLTE_MAX_RXANT]; + cf_t *input_fft[SRSLTE_MAX_PORTS]; srslte_pdsch_cfg_t cfg; srslte_softbuffer_rx_t softbuffer; uint32_t rnti32; @@ -196,8 +196,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) nof_retx = mexutils_getLength(INPUT); } - cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_RXANT]; - for (int j=0;jpcfich, &q->regs, q->cell)) { + if (srslte_pcfich_init_multi(&q->pcfich, &q->regs, q->cell, nof_rx_antennas)) { fprintf(stderr, "Error creating PCFICH object\n"); goto clean_exit; } @@ -193,11 +193,11 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti) { +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti) { return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); } -int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint32_t sf_idx, uint32_t *cfi) { +int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi) { if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Run FFT for all subframe data */ @@ -228,11 +228,7 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols, q->ce, sf_idx, q->nof_rx_antennas); /* First decode PCFICH and obtain CFI */ - cf_t *ce0[SRSLTE_MAX_PORTS]; - for (int i=0;ice[i][0]; - } - if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols[0], ce0, + if (srslte_pcfich_decode_multi(&q->pcfich, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); @@ -258,7 +254,7 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_RXANT], uint8_t *data, uint32_t tti, uint16_t rnti) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti, uint16_t rnti) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; diff --git a/srslte/lib/ue/ue_mib.c b/srslte/lib/ue/ue_mib.c index 7e178161b..bf0b97ce2 100644 --- a/srslte/lib/ue/ue_mib.c +++ b/srslte/lib/ue/ue_mib.c @@ -166,7 +166,7 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t, srslte_timestamp_t*), + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) { diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index bc045eb57..70eec60be 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -50,7 +50,7 @@ cf_t dummy_buffer0[15*2048/2]; cf_t dummy_buffer1[15*2048/2]; // FIXME: this will break for 4 antennas!! -cf_t *dummy_offset_buffer[SRSLTE_MAX_RXANT] = {dummy_buffer0, dummy_buffer1}; +cf_t *dummy_offset_buffer[SRSLTE_MAX_PORTS] = {dummy_buffer0, dummy_buffer1}; int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset_time, float offset_freq) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -108,7 +108,7 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_RXANT], uint32_t,srslte_timestamp_t*), + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) { @@ -117,7 +117,7 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, if (q != NULL && stream_handler != NULL && srslte_nofprb_isvalid(cell.nof_prb) && - nof_rx_antennas <= SRSLTE_MAX_RXANT && + nof_rx_antennas <= SRSLTE_MAX_PORTS && recv_callback != NULL) { ret = SRSLTE_ERROR; @@ -299,7 +299,7 @@ void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, uint32_t period) { q->agc_period = period; } -static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { +static int find_peak_ok(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { if (srslte_sync_sss_detected(&q->sfind)) { @@ -433,7 +433,7 @@ static int track_peak_no(srslte_ue_sync_t *q) { } -static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { +static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { /* A negative time offset means there are samples in our buffer for the next subframe, because we are sampling too fast. @@ -443,8 +443,8 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RX } /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ - cf_t *ptr[SRSLTE_MAX_RXANT]; - for (int i=0;inext_rf_sample_offset]; } if (q->recv_callback(q->stream, ptr, q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { @@ -460,7 +460,7 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RX bool first_track = true; /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ -int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_RXANT]) { +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; From 255c157cb2f5466b6cf95ba02f4ab6d81dcae043 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 17 Feb 2017 11:54:34 +0100 Subject: [PATCH 23/38] compatible with single port srsUE --- srslte/examples/cell_measurement.c | 8 +- srslte/examples/cell_search.c | 2 +- srslte/examples/pdsch_ue.c | 18 ++-- srslte/examples/usrp_capture_sync.c | 4 +- srslte/include/srslte/ue/ue_cell_search.h | 9 +- srslte/include/srslte/ue/ue_dl.h | 33 ++++++-- srslte/include/srslte/ue/ue_mib.h | 10 ++- srslte/include/srslte/ue/ue_sync.h | 19 +++-- srslte/lib/phch/test/pdsch_pdcch_file_test.c | 4 +- srslte/lib/rf/rf_utils.c | 4 +- srslte/lib/ue/ue_cell_search.c | 57 ++++++++++++- srslte/lib/ue/ue_dl.c | 87 +++++++++++++------- srslte/lib/ue/ue_mib.c | 39 +++++++-- srslte/lib/ue/ue_sync.c | 27 +++++- 14 files changed, 247 insertions(+), 74 deletions(-) diff --git a/srslte/examples/cell_measurement.c b/srslte/examples/cell_measurement.c index 493bbd606..8c9d95fe3 100644 --- a/srslte/examples/cell_measurement.c +++ b/srslte/examples/cell_measurement.c @@ -237,11 +237,11 @@ int main(int argc, char **argv) { srslte_rf_stop_rx_stream(&rf); srslte_rf_flush_buffer(&rf); - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } - if (srslte_ue_dl_init(&ue_dl, cell, 1)) { + if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); return -1; } @@ -283,7 +283,7 @@ int main(int argc, char **argv) { /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { - ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -310,7 +310,7 @@ int main(int argc, char **argv) { case DECODE_SIB: /* We are looking for SI Blocks, search only in appropiate places */ if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { - n = srslte_ue_dl_decode(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); + n = srslte_ue_dl_decode_multi(&ue_dl, sf_buffer, data, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); return -1; diff --git a/srslte/examples/cell_search.c b/srslte/examples/cell_search.c index ee5704e5a..fc684578a 100644 --- a/srslte/examples/cell_search.c +++ b/srslte/examples/cell_search.c @@ -204,7 +204,7 @@ int main(int argc, char **argv) { bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_cellsearch_init_multi(&cs, cell_detect_config.max_frames_pss, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); exit(-1); } diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index db9fe7008..373e45449 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -411,7 +411,7 @@ int main(int argc, char **argv) { } else { #ifndef DISABLE_RF - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, prog_args.rf_nof_rx_ant, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } @@ -423,7 +423,7 @@ int main(int argc, char **argv) { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI + if (srslte_ue_dl_init_multi(&ue_dl, cell, prog_args.rf_nof_rx_ant)) { // This is the User RNTI fprintf(stderr, "Error initiating UE downlink processing module\n"); exit(-1); } @@ -478,7 +478,7 @@ int main(int argc, char **argv) { /* Main loop */ while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { - ret = srslte_ue_sync_zerocopy(&ue_sync, sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&ue_sync, sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } @@ -519,10 +519,10 @@ int main(int argc, char **argv) { } if (decode_pdsch) { INFO("Attempting DL decode SFN=%d\n", sfn); - n = srslte_ue_dl_decode(&ue_dl, - sf_buffer, - data, - sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); + n = srslte_ue_dl_decode_multi(&ue_dl, + sf_buffer, + data, + sfn*10+srslte_ue_sync_get_sfidx(&ue_sync)); if (n < 0) { // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); @@ -701,7 +701,7 @@ void *plot_thread_run(void *arg) { uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re; if (!prog_args.disable_plots_except_constellation) { for (i = 0; i < nof_re; i++) { - tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[0][i])); + tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i])); if (isinf(tmp_plot[i])) { tmp_plot[i] = -80; } @@ -710,7 +710,7 @@ void *plot_thread_run(void *arg) { bzero(tmp_plot2, sizeof(float)*sz); int g = (sz - 12*ue_dl.cell.nof_prb)/2; for (i = 0; i < 12*ue_dl.cell.nof_prb; i++) { - tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][0][i])); + tmp_plot2[g+i] = 20 * log10(cabs(ue_dl.ce[0][i])); if (isinf(tmp_plot2[g+i])) { tmp_plot2[g+i] = -80; } diff --git a/srslte/examples/usrp_capture_sync.c b/srslte/examples/usrp_capture_sync.c index 6059ae626..6e7f74cb6 100644 --- a/srslte/examples/usrp_capture_sync.c +++ b/srslte/examples/usrp_capture_sync.c @@ -158,7 +158,7 @@ int main(int argc, char **argv) { cell.nof_prb = nof_prb; cell.nof_ports = 1; - if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { + if (srslte_ue_sync_init_multi(&ue_sync, cell, srslte_rf_recv_wrapper, 1, (void*) &rf)) { fprintf(stderr, "Error initiating ue_sync\n"); exit(-1); } @@ -169,7 +169,7 @@ int main(int argc, char **argv) { while((subframe_count < nof_subframes || nof_subframes == -1) && !stop_capture) { - n = srslte_ue_sync_zerocopy(&ue_sync, buffer); + n = srslte_ue_sync_zerocopy_multi(&ue_sync, buffer); if (n < 0) { fprintf(stderr, "Error receiving samples\n"); exit(-1); diff --git a/srslte/include/srslte/ue/ue_cell_search.h b/srslte/include/srslte/ue/ue_cell_search.h index 6b53fe925..628683f09 100644 --- a/srslte/include/srslte/ue/ue_cell_search.h +++ b/srslte/include/srslte/ue/ue_cell_search.h @@ -83,10 +83,15 @@ typedef struct SRSLTE_API { SRSLTE_API int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t *q, uint32_t max_frames_total, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler); +SRSLTE_API int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t *q, + uint32_t max_frames_total, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API void srslte_ue_cellsearch_free(srslte_ue_cellsearch_t *q); SRSLTE_API int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t *q, diff --git a/srslte/include/srslte/ue/ue_dl.h b/srslte/include/srslte/ue/ue_dl.h index 1f29ea8d5..a32794aa2 100644 --- a/srslte/include/srslte/ue/ue_dl.h +++ b/srslte/include/srslte/ue/ue_dl.h @@ -90,8 +90,10 @@ typedef struct SRSLTE_API { uint32_t nof_rx_antennas; - cf_t *sf_symbols[SRSLTE_MAX_PORTS]; - cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; + cf_t *sf_symbols; // this is for backwards compatibility + cf_t *sf_symbols_m[SRSLTE_MAX_PORTS]; + cf_t *ce[SRSLTE_MAX_PORTS]; // compatibility + cf_t *ce_m[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS]; srslte_dci_format_t dci_format; uint64_t pkt_errors; @@ -112,12 +114,20 @@ typedef struct SRSLTE_API { /* This function shall be called just after the initial synchronization */ SRSLTE_API int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell, - uint32_t nof_rx_antennas); + srslte_cell_t cell); + +SRSLTE_API int srslte_ue_dl_init_multi(srslte_ue_dl_t *q, + srslte_cell_t cell, + uint32_t nof_rx_antennas); SRSLTE_API void srslte_ue_dl_free(srslte_ue_dl_t *q); SRSLTE_API int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, + cf_t *input, + uint32_t sf_idx, + uint32_t *cfi); + +SRSLTE_API int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi); @@ -157,16 +167,27 @@ SRSLTE_API void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset); SRSLTE_API int srslte_ue_dl_decode(srslte_ue_dl_t * q, - cf_t *input[SRSLTE_MAX_PORTS], + cf_t *input, uint8_t *data, uint32_t tti); +SRSLTE_API int srslte_ue_dl_decode_multi(srslte_ue_dl_t * q, + cf_t *input[SRSLTE_MAX_PORTS], + uint8_t *data, + uint32_t tti); + SRSLTE_API int srslte_ue_dl_decode_rnti(srslte_ue_dl_t * q, - cf_t *input[SRSLTE_MAX_PORTS], + cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti); +SRSLTE_API int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t * q, + cf_t *input[SRSLTE_MAX_PORTS], + uint8_t *data, + uint32_t tti, + uint16_t rnti); + SRSLTE_API bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_prb_lowest, diff --git a/srslte/include/srslte/ue/ue_mib.h b/srslte/include/srslte/ue/ue_mib.h index e31102a13..202b6ee7f 100644 --- a/srslte/include/srslte/ue/ue_mib.h +++ b/srslte/include/srslte/ue/ue_mib.h @@ -107,10 +107,16 @@ typedef struct { SRSLTE_API int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t *), void *stream_handler); +SRSLTE_API int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t *), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API void srslte_ue_mib_sync_free(srslte_ue_mib_sync_t *q); SRSLTE_API void srslte_ue_mib_sync_reset(srslte_ue_mib_sync_t * q); diff --git a/srslte/include/srslte/ue/ue_sync.h b/srslte/include/srslte/ue/ue_sync.h index 2483aa1a2..04efe3c18 100644 --- a/srslte/include/srslte/ue/ue_sync.h +++ b/srslte/include/srslte/ue/ue_sync.h @@ -75,7 +75,8 @@ typedef struct SRSLTE_API { uint32_t agc_period; void *stream; - int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*); + int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*); + int (*recv_callback_single)(void*, void*, uint32_t, srslte_timestamp_t*); srslte_timestamp_t last_timestamp; uint32_t nof_rx_antennas; @@ -115,19 +116,24 @@ typedef struct SRSLTE_API { float mean_sfo; uint32_t sample_offset_correct_period; float sfo_ema; + #ifdef MEASURE_EXEC_TIME float mean_exec_time; #endif } srslte_ue_sync_t; - SRSLTE_API int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), void *stream_handler); +SRSLTE_API int srslte_ue_sync_init_multi(srslte_ue_sync_t *q, + srslte_cell_t cell, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler); + SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, @@ -147,7 +153,10 @@ SRSLTE_API void srslte_ue_sync_set_agc_period(srslte_ue_sync_t *q, /* CAUTION: input_buffer MUST have space for 2 subframes */ SRSLTE_API int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, - cf_t *input_buffer[SRSLTE_MAX_PORTS]); + cf_t *input_buffer); + +SRSLTE_API int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, + cf_t *input_buffer[SRSLTE_MAX_PORTS]); SRSLTE_API void srslte_ue_sync_set_cfo(srslte_ue_sync_t *q, float cfo); diff --git a/srslte/lib/phch/test/pdsch_pdcch_file_test.c b/srslte/lib/phch/test/pdsch_pdcch_file_test.c index f31cc38da..0d19d689e 100644 --- a/srslte/lib/phch/test/pdsch_pdcch_file_test.c +++ b/srslte/lib/phch/test/pdsch_pdcch_file_test.c @@ -137,7 +137,7 @@ int base_init() { exit(-1); } - if (srslte_ue_dl_init(&ue_dl, cell, 1)) { + if (srslte_ue_dl_init_multi(&ue_dl, cell, 1)) { fprintf(stderr, "Error initializing UE DL\n"); return -1; } @@ -177,7 +177,7 @@ int main(int argc, char **argv) { srslte_filesource_read(&fsrc, input_buffer, flen); INFO("Reading %d samples sub-frame %d\n", flen, sf_idx); - ret = srslte_ue_dl_decode(&ue_dl, &input_buffer, data, sf_idx); + ret = srslte_ue_dl_decode(&ue_dl, input_buffer, data, sf_idx); if(ret > 0) { printf("PDSCH Decoded OK!\n"); } else if (ret == 0) { diff --git a/srslte/lib/rf/rf_utils.c b/srslte/lib/rf/rf_utils.c index 1f0a7d74e..10c6b53df 100644 --- a/srslte/lib/rf/rf_utils.c +++ b/srslte/lib/rf/rf_utils.c @@ -103,7 +103,7 @@ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t * srslte_ue_mib_sync_t ue_mib; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { + if (srslte_ue_mib_sync_init_multi(&ue_mib, cell->id, cell->cp, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } @@ -164,7 +164,7 @@ int rf_cell_search(srslte_rf_t *rf, uint32_t nof_rx_antennas, bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); - if (srslte_ue_cellsearch_init(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { + if (srslte_ue_cellsearch_init_multi(&cs, config->max_frames_pss, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } diff --git a/srslte/lib/ue/ue_cell_search.c b/srslte/lib/ue/ue_cell_search.c index 2306dc606..868af36b9 100644 --- a/srslte/lib/ue/ue_cell_search.c +++ b/srslte/lib/ue/ue_cell_search.c @@ -36,6 +36,59 @@ #include "srslte/utils/vector.h" int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), + void *stream_handler) +{ + int ret = SRSLTE_ERROR_INVALID_INPUTS; + + if (q != NULL) { + ret = SRSLTE_ERROR; + srslte_cell_t cell; + + bzero(q, sizeof(srslte_ue_cellsearch_t)); + + bzero(&cell, sizeof(srslte_cell_t)); + cell.id = SRSLTE_CELL_ID_UNKNOWN; + cell.nof_prb = SRSLTE_CS_NOF_PRB; + + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + fprintf(stderr, "Error initiating ue_sync\n"); + goto clean_exit; + } + + q->sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); + q->nof_rx_antennas = 1; + + q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames); + if (!q->candidates) { + perror("malloc"); + goto clean_exit; + } + q->mode_ntimes = calloc(sizeof(uint32_t), max_frames); + if (!q->mode_ntimes) { + perror("malloc"); + goto clean_exit; + } + q->mode_counted = calloc(sizeof(uint8_t), max_frames); + if (!q->mode_counted) { + perror("malloc"); + goto clean_exit; + } + + q->max_frames = max_frames; + q->nof_valid_frames = max_frames; + + ret = SRSLTE_SUCCESS; + } + +clean_exit: + if (ret == SRSLTE_ERROR) { + srslte_ue_cellsearch_free(q); + } + return ret; +} + +int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t * q, uint32_t max_frames, int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) @@ -52,7 +105,7 @@ int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, uint32_t max_frames, cell.id = SRSLTE_CELL_ID_UNKNOWN; cell.nof_prb = SRSLTE_CS_NOF_PRB; - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { + if (srslte_ue_sync_init_multi(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); goto clean_exit; } @@ -226,7 +279,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, srslte_ue_sync_reset(&q->ue_sync); do { - ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_dl.c b/srslte/lib/ue/ue_dl.c index 01569bc56..bd98802c0 100644 --- a/srslte/lib/ue/ue_dl.c +++ b/srslte/lib/ue/ue_dl.c @@ -44,10 +44,15 @@ const uint32_t nof_ue_formats = 2; static srslte_dci_format_t common_formats[] = {SRSLTE_DCI_FORMAT1A,SRSLTE_DCI_FORMAT1C}; const uint32_t nof_common_formats = 2; - int srslte_ue_dl_init(srslte_ue_dl_t *q, - srslte_cell_t cell, - uint32_t nof_rx_antennas) + srslte_cell_t cell) +{ + return srslte_ue_dl_init_multi(q, cell, 1); +} + +int srslte_ue_dl_init_multi(srslte_ue_dl_t *q, + srslte_cell_t cell, + uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -107,20 +112,25 @@ int srslte_ue_dl_init(srslte_ue_dl_t *q, srslte_cfo_set_tol(&q->sfo_correct, 1e-5/q->fft.symbol_sz); for (int j=0;jsf_symbols[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->sf_symbols[j]) { + q->sf_symbols_m[j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->sf_symbols_m[j]) { perror("malloc"); goto clean_exit; } for (uint32_t i=0;icell.nof_ports;i++) { - q->ce[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); - if (!q->ce[i][j]) { + q->ce_m[i][j] = srslte_vec_malloc(CURRENT_SFLEN_RE * sizeof(cf_t)); + if (!q->ce_m[i][j]) { perror("malloc"); goto clean_exit; } } } + q->sf_symbols = q->sf_symbols_m[0]; + for (int i=0;icell.nof_ports;i++) { + q->ce[i] = q->ce_m[i][0]; + } + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", @@ -146,12 +156,12 @@ void srslte_ue_dl_free(srslte_ue_dl_t *q) { srslte_cfo_free(&q->sfo_correct); srslte_softbuffer_rx_free(&q->softbuffer); for (int j=0;jnof_rx_antennas;j++) { - if (q->sf_symbols[j]) { - free(q->sf_symbols[j]); + if (q->sf_symbols_m[j]) { + free(q->sf_symbols_m[j]); } for (uint32_t i=0;icell.nof_ports;i++) { - if (q->ce[i][j]) { - free(q->ce[i][j]); + if (q->ce_m[i][j]) { + free(q->ce_m[i][j]); } } } @@ -193,23 +203,37 @@ void srslte_ue_dl_set_sample_offset(srslte_ue_dl_t * q, float sample_offset) { * - PDCCH decoding: Find DCI for RNTI given by previous call to srslte_ue_dl_set_rnti() * - PDSCH decoding: Decode TB scrambling with RNTI given by srslte_ue_dl_set_rnti() */ -int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti) { - return srslte_ue_dl_decode_rnti(q, input, data, tti, q->current_rnti); +int srslte_ue_dl_decode(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti) { + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_rnti_multi(q, _input, data, tti, q->current_rnti); } -int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi) { +int srslte_ue_dl_decode_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti) { + return srslte_ue_dl_decode_rnti_multi(q, input, data, tti, q->current_rnti); +} + +int srslte_ue_dl_decode_fft_estimate(srslte_ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t *cfi) +{ + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_fft_estimate_multi(q, _input, sf_idx, cfi); +} + +int srslte_ue_dl_decode_fft_estimate_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint32_t sf_idx, uint32_t *cfi) +{ if (input && q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Run FFT for all subframe data */ for (int j=0;jnof_rx_antennas;j++) { - srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols[j]); + srslte_ofdm_rx_sf(&q->fft, input[j], q->sf_symbols_m[j]); /* Correct SFO multiplying by complex exponential in the time domain */ if (q->sample_offset) { for (int i=0;i<2*SRSLTE_CP_NSYMB(q->cell.cp);i++) { srslte_cfo_correct(&q->sfo_correct, - &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], - &q->sf_symbols[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], + &q->sf_symbols_m[j][i*q->cell.nof_prb*SRSLTE_NRE], q->sample_offset / q->fft.symbol_sz); } } @@ -225,10 +249,10 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c if (q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Get channel estimates for each port */ - srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols, q->ce, sf_idx, q->nof_rx_antennas); + srslte_chest_dl_estimate_multi(&q->chest, q->sf_symbols_m, q->ce_m, sf_idx, q->nof_rx_antennas); /* First decode PCFICH and obtain CFI */ - if (srslte_pcfich_decode_multi(&q->pcfich, q->sf_symbols, q->ce, + if (srslte_pcfich_decode_multi(&q->pcfich, q->sf_symbols_m, q->ce_m, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); @@ -254,7 +278,14 @@ int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint3 return srslte_pdsch_cfg(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx); } -int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti, uint16_t rnti) +int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti) +{ + cf_t *_input[SRSLTE_MAX_PORTS]; + _input[0] = input; + return srslte_ue_dl_decode_rnti_multi(q, _input, data, tti, rnti); +} + +int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], uint8_t *data, uint32_t tti, uint16_t rnti) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; @@ -264,7 +295,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u uint32_t sf_idx = tti%10; - if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &cfi)) < 0) { + if ((ret = srslte_ue_dl_decode_fft_estimate_multi(q, input, sf_idx, &cfi)) < 0) { return ret; } @@ -272,7 +303,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u // Uncoment next line to do ZF by default in pdsch_ue example //float noise_estimate = 0; - if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols, q->ce, noise_estimate, sf_idx, cfi)) { + if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols_m, q->ce_m, noise_estimate, sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } @@ -310,7 +341,7 @@ int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_PORTS], u if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, - q->sf_symbols, q->ce, + q->sf_symbols_m, q->ce_m, noise_estimate, rnti, data); @@ -515,11 +546,11 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr cf_t *ce0[SRSLTE_MAX_PORTS]; for (int i=0;ice[i][0]; + ce0[i] = q->ce_m[i][0]; } - if (!srslte_phich_decode(&q->phich, q->sf_symbols[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { + if (!srslte_phich_decode(&q->phich, q->sf_symbols_m[0], ce0, 0, ngroup, nseq, sf_idx, &ack_bit, &distance)) { INFO("Decoded PHICH %d with distance %f\n", ack_bit, distance); } else { fprintf(stderr, "Error decoding PHICH\n"); @@ -533,11 +564,11 @@ bool srslte_ue_dl_decode_phich(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t n_pr } void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuffer, uint32_t tti, uint32_t rv_idx, uint16_t rnti, uint32_t cfi) { - srslte_vec_save_file("sf_symbols", q->sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("sf_symbols", q->sf_symbols_m, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); printf("%d samples\n", SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); - srslte_vec_save_file("ce0", q->ce[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("ce0", q->ce_m[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); if (q->cell.nof_ports > 1) { - srslte_vec_save_file("ce1", q->ce[1], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); + srslte_vec_save_file("ce1", q->ce_m[1], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t)); } srslte_vec_save_file("pcfich_ce0", q->pcfich.ce[0], q->pcfich.nof_symbols*sizeof(cf_t)); srslte_vec_save_file("pcfich_ce1", q->pcfich.ce[1], q->pcfich.nof_symbols*sizeof(cf_t)); diff --git a/srslte/lib/ue/ue_mib.c b/srslte/lib/ue/ue_mib.c index bf0b97ce2..9b5b4e9ef 100644 --- a/srslte/lib/ue/ue_mib.c +++ b/srslte/lib/ue/ue_mib.c @@ -161,13 +161,10 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input, return ret; } - - int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, uint32_t cell_id, srslte_cp_t cp, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t, srslte_timestamp_t*), void *stream_handler) { srslte_cell_t cell; @@ -177,6 +174,36 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, cell.cp = cp; cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + q->sf_buffer[0] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); + q->nof_rx_antennas = 1; + + if (srslte_ue_mib_init(&q->ue_mib, cell)) { + fprintf(stderr, "Error initiating ue_mib\n"); + return SRSLTE_ERROR; + } + if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, stream_handler)) { + fprintf(stderr, "Error initiating ue_sync\n"); + srslte_ue_mib_free(&q->ue_mib); + return SRSLTE_ERROR; + } + srslte_ue_sync_decode_sss_on_track(&q->ue_sync, true); + return SRSLTE_SUCCESS; +} + +int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, + uint32_t cell_id, + srslte_cp_t cp, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) +{ + srslte_cell_t cell; + // If the ports are set to 0, ue_mib goes through 1, 2 and 4 ports to blindly detect nof_ports + cell.nof_ports = 0; + cell.id = cell_id; + cell.cp = cp; + cell.nof_prb = SRSLTE_UE_MIB_NOF_PRB; + for (int i=0;isf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); } @@ -186,7 +213,7 @@ int srslte_ue_mib_sync_init(srslte_ue_mib_sync_t *q, fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } - if (srslte_ue_sync_init(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { + if (srslte_ue_sync_init_multi(&q->ue_sync, cell, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; @@ -226,7 +253,7 @@ int srslte_ue_mib_sync_decode(srslte_ue_mib_sync_t * q, ret = SRSLTE_SUCCESS; do { mib_ret = SRSLTE_UE_MIB_NOTFOUND; - ret = srslte_ue_sync_zerocopy(&q->ue_sync, q->sf_buffer); + ret = srslte_ue_sync_zerocopy_multi(&q->ue_sync, q->sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); break; diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 70eec60be..4cf61bbb3 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -106,11 +106,26 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi return n; } +int recv_callback_multi_to_single(void *h, cf_t *x[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t*t) +{ + srslte_ue_sync_t *q = (srslte_ue_sync_t*) h; + return q->recv_callback_single(q->stream, (void*) x[0], nsamples, t); +} + int srslte_ue_sync_init(srslte_ue_sync_t *q, srslte_cell_t cell, - int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), - uint32_t nof_rx_antennas, + int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler) +{ + q->recv_callback_single = recv_callback; + return srslte_ue_sync_init_multi(q, cell, recv_callback_multi_to_single, 1, q); +} + +int srslte_ue_sync_init_multi(srslte_ue_sync_t *q, + srslte_cell_t cell, + int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), + uint32_t nof_rx_antennas, + void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -459,8 +474,14 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PO bool first_track = true; +int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) { + cf_t *_input_buffer[SRSLTE_MAX_PORTS]; + _input_buffer[0] = input_buffer; + return srslte_ue_sync_zerocopy_multi(q, _input_buffer); +} + /* Returns 1 if the subframe is synchronized in time, 0 otherwise */ -int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { +int srslte_ue_sync_zerocopy_multi(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PORTS]) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t track_idx; From cfd0f01aa22a2e60fca897f1ecc08fdd6f3fdc67 Mon Sep 17 00:00:00 2001 From: Kewin Rausch Date: Fri, 17 Feb 2017 13:07:33 +0100 Subject: [PATCH 24/38] Fixed PRACH opportunity evaluator procedure to consider option 14 of PRACH Configuration Index as stated on 3GPP specifications. --- srslte/lib/phch/prach.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 59ed3d072..a29475380 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -195,6 +195,11 @@ bool srslte_prach_tti_opportunity(srslte_prach_t *p, uint32_t current_tti, int a // Get SFN and sf_idx from the PRACH configuration index srslte_prach_sfn_t prach_sfn = srslte_prach_get_sfn(config_idx); + // This is the only option which provides always an opportunity for PRACH transmission. + if(config_idx == 14) { + return true; + } + if ((prach_sfn == SRSLTE_PRACH_SFN_EVEN && ((current_tti/10)%2)==0) || prach_sfn == SRSLTE_PRACH_SFN_ANY) { From 7aa1e5f5c4c82c31273749c8536e493b9b63529a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 21 Feb 2017 12:34:49 +0100 Subject: [PATCH 25/38] added option in RF UHD for silent stdout --- srslte/lib/rf/rf_uhd_imp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 0052e801b..d936f4d18 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -267,6 +267,7 @@ int rf_uhd_open(char *args, void **h) } handler->devname = NULL; + /* If device type or name not given in args, choose a B200 */ if (args[0]=='\0') { if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) { @@ -294,7 +295,11 @@ int rf_uhd_open(char *args, void **h) uhd_string_vector_free(&devices_str); /* Create UHD handler */ - printf("Opening USRP with args: %s\n", args); + if (strstr(args, "silent")) { + rf_uhd_suppress_stdout(NULL); + } else { + printf("Opening USRP with args: %s\n", args); + } uhd_error error = uhd_usrp_make(&handler->usrp, args); if (error) { fprintf(stderr, "Error opening UHD: code %d\n", error); From e5b976f26d273c64ca1da480bdaed912ba2f1aa7 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 21 Feb 2017 12:35:07 +0100 Subject: [PATCH 26/38] fixed pdsch_enodeb crashing with new dci interface --- srslte/examples/pdsch_enodeb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/srslte/examples/pdsch_enodeb.c b/srslte/examples/pdsch_enodeb.c index 28c020708..8a6d3724e 100644 --- a/srslte/examples/pdsch_enodeb.c +++ b/srslte/examples/pdsch_enodeb.c @@ -340,6 +340,7 @@ int update_radl() { ra_dl.rv_idx = 0; ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask(); + ra_dl.tb_en[0] = 1; srslte_ra_pdsch_fprint(stdout, &ra_dl, cell.nof_prb); srslte_ra_dl_grant_t dummy_grant; From dba07268aa9f051e68ea1e22390cff766e00f987 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 1 Mar 2017 18:35:38 +0100 Subject: [PATCH 27/38] automatic viterbi normalization --- srslte/lib/fec/viterbi.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/srslte/lib/fec/viterbi.c b/srslte/lib/fec/viterbi.c index d290a16bf..2ba17d158 100644 --- a/srslte/lib/fec/viterbi.c +++ b/srslte/lib/fec/viterbi.c @@ -255,7 +255,14 @@ int srslte_viterbi_decode_f(srslte_viterbi_t *q, float *symbols, uint8_t *data, len = 3 * (frame_length + q->K - 1); } if (!q->decode_f) { - srslte_vec_quant_fuc(symbols, q->symbols_uc, q->gain_quant, 127.5, 255, len); + + float max = -9e9; + for (int i=0;i max) { + max = fabs(symbols[i]); + } + } + srslte_vec_quant_fuc(symbols, q->symbols_uc, 50/max, 127.5, 255, len); return srslte_viterbi_decode_uc(q, q->symbols_uc, data, frame_length); } else { return q->decode_f(q, symbols, data, frame_length); @@ -276,7 +283,15 @@ int srslte_viterbi_decode_s(srslte_viterbi_t *q, int16_t *symbols, uint8_t *data } else { len = 3 * (frame_length + q->K - 1); } - srslte_vec_quant_suc(symbols, q->symbols_uc, q->gain_quant_s, 127, 255, len); + + int16_t max = -INT16_MAX; + for (int i=0;i max) { + max = symbols[i]; + } + } + + srslte_vec_quant_suc(symbols, q->symbols_uc, 50/max, 127, 255, len); return srslte_viterbi_decode_uc(q, q->symbols_uc, data, frame_length); } From 619ed43e11b762d6b13d742ed1832a5b1a7176e7 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 6 Mar 2017 15:59:17 +0000 Subject: [PATCH 28/38] Removing old test files and references --- CMakeLists.txt | 11 +- cmake/modules/BuildMex.cmake | 63 ---- matlab/common/bin2hex.m | 21 -- matlab/common/read_complex.m | 20 -- matlab/common/read_int16.m | 18 -- matlab/common/read_real.m | 18 -- matlab/common/read_trace_uint.m | 19 -- matlab/common/read_uchar.m | 18 -- matlab/common/write_c_struct_complex.m | 16 -- matlab/common/write_complex.m | 22 -- matlab/common/write_int16.m | 14 - matlab/common/write_real.m | 14 - matlab/common/write_uchar.m | 14 - matlab/rate_algorithm.m | 20 -- matlab/resampler/arb_filter.mat | Bin 1475 -> 0 bytes matlab/resampler/arb_resample_linear.m | 46 --- matlab/resampler/arb_resample_nearest.m | 37 --- matlab/resampler/arb_resample_test.m | 33 --- matlab/sync/addnoise.m | 6 - matlab/sync/cfo_estimate_cp.m | 18 -- matlab/sync/cfo_test.m | 42 --- matlab/sync/check_pss.m | 33 --- matlab/sync/correct_cfo.m | 14 - matlab/sync/cp_corr.m | 9 - matlab/sync/cp_pss_comp.m | 8 - matlab/sync/epsilon.m | 14 - matlab/sync/find_peaks.m | 13 - matlab/sync/find_pss.m | 19 -- matlab/sync/find_pss2.m | 14 - matlab/sync/find_pss_ac.m | 7 - matlab/sync/find_sss.m | 50 ---- matlab/sync/ifo_pss.m | 13 - matlab/sync/ifo_pss_corr.m | 10 - matlab/sync/lte_pss_zc.m | 24 -- matlab/sync/sfo_estimate.m | 18 -- matlab/sync/sym_sync_cp.m | 13 - matlab/tests/diversity_decode_test.m | 46 --- matlab/tests/diversity_test_rate.m | 285 ------------------- matlab/tests/dlsch_test.m | 27 -- matlab/tests/dmrs_equalizer_test.m | 184 ------------ matlab/tests/drms_pusch_test.m | 52 ---- matlab/tests/equalizer_test.m | 277 ------------------ matlab/tests/get_sc.m | 111 -------- matlab/tests/pbch_bler.m | 130 --------- matlab/tests/pdcch_bler.m | 189 ------------ matlab/tests/pdsch_bler.m | 108 ------- matlab/tests/pdsch_decode_signal.m | 76 ----- matlab/tests/pdsch_equal.m | 166 ----------- matlab/tests/pdsch_resalloc.m | 76 ----- matlab/tests/pdsch_test_verify_unrm.m | 39 --- matlab/tests/phich_bler.m | 132 --------- matlab/tests/prach_detect_test.m | 200 ------------- matlab/tests/prach_falsealarm_test.m | 83 ------ matlab/tests/prach_test.m | 51 ---- matlab/tests/print_m.m | 9 - matlab/tests/pucch_bler.m | 133 --------- matlab/tests/pucch_test.m | 79 ----- matlab/tests/pusch_bler.m | 188 ------------ matlab/tests/pusch_decode_signal.m | 20 -- matlab/tests/pusch_encode_test.m | 67 ----- matlab/tests/rm_turbo_rx_test.m | 43 --- matlab/tests/srs_test.m | 47 --- matlab/tests/sss_test.m | 144 ---------- matlab/tests/sync_test.m | 96 ------- matlab/tests/test_ofdma_peakamp.m | 32 --- matlab/tests/test_scfdma.m | 26 -- matlab/tests/test_scfdma_peakamp.m | 32 --- matlab/tests/turbodecoder_bler.m | 51 ---- matlab/tests/ulsch_test.m | 67 ----- matlab/tests/viterbi_bler.m | 49 ---- mex/CMakeLists.txt | 49 ---- mex/include/srslte/mex/mexutils.h | 103 ------- mex/lib/CMakeLists.txt | 63 ---- mex/lib/mexutils.c | 249 ---------------- srslte/lib/ch_estimation/test/CMakeLists.txt | 6 - srslte/lib/fec/test/CMakeLists.txt | 6 - srslte/lib/mimo/test/CMakeLists.txt | 4 - srslte/lib/phch/test/CMakeLists.txt | 25 -- srslte/lib/sync/test/CMakeLists.txt | 7 - 79 files changed, 2 insertions(+), 4554 deletions(-) delete mode 100644 cmake/modules/BuildMex.cmake delete mode 100644 matlab/common/bin2hex.m delete mode 100644 matlab/common/read_complex.m delete mode 100644 matlab/common/read_int16.m delete mode 100644 matlab/common/read_real.m delete mode 100644 matlab/common/read_trace_uint.m delete mode 100644 matlab/common/read_uchar.m delete mode 100644 matlab/common/write_c_struct_complex.m delete mode 100644 matlab/common/write_complex.m delete mode 100644 matlab/common/write_int16.m delete mode 100644 matlab/common/write_real.m delete mode 100644 matlab/common/write_uchar.m delete mode 100644 matlab/rate_algorithm.m delete mode 100644 matlab/resampler/arb_filter.mat delete mode 100644 matlab/resampler/arb_resample_linear.m delete mode 100644 matlab/resampler/arb_resample_nearest.m delete mode 100644 matlab/resampler/arb_resample_test.m delete mode 100644 matlab/sync/addnoise.m delete mode 100644 matlab/sync/cfo_estimate_cp.m delete mode 100644 matlab/sync/cfo_test.m delete mode 100644 matlab/sync/check_pss.m delete mode 100644 matlab/sync/correct_cfo.m delete mode 100644 matlab/sync/cp_corr.m delete mode 100644 matlab/sync/cp_pss_comp.m delete mode 100644 matlab/sync/epsilon.m delete mode 100644 matlab/sync/find_peaks.m delete mode 100644 matlab/sync/find_pss.m delete mode 100644 matlab/sync/find_pss2.m delete mode 100644 matlab/sync/find_pss_ac.m delete mode 100644 matlab/sync/find_sss.m delete mode 100644 matlab/sync/ifo_pss.m delete mode 100644 matlab/sync/ifo_pss_corr.m delete mode 100644 matlab/sync/lte_pss_zc.m delete mode 100644 matlab/sync/sfo_estimate.m delete mode 100644 matlab/sync/sym_sync_cp.m delete mode 100644 matlab/tests/diversity_decode_test.m delete mode 100644 matlab/tests/diversity_test_rate.m delete mode 100644 matlab/tests/dlsch_test.m delete mode 100644 matlab/tests/dmrs_equalizer_test.m delete mode 100644 matlab/tests/drms_pusch_test.m delete mode 100644 matlab/tests/equalizer_test.m delete mode 100644 matlab/tests/get_sc.m delete mode 100644 matlab/tests/pbch_bler.m delete mode 100644 matlab/tests/pdcch_bler.m delete mode 100644 matlab/tests/pdsch_bler.m delete mode 100644 matlab/tests/pdsch_decode_signal.m delete mode 100644 matlab/tests/pdsch_equal.m delete mode 100644 matlab/tests/pdsch_resalloc.m delete mode 100644 matlab/tests/pdsch_test_verify_unrm.m delete mode 100644 matlab/tests/phich_bler.m delete mode 100644 matlab/tests/prach_detect_test.m delete mode 100644 matlab/tests/prach_falsealarm_test.m delete mode 100644 matlab/tests/prach_test.m delete mode 100644 matlab/tests/print_m.m delete mode 100644 matlab/tests/pucch_bler.m delete mode 100644 matlab/tests/pucch_test.m delete mode 100644 matlab/tests/pusch_bler.m delete mode 100644 matlab/tests/pusch_decode_signal.m delete mode 100644 matlab/tests/pusch_encode_test.m delete mode 100644 matlab/tests/rm_turbo_rx_test.m delete mode 100644 matlab/tests/srs_test.m delete mode 100644 matlab/tests/sss_test.m delete mode 100644 matlab/tests/sync_test.m delete mode 100644 matlab/tests/test_ofdma_peakamp.m delete mode 100644 matlab/tests/test_scfdma.m delete mode 100644 matlab/tests/test_scfdma_peakamp.m delete mode 100644 matlab/tests/turbodecoder_bler.m delete mode 100644 matlab/tests/ulsch_test.m delete mode 100644 matlab/tests/viterbi_bler.m delete mode 100644 mex/CMakeLists.txt delete mode 100644 mex/include/srslte/mex/mexutils.h delete mode 100644 mex/lib/CMakeLists.txt delete mode 100644 mex/lib/mexutils.c diff --git a/CMakeLists.txt b/CMakeLists.txt index fec7856b9..4f91dec82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,6 @@ MESSAGE( STATUS "CMAKE_CXX_COMPILER: " ${CMAKE_CXX_COMPILER} ) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") include(SRSLTEVersion) #sets version information include(SRSLTEPackage) #setup cpack -include(BuildMex) include(CTest) set( CTEST_MEMORYCHECK_COMMAND valgrind ) @@ -51,7 +50,7 @@ configure_file( ######################################################################## # Options ######################################################################## -option(DisableMEX "DisableMEX" ON) + ######################################################################## # Install Dirs @@ -69,7 +68,6 @@ endif() set(RUNTIME_DIR bin) set(LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}) set(INCLUDE_DIR include) -set(MEX_DIR mex) set(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}") set(DATA_DIR share/${CPACK_PACKAGE_NAME}) @@ -98,7 +96,7 @@ endif(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-write-strings -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE -g") - + if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") find_package(SSE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") @@ -141,8 +139,6 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup") endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - ######################################################################## # Create uninstall targets ######################################################################## @@ -153,7 +149,6 @@ configure_file( add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) - ######################################################################## # Macro to add -fPIC property to static libs @@ -173,10 +168,8 @@ message(STATUS "Building for version: ${VERSION}") ######################################################################## include_directories(${PROJECT_BINARY_DIR}/srslte/include/) include_directories(${PROJECT_SOURCE_DIR}/srslte/include/) -include_directories(${PROJECT_SOURCE_DIR}/mex/include) ######################################################################## # Add the subdirectories ######################################################################## add_subdirectory(srslte) -add_subdirectory(mex) diff --git a/cmake/modules/BuildMex.cmake b/cmake/modules/BuildMex.cmake deleted file mode 100644 index e1bb573eb..000000000 --- a/cmake/modules/BuildMex.cmake +++ /dev/null @@ -1,63 +0,0 @@ -# BuildMex.cmake -# Author: Kent Williams norman-k-williams at uiowa.edu -# Modified by Ismael Gomez, 2014 - -include(CMakeParseArguments) - -if(NOT DisableMEX) - if(NOT MATLAB_FOUND) - find_package(MATLAB) - endif() - - if(NOT OCTAVE_FOUND) - find_package(OCTAVE) - endif() - - # CMake 2.8.12 & earlier apparently don't define the - # Mex script path, so find it. - if(NOT MATLAB_MEX_PATH) - find_program( MATLAB_MEX_PATH mex - HINTS ${MATLAB_ROOT}/bin - PATHS ${MATLAB_ROOT}/bin - DOC "The mex program path" - ) - endif() -endif() - -# -# BuildMex -- arguments -# MEXNAME = root of mex library name -# SOURCE = list of source files -# LIBRARIES = libraries needed to link mex library -FUNCTION(BuildMex) - if(NOT DisableMEX) - set(oneValueArgs MEXNAME) - set(multiValueArgs SOURCES LIBRARIES) - cmake_parse_arguments(BuildMex "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - if (MATLAB_FOUND) - add_library(${BuildMex_MEXNAME}-mat SHARED ${BuildMex_SOURCES}) - #target_include_directories(${BuildMex_MEXNAME}-mat PUBLIC ${MATLAB_INCLUDE_DIR}) - set_target_properties(${BuildMex_MEXNAME}-mat PROPERTIES - SUFFIX "${MATLAB_MEX_EXTENSION}" - PREFIX "srslte_" - OUTPUT_NAME "${BuildMex_MEXNAME}" - COMPILE_FLAGS "-fvisibility=default ${MATLAB_MEX_CFLAGS} -DFORCE_STANDARD_RATE -I${MATLAB_INCLUDE_DIR}" - ) - target_link_libraries(${BuildMex_MEXNAME}-mat ${BuildMex_LIBRARIES} ${MATLAB_MEX_LIBRARY}) - install(TARGETS ${BuildMex_MEXNAME}-mat DESTINATION "${MEX_DIR}/srslte/") - endif(MATLAB_FOUND) - if (OCTAVE_FOUND) - add_library(${BuildMex_MEXNAME}-oct SHARED ${BuildMex_SOURCES}) - #target_include_directories(${BuildMex_MEXNAME}-oct PUBLIC ${OCTAVE_INCLUDE_DIR}) - set_target_properties(${BuildMex_MEXNAME}-oct PROPERTIES - SUFFIX ".${OCTAVE_MEXFILE_EXT}" - PREFIX "srslte_" - OUTPUT_NAME "${BuildMex_MEXNAME}" - COMPILE_FLAGS "-fvisibility=default ${OCTAVE_MEX_CFLAGS} -DFORCE_STANDARD_RATE -DUNDEF_BOOL -I${OCTAVE_INCLUDE_DIR}" - ) - target_link_libraries(${BuildMex_MEXNAME}-oct ${BuildMex_LIBRARIES} ${OCTAVE_LIBRARIES}) - install(TARGETS ${BuildMex_MEXNAME}-oct DESTINATION "${MEX_DIR}/srslte/") - endif (OCTAVE_FOUND) - endif (NOT DisableMEX) -ENDFUNCTION(BuildMex) - diff --git a/matlab/common/bin2hex.m b/matlab/common/bin2hex.m deleted file mode 100644 index 45ca9ea4f..000000000 --- a/matlab/common/bin2hex.m +++ /dev/null @@ -1,21 +0,0 @@ -function [ s ] = bin2hex( in ) -%BIN2HEX Summary of this function goes here -% Detailed explanation goes here - -a=reshape(in,8,[]); -t=size(a); -s=cell(1,t(2)); -nbit=2.^(7:-1:0); -for i=1:t(2) - s{i}=dec2hex(sum(nbit'.*double(a(:,i)))); -end -for i=1:t(2) - if (length(s{i})==1) - fprintf('0%s ',s{i}) - else - fprintf('%s ',s{i}) - end -end -fprintf('\n'); -end - diff --git a/matlab/common/read_complex.m b/matlab/common/read_complex.m deleted file mode 100644 index d9185a7ea..000000000 --- a/matlab/common/read_complex.m +++ /dev/null @@ -1,20 +0,0 @@ -function [ out ] = read_complex( filename, count ) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'r'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (nargin==1) - count=inf; - end - - x=fread(tidin,2*count,'single'); - i=1:2:length(x); - out=x(i)+x(i+1)*1i; -end - diff --git a/matlab/common/read_int16.m b/matlab/common/read_int16.m deleted file mode 100644 index 3db6a3179..000000000 --- a/matlab/common/read_int16.m +++ /dev/null @@ -1,18 +0,0 @@ -function [ out ] = read_int16( filename, count ) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'r'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (nargin==1) - count=inf; - end - - out=fread(tidin,count,'int16'); -end - diff --git a/matlab/common/read_real.m b/matlab/common/read_real.m deleted file mode 100644 index 2447d11ce..000000000 --- a/matlab/common/read_real.m +++ /dev/null @@ -1,18 +0,0 @@ -function [ out ] = read_real( filename, count ) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'r'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (nargin==1) - count=inf; - end - - out=fread(tidin,count,'single'); -end - diff --git a/matlab/common/read_trace_uint.m b/matlab/common/read_trace_uint.m deleted file mode 100644 index b383798e7..000000000 --- a/matlab/common/read_trace_uint.m +++ /dev/null @@ -1,19 +0,0 @@ -function [ values, tti] = read_trace_uint( filename, count ) - - [tidin msg]=fopen(filename,'r'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (nargin==1) - count=inf; - end - - x=fread(tidin,2*count,'uint'); - i=1:2:length(x); - tti=x(i); - values=x(i+1); -end - diff --git a/matlab/common/read_uchar.m b/matlab/common/read_uchar.m deleted file mode 100644 index 59ed56430..000000000 --- a/matlab/common/read_uchar.m +++ /dev/null @@ -1,18 +0,0 @@ -function [ out ] = read_uchar( filename, count ) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'r'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (nargin==1) - count=inf; - end - - out=fread(tidin,count,'uint8'); -end - diff --git a/matlab/common/write_c_struct_complex.m b/matlab/common/write_c_struct_complex.m deleted file mode 100644 index 41f312b90..000000000 --- a/matlab/common/write_c_struct_complex.m +++ /dev/null @@ -1,16 +0,0 @@ -function [ out ] = write_c_struct_complex( filename, varname, x) - - [tidin msg]=fopen(filename,'wt'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - fprintf(tidin, 'float %s[%d]={%.9g,%.9g',varname,2*length(x),real(x(1)),imag(x(1))); - for i=2:length(x) - fprintf(tidin, ',\n %.9g,%.9g',real(x(i)),imag(x(i))); - end - fprintf(tidin, '};\n'); - fclose(tidin); -end - diff --git a/matlab/common/write_complex.m b/matlab/common/write_complex.m deleted file mode 100644 index a152c8672..000000000 --- a/matlab/common/write_complex.m +++ /dev/null @@ -1,22 +0,0 @@ -function [ out ] = write_complex( filename, x) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'w'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - if (isreal(x)) - y=x; - else - i=1:2:2*length(x); - y(i)=real(x); - y(i+1)=imag(x); - end - - fwrite(tidin,y,'single'); -end - diff --git a/matlab/common/write_int16.m b/matlab/common/write_int16.m deleted file mode 100644 index afd6e0ff4..000000000 --- a/matlab/common/write_int16.m +++ /dev/null @@ -1,14 +0,0 @@ -function [ out ] = write_int16( filename, x) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'w'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - fwrite(tidin,x,'int16'); -end - diff --git a/matlab/common/write_real.m b/matlab/common/write_real.m deleted file mode 100644 index 039906b16..000000000 --- a/matlab/common/write_real.m +++ /dev/null @@ -1,14 +0,0 @@ -function [ out ] = write_complex( filename, x) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'w'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - fwrite(tidin,x,'single'); -end - diff --git a/matlab/common/write_uchar.m b/matlab/common/write_uchar.m deleted file mode 100644 index 7ba41fb46..000000000 --- a/matlab/common/write_uchar.m +++ /dev/null @@ -1,14 +0,0 @@ -function [ out ] = write_uchar( filename, x) -%READ_COMPLEX Summary of this function goes here -% Detailed explanation goes here - - [tidin msg]=fopen(filename,'w'); - if (tidin==-1) - fprintf('error opening %s: %s\n',filename, msg); - out=[]; - return - end - - fwrite(tidin,x,'uint8'); -end - diff --git a/matlab/rate_algorithm.m b/matlab/rate_algorithm.m deleted file mode 100644 index 0edd42697..000000000 --- a/matlab/rate_algorithm.m +++ /dev/null @@ -1,20 +0,0 @@ -F=100000./(1:100); -PQ=(1:50); - -PRB=50; -Mmax=1024; -N=PRB*12; - -Fmin=N*15*1.1; -Fs=F(F>Fmin); - -for i=length(Fs):-1:1 - for p=PQ - for q=PQ - if (mod(p/q*Fs(i),15)==0 && p/q*Fs(i)/15_4ZaN@Tb!8wyaB?6qH6SrIIyE*rH8vnJFflYBARr(hARr(hARr(hARr(hARr(h zARr(hARr(hARr(hARr(hARr(B00000000000ZB~{0000x1pokeoJEy;RLp4@$EP|f zX`}77vGc8X0c5vrIwI%nYJBerVS%H(IyGog~`$dO>Id$-H4i! zE>3H65@TJPbl7EUv39qwoj>M1zq$N=@B2L8=kqZW2m}ts0)gTC_5Jei`p;{`@U@=c zzc)RBfxt6nt6-#H_>19}v}1ySheH78Wk0gLU*yLNUccBGc+8*I6-}R}-4e*_nqvYC zdV+ZVEqQ0y!w^YtivE9bm7rQxk-<-9-_ z`-QuWg4@PIlAY&2O(;d?=S%CHI&<_u&fZB%6tTi^#Imq(yr= zn1sS+&)Hu`(suLB8D~>v)Yb0orms#UlawoVzianU+ehka+r3jrv(IUczw{tYwN%|c z?vqYSvey@?oDY-#{osKz+boKeG=xoiag4OHHuW~Cvq>n)TNN-Zmr~6|ny&SEG(wlS zGBW-IJ)Yd%a6aZFnQhbmLm^g?*wA~vP$B%IOCf| zHG%W&X9*6Gq`msN;gb{!I^UA;Kqe=z@!x^uyuyZnqMZ>vXS)R zuF(2gZrN>iLPd3)Hu$E}D5Z{__bfc*{!<-K)YA{2{Qf%8-tub0{5oEqb0hxn$yyFC zQ5s2FYxtX34`We9HIJ3JTLh>tb9lAEl3O7c*&)e%$zW1BHx@3Gy)sktlY&8;WWz!p zzc|UKuRe!A&(MujL@Bt|nv!hSq>+Bq&{9RyDQeS8muN4l>FpU|wzGK^dC44GTElC} z?#A~+cSbdkYo2$h@^%yXj@!5`KCG3ZgZ#T<2HU9ocz9afIAzE@t;qrvGCYe!sci6 za$juKoxOczIzHKOsz^uTkfFq`3LPo`I=cRiT|bHQ9feKt{iN~LRh|C1pRCu;2ytxx zf5qqc-G~1T-v{@_bMRd31N*{0v2UCM=fXL0ZqxyFL7h-H)Dd+>ol$r60ewNA&^PoE zeMO(qcjN%MKu(Yw#xkk>Bd&~jm0&{}7!5m?(FlU%M%pv9y zbBeje9AmCA=a_qN09*hkzzuK&Tmfgm9dHO-0;j+&a12}n=fFL15L^T&!A)=!Tm@&r zU2qs&2B*Poa2#9*=fQn=0A7G6;0<^LUV&%e9e4;{f~Vjucnn^H=iohf5MKP?$zgB8 dqwp#`3-7|i@G?9NZ^Ps8Iy?{W{|&w3`HXB8)ZG98 diff --git a/matlab/resampler/arb_resample_linear.m b/matlab/resampler/arb_resample_linear.m deleted file mode 100644 index 4bfb4df03..000000000 --- a/matlab/resampler/arb_resample_linear.m +++ /dev/null @@ -1,46 +0,0 @@ -function out = arb_resample_linear(sig, rate) - -N = 32; -M = 8; -step = (1/rate)*N; - -load('arb_filter.mat'); - -figure;plot(Num);title('Filter impulse response'); -[h,w] = freqz(Num, 1); -figure;plot(20*log10(abs(h)));title('Filter freq response'); - -% Create polyphase partition -poly = reshape(Num, N, M); - -% Filter -sig = [zeros(1,(M/2)-1) sig]; -k=0; -acc=0; -index=0; -frac=0; -out = []; -while k < length(sig)-M - sig_reg = fliplr(sig(k+1:k+M)); - filt_reg1 = poly(index+1, :); - filt_reg2 = poly(mod(index+1,N)+1, :); - res1 = sig_reg*filt_reg1'; - res2 = sig_reg*filt_reg2'; - - if index+1 == 32 - res = res1; - else - res = res1 + (res2-res1)*frac; - end - - out = [out res]; - - acc = acc+step; - index = fix(acc); - while index >= N - acc = acc - N; - index = index - N; - k = k+1; - end - frac = abs(acc-index); -end diff --git a/matlab/resampler/arb_resample_nearest.m b/matlab/resampler/arb_resample_nearest.m deleted file mode 100644 index 0601aa169..000000000 --- a/matlab/resampler/arb_resample_nearest.m +++ /dev/null @@ -1,37 +0,0 @@ -function out = arb_resample_nearest(sig, rate) - -N = 32; -M = 8; -step = (1/rate)*N; - -load('arb_filter.mat'); - -figure;plot(Num);title('Filter impulse response'); -[h,w] = freqz(Num, 1); -figure;plot(20*log10(abs(h)));title('Filter frequency response'); - -% Create polyphase partition -poly = reshape(Num, N, M); - -% Filter -sig = [zeros(1,(M/2)-1) sig]; -k=0; -acc=0; -index=0; -frac=0; -out = []; -while k < length(sig)-M - sig_reg = fliplr(sig(k+1:k+M)); - filt_reg1 = poly(index+1, :); - res = sig_reg*filt_reg1'; - - out = [out res]; - - acc = acc+step; - index = round(acc); - while index >= N - acc = acc - N; - index = index - N; - k = k+1; - end -end \ No newline at end of file diff --git a/matlab/resampler/arb_resample_test.m b/matlab/resampler/arb_resample_test.m deleted file mode 100644 index b6d661da4..000000000 --- a/matlab/resampler/arb_resample_test.m +++ /dev/null @@ -1,33 +0,0 @@ -close all -clear all - -up = 24; -down = 25; -d_rate = up/down; -Fs = 100; % Arbitrary sample rate (used for displays) -Fsin = 1; - -% Create a sine wave -t = 0:1/Fs:1-1/Fs; -sig = sin(2*pi*t); - -out = arb_resample_nearest(sig,d_rate); - -% matlab resample for comparison -out2 = resample(sig, up, down); -figure;hold on;title('Ours and matlabs'); -l = min(length(out), length(out2)); -stem(out(1:l)); -stem(out2(1:l), 'r', 'filled'); -diff = out2(1:l)-out(1:l); -figure;plot(diff);title('Difference between ours and matlabs'); - -figure; hold on;title('Original and resampled - no time scaling'); -stem(sig); -stem(out, 'r', 'filled'); - -% Time align and plot -figure;hold on;title('Original and resampled - with time scaling'); -stem((1:75)/Fs,real(sig(1:75))); -stem((1:72)/(Fs*d_rate),real(out(1:72)),'r','filled'); -xlabel('Time (sec)');ylabel('Signal value'); \ No newline at end of file diff --git a/matlab/sync/addnoise.m b/matlab/sync/addnoise.m deleted file mode 100644 index 56f49c4f8..000000000 --- a/matlab/sync/addnoise.m +++ /dev/null @@ -1,6 +0,0 @@ -function [ y ] = addnoise( x, snr_db ) -v = 10^(-snr_db/10); -y=x+sqrt(v)*(randn(size(x))+1i*randn(size(x)))/sqrt(2); -y=y/sqrt(mean(y.*conj(y))); -end - diff --git a/matlab/sync/cfo_estimate_cp.m b/matlab/sync/cfo_estimate_cp.m deleted file mode 100644 index ebc1f0735..000000000 --- a/matlab/sync/cfo_estimate_cp.m +++ /dev/null @@ -1,18 +0,0 @@ -function [cfo, r] = cfo_estimate_cp(input_slot, Nsyms, sym_len, cp0_len, cp_len) - -% Start correlating from the end. Nsyms is the number of symbols to -% correlate starting from the end. - -s=length(input_slot)-sym_len-cp_len; -e=length(input_slot)-sym_len; -for i=1:Nsyms - r(i)=sum(input_slot(s:e).*conj(input_slot(s+sym_len:e+sym_len))); - if (i < 7) - s=s-sym_len-cp_len; - e=e-sym_len-cp_len; - else - s=s-sym_len-cp0_len; - e=e-sym_len-cp0_len; - end -end -cfo=-angle(mean(r))/pi; \ No newline at end of file diff --git a/matlab/sync/cfo_test.m b/matlab/sync/cfo_test.m deleted file mode 100644 index cd957fb5c..000000000 --- a/matlab/sync/cfo_test.m +++ /dev/null @@ -1,42 +0,0 @@ -clear; -sym_len=128; -hflen = (sym_len/128)*1920*5; -samp_rate = (sym_len/128)*1920000; -N_id_2=0; -input=read_complex('../../debug/lte_signal.dat', hflen*240); - -addpath('../../debug/srslte/lib/sync/test') - -off=100; -halfframes=reshape(input(hflen-off+1:end-hflen-off),hflen,[]); -[n m]=size(halfframes); - -fo=linspace(-30000,30000,m); - -nreal=1; - -cfdl=struct('NDLRB',6,'CyclicPrefix','Normal','NCellID',0,'CellRefP',1,'DuplexMode','FDD'); -cfo=zeros(m,3); -toffset=zeros(m,2); -for i=1:m - x = halfframes(:,i); - t = (0:n-1).'/samp_rate; - x = x .* exp(1i*2*pi*fo(i).*t); - cfo_=zeros(nreal,2); - idx_=zeros(nreal,2); - for j=1:nreal - y=awgn(x,5); - cfo_(j,1) = lteFrequencyOffset(cfdl,y)/15000; - [idx_(j,1), cfo_(j,2)] = find_pss(y,N_id_2); - [idx_(j,2), corr] = srslte_cp_synch(cfdl,y); - cfo_(j,3) = -angle(corr(idx_(j,2)+1))/2/pi; - idx_(j,1) = idx_(j,1)-961; - end - cfo(i,:)=mean(cfo_,1); - toffset(i,:)=mean(idx_,1); -end - -error=abs(cfo-repmat(fo',1,3)/15000); -semilogy(fo/15000,error) -%plot(fo/15000,toffset) -legend('Matlab','PSS-based','CP-based') diff --git a/matlab/sync/check_pss.m b/matlab/sync/check_pss.m deleted file mode 100644 index a0a3544f0..000000000 --- a/matlab/sync/check_pss.m +++ /dev/null @@ -1,33 +0,0 @@ -function [ fs ] = check_pss( x, N_id_2, threshold) -%CHECK_PSS Summary of this function goes here -% Detailed explanation goes here -flen=9600; -n=length(x); -nf=floor(n/flen); - -xf=reshape(x(1:nf*flen),flen,[]); - -fs=zeros(nf,1); -cfo=zeros(nf,1); -cfo2=zeros(nf,1); -m_p=zeros(nf,1); -for i=1:nf - [fs(i) cfo(i) m_p(i)]=find_pss(xf(:,i),N_id_2,false, threshold); -end - -fs=fs+960; -[sfo sfo_v]=srslte_sfo_estimate(fs, 5/1000); - -subplot(1,3,1) -plot(1:nf,fs) -subplot(1,3,2) -plot(1:nf, cfo) -if (nf > 0) - axis([0 nf -0.5 0.5]) -end -subplot(1,3,3) -plot(m_p) -fprintf('cfo_mean=%g Hz, cfo_std=%g Hz, m_p=%g sfo=%g Hz\n',15000*nanmean(cfo),15000*nanstd(cfo), nanmean(m_p), sfo) -end - - diff --git a/matlab/sync/correct_cfo.m b/matlab/sync/correct_cfo.m deleted file mode 100644 index effff8dc4..000000000 --- a/matlab/sync/correct_cfo.m +++ /dev/null @@ -1,14 +0,0 @@ -function [ y eps] = correct_cfo( x ) - -xf=reshape(x,9600,[]); -yf=zeros(size(xf)); -[m n]=size(xf); - -for i=1:n - [fs eps(i)]=find_pss(xf(:,i),0,false); - yf(:,i)=xf(:,i).*exp(-1i.*(1:length(xf(:,i)))'.*2*pi*eps(i)/128); -end - -y=reshape(yf,1,[]); - -end \ No newline at end of file diff --git a/matlab/sync/cp_corr.m b/matlab/sync/cp_corr.m deleted file mode 100644 index c97a2f82b..000000000 --- a/matlab/sync/cp_corr.m +++ /dev/null @@ -1,9 +0,0 @@ -function [ lambda ] = cp_corr( x, theta, N, L) - -l0=sum(x(theta:theta+L-1).*conj(x(theta+N:theta+L+N-1))); -l1=0; -for i=theta:theta+L-1 - l1=l1+abs(x(i))^2+abs(x(i+N))^2; -end - -lambda=l1;%2*abs(l0)-rho*l1; diff --git a/matlab/sync/cp_pss_comp.m b/matlab/sync/cp_pss_comp.m deleted file mode 100644 index a589e482a..000000000 --- a/matlab/sync/cp_pss_comp.m +++ /dev/null @@ -1,8 +0,0 @@ -function cp_pss_comp(x,N_id_2) - -[ fs eps p_m w2] = find_pss( x, N_id_2); -lambda=zeros(1,length(x)-138); -for theta=1:length(lambda) - lambda(theta)=cp_corr(x,theta,128,9,0); -end -plot(1:length(w2),abs(w2)/max(abs(w2)),1:length(lambda),abs(lambda)/max(abs(lambda))) \ No newline at end of file diff --git a/matlab/sync/epsilon.m b/matlab/sync/epsilon.m deleted file mode 100644 index 4accfcc3a..000000000 --- a/matlab/sync/epsilon.m +++ /dev/null @@ -1,14 +0,0 @@ -function [ eps fs] = epsilon( x ) - -xf=reshape(x,19200,[]); - -[m n]=size(xf); -eps=zeros(n,1); -fs=zeros(n,1); - -for i=1:n - [fs(i) eps(i)]=find_pss(xf(:,i),0,false); -end - - -end \ No newline at end of file diff --git a/matlab/sync/find_peaks.m b/matlab/sync/find_peaks.m deleted file mode 100644 index 7f9b27bf5..000000000 --- a/matlab/sync/find_peaks.m +++ /dev/null @@ -1,13 +0,0 @@ -function [peaks] = find_peaks(x, N_id_2, fft_size) - -flen=4800*(ceil(fft_size/64)); - -n=floor(length(x)/flen)*flen; -xf=reshape(x(1:n),flen,[]); - -[n m] = size(xf); - -peaks=zeros(m,1); -for i=1:m - [w, peaks(i)]= find_pss2(xf(:,i),N_id_2,fft_size); -end diff --git a/matlab/sync/find_pss.m b/matlab/sync/find_pss.m deleted file mode 100644 index 1dbd4a4fb..000000000 --- a/matlab/sync/find_pss.m +++ /dev/null @@ -1,19 +0,0 @@ -function [ fs, cfo, p_m, w2] = find_pss( x, N_id_2) - - c=lte_pss_zc(N_id_2); - cc=[zeros(33,1); c; zeros(33,1)]; - ccf=[0; cc(65:128); cc(2:64)]; - ccf=sqrt(128)*conj(ifft(ccf)); - w2=conv(x,ccf); - [m, fs]=max(abs(w2)); - - if (fs > 128 && fs < length(x)) - y=ccf.*x(fs-128:fs-1); - y0=y(1:64); - y1=y(65:length(y)); - - cfo=angle(conj(sum(y0))*sum(y1))/pi; - p_m = m/mean(abs(w2)); - end -end - diff --git a/matlab/sync/find_pss2.m b/matlab/sync/find_pss2.m deleted file mode 100644 index 478a47cdb..000000000 --- a/matlab/sync/find_pss2.m +++ /dev/null @@ -1,14 +0,0 @@ -function [w2, m, idx] = find_pss2( x, N_id_2, fft_size) - c=lte_pss_zc(N_id_2); - cc=[zeros(fft_size/2-31,1); c; zeros(fft_size/2-31,1)]; - ccd=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)]; - ccf=sqrt(fft_size)*conj(ifft(ccd)); - - w2=abs(conv(x,ccf/62)).^2/var(x,1)/sqrt(2); - plot(w2) - [m, idx]=max(w2); - - %fprintf('Frame starts at %d, energy=%g, p=%g, p/en=%g dB\n',i, ... - % en, m, m/en); -end - diff --git a/matlab/sync/find_pss_ac.m b/matlab/sync/find_pss_ac.m deleted file mode 100644 index 0bff75866..000000000 --- a/matlab/sync/find_pss_ac.m +++ /dev/null @@ -1,7 +0,0 @@ -function fs = find_pss_ac( x) - - w2=xcorr(x,x); - [m, fs]=max(abs(w2)); - fs=fs-1920; -end - diff --git a/matlab/sync/find_sss.m b/matlab/sync/find_sss.m deleted file mode 100644 index a6fddd9c9..000000000 --- a/matlab/sync/find_sss.m +++ /dev/null @@ -1,50 +0,0 @@ -function [ m1 m2 out Zprod0 Zprod1] = find_sss( y, Nid_2,c0,c1) - - y=y((960-2*137+1):(960-137-9)); - yf=fft(y,128); - y=[yf(98:128) yf(2:32)]; - - - n=length(y); - Y0=y(1:2:n); - Y1=y(2:2:n); - - Z0=Y0.*c0; - nz=length(Z0); - - sm0=zeros(31,31); - sm1=zeros(31,31); - zm0=zeros(31,31); - - for i=1:31 - [sm0(i,:) zm0(i,:)]=compute_m0(i-1); - end - - Zprod0=Z0(2:nz).*conj(Z0(1:(nz-1))); - - sum0=zeros(31,1); - for m=1:31 - for i=2:31 - sum0(m)=sum0(m)+Z0(i)*conj(Z0(i-1))*sm0(m,i)*conj(sm0(m,i-1)); - end - end - - [mi1 i1]=max(abs(sum0)); - - Z1=Y1.*c1.*zm0(i1,:); - - Zprod1=Z1(2:nz).*conj(Z1(1:(nz-1))); - - sum1=zeros(31,1); - for m=1:31 - for i=2:31 - sum1(m)=sum1(m)+Z1(i)*conj(Z1(i-1))*sm0(m,i)*conj(sm0(m,i-1)); - end - end - [mi2 i2]=max(abs(sum1)); - - m1=i1; - m2=i2; - out=[sum0; sum1]; -end - diff --git a/matlab/sync/ifo_pss.m b/matlab/sync/ifo_pss.m deleted file mode 100644 index 739cbe1a7..000000000 --- a/matlab/sync/ifo_pss.m +++ /dev/null @@ -1,13 +0,0 @@ -function [ ifo ] = ifo_pss( r_pss, x_pss) - -k=1; -v=-31:31; -c=zeros(length(v),1); -for i=v - c(k) = ifo_pss_corr(i, r_pss, x_pss); - k=k+1; -end -[m i]=max(c); -ifo=v(i); -plot(v,c); - diff --git a/matlab/sync/ifo_pss_corr.m b/matlab/sync/ifo_pss_corr.m deleted file mode 100644 index c921cba9c..000000000 --- a/matlab/sync/ifo_pss_corr.m +++ /dev/null @@ -1,10 +0,0 @@ -function [ corr ] = ifo_pss_corr( n, r_pss, x_pss) - - x=0; - for i=1:length(x_pss) - x=x+r_pss(1+mod(i+n-1,length(r_pss)))*conj(x_pss(i)); - end - corr=real(exp(1i*2*pi*9*n/128)*x); -% corr=abs(x); -end - diff --git a/matlab/sync/lte_pss_zc.m b/matlab/sync/lte_pss_zc.m deleted file mode 100644 index 1cf94af88..000000000 --- a/matlab/sync/lte_pss_zc.m +++ /dev/null @@ -1,24 +0,0 @@ -function[a]=lte_pss_zc(cell_id) -% Function returns 1 out of 3 possible Zadoff-Chu sequences used in LTE. - -Nzc=62; -u=0; -if cell_id==0 - u=25; -end -if cell_id==1 - u=29; -end -if cell_id==2 - u=34; -end - -a = zeros(Nzc,1); -for n=0:30 - a(n+1)=exp(complex(0,-1)*pi*u*n*(n+1)/63); -end -for n=31:61 - a(n+1)=exp(complex(0,-1)*pi*u*(n+1)*(n+2)/63); -end - -end diff --git a/matlab/sync/sfo_estimate.m b/matlab/sync/sfo_estimate.m deleted file mode 100644 index 16c208712..000000000 --- a/matlab/sync/sfo_estimate.m +++ /dev/null @@ -1,18 +0,0 @@ -function [ sfo sfo_v ] = srslte_sfo_estimate( fs, T ) - - -nanfs=fs(~isnan(fs)); -idx=find(~isnan(fs)); -sfo_v = zeros(length(nanfs)-1,1); -for i=2:length(nanfs) - if (abs(nanfs(i)-nanfs(i-1))<9000) - sfo_v(i-1)=(nanfs(i)-nanfs(i-1))/T/(idx(i)-idx(i-1)); - else - sfo_v(i-1)=sfo_v(i-2); - end -end - -sfo = mean(sfo_v); - - - diff --git a/matlab/sync/sym_sync_cp.m b/matlab/sync/sym_sync_cp.m deleted file mode 100644 index a122ef182..000000000 --- a/matlab/sync/sym_sync_cp.m +++ /dev/null @@ -1,13 +0,0 @@ -function [ fs ] = sym_sync_cp( x, s ) - -lambda=zeros(1,length(x)-138); -for theta=1:length(lambda) - lambda(theta)=cp_corr(x,theta,128,9,s); -end - -subplot(1,2,1) -plot(abs(lambda)) -subplot(1,2,2) -plot(angle(lambda)) -[m i] = max(abs(lambda)) - diff --git a/matlab/tests/diversity_decode_test.m b/matlab/tests/diversity_decode_test.m deleted file mode 100644 index 9f21a971b..000000000 --- a/matlab/tests/diversity_decode_test.m +++ /dev/null @@ -1,46 +0,0 @@ -clear - -addpath('../../build/srslte/lib/mimo/test') - -enb = lteRMCDL('R.10'); - -cec = struct('FreqWindow',9,'TimeWindow',9,'InterpType','cubic'); -cec.PilotAverage = 'UserDefined'; -cec.InterpWinSize = 1; -cec.InterpWindow = 'Causal'; - -cfg.Seed = 1; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'ETU'; % EVA delay spread -cfg.DopplerFreq = 100; % 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 - -[txWaveform, ~, info] = lteRMCDLTool(enb,[1;0;0;1]); -n = length(txWaveform); -cfg.SamplingRate = info.SamplingRate; - -txWaveform = txWaveform+complex(randn(n,2),randn(n,2))*1e-3; - -rxWaveform = lteFadingChannel(cfg,txWaveform); - -rxGrid = lteOFDMDemodulate(enb,sum(rxWaveform,2)); - -[h,n0] = lteDLChannelEstimate(enb,cec,rxGrid); - -signal=rxGrid(:,1); -hest(:,1,1)=reshape(h(:,1,1,1),[],1); -hest(:,1,2)=reshape(h(:,1,1,1),[],1); - -output_mat = lteTransmitDiversityDecode(signal(, hest(1:598,1,:)); -output_srs = srslte_diversitydecode(signal(1:598), hest(1:598,1,:)); - -plot(abs(output_mat-output_srs)) -mean(abs(output_mat-output_srs).^2) - - diff --git a/matlab/tests/diversity_test_rate.m b/matlab/tests/diversity_test_rate.m deleted file mode 100644 index 87e8f2f8d..000000000 --- a/matlab/tests/diversity_test_rate.m +++ /dev/null @@ -1,285 +0,0 @@ -%% PDSCH Transmit Diversity Throughput Conformance Test -% This example demonstrates the throughput performance under conformance -% test conditions as defined in TS36.101[ <#9 1> ]: single codeword, -% transmit diversity 4Tx-2Rx with medium correlation, EPA5 (Extended -% Pedestrian A) channel. The example also introduces the use of Parallel -% Computing Toolbox(TM) to provide improvements in the simulation time. - -% Copyright 2009-2013 The MathWorks, Inc. - -%% Introduction -% In this example, Hybrid Automatic Repeat Request(HARQ) is used in line -% with conformance test requirements. A total of 8 HARQ processes are used -% with a maximum of 4 retransmissions permitted. This example uses the R.12 -% Reference Measurement Channel (RMC). -% -% This example also uses loop instead of the -% loop for SNR calculation. , as part of the Parallel Computing Toolbox, executes the SNR loop -% in parallel to reduce the total simulation time. - -%% Simulation Settings -% The default simulation length is set to 10 frames at a number of |SNR| -% values including 0.2dB (as per TS36.101 (Section 8.2.1.2.2-Test1)[ <#9 -% 1> ]). -NFrames = 50; % Number of frames -SNRdB = [4 5 6]; % SNR range - -% eNodeB Configuration -enb = struct; % eNodeB config structure -enb.TotSubframes = 1; % Total subframes RMC will generate -enb.RC = 'R.10'; % RMC number - -% Channel Configuration -channel = struct; % Channel config structure -channel.Seed = 2; % Random channel seed -channel.NRxAnts = 1; % 2 receive antennas -channel.DelayProfile ='EVA'; % Delay profile -channel.DopplerFreq = 5; % Doppler frequency -channel.MIMOCorrelation = 'Low'; % Multi-antenna correlation -channel.NTerms = 16; % Oscillators used in fading model -channel.ModelType = 'GMEDS'; % Rayleigh fading model type -channel.InitPhase = 'Random'; % Random initial phases -channel.NormalizePathGains = 'On'; % Normalize delay profile power -channel.NormalizeTxAnts = 'On'; % Normalize for transmit antennas - -% Channel Estimator Configuration -cec = struct; % Channel estimation config structure -cec.PilotAverage = 'UserDefined'; % Type of pilot symbol averaging -cec.FreqWindow = 9; % Frequency window size -cec.TimeWindow = 9; % Time window size -cec.InterpType = 'Linear'; % 2D interpolation type -cec.InterpWindow = 'Centered'; % Interpolation window type -cec.InterpWinSize = 1; % Interpolation window size - -% PDSCH Configuration -enb.PDSCH.TxScheme = 'TxDiversity'; % Transmission scheme -enb.PDSCH.RNTI = 1; % 16-bit User Equipment (UE) mask -enb.PDSCH.Rho = 0; % PDSCH RE power adjustment factor -enb.PDSCH.CSI = 'Off'; % No CSI scaling of soft bits - -% Simulation Variables -totalBLKCRC = []; % Define total block CRC vector -bitThroughput = []; % Define total bit throughput vector - -%% System Processing -% Working on a subframe by subframe basis and using the LTE System -% Toolbox(TM) a populated resource grid is generated and OFDM modulated to -% create a transmit waveform. The generated waveform is transmitted through -% a propagation channel and AWGN is added. Channel estimation, equalization -% and the inverse of transmission chain are performed at receiver. The -% throughput performance of the PDSCH is determined using the block CRC -% result. - -% Generate the RMC configuration structure for RMC R.12 -rmc = lteRMCDL(enb); -rvSeq = rmc.PDSCH.RVSeq; - -% Transport block sizes for each subframe in a frame -trBlkSizes = rmc.PDSCH.TrBlkSizes; -codedTrBlkSizes = rmc.PDSCH.CodedTrBlkSizes; - -% Determine resource grid dimensions -dims = lteDLResourceGridSize(rmc); -p = dims(3); - -% Set up channel model sampling rate -ofdmInfo = lteOFDMInfo(rmc); -channel.SamplingRate = ofdmInfo.SamplingRate; - -% Generation HARQ table for 8-HARQ processes -harqTable = hHARQTable(); - -% Initializing state of all HARQ processes -for i=1:9 - harqProcess_init(i) = hTxDiversityNewHARQProcess ... - (trBlkSizes(i),codedTrBlkSizes(i),rvSeq); %#ok -end - -% Display the SNR points being simulated -for s=1:numel(SNRdB) - fprintf('\nSimulating at %gdB SNR for a total %d Frame(s)\n', ... - SNRdB(s),NFrames); -end - -% The temporary variables 'rmc_init' and 'channel_init' are used to create -% the temporary variables 'rmc' and 'channel' within the SNR loop to create -% independent simulation loops for the parfor loop -rmc_init = rmc; -channel_init = channel; - -% 'parfor' will default to the normal 'for' when executed without Parallel -% Computing Toolbox. -parfor index = 1:numel(SNRdB) - - % Set the random number generator seed depending to the loop variable - % to ensure independent random streams - rng(index,'combRecursive'); - - % Set up variables for the SNR loop - offsets = 0; % Initialize overall frame offset value for the SNR - offset = 0; % Initialize frame offset value for the radio frame - rmc = rmc_init; % Initialize RMC configuration - channel = channel_init; % Initialize channel configuration - blkCRC = []; % Define intermediate block CRC vector - bitTput = []; % Intermediate bit throughput vector - - % Initializing state of all HARQ processes - harqProcess = harqProcess_init; - - for subframeNo = 0:(NFrames*10-1) - - % Updating subframe number - rmc.NSubframe = subframeNo; - - % HARQ index table - harqIdx = harqTable(mod(subframeNo,length(harqTable))+1); %#ok - - % Update HARQ process - harqProcess(harqIdx) = hTxDiversityHARQScheduling( ... - harqProcess(harqIdx)); - - % Updating the RV value for correct waveform generation - rmc.PDSCH.RV = harqProcess(harqIdx).rvSeq ... - (harqProcess(harqIdx).rvIdx); - - rmc.PDSCH.RVSeq = harqProcess(harqIdx).rvSeq ... - (harqProcess(harqIdx).rvIdx); - - [txWaveform txGrid] = lteRMCDLTool(rmc, ... - {harqProcess(harqIdx).dlschTransportBlk}); - txWaveform = [txWaveform; zeros(25,p)]; - - % Initialize at time zero - channel.InitTime = subframeNo/1000; - - % Pass data through the fading channel model - rxWaveform = lteFadingChannel(channel,txWaveform); - - % Noise setup including compensation for downlink power allocation - SNR = 10^((SNRdB(index)-rmc.PDSCH.Rho)/20); % Linear SNR - - % Normalize noise power to take account of sampling rate, which is - % a function of the IFFT size used in OFDM modulation, and the - % number of antennas - N0 = 1/(sqrt(2.0*rmc.CellRefP*double(ofdmInfo.Nfft))*SNR); - - % Create additive white Gaussian noise - noise = N0*complex(randn(size(rxWaveform)), ... - randn(size(rxWaveform))); - - % Add AWGN to the received time domain waveform - rxWaveform = rxWaveform + noise; - - % Receiver - % Perform synchronization - % An offset within the range of delays expected from the channel - % modeling(a combination of implementation delay and channel delay - % spread) indicates success - if (mod(subframeNo,10)==0) - [offset] = lteDLFrameOffset(rmc,rxWaveform); - if (offset > 25) - offset = offsets(end); - end - offsets = [offsets offset]; - end - rxWaveform = rxWaveform(1+offset:end,:); - - % Perform OFDM demodulation on the received data to recreate the - % resource grid - rxSubframe = lteOFDMDemodulate(rmc,rxWaveform); - - % Equalization and channel estimation - [estChannelGrid,noiseEst] = lteDLChannelEstimate(rmc,cec, ... - rxSubframe); - - addpath('../../debug/lte/phy/lib/ch_estimation/test') - [est, ~, output] = srslte_chest(rmc.NCellID,rmc.CellRefP,rxSubframe,[0.25 0.5 0.25],[0.1 0.9],mod(rmc.NSubframe,10)); - - %estChannelGrid=reshape(est,size(estChannelGrid)); - - % Perform deprecoding, layer demapping, demodulation and - % descrambling on the received data using the estimate of - % the channel - rxEncodedBits = ltePDSCHDecode2(rmc,rmc.PDSCH,rxSubframe,estChannelGrid,noiseEst); - - % Decode DownLink Shared Channel (DL-SCH) - [decbits,harqProcess(harqIdx).crc,harqProcess(harqIdx).decState] = ... - lteDLSCHDecode(rmc,rmc.PDSCH,harqProcess(harqIdx).trBlkSize, ... - rxEncodedBits{1},harqProcess(harqIdx).decState); - - if(harqProcess(harqIdx).trBlkSize ~= 0) - blkCRC = [blkCRC harqProcess(harqIdx).crc]; - bitTput = [bitTput harqProcess(harqIdx).trBlkSize.*(1- ... - harqProcess(harqIdx).crc)]; - end - end - % Record the block CRC and bit throughput for the total number of - % frames simulated at a particular SNR - totalBLKCRC(index,:) = blkCRC; - bitThroughput(index,:) = bitTput; - -end -%% -% |totalBLKCRC| is a matrix where each row contains the results of decoding -% the block CRC for a defined value of SNR. |bitThroughput| is a matrix -% containing the total number of bits per subframe at the different SNR -% points that have been successfully received and decoded. - -%% Results - -% First graph shows the throughput as total bits per second against the -% range of SNRs -% figure; -% plot(SNRdB,mean(bitThroughput,2),'-*'); -% %axis([-5 3 200 400]) -% title(['Throughput for ', num2str(NFrames) ' frame(s)'] ); -% xlabel('SNRdB'); ylabel('Throughput (kbps)'); -% grid on; -% hold on; -% plot(SNRdB,mean([trBlkSizes(1:5) trBlkSizes(7:10)])*0.7*ones ... -% (1,numel(SNRdB)),'--rs'); -% legend('Simulation Result','70 Percent Throughput','Location','SouthEast'); -% -% % Second graph shows the total throughput as a percentage of CRC passes -% % against SNR range -% figure; -plot(SNRdB,100*(1-mean(totalBLKCRC,2)),'-*'); -%axis([-5 3 50 110]) -title(['Throughput for ', num2str(NFrames) ' frame(s)'] ); -xlabel('SNRdB'); ylabel('Throughput (%)'); -grid on; -hold on; -plot(SNRdB,70*ones(1,numel(SNRdB)),'--rs'); -legend('Simulation Result','70 Percent Throughput','Location','SouthEast'); - - -%% Further Exploration -% -% You can modify parts of this example to experiment with different number -% of |NFrames| and different values of SNR. SNR can be a vector of -% values or a single value. Following scenarios can be simulated. -%% -% * Allows control over the total number of frames to run the demo at an -% SNR of 0.2dB (as per TS 36.101). -% -% * Allows control over the total number of frames to run the demo, as well -% as defining a set of desired SNR values. |SNRIn| can be a single value -% or a vector containing a range of values. -% -% * For simulations of multiple SNR points over a large number of frames, -% the use of Parallel Computing Toolbox provides significant improvement in -% the simulation time. This can be easily verified by changing the |parfor| -% in the SNR loop to |for| and re-running the example. - -%% Appendix -% This example uses the following helper functions: -% -% * -% * -% * - -%% Selected Bibliography -% # 3GPP TS 36.101 - -displayEndOfDemoMessage(mfilename) diff --git a/matlab/tests/dlsch_test.m b/matlab/tests/dlsch_test.m deleted file mode 100644 index c8414c755..000000000 --- a/matlab/tests/dlsch_test.m +++ /dev/null @@ -1,27 +0,0 @@ -clear -enbConfig=struct('NCellID',0,'CyclicPrefix','Normal','CellRefP',1); -pdschConfig=struct('Modulation','64QAM','RV',1,'TxScheme','Port0','NTurboDecIts',10); - -addpath('../../build/srslte/lib/phch/test') - -TBs=18336; -i=1; -e_bits=3450*6; -error=zeros(size(TBs)); -for i=1:length(TBs) - trblkin=randi(2,TBs(i),1)-1; - - [mat, info]=lteDLSCH(enbConfig,pdschConfig,e_bits,trblkin); - lib=srslte_dlsch_encode(enbConfig,pdschConfig,e_bits,trblkin); - error(i)=mean(abs(double(mat)-double(lib))); - -end - - if (length(TBs) == 1) - disp(info) - disp(error) - n=1:length(mat); - plot(abs(double(mat)-double(lib))) - else - plot(error) - end diff --git a/matlab/tests/dmrs_equalizer_test.m b/matlab/tests/dmrs_equalizer_test.m deleted file mode 100644 index 11f14cbff..000000000 --- a/matlab/tests/dmrs_equalizer_test.m +++ /dev/null @@ -1,184 +0,0 @@ -%% LTE Downlink Channel Estimation and Equalization - -%% Cell-Wide Settings - -clear - -plot_noise_estimation_only=false; - -SNR_values_db=100;%linspace(0,30,5); -Nrealizations=1; - -w1=1/3; - -%% UE Configuration -ue = lteRMCUL('A3-5'); -ue.TotSubframes = 2; - -K=ue.NULRB*12; -P=K/6; - -%% Channel Model Configuration -chs.Seed = 1; % Random channel seed -chs.InitTime = 0; -chs.NRxAnts = 1; % 1 receive antenna -chs.DelayProfile = 'EVA'; -chs.DopplerFreq = 300; % 120Hz Doppler frequency -chs.MIMOCorrelation = 'Low'; % Low (no) MIMO correlation -chs.NTerms = 16; % Oscillators used in fading model -chs.ModelType = 'GMEDS'; % Rayleigh fading model type -chs.InitPhase = 'Random'; % Random initial phases -chs.NormalizePathGains = 'On'; % Normalize delay profile power -chs.NormalizeTxAnts = 'On'; % Normalize for transmit antennas - -%% Channel Estimator Configuration -cec = struct; % Channel estimation config structure -cec.PilotAverage = 'UserDefined'; % Type of pilot symbol 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 - - -%% Allocate memory -Ntests=3; -hest=cell(1,Ntests); -for i=1:Ntests - hest{i}=zeros(K,14); -end -MSE=zeros(Ntests,Nrealizations,length(SNR_values_db)); -noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db)); - -legends={'matlab','ls',num2str(w1)}; -colors={'bo-','rx-','m*-','k+-','c+-'}; -colors2={'b-','r-','m-','k-','c-'}; - -addpath('../../debug/srslte/lib/ch_estimation/test') - -offset = -1; -for nreal=1:Nrealizations - - %% Signal Generation - [txWaveform, txGrid, info] = lteRMCULTool(ue,[1;0;0;1]); - - %% SNR Configuration - for snr_idx=1:length(SNR_values_db) - SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB - SNR = 10^(SNRdB/20); % Linear SNR - - fprintf('SNR=%.1f dB\n',SNRdB) - - %% Fading Channel - - chs.SamplingRate = info.SamplingRate; - [rxWaveform, chinfo] = lteFadingChannel(chs,txWaveform); - - %% Additive Noise - - % Calculate noise gain - N0 = 1/(sqrt(2.0*double(info.Nfft))*SNR); - - % Create additive white Gaussian noise - noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))); - - % Add noise to the received time domain waveform - rxWaveform = rxWaveform + noise; - - %% Synchronization - - % Time offset estimation is done once because depends on channel - % model only - if (offset==-1) - offset = lteULFrameOffset(ue,ue.PUSCH,rxWaveform); - end - rxWaveform = rxWaveform(1+offset:end); - - %% OFDM Demodulation - rxGrid = lteSCFDMADemodulate(ue,rxWaveform); - rxGrid = rxGrid(:,1:14); - - %% Perfect channel estimate - h=lteULPerfectChannelEstimate(ue,chs,offset); - h=h(:,1:14); - - %% Channel Estimation with Matlab - [hest{1}, noiseEst(1,nreal,snr_idx)] = lteULChannelEstimate(ue,ue.PUSCH,cec,rxGrid); - - %% LS-Linear estimation with srsLTE - [hest{2}, noiseEst(2,nreal,snr_idx)] = srslte_chest_ul(ue,ue.PUSCH,rxGrid); - - %% LS-Linear estimation + averaging with srsLTE - [hest{3}, noiseEst(3,nreal,snr_idx)] = srslte_chest_ul(ue,ue.PUSCH,rxGrid,w1); - - %% Compute MSE - for i=1:Ntests - MSE(i,nreal,snr_idx)=mean(mean(abs(h-hest{i}).^2)); - fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx))); - end - - %% Plot a single realization - if (length(SNR_values_db) == 1) - subplot(1,1,1) - sym=1; - n=1:(K*length(sym)); - for i=1:Ntests - plot(n,abs(reshape(hest{i}(:,sym),1,[])),colors2{i}); - hold on; - end - plot(n,abs(reshape(h(:,sym),1,[])),'k'); - hold off; - - tmp=cell(Ntests+1,1); - for i=1:Ntests - tmp{i}=legends{i}; - end - tmp{Ntests+1}='Perfect'; - legend(tmp) - - xlabel('SNR (dB)') - ylabel('Channel Gain') - grid on; - - end - - end -end - -%% Compute average MSE and noise estimation -mean_mse=mean(MSE,2); -mean_snr=10*log10(1./mean(noiseEst,2)); - -%disp(mean_snr(3) - -%% Plot average over all SNR values -if (length(SNR_values_db) > 1) - subplot(1,2,1) - for i=1:Ntests - plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i}) - hold on; - end - hold off; - legend(legends); - grid on - xlabel('SNR (dB)') - ylabel('MSE (dB)') - - subplot(1,2,2) - plot(SNR_values_db, SNR_values_db,'k:') - hold on; - for i=1:Ntests - plot(SNR_values_db, mean_snr(i,:), colors{i}) - end - hold off - tmp=cell(Ntests+1,1); - tmp{1}='Theory'; - for i=2:Ntests+1 - tmp{i}=legends{i-1}; - end - legend(tmp) - grid on - xlabel('SNR (dB)') - ylabel('Estimated SNR (dB)') -end - diff --git a/matlab/tests/drms_pusch_test.m b/matlab/tests/drms_pusch_test.m deleted file mode 100644 index 271e925d8..000000000 --- a/matlab/tests/drms_pusch_test.m +++ /dev/null @@ -1,52 +0,0 @@ -ueConfig=struct('CyclicPrefixUL','Normal','NTxAnts',1,'NULRB',6); -puschConfig=struct('NLayers',1,'OrthCover','Off'); - -addpath('../../debug/lte/phy/lib/ch_estimation/test') - -Hopping={'Off','Sequence','Group'}; - -k=1; -for prb=4 - for ncell=1 - for ns=8 - for h=1 - for sg=0 - for cs=0 - for ds=0 - - ueConfig.NCellID=ncell; - ueConfig.NSubframe=ns; - ueConfig.Hopping=Hopping{h}; - ueConfig.SeqGroup=sg; - ueConfig.CyclicShift=cs; - - puschConfig.PRBSet=(1:4)'; - puschConfig.DynCyclicShift=ds; - - [mat, info]=ltePUSCHDRS(ueConfig,puschConfig); - ind=ltePUSCHDRSIndices(ueConfig, puschConfig); - subframe_mat = lteULResourceGrid(ueConfig); - subframe_mat(ind)=mat; - - subframe_lib=srslte_refsignal_pusch(ueConfig,puschConfig); - - error(k)=mean(abs(subframe_mat(:)-subframe_lib(:))); - disp(error(k)) - if (error(k) > 10^-3) - k=1; - end - k=k+1; - end - end - end - end - end - end -end - -plot(error); -disp(info) -disp(length(subframe_mat)) -n=1:length(subframe_mat(:)); -%plot(n,real(subframe_mat(:)),n,real(subframe_lib(:))) -plot(abs(subframe_mat(:)-subframe_lib(:))) diff --git a/matlab/tests/equalizer_test.m b/matlab/tests/equalizer_test.m deleted file mode 100644 index 816a29957..000000000 --- a/matlab/tests/equalizer_test.m +++ /dev/null @@ -1,277 +0,0 @@ -%% LTE Downlink Channel Estimation and Equalization - -%% Cell-Wide Settings - -clear - -plot_noise_estimation_only=false; - -SNR_values_db=linspace(0,30,8); -Nrealizations=10; - -w1=0.1; -w2=0.2; - -enb.NDLRB = 6; % Number of resource blocks - -enb.CellRefP = 1; % One transmit antenna port -enb.NCellID = 0; % Cell ID -enb.CyclicPrefix = 'Normal'; % Normal cyclic prefix -enb.DuplexMode = 'FDD'; % FDD - -K=enb.NDLRB*12; -P=K/6; - -%% Channel Model Configuration -cfg.Seed = 0; % Random channel seed -cfg.InitTime = 0; -cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'EVA'; - -% doppler 5, 70 300 - -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 -cfg.InitPhase = 'Random'; % Random initial phases -cfg.NormalizePathGains = 'On'; % Normalize delay profile power -cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas - -%% Channel Estimator Configuration -cec = struct; % Channel estimation config structure -cec.PilotAverage = 'UserDefined'; % Type of pilot symbol 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 Resource Grid Size - -gridsize = lteDLResourceGridSize(enb); -Ks = gridsize(1); % Number of subcarriers -L = gridsize(2); % Number of OFDM symbols in one subframe -Ports = gridsize(3); % Number of transmit antenna ports - -%% Allocate memory -Ntests=4; -hest=cell(1,Ntests); -tmpnoise=cell(1,Ntests); -for i=1:Ntests - hest{i}=zeros(K,140); - tmpnoise{i}=zeros(1,10); -end -hls=zeros(4,4*P*10); -MSE=zeros(Ntests,Nrealizations,length(SNR_values_db)); -noiseEst=zeros(Ntests,Nrealizations,length(SNR_values_db)); - -legends={'matlab','ls',num2str(w1),num2str(w2)}; -colors={'bo-','rx-','m*-','k+-','c+-'}; -colors2={'b-','r-','m-','k-','c-'}; - -addpath('../../build/srslte/lib/ch_estimation/test') - -offset=-1; - -for nreal=1:Nrealizations -%% Transmit Resource Grid -txGrid = []; - -%% Payload Data Generation -% Number of bits needed is size of resource grid (K*L*P) * number of bits -% per symbol (2 for QPSK) -numberOfBits = Ks*L*Ports*2; - -% Create random bit stream -inputBits = randi([0 1], numberOfBits, 1); - -% Modulate input bits -inputSym = lteSymbolModulate(inputBits,'QPSK'); - -%% Frame Generation - -% For all subframes within the frame -for sf = 0:10 - - % Set subframe number - enb.NSubframe = mod(sf,10); - - % Generate empty subframe - subframe = lteDLResourceGrid(enb); - - % Map input symbols to grid - subframe(:) = inputSym; - - % Generate synchronizing signals - pssSym = ltePSS(enb); - sssSym = lteSSS(enb); - pssInd = ltePSSIndices(enb); - sssInd = lteSSSIndices(enb); - - % Map synchronizing signals to the grid - subframe(pssInd) = pssSym; - subframe(sssInd) = sssSym; - - % Generate cell specific reference signal symbols and indices - cellRsSym = lteCellRS(enb); - cellRsInd = lteCellRSIndices(enb); - - % Map cell specific reference signal to grid - subframe(cellRsInd) = cellRsSym; - - % Append subframe to grid to be transmitted - txGrid = [txGrid subframe]; %#ok - -end - -txGrid([1:5 68:72],6:7) = ones(10,2); - -%% OFDM Modulation - -[txWaveform,info] = lteOFDMModulate(enb,txGrid); -txGrid = txGrid(:,1:140); - -%% SNR Configuration -for snr_idx=1:length(SNR_values_db) -SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB -SNR = 10^(SNRdB/20); % Linear SNR - -fprintf('SNR=%.1f dB\n',SNRdB) - -%% Fading Channel - -cfg.SamplingRate = info.SamplingRate; -[rxWaveform, chinfo] = lteFadingChannel(cfg,txWaveform); - -%% Additive Noise - -% Calculate noise gain -N0 = 1/(sqrt(2.0*enb.CellRefP*double(info.Nfft))*SNR); - -% Create additive white Gaussian noise -noise = N0*complex(randn(size(rxWaveform)),randn(size(rxWaveform))); - -% Add noise to the received time domain waveform -rxWaveform_nonoise = rxWaveform; -rxWaveform = rxWaveform + noise; - -%% Synchronization - -if (offset==-1) - offset = lteDLFrameOffset(enb,rxWaveform); -end - -rxWaveform = rxWaveform(1+offset:end,:); -rxWaveform_nonoise = rxWaveform_nonoise(1+offset:end,:); - -%% OFDM Demodulation -rxGrid = lteOFDMDemodulate(enb,rxWaveform); -rxGrid = rxGrid(:,1:140); - -rxGrid_nonoise = lteOFDMDemodulate(enb,rxWaveform_nonoise); -rxGrid_nonoise = rxGrid_nonoise(:,1:140); - -% True channel -h=rxGrid_nonoise./(txGrid); - -for i=1:10 - enb.NSubframe=i-1; - - rxGrid_sf = rxGrid(:,(i-1)*14+1:i*14); - - %% Channel Estimation with Matlab - [hest{1}(:,(1:14)+(i-1)*14), tmpnoise{1}(i)] = ... - lteDLChannelEstimate(enb,cec,rxGrid_sf); - tmpnoise{1}(i)=tmpnoise{1}(i)*sqrt(2)*enb.CellRefP; - - %% LS-Linear estimation with srsLTE - [hest{2}(:,(1:14)+(i-1)*14), tmpnoise{2}(i)] = srslte_chest_dl(enb,rxGrid_sf); - - %% LS-Linear + averaging with srsLTE - [hest{3}(:,(1:14)+(i-1)*14), tmpnoise{3}(i)] = srslte_chest_dl(enb,rxGrid_sf,w1); - - %% LS-Linear + more averaging with srsLTE - [hest{4}(:,(1:14)+(i-1)*14), tmpnoise{4}(i)] = srslte_chest_dl(enb,rxGrid_sf,w2); - -end - -%% Average noise estimates over all frame -for i=1:Ntests - noiseEst(i,nreal,snr_idx)=mean(tmpnoise{i}); -end - -%% Compute MSE -for i=1:Ntests - MSE(i,nreal,snr_idx)=mean(mean(abs(h-hest{i}).^2)); - fprintf('MSE test %d: %f\n',i, 10*log10(MSE(i,nreal,snr_idx))); -end - -%% Plot a single realization -if (length(SNR_values_db) == 1) - sym=1; - ref_idx=1:P; - ref_idx_x=[1:6:K];% (292:6:360)-216];% 577:6:648]; - n=1:(K*length(sym)); - for i=1:Ntests - plot(n,abs(reshape(hest{i}(:,sym),1,[])),colors2{i}); - hold on; - end - 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}='Real'; - legend(tmp) - - xlabel('SNR (dB)') - ylabel('Channel Gain') - grid on; - - fprintf('Mean MMSE Robust %.2f dB\n', 10*log10(MSE(4,nreal,snr_idx))) - fprintf('Mean MMSE matlab %.2f dB\n', 10*log10(MSE(1,nreal,snr_idx))) -end - -end -end - - -%% Compute average MSE and noise estimation -mean_mse=mean(MSE,2); -mean_snr=10*log10(1./mean(noiseEst,2)); - - -%% Plot average over all SNR values -if (length(SNR_values_db) > 1) - subplot(1,2,1) - for i=1:Ntests - plot(SNR_values_db, 10*log10(mean_mse(i,:)),colors{i}) - hold on; - end - hold off; - legend(legends); - grid on - xlabel('SNR (dB)') - ylabel('MSE (dB)') - - subplot(1,2,2) - plot(SNR_values_db, SNR_values_db,'k:') - hold on; - for i=1:Ntests - plot(SNR_values_db, mean_snr(i,:), colors{i}) - end - hold off - tmp=cell(Ntests+1,1); - tmp{1}='Theory'; - for i=2:Ntests+1 - tmp{i}=legends{i-1}; - end - legend(tmp) - grid on - xlabel('SNR (dB)') - ylabel('Estimated SNR (dB)') -end - diff --git a/matlab/tests/get_sc.m b/matlab/tests/get_sc.m deleted file mode 100644 index 2db50dd1f..000000000 --- a/matlab/tests/get_sc.m +++ /dev/null @@ -1,111 +0,0 @@ -function [ s, c0, c1 ] = get_sc( N_id_2 ) - - if (N_id_2 == 0) - - s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ]; - s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ]; - s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ]; - s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ]; - s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ]; - s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ]; - s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ]; - s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; - s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ]; - s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ]; - s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ]; - s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ]; - s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ]; - s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ]; - s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ]; - s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ]; - s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ]; - s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ]; - s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ]; - s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ]; - s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ]; - s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ]; - s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ]; - s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ]; - s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ]; - s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ]; - s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ]; - s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ]; - s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ]; - s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ]; - s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ]; - c0=[1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, ]; - c1=[1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, ]; - elseif (N_id_2 == 1) - s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ]; - s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ]; - s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ]; - s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ]; - s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ]; - s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ]; - s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ]; - s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; - s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ]; - s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ]; - s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ]; - s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ]; - s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ]; - s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ]; - s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ]; - s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ]; - s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ]; - s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ]; - s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ]; - s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ]; - s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ]; - s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ]; - s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ]; - s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ]; - s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ]; - s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ]; - s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ]; - s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ]; - s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ]; - s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ]; - s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ]; - c0=[1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, ]; - c1=[-1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, ]; - - else - s(1,:)=[1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, ]; - s(2,:)=[1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, ]; - s(3,:)=[1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, ]; - s(4,:)=[1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, ]; - s(5,:)=[-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, ]; - s(6,:)=[1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, ]; - s(7,:)=[1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, ]; - s(8,:)=[-1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, ]; - s(9,:)=[1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, ]; - s(10,:)=[-1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, ]; - s(11,:)=[-1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, ]; - s(12,:)=[1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, ]; - s(13,:)=[1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, ]; - s(14,:)=[-1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, ]; - s(15,:)=[-1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, ]; - s(16,:)=[-1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, ]; - s(17,:)=[-1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, ]; - s(18,:)=[-1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, ]; - s(19,:)=[1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, ]; - s(20,:)=[1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, ]; - s(21,:)=[1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, ]; - s(22,:)=[-1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, ]; - s(23,:)=[-1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, ]; - s(24,:)=[1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, ]; - s(25,:)=[-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, ]; - s(26,:)=[-1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, ]; - s(27,:)=[-1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, ]; - s(28,:)=[1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, ]; - s(29,:)=[-1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, ]; - s(30,:)=[1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, ]; - s(31,:)=[-1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, ]; - c0=[1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, ]; - c1=[1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, ]; - - end - -end - diff --git a/matlab/tests/pbch_bler.m b/matlab/tests/pbch_bler.m deleted file mode 100644 index ed67da4ff..000000000 --- a/matlab/tests/pbch_bler.m +++ /dev/null @@ -1,130 +0,0 @@ -clear - -Nblock=[3]; -SNR_values_db=100;%linspace(-4,0,6); -Nrealizations=1; -enb = struct('NCellID',62,'NDLRB',50,'CellRefP',2,'CyclicPrefix','Normal','DuplexMode','FDD',... - 'NSubframe',0,'PHICHDuration','Normal','Ng','One','NFrame',101,'TotSubframes',40); - -cfg.Seed = 8; % 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 - -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 = 'Centered'; % Interpolation window type -cec.InterpWinSize = 1; % Interpolation window size - -griddims = lteResourceGridSize(enb); % Resource grid dimensions -L = griddims(2); - -% Generate signal -mib = lteMIB(enb); -bchCoded = lteBCH(enb,mib); -mibCRC = lteCRCEncode(mib,'16'); -mibCoded = lteConvolutionalEncode(mibCRC); -pbchSymbolsTx = ltePBCH(enb,bchCoded); -pbchIndtx = ltePBCHIndices(enb); -subframe_tx = lteDLResourceGrid(enb); -rs = lteCellRS(enb); -rsind = lteCellRSIndices(enb); -subframe_tx(rsind)=rs; - -NofPortsTx=enb.CellRefP; - -addpath('../../build/srslte/lib/phch/test') - -txWaveform=cell(length(Nblock)); -rxWaveform=cell(length(Nblock)); -for n=1:length(Nblock) - subframe_tx2=subframe_tx; - subframe_tx2(pbchIndtx)=pbchSymbolsTx(Nblock(n)*240+1:(Nblock(n)+1)*240,:); - [txWaveform{n},info] = lteOFDMModulate(enb, subframe_tx2, 0); - cfg.SamplingRate = info.SamplingRate; -end - -error=zeros(length(SNR_values_db),2); -for snr_idx=1:length(SNR_values_db) - SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB - SNR = 10^(SNRdB/10); % Linear SNR - - errorReal = zeros(Nrealizations,2); - for i=1:Nrealizations - - for n=1:length(Nblock) - - %rxWaveform = lteFadingChannel(cfg,sum(txWaveform,2)); - rxWaveform{n} = sum(txWaveform{n},2); - - %% Additive Noise - N0 = 1/(sqrt(2.0*double(enb.CellRefP)*double(info.Nfft))*SNR); - - % Create additive white Gaussian noise - noise = N0*complex(randn(size(rxWaveform{n})),randn(size(rxWaveform{n}))); - - rxWaveform{n} = noise + rxWaveform{n}; - - % Number of OFDM symbols in a subframe - % OFDM demodulate signal - rxgrid = lteOFDMDemodulate(enb, rxWaveform{n}, 0); - - % Perform channel estimation - %enb.CellRefP=2; - [hest, nest] = lteDLChannelEstimate(enb, cec, rxgrid(:,1:L,:)); - - pbchIndices = ltePBCHIndices(enb); - [pbchRx, pbchHest] = lteExtractResources(pbchIndices, rxgrid(:,1:L,:), ... - hest(:,1:L,:,:)); - - % Decode PBCH - [bchBits, pbchSymbols, nfmod4, mib, nof_ports] = ltePBCHDecode(enb, pbchRx, pbchHest, nest); - - if (nof_ports ~= NofPortsTx) - errorReal(i,1)=1; - end - end - - %enb.CellRefP=NofPortsTx; - [nof_ports2, pbchSymbols2, pbchBits, ce, ce2, pbchRx2, pbchHest2, mod2, codedbits]= ... - srslte_pbch(enb, rxWaveform); - - subplot(2,1,1) - plot(abs((bchCoded(1:960)>0)-(pbchBits(1:960)>0))) - subplot(2,1,2) - codedbits2 = reshape(reshape(codedbits,3,[])',1,[]); - plot(abs((codedbits2'>0)-(mibCoded>0))) - - %decodedData = lteConvolutionalDecode(noisysymbols); - %[decodedData2, quant] = srslte_viterbi(interleavedSymbols); - - if (nof_ports2 ~= NofPortsTx) - errorReal(i,2)=1; - end - end - error(snr_idx,:) = sum(errorReal); - fprintf('SNR: %.2f dB\n', SNR_values_db(snr_idx)); -end - -if (length(SNR_values_db) > 1) - semilogy(SNR_values_db, error/Nrealizations) - grid on - xlabel('SNR (dB)'); - ylabel('BLER') - legend('Matlab','srsLTE') - axis([min(SNR_values_db) max(SNR_values_db) 1/Nrealizations/10 1]) -else - disp(error) - disp(nfmod4) - disp(mod2) -end - diff --git a/matlab/tests/pdcch_bler.m b/matlab/tests/pdcch_bler.m deleted file mode 100644 index d63883b7d..000000000 --- a/matlab/tests/pdcch_bler.m +++ /dev/null @@ -1,189 +0,0 @@ - -%% PDCCH Blind Search and DCI Decoding + PCFICH encoding/decoding - -%% Cell-Wide Settings -% A structure |enbConfig| is used to configure the eNodeB. -clear - -Npackets = 60; -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.Ng = 'One'; % HICH groups -enbConfig.CellRefP = 1; % 1-antenna ports -enbConfig.NCellID = 0; % Physical layer cell identity -enbConfig.NSubframe = 5; % Subframe number 0 -enbConfig.DuplexMode = 'FDD'; % Frame structure -enbConfig.PHICHDuration = 'Normal'; -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 = '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 - -% 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 - -%% DCI Message Generation -% Generate a DCI message to be mapped to the PDCCH. - -dciConfig.DCIFormat = 'Format1A'; % DCI message format -dciConfig.Allocation.RIV = 26; % Resource indication value - -% Create DCI message for given configuration -[dciMessage, dciMessageBits] = lteDCI(enbConfig, dciConfig); - -%% DCI Channel Coding - -% Do not include RNTI if Common Search space -if C_RNTI<65535 - pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier -end -pdcchConfig.PDCCHFormat = 3; % PDCCH format -ueConfig.RNTI = C_RNTI; - -candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'}); - -% Include now RNTI in pdcch -pdcchConfig.RNTI = C_RNTI; - -% DCI message bits coding to form coded DCI bits -codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits); - -%% PDCCH Bits Generation - -pdcchDims = ltePDCCHInfo(enbConfig); - -% Initialize elements with -1 to indicate that all the bits are unused -pdcchBitsTx = -1*ones(pdcchDims.MTot, 1); - - -Ncad=1; - -% Map PDCCH payload on available UE-specific candidate. In this example the -% first available candidate is used to map the coded DCI bits. -pdcchBitsTx ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits; - -%% PDCCH Complex-Valued Modulated Symbol Generation - -pdcchSymbolsTx = ltePDCCH(enbConfig, pdcchBitsTx); -pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'}); -subframe_tx = lteDLResourceGrid(enbConfig); -subframe_tx(pdcchIndices) = pdcchSymbolsTx; - -%% PCFICH -cfiCodeword = lteCFI(enbConfig); -pcfichSymbols = ltePCFICH(enbConfig,cfiCodeword); -pcfichIndices = ltePCFICHIndices(enbConfig,'1based'); -subframe_tx(pcfichIndices) = pcfichSymbols; - -%% Add references -cellRsSym = lteCellRS(enbConfig); -cellRsInd = lteCellRSIndices(enbConfig); -subframe_tx(cellRsInd) = cellRsSym; - -[txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx); -cfg.SamplingRate = info.SamplingRate; - -addpath('../../build/srslte/lib/phch/test') - -decoded = zeros(size(SNR_values)); -decoded_cfi = zeros(size(SNR_values)); -decoded_srslte = zeros(size(SNR_values)); -decoded_cfi_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*enbConfig.CellRefP*double(info.Nfft))*SNR); - for i=1:Npackets - - enbConfigRx=enbConfig; - - rxWaveform = sum(txWaveform,2); - - %% Fading - rxWaveform = lteFadingChannel(cfg,rxWaveform); - - %% Noise Addition - noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise - rxWaveform = rxWaveform + noise; - - %% Demodulate - subframe_rx = lteOFDMDemodulate(enbConfigRx, rxWaveform); - - % Perform channel estimation - [hest, nest] = lteDLChannelEstimate(enbConfigRx, cec, subframe_rx); - - [pcfichSymbolsRx, pcfichSymbolsHest] = lteExtractResources(pcfichIndices(:,1), subframe_rx, hest); - - %% PCFICH decoding - [pcfichBits, pcfichSymbols] = ltePCFICHDecode(enbConfigRx,pcfichSymbolsRx, pcfichSymbolsHest, nest); - rxCFI = lteCFIDecode(pcfichBits); - - decoded_cfi(snr_idx) = decoded_cfi(snr_idx) + (rxCFI == txCFI); - - %% PDCCH Decoding - enbConfigRx.CFI = rxCFI; - pdcchIndicesRx = ltePDCCHIndices(enbConfigRx,{'1based'}); - [pdcchRx, pdcchHest] = lteExtractResources(pdcchIndicesRx(:,1), subframe_rx, hest); - [pdcchBits, pdcchSymbols] = ltePDCCHDecode(enbConfigRx, pdcchRx, pdcchHest, nest); - - %% Blind Decoding using DCI Search - [rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfigRx, ueConfig, pdcchBits); - decoded(snr_idx) = decoded(snr_idx) + (length(rxDCI)>0); - - %% 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 = 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 - fprintf('SNR: %.1f\n',SNRdB) -end - -if (Npackets>1) - semilogy(SNR_values,1-decoded/Npackets,'bo-',... - SNR_values,1-decoded_cfi/Npackets,'bx:',... - SNR_values,1-decoded_srslte/Npackets, 'ro-',... - SNR_values,1-decoded_cfi_srslte/Npackets,'rx:') - grid on - legend('Matlab all','Matlab cfi', 'srsLTE all', 'srsLTE cfi') - xlabel('SNR (dB)') - ylabel('BLER') - axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1]) -else - - n=min(length(pdcchSymbols),length(pdcchSymbols2)); - subplot(2,1,1) - plot(abs(pdcchSymbols(1:n)-pdcchSymbols2(1:n))) - n=min(length(pdcchBits),length(pdcchBits2)); - subplot(2,1,2) - pdcchBitsTx(pdcchBitsTx==-1)=0; - plot(abs((pdcchBitsTx(1:n)>0.1)-(pdcchBits2(1:n)>0.1))) - - subplot(1,1,1) - plot(1:180,real(hest(:,1,1,1)),1:180,real(hest2(1:180))) - - disp(decoded) - disp(decoded_srslte) -end - diff --git a/matlab/tests/pdsch_bler.m b/matlab/tests/pdsch_bler.m deleted file mode 100644 index 4efc17348..000000000 --- a/matlab/tests/pdsch_bler.m +++ /dev/null @@ -1,108 +0,0 @@ -%% Plot PDSCH BLER vs SNR for PDSCH without equalization -clear -transportBlkSize=75376; -modulation='64QAM'; -rvValues=[0 2 3 1]; -SNR=linspace(-2.9,-2.0,8); -Nblocks=30; - -addpath('../../build/srslte/lib/phch/test') - -% Subframe configuration -enbConfig.NCellID = 100; -enbConfig.CyclicPrefix = 'Normal'; -enbConfig.NSubframe = 1; -enbConfig.CellRefP = 1; -enbConfig.NDLRB = 100; -enbConfig.CFI = 1; -enbConfig.DuplexMode='FDD'; - -% Transmission mode configuration for PDSCH -pdschConfig.NLayers = 1; -pdschConfig.TxScheme = 'Port0'; -pdschConfig.Modulation = {modulation}; -pdschConfig.RNTI = 100; -pdschConfig.NTurboDecIts = 5; -pdschConfig.PRBSet = (0:enbConfig.NDLRB-1)'; - -switch (modulation) - case 'QPSK' - bitsPerSym = 2; - case '16QAM' - bitsPerSym = 4; - case '64QAM' - bitsPerSym = 6; -end -noiseVarfactor = sqrt(2*bitsPerSym); -snr = 10.^(SNR/10); - -nErrors_mat = zeros(length(SNR),length(rvValues)); -nErrors_srs = zeros(length(SNR),length(rvValues)); - -for k = 1:length(SNR); - subframe=cell(length(rvValues)); - pdschIdx=ltePDSCHIndices(enbConfig,pdschConfig,pdschConfig.PRBSet); - for i=1:length(rvValues) - subframe{i} = lteDLResourceGrid(enbConfig); - end - blkCounter = 0; - for l = 1:Nblocks; - % DL-SCH data bits - dlschBits = randi([0 1],transportBlkSize,1); - softBuffer = {}; - for rvIndex = 1:length(rvValues) - % DLSCH transport channel - pdschConfig.RV = rvValues(rvIndex); - pdschPayload = lteDLSCH(enbConfig, pdschConfig, length(pdschIdx)*bitsPerSym, dlschBits); - - % PDSCH modulated symbols - pdschSymbols = ltePDSCH(enbConfig, pdschConfig, pdschPayload); - pdschSize = size(pdschSymbols); - - % Addition of noise - noise = (1/noiseVarfactor)*sqrt(1/snr(k))*complex(randn(pdschSize),randn(pdschSize)); - noisySymbols = pdschSymbols + noise; - - subframe{rvIndex}(pdschIdx)=noisySymbols; - - % PDSCH Rx-side - rxCW = ltePDSCHDecode(enbConfig, pdschConfig, noisySymbols); - - % DL-SCH turbo decoding - [rxBits, blkCRCerr, softBuffer] = lteDLSCHDecode(enbConfig, pdschConfig, transportBlkSize, rxCW{1}, softBuffer); - - % Add errors to previous error counts - nErrors_mat(k,rvIndex) = nErrors_mat(k,rvIndex)+blkCRCerr; - end - - % Same with srsLTE - [okSRSLTE, data, pdschRx, pdschSymbols, cws] = srslte_pdsch(enbConfig, pdschConfig, ... - transportBlkSize, subframe, ones(size(subframe{1})), 0); - - nErrors_srs(k,rvIndex) = nErrors_srs(k,rvIndex)+~okSRSLTE; - end - fprintf('SNR=%.1f dB, BLER_mat=%f, BLER_srs=%f\n',SNR(k),nErrors_mat(k,rvIndex)/Nblocks, nErrors_srs(k,rvIndex)/Nblocks); -end - -PDSCHBLER_MAT = nErrors_mat./Nblocks; -PDSCHBLER_MAT(PDSCHBLER_MAT==0)=10^-10; - -PDSCHBLER_SRS = nErrors_srs./Nblocks; -PDSCHBLER_SRS(PDSCHBLER_SRS==0)=10^-10; - -if (Nblocks == 1 && length(SNR) == 1) -else - semilogy(SNR,PDSCHBLER_MAT,SNR,PDSCHBLER_SRS) - grid on - xlabel('Eb/No (dB)') - ylabel('BLER') - leg=[]; - for rvIndex = 1:length(rvValues) - leg=strvcat(leg,sprintf('Matlab rv=%d',rvValues(rvIndex))); - end - for rvIndex = 1:length(rvValues) - leg=strvcat(leg,sprintf('srsLTE rv=%d',rvValues(rvIndex))); - end - legend(leg); - axis([min(SNR) max(SNR) 10^-4 1]) -end diff --git a/matlab/tests/pdsch_decode_signal.m b/matlab/tests/pdsch_decode_signal.m deleted file mode 100644 index 72b733eb5..000000000 --- a/matlab/tests/pdsch_decode_signal.m +++ /dev/null @@ -1,76 +0,0 @@ -enb=struct('NCellID',313,'NDLRB',75,'NSubframe',5,'CFI',1,'CyclicPrefix','Normal','CellRefP',2,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); - -RNTI=65535; - -addpath('../../build/srslte/lib/phch/test') - -cec.PilotAverage = 'UserDefined'; % Type of pilot averaging -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,x); -subframe_rx=reshape(x,[],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, dcidecBits] = 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 = 16; - %pdsch.Modulation = {'64QAM'}; - pdsch.RV=0; - 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, pdschRx, pdschHest, 0); - [sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits); - - - [dec2, data, pdschRx2, pdschSymbols2, e_bits, ce] = srslte_pdsch(enb, pdsch, ... - trblklen, ... - subframe_rx); - - - subplot(2,1,1) - scatter(real(pdschSymbols{1}),imag(pdschSymbols{1})) - subplot(2,1,2) - scatter(real(pdschSymbols2),imag(pdschSymbols2)) - - if crc == 0 - fprintf('PDSCH Matlab OK.\n\n'); - else - fprintf('PDSCH Matlab ERROR.\n\n'); - end - - if dec2 == 1 - fprintf('PDSCH srsLTE OK.\n\n'); - else - fprintf('PDSCH srsLTE 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)) - \ No newline at end of file diff --git a/matlab/tests/pdsch_equal.m b/matlab/tests/pdsch_equal.m deleted file mode 100644 index 1ad1d86dc..000000000 --- a/matlab/tests/pdsch_equal.m +++ /dev/null @@ -1,166 +0,0 @@ - -%% PDSCH decoding based on RMC channels - -%% Cell-Wide Settings -% A structure |enbConfig| is used to configure the eNodeB. -%clear12 - -recordedSignal=[]; - -Npackets = 1; -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.5',[1;0;0;1]); -waveform = sum(waveform,2); - -if ~isempty(recordedSignal) - 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'; - 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 = 2; - -%% 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 = 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 - -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, 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 - 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] = lteDLChannelEstimate(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, ce] = 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 - subplot(2,1,1) - scatter(real(pdschSymbols2),imag(pdschSymbols2)) - %plot(real(hest)) - subplot(2,1,2) - %plot(1:180,angle(ce(1:180)),1:180,angle(hest(:,1))) - plot(abs(ce-hest(:))) - fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); -end - diff --git a/matlab/tests/pdsch_resalloc.m b/matlab/tests/pdsch_resalloc.m deleted file mode 100644 index d274c0c99..000000000 --- a/matlab/tests/pdsch_resalloc.m +++ /dev/null @@ -1,76 +0,0 @@ -filename='../../debug/dist_ra.dat'; - -enb.NDLRB = 50; -enb.CyclicPrefix = 'Normal'; -enb.PHICHDuration = 'Normal'; -enb.CFI = 2; -enb.Ng = 'Sixth'; -enb.CellRefP = 1; -enb.NCellID = 196; -enb.NSubframe = 5; -enb.NTotalSubframes=1; -enb.DuplexMode = 'FDD'; - -dci.NDLRB = enb.NDLRB; -dci.DCIFormat = 'SRSLTE_DCI_FORMAT1C'; -dci.AllocationType=1; -%dci.Allocation.Bitmap='01111000011110000'; -%dci.Allocation.Subset=3; -dci.Allocation.RIV = 33; -dci.Allocation.Gap = 0; -dci.ModCoding=6; -dci.RV=0; -dci.DuplexMode = enb.DuplexMode; -dci.NTxAnts = enb.CellRefP; -pdcch.RNTI = 65535; -pdcch.PDCCHFormat = 3; - -pdsch.Modulation='QPSK'; -pdsch.RNTI=pdcch.RNTI; -if (enb.CellRefP == 1) - pdsch.TxScheme='Port0'; -else - pdsch.TxScheme='TxDiversity'; -end -pdsch.NLayers=enb.CellRefP; -pdsch.trblklen=176; -pdsch.RV=dci.RV; - -% Begin frame generation -subframe = lteDLResourceGrid(enb); - -%%% Create Reference Signals -rsAnt = lteCellRS(enb); -indAnt = lteCellRSIndices(enb); -subframe(indAnt) = rsAnt; - -%%% Create PDCCH -[dciMessage,dciMessageBits] = lteDCI(enb,dci); -codedDciBits = lteDCIEncode(pdcch,dciMessageBits); -pdcchInfo = ltePDCCHInfo(enb); -pdcchBits = -1*ones(1,pdcchInfo.MTot); -candidates = ltePDCCHSpace(enb,pdcch,{'bits','1based'}); -pdcchBits (candidates(1,1):candidates(1,2)) = codedDciBits; -pdcchSymbols = ltePDCCH(enb, pdcchBits); -pdcchIndices = ltePDCCHIndices(enb,{'1based'}); -subframe(pdcchIndices) = pdcchSymbols; - -% Create PDSCH -pdsch.prbset = lteDCIResourceAllocation(enb,dci); - -[pdschIndices,pdschInfo] = ltePDSCHIndices(enb,pdsch,pdsch.prbset); - -dlschTransportBlk=randi([0 1],pdsch.trblklen,1); -pdschcodeword = lteDLSCH(enb,pdsch,pdschInfo.G,dlschTransportBlk); -%crced = lteCRCEncode(dlschTransportBlk, '24A'); -%encoded = lteTurboEncode(crced); -%pdschcodeword2 = lteRateMatchTurbo(encoded,pdschInfo.G,pdsch.RV); -pdschSymbols = ltePDSCH(enb,pdsch,pdschcodeword); - -subframe(pdschIndices) = pdschSymbols; - -txwaveform = lteOFDMModulate(enb,subframe); - -write_complex(filename,sum(txwaveform,2)); -fprintf('Written signal to %s\n',filename); - diff --git a/matlab/tests/pdsch_test_verify_unrm.m b/matlab/tests/pdsch_test_verify_unrm.m deleted file mode 100644 index 3f32c7466..000000000 --- a/matlab/tests/pdsch_test_verify_unrm.m +++ /dev/null @@ -1,39 +0,0 @@ -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) - diff --git a/matlab/tests/phich_bler.m b/matlab/tests/phich_bler.m deleted file mode 100644 index 723c8b572..000000000 --- a/matlab/tests/phich_bler.m +++ /dev/null @@ -1,132 +0,0 @@ -clear - -%% PHICH encoding/decoding - -%% Setup simulation -Npackets = 80; -SNR_values = linspace(-6,0,6); -enable_fading=false; -addpath('../../debug/srslte/lib/phch/test') - - -%% Cell-Wide Settings -enbConfig.NDLRB = 50; % No of Downlink RBs in total BW -enbConfig.CyclicPrefix = 'Normal'; % CP length -enbConfig.Ng = 'One'; % HICH groups -enbConfig.CellRefP = 1; % 1-antenna ports -enbConfig.NCellID = 36; % Physical layer cell identity -enbConfig.NSubframe = 5; % Subframe number 0 -enbConfig.DuplexMode = 'FDD'; % Frame structure -enbConfig.PHICHDuration = 'Normal'; - -%% Define HI resource -hi_res = [1 1]; -ack_bit = 1; - -%% Setup Fading channel model -if (enable_fading) - cfg.Seed = 8; % 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 -end - -% 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 - -%% Generate TX subframe -subframe_tx = lteDLResourceGrid(enbConfig); - -%% Genearte PHICH signal -hi_sym_tx = ltePHICH(enbConfig, [hi_res ack_bit]); -hi_indices = ltePHICHIndices(enbConfig); -subframe_tx(hi_indices)=hi_sym_tx; - -%% Add references to subframe -cellRsSym = lteCellRS(enbConfig); -cellRsInd = lteCellRSIndices(enbConfig); -subframe_tx(cellRsInd) = cellRsSym; - -%% Modulate signal -[txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx); -cfg.SamplingRate = info.SamplingRate; - -%% Start simulation -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*enbConfig.CellRefP*double(info.Nfft))*SNR); - for i=1:Npackets - - %% Fading - rxWaveform = sum(txWaveform,2); - if (enable_fading) - rxWaveform = lteFadingChannel(cfg,rxWaveform); - end - - %% Noise Addition - noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); - rxWaveform = rxWaveform + noise; - - %% Demodulate - subframe_rx = lteOFDMDemodulate(enbConfig, rxWaveform); - - %% Channel estimation - if (enable_fading) - [hest, nest] = lteDLChannelEstimate(enbConfig, cec, subframe_rx); - else - hest=ones(size(subframe_rx)); - nest=0; - end - - %% Extract resources - phichSymbolsRx = subframe_rx(hi_indices); - phichSymbolsHest = hest(hi_indices); - - %% PHICH decoding - [hi, hi_symbols] = ltePHICHDecode(enbConfig,hi_res, phichSymbolsRx, phichSymbolsHest, nest); - decoded(snr_idx) = decoded(snr_idx) + (hi == ack_bit); - - %% Same with srsLTE - [hi_srslte, hi_symbols_srslte] = srslte_phich(enbConfig, hi_res, subframe_rx, hest, nest); - decoded_srslte(snr_idx) = decoded_srslte(snr_idx) + (hi_srslte == ack_bit); - end - fprintf('SNR: %.1f\n',SNRdB) -end - -if (Npackets>1) - semilogy(SNR_values,1-decoded/Npackets,'bo-',... - SNR_values,1-decoded_srslte/Npackets, 'ro-') - grid on - legend('Matlab','srsLTE') - xlabel('SNR (dB)') - ylabel('BLER') - axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1]) -else - - scatter(real(hi_symbols),imag(hi_symbols)) - hold on - scatter(real(hi_symbols_srslte),imag(hi_symbols_srslte)) - hold off - grid on; - axis([-2 2 -2 2]) - disp(hi) - disp(hi_srslte) - -end - diff --git a/matlab/tests/prach_detect_test.m b/matlab/tests/prach_detect_test.m deleted file mode 100644 index 51bda6c21..000000000 --- a/matlab/tests/prach_detect_test.m +++ /dev/null @@ -1,200 +0,0 @@ -%% PRACH Detection Conformance Test -%clear - -d=80;%linspace(4,14,6); -pDetection2 = zeros(2,length(d)); -for dd=1:length(d) -detect_factor=d(dd); - -numSubframes = 1; % Number of subframes frames to simulate at each SNR -SNRdB = 50;%linspace(-14,10,8); % SNR points to simulate -foffset = 0.0; % Frequency offset in Hertz -delay=0; -add_fading=false; - -addpath('../../build/srslte/lib/phch/test') - -%% UE Configuration -% User Equipment (UE) settings are specified in the structure |ue|. - -ue.NULRB = 15; % 6 Resource Blocks -ue.DuplexMode = 'FDD'; % Frequency Division Duplexing (FDD) -ue.CyclicPrefixUL = 'Normal'; % Normal cyclic prefix length -ue.NTxAnts = 1; % Number of transmission antennas - -%% PRACH Configuration - -prach.Format = 0; % PRACH format: TS36.104, Table 8.4.2.1-1 -prach.HighSpeed = 0; % Normal mode: TS36.104, Table 8.4.2.1-1 -prach.FreqOffset = 2; % Default frequency location -info = ltePRACHInfo(ue, prach); % PRACH information - -%% Propagation Channel Configuration -% Configure the propagation channel model using a structure |chcfg| as per -% TS36.104, Table 8.4.2.1-1 [ <#9 1> ]. - -chcfg.NRxAnts = 1; % Number of receive antenna -chcfg.DelayProfile = 'ETU'; % Delay profile -chcfg.DopplerFreq = 70.0; % Doppler frequency -chcfg.MIMOCorrelation = 'Low'; % MIMO correlation -chcfg.Seed = 1; % Channel seed -chcfg.NTerms = 16; % Oscillators used in fading model -chcfg.ModelType = 'GMEDS'; % Rayleigh fading model type -chcfg.InitPhase = 'Random'; % Random initial phases -chcfg.NormalizePathGains = 'On'; % Normalize delay profile power -chcfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas -chcfg.SamplingRate = info.SamplingRate; % Sampling rate - -%% Loop for SNR Values - -% Initialize the random number generator stream -rng('default'); - -% Initialize variables storing probability of detection at each SNR -pDetection = zeros(2,length(SNRdB)); - -for nSNR = 1:length(SNRdB) - - % Scale noise to ensure the desired SNR after SC-FDMA demodulation - ulinfo = lteSCFDMAInfo(ue); - SNR = 10^(SNRdB(nSNR)/20); - N = 1/(SNR*sqrt(double(ulinfo.Nfft)))/sqrt(2.0); - - % Detected preamble count - detectedCount = 0; - detectedCount_srs = 0; - - % Loop for each subframe - for nsf = 1:numSubframes - - prach.SeqIdx = 41;%randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1 - prach.CyclicShiftIdx = 11;%randi(16,1,1)-1; % Cyclic shift index: TS36.141, Table A.6-1 - prach.PreambleIdx = 1;%randi(64,1,1)-1; % Preamble index: TS36.141, Table A.6-1 - prach.TimingOffset = 0; - info = ltePRACHInfo(ue, prach); % PRACH information - - % PRACH transmission - ue.NSubframe = mod(nsf-1, 10); - ue.NFrame = fix((nsf-1)/10); - - % Set PRACH timing offset in us as per TS36.141, Figure 8.4.1.4.2-2 - %prach.TimingOffset = info.BaseOffset + ue.NSubframe/10.0; - prach.TimingOffset = 0; - - % Generate transmit wave - [txwave,prachinfo] = ltePRACH(ue, prach); - - % Channel modeling - if (add_fading) - chcfg.InitTime = (nsf-1)/1000; - [rxwave, fadinginfo] = lteFadingChannel(chcfg, ... - [txwave; zeros(25, 1)]); - else - rxwave = txwave; - end - % Add noise - %noise = N*complex(randn(size(rxwave)), randn(size(rxwave))); - %rxwave = rxwave + noise; - % Remove the implementation delay of the channel modeling - if (add_fading) - rxwave = rxwave((fadinginfo.ChannelFilterDelay + 1):end, :); - end - - rxwave=lteFrequencyCorrect(ue, x, -20); - % rxwave=[zeros(delay,1); txwave(1:end-delay)]; - - % Apply frequency offset - t = ((0:size(rxwave, 1)-1)/chcfg.SamplingRate).'; - rxwave = rxwave .* repmat(exp(1i*2*pi*foffset*t), ... - 1, size(rxwave, 2)); - - - % PRACH detection for all cell preamble indices - [detected, offsets] = ltePRACHDetect(ue, prach, rxwave, (0:63).'); - - [detected_srs, offsets_srs, corrout] = srslte_prach_detect(ue, prach, rxwave, detect_factor); - - disp(detected) - disp(detected_srs) - disp(offsets_srs*1e6) - - % Test for preamble detection - if (length(detected)==1) - - % Test for correct preamble detection - if (detected==prach.PreambleIdx) - - % Calculate timing estimation error. The true offset is - % PRACH offset plus channel delay - trueOffset = prach.TimingOffset/1e6 + 310e-9; - measuredOffset = offsets(1)/chcfg.SamplingRate; - timingerror = abs(measuredOffset-trueOffset); - - % Test for acceptable timing error - if (timingerror<=2.08e-6) - detectedCount = detectedCount + 1; % Detected preamble - else - disp('Timing error'); - end - else - disp('Detected incorrect preamble'); - end - else - disp('Detected multiple or zero preambles'); - end - - % Test for preamble detection - if (length(detected_srs)==1) - - % Test for correct preamble detection - if (detected_srs==prach.PreambleIdx) - - % Calculate timing estimation error. The true offset is - % PRACH offset plus channel delay - trueOffset = prach.TimingOffset/1e6 + 310e-9; - measuredOffset = offsets_srs(1); - timingerror = abs(measuredOffset-trueOffset); - - % Test for acceptable timing error - if (timingerror<=2.08e-6) - detectedCount_srs = detectedCount_srs + 1; % Detected preamble - else - disp('SRS: Timing error'); - end - else - disp('SRS: Detected incorrect preamble'); - end - else - fprintf('SRS: Detected %d preambles. D=%.1f, Seq=%3d, NCS=%2d, Idx=%2d\n', ... - length(detected_srs),detect_factor, prach.SeqIdx, prach.CyclicShiftIdx, prach.PreambleIdx); - end - - - end % of subframe loop - - % Compute final detection probability for this SNR - pDetection(1,nSNR) = detectedCount/numSubframes; - pDetection(2,nSNR) = detectedCount_srs/numSubframes; - -end % of SNR loop - -pDetection2(1,dd)=pDetection(1,1); -pDetection2(2,dd)=pDetection(2,1); -end -%% Analysis -if (length(SNRdB)>1) - plot(SNRdB, pDetection) - legend('Matlab','srsLTE') - grid on - xlabel('SNR (dB)') - ylabel('Pdet') -else - plot(d,pDetection2) - legend('Matlab','srsLTE') - grid on - xlabel('d') - ylabel('Pdet') - fprintf('Pdet=%.4f%%, Pdet_srs=%.4f%%\n',pDetection(1,nSNR),pDetection(2,nSNR)) -end - -plot(corrout) diff --git a/matlab/tests/prach_falsealarm_test.m b/matlab/tests/prach_falsealarm_test.m deleted file mode 100644 index 48ccc533b..000000000 --- a/matlab/tests/prach_falsealarm_test.m +++ /dev/null @@ -1,83 +0,0 @@ -%% PRACH False Alarm Probability Conformance Test -clear - -detect_factor=5; - -ue.NULRB = 6; % Number of resource blocks -ue.DuplexMode = 'FDD'; % FDD duplexing mode - -%% PRACH Configuration -prach.Format = 0; % Preamble format -prach.SeqIdx = 2; % Logical root sequence index -prach.CyclicShiftIdx = 1; % Cyclic shift configuration index -prach.HighSpeed = 0; % High speed flag -prach.FreqOffset = 0; % Use default frequency resource index -prach.PreambleIdx = []; % Empty since no preamble is transmitted - -%% Establish PRACH Generator Output Length for this Configuration -info = ltePRACHInfo(ue, prach); -nSamples = info.SamplingRate*info.TotSubframes*0.001; - -%% Loop for Detection in Each Subframe -numTrials = 2000; -falseCount = 0; % Initialize false detection counter -falseCount_srs = 0; % Initialize false detection counter -rng('default'); % Random number generator to default state - -runningP=zeros(1, numTrials); -runningP_srs=zeros(1, numTrials); -for nt = 1:numTrials - - % Create noise - noise = complex(randn(nSamples, 1), randn(nSamples, 1)); - - % Attempt detection for all cell preamble indices (0...63) - [detected,offset] = ltePRACHDetect(ue, prach, noise, 0:63); - [detected_srs] = srslte_prach_detect(ue, prach, noise, detect_factor); - - % Record false alarm - if (~isempty(detected)) - falseCount = falseCount+1; - end - - if (~isempty(detected_srs)) - falseCount_srs = falseCount_srs+1; - end - - % Calculate running false alarm probability - runningP(nt) = falseCount/nt*100; - runningP_srs(nt) = falseCount_srs/nt*100; - - % Plot information about false alarm (if applicable) - if (~isempty(detected)) - plot(nt,runningP(nt),'ro','LineWidth',2,'MarkerSize',7); - hold on; - text(nt,runningP(nt), sprintf(['Preamble index = %d' ... - ' \nTiming offset = %0.2f samples '],detected,offset), ... - 'HorizontalAlignment','right'); - end - - if (~isempty(detected_srs)) - plot(nt,runningP(nt),'mx','LineWidth',2,'MarkerSize',7); - hold on; - text(nt,runningP(nt), sprintf(['SRS index = %d' ... - ' \nTiming offset = %0.2f samples '],detected,offset), ... - 'HorizontalAlignment','right'); - end - -end - -%% Compute Final False Alarm Probability - -P = falseCount / numTrials; -P_srs = falseCount_srs / numTrials; -plot(1:numTrials,runningP,'b','LineWidth',2); -plot(1:numTrials,runningP_srs,'k','LineWidth',2); -hold off -axis([0 numTrials+1 -0.1 0.2]); -xlabel('Trials'); -ylabel('Running false alarm probability (%)'); -title('PRACH False Alarm Detection Probability'); - -fprintf('\nFalse alarm probability = %0.4f%% - %.04f%%\n',P*100, P_srs*100); - diff --git a/matlab/tests/prach_test.m b/matlab/tests/prach_test.m deleted file mode 100644 index 049fe1b2e..000000000 --- a/matlab/tests/prach_test.m +++ /dev/null @@ -1,51 +0,0 @@ -clear -ueConfig=struct('NULRB',6,'DuplexMode','FDD','CyclicPrefix','Normal'); -prachConfig=struct('Format',0,'SeqIdx',0,'PreambleIdx',0,'CyclicShiftIdx',0,'HighSpeed',0,'TimingOffset',0,'FreqIdx',0,'FreqOffset',8); - -addpath('../../build/srslte/lib/phch/test') - -NULRB=[100]; - -% FreqIdx, FreqOffset and TimeOffset need to be tested - -for n_rb=1:length(NULRB) - for format=0; - for seqIdx=7:17:237 - for preambleIdx=0:23:63 - for CyclicShift=1:3:15 - fprintf('RB: %d, format %d, seqIdx: %d, Cyc=%d Idx=%d\n',NULRB(n_rb),format,seqIdx, CyclicShift, preambleIdx); - %for hs=0:1 - hs=0; - ueConfig.NULRB=NULRB(n_rb); - prachConfig.Format=format; - prachConfig.SeqIdx=seqIdx; - prachConfig.PreambleIdx=preambleIdx; - prachConfig.CyclicShiftIdx=CyclicShift; - prachConfig.HighSpeed=hs; - prachConfig.FreqIdx=0; - prachConfig.FreqOffset=0; - lib=srslte_prach(ueConfig,prachConfig); - - [mat, info]=ltePRACH(ueConfig,prachConfig); - err=max(abs(mat-lib)); - if (err > 2*10^-3) - disp(err) - a=1:100; - plot(a,real(lib(a)),a,real(mat(a))) - error('Error!'); - end - %end - end - end - end - end -end - -% -% disp(info) - n=1:length(mat); -% plot(abs(double(mat)-double(lib))) -flib=fft(lib(199:end),1536); -fmat=fft(mat(199:end),1536); -n=1:1536; -plot(n,real(flib(n)),n,real(fmat(n))) diff --git a/matlab/tests/print_m.m b/matlab/tests/print_m.m deleted file mode 100644 index 0aa456902..000000000 --- a/matlab/tests/print_m.m +++ /dev/null @@ -1,9 +0,0 @@ -fprintf('static uint8_t M_basis_seq_pucch[20][13]={\n'); -for i=1:20 - fprintf('\t\t{'); - for j=1:12 - fprintf('%d, ',y(i,j)); - end - fprintf('%d},\n',y(i,13)); -end -fprintf('\t\t};\n'); diff --git a/matlab/tests/pucch_bler.m b/matlab/tests/pucch_bler.m deleted file mode 100644 index 4bac59411..000000000 --- a/matlab/tests/pucch_bler.m +++ /dev/null @@ -1,133 +0,0 @@ -clear -ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); -pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2); - -format_str={'1','1a'}; - -threshold=[0.5 0]; -formats=[1]; -pucchConfig.ResourceIdx= 0; -pucchConfig.DeltaShift = 1; -pucchConfig.CyclicShifts = 0; -ueConfig.NSubframe=0; - -enable_fading=false; - -SNR_values=-5;%linspace(-8,0,8); -Nreal=50; - -% Setup Fading channel model -cfg.Seed = 8; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'EVA'; % 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 - -% Setup matlab 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('../../debug/srslte/lib/phch/test') - - -ber=zeros(length(formats),length(SNR_values)); -ber2=zeros(length(formats),length(SNR_values)); -for f=1:length(formats) - nb=formats(f); - for s=1:length(SNR_values) - SNRdB=SNR_values(s); - SNR = 10^(SNRdB/10); % Linear SNR - - errors = 0; - errors2 = 0; - for n=1:Nreal - bits=randi(2,nb-1,1)-1; - - [sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits); - idx=ltePUCCH1Indices(ueConfig,pucchConfig); - [dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig); - idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig); - - % Resource mapping - subframe_tx = lteULResourceGrid(ueConfig); - subframe_tx(idx)=sym_mat; - subframe_tx(idx_dmrs)=dmrs_mat; - - [txWaveform, info] = lteSCFDMAModulate(ueConfig,subframe_tx); - cfg.SamplingRate = info.SamplingRate; - - % Fading - if (enable_fading) - rxWaveform = lteFadingChannel(cfg,txWaveform); - else - rxWaveform = txWaveform; - end - - % Noise Addition - N0 = 1/(sqrt(2.0*double(info.Nfft))*SNR); - noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise - rxWaveform = rxWaveform + noise; - - % Demodulate - subframe_rx = lteSCFDMADemodulate(ueConfig, rxWaveform); - - % Perform channel estimation - [hest, nest] = lteULChannelEstimatePUCCH1(ueConfig, pucchConfig, cec, subframe_rx); - - % Equalize - pucchSymbols = lteEqualizeMMSE(subframe_rx(idx), hest(idx), nest); - - % Decoding - bits_rx = ltePUCCH1Decode(ueConfig, pucchConfig, length(bits), pucchSymbols); - - % Check errors - a=size(bits_rx); - if (a(2) ~= 1) - errors = errors + 1; - elseif (formats(f) == 2) - if (a(1) ~= 1) - errors = errors + 1; - elseif (bits_rx(1) ~= bits(1)) - errors = errors + 1; - end - end - - % Decoding srsLTE - [bits_rx,z,ce]= srslte_pucch(ueConfig, pucchConfig, length(bits), subframe_rx, threshold); - - % Check errors - a=size(bits_rx); - if (a(2) ~= 1) - errors2 = errors2 + 1; - elseif (formats(f) == 2) - if (a(1) ~= 1) - errors2 = errors2 + 1; - elseif (bits_rx(1) ~= bits(1)) - errors2 = errors2 + 1; - end - end - - end - ber(f,s)=errors/Nreal; - ber2(f,s)=errors2/Nreal; - fprintf('Format %s, SNR=%.1f dB, errors=%d, errors2=%d\n', format_str{formats(f)},SNRdB,errors,errors2); - end -end - -semilogy(SNR_values,ber,SNR_values,ber2) -xlabel('SNR (dB)') -ylabel('BER') -grid on -legend(format_str(formats)) - diff --git a/matlab/tests/pucch_test.m b/matlab/tests/pucch_test.m deleted file mode 100644 index a9e2bc4e6..000000000 --- a/matlab/tests/pucch_test.m +++ /dev/null @@ -1,79 +0,0 @@ -clear -ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); -pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2); - -addpath('../../build/srslte/lib/phch/test') - -format_str={'1','1a','1b','2','2a','2b'}; - -k=1; -for f=0:5 - for n=0:7:130 - for d=1:3 - for ncs=0:d:7 - for nsf=0:9 - pucchConfig.ResourceIdx= n; - pucchConfig.DeltaShift = d; - pucchConfig.CyclicShifts = ncs; - ueConfig.NSubframe=nsf; - if (f >= 3) - nb=20; - nb_ack=f-3; - else - nb=f; - nb_ack=0; - end - bits=mod(0:nb-1,2); - bits_ack=randi(2,nb_ack,1)-1; - fprintf('Testing PUCCH Format: %s, n_pucch=%d, DeltaShift=%d, CyclicShift=%d, Nsf=%d\n',format_str{f+1},n,d,ncs,nsf); - if (f >= 3) - [sym_mat, info]=ltePUCCH2(ueConfig,pucchConfig,bits); - idx=ltePUCCH2Indices(ueConfig,pucchConfig); - [dmrs_mat, info_dmrs]=ltePUCCH2DRS(ueConfig,pucchConfig,bits_ack); - idx_dmrs=ltePUCCH2DRSIndices(ueConfig,pucchConfig); - else - [sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits); - idx=ltePUCCH1Indices(ueConfig,pucchConfig); - [dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig); - idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig); - end - subframe_mat = lteULResourceGrid(ueConfig); - subframe_mat(idx)=sym_mat; - subframe_mat(idx_dmrs)=dmrs_mat; - - [sym, dmrs, subframe]=srslte_pucch_encode(ueConfig,pucchConfig,[bits; bits_ack]); - - error_sym=max(abs(sym-sym_mat)); - error_dmrs=max(abs(dmrs-dmrs_mat)); - error_sf=max(abs(subframe_mat(:)-subframe)); - k=k+1; - - if (error_sym > 1e-5) - disp(info) - plot(1:length(sym),sym,1:length(sym_mat),sym_mat) - legend('srsLTE','Matlab') - error('Error in symbols'); - end - if (error_dmrs > 1e-5) - disp(info_dmrs) - plot(angle(dmrs)-angle(dmrs_mat)) - error('Error in DMRS'); - end - if (error_sf > 1e-5) - disp(info) - plot(abs(subframe-subframe_mat(:))) - error('Error in subframe'); - end - end - end - end - end -end - -if (k == 2) - disp(info) - disp(error_sym) - disp(error_sf) - n=1:length(sym); - plot(n,real(sym(n)),n,real(sym_mat(n))) -end diff --git a/matlab/tests/pusch_bler.m b/matlab/tests/pusch_bler.m deleted file mode 100644 index 5286434b0..000000000 --- a/matlab/tests/pusch_bler.m +++ /dev/null @@ -1,188 +0,0 @@ -%% Plot PUSCH BLER vs SNR for PUSCH without equalization -clear -transportBlkSize=904; -modulation='64QAM'; -rvValues=0; -SNR=linspace(-5,0.0,8); -Nblocks=30; - -addpath('../../build/srslte/lib/phch/test') - -% Subframe configuration -ueConfig.NCellID = 100; -ueConfig.CyclicPrefixUL = 'Normal'; -ueConfig.NSubframe = 0; -ueConfig.NULRB = 6; -ueConfig.Shortened = 0; -ueConfig.NTxAnts = 1; -ueConfig.RNTI = 1; -ueConfig.DuplexMode='FDD'; -ueConfig.Hopping = 'Off'; -ueConfig.SeqGroup = 0; -ueConfig.CyclicShift = 0; -ueConfig.Shortened = 0; - -% Transmission mode configuration for PUSCH -puschConfig.NLayers = 1; -puschConfig.TxScheme = 'Port0'; -puschConfig.Modulation = modulation; -puschConfig.NTurboDecIts = 5; -puschConfig.PRBSet = (0:ueConfig.NULRB-1)'; -puschConfig.NBundled = 0; - -% Configure control channels -puschConfig.OCQI = 0; -puschConfig.ORI = 0; -puschConfig.OACK = 0; - -puschConfig.BetaCQI = 2; -puschConfig.BetaRI = 3; -puschConfig.BetaACK = 1; - -info=lteULSCHInfo(ueConfig,puschConfig,transportBlkSize,puschConfig.OCQI,puschConfig.ORI,puschConfig.OACK); -puschConfig.QdACK=info.QdACK; -puschConfig.QdRI=info.QdRI; -puschConfig.QdCQI=info.QdCQI; - -switch (modulation) - case 'QPSK' - bitsPerSym = 2; - case '16QAM' - bitsPerSym = 4; - case '64QAM' - bitsPerSym = 6; -end - -noiseVarfactor = sqrt(2*bitsPerSym); -snr = 10.^(SNR/10); - -nErrors_mat = zeros(length(SNR),length(rvValues)); -nErrorsCtrl_mat = zeros(length(SNR),3); -nErrors_srs = zeros(length(SNR),length(rvValues)); -nErrorsCtrl_srs = zeros(length(SNR),3); - -for k = 1:length(SNR); - subframe=cell(length(rvValues)); - puschIdx=ltePUSCHIndices(ueConfig,puschConfig); - for i=1:length(rvValues) - subframe{i} = lteULResourceGrid(ueConfig); - end - blkCounter = 0; - for l = 1:Nblocks; - % UL-SCH data bits - ulschBits = randi([0 1],transportBlkSize,1); - softBuffer = {}; - - % Control bits - cqi = randi([0 1], puschConfig.OCQI,1); - ri = randi([0 1], puschConfig.ORI,1); - ack = randi([0 1], puschConfig.OACK,1); - - for rvIndex = 1:length(rvValues) - % ULSCH transport channel - puschConfig.RV = rvValues(rvIndex); - puschPayload = lteULSCH(ueConfig, puschConfig, ulschBits, cqi, ri, ack); - - % PUSCH modulated symbols - puschSymbols = ltePUSCH(ueConfig, puschConfig, puschPayload); - puschSize = size(puschSymbols); - - % Addition of noise - noise = (1/noiseVarfactor)*sqrt(1/snr(k))*complex(randn(puschSize),randn(puschSize)); - noisySymbols = puschSymbols + noise; - - subframe{rvIndex}(puschIdx)=noisySymbols; - - % PUSCH Rx-side - [rxCW, puschSymbolsRx] = ltePUSCHDecode(ueConfig, puschConfig, noisySymbols); - if (iscell(rxCW)) - rxCW_=rxCW{1}; - else - rxCW_=rxCW; - end - - % UL-SCH turbo decoding - [rxBits, blkCRCerr, softBuffer,ccqi,cri,cack] = lteULSCHDecode2(ueConfig, puschConfig, ... - transportBlkSize, rxCW_, softBuffer); - - % Add errors to previous error counts - nErrors_mat(k,rvIndex) = nErrors_mat(k,rvIndex)+blkCRCerr; - - if (rvIndex==1) - ack_rx=lteACKDecode(puschConfig,cack); - ri_rx=lteRIDecode(puschConfig,cri); - cqi_rx=lteCQIDecode(puschConfig,ccqi); - - nErrorsCtrl_mat(k,1) = nErrorsCtrl_mat(k,1)+(sum(ack_rx~=ack)>0); - nErrorsCtrl_mat(k,2) = nErrorsCtrl_mat(k,2)+(sum(ri_rx~=ri)>0); - nErrorsCtrl_mat(k,3) = nErrorsCtrl_mat(k,3)+(sum(cqi_rx~=cqi)>0); - end - end - - % Same with srsLTE - [okSRSLTE, cqi_rx_srs, ri_rx_srs, ack_rx_srs] = srslte_puscht(ueConfig, puschConfig, ... - transportBlkSize, subframe, ones(size(subframe{1})), 0); - - nErrors_srs(k,rvIndex) = nErrors_srs(k,rvIndex)+~okSRSLTE; - - if (rvIndex==1) - nErrorsCtrl_srs(k,1) = nErrorsCtrl_srs(k,1)+(sum(ack_rx_srs~=ack)>0); - nErrorsCtrl_srs(k,2) = nErrorsCtrl_srs(k,2)+(sum(ri_rx_srs~=ri)>0); - nErrorsCtrl_srs(k,3) = nErrorsCtrl_srs(k,3)+(sum(cqi_rx_srs~=cqi)>0); - end - end - fprintf('SNR=%.1f dB, BLER_mat=%.2f, BLER_srs=%.2f, BLER_ack=%.2f/%.2f, BLER_ri=%.2f/%.2f, BLER_cqi=%.2f/%.2f\n',... - SNR(k),nErrors_mat(k,rvIndex)/Nblocks, nErrors_srs(k,rvIndex)/Nblocks, ... - nErrorsCtrl_mat(k,1)/Nblocks, nErrorsCtrl_srs(k,1)/Nblocks, ... - nErrorsCtrl_mat(k,3)/Nblocks, nErrorsCtrl_srs(k,2)/Nblocks, ... - nErrorsCtrl_mat(k,2)/Nblocks, nErrorsCtrl_srs(k,3)/Nblocks); -end - -puschBLER_mat = nErrors_mat./Nblocks; -puschBLER_mat(puschBLER_mat==0)=10^-10; - -puschBLER_srs = nErrors_srs./Nblocks; -puschBLER_srs(puschBLER_srs==0)=10^-10; - - -puschCtrlBLER_mat = nErrorsCtrl_mat./Nblocks; -puschCtrlBLER_mat(puschCtrlBLER_mat==0)=10^-10; - -puschCtrlBLER_srs = nErrorsCtrl_srs./Nblocks; -puschCtrlBLER_srs(puschCtrlBLER_srs==0)=10^-10; - -if (Nblocks == 1 && length(SNR) == 1) -else - - ctrlplot=1; - if (puschConfig.OCQI+puschConfig.ORI+puschConfig.OACK>0) - ctrlplot=2; - end - - subplot(ctrlplot,1,1) - semilogy(SNR,puschBLER_mat,SNR,puschBLER_srs); - grid on - xlabel('Eb/No (dB)') - ylabel('BLER') - leg=[]; - for rvIndex = 1:length(rvValues) - leg=strvcat(leg,sprintf('Matlab rv=%d',rvValues(rvIndex))); - end - for rvIndex = 1:length(rvValues) - leg=strvcat(leg,sprintf('srsLTE rv=%d',rvValues(rvIndex))); - end - axis([min(SNR) max(SNR) 10^-4 1]) - - if (ctrlplot==2) - subplot(2,1,2) - semilogy(SNR,puschCtrlBLER_mat,SNR,puschCtrlBLER_srs) - grid on - xlabel('Eb/No (dB)') - ylabel('BLER') - leg=[]; - leg=strvcat(leg,'Matlab ACK','Matlab RI', 'Matlab CQI'); - leg=strvcat(leg,'srsLTE ACK','srsLTE RI', 'srsLTE CQI'); - legend(leg); - axis([min(SNR) max(SNR) 10^-4 1]) - end -end diff --git a/matlab/tests/pusch_decode_signal.m b/matlab/tests/pusch_decode_signal.m deleted file mode 100644 index 4973e3aee..000000000 --- a/matlab/tests/pusch_decode_signal.m +++ /dev/null @@ -1,20 +0,0 @@ -ueConfig=struct('NCellID',1,'NULRB',15,'NSubframe',0,'RNTI',30,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0); -puschConfig=struct('NTurboDecIts',5,'NLayers',1,'OrthCover','Off','PRBSet',(0:14)','Modulation','QPSK','RV',0); - -TBS=392; -cfo=0; -t0=1; -x=[rx(t0:end); zeros(t0-1,1)]; - -x=lteFrequencyCorrect(ueConfig,x,cfo); -subframe_rx=lteSCFDMADemodulate(ueConfig,x); -idx=ltePUSCHIndices(ueConfig,puschConfig); -pusch_rx=subframe_rx(idx); -dmrs_rx=subframe_rx(ltePUSCHDRSIndices(ueConfig,puschConfig)); -[hest, noiseest] = lteULChannelEstimate(ueConfig,puschConfig,subframe_rx); -ce=hest(idx); -[cws,symbols] = ltePUSCHDecode(ueConfig,puschConfig,pusch_rx,ce,noiseest); -[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,TBS,cws); -disp(blkcrc) -scatter(real(symbols),imag(symbols)) -%plot(angle(hest(:,1))) \ No newline at end of file diff --git a/matlab/tests/pusch_encode_test.m b/matlab/tests/pusch_encode_test.m deleted file mode 100644 index 5d09e88f5..000000000 --- a/matlab/tests/pusch_encode_test.m +++ /dev/null @@ -1,67 +0,0 @@ -ueConfig=struct('NCellID',1,'NULRB',6,'CyclicPrefixUL','Normal','NTxAnts',1,'RNTI',64); -puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'NBundled',0); - -addpath('../../build//srslte/lib/phch/test') - -cqilen=0;%[0 4 20]; -mods={'64QAM'}; -rvs=0; -betas=0;%[0 5.0, 20.0]; -for p=1 - for i=0:26 - for m=1:length(mods) - for r=1:length(rvs) - for bri=1:length(betas) - for back=1:length(betas) - for c=1:length(cqilen) - for s=0:9 - ueConfig.NSubframe=s; - puschConfig.PRBSet=(0:p-1)'; - - TBs=lteTBS(length(puschConfig.PRBSet),i); - %TBs=256; - %trblkin=randi(2,TBs,1)-1; - trblkin=ones(1,TBs); - - puschConfig.Modulation = mods{m}; - puschConfig.RV = rvs(r); - puschConfig.BetaCQI = 5; - puschConfig.BetaRI = betas(bri); - puschConfig.BetaACK = betas(back); - - if (betas(bri)>0) - ri_bit=randi(2,1,1)-1; - else - ri_bit=[]; - end - if (betas(back)>0) - ack_bit=randi(2,1,1)-1; - else - ack_bit=[]; - end - - if (cqilen(c)>0 || TBs>0) - [enc, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit); - cw_mat=ltePUSCH(ueConfig,puschConfig,enc); - %[drs, infodrs]=ltePUSCHDRS(ueConfig,puschConfig); - idx=ltePUSCHIndices(ueConfig,puschConfig); - %drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig); - subframe_mat = lteULResourceGrid(ueConfig); - subframe_mat(idx)=cw_mat; - - [~, subframe_lib, cwlib, bits]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit); - err=max(abs(subframe_mat(:)-subframe_lib)); - if (err > 10^-5) - plot(abs(subframe_mat(:)-subframe_lib)) - error('Error!'); - end - end - end - end - end - end - end - end - end -end - diff --git a/matlab/tests/rm_turbo_rx_test.m b/matlab/tests/rm_turbo_rx_test.m deleted file mode 100644 index a6139f251..000000000 --- a/matlab/tests/rm_turbo_rx_test.m +++ /dev/null @@ -1,43 +0,0 @@ -clear - -enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1); -pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0'); - -addpath('../../build/srslte/lib/fec/test') - - -codewordLen = 12000; -trBlkLenVec = 6201; -error=zeros(size(trBlkLenVec)); -for i=1:length(trBlkLenVec) - trBlkLen=trBlkLenVec(i); - in=randi(2,trBlkLen,1)-1; - - RV = 0; - trblockwithcrc = lteCRCEncode(in,'24A'); - codeblocks = lteCodeBlockSegment(trblockwithcrc); - turbocodedblocks = lteTurboEncode(codeblocks); - codeword = lteRateMatchTurbo(turbocodedblocks,codewordLen,RV); - - info = lteDLSCHInfo(trBlkLen); - - mat = lteRateRecoverTurbo(codeword,trBlkLen,RV); - mat2 = reshape(reshape(mat{1},[],3)',[],1); - out = lteTurboDecode(mat{1}); - - lib=srslte_rm_turbo_rx(double(codeword),trBlkLen,RV); - [outLib] = srslte_turbodecoder(lib); - - if (length(trBlkLenVec) == 1) -% fprintf('Err mat: %d. Err lib: %d\n',sum(out(1+info.F:trBlkLen+info.F)~=in),sum(outLib(1+info.F:trBlkLen+info.F)~=in)); - end - error(i)=mean(abs(double(mat2)-double(lib))); -end - -if (length(trBlkLenVec) == 1) - n=1:length(mat{1}); - plot(abs(double(mat2)-double(lib))) - %plot(n,mat{1},n,lib) -else - plot(error) -end diff --git a/matlab/tests/srs_test.m b/matlab/tests/srs_test.m deleted file mode 100644 index 48c615e78..000000000 --- a/matlab/tests/srs_test.m +++ /dev/null @@ -1,47 +0,0 @@ -clear -ueConfig=struct('NCellID',1,'NULRB',100,'DuplexMode','FDD','NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1); -srsConfig=struct('NTxAnts',1,'ConfigIdx',317,'SeqGroup',1,'SeqIdx',0,'TxComb',0); - -addpath('../../build/srslte/lib/ch_estimation/test') - -for k=0:50 - for csbw=0:7 - for uebw=0:3 - for hop=0:3 - for ncs=0 - for n_rrc=1:5:20 - ueConfig.NFrame=mod(32*k,1024); - srsConfig.BWConfig = csbw; - srsConfig.BW = uebw; - srsConfig.CyclicShift = ncs; - srsConfig.HoppingBW = hop; - srsConfig.FreqPosition = n_rrc; - fprintf('Testing SRS: Nframe=%d, CSBW=%d, UEBW=%d, b_hop=%d n_rrc=%d\n',ueConfig.NFrame, csbw, uebw, hop, n_rrc); - - [sym_mat, info]=lteSRS(ueConfig,srsConfig); - [idx, info2]=lteSRSIndices(ueConfig,srsConfig); - subframe_mat = lteULResourceGrid(ueConfig); - subframe_mat(idx)=sym_mat; - - [sym, subframe]=srslte_refsignal_srs(ueConfig,srsConfig); - - error_sym=max(abs(sym-sym_mat)); - error_sf=max(abs(subframe_mat(:)-subframe)); - - if (error_sym > 3.5e-3) - disp(info) - plot(abs(sym-sym_mat)) - legend('srsLTE','Matlab') - error('Error in symbols'); - end - if (error_sf > 3.5e-3) - disp(info2) - plot(abs(subframe-subframe_mat(:))) - error('Error in subframe'); - end - end - end - end - end - end -end \ No newline at end of file diff --git a/matlab/tests/sss_test.m b/matlab/tests/sss_test.m deleted file mode 100644 index f9d4beb83..000000000 --- a/matlab/tests/sss_test.m +++ /dev/null @@ -1,144 +0,0 @@ - -SNR_values = linspace(-6,4,10); -Npackets = 200; -CFO=4/15; -m0=7; -m1=10; -%m0=26; -%m1=21; - -recordedWaveform = x; -if (~isempty(recordedWaveform)) - Npackets = floor(length(recordedWaveform)/19200)-1; - SNR_values = 0; -end - -error = zeros(6,length(SNR_values)); - -enb = struct('NCellID',2,'NSubframe',0,'NDLRB',6,'CellRefP',1,'CyclicPrefix','Normal','DuplexMode','FDD'); -sss=lteSSS(enb); - -cfg.Seed = 2; % Random channel seed -cfg.NRxAnts = 1; % 1 receive antenna -cfg.DelayProfile = 'ETU'; % EVA delay spread -cfg.DopplerFreq = 144; % 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 -cfg.InitPhase = 'Random'; % Random initial phases -cfg.NormalizePathGains = 'On'; % Normalize delay profile power -cfg.NormalizeTxAnts = 'On'; % Normalize for transmit antennas % Initialize at time zero - -[s, c0, c1] = get_sc(mod(enb.NCellID,3)); - -subframe = lteDLResourceGrid(enb); -sssSym = lteSSS(enb); -sssInd = lteSSSIndices(enb); -subframe(sssInd) = sssSym; -N_id_1 = floor(enb.NCellID/3); - -[txWaveform,info] = lteOFDMModulate(enb,subframe); -cfg.SamplingRate = info.SamplingRate; -fftSize = info.Nfft; - - -addpath('../../debug/lte/phy/lib/sync/test') - -for snr_idx=1:length(SNR_values) - SNRdB = SNR_values(snr_idx); - for i=1:Npackets - %% Noise Addition - SNR = 10^(SNRdB/10); % Linear SNR - - if (isempty(recordedWaveform)) - cfg.InitTime = i*(10^-3); - [rxWaveform, info]= lteFadingChannel(cfg,txWaveform); - rxWaveform = txWaveform; - - % Add CFO - freq = CFO/double(fftSize); - rxWaveform = rxWaveform.*exp(1i*2*pi*freq*(1:length(txWaveform))'); - - N0 = 1/(sqrt(2.0*enb.CellRefP*double(fftSize))*SNR); - noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise - - rxWaveform = rxWaveform + noise; - else - rxWaveform = recordedWaveform(i*19200+1:(i+1)*19200); - end - - offset = lteDLFrameOffset(enb,rxWaveform); - offsetVec(i)=offset; - rxWaveform = [rxWaveform(1+offset:end,:); zeros(offset,1)]; - - subframe_rx = lteOFDMDemodulate(enb,rxWaveform,1); - - sss_rx = subframe_rx(lteSSSIndices(enb)); - sss0=sss_rx(1:2:end); - sss1=sss_rx(2:2:end); - - beta0=sss0.*c0'; - beta1=sss1.*c1'; - - corr0=zeros(31,1); - for m=1:31 - corr0(m)=sum(beta0.*s(m,:)'); - end - corr0=abs(corr0).^2; - [m, idx]=max(corr0); - - error(1,snr_idx) = error(1,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - M=2; - Nm=10; - - corr2=zeros(31,1); - for m=1:31 - for j=0:M - idx=1+j*Nm:(j+1)*Nm; - corr2(m)=corr2(m)+abs(sum(beta0(idx).*s(m,idx)')).^2; - end - end - [m, idx]=max(corr2); - - error(2,snr_idx) = error(2,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - corr3=zeros(31,1); - for m=1:31 - corr3(m)=abs(sum(beta0(2:end).*conj(beta0(1:end-1)).*transpose(s(m,2:end).*conj(s(m,1:end-1))))).^2; - end - [m, idx]=max(corr3); - - error(3,snr_idx) = error(3,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - % srsLTE results - [n,sf_idx,lt_corr0]=srslte_sss(enb,rxWaveform,'full'); - [m, idx]=max(lt_corr0); - error(4,snr_idx) = error(4,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - [n,sf_idx,lt_corr2]=srslte_sss(enb,rxWaveform,'partial'); - [m, idx]=max(lt_corr2); - error(5,snr_idx) = error(5,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - [n,sf_idx,lt_corr3]=srslte_sss(enb,rxWaveform,'diff'); - [m, idx]=max(lt_corr3); - error(6,snr_idx) = error(6,snr_idx) + ((idx ~= m0 && idx ~= m1)); - - end -end - -if (length(SNR_values) > 1) - plot(SNR_values,1-error/Npackets) - legend('Full','Partial','Differential','Full-lt','Partial-lt','Differential-lt') - grid on -else - e=error/Npackets; - fprintf('Full (mt/lt): \t%f/%f\n',e(1),e(4)); - fprintf('Partial (mt/lt):%f/%f\n',e(2),e(5)); - fprintf('Diff (mt/lt): \t%f/%f\n',e(3),e(6)); -end - - - - - diff --git a/matlab/tests/sync_test.m b/matlab/tests/sync_test.m deleted file mode 100644 index c71437aee..000000000 --- a/matlab/tests/sync_test.m +++ /dev/null @@ -1,96 +0,0 @@ -clear -enb = lteTestModel('1.1','1.4MHz'); -Ntrials = 1; -SNR_values = 100;%linspace(-8,0,6); -flen=1920; -fft_size=128; -fading_enabled = true; - -tx_offset = 10;%randi(50,1,Ntrials); - -tx_signal = lteTestModelTool(enb); -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.SSS='On'; -corrcfg.CellRS='Off'; - -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=fft_size; -M=4; -diff=zeros(length(SNR_values),M); -for snr_idx=1:length(SNR_values) - fprintf('SNR=%.1f dB\n', SNR_values(snr_idx)); - SNRdB = SNR_values(snr_idx); - rx_offset = zeros(M,length(tx_offset)); - for i=1:Ntrials - if fading_enabled - [rx_signal, chinfo] = lteFadingChannel(cfg,tx_signal); - else - rx_signal = tx_signal; - end - SNR = 10^(SNRdB/10); % Linear SNR - rx = [zeros(tx_offset(i),1); rx_signal]; - N0 = tx_power/(sqrt(2.0)*SNR); - noise = N0*complex(randn(size(rx)), randn(size(rx))); % Generate noise - rx=noise+rx; - [rx_offset(1,i),corr_res] = lteDLFrameOffset(enb,rx(1:flen),corrcfg); - - % 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) - L/2) + 1; - - % CP based - [rx_offset(4,i), corr_lt_cp] = srslte_cp_synch(enb, rx); - - end - if fading_enabled - ch_delay = chinfo.ChannelFilterDelay; - else - ch_delay = 0; - end - diff(snr_idx,:)=mean(abs(rx_offset-repmat(tx_offset,M,1) - ch_delay),2); -end - -if (Ntrials == 1) - disp(rx_offset) - disp(diff) - %plot(1:flen,abs(corr_res(1:flen)),1:flen,abs(corr_lt(1:flen))); - t=1:L; - plot(t,abs(corr_lt_track(t))); - %plot(lambda) - %plot(1:L,abs(corr_lt_track),[L/2, L/2], [0 max(abs(corr_lt_track))]) - grid on - -else - plot(SNR_values,diff); - legend('Matlab','srs find','srs tracking','srs cp') - grid on - xlabel('SNR (dB)') - ylabel('Avg time offset') -end - diff --git a/matlab/tests/test_ofdma_peakamp.m b/matlab/tests/test_ofdma_peakamp.m deleted file mode 100644 index 81f21be10..000000000 --- a/matlab/tests/test_ofdma_peakamp.m +++ /dev/null @@ -1,32 +0,0 @@ -clear -enbConfig=struct('NCellID',0,'DuplexMode','TDD','CyclicPrefix','Normal','CellRefP',1,'CFI',2,'NDLRB',25,'NSubframe',4,'CyclicPrefixUL','Normal','NTxAnts',1); -pdschConfig=struct('NLayers',1,'TxScheme','Port0','OrthCover','Off','PRBSet',0,'RNTI',82,'Modulation','QPSK','RV',0,'Shortened',0); - -addpath('../../debug/lte/phy/lib/phch/test') - -NDLRB=[6 15 25 50 100]; - -Peak=[]; -k=1; -for r=1:length(NDLRB) - fprintf('NDLRB: %d\n',NDLRB(r)); - for l=1:NDLRB(r) - trblkin=randi(2,l*5,1)-1; - - enbConfig.NDLRB=NDLRB(r); - pdschConfig.PRBSet=(0:(l-1))'; - - idx=ltePDSCHIndices(enbConfig,pdschConfig,pdschConfig.PRBSet); - [cw, info]=lteDLSCH(enbConfig,pdschConfig,2*length(idx),trblkin); - cw_mat=ltePDSCH(enbConfig,pdschConfig,cw); - subframe_mat = lteDLResourceGrid(enbConfig); - subframe_mat(idx)=cw_mat; - waveform = lteOFDMModulate(enbConfig,subframe_mat,0); - waveform = waveform*sqrt(512)/sqrt(l)*NDLRB(r)/15; - Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform)))); - k=k+1; - end -end - -plot(Peak(:)') - diff --git a/matlab/tests/test_scfdma.m b/matlab/tests/test_scfdma.m deleted file mode 100644 index 70edcb9f3..000000000 --- a/matlab/tests/test_scfdma.m +++ /dev/null @@ -1,26 +0,0 @@ -clear -ue = struct('NULRB',6,'NDLRB',6); -d = lteULResourceGridSize(ue); -rgrid = complex(rand(d)-0.5,rand(d)-0.5); -waveform = lteSCFDMAModulate(ue,rgrid,0); - -wave = []; -freq_correct=[]; -for i=1:14 - symbol = ifft(ifftshift([zeros(28,1); rgrid(:,i); zeros(28,1)]),128); - if (i==1 || i==8) - cp_len=10; - else - cp_len=9; - end - symbol_cp=[symbol((128-cp_len+1):128); symbol(1:128)]; - freq_correct=[freq_correct; exp(1i*pi*(-cp_len:127)'/128)]; - wave = [wave; symbol_cp]; -end - -wave=wave.*freq_correct; - -%wave=transpose(wave); -%plot(1:138,fftshift(fft(waveform(1:138))),1:138,fftshift(fft(wave(1:138)))) -plot(abs(wave(1:138)-waveform(1:138))) -mean(abs(wave-waveform)) diff --git a/matlab/tests/test_scfdma_peakamp.m b/matlab/tests/test_scfdma_peakamp.m deleted file mode 100644 index 211d0e45b..000000000 --- a/matlab/tests/test_scfdma_peakamp.m +++ /dev/null @@ -1,32 +0,0 @@ -clear -ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1); -puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','QPSK','RV',0,'Shortened',0); - -addpath('../../debug/lte/phy/lib/phch/test') - -NULRB=[6 15 25 50 100]; - -Peak=[]; -k=1; -for r=1:length(NULRB) - fprintf('NULRB: %d\n',NULRB(r)); - for l=1:NULRB(r) - trblkin=randi(2,l*5,1)-1; - - ueConfig.NULRB=NULRB(r); - puschConfig.PRBSet=(0:(l-1))'; - - [cw, info]=lteULSCH(ueConfig,puschConfig,trblkin); - cw_mat=ltePUSCH(ueConfig,puschConfig,cw); - idx=ltePUSCHIndices(ueConfig,puschConfig); - subframe_mat = lteULResourceGrid(ueConfig); - subframe_mat(idx)=cw_mat; - waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0); - waveform = waveform*sqrt(512)/sqrt(l)*NULRB(r)/10; - Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform)))); - k=k+1; - end -end - -plot(Peak(:)') - diff --git a/matlab/tests/turbodecoder_bler.m b/matlab/tests/turbodecoder_bler.m deleted file mode 100644 index 754d1c9de..000000000 --- a/matlab/tests/turbodecoder_bler.m +++ /dev/null @@ -1,51 +0,0 @@ - -clear -blen=5184; -SNR_values_db=linspace(-1.3,-0.7,6); -Nrealizations=600; - -addpath('../../build/srslte/lib/fec/test') - -errors1=zeros(1,length(SNR_values_db)); -errors2=zeros(1,length(SNR_values_db)); -for snr_idx=1:length(SNR_values_db) - SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB - SNR = 10^(SNRdB/20); % Linear SNR - - for i=1:Nrealizations - Data = randi(2,blen,1)==1; - codedData = lteTurboEncode(Data); - - codedsymbols = 2*double(codedData)-1; - - %% Additive Noise - N0 = 1/SNR; - - % Create additive white Gaussian noise - noise = N0*randn(size(codedsymbols)); - - noisysymbols = noise + codedsymbols; - - decodedData = lteTurboDecode(noisysymbols); - interleavedSymbols = reshape(reshape(noisysymbols,[],3)',1,[]); - [decodedData2] = srslte_turbodecoder(interleavedSymbols); - - errors1(snr_idx) = errors1(snr_idx) + any(decodedData ~= Data); - errors2(snr_idx) = errors2(snr_idx) + any(decodedData2 ~= Data); - end - - fprintf('SNR: %.2f BLER: %f-%f\n', SNR_values_db(snr_idx), ... - errors1(snr_idx)/Nrealizations, errors2(snr_idx)/Nrealizations); -end - -if (length(SNR_values_db) > 1) - semilogy(SNR_values_db, errors1/Nrealizations, ... - SNR_values_db, errors2/Nrealizations) - grid on - xlabel('SNR (dB)') - ylabel('BLER') - legend('Matlab','srsLTE'); -else - disp(errors1); - disp(errors2); -end \ No newline at end of file diff --git a/matlab/tests/ulsch_test.m b/matlab/tests/ulsch_test.m deleted file mode 100644 index 013ebca1d..000000000 --- a/matlab/tests/ulsch_test.m +++ /dev/null @@ -1,67 +0,0 @@ -clear -ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1); -puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0); - -addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test') - -cqilen=[0 20]; -mods={'QPSK','16QAM', '64QAM'}; -rvs=0; -betas=[0 2.0 2.5 5.0, 20.0]; -for p=1:100 - for i=0:26 - for m=1:length(mods) - for r=1:length(rvs) - for bri=1:length(betas) - for back=1:length(betas) - for c=1:length(cqilen) - puschConfig.PRBSet=(0:p-1)'; - - TBs=lteTBS(length(puschConfig.PRBSet),i); - %TBs=256; - %trblkin=randi(2,TBs,1)-1; - trblkin=ones(1,TBs); - - puschConfig.Modulation = mods{m}; - puschConfig.RV = rvs(r); - puschConfig.BetaCQI = 5; - puschConfig.BetaRI = betas(bri); - puschConfig.BetaACK = betas(back); - - if (betas(bri)>0) - ri_bit=randi(2,1,1)-1; - else - ri_bit=[]; - end - if (betas(back)>0) - ack_bit=randi(2,1,1)-1; - else - ack_bit=[]; - end - - if (cqilen(c)>0 || TBs>0) - [lib]=srslte_ulsch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit); - [mat, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]); - mat(mat==-2)=0; - mat(mat==-1)=0; - err=sum(abs(double(mat)-double(lib))); - if (err > 0) - disp(err) - plot(abs(double(mat)-double(lib))) - error('Error!'); - end - end - end - end - end - end - end - end -end - -if (length(TBs) == 1) - %disp(info) - n=1:length(mat); - %plot(abs(double(mat)-double(lib))) - plot(n,lib(n),n,mat(n)) -end diff --git a/matlab/tests/viterbi_bler.m b/matlab/tests/viterbi_bler.m deleted file mode 100644 index d0fc61d04..000000000 --- a/matlab/tests/viterbi_bler.m +++ /dev/null @@ -1,49 +0,0 @@ - -clear -blen=40; -SNR_values_db=linspace(-3,4,8); -Nrealizations=50000; - -addpath('../../build/srslte/lib/fec/test') - -errors1=zeros(1,length(SNR_values_db)); -errors2=zeros(1,length(SNR_values_db)); -for snr_idx=1:length(SNR_values_db) - SNRdB = SNR_values_db(snr_idx); % Desired SNR in dB - SNR = 10^(SNRdB/20); % Linear SNR - - for i=1:Nrealizations - Data = randi(2,blen,1)==1; - codedData = lteConvolutionalEncode(Data); - - codedsymbols = 2*double(codedData)-1; - - %% Additive Noise - N0 = 1/SNR; - - % Create additive white Gaussian noise - noise = N0*randn(size(codedsymbols)); - - noisysymbols = noise + codedsymbols; - - decodedData = lteConvolutionalDecode(noisysymbols); - interleavedSymbols = reshape(reshape(noisysymbols,[],3)',1,[]); - [decodedData2, quant] = srslte_viterbi(interleavedSymbols, 32); - - errors1(snr_idx) = errors1(snr_idx) + any(decodedData ~= Data); - errors2(snr_idx) = errors2(snr_idx) + any(decodedData2 ~= Data); - end -end - -if (length(SNR_values_db) > 1) - semilogy(SNR_values_db, errors1/Nrealizations, ... - SNR_values_db, errors2/Nrealizations) - grid on - xlabel('SNR (dB)') - ylabel('BLER') - legend('Matlab','srsLTE'); -else - disp(errors1); - disp(errors2); - disp(errors3); -end \ No newline at end of file diff --git a/mex/CMakeLists.txt b/mex/CMakeLists.txt deleted file mode 100644 index 51df7daea..000000000 --- a/mex/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright 2013-2015 Software Radio Systems Limited -# -# This file is part of the srsLTE library. -# -# srsLTE is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of -# the License, or (at your option) any later version. -# -# srsLTE is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# A copy of the GNU Affero General Public License can be found in -# the LICENSE file in the top-level directory of this distribution -# and at http://www.gnu.org/licenses/. -# - -if(NOT DisableMEX) - ######################################################################## - # Install headers - ######################################################################## - INSTALL(DIRECTORY include/ - DESTINATION "${INCLUDE_DIR}" - FILES_MATCHING PATTERN "*.h" - PATTERN ".svn" EXCLUDE - ) - - ######################################################################## - # Add headers to cmake project (useful for IDEs) - ######################################################################## - set(HEADERS_ALL "") - file(GLOB headers *) - FOREACH (_header ${headers}) - if(IS_DIRECTORY ${_header}) - file(GLOB_RECURSE tmp "${_header}/*.h") - list(APPEND HEADERS_ALL ${tmp}) - endif(IS_DIRECTORY ${_header}) - ENDFOREACH() - - add_custom_target (add_mex_headers SOURCES ${HEADERS_ALL}) - - ######################################################################## - # Add the subdirectories - ######################################################################## - add_subdirectory(lib) -endif() diff --git a/mex/include/srslte/mex/mexutils.h b/mex/include/srslte/mex/mexutils.h deleted file mode 100644 index b808c14da..000000000 --- a/mex/include/srslte/mex/mexutils.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#ifndef MEXUTILS_ -#define MEXUTILS_ - -#ifdef UNDEF_BOOL -#undef bool -#endif - -#include "mex.h" - -#include - -#include "srslte/config.h" -#include "srslte/common/phy_common.h" - - - -SRSLTE_API bool mexutils_isScalar(const mxArray *ptr); - -SRSLTE_API bool mexutils_isCell(const mxArray *ptr); - -SRSLTE_API int mexutils_getLength(const mxArray *ptr); - -SRSLTE_API mxArray* mexutils_getCellArray(const mxArray *ptr, int idx); - -SRSLTE_API int mexutils_read_cell(const mxArray *ptr, - srslte_cell_t *cell); - -SRSLTE_API char *mexutils_get_char_struct(const mxArray *ptr, - const char *field_name); - -SRSLTE_API int mexutils_read_uint32_struct(const mxArray *ptr, - const char *field_name, - uint32_t *value); - -SRSLTE_API int mexutils_read_float_struct(const mxArray *ptr, - const char *field_name, - float *value); - -SRSLTE_API int mexutils_write_f(float *buffer, - mxArray **ptr, - uint32_t nr, - uint32_t nc); - -SRSLTE_API int mexutils_write_s(short *buffer, - mxArray **ptr, - uint32_t nr, - uint32_t nc); - -SRSLTE_API int mexutils_write_cf(cf_t *buffer, - mxArray **ptr, - uint32_t nr, - uint32_t nc); - -SRSLTE_API int mexutils_write_uint8(uint8_t *buffer, - mxArray **ptr, - uint32_t nr, - uint32_t nc); - -SRSLTE_API int mexutils_write_int(int *buffer, - mxArray **ptr, - uint32_t nr, - uint32_t nc); - -SRSLTE_API int mexutils_read_uint8(const mxArray *ptr, - uint8_t **buffer); - -SRSLTE_API int mexutils_read_uint64(const mxArray *ptr, - uint64_t **buffer); - -SRSLTE_API int mexutils_read_f(const mxArray *ptr, - float **buffer); - -SRSLTE_API int mexutils_read_cf(const mxArray *ptr, - cf_t **buffer); - -#endif diff --git a/mex/lib/CMakeLists.txt b/mex/lib/CMakeLists.txt deleted file mode 100644 index ec571681a..000000000 --- a/mex/lib/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -# -# Copyright 2013-2015 Software Radio Systems Limited -# -# This file is part of the srsLTE library. -# -# srsLTE is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of -# the License, or (at your option) any later version. -# -# srsLTE is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# A copy of the GNU Affero General Public License can be found in -# the LICENSE file in the top-level directory of this distribution -# and at http://www.gnu.org/licenses/. -# - -if(NOT MATLAB_FOUND) - find_package(MATLAB) -endif() - -if(NOT OCTAVE_FOUND) - find_package(OCTAVE) -endif() - -# CMake 2.8.12 & earlier apparently don't define the -# Mex script path, so find it. -if(NOT MATLAB_MEX_PATH) - find_program( MATLAB_MEX_PATH mex - HINTS ${MATLAB_ROOT}/bin - PATHS ${MATLAB_ROOT}/bin - DOC "The mex program path" - ) -endif() - -if(MATLAB_FOUND) - message(STATUS "Found MATLAB in ${MATLAB_ROOT}") - add_library(srslte_mex SHARED mexutils.c) - install(TARGETS srslte_mex DESTINATION ${LIBRARY_DIR}) - SRSLTE_SET_PIC(srslte_mex) - include_directories(${MATLAB_INCLUDE_DIR}) -endif(MATLAB_FOUND) - -if(OCTAVE_FOUND) - message(STATUS "Found OCTAVE in ${OCTAVE_INCLUDE_PATHS}") - if (NOT MATLAB_FOUND) - add_library(srslte_mex SHARED mexutils.c) - install(TARGETS srslte_mex DESTINATION ${LIBRARY_DIR}) - SRSLTE_SET_PIC(srslte_mex) - endif (NOT MATLAB_FOUND) - include_directories(${OCTAVE_INCLUDE_DIR}) -endif(OCTAVE_FOUND) - -if(NOT MATLAB_FOUND) - if(NOT OCTAVE_FOUND) - message(STATUS "Could NOT find OCTAVE or MATLAB. MEX files won't be compiled") - endif(NOT OCTAVE_FOUND) -endif(NOT MATLAB_FOUND) - - diff --git a/mex/lib/mexutils.c b/mex/lib/mexutils.c deleted file mode 100644 index dc6a66729..000000000 --- a/mex/lib/mexutils.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 Software Radio Systems Limited - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include "srslte/mex/mexutils.h" -#include "srslte/utils/vector.h" -#include "srslte/common/phy_common.h" - - -bool mexutils_isScalar(const mxArray *ptr) { - return mxGetM(ptr) == 1 && mxGetN(ptr) == 1; -} - -bool mexutils_isCell(const mxArray *ptr) { - return mxIsCell(ptr); -} - -int mexutils_getLength(const mxArray *ptr) { - const mwSize *dims; - dims = mxGetDimensions(ptr); - return dims[0]; -} - -mxArray* mexutils_getCellArray(const mxArray *ptr, int idx) { - return mxGetCell(ptr, idx); -} - -char *mexutils_get_char_struct(const mxArray *ptr, const char *field_name) { - mxArray *p; - p = mxGetField(ptr, 0, field_name); - if (!p) { - return ""; - } - - if (mxIsCell(p)) { - return mxArrayToString(mxGetCell(p,0)); - } else { - return mxArrayToString(p); - } -} - -int mexutils_read_uint32_struct(const mxArray *ptr, const char *field_name, uint32_t *value) -{ - mxArray *p; - p = mxGetField(ptr, 0, field_name); - if (!p) { - return -1; - } - *value = (uint32_t) mxGetScalar(p); - return 0; -} - -int mexutils_read_float_struct(const mxArray *ptr, const char *field_name, float *value) -{ - mxArray *p; - p = mxGetField(ptr, 0, field_name); - if (!p) { - return -1; - } - *value = (float) mxGetScalar(p); - return 0; -} - -int mexutils_read_cell(const mxArray *ptr, srslte_cell_t *cell) { - if (mexutils_read_uint32_struct(ptr, "NCellID", &cell->id)) { - return -1; - } - if (mexutils_read_uint32_struct(ptr, "CellRefP", &cell->nof_ports)) { - return -1; - } - if (mexutils_read_uint32_struct(ptr, "NDLRB", &cell->nof_prb)) { - return -1; - } - if (!strcmp(mexutils_get_char_struct(ptr, "CyclicPrefix"), "Extended")) { - cell->cp = SRSLTE_CP_EXT; - } else { - cell->cp = SRSLTE_CP_NORM; - } - if (!strcmp(mexutils_get_char_struct(ptr, "PHICHDuration"), "Extended")) { - cell->phich_length = SRSLTE_PHICH_EXT; - } else { - cell->phich_length = SRSLTE_PHICH_NORM; - } - if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Sixth")) { - cell->phich_resources = SRSLTE_PHICH_R_1_6; - } else if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Half")) { - cell->phich_resources = SRSLTE_PHICH_R_1_2; - } else if (!strcmp(mexutils_get_char_struct(ptr, "Ng"), "Two")) { - cell->phich_resources = SRSLTE_PHICH_R_2; - } else { - cell->phich_resources = SRSLTE_PHICH_R_1; - } - - return 0; -} - -int mexutils_read_cf(const mxArray *ptr, cf_t **buffer) { - int numelems = mxGetNumberOfElements(ptr); - cf_t *tmp = srslte_vec_malloc(numelems * sizeof(cf_t)); - if (tmp) { - double *inr=mxGetPr(ptr); - double *ini=mxGetPi(ptr); - for (int i=0;i Date: Mon, 6 Mar 2017 16:02:08 +0000 Subject: [PATCH 29/38] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 5df567913..0423f3dc2 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ Current Features: * All UL channels/signals are supported for UE side: PRACH, PUSCH, PUCCH, SRS * Frequency-based ZF and MMSE equalizer * Highly optimized Turbo Decoder available in Intel SSE4.1/AVX (+100 Mbps) and standard C (+25 Mbps) - * MATLAB and OCTAVE MEX library generation for many components * UE receiver tested and verified with Amarisoft LTE 100 eNodeB and commercial LTE networks (Telefonica Spain, Three.ie and Eircom in Ireland) Missing Features: @@ -44,8 +43,7 @@ Download & Install Instructions * libfftw * Optional requirements: * srsgui: for real-time plotting. Download it here: https://github.com/srslte/srsgui - * VOLK: if the VOLK library and headers are detected, they will be used for accelerating some signal processing functions. - * Matlab/Octave: if found by CMake, MEX files will also be generated and installed. If you find any compilation issue with MEX and you don't need them, pass -DDisableMEX=ON to cmake to disable them. + * VOLK: if the VOLK library and headers are detected, they will be used for accelerating some signal processing functions. Download and build srsLTE: ``` From c49a299796dca9dde52b5ddb39a63a469c3cd7a7 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Mon, 6 Mar 2017 16:12:55 +0000 Subject: [PATCH 30/38] Removing old files --- cmake/modules/FindMATLAB.cmake | 220 --------------------------------- cmake/modules/FindOCTAVE.cmake | 138 --------------------- 2 files changed, 358 deletions(-) delete mode 100644 cmake/modules/FindMATLAB.cmake delete mode 100644 cmake/modules/FindOCTAVE.cmake diff --git a/cmake/modules/FindMATLAB.cmake b/cmake/modules/FindMATLAB.cmake deleted file mode 100644 index 1339ea77a..000000000 --- a/cmake/modules/FindMATLAB.cmake +++ /dev/null @@ -1,220 +0,0 @@ -# - this module looks for Matlab -# Defines: -# MATLAB_INCLUDE_DIR: include path for mex.h, engine.h -# MATLAB_LIBRARIES: required libraries: libmex, etc -# MATLAB_MEX_LIBRARY: path to libmex.lib -# MATLAB_MX_LIBRARY: path to libmx.lib -# MATLAB_MAT_LIBRARY: path to libmat.lib # added -# MATLAB_ENG_LIBRARY: path to libeng.lib -# MATLAB_ROOT: path to Matlab's root directory - -# This file is part of Gerardus -# -# This is a derivative work of file FindMatlab.cmake released with -# CMake v2.8, because the original seems to be a bit outdated and -# doesn't work with my Windows XP and Visual Studio 10 install -# -# (Note that the original file does work for Ubuntu Natty) -# -# Author: Ramon Casero , Tom Doel -# Version: 0.2.3 -# $Rev$ -# $Date$ -# -# The original file was copied from an Ubuntu Linux install -# /usr/share/cmake-2.8/Modules/FindMatlab.cmake - -set(MATLAB_FOUND FALSE) -if(WIN32) - # Search for a version of Matlab available, starting from the most modern one to older versions - foreach(MATVER "7.14" "7.11" "7.10" "7.9" "7.8" "7.7" "7.6" "7.5" "7.4") - if((NOT DEFINED MATLAB_ROOT) - OR ("${MATLAB_ROOT}" STREQUAL "") - OR ("${MATLAB_ROOT}" STREQUAL "/registry")) - get_filename_component(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${MATVER};MATLABROOT]" - ABSOLUTE) - set(MATLAB_VERSION ${MATVER}) - endif() - endforeach() - - # Directory name depending on whether the Windows architecture is 32 - # bit or 64 bit - set(CMAKE_SIZEOF_VOID_P 8) # Note: For some wierd reason this variable is undefined in my system... - if(CMAKE_SIZEOF_VOID_P MATCHES "4") - set(WINDIR "win32") - elseif(CMAKE_SIZEOF_VOID_P MATCHES "8") - set(WINDIR "win64") - else() - message(FATAL_ERROR "CMAKE_SIZEOF_VOID_P (${CMAKE_SIZEOF_VOID_P}) doesn't indicate a valid platform") - endif() - - # Folder where the MEX libraries are, depending of the Windows compiler - if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6") - set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc60") - elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio 7") - # Assume people are generally using Visual Studio 7.1, - # if using 7.0 need to link to: ../extern/lib/${WINDIR}/microsoft/msvc70 - set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc71") - # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/msvc70") - elseif(${CMAKE_GENERATOR} MATCHES "Borland") - # Assume people are generally using Borland 5.4, - # if using 7.0 need to link to ../extern/lib/${WINDIR}/microsoft/msvc70 - set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc54") - # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc50") - # set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/bcc51") - elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio*") - # If the compiler is Visual Studio, but not any of the specific - # versions above, we try our luck with the microsoft directory - set(MATLAB_LIBRARIES_DIR "${MATLAB_ROOT}/extern/lib/${WINDIR}/microsoft/") - else() - message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}") - endif() - - # Get paths to the Matlab MEX libraries - find_library(MATLAB_MEX_LIBRARY libmex ${MATLAB_LIBRARIES_DIR} ) - find_library(MATLAB_MX_LIBRARY libm ${MATLAB_LIBRARIES_DIR} ) - find_library(MATLAB_MAT_LIBRARY libmat ${MATLAB_LIBRARIES_DIR} ) - find_library(MATLAB_ENG_LIBRARY libeng ${MATLAB_LIBRARIES_DIR} ) - - # Get path to the include directory - find_path(MATLAB_INCLUDE_DIR "mex.h" "${MATLAB_ROOT}/extern/include" ) - -else() - - if((NOT DEFINED MATLAB_ROOT) - OR ("${MATLAB_ROOT}" STREQUAL "")) - # get path to the Matlab root directory - - execute_process( - COMMAND which matlab - OUTPUT_VARIABLE MATLAB_BIN_EXISTS - ) - - IF (MATLAB_BIN_EXISTS) - execute_process( - COMMAND which matlab - COMMAND xargs realpath - COMMAND xargs dirname - COMMAND xargs dirname - COMMAND xargs echo -n - OUTPUT_VARIABLE MATLAB_ROOT - ) - ENDIF (MATLAB_BIN_EXISTS) - endif() - - # Check if this is a Mac - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - set(LIBRARY_EXTENSION .dylib) - - # If this is a Mac and the attempts to find MATLAB_ROOT have so far failed, - # we look in the applications folder - if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL "")) - - # Search for a version of Matlab available, starting from the most modern one to older versions - foreach(MATVER "R2013b" "R2013a" "R2012b" "R2012a" "R2011b" "R2011a" "R2010b" "R2010a" "R2009b" "R2009a" "R2008b") - if((NOT DEFINED MATLAB_ROOT) OR ("${MATLAB_ROOT}" STREQUAL "")) - if(EXISTS /Applications/MATLAB_${MATVER}.app) - set(MATLAB_ROOT /Applications/MATLAB_${MATVER}.app) - endif() - endif() - endforeach() - endif() - - else() - set(LIBRARY_EXTENSION .so) - endif() - - # Get path to the MEX libraries - execute_process( - #COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmex${LIBRARY_EXTENSION} # Peter - COMMAND find "${MATLAB_ROOT}/bin" -name libmex${LIBRARY_EXTENSION} # standard - COMMAND xargs echo -n - OUTPUT_VARIABLE MATLAB_MEX_LIBRARY - ) - execute_process( - #COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmx${LIBRARY_EXTENSION} # Peter - COMMAND find "${MATLAB_ROOT}/bin" -name libmx${LIBRARY_EXTENSION} # Standard - COMMAND xargs echo -n - OUTPUT_VARIABLE MATLAB_MX_LIBRARY - ) - execute_process( - #COMMAND find "${MATLAB_ROOT}/extern/lib" -name libmat${LIBRARY_EXTENSION} # Peter - COMMAND find "${MATLAB_ROOT}/bin" -name libmat${LIBRARY_EXTENSION} # Standard - COMMAND xargs echo -n - OUTPUT_VARIABLE MATLAB_MAT_LIBRARY - ) - execute_process( - #COMMAND find "${MATLAB_ROOT}/extern/lib" -name libeng${LIBRARY_EXTENSION} # Peter - COMMAND find "${MATLAB_ROOT}/bin" -name libeng${LIBRARY_EXTENSION} # Standard - COMMAND xargs echo -n - OUTPUT_VARIABLE MATLAB_ENG_LIBRARY - ) - - # Get path to the include directory - find_path(MATLAB_INCLUDE_DIR - "mex.h" - PATHS "${MATLAB_ROOT}/extern/include" - ) - - find_program( MATLAB_MEX_PATH mex - HINTS ${MATLAB_ROOT}/bin - PATHS ${MATLAB_ROOT}/bin - DOC "The mex program path" - ) - - find_program( MATLAB_MEXEXT_PATH mexext - HINTS ${MATLAB_ROOT}/bin - PATHS ${MATLAB_ROOT}/bin - DOC "The mexext program path" - ) - - execute_process( - COMMAND ${MATLAB_MEXEXT_PATH} - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE MATLAB_MEX_EXT - ) - -endif() - -# This is common to UNIX and Win32: -set(MATLAB_LIBRARIES - ${MATLAB_MEX_LIBRARY} - ${MATLAB_MX_LIBRARY} - ${MATLAB_ENG_LIBRARY} -) - -if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES) - set(MATLAB_FOUND TRUE) -endif() - -# 32-bit or 64-bit mex -if(WIN32) - if (CMAKE_CL_64) - SET(MATLAB_MEX_EXTENSION .mexw64) - else(CMAKE_CL_64) - SET(MATLAB_MEX_EXTENSION .mexw32) - endif(CMAKE_CL_64) -else(WIN32) - if (CMAKE_SIZEOF_VOID_P MATCHES "8") - SET(MATLAB_MEX_EXTENSION .mexa64) - else(CMAKE_SIZEOF_VOID_P MATCHES "8") - SET(MATLAB_MEX_EXTENSION .mexglx) - endif (CMAKE_SIZEOF_VOID_P MATCHES "8") -endif(WIN32) - -SET(MATLAB_MEX_CFLAGS "-DMATLAB_MEX_FILE -DMX_COMPAT_32") - -mark_as_advanced( - MATLAB_LIBRARIES - MATLAB_MEX_LIBRARY - MATLAB_MX_LIBRARY - MATLAB_ENG_LIBRARY - MATLAB_INCLUDE_DIR - MATLAB_FOUND - MATLAB_ROOT - MATLAB_MEX_PATH - MATLAB_MEXEXT_PATH - MATLAB_MEX_EXT -) - diff --git a/cmake/modules/FindOCTAVE.cmake b/cmake/modules/FindOCTAVE.cmake deleted file mode 100644 index 63a43d740..000000000 --- a/cmake/modules/FindOCTAVE.cmake +++ /dev/null @@ -1,138 +0,0 @@ -# - Try to find a version of Octave and headers/library required by the -# used compiler. It determines the right MEX-File extension and add -# a macro to help the build of MEX-functions. -# -# This module defines: -# OCTAVE_INCLUDE_DIR: include path for mex.h, mexproto.h -# OCTAVE_OCTINTERP_LIBRARY: path to the library octinterp -# OCTAVE_OCTAVE_LIBRARY: path to the library octave -# OCTAVE_CRUFT_LIBRARY: path to the library cruft -# OCTAVE_LIBRARIES: required libraries: octinterp, octave, cruft -# OCTAVE_CREATE_MEX: macro to build a MEX-file -# -# The macro OCTAVE_CREATE_MEX requires in this order: -# - function's name which will be called in Octave; -# - C/C++ source files; -# - third libraries required. - -# Copyright (c) 2009-2013 Arnaud Barré -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -IF(OCTAVE_ROOT AND OCTAVE_INCLUDE_DIR AND OCTAVE_LIBRARIES) - STRING(COMPARE NOTEQUAL "${OCTAVE_ROOT}" "${OCTAVE_ROOT_LAST}" OCTAVE_CHANGED) - IF(OCTAVE_CHANGED) - SET(OCTAVE_USE_MINGW32 OCTAVE_USE_MINGW32-NOTFOUND CACHE INTERNAL "") - SET(OCTAVE_OCTAVE_LIBRARY OCTAVE_OCTAVE_LIBRARY-NOTFOUND CACHE INTERNAL "") - SET(OCTAVE_INCLUDE_DIR OCTAVE_INCLUDE_DIR-NOTFOUND CACHE INTERNAL "") - ELSE(OCTAVE_CHANGED) - # in cache already - SET(Octave_FIND_QUIETLY TRUE) - ENDIF(OCTAVE_CHANGED) -ENDIF(OCTAVE_ROOT AND OCTAVE_INCLUDE_DIR AND OCTAVE_LIBRARIES) - -SET(OCTAVE_MEXFILE_EXT mex) - -IF(WIN32) - SET(OCTAVE_PATHS_L1 ) - SET(OCTAVE_PATHS_L2 ) - # Level 0 - FILE(GLOB OCTAVE_PATHS_L0 "c:/Octave*") - # Level 1 - FOREACH(_file_ ${OCTAVE_PATHS_L0}) - FILE(GLOB OCTAVE_PATHS_TEMP "${_file_}/*") - SET(OCTAVE_PATHS_L1 ${OCTAVE_PATHS_L1};${OCTAVE_PATHS_TEMP}) - ENDFOREACH(_file_ OCTAVE_PATHS_L0) - # Level 2 - FOREACH(_file_ ${OCTAVE_PATHS_L1}) - FILE(GLOB OCTAVE_PATHS_TEMP "${_file_}/*") - SET(OCTAVE_PATHS_L2 ${OCTAVE_PATHS_L2};${OCTAVE_PATHS_TEMP}) - ENDFOREACH(_file_ OCTAVE_PATHS_L1) - # Merge levels - SET(OCTAVE_PATHS ${OCTAVE_PATHS_L0} ${OCTAVE_PATHS_L1} ${OCTAVE_PATHS_L2}) - - FIND_PATH(OCTAVE_ROOT "bin/octave.exe" ${OCTAVE_PATHS}) - FIND_PATH(OCTAVE_USE_MINGW32 "bin/mingw32-make.exe" "${OCTAVE_ROOT}/mingw32") - - IF(MSVC AND OCTAVE_USE_MINGW32) - MESSAGE(FATAL_ERROR - "You must use the generator \"MinGW Makefiles\" as the " - "version of Octave installed on your computer was compiled " - "with MinGW. You should also specify the native compiler " - "(GCC, G++ and GFortan) and add the path of MinGW in the " - "environment variable PATH. Contact the developers of the " - "project for more details") - ENDIF(MSVC AND OCTAVE_USE_MINGW32) - - FILE(GLOB OCTAVE_INCLUDE_PATHS "${OCTAVE_ROOT}/include/octave-*/octave") - FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/lib/octave-*") - IF (NOT OCTAVE_LIBRARIES_PATHS) - FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/lib/octave/*") - ENDIF (NOT OCTAVE_LIBRARIES_PATHS) - - # LIBOCTINTERP, LIBOCTAVE, LIBCRUFT names - SET(LIBOCTAVE "liboctave") - -ELSE(WIN32) - IF(APPLE) - FILE(GLOB OCTAVE_PATHS "/Applications/Octave*") - FIND_PATH(OCTAVE_ROOT "Contents/Resources/bin/octave" ${OCTAVE_PATHS}) - - FILE(GLOB OCTAVE_INCLUDE_PATHS "${OCTAVE_ROOT}/Contents/Resources/include/octave-*/octave") - FILE(GLOB OCTAVE_LIBRARIES_PATHS "${OCTAVE_ROOT}/Contents/Resources/lib/octave-*") - - SET(LIBOCTAVE "liboctave.dylib") - ELSE(APPLE) - FILE(GLOB OCTAVE_LOCAL_PATHS "/usr/local/lib/octave-*") - FILE(GLOB OCTAVE_USR_PATHS "/usr/lib/octave-*") - FILE(GLOB OCTAVE_INCLUDE_PATHS "/usr/include/octave-*") - - SET (OCTAVE_INCLUDE_PATHS - "/usr/local/include" - "/usr/local/include/octave" - "/usr/include" - "${OCTAVE_INCLUDE_PATHS}" - "${OCTAVE_INCLUDE_PATHS}/octave") - SET (OCTAVE_LIBRARIES_PATHS - "/usr/local/lib" - "/usr/local/lib/octave" - ${OCTAVE_LOCAL_PATHS} - "/usr/lib" - "/usr/lib/octave" - ${OCTAVE_USR_PATHS}) - - SET (LIBOCTAVE "octave") - ENDIF(APPLE) -ENDIF(WIN32) - -FIND_LIBRARY(OCTAVE_OCTAVE_LIBRARY - ${LIBOCTAVE} - ${OCTAVE_LIBRARIES_PATHS} - ) -FIND_PATH(OCTAVE_INCLUDE_DIR - "mex.h" - ${OCTAVE_INCLUDE_PATHS} - ) - -SET(OCTAVE_ROOT_LAST "${OCTAVE_ROOT}" CACHE INTERNAL "" FORCE) - -# This is common to UNIX and Win32: -SET(OCTAVE_LIBRARIES - ${OCTAVE_OCTAVE_LIBRARY} - CACHE INTERNAL "Octave libraries" FORCE -) - -INCLUDE(FindPackageHandleStandardArgs) - -# The variable OCTAVE_ROOT is only relevant for WIN32 -IF(WIN32) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Octave DEFAULT_MSG OCTAVE_ROOT OCTAVE_INCLUDE_DIR OCTAVE_OCTAVE_LIBRARY ) -ELSE(WIN32) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Octave DEFAULT_MSG OCTAVE_INCLUDE_DIR OCTAVE_OCTAVE_LIBRARY ) -ENDIF(WIN32) - -MARK_AS_ADVANCED( - OCTAVE_OCTAVE_LIBRARY - OCTAVE_LIBRARIES - OCTAVE_INCLUDE_DIR -) \ No newline at end of file From e8ab4ce24dc1b25a56b5f1b69488d75c5a44e262 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 8 Mar 2017 11:53:55 +0100 Subject: [PATCH 31/38] workaround for simd lut in debug mode --- CMakeLists.txt | 2 +- srslte/lib/fec/rm_turbo.c | 5 +++++ srslte/lib/utils/vector.c | 5 +++++ srslte/lib/utils/vector_simd.c | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faf11be37..8453f7b56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,7 @@ if(CMAKE_COMPILER_IS_GNUCC) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") find_package(SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -DDEBUG_MODE") if(HAVE_AVX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -mfpmath=sse -mavx -DLV_HAVE_AVX -DLV_HAVE_SSE") elseif(HAVE_SSE) diff --git a/srslte/lib/fec/rm_turbo.c b/srslte/lib/fec/rm_turbo.c index 5856a4e46..1d250ff43 100644 --- a/srslte/lib/fec/rm_turbo.c +++ b/srslte/lib/fec/rm_turbo.c @@ -36,6 +36,11 @@ #include "srslte/utils/vector.h" #include "srslte/fec/cbsegm.h" +#ifdef DEBUG_MODE +#warning FIXME: Disabling SSE/AVX turbo rate matching +#undef LV_HAVE_SSE +#undef LV_HAVE_AVX +#endif #ifdef LV_HAVE_SSE #include diff --git a/srslte/lib/utils/vector.c b/srslte/lib/utils/vector.c index 469320177..f42c75b0e 100644 --- a/srslte/lib/utils/vector.c +++ b/srslte/lib/utils/vector.c @@ -285,6 +285,10 @@ void srslte_vec_lut_fuf(float *x, uint32_t *lut, float *y, uint32_t len) { } void srslte_vec_lut_sss(short *x, unsigned short *lut, short *y, uint32_t len) { +#ifdef DEBUG_MODE +#warning FIXME: Disabling SSE/AVX in srslte_vec_lut_sss + srslte_vec_lut_sss_simd(x, lut, y, len); +#else #ifndef LV_HAVE_SSE for (int i=0;i Date: Wed, 8 Mar 2017 13:41:59 +0100 Subject: [PATCH 32/38] removed layermapping tests for >4 layers --- srslte/lib/mimo/test/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/srslte/lib/mimo/test/CMakeLists.txt b/srslte/lib/mimo/test/CMakeLists.txt index c7925bff2..d8d4f2359 100644 --- a/srslte/lib/mimo/test/CMakeLists.txt +++ b/srslte/lib/mimo/test/CMakeLists.txt @@ -34,19 +34,11 @@ add_test(layermap_multiplex_11 layermap_test -n 1000 -m multiplex -c 1 -l 1) add_test(layermap_multiplex_12 layermap_test -n 1000 -m multiplex -c 1 -l 2) add_test(layermap_multiplex_13 layermap_test -n 1002 -m multiplex -c 1 -l 3) add_test(layermap_multiplex_14 layermap_test -n 1000 -m multiplex -c 1 -l 4) -add_test(layermap_multiplex_15 layermap_test -n 1000 -m multiplex -c 1 -l 5) -add_test(layermap_multiplex_16 layermap_test -n 1002 -m multiplex -c 1 -l 6) -add_test(layermap_multiplex_17 layermap_test -n 994 -m multiplex -c 1 -l 7) -add_test(layermap_multiplex_18 layermap_test -n 1000 -m multiplex -c 1 -l 8) add_test(layermap_multiplex_22 layermap_test -n 1000 -m multiplex -c 2 -l 2) add_test(layermap_multiplex_23 layermap_test -n 1002 -m multiplex -c 2 -l 3) add_test(layermap_multiplex_24 layermap_test -n 1000 -m multiplex -c 2 -l 4) -add_test(layermap_multiplex_25 layermap_test -n 1002 -m multiplex -c 2 -l 5) -add_test(layermap_multiplex_26 layermap_test -n 1002 -m multiplex -c 2 -l 6) -add_test(layermap_multiplex_27 layermap_test -n 1000 -m multiplex -c 2 -l 7) -add_test(layermap_multiplex_28 layermap_test -n 1000 -m multiplex -c 2 -l 8) ######################################################################## From 0d322846952c813f46a8cd4cc3bf44df98220e75 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 8 Mar 2017 19:50:34 +0100 Subject: [PATCH 33/38] fixed ue_sync API compatibility with single antenna --- srslte/include/srslte/ue/ue_sync.h | 1 + srslte/lib/rf/rf_uhd_imp.c | 3 --- srslte/lib/ue/ue_sync.c | 9 +++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/srslte/include/srslte/ue/ue_sync.h b/srslte/include/srslte/ue/ue_sync.h index 04efe3c18..3764e4331 100644 --- a/srslte/include/srslte/ue/ue_sync.h +++ b/srslte/include/srslte/ue/ue_sync.h @@ -75,6 +75,7 @@ typedef struct SRSLTE_API { uint32_t agc_period; void *stream; + void *stream_single; int (*recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*); int (*recv_callback_single)(void*, void*, uint32_t, srslte_timestamp_t*); srslte_timestamp_t last_timestamp; diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index f4e8671f8..8a260a7e4 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -519,9 +519,6 @@ int rf_uhd_recv_with_time(void *h, return rf_uhd_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); } -cf_t data1[1024*100]; -cf_t data2[1024*100]; - int rf_uhd_recv_with_time_multi(void *h, void **data, uint32_t nsamples, diff --git a/srslte/lib/ue/ue_sync.c b/srslte/lib/ue/ue_sync.c index 4cf61bbb3..42aab49e2 100644 --- a/srslte/lib/ue/ue_sync.c +++ b/srslte/lib/ue/ue_sync.c @@ -109,7 +109,7 @@ int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(voi int recv_callback_multi_to_single(void *h, cf_t *x[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t*t) { srslte_ue_sync_t *q = (srslte_ue_sync_t*) h; - return q->recv_callback_single(q->stream, (void*) x[0], nsamples, t); + return q->recv_callback_single(q->stream_single, (void*) x[0], nsamples, t); } int srslte_ue_sync_init(srslte_ue_sync_t *q, @@ -117,8 +117,10 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q, int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler) { + int ret = srslte_ue_sync_init_multi(q, cell, recv_callback_multi_to_single, 1, (void*) q); q->recv_callback_single = recv_callback; - return srslte_ue_sync_init_multi(q, cell, recv_callback_multi_to_single, 1, q); + q->stream_single = stream_handler; + return ret; } int srslte_ue_sync_init_multi(srslte_ue_sync_t *q, @@ -459,13 +461,12 @@ static int receive_samples(srslte_ue_sync_t *q, cf_t *input_buffer[SRSLTE_MAX_PO /* Get N subframes from the USRP getting more samples and keeping the previous samples, if any */ cf_t *ptr[SRSLTE_MAX_PORTS]; - for (int i=0;inof_rx_antennas;i++) { ptr[i] = &input_buffer[i][q->next_rf_sample_offset]; } if (q->recv_callback(q->stream, ptr, q->frame_len - q->next_rf_sample_offset, &q->last_timestamp) < 0) { return SRSLTE_ERROR; } - /* reset time offset */ q->next_rf_sample_offset = 0; From 5934f3a1dfeda9459faa75b00b734bedb0f49cf8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Mar 2017 11:11:17 +0100 Subject: [PATCH 34/38] fixed rsrp computation --- srslte/lib/ch_estimation/chest_dl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srslte/lib/ch_estimation/chest_dl.c b/srslte/lib/ch_estimation/chest_dl.c index 805e5ae41..f198344f0 100644 --- a/srslte/lib/ch_estimation/chest_dl.c +++ b/srslte/lib/ch_estimation/chest_dl.c @@ -421,7 +421,7 @@ float srslte_chest_dl_get_rsrp(srslte_chest_dl_t *q) { // return sum of power received from all tx ports float n = 0; for (int i=0;ilast_nof_antennas;i++) { - n += srslte_vec_acc_ff(q->rsrp[i], q->cell.nof_ports)/q->cell.nof_ports; + n += srslte_vec_acc_ff(q->rsrp[i], q->cell.nof_ports); } return n/q->last_nof_antennas; } From 4dac5d8c63420e6cefbe70e66c54845e572e777e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Mar 2017 13:28:04 +0100 Subject: [PATCH 35/38] fixed 2tx --- srslte/lib/rf/rf_uhd_imp.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/srslte/lib/rf/rf_uhd_imp.c b/srslte/lib/rf/rf_uhd_imp.c index 8a260a7e4..2c6584abc 100644 --- a/srslte/lib/rf/rf_uhd_imp.c +++ b/srslte/lib/rf/rf_uhd_imp.c @@ -60,6 +60,9 @@ void suppress_handler(const char *x) // do nothing } +cf_t zero_mem[64*1024]; + + srslte_rf_error_handler_t uhd_error_handler = NULL; void msg_handler(const char *msg) @@ -276,6 +279,7 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_rx_antennas) } handler->devname = NULL; + bzero(zero_mem, sizeof(cf_t)*64*1024); /* If device type or name not given in args, choose a B200 */ if (args[0]=='\0') { @@ -327,17 +331,6 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_rx_antennas) if (!handler->devname) { handler->devname = "uhd_unknown"; } - size_t channel[4] = {0, 1, 2, 3}; - uhd_stream_args_t stream_args = { - .cpu_format = "fc32", - .otw_format = "sc16", - .args = "", - .channel_list = channel, - .n_channels = nof_rx_antennas - }; - - handler->nof_rx_channels = nof_rx_antennas; - handler->nof_tx_channels = 1; // Set external clock reference if (strstr(args, "clock=external")) { @@ -349,6 +342,18 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_rx_antennas) uhd_sensor_value_make_from_realnum(&handler->rssi_value, "rssi", 0, "dBm", "%f"); } + size_t channel[4] = {0, 1, 2, 3}; + uhd_stream_args_t stream_args = { + .cpu_format = "fc32", + .otw_format = "sc12", + .args = "", + .channel_list = channel, + .n_channels = nof_rx_antennas + }; + + handler->nof_rx_channels = nof_rx_antennas; + handler->nof_tx_channels = 1; + /* Initialize rx and tx stremers */ uhd_rx_streamer_make(&handler->rx_stream); error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args, handler->rx_stream); @@ -604,7 +609,7 @@ int rf_uhd_send_timed(void *h, } void *buff = (void*) &data_c[n]; - const void **buffs_ptr = (const void**) &buff; + const void *buffs_ptr[4] = {buff, zero_mem, zero_mem, zero_mem}; uhd_error error = uhd_tx_streamer_send(handler->tx_stream, buffs_ptr, tx_samples, &handler->tx_md, 3.0, &txd_samples); if (error) { @@ -618,7 +623,7 @@ int rf_uhd_send_timed(void *h, } while (n < nsamples && trials < 100); return nsamples; } else { - const void **buffs_ptr = (const void**) &data; + const void *buffs_ptr[4] = {data, zero_mem, zero_mem, zero_mem}; uhd_tx_metadata_set_start(&handler->tx_md, is_start_of_burst); uhd_tx_metadata_set_end(&handler->tx_md, is_end_of_burst); return uhd_tx_streamer_send(handler->tx_stream, buffs_ptr, nsamples, &handler->tx_md, 0.0, &txd_samples); From 7d8c9a48b3fc67887c1290701b031b4b4310f4f6 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Mar 2017 15:43:17 +0100 Subject: [PATCH 36/38] check valid RA --- srslte/lib/phch/ra.c | 46 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index e830710f5..028a11e23 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -166,7 +166,14 @@ int srslte_ra_ul_dci_to_grant_prb_allocation(srslte_ra_ul_dci_t *dci, srslte_ra_ INFO("n_rb_pusch: %d, prb1: %d, prb2: %d, L: %d\n", n_rb_pusch, grant->n_prb[0], grant->n_prb[1], grant->L_prb); grant->freq_hopping = 1; } - return SRSLTE_SUCCESS; + + if (grant->n_prb[0] + grant->L_prb < nof_prb && + grant->n_prb[1] + grant->L_prb < nof_prb) + { + return SRSLTE_SUCCESS; + } else { + return SRSLTE_ERROR; + } } srslte_mod_t last_mod[8]; @@ -325,15 +332,20 @@ int srslte_ra_dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_ bitmask = dci->type1_alloc.vrb_bitmask; for (i = 0; i < n_rb_type1; i++) { if (bitmask & (1 << (n_rb_type1 - i - 1))) { - grant->prb_idx[0][((i + shift) / P) + if ((((i + shift) / P) + * P * P + dci->type1_alloc.rbg_subset * P + (i + shift) % P) < nof_prb) { + grant->prb_idx[0][((i + shift) / P) * P * P + dci->type1_alloc.rbg_subset * P + (i + shift) % P] = true; - grant->nof_prb++; + grant->nof_prb++; + } else { + return SRSLTE_ERROR; + } } } memcpy(&grant->prb_idx[1], &grant->prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool)); break; case SRSLTE_RA_ALLOC_TYPE2: - if (dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) { + if (dci->type2_alloc.mode == SRSLTE_RA_TYPE2_LOC) { for (i = 0; i < dci->type2_alloc.L_crb; i++) { grant->prb_idx[0][i + dci->type2_alloc.RB_start] = true; grant->nof_prb++; @@ -379,17 +391,31 @@ int srslte_ra_dl_dci_to_grant_prb_allocation(srslte_ra_dl_dci_t *dci, srslte_ra_ + N_tilde_vrb * (n_vrb / N_tilde_vrb); if (n_tilde_prb_odd < N_tilde_vrb / 2) { - grant->prb_idx[0][n_tilde_prb_odd] = true; + if (n_tilde_prb_odd < nof_prb) { + grant->prb_idx[0][n_tilde_prb_odd] = true; + } else { + return SRSLTE_ERROR; + } } else { - grant->prb_idx[0][n_tilde_prb_odd + N_gap - - N_tilde_vrb / 2] = true; + if (n_tilde_prb_odd + N_gap - N_tilde_vrb / 2 < nof_prb) { + grant->prb_idx[0][n_tilde_prb_odd + N_gap - N_tilde_vrb / 2] = true; + } else { + return SRSLTE_ERROR; + } } grant->nof_prb++; if (n_tilde_prb_even < N_tilde_vrb / 2) { - grant->prb_idx[1][n_tilde_prb_even] = true; + if(n_tilde_prb_even < nof_prb) { + grant->prb_idx[1][n_tilde_prb_even] = true; + } else { + return SRSLTE_ERROR; + } } else { - grant->prb_idx[1][n_tilde_prb_even + N_gap - - N_tilde_vrb / 2] = true; + if (n_tilde_prb_even + N_gap - N_tilde_vrb / 2 < nof_prb) { + grant->prb_idx[1][n_tilde_prb_even + N_gap - N_tilde_vrb / 2] = true; + } else { + return SRSLTE_ERROR; + } } } } From 18251002e26032a63908046d3f060d5b3753c63d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Mar 2017 15:46:15 +0100 Subject: [PATCH 37/38] removed error messages in invalid RA --- srslte/lib/phch/dci.c | 1 - srslte/lib/phch/ra.c | 1 - 2 files changed, 2 deletions(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 4561d64c3..0a31f8975 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -112,7 +112,6 @@ int srslte_dci_rar_to_ul_grant(srslte_dci_rar_grant_t *rar, uint32_t nof_prb, nof_prb, nof_prb); if (srslte_ra_ul_dci_to_grant(ul_dci, nof_prb, n_rb_ho, grant, 0)) { - fprintf(stderr, "Error computing resource allocation\n"); return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/ra.c b/srslte/lib/phch/ra.c index 028a11e23..f2164ec1b 100644 --- a/srslte/lib/phch/ra.c +++ b/srslte/lib/phch/ra.c @@ -252,7 +252,6 @@ int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, uint32_t nof_prb, uint32_ return SRSLTE_ERROR; } } else { - fprintf(stderr, "Error computing PRB allocation\n"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; From 7c835992e08e316eb6310cd286389a6ba4005d45 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 9 Mar 2017 15:47:21 +0100 Subject: [PATCH 38/38] removed error messages in invalid RA --- srslte/lib/phch/dci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/srslte/lib/phch/dci.c b/srslte/lib/phch/dci.c index 0a31f8975..3c2f04856 100644 --- a/srslte/lib/phch/dci.c +++ b/srslte/lib/phch/dci.c @@ -178,7 +178,6 @@ int srslte_dci_msg_to_ul_grant(srslte_dci_msg_t *msg, uint32_t nof_prb, } if (srslte_ra_ul_dci_to_grant(ul_dci, nof_prb, n_rb_ho, grant, harq_pid)) { - fprintf(stderr, "Error computing resource allocation\n"); return ret; }