mirror of https://github.com/PentHertz/srsLTE.git
Added Matlab tests to verify PDSCH BLER
This commit is contained in:
parent
fb1d2d32c4
commit
75357c8526
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
% Subframe configuration
|
||||
enbConfig.NCellID = 100;
|
||||
enbConfig.CyclicPrefix = 'Normal';
|
||||
enbConfig.NSubframe = 1;
|
||||
enbConfig.CellRefP = 1;
|
||||
enbConfig.NDLRB = 100;
|
||||
enbConfig.CFI = 1;
|
||||
enbConfig.DuplexMode='FDD';
|
||||
|
||||
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);
|
||||
% 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)';
|
||||
|
||||
for i=1:Npackets
|
||||
switch (modulation)
|
||||
case 'QPSK'
|
||||
bitsPerSym = 2;
|
||||
case '16QAM'
|
||||
bitsPerSym = 4;
|
||||
case '64QAM'
|
||||
bitsPerSym = 6;
|
||||
end
|
||||
noiseVarfactor = sqrt(2*bitsPerSym);
|
||||
snr = 10.^(SNR/10);
|
||||
|
||||
if isempty(recordedSignal)
|
||||
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);
|
||||
|
||||
%% Fading
|
||||
%rxWaveform = lteFadingChannel(cfg,waveform);
|
||||
rxWaveform = waveform;
|
||||
% 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
|
||||
|
||||
|
|
|
@ -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,[]))
|
|
@ -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))
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(i<nof_bits && y[1+i] == 1)
|
||||
i++;
|
||||
if (i == nof_bits) {
|
||||
printf("Warning check me: could this be a RA PDCCH order??\n");
|
||||
i=1+10+nof_bits;
|
||||
while(i<msg->nof_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++;
|
||||
|
|
|
@ -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;i<cfg->nbits.nof_bits;i++) {
|
||||
e[i] = e[i]>0?10:-10;
|
||||
}
|
||||
*/
|
||||
|
||||
/* descramble */
|
||||
if (rnti != q->rnti) {
|
||||
srslte_sequence_t seq;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<cell.nof_ports;i++) {
|
||||
ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
}
|
||||
|
||||
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<cell.nof_ports;i++) {
|
||||
for (int j=0;j<nof_re/cell.nof_ports;j++) {
|
||||
ce[i][j] = *cearray;
|
||||
cearray++;
|
||||
}
|
||||
}
|
||||
if (cearray_ptr)
|
||||
free(cearray_ptr);
|
||||
} else {
|
||||
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
|
||||
}
|
||||
|
||||
float noise_power;
|
||||
if (nrhs > 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<nof_retx && r != 0;rvIdx++) {
|
||||
|
||||
mxArray *tmp = (mxArray*) INPUT;
|
||||
if (mexutils_isCell(INPUT)) {
|
||||
tmp = mexutils_getCellArray(INPUT, rvIdx);
|
||||
if (nof_retx > 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<cell.nof_ports;i++) {
|
||||
for (int j=0;j<nof_re/cell.nof_ports;j++) {
|
||||
ce[i][j] = *cearray;
|
||||
cearray++;
|
||||
}
|
||||
}
|
||||
if (cearray_ptr)
|
||||
free(cearray_ptr);
|
||||
} else {
|
||||
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
|
||||
}
|
||||
|
||||
float noise_power;
|
||||
if (nrhs > 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<cell.nof_ports;i++) {
|
||||
free(ce[i]);
|
||||
}
|
||||
free(data_bytes);
|
||||
free(data);
|
||||
free(input_fft);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue