Fixed bug in PDCCH REG cyclic shift

master
ismagom 9 years ago
parent aee336b586
commit 799af37bed

@ -5,16 +5,16 @@
% A structure |enbConfig| is used to configure the eNodeB. % A structure |enbConfig| is used to configure the eNodeB.
clear clear
Npackets = 1000; Npackets = 1;
SNR_values = linspace(-5,0,8); SNR_values = 100;%linspace(-5,0,8);
txCFI = 3; txCFI = 1;
enbConfig.NDLRB = 15; % No of Downlink RBs in total BW enbConfig.NDLRB = 50; % No of Downlink RBs in total BW
enbConfig.CyclicPrefix = 'Normal'; % CP length enbConfig.CyclicPrefix = 'Normal'; % CP length
enbConfig.CFI = txCFI; ; % 4 PDCCH symbols as NDLRB <= 10 enbConfig.CFI = txCFI; ; % 4 PDCCH symbols as NDLRB <= 10
enbConfig.Ng = 'Sixth'; % HICH groups enbConfig.Ng = 'One'; % HICH groups
enbConfig.CellRefP = 2; % 1-antenna ports enbConfig.CellRefP = 2; % 1-antenna ports
enbConfig.NCellID = 0; % Physical layer cell identity enbConfig.NCellID = 424; % Physical layer cell identity
enbConfig.NSubframe = 5; % Subframe number 0 enbConfig.NSubframe = 5; % Subframe number 0
enbConfig.DuplexMode = 'FDD'; % Frame structure enbConfig.DuplexMode = 'FDD'; % Frame structure
enbConfig.PHICHDuration = 'Normal'; enbConfig.PHICHDuration = 'Normal';
@ -38,13 +38,13 @@ cec.PilotAverage = 'UserDefined'; % Type of pilot averaging
cec.FreqWindow = 9; % Frequency window size cec.FreqWindow = 9; % Frequency window size
cec.TimeWindow = 9; % Time window size cec.TimeWindow = 9; % Time window size
cec.InterpType = 'linear'; % 2D interpolation type cec.InterpType = 'linear'; % 2D interpolation type
cec.InterpWindow = 'Centered'; % Interpolation window type cec.InterpWindow = 'Causal'; % Interpolation window type
cec.InterpWinSize = 1; % Interpolation window size cec.InterpWinSize = 1; % Interpolation window size
%% DCI Message Generation %% DCI Message Generation
% Generate a DCI message to be mapped to the PDCCH. % Generate a DCI message to be mapped to the PDCCH.
dciConfig.DCIFormat = 'SRSLTE_DCI_FORMAT1A'; % DCI message format dciConfig.DCIFormat = 'Format1A'; % DCI message format
dciConfig.Allocation.RIV = 26; % Resource indication value dciConfig.Allocation.RIV = 26; % Resource indication value
% Create DCI message for given configuration % Create DCI message for given configuration
@ -52,10 +52,18 @@ dciConfig.Allocation.RIV = 26; % Resource indication value
%% DCI Channel Coding %% DCI Channel Coding
% Do not include RNTI if Common Search space
if C_RNTI<65535
pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier pdcchConfig.RNTI = C_RNTI; % Radio network temporary identifier
pdcchConfig.PDCCHFormat = 3; % PDCCH format end
pdcchConfig.PDCCHFormat = 2; % PDCCH format
ueConfig.RNTI = C_RNTI; 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 % DCI message bits coding to form coded DCI bits
codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits); codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
@ -64,23 +72,21 @@ codedDciBits = lteDCIEncode(pdcchConfig, dciMessageBits);
pdcchDims = ltePDCCHInfo(enbConfig); pdcchDims = ltePDCCHInfo(enbConfig);
% Initialize elements with -1 to indicate that all the bits are unused % Initialize elements with -1 to indicate that all the bits are unused
pdcchBits = -1*ones(pdcchDims.MTot, 1); pdcchBitsTx = -1*ones(pdcchDims.MTot, 1);
% Perform search space for UE-specific control channel candidates.
candidates = ltePDCCHSpace(enbConfig, pdcchConfig, {'bits', '1based'});
Ncad=randi(length(candidates),1,1); Ncad=1;
% Map PDCCH payload on available UE-specific candidate. In this example the % Map PDCCH payload on available UE-specific candidate. In this example the
% first available candidate is used to map the coded DCI bits. % first available candidate is used to map the coded DCI bits.
pdcchBits ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits; pdcchBitsTx ( candidates(Ncad, 1) : candidates(Ncad, 2) ) = codedDciBits;
%% PDCCH Complex-Valued Modulated Symbol Generation %% PDCCH Complex-Valued Modulated Symbol Generation
pdcchSymbols = ltePDCCH(enbConfig, pdcchBits); pdcchSymbolsTx = ltePDCCH(enbConfig, pdcchBitsTx);
pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'}); pdcchIndices = ltePDCCHIndices(enbConfig,{'1based'});
subframe_tx = lteDLResourceGrid(enbConfig); subframe_tx = lteDLResourceGrid(enbConfig);
subframe_tx(pdcchIndices) = pdcchSymbols; subframe_tx(pdcchIndices) = pdcchSymbolsTx;
%% PCFICH %% PCFICH
cfiCodeword = lteCFI(enbConfig); cfiCodeword = lteCFI(enbConfig);
@ -96,14 +102,14 @@ subframe_tx(cellRsInd) = cellRsSym;
[txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx); [txWaveform, info] = lteOFDMModulate(enbConfig,subframe_tx);
cfg.SamplingRate = info.SamplingRate; cfg.SamplingRate = info.SamplingRate;
addpath('../../debug/lte/phy/lib/phch/test') addpath('../../build/srslte/lib/phch/test')
decoded = zeros(size(SNR_values)); decoded = zeros(size(SNR_values));
decoded_cfi = zeros(size(SNR_values)); decoded_cfi = zeros(size(SNR_values));
decoded_srslte = zeros(size(SNR_values)); decoded_srslte = zeros(size(SNR_values));
decoded_cfi_srslte = zeros(size(SNR_values)); decoded_cfi_srslte = zeros(size(SNR_values));
parfor snr_idx=1:length(SNR_values) for snr_idx=1:length(SNR_values)
SNRdB = SNR_values(snr_idx); SNRdB = SNR_values(snr_idx);
SNR = 10^(SNRdB/10); % Linear SNR SNR = 10^(SNRdB/10); % Linear SNR
N0 = 1/(sqrt(2.0*enbConfig.CellRefP*double(info.Nfft))*SNR); N0 = 1/(sqrt(2.0*enbConfig.CellRefP*double(info.Nfft))*SNR);
@ -126,10 +132,10 @@ parfor snr_idx=1:length(SNR_values)
% Perform channel estimation % Perform channel estimation
[hest, nest] = lteDLChannelEstimate(enbConfigRx, cec, subframe_rx); [hest, nest] = lteDLChannelEstimate(enbConfigRx, cec, subframe_rx);
[pcfichSymbolsRx, pdcfichSymbolsHest] = lteExtractResources(pcfichIndices(:,1), subframe_rx, hest); [pcfichSymbolsRx, pcfichSymbolsHest] = lteExtractResources(pcfichIndices(:,1), subframe_rx, hest);
%% PCFICH decoding %% PCFICH decoding
[pcfichBits, pcfichSymbols] = ltePCFICHDecode(enbConfigRx,pcfichSymbolsRx, pdcfichSymbolsHest, nest); [pcfichBits, pcfichSymbols] = ltePCFICHDecode(enbConfigRx,pcfichSymbolsRx, pcfichSymbolsHest, nest);
rxCFI = lteCFIDecode(pcfichBits); rxCFI = lteCFIDecode(pcfichBits);
decoded_cfi(snr_idx) = decoded_cfi(snr_idx) + (rxCFI == txCFI); decoded_cfi(snr_idx) = decoded_cfi(snr_idx) + (rxCFI == txCFI);
@ -137,19 +143,18 @@ parfor snr_idx=1:length(SNR_values)
%% PDCCH Decoding %% PDCCH Decoding
enbConfigRx.CFI = rxCFI; enbConfigRx.CFI = rxCFI;
pdcchIndicesRx = ltePDCCHIndices(enbConfigRx,{'1based'}); pdcchIndicesRx = ltePDCCHIndices(enbConfigRx,{'1based'});
[pdcchSymbolsRx, pdcchSymbolsHest] = lteExtractResources(pdcchIndicesRx(:,1), subframe_rx, hest); [pdcchRx, pdcchHest] = lteExtractResources(pdcchIndicesRx(:,1), subframe_rx, hest);
[recPdcchBits] = ltePDCCHDecode(enbConfigRx, pdcchSymbolsRx, pdcchSymbolsHest, nest); [pdcchBits, pdcchSymbols] = ltePDCCHDecode(enbConfigRx, pdcchRx, pdcchHest, nest);
%% Blind Decoding using DCI Search %% Blind Decoding using DCI Search
[rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfigRx, ueConfig, recPdcchBits); [rxDCI, rxDCIBits] = ltePDCCHSearch(enbConfigRx, ueConfig, pdcchBits);
decoded(snr_idx) = decoded(snr_idx) + (length(rxDCI)>0); decoded(snr_idx) = decoded(snr_idx) + (length(rxDCI)>0);
%% Same with srsLTE %% Same with srsLTE
[rxCFI, pcfichSymbols2, pcfichSymbolsRx2] = srslte_pcfich(enbConfigRx, rxWaveform); [rxCFI_srslte, pcfichRx2, pcfichSymbols2] = srslte_pcfich(enbConfigRx, subframe_rx);
decoded_cfi_srslte(snr_idx) = decoded_cfi_srslte(snr_idx) + (rxCFI == txCFI); decoded_cfi_srslte(snr_idx) = decoded_cfi_srslte(snr_idx) + (rxCFI_srslte == txCFI);
enbConfigRx.CFI = rxCFI; enbConfigRx.CFI = rxCFI_srslte;
[found_srslte, llr, pdcchSymbols2] = srslte_pdcch(enbConfigRx, ueConfig.RNTI, rxWaveform); [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; decoded_srslte(snr_idx) = decoded_srslte(snr_idx)+found_srslte;
end end
fprintf('SNR: %.1f\n',SNRdB) fprintf('SNR: %.1f\n',SNRdB)
@ -166,6 +171,21 @@ if (Npackets>1)
ylabel('BLER') ylabel('BLER')
axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1]) axis([min(SNR_values) max(SNR_values) 1/Npackets/10 1])
else else
%scatter(real(pdcchSymbols2),imag(pdcchSymbols2))
%hold on
%scatter(real(pdcchSymbols),imag(pdcchSymbols))
%axis([-1.5 1.5 -1.5 1.5])
%hold off
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)))
disp(decoded) disp(decoded)
disp(decoded_srslte) disp(decoded_srslte)
end end

@ -1,6 +1,6 @@
enb=struct('NCellID',0,'NDLRB',100,'NSubframe',9,'CFI',1,'CyclicPrefix','Normal','CellRefP',1,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD'); %enb=struct('NCellID',424,'NDLRB',100,'NSubframe',9,'CFI',2,'CyclicPrefix','Normal','CellRefP',2,'Ng','One','PHICHDuration','Normal','DuplexMode','FDD');
RNTI=73; RNTI=65535;
addpath('../../build/srslte/lib/phch/test') addpath('../../build/srslte/lib/phch/test')
@ -30,8 +30,8 @@ if ~isempty(dci)
% Get the PDSCH configuration from the DCI % Get the PDSCH configuration from the DCI
[pdsch, trblklen] = hPDSCHConfiguration(enb, dci, pdcch.RNTI); [pdsch, trblklen] = hPDSCHConfiguration(enb, dci, pdcch.RNTI);
pdsch.NTurboDecIts = 10; pdsch.NTurboDecIts = 10;
pdsch.Modulation = {'64QAM'}; %pdsch.Modulation = {'QPSK'};
trblklen=75376; %trblklen=75376;
fprintf('PDSCH settings after DCI decoding:\n'); fprintf('PDSCH settings after DCI decoding:\n');
disp(pdsch); disp(pdsch);
@ -40,12 +40,12 @@ if ~isempty(dci)
[pdschIndices,pdschIndicesInfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet); [pdschIndices,pdschIndicesInfo] = ltePDSCHIndices(enb, pdsch, pdsch.PRBSet);
[pdschRx, pdschHest] = lteExtractResources(pdschIndices, subframe_rx, hest); [pdschRx, pdschHest] = lteExtractResources(pdschIndices, subframe_rx, hest);
% Decode PDSCH % Decode PDSCH
[dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, d); [dlschBits,pdschSymbols] = ltePDSCHDecode(enb, pdsch, pdschRx, pdschHest, nest);
[sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits); [sib1, crc] = lteDLSCHDecode(enb, pdsch, trblklen, dlschBits);
% [dec2, data, pdschRx2, pdschSymbols2, e_bits, indices] = srslte_pdsch(enb, pdsch, ... [dec2, data, pdschRx2, pdschSymbols2, e_bits] = srslte_pdsch(enb, pdsch, ...
% trblklen, ... trblklen, ...
% subframe_rx); subframe_rx, hest, nest);
scatter(real(pdschSymbols{1}),imag(pdschSymbols{1})) scatter(real(pdschSymbols{1}),imag(pdschSymbols{1}))

@ -95,10 +95,26 @@ int mexutils_read_cell(const mxArray *ptr, srslte_cell_t *cell) {
if (mexutils_read_uint32_struct(ptr, "NDLRB", &cell->nof_prb)) { if (mexutils_read_uint32_struct(ptr, "NDLRB", &cell->nof_prb)) {
return -1; return -1;
} }
// TODO if (!strcmp(mexutils_get_char_struct(ptr, "CyclicPrefix"), "Extended")) {
cell->cp = SRSLTE_CP_EXT;
} else {
cell->cp = SRSLTE_CP_NORM; 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; cell->phich_length = SRSLTE_PHICH_NORM;
cell->phich_resources = SRSLTE_PHICH_SRSLTE_PHICH_R_1_6; }
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; return 0;
} }

@ -66,7 +66,7 @@ bool plot_track = true;
#define PLOT_CHEST_ARGUMENT #define PLOT_CHEST_ARGUMENT
#define PRINT_CHANGE_SCHEDULIGN #define PRINT_CHANGE_SCHEDULIGN
#define CORRECT_SAMPLE_OFFSET //#define CORRECT_SAMPLE_OFFSET
/********************************************************************** /**********************************************************************
* Program arguments processing * Program arguments processing
@ -394,8 +394,6 @@ int main(int argc, char **argv) {
#endif #endif
} }
state = DECODE_MIB;
if (srslte_ue_mib_init(&ue_mib, cell)) { if (srslte_ue_mib_init(&ue_mib, cell)) {
fprintf(stderr, "Error initaiting UE MIB decoder\n"); fprintf(stderr, "Error initaiting UE MIB decoder\n");
exit(-1); exit(-1);
@ -479,9 +477,8 @@ int main(int argc, char **argv) {
if (prog_args.rnti != SRSLTE_SIRNTI) { if (prog_args.rnti != SRSLTE_SIRNTI) {
decode_pdsch = true; decode_pdsch = true;
} else { } else {
/* We are looking for SIB1 Blocks, 2search only in appropiate places */ /* We are looking for SIB1 Blocks, search only in appropiate places */
// Decode only RV=0 if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) {
if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%8)==0)) {
decode_pdsch = true; decode_pdsch = true;
} else { } else {
decode_pdsch = false; decode_pdsch = false;
@ -498,10 +495,12 @@ int main(int argc, char **argv) {
n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data, n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data,
srslte_ue_sync_get_sfidx(&ue_sync), srslte_ue_sync_get_sfidx(&ue_sync),
SRSLTE_SIRNTI, rv); SRSLTE_SIRNTI, rv);
srslte_ue_dl_save_signal(&ue_dl, &ue_dl.softbuffer, sfn*10+srslte_ue_sync_get_sfidx(&ue_sync), rv);
} }
if (n < 0) { if (n < 0) {
// fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); // fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
} else if (n > 0) { } else if (n > 0) {
/* Send data if socket active */ /* Send data if socket active */
if (prog_args.net_port > 0) { if (prog_args.net_port > 0) {
srslte_netsink_write(&net_sink, data, 1+(n-1)/8); srslte_netsink_write(&net_sink, data, 1+(n-1)/8);

@ -133,8 +133,8 @@ typedef enum SRSLTE_API {
} srslte_phich_length_t; } srslte_phich_length_t;
typedef enum SRSLTE_API { typedef enum SRSLTE_API {
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6 = 0, SRSLTE_PHICH_R_1_6 = 0,
SRSLTE_PHICH_SRSLTE_PHICH_R_1_2, SRSLTE_PHICH_R_1_2,
SRSLTE_PHICH_R_1, SRSLTE_PHICH_R_1,
SRSLTE_PHICH_R_2 SRSLTE_PHICH_R_2

@ -168,4 +168,10 @@ SRSLTE_API void srslte_ue_dl_reset(srslte_ue_dl_t *q);
SRSLTE_API void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q, SRSLTE_API void srslte_ue_dl_set_rnti(srslte_ue_dl_t *q,
uint16_t rnti); uint16_t rnti);
SRSLTE_API void srslte_ue_dl_save_signal(srslte_ue_dl_t *q,
srslte_softbuffer_rx_t *softbuffer,
uint32_t tti,
uint32_t rv_idx);
#endif #endif

@ -124,7 +124,9 @@ int srslte_chest_dl_init(srslte_chest_dl_t *q, srslte_cell_t cell)
} }
q->smooth_filter_len = 0; q->smooth_filter_len = 0;
set_default_filter(q, DEFAULT_FILTER_LEN); float fil[3] = {0.1, 0.8, 0.1};
srslte_chest_dl_set_smooth_filter(q, fil, 3);
//set_default_filter(q, DEFAULT_FILTER_LEN);
q->cell = cell; q->cell = cell;
} }

@ -34,6 +34,7 @@
#include "srslte/common/phy_common.h" #include "srslte/common/phy_common.h"
#include "srslte/common/sequence.h" #include "srslte/common/sequence.h"
#define FORCE_STANDARD_RATE
#ifdef FORCE_STANDARD_RATE #ifdef FORCE_STANDARD_RATE
static bool use_standard_rates = true; static bool use_standard_rates = true;
#else #else
@ -74,10 +75,10 @@ void srslte_cell_fprint(FILE *stream, srslte_cell_t *cell, uint32_t sfn) {
cell->phich_length == SRSLTE_PHICH_EXT ? "Extended" : "Normal"); cell->phich_length == SRSLTE_PHICH_EXT ? "Extended" : "Normal");
fprintf(stream, " - PHICH Resources: "); fprintf(stream, " - PHICH Resources: ");
switch (cell->phich_resources) { switch (cell->phich_resources) {
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_6: case SRSLTE_PHICH_R_1_6:
fprintf(stream, "1/6"); fprintf(stream, "1/6");
break; break;
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_2: case SRSLTE_PHICH_R_1_2:
fprintf(stream, "1/2"); fprintf(stream, "1/2");
break; break;
case SRSLTE_PHICH_R_1: case SRSLTE_PHICH_R_1:

@ -277,10 +277,10 @@ void srslte_pbch_mib_unpack(uint8_t *msg, srslte_cell_t *cell, uint32_t *sfn) {
phich_res = srslte_bit_pack(&msg, 2); phich_res = srslte_bit_pack(&msg, 2);
switch (phich_res) { switch (phich_res) {
case 0: case 0:
cell->phich_resources = SRSLTE_PHICH_SRSLTE_PHICH_R_1_6; cell->phich_resources = SRSLTE_PHICH_R_1_6;
break; break;
case 1: case 1:
cell->phich_resources = SRSLTE_PHICH_SRSLTE_PHICH_R_1_2; cell->phich_resources = SRSLTE_PHICH_R_1_2;
break; break;
case 2: case 2:
cell->phich_resources = SRSLTE_PHICH_R_1; cell->phich_resources = SRSLTE_PHICH_R_1;
@ -315,10 +315,10 @@ void srslte_pbch_mib_pack(srslte_cell_t *cell, uint32_t sfn, uint8_t *msg) {
msg++; msg++;
switch (cell->phich_resources) { switch (cell->phich_resources) {
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_6: case SRSLTE_PHICH_R_1_6:
phich_res = 0; phich_res = 0;
break; break;
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_2: case SRSLTE_PHICH_R_1_2:
phich_res = 1; phich_res = 1;
break; break;
case SRSLTE_PHICH_R_1: case SRSLTE_PHICH_R_1:

@ -243,7 +243,7 @@ uint32_t srslte_pdcch_common_locations(srslte_pdcch_t *q, srslte_dci_location_t
if (k < max_candidates) { if (k < max_candidates) {
c[k].L = l; c[k].L = l;
c[k].ncce = (L) * (i % (q->nof_cce / (L))); c[k].ncce = (L) * (i % (q->nof_cce / (L)));
INFO("Common SS Candidate %d: nCCE: %d, L: %d\n", DEBUG("Common SS Candidate %d: nCCE: %d, L: %d\n",
k, c[k].ncce, c[k].L); k, c[k].ncce, c[k].L);
k++; k++;
} }
@ -284,15 +284,9 @@ static int dci_decode(srslte_pdcch_t *q, float *e, uint8_t *data, uint32_t E, ui
/* viterbi decoder */ /* viterbi decoder */
srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16); srslte_viterbi_decode_f(&q->decoder, q->rm_f, data, nof_bits + 16);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_bit_fprint(stdout, data, nof_bits + 16);
}
x = &data[nof_bits]; x = &data[nof_bits];
p_bits = (uint16_t) srslte_bit_pack(&x, 16); p_bits = (uint16_t) srslte_bit_pack(&x, 16);
crc_res = ((uint16_t) srslte_crc_checksum(&q->crc, data, nof_bits) & 0xffff); crc_res = ((uint16_t) srslte_crc_checksum(&q->crc, data, nof_bits) & 0xffff);
DEBUG("p_bits: 0x%x, crc_checksum: 0x%x, crc_rem: 0x%x\n", p_bits, crc_res,
p_bits ^ crc_res);
if (crc) { if (crc) {
*crc = p_bits ^ crc_res; *crc = p_bits ^ crc_res;
@ -329,9 +323,6 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q,
uint32_t nof_bits = srslte_dci_format_sizeof_lut(format, q->cell.nof_prb); uint32_t nof_bits = srslte_dci_format_sizeof_lut(format, q->cell.nof_prb);
uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L); uint32_t e_bits = PDCCH_FORMAT_NOF_BITS(location->L);
DEBUG("Decoding DCI offset %d, e_bits: %d, msg_len %d (nCCE: %d, L: %d)\n",
location->ncce * 72, e_bits, nof_bits, location->ncce, location->L);
double mean = 0; double mean = 0;
for (int i=0;i<e_bits;i++) { for (int i=0;i<e_bits;i++) {
mean += fabsf(q->llr[location->ncce * 72 + i]); mean += fabsf(q->llr[location->ncce * 72 + i]);
@ -343,7 +334,13 @@ int srslte_pdcch_decode_msg(srslte_pdcch_t *q,
if (ret == SRSLTE_SUCCESS) { if (ret == SRSLTE_SUCCESS) {
msg->nof_bits = nof_bits; msg->nof_bits = nof_bits;
} }
if (crc_rem) {
DEBUG("Decoded DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f, crc_rem=0x%x\n",
location->ncce, location->L, nof_bits, mean, *crc_rem);
}
} else { } else {
DEBUG("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f\n",
location->ncce, location->L, nof_bits, mean);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
} }
@ -413,11 +410,6 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT
srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports); srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports, nof_symbols / q->cell.nof_ports);
} }
DEBUG("pdcch d symbols: ", 0);
if (SRSLTE_VERBOSE_ISDEBUG()) {
srslte_vec_fprint_c(stdout, q->d, nof_symbols);
}
/* demodulate symbols */ /* demodulate symbols */
srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->llr, nof_symbols); srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->llr, nof_symbols);

@ -131,7 +131,7 @@ int regs_pdcch_init(srslte_regs_t *h) {
if (i*PDCCH_NCOLS + PDCCH_PERM[j] >= ndummy) { if (i*PDCCH_NCOLS + PDCCH_PERM[j] >= ndummy) {
m = i*PDCCH_NCOLS + PDCCH_PERM[j]-ndummy; m = i*PDCCH_NCOLS + PDCCH_PERM[j]-ndummy;
if (k < h->cell.id) { if (k < h->cell.id) {
kp = (h->pdcch[cfi].nof_regs + k-h->cell.id)%h->pdcch[cfi].nof_regs; kp = (h->pdcch[cfi].nof_regs + k-(h->cell.id%h->pdcch[cfi].nof_regs))%h->pdcch[cfi].nof_regs;
} else { } else {
kp = (k-h->cell.id)%h->pdcch[cfi].nof_regs; kp = (k-h->cell.id)%h->pdcch[cfi].nof_regs;
} }
@ -239,10 +239,10 @@ int regs_phich_init(srslte_regs_t *h) {
int ret = SRSLTE_ERROR; int ret = SRSLTE_ERROR;
switch(h->phich_res) { switch(h->phich_res) {
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_6: case SRSLTE_PHICH_R_1_6:
ng = (float) 1/6; ng = (float) 1/6;
break; break;
case SRSLTE_PHICH_SRSLTE_PHICH_R_1_2: case SRSLTE_PHICH_R_1_2:
ng = (float) 1/2; ng = (float) 1/2;
break; break;
case SRSLTE_PHICH_R_1: case SRSLTE_PHICH_R_1:

@ -49,9 +49,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
srslte_cell_t cell; srslte_cell_t cell;
srslte_pbch_t pbch; srslte_pbch_t pbch;
srslte_chest_dl_t chest; srslte_chest_dl_t chest;
srslte_ofdm_t fft; srslte_ofdm_t ofdm_rx;
cf_t *input_symbols, *input_fft; cf_t *input_fft;
int nof_re;
cf_t *ce[SRSLTE_MAX_PORTS], *ce_slot[SRSLTE_MAX_PORTS]; cf_t *ce[SRSLTE_MAX_PORTS], *ce_slot[SRSLTE_MAX_PORTS];
if (nrhs < NOF_INPUTS) { if (nrhs < NOF_INPUTS) {
@ -64,15 +63,9 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
// Read input symbols
mexutils_read_cf(INPUT, &input_symbols);
nof_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);
// Allocate memory // Allocate memory
input_fft = srslte_vec_malloc(nof_re * sizeof(cf_t));
for (i=0;i<SRSLTE_MAX_PORTS;i++) { for (i=0;i<SRSLTE_MAX_PORTS;i++) {
ce[i] = srslte_vec_malloc(nof_re * sizeof(cf_t)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
if (srslte_chest_dl_init(&chest, cell)) { if (srslte_chest_dl_init(&chest, cell)) {
@ -80,7 +73,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&ofdm_rx, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return; return;
} }
@ -90,16 +83,33 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
srslte_ofdm_rx_sf(&fft, input_symbols, input_fft); // Read input signal
cf_t *input_signal = NULL;
int insignal_len = mexutils_read_cf(INPUT, &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;
} else {
input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft);
free(input_signal);
}
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray = NULL;
mexutils_read_cf(prhs[NOF_INPUTS], &cearray); mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
cf_t *cearray_ptr = cearray;
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
for (int j=0;j<nof_re;j++) { for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
ce[i][j] = *cearray; ce[i][j] = *cearray_ptr;
cearray++; cearray_ptr++;
}
} }
if (cearray) {
free(cearray);
} }
} else { } else {
srslte_chest_dl_estimate(&chest, input_fft, ce, 0); srslte_chest_dl_estimate(&chest, input_fft, ce, 0);
@ -107,6 +117,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
float noise_power; float noise_power;
if (nrhs > NOF_INPUTS + 1) { if (nrhs > NOF_INPUTS + 1) {
noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); noise_power = mxGetScalar(prhs[NOF_INPUTS+1]);
} else if (nrhs > NOF_INPUTS) {
noise_power = 0;
} else { } else {
noise_power = srslte_chest_dl_get_noise_estimate(&chest); noise_power = srslte_chest_dl_get_noise_estimate(&chest);
} }
@ -147,13 +159,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_rx_free(&fft); srslte_ofdm_rx_free(&ofdm_rx);
srslte_pbch_free(&pbch); srslte_pbch_free(&pbch);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
free(ce[i]); free(ce[i]);
} }
free(input_symbols);
free(input_fft); free(input_fft);
return; return;

@ -48,12 +48,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
srslte_cell_t cell; srslte_cell_t cell;
srslte_pcfich_t pcfich; srslte_pcfich_t pcfich;
srslte_chest_dl_t chest; srslte_chest_dl_t chest;
srslte_ofdm_t fft; srslte_ofdm_t ofdm_rx;
srslte_regs_t regs; srslte_regs_t regs;
uint32_t sf_idx; uint32_t sf_idx;
cf_t *input_fft, *input_signal; cf_t *input_fft, *input_signal;
if (nrhs != NOF_INPUTS) { if (nrhs < NOF_INPUTS) {
help(); help();
return; return;
} }
@ -73,7 +73,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&ofdm_rx, cell.cp, cell.nof_prb)) {
mexErrMsgTxt("Error initializing FFT\n"); mexErrMsgTxt("Error initializing FFT\n");
return; return;
} }
@ -88,29 +88,39 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
/** Allocate input buffers */ // Read input signal
if (mexutils_read_cf(INPUT, &input_signal) < 0) { input_signal = NULL;
int insignal_len = mexutils_read_cf(INPUT, &input_signal);
if (insignal_len < 0) {
mexErrMsgTxt("Error reading input signal\n"); mexErrMsgTxt("Error reading input signal\n");
return; return;
} }
if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) {
input_fft = input_signal;
} else {
input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft);
free(input_signal);
}
// Set Channel estimates to 1.0 (ignore fading)
cf_t *ce[SRSLTE_MAX_PORTS]; cf_t *ce[SRSLTE_MAX_PORTS];
for (i=0;i<cell.nof_ports;i++) { 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)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
srslte_ofdm_rx_sf(&fft, input_signal, input_fft); mexPrintf("sf_idx=%d, nof_ports=%d, cell_id=%d\n", sf_idx, cell.nof_ports, cell.id);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray = NULL;
mexutils_read_cf(prhs[NOF_INPUTS], &cearray); mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
cf_t *cearray_ptr = cearray;
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) { for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
ce[i][j] = *cearray; ce[i][j] = *cearray_ptr;
cearray++; cearray_ptr++;
}
} }
if (cearray) {
free(cearray);
} }
} else { } else {
srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx); srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx);
@ -118,6 +128,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
float noise_power; float noise_power;
if (nrhs > NOF_INPUTS + 1) { if (nrhs > NOF_INPUTS + 1) {
noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); noise_power = mxGetScalar(prhs[NOF_INPUTS+1]);
} else if (nrhs > NOF_INPUTS) {
noise_power = 0;
} else { } else {
noise_power = srslte_chest_dl_get_noise_estimate(&chest); noise_power = srslte_chest_dl_get_noise_estimate(&chest);
} }
@ -142,14 +154,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_rx_free(&fft); srslte_ofdm_rx_free(&ofdm_rx);
srslte_pcfich_free(&pcfich); srslte_pcfich_free(&pcfich);
srslte_regs_free(&regs); srslte_regs_free(&regs);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
free(ce[i]); free(ce[i]);
} }
free(input_signal);
free(input_fft); free(input_fft);
return; return;

@ -59,7 +59,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
srslte_cell_t cell; srslte_cell_t cell;
srslte_pdcch_t pdcch; srslte_pdcch_t pdcch;
srslte_chest_dl_t chest; srslte_chest_dl_t chest;
srslte_ofdm_t fft; srslte_ofdm_t ofdm_rx;
srslte_regs_t regs; srslte_regs_t regs;
srslte_dci_location_t locations[MAX_CANDIDATES]; srslte_dci_location_t locations[MAX_CANDIDATES];
uint32_t cfi, sf_idx; uint32_t cfi, sf_idx;
@ -69,7 +69,9 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
uint32_t nof_formats; uint32_t nof_formats;
srslte_dci_format_t *formats = NULL; srslte_dci_format_t *formats = NULL;
if (nrhs != NOF_INPUTS) { srslte_verbose = SRSLTE_VERBOSE_DEBUG;
if (nrhs < NOF_INPUTS) {
help(); help();
return; return;
} }
@ -93,7 +95,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { if (srslte_ofdm_rx_init(&ofdm_rx, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n"); fprintf(stderr, "Error initializing FFT\n");
return; return;
} }
@ -115,39 +117,53 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
/** Allocate input buffers */ // Read input signal
if (mexutils_read_cf(INPUT, &input_signal) < 0) { int insignal_len = mexutils_read_cf(INPUT, &input_signal);
if (insignal_len < 0) {
mexErrMsgTxt("Error reading input signal\n"); mexErrMsgTxt("Error reading input signal\n");
return; return;
} }
if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) {
input_fft = input_signal;
mexPrintf("Input is freq domain\n");
} else {
input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft);
free(input_signal);
mexPrintf("Input is time domain\n");
}
// Set Channel estimates to 1.0 (ignore fading)
cf_t *ce[SRSLTE_MAX_PORTS]; cf_t *ce[SRSLTE_MAX_PORTS];
for (i=0;i<cell.nof_ports;i++) { 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)); ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
} }
srslte_ofdm_rx_sf(&fft, input_signal, input_fft);
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray; cf_t *cearray = NULL;
nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray); nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
cf_t *cearray_ptr = cearray;
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
for (int j=0;j<nof_re;j++) { for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
ce[i][j] = *cearray; ce[i][j] = *cearray_ptr;
cearray++; cearray_ptr++;
} }
} }
printf("loading %d re ce\n", nof_re);
if (cearray) {
free(cearray);
}
} else { } else {
srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx); srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx);
} }
float noise_power; float noise_power;
if (nrhs > NOF_INPUTS + 1) { if (nrhs > NOF_INPUTS + 1) {
noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); noise_power = mxGetScalar(prhs[NOF_INPUTS+1]);
} else if (nrhs > NOF_INPUTS) {
noise_power = 0;
} else { } else {
noise_power = srslte_chest_dl_get_noise_estimate(&chest); noise_power = srslte_chest_dl_get_noise_estimate(&chest);
} }
mexPrintf("noise power=%f, RNTI=0x%x, cfi=%d\n", noise_power, rnti, cfi);
srslte_pdcch_extract_llr(&pdcch, input_fft, ce, noise_power, sf_idx, cfi); srslte_pdcch_extract_llr(&pdcch, input_fft, ce, noise_power, sf_idx, cfi);
@ -184,16 +200,21 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
if (nlhs >= 3) { if (nlhs >= 3) {
mexutils_write_cf(pdcch.symbols[0], &plhs[2], 36*pdcch.nof_cce, 1); mexutils_write_cf(pdcch.symbols[0], &plhs[2], 36*pdcch.nof_cce, 1);
} }
if (nlhs >= 4) {
mexutils_write_cf(pdcch.d, &plhs[3], 36*pdcch.nof_cce, 1);
}
if (nlhs >= 5) {
mexutils_write_cf(ce[0], &plhs[4], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1);
}
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_ofdm_rx_free(&fft); srslte_ofdm_rx_free(&ofdm_rx);
srslte_pdcch_free(&pdcch); srslte_pdcch_free(&pdcch);
srslte_regs_free(&regs); srslte_regs_free(&regs);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
free(ce[i]); free(ce[i]);
} }
free(input_signal);
free(input_fft); free(input_fft);
return; return;

@ -42,7 +42,7 @@ srslte_cell_t cell = {
0, 0,
0, // cell_id 0, // cell_id
SRSLTE_CP_NORM, // cyclic prefix SRSLTE_CP_NORM, // cyclic prefix
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources SRSLTE_PHICH_R_1_6, // PHICH resources
SRSLTE_PHICH_NORM // PHICH length SRSLTE_PHICH_NORM // PHICH length
}; };

@ -52,6 +52,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ {
int i; int i;
srslte_cell_t cell; srslte_cell_t cell;
srslte_ofdm_t ofdm_rx;
srslte_pdsch_t pdsch; srslte_pdsch_t pdsch;
srslte_chest_dl_t chest; srslte_chest_dl_t chest;
cf_t *input_fft; cf_t *input_fft;
@ -87,6 +88,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
return; return;
} }
if (srslte_ofdm_rx_init(&ofdm_rx, cell.cp, cell.nof_prb)) {
fprintf(stderr, "Error initializing FFT\n");
return;
}
if (srslte_pdsch_init(&pdsch, cell)) { if (srslte_pdsch_init(&pdsch, cell)) {
mexErrMsgTxt("Error initiating PDSCH\n"); mexErrMsgTxt("Error initiating PDSCH\n");
return; return;
@ -192,6 +198,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
} }
srslte_sch_set_max_noi(&pdsch.dl_sch, max_iterations); srslte_sch_set_max_noi(&pdsch.dl_sch, max_iterations);
input_fft = NULL;
int r=-1; int r=-1;
for (int rvIdx=0;rvIdx<nof_retx && r != 0;rvIdx++) { for (int rvIdx=0;rvIdx<nof_retx && r != 0;rvIdx++) {
@ -202,23 +209,34 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
cfg.rv = rv_seq[rvIdx%4]; cfg.rv = rv_seq[rvIdx%4];
} }
} }
if (mexutils_read_cf(tmp, &input_fft) < 0) {
// 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"); mexErrMsgTxt("Error reading input signal\n");
return; return;
} }
if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) {
input_fft = input_signal;
} else {
input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft);
free(input_signal);
}
if (nrhs > NOF_INPUTS) { if (nrhs > NOF_INPUTS) {
cf_t *cearray = NULL; cf_t *cearray = NULL;
int nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray); mexutils_read_cf(prhs[NOF_INPUTS], &cearray);
cf_t *cearray_ptr = cearray; cf_t *cearray_ptr = cearray;
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
for (int j=0;j<nof_re/cell.nof_ports;j++) { for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) {
ce[i][j] = *cearray; ce[i][j] = *cearray_ptr;
cearray++; cearray_ptr++;
} }
} }
if (cearray_ptr) if (cearray)
free(cearray_ptr); free(cearray);
} else { } else {
srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx); srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx);
} }
@ -226,14 +244,13 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
float noise_power; float noise_power;
if (nrhs > NOF_INPUTS + 1) { if (nrhs > NOF_INPUTS + 1) {
noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); noise_power = mxGetScalar(prhs[NOF_INPUTS+1]);
} else if (nrhs > NOF_INPUTS) {
noise_power = 0;
} else { } else {
noise_power = srslte_chest_dl_get_noise_estimate(&chest); noise_power = srslte_chest_dl_get_noise_estimate(&chest);
} }
r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, 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); uint8_t *data = malloc(grant.mcs.tbs);
@ -258,12 +275,16 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
srslte_softbuffer_rx_free(&softbuffer); srslte_softbuffer_rx_free(&softbuffer);
srslte_chest_dl_free(&chest); srslte_chest_dl_free(&chest);
srslte_pdsch_free(&pdsch); srslte_pdsch_free(&pdsch);
srslte_ofdm_rx_free(&ofdm_rx);
for (i=0;i<cell.nof_ports;i++) { for (i=0;i<cell.nof_ports;i++) {
free(ce[i]); free(ce[i]);
} }
free(data_bytes); free(data_bytes);
free(data); free(data);
if (input_fft) {
free(input_fft);
}
return; return;
} }

@ -89,9 +89,9 @@ void parse_args(int argc, char **argv) {
break; break;
case 'g': case 'g':
if (!strcmp(argv[optind], "1/6")) { if (!strcmp(argv[optind], "1/6")) {
cell.phich_resources = SRSLTE_PHICH_SRSLTE_PHICH_R_1_6; cell.phich_resources = SRSLTE_PHICH_R_1_6;
} else if (!strcmp(argv[optind], "1/2")) { } else if (!strcmp(argv[optind], "1/2")) {
cell.phich_resources = SRSLTE_PHICH_SRSLTE_PHICH_R_1_2; cell.phich_resources = SRSLTE_PHICH_R_1_2;
} else if (!strcmp(argv[optind], "1")) { } else if (!strcmp(argv[optind], "1")) {
cell.phich_resources = SRSLTE_PHICH_R_1; cell.phich_resources = SRSLTE_PHICH_R_1;
} else if (!strcmp(argv[optind], "2")) { } else if (!strcmp(argv[optind], "2")) {

@ -71,9 +71,9 @@ void parse_args(int argc, char **argv) {
break; break;
case 'g': case 'g':
if (!strcmp(argv[optind], "1/6")) { if (!strcmp(argv[optind], "1/6")) {
phich_res = SRSLTE_PHICH_SRSLTE_PHICH_R_1_6; phich_res = SRSLTE_PHICH_R_1_6;
} else if (!strcmp(argv[optind], "1/2")) { } else if (!strcmp(argv[optind], "1/2")) {
phich_res = SRSLTE_PHICH_SRSLTE_PHICH_R_1_2; phich_res = SRSLTE_PHICH_R_1_2;
} else if (!strcmp(argv[optind], "1")) { } else if (!strcmp(argv[optind], "1")) {
phich_res = SRSLTE_PHICH_R_1; phich_res = SRSLTE_PHICH_R_1;
} else if (!strcmp(argv[optind], "2")) { } else if (!strcmp(argv[optind], "2")) {

@ -39,7 +39,7 @@ srslte_cell_t cell = {
2, // bw_idx = 5 MHz 2, // bw_idx = 5 MHz
1, // cell_id 1, // cell_id
SRSLTE_CP_NORM, // cyclic prefix SRSLTE_CP_NORM, // cyclic prefix
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources SRSLTE_PHICH_R_1_6, // PHICH resources
SRSLTE_PHICH_NORM // PHICH length SRSLTE_PHICH_NORM // PHICH length
}; };

@ -38,7 +38,7 @@ srslte_cell_t cell = {
1, // nof_ports 1, // nof_ports
0, // cell_id 0, // cell_id
SRSLTE_CP_NORM, // cyclic prefix SRSLTE_CP_NORM, // cyclic prefix
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources SRSLTE_PHICH_R_1_6, // PHICH resources
SRSLTE_PHICH_NORM // PHICH length SRSLTE_PHICH_NORM // PHICH length
}; };

@ -220,7 +220,7 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
INFO("Decoded CFI=%d with correlation %.2f\n", *cfi, cfi_corr); INFO("Decoded CFI=%d with correlation %.2f, sf_idx=%d\n", *cfi, cfi_corr, sf_idx);
if (srslte_regs_set_cfi(&q->regs, *cfi)) { if (srslte_regs_set_cfi(&q->regs, *cfi)) {
fprintf(stderr, "Error setting CFI\n"); fprintf(stderr, "Error setting CFI\n");
@ -252,7 +252,7 @@ int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *
} }
if (q->pdsch_cfg.rv == 0) { if (q->pdsch_cfg.rv == 0) {
srslte_softbuffer_rx_reset(&q->softbuffer); srslte_softbuffer_rx_reset_tbs(&q->softbuffer, grant->mcs.tbs);
} }
// Uncoment next line to do ZF by default in pdsch_ue example // Uncoment next line to do ZF by default in pdsch_ue example
@ -359,7 +359,7 @@ int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg,
uint16_t crc_rem = 0; uint16_t crc_rem = 0;
for (int f=0;f<nof_formats && crc_rem != rnti;f++) { for (int f=0;f<nof_formats && crc_rem != rnti;f++) {
for (int i=0;i<nof_locations && crc_rem != rnti;i++) { for (int i=0;i<nof_locations && crc_rem != rnti;i++) {
INFO("Trying format %s (nbits=%d), location L=%d, ncce=%d\n", srslte_dci_format_string(formats[f]), DEBUG("Trying format %s (nbits=%d), location L=%d, ncce=%d\n", srslte_dci_format_string(formats[f]),
srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb), locations[i].L, locations[i].ncce); srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb), locations[i].L, locations[i].ncce);
q->last_n_cce = locations[i].ncce; q->last_n_cce = locations[i].ncce;
if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &locations[i], formats[f], &crc_rem)) { if (srslte_pdcch_decode_msg(&q->pdcch, dci_msg, &locations[i], formats[f], &crc_rem)) {
@ -367,6 +367,7 @@ int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg,
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (crc_rem == rnti) { if (crc_rem == rnti) {
INFO("Found DCI nCCE: %d, L: %d, n_bits=%d\n", locations[i].ncce, locations[i].L, srslte_dci_format_sizeof_lut(formats[f], q->cell.nof_prb));
memcpy(&q->last_location, &locations[i], sizeof(srslte_dci_location_t)); memcpy(&q->last_location, &locations[i], sizeof(srslte_dci_location_t));
} }
if (crc_rem == rnti && formats[f] == SRSLTE_DCI_FORMAT1A && dci_msg->data[0] != 1) { if (crc_rem == rnti && formats[f] == SRSLTE_DCI_FORMAT1A && dci_msg->data[0] != 1) {
@ -381,6 +382,7 @@ int srslte_ue_dl_find_dl_dci_type(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg,
if (crc_rem == rnti) { if (crc_rem == rnti) {
return 1; return 1;
} else { } else {
INFO("Couldn't find any DCI for RNTI=0x%x\n", rnti);
return 0; return 0;
} }
} }
@ -444,5 +446,36 @@ 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) {
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("ce0", q->ce[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("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));
srslte_vec_save_file("pcfich_symbols", q->pcfich.symbols[0], q->pcfich.nof_symbols*sizeof(cf_t));
srslte_vec_save_file("pcfich_eq_symbols", q->pcfich.d, q->pcfich.nof_symbols*sizeof(cf_t));
srslte_vec_save_file("pcfich_llr", q->pcfich.data_f, PCFICH_CFI_LEN*sizeof(float));
srslte_vec_save_file("pdcch_ce0", q->pdcch.ce[0], q->pdcch.nof_cce*36*sizeof(cf_t));
srslte_vec_save_file("pdcch_ce1", q->pdcch.ce[1], q->pdcch.nof_cce*36*sizeof(cf_t));
srslte_vec_save_file("pdcch_symbols", q->pdcch.symbols[0], q->pdcch.nof_cce*36*sizeof(cf_t));
srslte_vec_save_file("pdcch_eq_symbols", q->pdcch.d, q->pdcch.nof_cce*36*sizeof(cf_t));
srslte_vec_save_file("pdcch_llr", q->pdcch.llr, q->pdcch.nof_cce*72*sizeof(float));
srslte_vec_save_file("pdsch_symbols", q->pdsch.d, q->pdsch_cfg.nbits.nof_re*sizeof(cf_t));
srslte_vec_save_file("llr", q->pdsch.e, q->pdsch_cfg.nbits.nof_bits*sizeof(cf_t));
int cb_len = q->pdsch_cfg.cb_segm.K1;
for (int i=0;i<q->pdsch_cfg.cb_segm.C;i++) {
char tmpstr[64];
snprintf(tmpstr,64,"rmout_%d.dat",i);
srslte_vec_save_file(tmpstr, softbuffer->buffer_f[i], (3*cb_len+12)*sizeof(int16_t));
}
printf("Saved files for tti=%d, sf=%d, cfi=%d, mcs=%d, rv=%d, rnti=%d\n", tti, tti%10, q->cfi,
q->pdsch_cfg.grant.mcs.idx, rv_idx, q->current_rnti);
}

@ -153,7 +153,7 @@ int srslte_ue_mib_decode(srslte_ue_mib_t * q, cf_t *input,
srslte_ue_mib_reset(q); srslte_ue_mib_reset(q);
ret = SRSLTE_UE_MIB_FOUND; ret = SRSLTE_UE_MIB_FOUND;
} else { } else {
DEBUG("MIB not decoded: %u\n", q->frame_cnt); INFO("MIB not decoded: %u\n", q->frame_cnt);
q->frame_cnt++; q->frame_cnt++;
ret = SRSLTE_UE_MIB_NOTFOUND; ret = SRSLTE_UE_MIB_NOTFOUND;
} }

@ -504,7 +504,7 @@ int srslte_ue_sync_zerocopy(srslte_ue_sync_t *q, cf_t *input_buffer) {
if (q->sf_idx == 10) { if (q->sf_idx == 10) {
q->sf_idx = 0; q->sf_idx = 0;
} }
DEBUG("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx); INFO("Reading %d samples. sf_idx = %d\n", q->sf_len, q->sf_idx);
ret = 1; ret = 1;
} else { } else {
if (receive_samples(q, input_buffer)) { if (receive_samples(q, input_buffer)) {

Loading…
Cancel
Save