From d3ce6e83f01c72a3dc54078538d74d5ab61fd2e0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 28 Apr 2016 17:57:46 +0200 Subject: [PATCH] Added Matlab pusch verification model --- matlab/tests/ce | Bin 0 -> 6912 bytes matlab/tests/d | Bin 0 -> 6912 bytes matlab/tests/pdsch_bler.m | 2 - .../{pdsch_bler_equal.m => pdsch_equal.m} | 0 matlab/tests/pusch_bler.m | 188 +++++++++++ .../{pusch_test.m => pusch_encode_test.m} | 20 +- matlab/tests/sf_symbols | Bin 0 -> 8064 bytes matlab/tests/z | Bin 0 -> 6912 bytes srslte/lib/phch/prach.c | 2 +- srslte/lib/phch/pusch.c | 4 +- srslte/lib/phch/test/CMakeLists.txt | 2 + srslte/lib/phch/test/prach_detect_test_mex.c | 113 +++++++ srslte/lib/phch/test/pusch_encode_test_mex.c | 33 +- srslte/lib/phch/test/pusch_test_mex.c | 308 ++++++++++++++++++ 14 files changed, 638 insertions(+), 34 deletions(-) create mode 100644 matlab/tests/ce create mode 100644 matlab/tests/d rename matlab/tests/{pdsch_bler_equal.m => pdsch_equal.m} (100%) create mode 100644 matlab/tests/pusch_bler.m rename matlab/tests/{pusch_test.m => pusch_encode_test.m} (74%) create mode 100644 matlab/tests/sf_symbols create mode 100644 matlab/tests/z create mode 100644 srslte/lib/phch/test/prach_detect_test_mex.c create mode 100644 srslte/lib/phch/test/pusch_test_mex.c diff --git a/matlab/tests/ce b/matlab/tests/ce new file mode 100644 index 0000000000000000000000000000000000000000..cefc6508efb16163af5a44fcd9594b9cb60e5f12 GIT binary patch literal 6912 zcmeIyF%19!2m`P=!y3{FxF9JH|FSjd%AGHVO+XLyKo9JI103K02ROh14sd`29N+*4 RIKTl8aDW3G-~b1HJ21W6gueg) literal 0 HcmV?d00001 diff --git a/matlab/tests/d b/matlab/tests/d new file mode 100644 index 0000000000000000000000000000000000000000..3ad03af0688ef97e64cf388024f1bbe11e50afc3 GIT binary patch literal 6912 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 + 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_pusch(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_test.m b/matlab/tests/pusch_encode_test.m similarity index 74% rename from matlab/tests/pusch_test.m rename to matlab/tests/pusch_encode_test.m index 9bfac1dfb..13a94a7b5 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_encode_test.m @@ -1,12 +1,12 @@ -ueConfig=struct('NCellID',1,'NULRB',50,'CyclicPrefixUL','Normal','NTxAnts',1,'RNTI',64); +ueConfig=struct('NCellID',1,'NULRB',6,'CyclicPrefixUL','Normal','NTxAnts',1,'RNTI',64); puschConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'NBundled',0); -addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test') +addpath('../../build//srslte/lib/phch/test') -cqilen=[0 20]; +cqilen=[0 4 20]; mods={'64QAM'}; rvs=0; -betas=[0 2.0 2.5 5.0, 20.0]; +betas=[0 5.0, 20.0]; for p=1:ueConfig.NULRB for i=0:26 for m=1:length(mods) @@ -40,7 +40,6 @@ for p=1:ueConfig.NULRB 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); @@ -49,16 +48,11 @@ for p=1:ueConfig.NULRB %drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig); subframe_mat = lteULResourceGrid(ueConfig); subframe_mat(idx)=cw_mat; - %subframe_mat(drs_idx)=drs; - waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0); - [waveform_lib, subframe_lib, cwlib, bits]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit); - err=max(abs(waveform-waveform_lib)); + [~, 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) - disp(err) - t=1:200; - %plot(t,bits(t),t,cw_scram(t)) - plot(abs(double(bits)-double(cw_scram))) + plot(abs(subframe_mat(:)-subframe_lib)) error('Error!'); end end diff --git a/matlab/tests/sf_symbols b/matlab/tests/sf_symbols new file mode 100644 index 0000000000000000000000000000000000000000..c18c441e421bd28c2d69529881290fb5cc75af11 GIT binary patch literal 8064 zcmeI1_g~Nd_x~%2qN1TqNrNIZkmuu^WMq_)j7Vi=MjEIHX-I?8B4wr&k`$@OIS5H* z%j}g^kuow$p>N;6;q&YJ{`=!{xnFLN%k6%<-p+a9kb!PDRZ! z5E8MUa|K^)Poy6yS@hhX6#s}Z?Cv&)Y>y#pjL0VQ*u(TPumC0v)92*%hafhrsli()&6%rjoD#=wjjFI@&XE4i8u`S{$`@8#zV{WTOl-yFqpXd8Bq+B>NhgV7UJP3{|wiZ53-pbRU5$KPlqV7u#UivurlluEo8!^`n5J+3foz zS%|x31s9j*iwawTpPe|4m;56kZeCBW`LUh%U7P}!9$KOKc^!6cPXy_RGJbyc9$Fa| z!y)aFNUn}Fue^~LMn<4XpG;w`bPtS=zlTp+ZK3ttZu0n^LC61zeDB~KwEJ_Iy@NW1 zbpt`mKV)d5q1he`pA(E$ zJ#{cr`!dI_eIxF!-i4F9YC%5Go0RgF@}m2rF*a6{o17POo4X<%x}uND`EhLWGnv(1 z+H+ZlGWQ650i*Liz+0!QRR5p{TP&FcK0bped9)KyeFP? z&c{_u^imLyg}I~F9T%~m*ImgwiwlBs$_+YcqmIMwS@6#*qagTWKS9^?DEBR~q$Z65 zdX-%SZLP22jp-R^KK_M$E=JS5Zhr;)d%)`7PleyAfUgQ)faRgtJmtbZM9*Yg^wJsM z=A_WSzbSMzXCKBsGUwH!$5Z@)x8k{F`)JUkPyFWbZ*fwkfNw9xK(WFIE|89grUVa; zPRitdp|`-p#uh5Bdy!7P1ALt}gx%v8ae8VQ>@@mB9mYnOIW7!KEsyY+>`V&quM>O! zP81iZ%mBM#C3sowG+4_&r}V?;;Ae(rY5k{Mihq9qE=*m9-=m+|8ohfhOpa?~EqhC{ z7&4h18;jxc^X)WyNfSxhELhssAA)^m0Q(3+^^#fTil;*kNN5J|@ zBjnxgfLXU}@L}0?_*G%SuFlnTP~!}EejI=?$M=3@o}8;do<^(G?LVXB$$8I1kI03L4TE__;}(W z0cU<0_w-je*PR}YcIPFS5|hMQo%>)`*-1XroC+0IX}s@lImwz3wDj01=!(+pTgjM~O=#8@ zE4B+2Kt28x|0yvh)5*7JMwlgsBx{pm(l4rLss!8CUfA(Ap5C;)=Cto>f_J+b#4V|Z ze>E9mUsuG(>hriN`5T;ZS;|FSQ~0OtetuFN$=iMbWIZ?Je%3bNSJ5SmYR=@V(O+rC z@HTS0JD+Vc=xq4=_XR!MJ3^Qq6~Qihhl3{{k<8wG2EM)S zpp-8SbgWI4?+4!&=jUF*wg4kcc1$GYb(7J|&<36G7=8Y3PW_w`$lYfg-S)2&mZz9- z-!?sT{dNu3%=4#v!4rh%_YTpz*p<9WCj$cJSU|5c`}qCOwcOPjf_oc$xg@~{BeoUs z!dLHwG0*Qn{G?NKxnU%0I3=LmKp9an-jwV|ox?E+rtrQ0SC|}F2?OS5fXb9|TAuJu zGPuy06-FKBY`rA#?5&OF|60Ux3#9qOkog?$S4Sapv)O0#9okx=iO>Hc8vPr|)oZ8H z8=dj2AFs+g+BdP?1!+EaE`#yY= zisZd1CTJ}?i^cVdS7RrKv*xaNuwHjX7;z$*^mQ}gRc0Z-FYS+80>|KXy#&eK11+RD zauThNHiCl8)AZFRkE^qeg5j#8tlJd`(^VXCv!xz}o(#hg&BlCjVJIl}2%wUM-|1*? zWi(E_giqg|M3+8M9N;&b5BG4w%E8KlxAz-Z+^Qz-wYdUn>r!|lD#F85DQtPCgWs2^ zb8pQ)9Ml#I!ETS>g_#wW1?hvbLKkW%NN|$WIdP?HDP8CngQMq{3O<)Kp-g9-cs`dQ zw8arWx?K{Qa<%cDi#NLz6~dXde$=@+o(pdH(ybd-ywO_$M$c6vvqSa_@=9DN9}Eo! z&G7$OepfdG70w-uqdv%sq3}*j8_+`YvM1xu9g6&^N`)_byO8z8zHFj+PkfYpmkg?6 zN%ev)tLH~ho?01MIQhcZ-8uZvMhm@yWLT*x12@Z_Ww)UbXg}Z=%-B~1TjZ?q^L1mK z*18a~9_wOJKSf@)yq?4KBXNas3K-5zq&fYDU}|ejJwKAK zb24uzjl~(h0la48VK`_RMjX+D_Lf(pPWl;iT_r_X&at$>&K~me{2^#!6#9i!Nd|6} zL7huR&@w3vn$rfOa?Ao$`T0g-mU^ELU%NzU**_(JDwd+hgxBDyq{_bn?ac|!@$3k5|PTX?-*C6mI!0U*g~zm2`tRe!rp$VC@kC~hL)JX#8GE?P^&E`=D(wn zkK*~admQa<_aaef!LOG*q4aGWN`0|o{2Pv2{Ro@7^_k#b2O-C+VQ!r=|M2nW+?NS> z%S#%4uGhnvcV0BwDxXw5d$QAVWZ$#K{O+j(w6ALt8MBPdH4nXG+mwQ>0*5SU?9o2BOS8Z836^8!rky zE@ofRqM@q{|CQF@wd-Yge(V>jtc*vc16pX8SW_BFPFV5X4Ba<|;h%nvI5d4c zUrd_LyeyPjXr^FO9s(ye%dl~`KK(*Ikfy9GU-sJ!rPUjRoC)n%q_lt?=l23RVAKWyLtPB@oQB0r-G6}hVx4867lGxhF}urZ3terTe_`kv^sv>0-RouZsD87#N>3<(-3JZbkZ zoVd7B7;!EE^jm*I{}_FqTob|OUu#LdaVNy545hxPihB#~(0_I-thu9Z*K5faczwuG z?ESck%Kux6+q=7awQrs9GqvwHm1#kox7ma>hanawJOGvJ!}(Bm1_f7426>FOu;0)%HT!?F<^cS_GA>eZ2qkuTt|N`6Mwa<-6HiFlHYMhNg3& z%|8d{%QuJvZff8eVF0{a-3yndj^oAGEcjKI2*n4>g`>{KR2fhwHY^OKs0rzK`sy9( z@w-d7>lcj~QbW2gbq4&bhVrHTC*Y_062Z4uj^t;UJ?l+0fcZ@aNp;zFd?T-oqb3#8 zfEqJw&eEqR?+#Gb%_wd!{3KrbbA@-}VDN2y20Sj8k2xp_TZbMKW_A^DWc-Wq-YfUQ zyB`PPVOlDT+qfHc4;jNZR9h)+_I_*_q=RK7$Ibeg@b;J!sp=Pl=cWLt_g3Ss6AIW- zd_nwrxmnaUbK+&~yU_A-2u}HIBL>Jv(ccw&aFvHD9yu+4_1nf2SSiyJ%U8|aeq9*(3u}IBg>s8H~o;OU>-MKGwqhDSfDOf(Jze8S~sWOJTji1EET3Fe-I3!o2Q0 z9Xw!>ut?!4BszVDm*-`%V$NprM1B0)dyE(?6w!FuFOp~{ZC)_9O;GdG=3>1B&fd}= zr#Z>ellX_F;i~5aHPe}N8+)^3#Yv2*IfsT0D)?=vJQm!31*+10IM(3~jEaj#|BVM} z>|9q`wO}PqST_m2w%@_V1)(tS$4wgD%^F|2JI3{r8Eka*k~p>emBg(7UGe5L0#*JE zL#>Wr>w`B?nYfpO-C|4i^AXkFl?uRe zMh`>7p1O3y?y7ivO&;I~+kF<~2{|Dm=uh zx-9JNKOFC0mbH8QzEfPKABNjE>*4r^58(4LRqj()Mssai=+I0#=%w&ym77jNL$F%_y*d|zxHY;>ApuEr|UcRz~QuH+O@qyhOa9|Xz@Up`% z|Bc~`}fc}_9K;dv(L!x{7M=XM3;lc3ct?WDm`Ib0@sh2vfpuk9&*zc7X}Rl zPm5e(&a{c5iZ~oUkGddMNPiY47tKYDYF!vp{!OSl69w5p_B5V0(3I)BxPOlg;|Ctk z1QqpcO1rpP+71T3&j$F7^p`G&;@q5Ai8_^`h(n%uR( zQHv@>w=fgY5wYQQ0? zreb5G(p9aK^Vlmb97DgP;99GmylL+UxVgL@CtmtWF@AEm#s8?-;AO~}6M}HPfi5UK z>Y(^B)5&^vGHmRMVW~|5F1R}lR(;gs?^_X8G|RKhwIq^ww27OC3=yW*?xljNA$a|i z6V9r#0JnBE)?6NpvNerRzP%qe47mjdhe%1DcLj5DkrWxsIspZDjCsvSJz6~RIphyc z1xu4S&}h*FzrPzWIpk64?yhKDGi;GCAXT2N3!-6y=6=Z4Tu2jBG_WxA06#Py#+mgt zqQfL5{@P%~`}f3>;SLu*-l+*quVguWR~kUA7wnjKi*|PB*D;$bWaoR2U)>+fGlKnj zm(&Hg8E8Q7ci3`cqbo0#3*sAIdh9M`Nu|}lggx5L;=gB+eCLBTE04X;LxZ;9yf^!? z&`_3@v*)lKtVVY;N8z{oV00+Z#g(hif!p;h>^n1*`+c`S+wS~*X+0WLU+%_}yhrfZ zu?s%8CSXL`W7z%!Z4z8VX-Ldo4mY_Dan|2}K7OXUjQ#j+>p)@3FJ(t<@KK!q;42j;EF-0z4{T0$^XkZ&OXLvc zKqk)D#BGvEyr%Rhx_qdhg5V}`yoM`2_8rP@=Qr_D4{4e(HG@oiYe3U!H;=lz1WxN) z;hg%L!sVjxqTMi6?s0M*OW&#I`|iv2kKCGX*%6XxkDfSN%K=53w-rZ7mvIxf*~Dh@VdK$ zg?v%Lt#fK{q}oDghz%tJ&mPq9xEb=>2-RysQAmsC1qakoUA_!X+?!99c{5M!}L$T$3B}pfThy_Q#ld7jO>wdTZMplfq z9e?1<>It~)n*to|T}E*5G>w?yJU(gtHL7V#LYVD-YI%^>Z^M3?5IkycAF~O+?>QQ-TQ>K=U-B; zS{2x}PKQp_Xjq@~P%>t8EmSL>gwLyW$T&WeZ1y}7#m9H(Yv@MF0nN*x=+yv<_uTp2 zEjj%A$rxweYNd-qB898zM!X>>1{Y_gvV1pdjBisD4KzlxTVW)=%r-*V{(s2aEeYq& zs}Za6?BS{WI@Isxxl6fqlE3LkNLM@ycl9h#*6so%9#qBOU*veD{$x_`GYnG{`<325 zWegT^8?dw>oNv^-aIb|sq24?S3)~symA7!j_>H{x{V3Kmx24D*JwdBX10A27gd*X& zu=cl_u)TYpaMRnE7nwz&VZbyteAy<(FWAVvPR6nPw$ms(Po95W9>k|iehV7f`TVOj zMo=n~!$`%wT-L{(F6L|CgEJ3H%d`fdal9_i@%tqH@KR%0s{pWk*v&8p%Ow*x-3DcU z1C;YR53i?&QH5m@tXVAbmhTpzaUzex3?sRIm`-;t_#*sA9H)JUw2nL!KJ=fC$*Em1 zaaS`m>)oR++J}C!FU1|3?u#3TBy*P4Wtb8?8=h$Q5nZ=9(zf`1SCut;+4Zapq-oW% zydyOSydy$!PlKlzdcqg}2KwTx1`8fOD-KlaZqjl`4;(pm7N2}P3p)>IQCy#NZoXd* M;hj5BvHxoRe??m;KL7v# literal 0 HcmV?d00001 diff --git a/matlab/tests/z b/matlab/tests/z new file mode 100644 index 0000000000000000000000000000000000000000..3ad03af0688ef97e64cf388024f1bbe11e50afc3 GIT binary patch literal 6912 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 - INFO("srslte_prach_detect: Signal is not of length %d", p->N_ifft_prach); + fprintf(stderr, "srslte_prach_detect: Signal is not of length %d", p->N_ifft_prach); return SRSLTE_ERROR_INVALID_INPUTS; } diff --git a/srslte/lib/phch/pusch.c b/srslte/lib/phch/pusch.c index 9bd5ce200..322fe4475 100644 --- a/srslte/lib/phch/pusch.c +++ b/srslte/lib/phch/pusch.c @@ -553,10 +553,10 @@ int srslte_pusch_uci_decode(srslte_pusch_t *q, // Equalization srslte_predecoding_single(q->d, q->ce, q->z, cfg->nbits.nof_re, noise_estimate); - + // DFT predecoding srslte_dft_predecoding(&q->dft_precoding, q->z, q->d, cfg->grant.L_prb, cfg->nbits.nof_symb); - + // Soft demodulation srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); diff --git a/srslte/lib/phch/test/CMakeLists.txt b/srslte/lib/phch/test/CMakeLists.txt index ea1d14aca..6f9653f85 100644 --- a/srslte/lib/phch/test/CMakeLists.txt +++ b/srslte/lib/phch/test/CMakeLists.txt @@ -133,6 +133,7 @@ target_link_libraries(pusch_test srslte) BuildMex(MEXNAME ulsch_encode SOURCES ulsch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) BuildMex(MEXNAME pusch_encode SOURCES pusch_encode_test_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME pusch SOURCES pusch_test_mex.c LIBRARIES srslte_static srslte_mex) add_test(pusch_test pusch_test) @@ -191,6 +192,7 @@ add_test(prach_test_multi_n4 prach_test_multi -n 4) BuildMex(MEXNAME prach SOURCES prach_test_mex.c LIBRARIES srslte_static srslte_mex) +BuildMex(MEXNAME prach_detect SOURCES prach_detect_test_mex.c LIBRARIES srslte_static srslte_mex) if(UHD_FOUND) diff --git a/srslte/lib/phch/test/prach_detect_test_mex.c b/srslte/lib/phch/test/prach_detect_test_mex.c new file mode 100644 index 000000000..49a45fc99 --- /dev/null +++ b/srslte/lib/phch/test/prach_detect_test_mex.c @@ -0,0 +1,113 @@ +/** + * + * \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 +#define FORCE_POWER2_FFT +#include "srslte/srslte.h" +#include "srslte/mex/mexutils.h" + +/** MEX function to be called from MATLAB to test the channel estimator + */ + +#define UECFG prhs[0] +#define PRACHCFG prhs[1] +#define INPUT prhs[2] +#define NOF_INPUTS 3 + +void help() +{ + mexErrMsgTxt + ("[preamble, offset] = srslte_prach(ueConfig, prachConfig, signal)\n\n"); +} + +/* the gateway function */ +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + + if (nrhs != NOF_INPUTS) { + help(); + return; + } + + uint32_t n_ul_rb = 0; + if (mexutils_read_uint32_struct(UECFG, "NULRB", &n_ul_rb)) { + mexErrMsgTxt("Field NULRB not found in UE config\n"); + return; + } + int r = srslte_symbol_sz(n_ul_rb); + if (r < 0) { + mexErrMsgTxt("Invalid NULRB\n"); + return; + } + uint32_t N_ifft_ul = (uint32_t) r; + + uint32_t sf_idx = 0; + mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx); + uint32_t nframe = 0; + mexutils_read_uint32_struct(UECFG, "NFrame", &nframe); + + uint32_t preamble_format = 0; + mexutils_read_uint32_struct(PRACHCFG, "Format", &preamble_format); + uint32_t root_seq_idx = 0; + mexutils_read_uint32_struct(PRACHCFG, "SeqIdx", &root_seq_idx); + uint32_t seq_idx = 0; + mexutils_read_uint32_struct(PRACHCFG, "PreambleIdx", &seq_idx); + uint32_t zero_corr_zone = 0; + mexutils_read_uint32_struct(PRACHCFG, "CyclicShiftIdx", &zero_corr_zone); + uint32_t high_speed_flag = 0; + mexutils_read_uint32_struct(PRACHCFG, "HighSpeed", &high_speed_flag); + uint32_t timing_offset = 0; + mexutils_read_uint32_struct(PRACHCFG, "TimingOffset", &timing_offset); + uint32_t frequency_offset = 0; + mexutils_read_uint32_struct(PRACHCFG, "FreqOffset", &frequency_offset); + + srslte_prach_t prach; + if (srslte_prach_init(&prach, N_ifft_ul, preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone)) { + mexErrMsgTxt("Error initiating PRACH\n"); + return; + } + + cf_t *input_signal = NULL; + int nof_samples = mexutils_read_cf(INPUT, &input_signal); + + uint32_t preambles[64]; + uint32_t nof_detected = 0; + mexPrintf("nof_samples=%d\n", nof_samples); + if (srslte_prach_detect(&prach, frequency_offset, input_signal, nof_samples, preambles, &nof_detected)) { + mexErrMsgTxt("Error detecting PRACH\n"); + return; + } + + if (nlhs >= 1) { + mexutils_write_int((int*) preambles, &plhs[0], nof_detected, 1); + } + + free(input_signal); + srslte_prach_free(&prach); + + return; +} + diff --git a/srslte/lib/phch/test/pusch_encode_test_mex.c b/srslte/lib/phch/test/pusch_encode_test_mex.c index 0e9a0d7f2..02bf3ecd7 100644 --- a/srslte/lib/phch/test/pusch_encode_test_mex.c +++ b/srslte/lib/phch/test/pusch_encode_test_mex.c @@ -101,7 +101,6 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Unknown modulation\n"); return; } - mxFree(mod_str); float *prbset = NULL; @@ -135,20 +134,18 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) grant.Qm = srslte_mod_bits_x_symbol(grant.mcs.mod); if (srslte_pusch_cfg(&pusch, &cfg, &grant, NULL, NULL, NULL, cfg.sf_idx, cfg.rv, 0)) { - fprintf(stderr, "Error configuring PDSCH\n"); + fprintf(stderr, "Error configuring PUSCH\n"); exit(-1); } mexPrintf("L_prb: %d, n_prb: %d\n", grant.L_prb, grant.n_prb[0]); - srslte_softbuffer_tx_t softbuffer; if (srslte_softbuffer_tx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); return; } - uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp); cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re); if (!sf_symbols) { @@ -215,19 +212,23 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } } - cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - srslte_ofdm_t fft; - srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb); - srslte_ofdm_set_normalize(&fft, true); - srslte_ofdm_set_freq_shift(&fft, 0.5); - srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma); - // Matlab toolbox expects further normalization - srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb)); - if (nlhs >= 1) { + + cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); + bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); + srslte_ofdm_t fft; + srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb); + srslte_ofdm_set_normalize(&fft, true); + srslte_ofdm_set_freq_shift(&fft, 0.5); + srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma); + // Matlab toolbox expects further normalization + srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb)); + mexutils_write_cf(scfdma, &plhs[0], SRSLTE_SF_LEN_PRB(cell.nof_prb), 1); + + free(scfdma); + } if (nlhs >= 2) { mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1); @@ -238,10 +239,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) if (nlhs >= 4) { mexutils_write_uint8(pusch.q, &plhs[3], cfg.nbits.nof_bits, 1); } - srslte_pusch_free(&pusch); + srslte_pusch_free(&pusch); + srslte_softbuffer_tx_free(&softbuffer); free(trblkin); free(sf_symbols); - free(scfdma); return; } diff --git a/srslte/lib/phch/test/pusch_test_mex.c b/srslte/lib/phch/test/pusch_test_mex.c new file mode 100644 index 000000000..92589e5e5 --- /dev/null +++ b/srslte/lib/phch/test/pusch_test_mex.c @@ -0,0 +1,308 @@ +/** + * + * \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 channel estimator + */ + +#define UECFG prhs[0] +#define PUSCHCFG prhs[1] +#define TBS prhs[2] +#define INPUT prhs[3] +#define NOF_INPUTS 4 + +void help() +{ + mexErrMsgTxt + ("[decoded_ok, cqi_data, ri_data, ack_data] = srslte_pusch(ueConfig, puschConfig, trblklen, rxWaveform)\n\n"); +} + +extern int indices[2048]; + +int rv_seq[4] = {0, 2, 3, 1}; + +/* the gateway function */ +void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) +{ + srslte_ofdm_t ofdm_tx; + srslte_pusch_t pusch; + srslte_chest_ul_t chest; + cf_t *input_fft; + srslte_softbuffer_rx_t softbuffer; + uint32_t rnti32; + + if (nrhs < NOF_INPUTS) { + help(); + return; + } + + srslte_verbose = SRSLTE_VERBOSE_INFO; + + srslte_cell_t cell; + bzero(&cell, sizeof(srslte_cell_t)); + cell.nof_ports = 1; + if (mexutils_read_uint32_struct(UECFG, "NCellID", &cell.id)) { + mexErrMsgTxt("Field NCellID not found in UE config\n"); + return; + } + if (mexutils_read_uint32_struct(UECFG, "NULRB", &cell.nof_prb)) { + mexErrMsgTxt("Field NULRB not found in UE config\n"); + return; + } + + srslte_pusch_cfg_t cfg; + bzero(&cfg, sizeof(srslte_pusch_cfg_t)); + if (mexutils_read_uint32_struct(UECFG, "RNTI", &rnti32)) { + mexErrMsgTxt("Field RNTI not found in pdsch config\n"); + return; + } + + if (mexutils_read_uint32_struct(UECFG, "NSubframe", &cfg.sf_idx)) { + help(); + return; + } + + if (srslte_ofdm_rx_init(&ofdm_tx, cell.cp, cell.nof_prb)) { + fprintf(stderr, "Error initializing FFT\n"); + return; + } + srslte_ofdm_set_normalize(&ofdm_tx, true); + srslte_ofdm_set_freq_shift(&ofdm_tx, 0.5); + + if (srslte_pusch_init(&pusch, cell)) { + mexErrMsgTxt("Error initiating PDSCH\n"); + return; + } + srslte_pusch_set_rnti(&pusch, (uint16_t) (rnti32 & 0xffff)); + + if (srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb)) { + mexErrMsgTxt("Error initiating soft buffer\n"); + return; + } + + if (srslte_chest_ul_init(&chest, cell)) { + mexErrMsgTxt("Error initializing equalizer\n"); + return; + } + + srslte_ra_ul_grant_t grant; + bzero(&grant, sizeof(srslte_ra_ul_grant_t)); + + char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation"); + if (!strcmp(mod_str, "QPSK")) { + grant.mcs.mod = SRSLTE_MOD_QPSK; + } else if (!strcmp(mod_str, "16QAM")) { + grant.mcs.mod = SRSLTE_MOD_16QAM; + } else if (!strcmp(mod_str, "64QAM")) { + grant.mcs.mod = SRSLTE_MOD_64QAM; + } else { + mexErrMsgTxt("Unknown modulation\n"); + return; + } + mxFree(mod_str); + + grant.mcs.tbs = mxGetScalar(TBS); + if (grant.mcs.tbs == 0) { + mexErrMsgTxt("Error trblklen is zero\n"); + return; + } + + uint32_t N_srs = 0; + mexutils_read_uint32_struct(PUSCHCFG, "Shortened", &N_srs); + if (N_srs == 1) { + pusch.shortened = true; + } + + float *prbset = NULL; + mxArray *p; + p = mxGetField(PUSCHCFG, 0, "PRBSet"); + if (!p) { + mexErrMsgTxt("Error field PRBSet not found\n"); + return; + } + + grant.L_prb = mexutils_read_f(p, &prbset); + grant.n_prb[0] = prbset[0]; + grant.n_prb[1] = prbset[0]; + free(prbset); + + grant.M_sc = grant.L_prb*SRSLTE_NRE; + grant.M_sc_init = grant.M_sc; // FIXME: What should M_sc_init be? + grant.Qm = srslte_mod_bits_x_symbol(grant.mcs.mod); + + if (srslte_cbsegm(&cfg.cb_segm, grant.mcs.tbs)) { + mexErrMsgTxt("Error computing CB segmentation\n"); + return; + } + + if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &cfg.rv)) { + mexErrMsgTxt("Field RV not found in pdsch config\n"); + return; + } + + uint32_t max_iterations = 5; + mexutils_read_uint32_struct(PUSCHCFG, "NTurboDecIts", &max_iterations); + + /* Configure rest of pdsch_cfg parameters */ + if (srslte_pusch_cfg(&pusch, &cfg, &grant, NULL, NULL, NULL, cfg.sf_idx, cfg.rv, 0)) { + fprintf(stderr, "Error configuring PDSCH\n"); + exit(-1); + } + + srslte_uci_data_t uci_data; + bzero(&uci_data, sizeof(srslte_uci_data_t)); + + mexutils_read_uint32_struct(PUSCHCFG, "OCQI", &uci_data.uci_cqi_len); + mexutils_read_uint32_struct(PUSCHCFG, "ORI", &uci_data.uci_ri_len); + mexutils_read_uint32_struct(PUSCHCFG, "OACK", &uci_data.uci_ack_len); + + float beta; + if (mexutils_read_float_struct(PUSCHCFG, "BetaCQI", &beta)) { + cfg.uci_cfg.I_offset_cqi = 7; + } else { + cfg.uci_cfg.I_offset_cqi = srslte_sch_find_Ioffset_cqi(beta); + } + if (mexutils_read_float_struct(PUSCHCFG, "BetaRI", &beta)) { + cfg.uci_cfg.I_offset_ri = 2; + } else { + cfg.uci_cfg.I_offset_ri = srslte_sch_find_Ioffset_ri(beta); + } + if (mexutils_read_float_struct(PUSCHCFG, "BetaACK", &beta)) { + cfg.uci_cfg.I_offset_ack = 0; + } else { + cfg.uci_cfg.I_offset_ack = srslte_sch_find_Ioffset_ack(beta); + } + mexPrintf("TRBL_len: %d, CQI_len: %2d, ACK_len: %d (%d), RI_len: %d (%d)\n", grant.mcs.tbs, + uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ack, uci_data.uci_ri_len, uci_data.uci_ri); + + mexPrintf("I_cqi: %2d, I_ri: %2d, I_ack=%2d\n", cfg.uci_cfg.I_offset_cqi, cfg.uci_cfg.I_offset_ri, cfg.uci_cfg.I_offset_ack); + + + mexPrintf("L_prb: %d, n_prb: %d/%d, TBS=%d\n", grant.L_prb, grant.n_prb[0], grant.n_prb[1], grant.mcs.tbs); + + /** Allocate input buffers */ + int nof_retx=1; + if (mexutils_isCell(INPUT)) { + nof_retx = mexutils_getLength(INPUT); + } + + cf_t *ce = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));; + + uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8); + if (!data_bytes) { + return; + } + srslte_sch_set_max_noi(&pusch.dl_sch, max_iterations); + + input_fft = NULL; + int r=-1; + for (int rvIdx=0;rvIdx 1) { + cfg.rv = rv_seq[rvIdx%4]; + } + } + + // Read input signal + cf_t *input_signal = NULL; + int insignal_len = mexutils_read_cf(tmp, &input_signal); + if (insignal_len < 0) { + mexErrMsgTxt("Error reading input signal\n"); + return; + } + if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) { + input_fft = input_signal; + mexPrintf("Input is after fft\n"); + } else { + input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); + srslte_ofdm_rx_sf(&ofdm_tx, input_signal, input_fft); + mexPrintf("Input is before fft\n"); + free(input_signal); + } + + if (nrhs > NOF_INPUTS) { + cf_t *cearray = NULL; + mexutils_read_cf(prhs[NOF_INPUTS], &cearray); + cf_t *cearray_ptr = cearray; + for (int j=0;j NOF_INPUTS + 1) { + noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); + } else if (nrhs > NOF_INPUTS) { + noise_power = 0; + } else { + noise_power = srslte_chest_ul_get_noise_estimate(&chest); + } + + r = srslte_pusch_uci_decode(&pusch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes, &uci_data); + } + + uint8_t *data = malloc(grant.mcs.tbs); + srslte_bit_unpack_vector(data_bytes, data, grant.mcs.tbs); + + if (nlhs >= 1) { + plhs[0] = mxCreateLogicalScalar(r == 0); + } + if (nlhs >= 2) { + mexutils_write_uint8(uci_data.uci_cqi, &plhs[1], uci_data.uci_cqi_len, 1); + } + if (nlhs >= 3 && uci_data.uci_ri_len <= 1) { + mexutils_write_uint8(&uci_data.uci_ri, &plhs[2], uci_data.uci_ri_len, 1); + } + if (nlhs >= 4 && uci_data.uci_ack_len <= 1) { + mexutils_write_uint8(&uci_data.uci_ack, &plhs[3], uci_data.uci_ack_len, 1); + } + + srslte_softbuffer_rx_free(&softbuffer); + srslte_chest_ul_free(&chest); + srslte_pusch_free(&pusch); + srslte_ofdm_rx_free(&ofdm_tx); + + free(ce); + free(data_bytes); + free(data); + if (input_fft) { + free(input_fft); + } + + return; +} +