DL grant parameter are now vectors of MAX_CODEWORDS

master
Xavier Arteaga 7 years ago
parent cb4b4f4d4c
commit 2c07a16189

@ -86,7 +86,8 @@ srslte_pdsch_t pdsch;
srslte_pdsch_cfg_t pdsch_cfg;
srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS];
srslte_regs_t regs;
srslte_ra_dl_dci_t ra_dl;
srslte_ra_dl_dci_t ra_dl;
int rvidx[SRSLTE_MAX_CODEWORDS] = {0, 0};
cf_t *sf_buffer[SRSLTE_MAX_PORTS] = {NULL}, *output_buffer [SRSLTE_MAX_PORTS] = {NULL};
int sf_n_re, sf_n_samples;
@ -423,7 +424,7 @@ int update_radl() {
ra_dl.harq_process = 0;
ra_dl.mcs_idx = mcs_idx;
ra_dl.ndi = 0;
ra_dl.rv_idx = 0;
ra_dl.rv_idx = rvidx[0];
ra_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
ra_dl.type0_alloc.rbg_bitmask = prbset_to_bitmask();
ra_dl.tb_en[0] = 1;
@ -431,7 +432,7 @@ int update_radl() {
if (nof_tb > 1) {
ra_dl.mcs_idx_1 = mcs_idx;
ra_dl.ndi_1 = 0;
ra_dl.rv_idx_1 = 0;
ra_dl.rv_idx_1 = rvidx[1];
ra_dl.tb_en[1] = 1;
}
@ -513,7 +514,7 @@ void *net_thread_fnc(void *arg) {
n = srslte_netsource_read(&net_source, &data2[rpm], DATA_BUFF_SZ-rpm);
if (n > 0) {
// FIXME: I assume that both transport blocks have same size in case of 2 tb are active
int nbytes = 1 + (pdsch_cfg.grant.mcs.tbs + pdsch_cfg.grant.mcs2.tbs - 1) / 8;
int nbytes = 1 + (pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs - 1) / 8;
rpm += n;
INFO("received %d bytes. rpm=%d/%d\n",n,rpm,nbytes);
wpm = 0;
@ -696,12 +697,11 @@ int main(int argc, char **argv) {
INFO("Transmitting packet\n",0);
}
} else {
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs.tbs);
for (i = 0; i < pdsch_cfg.grant.mcs.tbs / 8; i++) {
data[0][i] = rand() % 256;
}
for (i = 0; i < pdsch_cfg.grant.mcs2.tbs / 8; i++) {
data[1][i] = rand() % 256;
INFO("SF: %d, Generating %d random bits\n", sf_idx, pdsch_cfg.grant.mcs[0].tbs + pdsch_cfg.grant.mcs[1].tbs);
for (uint32_t tb = 0; tb < pdsch_cfg.grant.nof_tb; tb++) {
for (i = 0; i < pdsch_cfg.grant.mcs[tb].tbs / 8; i++) {
data[tb][i] = (uint8_t) rand();
}
}
/* Uncomment this to transmit on sf 0 and 5 only */
if (sf_idx != 0 && sf_idx != 5) {
@ -744,7 +744,7 @@ int main(int argc, char **argv) {
/* Configure pdsch_cfg parameters */
srslte_ra_dl_grant_t grant;
srslte_ra_dl_dci_to_grant(&ra_dl, cell.nof_prb, UE_CRNTI, &grant);
if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, sf_idx, 0, 0, pdsch_cfg.mimo_type, multiplex_pmi)) {
if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, sf_idx, rvidx, pdsch_cfg.mimo_type, multiplex_pmi)) {
fprintf(stderr, "Error configuring PDSCH\n");
exit(-1);
}
@ -757,13 +757,9 @@ int main(int argc, char **argv) {
}
if (net_port > 0 && net_packet_ready) {
if (null_file_sink) {
srslte_bit_pack_vector(data[0], data_tmp, pdsch_cfg.grant.mcs.tbs);
if (srslte_netsink_write(&net_sink, data_tmp, 1+(pdsch_cfg.grant.mcs.tbs-1)/8) < 0) {
fprintf(stderr, "Error sending data through UDP socket\n");
}
if (nof_tb > 1) {
srslte_bit_pack_vector(data[1], data_tmp, pdsch_cfg.grant.mcs2.tbs);
if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.mcs2.tbs - 1) / 8) < 0) {
for (uint32_t tb = 0; tb < pdsch_cfg.grant.nof_tb; tb++) {
srslte_bit_pack_vector(data[tb], data_tmp, pdsch_cfg.grant.mcs[tb].tbs);
if (srslte_netsink_write(&net_sink, data_tmp, 1 + (pdsch_cfg.grant.mcs[tb].tbs - 1) / 8) < 0) {
fprintf(stderr, "Error sending data through UDP socket\n");
}
}

@ -594,8 +594,10 @@ int main(int argc, char **argv) {
/* Send data if socket active */
if (prog_args.net_port > 0) {
// FIXME: UDP Data transmission does not work
srslte_netsink_write(&net_sink, data[0], 1 + (ue_dl.pdsch_cfg.grant.mcs.tbs - 1) / 8);
srslte_netsink_write(&net_sink, data[1], 1 + (ue_dl.pdsch_cfg.grant.mcs2.tbs - 1) / 8);
for (uint32_t tb = 0; tb < ue_dl.pdsch_cfg.grant.nof_tb; tb++) {
srslte_netsink_write(&net_sink, data[tb], 1 + (ue_dl.pdsch_cfg.grant.mcs[tb].tbs - 1) / 8);
}
}
#ifdef PRINT_CHANGE_SCHEDULIGN
@ -616,12 +618,12 @@ int main(int argc, char **argv) {
nof_trials++;
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1);
rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05);
rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05);
noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05);
enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs.tbs + ue_dl.pdsch_cfg.grant.mcs2.tbs)/1000.0, enodebrate, 0.05);
uerate = SRSLTE_VEC_EMA((n>0)?(ue_dl.pdsch_cfg.grant.mcs.tbs + ue_dl.pdsch_cfg.grant.mcs2.tbs)/1000.0:0.0, uerate, 0.01);
rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&ue_dl.chest), rsrq, 0.1f);
rsrp0 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 0), rsrp0, 0.05f);
rsrp1 = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp_port(&ue_dl.chest, 1), rsrp1, 0.05f);
noise = SRSLTE_VEC_EMA(srslte_chest_dl_get_noise_estimate(&ue_dl.chest), noise, 0.05f);
enodebrate = SRSLTE_VEC_EMA((ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f, enodebrate, 0.05f);
uerate = SRSLTE_VEC_EMA((n>0)?(ue_dl.pdsch_cfg.grant.mcs[0].tbs + ue_dl.pdsch_cfg.grant.mcs[1].tbs)/1000.0f:0.0f, uerate, 0.01f);
nframes++;
if (isnan(rsrq)) {
@ -812,7 +814,7 @@ void *plot_thread_run(void *arg) {
while(1) {
sem_wait(&plot_sem);
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits.nof_re;
uint32_t nof_symbols = ue_dl.pdsch_cfg.nbits[0].nof_re;
if (!prog_args.disable_plots_except_constellation) {
for (i = 0; i < nof_re; i++) {
tmp_plot[i] = 20 * log10f(cabsf(ue_dl.sf_symbols[i]));

@ -104,15 +104,14 @@ SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg,
srslte_ra_dl_grant_t *grant,
uint32_t cfi,
uint32_t sf_idx,
uint32_t rvidx);
int rvidx);
SRSLTE_API int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg,
srslte_cell_t cell,
srslte_ra_dl_grant_t *grant,
uint32_t cfi,
uint32_t sf_idx,
uint32_t rvidx,
uint32_t rvidx2,
int rvidx[SRSLTE_MAX_CODEWORDS],
srslte_mimo_type_t mimo_type,
uint32_t pmi);
@ -156,7 +155,7 @@ SRSLTE_API int srslte_pdsch_pmi_select(srslte_pdsch_t *q,
uint32_t pmi[SRSLTE_MAX_LAYERS],
float sinr[SRSLTE_MAX_LAYERS][SRSLTE_MAX_CODEBOOKS]);
SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, int max_iter);
SRSLTE_API void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, uint32_t max_iter);
SRSLTE_API float srslte_pdsch_average_noi(srslte_pdsch_t *q);

@ -40,14 +40,11 @@
#include "srslte/phy/fec/cbsegm.h"
typedef struct SRSLTE_API {
srslte_cbsegm_t cb_segm;
srslte_cbsegm_t cb_segm2;
srslte_ra_dl_grant_t grant;
srslte_ra_nbits_t nbits;
srslte_ra_nbits_t nbits2;
uint32_t rv;
uint32_t rv2;
uint32_t sf_idx;
srslte_cbsegm_t cb_segm[SRSLTE_MAX_CODEWORDS];
srslte_ra_dl_grant_t grant;
srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS];
uint32_t rv[SRSLTE_MAX_CODEWORDS];
uint32_t sf_idx;
uint32_t nof_layers;
uint32_t codebook_idx;
srslte_mimo_type_t mimo_type;

@ -102,10 +102,8 @@ typedef struct SRSLTE_API {
typedef struct SRSLTE_API {
bool prb_idx[2][SRSLTE_MAX_PRB];
uint32_t nof_prb;
uint32_t Qm;
uint32_t Qm2;
srslte_ra_mcs_t mcs;
srslte_ra_mcs_t mcs2;
uint32_t Qm[SRSLTE_MAX_CODEWORDS];
srslte_ra_mcs_t mcs[SRSLTE_MAX_CODEWORDS];
uint32_t nof_tb;
} srslte_ra_dl_grant_t;
@ -206,8 +204,8 @@ SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci,
SRSLTE_API void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant,
uint32_t cfi,
srslte_cell_t cell,
uint32_t sf_idx,
srslte_ra_nbits_t *nbits);
uint32_t sf_idx,
srslte_ra_nbits_t nbits[SRSLTE_MAX_CODEWORDS]);
SRSLTE_API void srslte_ra_dl_grant_to_nbits_multi(srslte_ra_dl_grant_t *grant,
uint32_t cfi,

@ -103,12 +103,6 @@ SRSLTE_API int srslte_dlsch_encode2(srslte_sch_t *q,
uint8_t *e_bits,
int codeword_idx);
SRSLTE_API int srslte_dlsch_encode_multi(srslte_sch_t *q,
srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS],
uint8_t *data[SRSLTE_MAX_CODEWORDS],
uint8_t *e_bits[SRSLTE_MAX_CODEWORDS]);
SRSLTE_API int srslte_dlsch_decode(srslte_sch_t *q,
srslte_pdsch_cfg_t *cfg,
srslte_softbuffer_rx_t *softbuffer,

@ -145,14 +145,13 @@ SRSLTE_API int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q,
srslte_ra_dl_grant_t *grant,
uint32_t cfi,
uint32_t sf_idx,
uint32_t rvidx);
int rvidx);
SRSLTE_API int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q,
srslte_ra_dl_grant_t *grant,
uint32_t cfi,
uint32_t sf_idx,
uint32_t rvidx,
uint32_t rvidx2,
int rvidx[SRSLTE_MAX_CODEWORDS],
srslte_mimo_type_t mimo_type,
uint32_t pinfo);

@ -58,10 +58,10 @@ SRSLTE_API extern int srslte_verbose;
#define PRINT_NONE srslte_verbose=SRSLTE_VERBOSE_NONE
#define DEBUG(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_DEBUG) \
fprintf(stdout, "[DEBUG]: " _fmt, __VA_ARGS__)
fprintf(stdout, "[DEBUG]: " _fmt, ##__VA_ARGS__)
#define INFO(_fmt, ...) if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO) \
fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__)
fprintf(stdout, "[INFO]: " _fmt, ##__VA_ARGS__)
#if CMAKE_BUILD_TYPE==Debug
/* In debug mode, it prints out the */

@ -358,50 +358,35 @@ void srslte_pdsch_free(srslte_pdsch_t *q) {
/* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg.
* If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant
*/
int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint32_t rvidx)
{
if (cfg) {
if (grant) {
memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t));
}
if (srslte_cbsegm(&cfg->cb_segm, cfg->grant.mcs.tbs)) {
fprintf(stderr, "Error computing Codeblock segmentation for TBS=%d\n", cfg->grant.mcs.tbs);
return SRSLTE_ERROR;
}
srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits);
cfg->sf_idx = sf_idx;
cfg->rv = rvidx;
int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi,
uint32_t sf_idx, int rvidx) {
int _rvids[SRSLTE_MAX_CODEWORDS] = {1};
_rvids[0] = rvidx;
return SRSLTE_SUCCESS;
} else {
return SRSLTE_ERROR_INVALID_INPUTS;
}
return srslte_pdsch_cfg_multi(cfg, cell, grant, cfi, sf_idx, _rvids, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0);
}
/* Configures the structure srslte_pdsch_cfg_t from the DL DCI allocation dci_msg.
* If dci_msg is NULL, the grant is assumed to be already stored in cfg->grant
*/
int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_ra_dl_grant_t *grant, uint32_t cfi,
uint32_t sf_idx, uint32_t rvidx, uint32_t rvidx2, srslte_mimo_type_t mimo_type, uint32_t pmi)
{
uint32_t sf_idx, int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type,
uint32_t pmi) {
if (cfg) {
if (grant) {
memcpy(&cfg->grant, grant, sizeof(srslte_ra_dl_grant_t));
}
if (srslte_cbsegm(&cfg->cb_segm, (uint32_t) cfg->grant.mcs.tbs)) {
fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs.tbs);
return SRSLTE_ERROR;
}
if (srslte_cbsegm(&cfg->cb_segm2, (uint32_t) cfg->grant.mcs2.tbs)) {
fprintf(stderr, "Error computing Codeblock (2) segmentation for TBS=%d\n", cfg->grant.mcs2.tbs);
return SRSLTE_ERROR;
for (int i = 0; i < grant->nof_tb; i++) {
if (srslte_cbsegm(&cfg->cb_segm[i], (uint32_t) cfg->grant.mcs[i].tbs)) {
fprintf(stderr, "Error computing Codeblock (1) segmentation for TBS=%d\n", cfg->grant.mcs[i].tbs);
return SRSLTE_ERROR;
}
}
srslte_ra_dl_grant_to_nbits(&cfg->grant, cfi, cell, sf_idx, cfg->nbits);
srslte_ra_dl_grant_to_nbits_multi(&cfg->grant, cfi, cell, sf_idx, &cfg->nbits, &cfg->nbits2);
cfg->sf_idx = sf_idx;
cfg->rv = rvidx;
cfg->rv2 = rvidx2;
memcpy(cfg->rv, rvidx, sizeof(uint32_t) * SRSLTE_MAX_CODEWORDS);
cfg->mimo_type = mimo_type;
/* Check and configure PDSCH transmission modes */
@ -428,11 +413,12 @@ int srslte_pdsch_cfg_multi(srslte_pdsch_cfg_t *cfg, srslte_cell_t cell, srslte_r
cfg->codebook_idx = pmi + 1;
cfg->nof_layers = 2;
}
INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; codebook_idx=%d;\n", grant->nof_tb, cfg->nof_layers, cfg->codebook_idx);
INFO("PDSCH configured for Spatial Multiplex; nof_codewords=%d; nof_layers=%d; codebook_idx=%d;\n",
grant->nof_tb, cfg->nof_layers, cfg->codebook_idx);
break;
case SRSLTE_MIMO_TYPE_CDD:
if (grant->nof_tb != 2) {
ERROR("Number of transport blocks is not supported for CDD transmission mode.");
ERROR("Number of transport blocks (%d) is not supported for CDD transmission mode.", grant->nof_tb);
return SRSLTE_ERROR;
}
cfg->nof_layers = 2;
@ -472,13 +458,14 @@ static int srslte_pdsch_codeword_encode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_
srslte_softbuffer_tx_t *softbuffer, uint16_t rnti, uint8_t *data,
uint32_t codeword_idx) {
srslte_sch_t *dl_sch = &pdsch->dl_sch[codeword_idx];
srslte_ra_nbits_t *nbits = (codeword_idx == 0) ? &cfg->nbits : &cfg->nbits2;
srslte_ra_mcs_t *mcs = (codeword_idx == 0) ? &cfg->grant.mcs : &cfg->grant.mcs2;
srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx];
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx];
uint32_t rv = cfg->rv[codeword_idx];
if (nbits->nof_bits) {
INFO("Encoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
nbits->nof_re, nbits->nof_bits, (codeword_idx == 0) ? cfg->rv : cfg->rv2);
nbits->nof_re, nbits->nof_bits, rv);
/* Channel coding */
if (srslte_dlsch_encode2(dl_sch, cfg, softbuffer, data, pdsch->e[codeword_idx], codeword_idx)) {
@ -516,19 +503,20 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *pdsch, srslte_pdsch_cfg_
srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
uint32_t codeword_idx) {
srslte_sch_t *dl_sch = &pdsch->dl_sch[codeword_idx];
srslte_ra_nbits_t *nbits = (codeword_idx == 0) ? &cfg->nbits : &cfg->nbits2;
srslte_ra_mcs_t *mcs = (codeword_idx == 0) ? &cfg->grant.mcs : &cfg->grant.mcs2;
srslte_ra_nbits_t *nbits = &cfg->nbits[codeword_idx];
srslte_ra_mcs_t *mcs = &cfg->grant.mcs[codeword_idx];
uint32_t rv = cfg->rv[codeword_idx];
if (nbits->nof_bits) {
INFO("Decoding PDSCH SF: %d (TB %d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, codeword_idx, srslte_mod_string(mcs->mod), mcs->tbs,
nbits->nof_re, nbits->nof_bits, (codeword_idx == 0) ? cfg->rv : cfg->rv2);
nbits->nof_re, nbits->nof_bits, rv);
/* demodulate symbols
* The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
* thus we don't need tot set it in the LLRs normalization
*/
srslte_demod_soft_demodulate_s(mcs->mod, pdsch->d[codeword_idx], pdsch->e[codeword_idx], cfg->nbits.nof_re);
srslte_demod_soft_demodulate_s(mcs->mod, pdsch->d[codeword_idx], pdsch->e[codeword_idx], nbits->nof_re);
if (pdsch->users[rnti] && pdsch->users[rnti]->sequence_generated) {
srslte_scrambling_s_offset(&pdsch->users[rnti]->seq[codeword_idx][cfg->sf_idx], pdsch->e[codeword_idx],
@ -596,23 +584,22 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
cfg != NULL)
{
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: [%d %d], C_prb=%d\n",
cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
cfg->nbits.nof_bits, cfg->rv, cfg->rv2, cfg->grant.nof_prb);
INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d\n",
cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb);
for (int j=0;j<q->nof_rx_antennas;j++) {
/* extract symbols */
int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
if (n != cfg->nbits[0].nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
return SRSLTE_ERROR;
}
/* extract channel estimates */
for (i = 0; i < q->cell.nof_ports; i++) {
n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
if (n != cfg->nbits.nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
if (n != cfg->nbits[0].nof_re) {
fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
return SRSLTE_ERROR;
}
}
@ -620,35 +607,31 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
INFO("PDSCH Layer demapper and predecode: mimo_type=%d, nof_layers=%d, nof_tb=%d\n", cfg->mimo_type,
cfg->nof_layers, cfg->grant.nof_tb);
if (q->cell.nof_ports == 1) {
/* no need for layer demapping */
srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d[0], q->nof_rx_antennas, cfg->nbits.nof_re, noise_estimate);
} else {
int nof_symbols [SRSLTE_MAX_CODEWORDS];
nof_symbols[0] = cfg->nbits.nof_re * cfg->grant.nof_tb / cfg->nof_layers;
nof_symbols[1] = cfg->nbits2.nof_re * cfg->grant.nof_tb / cfg->nof_layers;
if (cfg->nof_layers == cfg->grant.nof_tb) {
for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->d[i];
}
int nof_symbols [SRSLTE_MAX_CODEWORDS];
nof_symbols[0] = cfg->nbits[0].nof_re * cfg->grant.nof_tb / cfg->nof_layers;
nof_symbols[1] = cfg->nbits[1].nof_re * cfg->grant.nof_tb / cfg->nof_layers;
if (cfg->nof_layers == cfg->grant.nof_tb) {
/* Skip layer demap */
for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->d[i];
}
srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
cfg->codebook_idx, cfg->nbits.nof_re, cfg->mimo_type, noise_estimate);
srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, noise_estimate);
} else {
/* number of layers equals number of ports */
for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->x[i];
}
memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers));
} else {
/* number of layers equals number of ports */
for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->x[i];
}
memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers));
srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
cfg->codebook_idx, cfg->nbits.nof_re, cfg->mimo_type, noise_estimate);
srslte_predecoding_type_multi(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, noise_estimate);
srslte_layerdemap_type(x, q->d, cfg->nof_layers, cfg->grant.nof_tb,
nof_symbols[0], nof_symbols, cfg->mimo_type);
}
srslte_layerdemap_type(x, q->d, cfg->nof_layers, cfg->grant.nof_tb,
nof_symbols[0], nof_symbols, cfg->mimo_type);
}
if (SRSLTE_VERBOSE_ISDEBUG()) {
@ -671,7 +654,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
}
}
DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0);
srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits.nof_re*sizeof(cf_t));
srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits[0].nof_re*sizeof(cf_t));
}
for (uint32_t tb = 0; tb < cfg->grant.nof_tb; tb ++) {
@ -680,7 +663,7 @@ int srslte_pdsch_decode_multi(srslte_pdsch_t *q,
if (SRSLTE_VERBOSE_ISDEBUG()) {
DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0);
srslte_vec_save_file("llr.dat", q->e, cfg->nbits.nof_bits*sizeof(int16_t));
srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t));
}
return ret;
@ -733,20 +716,20 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
}
}
if (cfg->grant.mcs.tbs == 0) {
if (cfg->grant.mcs[0].tbs == 0) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (cfg->nbits.nof_re > q->max_re) {
if (cfg->nbits[0].nof_re > q->max_re) {
fprintf(stderr,
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
cfg->nbits.nof_re, q->max_re, q->cell.nof_prb);
cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb);
return SRSLTE_ERROR_INVALID_INPUTS;
}
INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs,
cfg->nbits.nof_re, cfg->nbits.nof_bits, cfg->rv);
cfg->sf_idx, srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs,
cfg->nbits[0].nof_re, cfg->nbits[0].nof_bits, cfg->rv[0]);
/* number of layers equals number of ports */
for (i = 0; i < q->cell.nof_ports; i++) {
@ -761,30 +744,30 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
/* scramble */
if (q->users[rnti] && q->users[rnti]->sequence_generated) {
srslte_scrambling_bytes(&q->users[rnti]->seq[0][cfg->sf_idx], (uint8_t*) q->e[0], cfg->nbits.nof_bits);
srslte_scrambling_bytes(&q->users[rnti]->seq[0][cfg->sf_idx], (uint8_t*) q->e[0], cfg->nbits[0].nof_bits);
} else {
srslte_sequence_t seq;
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits[0].nof_bits)) {
return SRSLTE_ERROR;
}
srslte_scrambling_bytes(&seq, (uint8_t*) q->e[0], cfg->nbits.nof_bits);
srslte_scrambling_bytes(&seq, (uint8_t*) q->e[0], cfg->nbits[0].nof_bits);
srslte_sequence_free(&seq);
}
srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->e[0], q->d[0], cfg->nbits.nof_bits);
srslte_mod_modulate_bytes(&q->mod[cfg->grant.mcs[0].mod], (uint8_t*) q->e[0], q->d[0], cfg->nbits[0].nof_bits);
/* TODO: only diversity supported */
if (q->cell.nof_ports > 1) {
srslte_layermap_diversity(q->d[0], x, q->cell.nof_ports, cfg->nbits.nof_re);
srslte_layermap_diversity(q->d[0], x, q->cell.nof_ports, cfg->nbits[0].nof_re);
srslte_precoding_diversity(x, q->symbols, q->cell.nof_ports,
cfg->nbits.nof_re / q->cell.nof_ports);
cfg->nbits[0].nof_re / q->cell.nof_ports);
} else {
memcpy(q->symbols[0], q->d, cfg->nbits.nof_re * sizeof(cf_t));
memcpy(q->symbols[0], q->d, cfg->nbits[0].nof_re * sizeof(cf_t));
}
/* mapping to resource elements */
for (i = 0; i < q->cell.nof_ports; i++) {
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
}
ret = SRSLTE_SUCCESS;
@ -810,15 +793,15 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q,
}
}
/* If both transport block sizes are zero return error */
if (cfg->grant.mcs.tbs == 0 && cfg->grant.mcs2.tbs == 0) {
/* If both transport block size is zero return error */
if (cfg->grant.mcs[0].tbs == 0) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
if (cfg->nbits.nof_re > q->max_re) {
if (cfg->nbits[0].nof_re > q->max_re) {
fprintf(stderr,
"Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n",
cfg->nbits.nof_re, q->max_re, q->cell.nof_prb);
cfg->nbits[0].nof_re, q->max_re, q->cell.nof_prb);
return SRSLTE_ERROR_INVALID_INPUTS;
}
@ -833,7 +816,7 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q,
for (i = 0; i < cfg->nof_layers; i++) {
x[i] = q->d[i];
}
nof_symbols = cfg->nbits.nof_re;
nof_symbols = cfg->nbits[0].nof_re;
} else {
/* Initialise layer map pointers */
for (i = 0; i < cfg->nof_layers; i++) {
@ -842,20 +825,21 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q,
memset(&x[cfg->nof_layers], 0, sizeof(cf_t *) * (SRSLTE_MAX_LAYERS - cfg->nof_layers));
nof_symbols = srslte_layermap_type(q->d, x, cfg->grant.nof_tb, cfg->nof_layers,
(int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits.nof_re, cfg->nbits2.nof_re}, cfg->mimo_type);
(int[SRSLTE_MAX_CODEWORDS]) {cfg->nbits[0].nof_re, cfg->nbits[1].nof_re},
cfg->mimo_type);
}
/* Precode */
srslte_precoding_type(x, q->symbols, cfg->nof_layers, q->cell.nof_ports, cfg->codebook_idx,
nof_symbols, cfg->mimo_type);
} else {
memcpy(q->symbols[0], q->d[0], cfg->nbits.nof_re * sizeof(cf_t));
memcpy(q->symbols[0], q->d[0], cfg->nbits[0].nof_re * sizeof(cf_t));
}
/* mapping to resource elements */
for (i = 0; i < q->cell.nof_ports; i++) {
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
srslte_pdsch_put(q, q->symbols[i], sf_symbols[i], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
}
ret = SRSLTE_SUCCESS;
@ -863,7 +847,7 @@ int srslte_pdsch_encode_multi(srslte_pdsch_t *q,
return ret;
}
void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, int max_iter) {
void srslte_pdsch_set_max_noi(srslte_pdsch_t *q, uint32_t max_iter) {
for (int cw = 0; cw < SRSLTE_MAX_CODEWORDS; cw++) {
srslte_sch_set_max_noi(&q->dl_sch[cw], max_iter);
}

@ -492,44 +492,43 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr
fprintf(stderr, "Error decoding DCI: P/SI/RA-RNTI supports Format1A/1C only\n");
return SRSLTE_ERROR;
}
grant->mcs.mod = SRSLTE_MOD_QPSK;
grant->mcs.tbs = (uint32_t) tbs;
grant->mcs[0].mod = SRSLTE_MOD_QPSK;
grant->mcs[0].tbs = (uint32_t) tbs;
} else {
n_prb = grant->nof_prb;
if (dci->tb_en[0]) {
grant->mcs.idx = dci->mcs_idx;
tbs = dl_fill_ra_mcs(&grant->mcs, n_prb);
grant->mcs[0].idx = dci->mcs_idx;
tbs = dl_fill_ra_mcs(&grant->mcs[0], n_prb);
if (tbs) {
last_dl_tbs[dci->harq_process%8] = tbs;
} else {
// For mcs>=29, set last TBS received for this PID
grant->mcs.tbs = last_dl_tbs[dci->harq_process%8];
grant->mcs[0].tbs = last_dl_tbs[dci->harq_process%8];
}
} else {
grant->mcs.tbs = 0;
grant->mcs[0].tbs = 0;
}
if (dci->tb_en[1]) {
grant->mcs2.idx = dci->mcs_idx_1;
tbs = dl_fill_ra_mcs(&grant->mcs2, n_prb);
grant->mcs[1].idx = dci->mcs_idx_1;
tbs = dl_fill_ra_mcs(&grant->mcs[1], n_prb);
if (tbs) {
last_dl_tbs2[dci->harq_process%8] = tbs;
} else {
// For mcs>=29, set last TBS received for this PID
grant->mcs2.tbs = last_dl_tbs2[dci->harq_process%8];
grant->mcs[1].tbs = last_dl_tbs2[dci->harq_process%8];
}
} else {
grant->mcs2.tbs = 0;
grant->mcs[1].tbs = 0;
}
}
grant->nof_tb = 0;
if (dci->tb_en[0]) {
grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod);
grant->nof_tb++;
}
if (dci->tb_en[1]) {
grant->Qm2 = srslte_mod_bits_x_symbol(grant->mcs2.mod);
grant->nof_tb++;
for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
if (dci->tb_en[tb]) {
grant->Qm[tb] = srslte_mod_bits_x_symbol(grant->mcs[tb].mod);
grant->nof_tb++;
}
}
if (tbs < 0) {
return SRSLTE_ERROR;
} else {
@ -537,29 +536,16 @@ static int dl_dci_to_grant_mcs(srslte_ra_dl_dci_t *dci, srslte_ra_dl_grant_t *gr
}
}
void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx, srslte_ra_nbits_t *nbits)
void srslte_ra_dl_grant_to_nbits(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx,
srslte_ra_nbits_t nbits [SRSLTE_MAX_CODEWORDS])
{
// Compute number of RE
nbits->nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
nbits->lstart = cell.nof_prb<10?(cfi+1):cfi;
nbits->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nbits->lstart;
nbits->nof_bits = nbits->nof_re * grant->Qm;
}
void srslte_ra_dl_grant_to_nbits_multi(srslte_ra_dl_grant_t *grant, uint32_t cfi, srslte_cell_t cell, uint32_t sf_idx,
srslte_ra_nbits_t *nbits, srslte_ra_nbits_t *nbits2) {
/* Compute number of RE for first transport block */
nbits->nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb<10?(cfi+1):cfi);
nbits->lstart = cell.nof_prb<10?(cfi+1):cfi;
nbits->nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-nbits->lstart;
nbits->nof_bits = nbits->nof_re * grant->Qm;
/*/ Compute number of RE for second transport block */
if (grant->nof_tb > 1) {
nbits2->nof_re = nbits->nof_re;
nbits2->lstart = nbits->lstart;
nbits2->nof_symb = 2 * SRSLTE_CP_NSYMB(cell.cp) - nbits2->lstart;
nbits2->nof_bits = nbits2->nof_re * grant->Qm2;
for (int i = 0; i < grant->nof_tb; i++) {
/* Compute number of RE for first transport block */
nbits[i].nof_re = srslte_ra_dl_grant_nof_re(grant, cell, sf_idx, cell.nof_prb < 10 ? (cfi + 1) : cfi);
nbits[i].lstart = cell.nof_prb < 10 ? (cfi + 1) : cfi;
nbits[i].nof_symb = 2 * SRSLTE_CP_NSYMB(cell.cp) - nbits[0].lstart;
nbits[i].nof_bits = nbits[i].nof_re * grant->Qm[i];
}
}
@ -834,10 +820,11 @@ void srslte_ra_dl_grant_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {
srslte_ra_prb_fprint(f, grant);
fprintf(f, " - Number of PRBs:\t\t\t%d\n", grant->nof_prb);
fprintf(f, " - Number of TBs:\t\t\t%d\n", grant->nof_tb);
fprintf(f, " - Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs.mod));
fprintf(f, " - Transport block size:\t\t%d\n", grant->mcs.tbs);
fprintf(f, " - Modulation type (TB2):\t\t%s\n", srslte_mod_string(grant->mcs2.mod));
fprintf(f, " - Transport block size (TB2):\t\t%d\n", grant->mcs2.tbs);
for (int i = 0; i < grant->nof_tb; i++) {
fprintf(f, " - Transport block:\t\t\t%d\n", i);
fprintf(f, " -> Modulation type:\t\t\t%s\n", srslte_mod_string(grant->mcs[i].mod));
fprintf(f, " -> Transport block size:\t\t%d\n", grant->mcs[i].tbs);
}
}
void srslte_ra_prb_fprint(FILE *f, srslte_ra_dl_grant_t *grant) {

@ -514,39 +514,23 @@ static int decode_tb(srslte_sch_t *q,
}
}
int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
int16_t *e_bits, uint8_t *data)
{
return decode_tb(q,
softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
e_bits, data);
int srslte_dlsch_decode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
int16_t *e_bits, uint8_t *data) {
return srslte_dlsch_decode2(q, cfg, softbuffer, e_bits, data, 0);
}
int srslte_dlsch_decode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
int16_t *e_bits, uint8_t *data, int codeword_idx)
{
int16_t *e_bits, uint8_t *data, int codeword_idx) {
uint32_t Nl = 1;
int ret = SRSLTE_ERROR;
if (cfg->nof_layers != cfg->grant.nof_tb) {
Nl = 2;
}
if (codeword_idx == 0) {
ret = decode_tb(q, softbuffer, &cfg->cb_segm,
cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits,
e_bits, data);
} else if (codeword_idx == 1) {
ret = decode_tb(q, softbuffer, &cfg->cb_segm2,
cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits,
e_bits, data);
} else {
ERROR("Not implemented");
}
return ret;
return decode_tb(q, softbuffer, &cfg->cb_segm[codeword_idx],
cfg->grant.Qm[codeword_idx] * Nl, cfg->rv[codeword_idx], cfg->nbits[codeword_idx].nof_bits,
e_bits, data);
}
/**
@ -562,64 +546,22 @@ int srslte_dlsch_decode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbu
int srslte_dlsch_encode(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
uint8_t *data, uint8_t *e_bits)
{
return encode_tb(q,
softbuffer, &cfg->cb_segm,
cfg->grant.Qm, cfg->rv, cfg->nbits.nof_bits,
data, e_bits);
return srslte_dlsch_encode2(q, cfg, softbuffer, data, e_bits, 0);
}
int srslte_dlsch_encode2(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t *softbuffer,
uint8_t *data, uint8_t *e_bits, int codeword_idx) {
int ret = SRSLTE_ERROR;
uint32_t Nl = 1;
if (cfg->nof_layers != cfg->grant.nof_tb) {
Nl = 2;
}
if(codeword_idx == 0) {
/* Codeword 1 shall be encoded */
ret = encode_tb(q, softbuffer, &cfg->cb_segm, cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits, data, e_bits);
} else if(codeword_idx == 1) {
/* Codeword 2 shall be encoded */
ret = encode_tb(q, softbuffer, &cfg->cb_segm2, cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits, data, e_bits);
} else {
ERROR("Not implemented");
}
return ret;
}
int srslte_dlsch_encode_multi(srslte_sch_t *q, srslte_pdsch_cfg_t *cfg, srslte_softbuffer_tx_t softbuffers[SRSLTE_MAX_CODEWORDS],
uint8_t *data[SRSLTE_MAX_CODEWORDS], uint8_t *e_bits[SRSLTE_MAX_CODEWORDS])
{
int ret = 0;
uint32_t Nl = 1;
if (cfg->nof_layers != cfg->grant.nof_tb) {
Nl = 2;
}
/* Check if codeword 1 shall be encoded */
if(cfg->nbits.nof_bits) {
ret |= encode_tb(q,
&softbuffers[0], &cfg->cb_segm,
cfg->grant.Qm*Nl, cfg->rv, cfg->nbits.nof_bits,
data[0], e_bits[0]);
}
/* Check if codeword 2 shall be encoded */
if(cfg->nbits2.nof_bits) {
ret |= encode_tb(q,
&softbuffers[1], &cfg->cb_segm2,
cfg->grant.Qm2*Nl, cfg->rv2, cfg->nbits2.nof_bits,
data[1], e_bits[1]);
}
return ret;
return encode_tb(q, softbuffer, &cfg->cb_segm[codeword_idx], cfg->grant.Qm[codeword_idx]*Nl, cfg->rv[codeword_idx],
cfg->nbits[codeword_idx].nof_bits, data, e_bits);
}
/* Compute the interleaving function on-the-fly, because it depends on number of RI bits
/* Compute the interleaving function on-the-fly, because it depends on number of RI bits
* Profiling show that the computation of this matrix is neglegible.
*/
static void ulsch_interleave_gen(uint32_t H_prime_total, uint32_t N_pusch_symbs, uint32_t Qm,

@ -27,7 +27,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/time.h>
#include <srslte/phy/phch/ra.h>
@ -55,11 +54,9 @@ srslte_cell_t cell = {
char mimo_type_str [32] = "single";
srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
uint32_t cfi = 2;
uint32_t mcs = 0;
uint32_t mcs2 = 0;
uint32_t mcs[SRSLTE_MAX_CODEWORDS] = {0, 0};
uint32_t subframe = 1;
uint32_t rv_idx = 0;
uint32_t rv_idx2 = 1;
int rv_idx[SRSLTE_MAX_CODEWORDS] = {0, 1};
uint16_t rnti = 1234;
uint32_t nof_rx_antennas = 1;
uint32_t pmi = 0;
@ -68,12 +65,12 @@ char *input_file = NULL;
void usage(char *prog) {
printf("Usage: %s [fmMcsrtRFpnwav] \n", prog);
printf("\t-f read signal from file [Default generate it with pdsch_encode()]\n");
printf("\t-m MCS [Default %d]\n", mcs);
printf("\t-M MCS2 [Default %d]\n", mcs2);
printf("\t-m MCS [Default %d]\n", mcs[0]);
printf("\t-M MCS2 [Default %d]\n", mcs[1]);
printf("\t-c cell id [Default %d]\n", cell.id);
printf("\t-s subframe [Default %d]\n", subframe);
printf("\t-r rv_idx [Default %d]\n", rv_idx);
printf("\t-t rv_idx2 [Default %d]\n", rv_idx2);
printf("\t-r rv_idx [Default %d]\n", rv_idx[0]);
printf("\t-t rv_idx2 [Default %d]\n", rv_idx[1]);
printf("\t-R rnti [Default %d]\n", rnti);
printf("\t-F cfi [Default %d]\n", cfi);
printf("\t-x Transmission mode [single|diversity|cdd|multiplex] [Default %s]\n", mimo_type_str);
@ -91,19 +88,19 @@ void parse_args(int argc, char **argv) {
input_file = argv[optind];
break;
case 'm':
mcs = atoi(argv[optind]);
mcs[0] = (uint32_t) atoi(argv[optind]);
break;
case 'M':
mcs2 = (uint32_t) atoi(argv[optind]);
mcs[1] = (uint32_t) atoi(argv[optind]);
break;
case 's':
subframe = atoi(argv[optind]);
break;
case 'r':
rv_idx = atoi(argv[optind]);
rv_idx[0] = (uint32_t) atoi(argv[optind]);
break;
case 't':
rv_idx2 = (uint32_t) atoi(argv[optind]);
rv_idx[1] = (uint32_t) atoi(argv[optind]);
break;
case 'R':
rnti = atoi(argv[optind]);
@ -197,16 +194,16 @@ int main(int argc, char **argv) {
dci.type0_alloc.rbg_bitmask = 0xffffffff;
/* If transport block 0 is enabled */
if (mcs != 0 || rv_idx != 1) {
dci.mcs_idx = mcs;
dci.rv_idx = rv_idx;
if (mcs[0] != 0 || rv_idx[0] != 1) {
dci.mcs_idx = mcs[0];
dci.rv_idx = rv_idx[0];
dci.tb_en[0] = true;
}
/* If transport block 0 is disabled */
if (mcs2 != 0 || rv_idx2 != 1) {
dci.mcs_idx_1 = mcs2;
dci.rv_idx_1 = rv_idx2;
if (mcs[1] != 0 || rv_idx[1] != 1) {
dci.mcs_idx_1 = mcs[1];
dci.rv_idx_1 = rv_idx[1];
dci.tb_en[1] = true;
}
@ -235,7 +232,7 @@ int main(int argc, char **argv) {
#endif /* DO_OFDM */
/* Configure PDSCH */
if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, subframe, rv_idx, rv_idx2, mimo_type, pmi)) {
if (srslte_pdsch_cfg_multi(&pdsch_cfg, cell, &grant, cfi, subframe, rv_idx, mimo_type, pmi)) {
fprintf(stderr, "Error configuring PDSCH\n");
goto quit;
}
@ -260,22 +257,15 @@ int main(int argc, char **argv) {
}
if (grant.mcs.tbs) {
data[0] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs);
if (!data[0]) {
perror("srslte_vec_malloc");
goto quit;
}
bzero(data[0], sizeof(uint8_t) * grant.mcs.tbs);
}
if (grant.mcs2.tbs) {
data[1] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs2.tbs);
if (!data[1]) {
perror("srslte_vec_malloc");
goto quit;
for (int i = 0; i < grant.nof_tb; i++) {
if (grant.mcs[i].tbs) {
data[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs);
if (!data[i]) {
perror("srslte_vec_malloc");
goto quit;
}
bzero(data[i], sizeof(uint8_t) * grant.mcs[i].tbs);
}
bzero(data[1], sizeof(uint8_t) * grant.mcs2.tbs);
}
if (srslte_pdsch_init_rx_multi(&pdsch_rx, cell, nof_rx_antennas)) {
@ -292,6 +282,7 @@ int main(int argc, char **argv) {
}
}
INFO(" Global:\n");
INFO(" nof_prb=%d\n", cell.nof_prb);
INFO(" nof_ports=%d\n", cell.nof_ports);
INFO(" id=%d\n", cell.id);
@ -300,28 +291,22 @@ int main(int argc, char **argv) {
INFO(" phich_resources=%d\n", (int) cell.phich_resources);
INFO(" nof_tb=%d\n", pdsch_cfg.grant.nof_tb);
INFO(" nof_prb=%d\n", pdsch_cfg.grant.nof_prb);
INFO(" Qm=%d\n", pdsch_cfg.grant.Qm);
INFO(" Qm2=%d\n", pdsch_cfg.grant.Qm2);
INFO(" mcs.idx=0x%X\n", pdsch_cfg.grant.mcs.idx);
INFO(" mcs.tbs=%d\n", pdsch_cfg.grant.mcs.tbs);
INFO(" mcs.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs.mod));
INFO(" mcs2.idx=0x%X\n", pdsch_cfg.grant.mcs2.idx);
INFO(" mcs2.tbs=%d\n", pdsch_cfg.grant.mcs2.tbs);
INFO(" mcs2.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs2.mod));
INFO(" nof_layers=%d\n", pdsch_cfg.nof_layers);
INFO(" rv=%d\n", pdsch_cfg.rv);
INFO(" rv2=%d\n", pdsch_cfg.rv2);
INFO(" sf_idx=%d\n", pdsch_cfg.sf_idx);
INFO(" mimo_type=%d\n", (int) pdsch_cfg.mimo_type);
INFO(" mimo_type=%s\n", srslte_mimotype2str(pdsch_cfg.mimo_type));
INFO(" nof_layers=%d\n", pdsch_cfg.nof_layers);
INFO(" nof_tb=%d\n", pdsch_cfg.grant.nof_tb);
INFO(" lstart=%d\n", pdsch_cfg.nbits.lstart);
INFO(" nof_bits=%d\n", pdsch_cfg.nbits.nof_bits);
INFO(" nof_re=%d\n", pdsch_cfg.nbits.nof_re);
INFO(" nof_symb=%d\n", pdsch_cfg.nbits.nof_symb);
INFO(" lstart=%d\n", pdsch_cfg.nbits2.lstart);
INFO(" nof_bits=%d\n", pdsch_cfg.nbits2.nof_bits);
INFO(" nof_re=%d\n", pdsch_cfg.nbits2.nof_re);
INFO(" nof_symb=%d\n", pdsch_cfg.nbits2.nof_symb);
for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
INFO(" Tranport block index %d:\n", i);
INFO(" Qm=%d\n", pdsch_cfg.grant.Qm[i]);
INFO(" mcs.idx=0x%X\n", pdsch_cfg.grant.mcs[i].idx);
INFO(" mcs.tbs=%d\n", pdsch_cfg.grant.mcs[i].tbs);
INFO(" mcs.mod=%s\n", srslte_mod_string(pdsch_cfg.grant.mcs[i].mod));
INFO(" rv=%d\n", pdsch_cfg.rv[i]);
INFO(" lstart=%d\n", pdsch_cfg.nbits[i].lstart);
INFO(" nof_bits=%d\n", pdsch_cfg.nbits[i].nof_bits);
INFO(" nof_re=%d\n", pdsch_cfg.nbits[i].nof_re);
INFO(" nof_symb=%d\n", pdsch_cfg.nbits[i].nof_symb);
}
if (input_file) {
srslte_filesource_t fsrc;
@ -368,29 +353,25 @@ int main(int argc, char **argv) {
}
}
for (i = 0; i < grant.mcs.tbs / 8; i++) {
data[0][i] = (uint8_t) (rand() % 256);
}
for (i = 0; i < grant.mcs2.tbs / 8; i++) {
data[1][i] = (uint8_t) (rand() % 256);
for (i = 0; i< grant.nof_tb; i++) {
for (i = 0; i < grant.mcs[i].tbs / 8; i++) {
data[i][i] = (uint8_t) (rand() % 256);
}
}
/*uint8_t databit[100000];
srslte_bit_unpack_vector(data, databit, grant.mcs.tbs);
srslte_vec_save_file("data_in", databit, grant.mcs.tbs);*/
if (rv_idx) {
if (rv_idx[0] != 0 || rv_idx[1] != 0) {
/* Do 1st transmission for rv_idx!=0 */
pdsch_cfg.rv = 0;
pdsch_cfg.rv2 = 0;
bzero(pdsch_cfg.rv, sizeof(uint32_t)*SRSLTE_MAX_CODEWORDS);
if (srslte_pdsch_encode_multi(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data, rnti, tx_slot_symbols)) {
fprintf(stderr, "Error encoding PDSCH\n");
goto quit;
}
}
pdsch_cfg.rv = rv_idx;
pdsch_cfg.rv2 = rv_idx2;
memcpy(pdsch_cfg.rv, rv_idx, sizeof(uint32_t)*SRSLTE_MAX_CODEWORDS);
gettimeofday(&t[1], NULL);
for (k = 0; k < M; k++) {
if (srslte_pdsch_encode_multi(&pdsch_tx, &pdsch_cfg, softbuffers_tx, data, rnti, tx_slot_symbols)) {
@ -401,8 +382,8 @@ int main(int argc, char **argv) {
gettimeofday(&t[2], NULL);
get_time_interval(t);
printf("ENCODED in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n",
(float) t[0].tv_usec/M, (float) (grant.mcs.tbs + grant.mcs2.tbs)/1000.0f,
(float) (grant.mcs.tbs + grant.mcs2.tbs)*M/t[0].tv_usec);
(float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f,
(float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec);
#ifdef DO_OFDM
for (i = 0; i < cell.nof_ports; i++) {
@ -444,19 +425,18 @@ int main(int argc, char **argv) {
srslte_ofdm_rx_sf(&ofdm_rx, tx_sf_symbols[i], rx_slot_symbols[i]);
}
#endif
if (grant.mcs.tbs) {
srslte_softbuffer_rx_reset_tbs(&softbuffers_rx[0], (uint32_t) grant.mcs.tbs);
}
if (grant.mcs2.tbs) {
srslte_softbuffer_rx_reset_tbs(&softbuffers_rx[1], (uint32_t) grant.mcs2.tbs);
for (i = 0; i < grant.nof_tb; i++) {
if (grant.mcs[i].tbs) {
srslte_softbuffer_rx_reset_tbs(&softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs);
}
}
r = srslte_pdsch_decode_multi(&pdsch_rx, &pdsch_cfg, softbuffers_rx, rx_slot_symbols, ce, 0, rnti, data);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
printf("DECODED %s in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", r?"Error":"OK",
(float) t[0].tv_usec/M, (float) (grant.mcs.tbs + grant.mcs2.tbs)/1000.0f,
(float) (grant.mcs.tbs + grant.mcs2.tbs)*M/t[0].tv_usec);
(float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f,
(float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec);
if (r) {
ret = -1;
goto quit;

@ -282,14 +282,16 @@ int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *c
}
int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx, uint32_t rvidx)
{
return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, 0, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0);
int srslte_ue_dl_cfg_grant(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx,
int rvidx) {
int _rvidx [SRSLTE_MAX_CODEWORDS] = {1};
_rvidx[0] = rvidx;
return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, _rvidx, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA, 0);
}
int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant, uint32_t cfi, uint32_t sf_idx,
uint32_t rvidx, uint32_t rvidx2, srslte_mimo_type_t mimo_type, uint32_t pinfo)
{
int rvidx[SRSLTE_MAX_CODEWORDS], srslte_mimo_type_t mimo_type, uint32_t pinfo) {
uint32_t pmi = 0;
/* Translates Precoding Information (pinfo) to Precoding matrix Index (pmi) as 3GPP 36.212 Table 5.3.3.1.5-4 */
@ -310,7 +312,7 @@ int srslte_ue_dl_cfg_grant_multi(srslte_ue_dl_t *q, srslte_ra_dl_grant_t *grant,
}
}
}
return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, rvidx2, mimo_type, pmi);
return srslte_pdsch_cfg_multi(&q->pdsch_cfg, q->cell, grant, cfi, sf_idx, rvidx, mimo_type, pmi);
}
int srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t tti, uint16_t rnti)
@ -357,23 +359,28 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR
/* ===== These lines of code are supposed to be MAC functionality === */
uint32_t rvidx = 0;
uint32_t rvidx2 = 0;
int rvidx[SRSLTE_MAX_CODEWORDS] = {1};
if (dci_unpacked.rv_idx < 0) {
uint32_t sfn = tti/10;
uint32_t k = (sfn/2)%4;
rvidx = ((uint32_t) ceilf((float)1.5*k))%4;
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[0], (uint32_t) grant.mcs.tbs);
if (grant.nof_tb > 1) {
rvidx2 = ((uint32_t) ceilf((float)1.5*k))%4;
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[1], (uint32_t) grant.mcs2.tbs);
uint32_t k = (sfn/2)%4;
for (int i = 0; i < grant.nof_tb; i++) {
rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4;
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[i], (uint32_t) grant.mcs[i].tbs);
}
} else {
rvidx = (uint32_t) dci_unpacked.rv_idx;
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[0], (uint32_t) grant.mcs.tbs);
if (grant.nof_tb > 1) {
rvidx2 = (uint32_t) dci_unpacked.rv_idx_1;
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[1], (uint32_t) grant.mcs2.tbs);
for (int i = 0; i < grant.nof_tb; i++) {
switch(i) {
case 0:
rvidx[i] = (uint32_t) dci_unpacked.rv_idx;
break;
case 1:
rvidx[i] = (uint32_t) dci_unpacked.rv_idx_1;
break;
default:
ERROR("Wrong number of transport blocks");
return SRSLTE_ERROR;
}
srslte_softbuffer_rx_reset_tbs(&q->softbuffers[i], (uint32_t) grant.mcs[i].tbs);
}
}
@ -408,7 +415,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR
return SRSLTE_ERROR;
}
if (srslte_ue_dl_cfg_grant_multi(q, &grant, cfi, sf_idx, rvidx, rvidx2, mimo_type, dci_unpacked.pinfo)) {
if (srslte_ue_dl_cfg_grant_multi(q, &grant, cfi, sf_idx, rvidx, mimo_type, dci_unpacked.pinfo)) {
ERROR("Configuing PDSCH");
return SRSLTE_ERROR;
}
@ -418,7 +425,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR
q->nof_detected++;
if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) {
if (q->pdsch_cfg.grant.mcs[0].mod > 0 && q->pdsch_cfg.grant.mcs[0].tbs >= 0) {
ret = srslte_pdsch_decode_multi(&q->pdsch, &q->pdsch_cfg, q->softbuffers,
q->sf_symbols_m, q->ce_m,
noise_estimate,
@ -446,7 +453,7 @@ int srslte_ue_dl_decode_rnti_multi(srslte_ue_dl_t *q, cf_t *input[SRSLTE_MAX_POR
q->pkts_total++;
if (found_dci == 1 && ret == SRSLTE_SUCCESS) {
return q->pdsch_cfg.grant.mcs.tbs;
return q->pdsch_cfg.grant.mcs[0].tbs;
} else {
return 0;
}
@ -723,16 +730,16 @@ void srslte_ue_dl_save_signal(srslte_ue_dl_t *q, srslte_softbuffer_rx_t *softbuf
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++) {
srslte_vec_save_file("pdsch_symbols", q->pdsch.d, q->pdsch_cfg.nbits[0].nof_re*sizeof(cf_t));
srslte_vec_save_file("llr", q->pdsch.e, q->pdsch_cfg.nbits[0].nof_bits*sizeof(cf_t));
int cb_len = q->pdsch_cfg.cb_segm[0].K1;
for (int i=0;i<q->pdsch_cfg.cb_segm[0].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=0x%x\n", tti, tti%10, cfi,
q->pdsch_cfg.grant.mcs.idx, rv_idx, rnti);
q->pdsch_cfg.grant.mcs[0].idx, rv_idx, rnti);
}

@ -632,7 +632,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
if (LOG_THIS(rnti)) {
uint8_t x = 0;
uint8_t *ptr = grants[i].data;
uint32_t len = phy_grant.mcs.tbs/8;
uint32_t len = phy_grant.mcs[0].tbs / (uint32_t) 8;
if (!ptr) {
ptr = &x;
len = 1;
@ -640,7 +640,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
log_h->info_hex(ptr, len,
"PDSCH: rnti=0x%x, l_crb=%2d, %s, harq=%d, tbs=%d, mcs=%d, rv=%d, tti_tx=%d\n",
rnti, phy_grant.nof_prb, grant_str, grants[i].grant.harq_process,
phy_grant.mcs.tbs/8, phy_grant.mcs.idx, grants[i].grant.rv_idx, tti_tx);
phy_grant.mcs[0].tbs/8, phy_grant.mcs[0].idx, grants[i].grant.rv_idx, tti_tx);
}
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffer, rnti, grants[i].grant.rv_idx, sf_idx,
grants[i].data))
@ -650,7 +650,7 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
}
// Save metrics stats
ue_db[rnti].metrics_dl(phy_grant.mcs.idx);
ue_db[rnti].metrics_dl(phy_grant.mcs[0].idx);
}
}
return SRSLTE_SUCCESS;

@ -76,9 +76,20 @@ private:
/* ... for DL */
bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant);
bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant);
bool decode_phich(bool *ack);
bool decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t* softbuffer, int rv, uint16_t rnti, uint32_t pid);
bool decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS], int rv, uint16_t rnti, uint32_t pid);
bool decode_phich(bool *ack);
bool decode_pdsch(srslte_ra_dl_grant_t *grant,
uint8_t *payload, srslte_softbuffer_rx_t *softbuffer,
int rv,
uint16_t rnti,
uint32_t pid);
bool decode_pdsch_multi(srslte_ra_dl_grant_t *grant,
uint8_t *payload[SRSLTE_MAX_CODEWORDS],
srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS],
int rv[SRSLTE_MAX_CODEWORDS],
uint16_t rnti,
uint32_t pid);
/* ... for UL */
void encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer,

@ -204,9 +204,9 @@ void phch_worker::work_imp()
/* Decode PDSCH if instructed to do so */
dl_ack = dl_action.default_ack;
if (dl_action.decode_enabled) {
dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr,
dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr,
dl_action.softbuffer, dl_action.rv, dl_action.rnti,
dl_mac_grant.pid);
dl_mac_grant.pid);
}
if (dl_action.generate_ack_callback && dl_action.decode_enabled) {
phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid);
@ -382,7 +382,7 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
/* Fill MAC grant structure */
grant->ndi = dci_unpacked.ndi;
grant->pid = dci_unpacked.harq_process;
grant->n_bytes = grant->phy_grant.dl.mcs.tbs/8;
grant->n_bytes = grant->phy_grant.dl.mcs[0].tbs/8;
grant->tti = tti;
grant->rv = dci_unpacked.rv_idx;
grant->rnti = dl_rnti;
@ -406,23 +406,70 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
}
bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload,
srslte_softbuffer_rx_t* softbuffer, int rv, uint16_t rnti, uint32_t harq_pid)
{
return decode_pdsch_multi(grant, &payload, softbuffer, rv, rnti, harq_pid);
srslte_softbuffer_rx_t *softbuffer, int rv,
uint16_t rnti, uint32_t harq_pid) {
int _rv [SRSLTE_MAX_CODEWORDS] = {1};
_rv[0] = rv;
return decode_pdsch_multi(grant, &payload, softbuffer, _rv, rnti, harq_pid);
}
bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS],
srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS], int rv, uint16_t rnti, uint32_t harq_pid)
{
srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS],
int rv[SRSLTE_MAX_CODEWORDS],
uint16_t rnti, uint32_t harq_pid) {
char timestr[64];
bool valid_config = true;
timestr[0]='\0';
srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
for (uint32_t tb = 0; tb < grant->nof_tb; tb++) {
if (rv[tb] < 0 || rv[tb] > 3) {
valid_config = false;
Error("Wrong RV (%d) for TB index %d", rv[tb], tb);
}
}
switch(phy->config->dedicated.antenna_info_explicit_value.tx_mode) {
case LIBLTE_RRC_TRANSMISSION_MODE_1:
mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
break;
case LIBLTE_RRC_TRANSMISSION_MODE_2:
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
break;
case LIBLTE_RRC_TRANSMISSION_MODE_3:
if (grant->nof_tb == 1) {
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else if (grant->nof_tb == 2) {
mimo_type = SRSLTE_MIMO_TYPE_CDD;
} else {
Error("Wrong number of transport blocks (%d) for TM3\n", grant->nof_tb);
valid_config = false;
}
break;
/* Not implemented cases */
case LIBLTE_RRC_TRANSMISSION_MODE_4:
case LIBLTE_RRC_TRANSMISSION_MODE_5:
case LIBLTE_RRC_TRANSMISSION_MODE_6:
case LIBLTE_RRC_TRANSMISSION_MODE_7:
case LIBLTE_RRC_TRANSMISSION_MODE_8:
Error("Not implemented Tx mode (%d)\n", phy->config->dedicated.antenna_info_explicit_value.tx_mode);
break;
/* Error cases */
case LIBLTE_RRC_TRANSMISSION_MODE_N_ITEMS:
default:
Error("Wrong Tx mode (%d)\n", phy->config->dedicated.antenna_info_explicit_value.tx_mode);
valid_config = false;
}
Debug("DL Buffer TTI %d: Decoding PDSCH\n", tti);
/* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */
if (rv >= 0 && rv <= 3) {
if (!srslte_ue_dl_cfg_grant(&ue_dl, grant, cfi, tti%10, rv)) {
if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) {
if (valid_config) {
if (!srslte_ue_dl_cfg_grant_multi(&ue_dl, grant, cfi, tti%10, rv, mimo_type, 0)) {
if (ue_dl.pdsch_cfg.grant.mcs[0].mod > 0 && ue_dl.pdsch_cfg.grant.mcs[0].tbs >= 0) {
float noise_estimate = srslte_chest_dl_get_noise_estimate(&ue_dl.chest);
@ -451,7 +498,7 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo
Info("PDSCH: l_crb=%2d, harq=%d, tbs=%d, mcs=%d, rv=%d, crc=%s, snr=%.1f dB, n_iter=%d%s\n",
grant->nof_prb, harq_pid,
grant->mcs.tbs/8, grant->mcs.idx, rv,
grant->mcs[0].tbs/8, grant->mcs[0].idx, rv,
ack?"OK":"KO",
10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)),
srslte_pdsch_last_noi(&ue_dl.pdsch),
@ -461,7 +508,7 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo
//srslte_vec_save_file("pdsch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
// Store metrics
dl_metrics.mcs = grant->mcs.idx;
dl_metrics.mcs = grant->mcs[0].idx;
return ack;
} else {
@ -470,8 +517,6 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo
} else {
Error("Error configuring DL grant\n");
}
} else {
Error("Error RV is not set or is invalid (%d)\n", rv);
}
return true;
}
@ -973,8 +1018,9 @@ int phch_worker::read_ce_abs(float *ce_abs) {
int phch_worker::read_pdsch_d(cf_t* pdsch_d)
{
memcpy(pdsch_d, ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits.nof_re*sizeof(cf_t));
return ue_dl.pdsch_cfg.nbits.nof_re;
memcpy(pdsch_d, ue_dl.pdsch.d, ue_dl.pdsch_cfg.nbits[0].nof_re*sizeof(cf_t));
return ue_dl.pdsch_cfg.nbits[0].nof_re;
}

Loading…
Cancel
Save