From 75357c8526374549654e93d064de8d38f7d8fb09 Mon Sep 17 00:00:00 2001 From: ismagom Date: Sun, 13 Mar 2016 23:08:53 +0100 Subject: [PATCH] Added Matlab tests to verify PDSCH BLER --- matlab/tests/dlsch_test.m | 48 ++--- matlab/tests/pdsch_bler.m | 242 ++++++++++---------------- matlab/tests/pdsch_check_rm_files.m | 22 --- matlab/tests/pdsch_decode_test.m | 63 ------- mex/include/srslte/mex/mexutils.h | 6 + mex/lib/mexutils.c | 16 ++ srslte/lib/phch/src/dci.c | 19 ++ srslte/lib/phch/src/pdsch.c | 8 + srslte/lib/phch/src/sch.c | 17 +- srslte/lib/phch/test/pdsch_test_mex.c | 85 +++++---- 10 files changed, 218 insertions(+), 308 deletions(-) delete mode 100644 matlab/tests/pdsch_check_rm_files.m delete mode 100644 matlab/tests/pdsch_decode_test.m diff --git a/matlab/tests/dlsch_test.m b/matlab/tests/dlsch_test.m index 120c1d4c9..c8414c755 100644 --- a/matlab/tests/dlsch_test.m +++ b/matlab/tests/dlsch_test.m @@ -4,44 +4,24 @@ pdschConfig=struct('Modulation','64QAM','RV',1,'TxScheme','Port0','NTurboDecIts' addpath('../../build/srslte/lib/phch/test') -%TBs=18336; +TBs=18336; i=1; e_bits=3450*6; -%error=zeros(size(TBs)); -%for i=1:length(TBs) - %trblkin=randi(2,TBs(i),1)-1; - trblkin=read_uchar('../../build/data_in'); +error=zeros(size(TBs)); +for i=1:length(TBs) + trblkin=randi(2,TBs(i),1)-1; - fprintf('e_bits=%d, trblkin=%d\n',e_bits,length(trblkin)); - [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))); - mat(mat==0)=-1; - mat=mat*10; - - rec = lteRateRecoverTurbo(mat,length(trblkin),pdschConfig.RV); - rec2 = reshape(reshape(rec{1},[],3)',[],1); - out = lteTurboDecode(rec{1}); - - x=read_int16('../../build/rmout_0.dat'); - subplot(2,1,1) - plot(abs(double(x)-double(rec2))); - t=1:100; - %plot(t,double(x(t)),t,double(rec2(t))) - 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) -%end -% -% if (length(TBs) == 1) -% %disp(info) -% disp(error) -% n=1:length(mat); -% plot(abs(double(mat)-double(lib))) -% else -% plot(error) -% end +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/pdsch_bler.m b/matlab/tests/pdsch_bler.m index 2f1af0a30..4efc17348 100644 --- a/matlab/tests/pdsch_bler.m +++ b/matlab/tests/pdsch_bler.m @@ -1,158 +1,108 @@ -%% PDSCH decoding based on RMC channels - -%% Cell-Wide Settings -% A structure |enbConfig| is used to configure the eNodeB. -%clear12 - -recordedSignal=[]; - -Npackets = 20; -SNR_values = linspace(2,6,10); - -Lp=12; -N=256; -K=180; -rstart=(N-K)/2; -P=K/6; -Rhphp=zeros(P,P); -Rhhp=zeros(K,P); -Rhh=zeros(K,K); - -t=0:Lp-1; -alfa=log(2*Lp)/Lp; -c_l=exp(-t*alfa); -c_l=c_l/sum(c_l); -C_l=diag(1./c_l); -prows=rstart+(1:6:K); - -F=dftmtx(N); -F_p=F(prows,1:Lp); -F_l=F((rstart+1):(K+rstart),1:Lp); -Wi=(F_p'*F_p+C_l*0.01)^(-1); -W2=F_l*Wi*F_p'; -w2=reshape(transpose(W2),1,[]); - - -%% Choose RMC -[waveform,rgrid,rmccFgOut] = lteRMCDLTool('R.0',[1;0;0;1]); -waveform = sum(waveform,2); - -if ~isempty(recordedSignal) - rmccFgOut = struct('CellRefP',1,'NDLRB',100,'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 = 9; - -%% 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 = 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 +%% 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') -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) +% 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); - %% Fading - %rxWaveform = lteFadingChannel(cfg,waveform); - rxWaveform = waveform; +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; - %% Noise Addition - noise = N0*complex(randn(size(rxWaveform)), randn(size(rxWaveform))); % Generate noise - rxWaveform = rxWaveform + noise; - else - rxWaveform = recordedSignal; + % 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 - %% 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,estimates] = lteDLChannelEstimate2(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] = 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 + % 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. Decoded: %d-%d\n',SNRdB, decoded(snr_idx), decoded_srslte(snr_idx)) + fprintf('SNR=%.1f dB, BLER_mat=%f, BLER_srs=%f\n',SNR(k),nErrors_mat(k,rvIndex)/Nblocks, nErrors_srs(k,rvIndex)/Nblocks); 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]) +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 - fprintf('Matlab: %d OK\nsrsLTE: %d OK\n',decoded, decoded_srslte); + 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_check_rm_files.m b/matlab/tests/pdsch_check_rm_files.m deleted file mode 100644 index 0af91deb2..000000000 --- a/matlab/tests/pdsch_check_rm_files.m +++ /dev/null @@ -1,22 +0,0 @@ -nof_cb=11; -TBS=61664; -K=5632; % Only supporting 1 K for now -rv=0; -chs.Modulation='64QAM'; -chs.NLayers=1; -% cws must be a vector of size TBS in workspace containing the output of the -% descrambler -rmout_mat=lteRateRecoverTurbo(cws{1},TBS,rv,chs); -scale=700; -%path='../../build/srslte/lib/phch/test'; -path='.'; -error=zeros(nof_cb,3*K+12); -rmout_lib=zeros(nof_cb,3*K+12); -for i=0:nof_cb-1 - filename=sprintf('%s/rmout_%d.dat',path,i); - x=read_int16(filename); - rmout_lib(i+1,:) = reshape(reshape(x,3,[])',[],1); - error(i+1,:)=abs(transpose(rmout_mat{i+1})-rmout_lib(i+1,:)/scale); -end - -plot(reshape(error',1,[])) \ No newline at end of file diff --git a/matlab/tests/pdsch_decode_test.m b/matlab/tests/pdsch_decode_test.m deleted file mode 100644 index 4d542bbd1..000000000 --- a/matlab/tests/pdsch_decode_test.m +++ /dev/null @@ -1,63 +0,0 @@ -enb=struct('NCellID',16,'NDLRB',6,'NSubframe',5,'CFI',3,'CyclicPrefix','Normal','CellRefP',1,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); - -RNTI=65535; - -addpath('../../build/srslte/lib/phch/test') - -cec.PilotAverage = 'UserDefined'; % Type of pilot averaging -cec.FreqWindow = 9; % Frequency window size -cec.TimeWindow = 9; % Time window size -cec.InterpType = 'cubic'; % 2D interpolation type -cec.InterpWindow = 'Centered'; % Interpolation window type -cec.InterpWinSize = 1; % Interpolation window size - -subframe_rx=lteOFDMDemodulate(enb,inputSignal); -[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 = 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 = 5; - 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, nest); - [sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits); - - [dec2, data, pdschRx2, pdschSymbols2, e_bits, indices] = srslte_pdsch(enb, pdsch, ... - trblklen, ... - subframe_rx); - - - scatter(real(pdschSymbols{1}),imag(pdschSymbols{1})) - - if crc == 0 - fprintf('PDSCH OK.\n\n'); - else - fprintf('PDSCH 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/mex/include/srslte/mex/mexutils.h b/mex/include/srslte/mex/mexutils.h index ea9115bb9..b808c14da 100644 --- a/mex/include/srslte/mex/mexutils.h +++ b/mex/include/srslte/mex/mexutils.h @@ -43,6 +43,12 @@ 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); diff --git a/mex/lib/mexutils.c b/mex/lib/mexutils.c index 618994c15..66a22d8e7 100644 --- a/mex/lib/mexutils.c +++ b/mex/lib/mexutils.c @@ -35,6 +35,20 @@ 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); @@ -98,6 +112,8 @@ int mexutils_read_cf(const mxArray *ptr, cf_t **buffer) { __real__ tmp[i] = (float) inr[i]; if (ini) { __imag__ tmp[i] = (float) ini[i]; + } else { + __imag__ tmp[i] = 0; } } *buffer = tmp; diff --git a/srslte/lib/phch/src/dci.c b/srslte/lib/phch/src/dci.c index d77a06a4d..719e3c5d0 100644 --- a/srslte/lib/phch/src/dci.c +++ b/srslte/lib/phch/src/dci.c @@ -649,6 +649,25 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32 INFO("DCI message is Format0\n", 0); return SRSLTE_ERROR; } + + // Check if RA procedure by PDCCH order + if (*y == 0) { + int nof_bits = riv_nbits(nof_prb); + int i=0; + while(inof_bits-1 && y[i] == 0) { + i++; + } + if (i == msg->nof_bits-1) { + printf("Received a Format1A RA PDCCH order. Not implemented!\n"); + return SRSLTE_ERROR; + } + } + } data->alloc_type = SRSLTE_RA_ALLOC_TYPE2; data->type2_alloc.mode = *y++; diff --git a/srslte/lib/phch/src/pdsch.c b/srslte/lib/phch/src/pdsch.c index 3e6670a84..e780c18c9 100644 --- a/srslte/lib/phch/src/pdsch.c +++ b/srslte/lib/phch/src/pdsch.c @@ -426,6 +426,14 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, */ srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re); + /* + printf("WARNING REMOVE ME!\n"); + int16_t *e=q->e; + for (int i=0;inbits.nof_bits;i++) { + e[i] = e[i]>0?10:-10; + } + */ + /* descramble */ if (rnti != q->rnti) { srslte_sequence_t seq; diff --git a/srslte/lib/phch/src/sch.c b/srslte/lib/phch/src/sch.c index 134b73789..006dcf530 100644 --- a/srslte/lib/phch/src/sch.c +++ b/srslte/lib/phch/src/sch.c @@ -229,13 +229,6 @@ static int encode_tb_off(srslte_sch_t *q, parity[0] = (par&(0xff<<16))>>16; parity[1] = (par&(0xff<<8))>>8; parity[2] = par&0xff; - - if (SRSLTE_VERBOSE_ISDEBUG()) { - DEBUG("DATA: ", 0); - srslte_vec_fprint_byte(stdout, data, cb_segm->tbs/8); - DEBUG("PARITY: ", 0); - srslte_vec_fprint_byte(stdout, parity, 3); - } } wp = 0; @@ -425,7 +418,7 @@ static int decode_tb(srslte_sch_t *q, srslte_tdec_decision_byte(&q->decoder, q->cb_in, cb_len); - /* Check Codeblock CRC and stop early if incorrect */ + /* Check Codeblock CRC and stop early if correct */ if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { early_stop = true; } @@ -447,12 +440,16 @@ static int decode_tb(srslte_sch_t *q, memcpy(&data[wp/8], q->cb_in, (rlen - 24)/8 * sizeof(uint8_t)); memcpy(parity, &q->cb_in[(rlen - 24)/8], 3 * sizeof(uint8_t)); } - + + if (SRSLTE_VERBOSE_ISDEBUG()) { + early_stop = true; + } + /* Set read/write pointers */ wp += rlen; rp += n_e; } - + if (!early_stop) { INFO("CB %d failed. TB is erroneous.\n",i-1); return SRSLTE_ERROR; diff --git a/srslte/lib/phch/test/pdsch_test_mex.c b/srslte/lib/phch/test/pdsch_test_mex.c index aed19ee42..eea0fe14d 100644 --- a/srslte/lib/phch/test/pdsch_test_mex.c +++ b/srslte/lib/phch/test/pdsch_test_mex.c @@ -45,6 +45,8 @@ void help() 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[]) { @@ -63,7 +65,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } - srslte_verbose = SRSLTE_VERBOSE_INFO; + srslte_verbose = SRSLTE_VERBOSE_DEBUG; bzero(&cfg, sizeof(srslte_pdsch_cfg_t)); if (mexutils_read_cell(ENBCFG, &cell)) { @@ -174,49 +176,65 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } /** Allocate input buffers */ - if (mexutils_read_cf(INPUT, &input_fft) < 0) { - mexErrMsgTxt("Error reading input signal\n"); - return; - } + int nof_retx=1; + if (mexutils_isCell(INPUT)) { + nof_retx = mexutils_getLength(INPUT); + } cf_t *ce[SRSLTE_MAX_PORTS]; for (i=0;i NOF_INPUTS) { - cf_t *cearray = NULL; - int nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray); - cf_t *cearray_ptr = cearray; - for (i=0;i NOF_INPUTS + 1) { - noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); - } else { - noise_power = srslte_chest_dl_get_noise_estimate(&chest); - } - + uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8); if (!data_bytes) { return; } - srslte_sch_set_max_noi(&pdsch.dl_sch, max_iterations); - int r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes); + int r=-1; + for (int rvIdx=0;rvIdx 1) { + cfg.rv = rv_seq[rvIdx%4]; + } + } + if (mexutils_read_cf(tmp, &input_fft) < 0) { + mexErrMsgTxt("Error reading input signal\n"); + return; + } + + if (nrhs > NOF_INPUTS) { + cf_t *cearray = NULL; + int nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray); + cf_t *cearray_ptr = cearray; + for (i=0;i NOF_INPUTS + 1) { + noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); + } else { + noise_power = srslte_chest_dl_get_noise_estimate(&chest); + } - free(data_bytes); + r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes); + + free(input_fft); + + } uint8_t *data = malloc(grant.mcs.tbs); srslte_bit_unpack_vector(data_bytes, data, grant.mcs.tbs); @@ -237,14 +255,15 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_write_s(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1); } + srslte_softbuffer_rx_free(&softbuffer); srslte_chest_dl_free(&chest); srslte_pdsch_free(&pdsch); for (i=0;i