From 48278aca842ebac0712187193e7c2879bb243884 Mon Sep 17 00:00:00 2001 From: ismagom Date: Fri, 13 Feb 2015 11:13:56 +0100 Subject: [PATCH] Changed harq object to include RV and subframe. Adapted PDSCH, PUSCH and SCH interfaces --- lte/examples/pdsch_enodeb.c | 18 +-- lte/phy/include/liblte/phy/phch/harq.h | 22 ++- lte/phy/include/liblte/phy/phch/pdsch.h | 22 +-- lte/phy/include/liblte/phy/phch/pusch.h | 28 ++-- lte/phy/include/liblte/phy/phch/sch.h | 27 ++-- lte/phy/lib/phch/src/harq.c | 65 +++++++-- lte/phy/lib/phch/src/pdsch.c | 100 ++++++-------- lte/phy/lib/phch/src/pusch.c | 101 ++++++-------- lte/phy/lib/phch/src/sch.c | 130 ++++++++---------- lte/phy/lib/phch/src/uci.c | 50 +++---- lte/phy/lib/phch/test/dlsch_encode_test_mex.c | 12 +- lte/phy/lib/phch/test/pdsch_file_test.c | 5 +- lte/phy/lib/phch/test/pdsch_test.c | 14 +- lte/phy/lib/phch/test/pdsch_test_mex.c | 4 +- lte/phy/lib/phch/test/pusch_test.c | 20 +-- lte/phy/lib/phch/test/ulsch_encode_test_mex.c | 20 +-- lte/phy/lib/ue/src/ue_dl.c | 9 +- 17 files changed, 315 insertions(+), 332 deletions(-) diff --git a/lte/examples/pdsch_enodeb.c b/lte/examples/pdsch_enodeb.c index d686170c5..2b11b7d52 100644 --- a/lte/examples/pdsch_enodeb.c +++ b/lte/examples/pdsch_enodeb.c @@ -312,7 +312,7 @@ uint32_t prbset_to_bitmask() { return reverse(mask)>>(32-nb); } -int update_radl() { +int update_radl(uint32_t sf_idx) { ra_prb_t prb_alloc; bzero(&ra_dl, sizeof(ra_pdsch_t)); @@ -331,7 +331,7 @@ int update_radl() { printf("Type new MCS index and press Enter: "); fflush(stdout); harq_reset(&harq_process); - if (harq_setup(&harq_process, ra_dl.mcs, &prb_alloc)) { + if (harq_setup_dl(&harq_process, ra_dl.mcs, ra_dl.rv_idx, sf_idx, &prb_alloc)) { fprintf(stderr, "Error configuring HARQ process\n"); return -1; } @@ -340,7 +340,7 @@ int update_radl() { } /* Read new MCS from stdin */ -int update_control() { +int update_control(uint32_t sf_idx) { char input[128]; fd_set set; @@ -380,11 +380,11 @@ int update_control() { mcs_idx = atoi(input); } bzero(input,sizeof(input)); - if (update_radl()) { + if (update_radl(sf_idx)) { printf("Trying with last known MCS index\n"); mcs_idx = last_mcs_idx; prbset_num = last_prbset_num; - return update_radl(); + return update_radl(sf_idx); } } return 0; @@ -437,7 +437,7 @@ void *net_thread_fnc(void *arg) { } int main(int argc, char **argv) { - int nf, sf_idx, N_id_2; + int nf=0, sf_idx=0, N_id_2=0; cf_t pss_signal[PSS_LEN]; float sss_signal0[SSS_LEN]; // for subframe 0 float sss_signal5[SSS_LEN]; // for subframe 5 @@ -498,7 +498,7 @@ int main(int argc, char **argv) { } #endif - if (update_radl()) { + if (update_radl(sf_idx)) { exit(-1); } @@ -540,7 +540,7 @@ int main(int argc, char **argv) { pcfich_encode(&pcfich, cfi, sf_symbols, sf_idx); /* Update DL resource allocation from control port */ - if (update_control(&ra_dl)) { + if (update_control(sf_idx)) { fprintf(stderr, "Error updating parameters from control port\n"); } @@ -570,7 +570,7 @@ int main(int argc, char **argv) { exit(-1); } - if (pdsch_encode(&pdsch, data, sf_symbols, sf_idx, &harq_process, ra_dl.rv_idx)) { + if (pdsch_encode(&pdsch, &harq_process, data, sf_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); exit(-1); } diff --git a/lte/phy/include/liblte/phy/phch/harq.h b/lte/phy/include/liblte/phy/phch/harq.h index c0886d6ce..c1ec7a022 100644 --- a/lte/phy/include/liblte/phy/phch/harq.h +++ b/lte/phy/include/liblte/phy/phch/harq.h @@ -45,11 +45,15 @@ typedef struct LIBLTE_API { ra_mcs_t mcs; + uint32_t rv; + uint32_t sf_idx; ra_prb_t prb_alloc; lte_cell_t cell; - uint32_t N_symb_ul; // Number of symbols for PUSCH transmission - uint32_t nof_prb_pusch_init; // Initial resource allocation for PUSCH. + uint32_t nof_re; // Number of RE per subframe + uint32_t nof_bits; // Number of bits per subframe + uint32_t nof_symb; // Number of symbols per subframe + uint32_t nof_prb; // Number of allocated PRB per subframe. uint32_t max_cb; uint32_t w_buff_size; @@ -63,9 +67,17 @@ typedef struct LIBLTE_API { LIBLTE_API int harq_init(harq_t * q, lte_cell_t cell); -LIBLTE_API int harq_setup(harq_t *p, - ra_mcs_t mcs, - ra_prb_t *prb_alloc); +LIBLTE_API int harq_setup_dl(harq_t *p, + ra_mcs_t mcs, + uint32_t rv, + uint32_t sf_idx, + ra_prb_t *prb_alloc); + +LIBLTE_API int harq_setup_ul(harq_t *p, + ra_mcs_t mcs, + uint32_t rv, + uint32_t sf_idx, + ra_prb_t *prb_alloc); LIBLTE_API void harq_reset(harq_t *p); diff --git a/lte/phy/include/liblte/phy/phch/pdsch.h b/lte/phy/include/liblte/phy/phch/pdsch.h index 76ffa0591..fc58e9672 100644 --- a/lte/phy/include/liblte/phy/phch/pdsch.h +++ b/lte/phy/include/liblte/phy/phch/pdsch.h @@ -49,7 +49,7 @@ typedef _Complex float cf_t; typedef struct LIBLTE_API { lte_cell_t cell; - uint32_t max_symbols; + uint32_t max_re; bool rnti_is_set; uint16_t rnti; @@ -79,30 +79,20 @@ LIBLTE_API void pdsch_free(pdsch_t *q); LIBLTE_API int pdsch_set_rnti(pdsch_t *q, uint16_t rnti); -LIBLTE_API int pdsch_encode(pdsch_t *q, +LIBLTE_API int pdsch_encode(pdsch_t *q, + harq_t *harq_process, uint8_t *data, - cf_t *sf_symbols[MAX_PORTS], - uint32_t nsubframe, - harq_t *harq_process, - uint32_t rv_idx); + cf_t *sf_symbols[MAX_PORTS]); LIBLTE_API int pdsch_decode(pdsch_t *q, + harq_t *harq_process, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, - uint8_t *data, - uint32_t nsubframe, - harq_t *harq_process, - uint32_t rv_idx); + uint8_t *data); LIBLTE_API float pdsch_average_noi(pdsch_t *q); LIBLTE_API uint32_t pdsch_last_noi(pdsch_t *q); -LIBLTE_API int pdsch_get(pdsch_t *q, - cf_t *sf_symbols, - cf_t *pdsch_symbols, - ra_prb_t *prb_alloc, - uint32_t subframe); - #endif diff --git a/lte/phy/include/liblte/phy/phch/pusch.h b/lte/phy/include/liblte/phy/phch/pusch.h index 424266ebb..d77eaa63b 100644 --- a/lte/phy/include/liblte/phy/phch/pusch.h +++ b/lte/phy/include/liblte/phy/phch/pusch.h @@ -49,7 +49,7 @@ typedef _Complex float cf_t; typedef struct LIBLTE_API { lte_cell_t cell; - uint32_t max_symbols; + uint32_t max_re; bool rnti_is_set; uint16_t rnti; @@ -84,40 +84,28 @@ LIBLTE_API int pusch_init(pusch_t *q, LIBLTE_API void pusch_free(pusch_t *q); LIBLTE_API int pusch_set_rnti(pusch_t *q, - uint16_t rnti); + uint16_t rnti); LIBLTE_API int pusch_encode(pusch_t *q, + harq_t *harq_process, uint8_t *data, - cf_t *sf_symbols, - uint32_t nsubframe, - harq_t *harq_process, - uint32_t rv_idx); + cf_t *sf_symbols); LIBLTE_API int pusch_uci_encode(pusch_t *q, + harq_t *harq_process, uint8_t *data, uci_data_t uci_data, - cf_t *sf_symbols, - uint32_t subframe, - harq_t *harq_process, - uint32_t rv_idx); + cf_t *sf_symbols); LIBLTE_API int pusch_decode(pusch_t *q, + harq_t *harq_process, cf_t *sf_symbols, cf_t *ce, float noise_estimate, - uint8_t *data, - uint32_t nsubframe, - harq_t *harq_process, - uint32_t rv_idx); + uint8_t *data); LIBLTE_API float pusch_average_noi(pusch_t *q); LIBLTE_API uint32_t pusch_last_noi(pusch_t *q); -LIBLTE_API int pusch_get(pusch_t *q, - cf_t *sf_symbols, - cf_t *pusch_symbols, - ra_prb_t *prb_alloc, - uint32_t subframe); - #endif diff --git a/lte/phy/include/liblte/phy/phch/sch.h b/lte/phy/include/liblte/phy/phch/sch.h index 9345a0615..f39c0ab54 100644 --- a/lte/phy/include/liblte/phy/phch/sch.h +++ b/lte/phy/include/liblte/phy/phch/sch.h @@ -79,42 +79,31 @@ LIBLTE_API float sch_average_noi(sch_t *q); LIBLTE_API uint32_t sch_last_noi(sch_t *q); LIBLTE_API int dlsch_encode(sch_t *q, + harq_t *harq_process, uint8_t *data, - uint8_t *e_bits, - uint32_t tbs, - uint32_t nb_e, - harq_t *harq_process, - uint32_t rv_idx); + uint8_t *e_bits); LIBLTE_API int dlsch_decode(sch_t *q, + harq_t *harq_process, float *e_bits, - uint8_t *data, - uint32_t tbs, - uint32_t nb_e, - harq_t *harq_process, - uint32_t rv_idx); + uint8_t *data); LIBLTE_API int ulsch_encode(sch_t *q, + harq_t *harq_process, uint8_t *data, uint8_t *g_bits, - harq_t *harq_process, - uint32_t rv_idx, uint8_t *q_bits); LIBLTE_API int ulsch_uci_encode(sch_t *q, + harq_t *harq_process, uint8_t *data, uci_data_t uci_data, uint8_t *g_bits, - harq_t *harq_process, - uint32_t rv_idx, uint8_t *q_bits); LIBLTE_API int ulsch_decode(sch_t *q, + harq_t *harq_process, float *e_bits, - uint8_t *data, - uint32_t tbs, - uint32_t nb_e, - harq_t *harq_process, - uint32_t rv_idx); + uint8_t *data); #endif diff --git a/lte/phy/lib/phch/src/harq.c b/lte/phy/lib/phch/src/harq.c index 9fee0b20b..1fafcdd67 100644 --- a/lte/phy/lib/phch/src/harq.c +++ b/lte/phy/lib/phch/src/harq.c @@ -183,23 +183,64 @@ void harq_reset(harq_t *q) { bzero(&q->prb_alloc, sizeof(ra_prb_t)); } -int harq_setup(harq_t *q, ra_mcs_t mcs, ra_prb_t *prb_alloc) { - int ret = LIBLTE_ERROR_INVALID_INPUTS; - - if (q != NULL) - { - q->mcs = mcs; - memcpy(&q->prb_alloc, prb_alloc, sizeof(ra_prb_t)); - - q->N_symb_ul = 2*(CP_NSYMB(q->cell.cp)-1); - q->nof_prb_pusch_init = q->prb_alloc.slot[0].nof_prb; - - codeblock_segmentation(&q->cb_segm, mcs.tbs); +static int harq_setup_common(harq_t *q, ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx, ra_prb_t *prb_alloc) { + if (mcs.tbs != q->mcs.tbs) { + codeblock_segmentation(&q->cb_segm, mcs.tbs); if (q->cb_segm.C > q->max_cb) { fprintf(stderr, "Codeblock segmentation returned more CBs (%d) than allocated (%d)\n", q->cb_segm.C, q->max_cb); return LIBLTE_ERROR; } + } + + memcpy(&q->prb_alloc, prb_alloc, sizeof(ra_prb_t)); + q->mcs = mcs; + q->sf_idx = sf_idx; + q->rv = rv; + return LIBLTE_SUCCESS; +} + +int harq_setup_dl(harq_t *q, ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx, ra_prb_t *prb_alloc) { + int ret = LIBLTE_ERROR_INVALID_INPUTS; + + if (q != NULL && + rv < 4 && + sf_idx < 10) + { + ret = harq_setup_common(q, mcs, rv, sf_idx, prb_alloc); + if (ret) { + return ret; + } + + // Number of symbols, RE and bits per subframe for DL + q->nof_re = q->prb_alloc.re_sf[q->sf_idx]; + q->nof_symb = 2*CP_NSYMB(q->cell.cp)-q->prb_alloc.lstart; + q->nof_bits = q->nof_re * lte_mod_bits_x_symbol(q->mcs.mod); + q->nof_prb = q->prb_alloc.slot[0].nof_prb; + + ret = LIBLTE_SUCCESS; + } + return ret; +} + +int harq_setup_ul(harq_t *q, ra_mcs_t mcs, uint32_t rv, uint32_t sf_idx, ra_prb_t *prb_alloc) { + int ret = LIBLTE_ERROR_INVALID_INPUTS; + + if (q != NULL && + rv < 4 && + sf_idx < 10) + { + ret = harq_setup_common(q, mcs, rv, sf_idx, prb_alloc); + if (ret) { + return ret; + } + + // Number of symbols, RE and bits per subframe for UL + q->nof_symb = 2*(CP_NSYMB(q->cell.cp)-1); + q->nof_re = q->nof_symb*q->prb_alloc.slot[0].nof_prb*RE_X_RB; + q->nof_bits = q->nof_re * lte_mod_bits_x_symbol(q->mcs.mod); + q->nof_prb = q->prb_alloc.slot[0].nof_prb; + ret = LIBLTE_SUCCESS; } return ret; diff --git a/lte/phy/lib/phch/src/pdsch.c b/lte/phy/lib/phch/src/pdsch.c index 8f7184819..6f7fac6da 100644 --- a/lte/phy/lib/phch/src/pdsch.c +++ b/lte/phy/lib/phch/src/pdsch.c @@ -208,10 +208,10 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) { ret = LIBLTE_ERROR; q->cell = cell; - q->max_symbols = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); + q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, - q->cell.nof_prb, q->max_symbols); + q->cell.nof_prb, q->max_re); if (precoding_init(&q->precoding, SF_LEN_RE(cell.nof_prb, cell.cp))) { fprintf(stderr, "Error initializing precoding\n"); @@ -224,7 +224,7 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) { } } - demod_soft_init(&q->demod, q->max_symbols); + demod_soft_init(&q->demod, q->max_re); demod_soft_alg_set(&q->demod, APPROX); sch_init(&q->dl_sch); @@ -232,26 +232,26 @@ int pdsch_init(pdsch_t *q, lte_cell_t cell) { q->rnti_is_set = false; // Allocate floats for reception (LLRs) - q->pdsch_e = vec_malloc(sizeof(float) * q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64)); + q->pdsch_e = vec_malloc(sizeof(float) * q->max_re * lte_mod_bits_x_symbol(LTE_QAM64)); if (!q->pdsch_e) { goto clean; } - q->pdsch_d = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->pdsch_d = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->pdsch_d) { goto clean; } for (i = 0; i < q->cell.nof_ports; i++) { - q->ce[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->ce[i] = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i]) { goto clean; } - q->pdsch_x[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->pdsch_x[i] = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->pdsch_x[i]) { goto clean; } - q->pdsch_symbols[i] = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->pdsch_symbols[i] = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->pdsch_symbols[i]) { goto clean; } @@ -306,7 +306,7 @@ int pdsch_set_rnti(pdsch_t *q, uint16_t rnti) { uint32_t i; for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { if (sequence_pdsch(&q->seq_pdsch[i], rnti, 0, 2 * i, q->cell.id, - q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64))) { + q->max_re * lte_mod_bits_x_symbol(LTE_QAM64))) { return LIBLTE_ERROR; } } @@ -318,30 +318,23 @@ int pdsch_set_rnti(pdsch_t *q, uint16_t rnti) { /** Decodes the PDSCH from the received symbols */ -int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data, uint32_t subframe, - harq_t *harq_process, uint32_t rv_idx) +int pdsch_decode(pdsch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_estimate, uint8_t *data) { /* Set pointers for layermapping & precoding */ uint32_t i, n; cf_t *x[MAX_LAYERS]; - uint32_t nof_symbols, nof_bits, nof_bits_e; if (q != NULL && sf_symbols != NULL && - data != NULL && - subframe < 10 && - harq_process != NULL) + data != NULL && + harq != NULL) { if (q->rnti_is_set) { - nof_bits = harq_process->mcs.tbs; - nof_symbols = harq_process->prb_alloc.re_sf[subframe]; - nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); - - INFO("Decoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx); + INFO("Decoding PDSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { @@ -350,17 +343,17 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); /* extract symbols */ - n = pdsch_get(q, sf_symbols, q->pdsch_symbols[0], &harq_process->prb_alloc, subframe); - if (n != nof_symbols) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); + n = pdsch_get(q, sf_symbols, q->pdsch_symbols[0], &harq->prb_alloc, harq->sf_idx); + if (n != harq->nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); return LIBLTE_ERROR; } /* extract channel estimates */ for (i = 0; i < q->cell.nof_ports; i++) { - n = pdsch_get(q, ce[i], q->ce[i], &harq_process->prb_alloc, subframe); - if (n != nof_symbols) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); + n = pdsch_get(q, ce[i], q->ce[i], &harq->prb_alloc, harq->sf_idx); + if (n != harq->nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); return LIBLTE_ERROR; } } @@ -369,12 +362,12 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ if (q->cell.nof_ports == 1) { /* no need for layer demapping */ predecoding_single(&q->precoding, q->pdsch_symbols[0], q->ce[0], q->pdsch_d, - nof_symbols, noise_estimate); + harq->nof_re, noise_estimate); } else { predecoding_diversity(&q->precoding, q->pdsch_symbols[0], q->ce, x, q->cell.nof_ports, - nof_symbols, noise_estimate); + harq->nof_re, noise_estimate); layerdemap_diversity(x, q->pdsch_d, q->cell.nof_ports, - nof_symbols / q->cell.nof_ports); + harq->nof_re / q->cell.nof_ports); } /* demodulate symbols @@ -382,13 +375,13 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ * thus we don't need tot set it in the LLRs normalization */ demod_soft_sigma_set(&q->demod, sqrt(0.5)); - demod_soft_table_set(&q->demod, &q->mod[harq_process->mcs.mod]); - demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, nof_symbols); + demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]); + demod_soft_demodulate(&q->demod, q->pdsch_d, q->pdsch_e, harq->nof_re); /* descramble */ - scrambling_f_offset(&q->seq_pdsch[subframe], q->pdsch_e, 0, nof_bits_e); + scrambling_f_offset(&q->seq_pdsch[harq->sf_idx], q->pdsch_e, 0, harq->nof_bits); - return dlsch_decode(&q->dl_sch, q->pdsch_e, data, nof_bits, nof_bits_e, harq_process, rv_idx); + return dlsch_decode(&q->dl_sch, harq, q->pdsch_e, data); } else { fprintf(stderr, "Must call pdsch_set_rnti() before calling pdsch_decode()\n"); return LIBLTE_ERROR; @@ -402,19 +395,16 @@ int pdsch_decode(pdsch_t *q, cf_t *sf_symbols, cf_t *ce[MAX_PORTS], float noise_ /** Converts the PDSCH data bits to symbols mapped to the slot ready for transmission */ -int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_t subframe, - harq_t *harq_process, uint32_t rv_idx) +int pdsch_encode(pdsch_t *q, harq_t *harq, uint8_t *data, cf_t *sf_symbols[MAX_PORTS]) { int i; - uint32_t nof_symbols, nof_bits, nof_bits_e; /* Set pointers for layermapping & precoding */ cf_t *x[MAX_LAYERS]; - int ret = LIBLTE_ERROR_INVALID_INPUTS; + int ret = LIBLTE_ERROR_INVALID_INPUTS; if (q != NULL && data != NULL && - subframe < 10 && - harq_process != NULL) + harq != NULL) { if (q->rnti_is_set) { @@ -424,28 +414,24 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_ } } - nof_bits = harq_process->mcs.tbs; - nof_symbols = harq_process->prb_alloc.re_sf[subframe]; - nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); - - if (harq_process->mcs.tbs == 0) { + if (harq->mcs.tbs == 0) { return LIBLTE_ERROR_INVALID_INPUTS; } - if (nof_bits > nof_bits_e) { - fprintf(stderr, "Invalid code rate %.2f\n", (float) nof_bits / nof_bits_e); + if (harq->mcs.tbs > harq->nof_bits) { + fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); return LIBLTE_ERROR_INVALID_INPUTS; } - if (nof_symbols > q->max_symbols) { + if (harq->nof_re > q->max_re) { fprintf(stderr, "Error too many RE per subframe (%d). PDSCH configured for %d RE (%d PRB)\n", - nof_symbols, q->max_symbols, q->cell.nof_prb); + harq->nof_re, q->max_re, q->cell.nof_prb); return LIBLTE_ERROR_INVALID_INPUTS; } INFO("Encoding PDSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx); + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { @@ -453,27 +439,27 @@ int pdsch_encode(pdsch_t *q, uint8_t *data, cf_t *sf_symbols[MAX_PORTS], uint32_ } memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); - if (dlsch_encode(&q->dl_sch, data, q->pdsch_e, nof_bits, nof_bits_e, harq_process, rv_idx)) { + if (dlsch_encode(&q->dl_sch, harq, data, q->pdsch_e)) { fprintf(stderr, "Error encoding TB\n"); return LIBLTE_ERROR; } - scrambling_b_offset(&q->seq_pdsch[subframe], (uint8_t*) q->pdsch_e, 0, nof_bits_e); + scrambling_b_offset(&q->seq_pdsch[harq->sf_idx], (uint8_t*) q->pdsch_e, 0, harq->nof_bits); - mod_modulate(&q->mod[harq_process->mcs.mod], (uint8_t*) q->pdsch_e, q->pdsch_d, nof_bits_e); + mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pdsch_e, q->pdsch_d, harq->nof_bits); /* TODO: only diversity supported */ if (q->cell.nof_ports > 1) { - layermap_diversity(q->pdsch_d, x, q->cell.nof_ports, nof_symbols); + layermap_diversity(q->pdsch_d, x, q->cell.nof_ports, harq->nof_re); precoding_diversity(&q->precoding, x, q->pdsch_symbols, q->cell.nof_ports, - nof_symbols / q->cell.nof_ports); + harq->nof_re / q->cell.nof_ports); } else { - memcpy(q->pdsch_symbols[0], q->pdsch_d, nof_symbols * sizeof(cf_t)); + memcpy(q->pdsch_symbols[0], q->pdsch_d, harq->nof_re * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { - pdsch_put(q, q->pdsch_symbols[i], sf_symbols[i], &harq_process->prb_alloc, subframe); + pdsch_put(q, q->pdsch_symbols[i], sf_symbols[i], &harq->prb_alloc, harq->sf_idx); } ret = LIBLTE_SUCCESS; } else { diff --git a/lte/phy/lib/phch/src/pusch.c b/lte/phy/lib/phch/src/pusch.c index f3491e413..bb0888260 100644 --- a/lte/phy/lib/phch/src/pusch.c +++ b/lte/phy/lib/phch/src/pusch.c @@ -102,10 +102,10 @@ int pusch_init(pusch_t *q, lte_cell_t cell) { ret = LIBLTE_ERROR; q->cell = cell; - q->max_symbols = q->cell.nof_prb * MAX_PUSCH_RE(q->cell.cp); + q->max_re = q->cell.nof_prb * MAX_PUSCH_RE(q->cell.cp); INFO("Init PUSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, - q->cell.nof_prb, q->max_symbols); + q->cell.nof_prb, q->max_re); for (i = 0; i < 4; i++) { if (modem_table_lte(&q->mod[i], modulations[i], true)) { @@ -113,7 +113,7 @@ int pusch_init(pusch_t *q, lte_cell_t cell) { } } - demod_soft_init(&q->demod, q->max_symbols); + demod_soft_init(&q->demod, q->max_re); demod_soft_alg_set(&q->demod, APPROX); sch_init(&q->dl_sch); @@ -129,26 +129,26 @@ int pusch_init(pusch_t *q, lte_cell_t cell) { q->rnti_is_set = false; // Allocate floats for reception (LLRs). Buffer casted to uint8_t for transmission - q->pusch_q = vec_malloc(sizeof(float) * q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64)); + q->pusch_q = vec_malloc(sizeof(float) * q->max_re * lte_mod_bits_x_symbol(LTE_QAM64)); if (!q->pusch_q) { goto clean; } // Allocate floats for reception (LLRs). Buffer casted to uint8_t for transmission - q->pusch_g = vec_malloc(sizeof(float) * q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64)); + q->pusch_g = vec_malloc(sizeof(float) * q->max_re * lte_mod_bits_x_symbol(LTE_QAM64)); if (!q->pusch_g) { goto clean; } - q->pusch_d = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->pusch_d = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->pusch_d) { goto clean; } - q->ce = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->ce = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce) { goto clean; } - q->pusch_z = vec_malloc(sizeof(cf_t) * q->max_symbols); + q->pusch_z = vec_malloc(sizeof(cf_t) * q->max_re); if (!q->pusch_z) { goto clean; } @@ -204,7 +204,7 @@ int pusch_set_rnti(pusch_t *q, uint16_t rnti) { for (i = 0; i < NSUBFRAMES_X_FRAME; i++) { if (sequence_pusch(&q->seq_pusch[i], rnti, 2 * i, q->cell.id, - q->max_symbols * lte_mod_bits_x_symbol(LTE_QAM64))) { + q->max_re * lte_mod_bits_x_symbol(LTE_QAM64))) { return LIBLTE_ERROR; } } @@ -216,61 +216,53 @@ int pusch_set_rnti(pusch_t *q, uint16_t rnti) { /** Decodes the PUSCH from the received symbols */ -int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data, uint32_t subframe, - harq_t *harq_process, uint32_t rv_idx) +int pusch_decode(pusch_t *q, harq_t *harq, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data) { - /* Set pointers for layermapping & precoding */ uint32_t n; - uint32_t nof_symbols, nof_bits, nof_bits_e; if (q != NULL && sf_symbols != NULL && data != NULL && - subframe < 10 && - harq_process != NULL) + harq != NULL) { if (q->rnti_is_set) { - nof_bits = harq_process->mcs.tbs; - nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1); - nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); - INFO("Decoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - subframe, lte_mod_string(harq_process->mcs.mod), nof_bits, nof_symbols, nof_bits_e, rv_idx); + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); /* extract symbols */ - n = pusch_get(q, sf_symbols, q->pusch_d, &harq_process->prb_alloc, subframe); - if (n != nof_symbols) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); + n = pusch_get(q, sf_symbols, q->pusch_d, &harq->prb_alloc, harq->sf_idx); + if (n != harq->nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); return LIBLTE_ERROR; } /* extract channel estimates */ - n = pusch_get(q, ce, q->ce, &harq_process->prb_alloc, subframe); - if (n != nof_symbols) { - fprintf(stderr, "Error expecting %d symbols but got %d\n", nof_symbols, n); + n = pusch_get(q, ce, q->ce, &harq->prb_alloc, harq->sf_idx); + if (n != harq->nof_re) { + fprintf(stderr, "Error expecting %d symbols but got %d\n", harq->nof_re, n); return LIBLTE_ERROR; } predecoding_single(&q->equalizer, q->pusch_d, q->ce, q->pusch_z, - nof_symbols, noise_estimate); + harq->nof_re, noise_estimate); dft_predecoding(&q->dft_precoding, q->pusch_z, q->pusch_d, - harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul); + harq->prb_alloc.slot[0].nof_prb, harq->nof_symb); /* 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 */ demod_soft_sigma_set(&q->demod, sqrt(0.5)); - demod_soft_table_set(&q->demod, &q->mod[harq_process->mcs.mod]); - demod_soft_demodulate(&q->demod, q->pusch_d, q->pusch_q, nof_symbols); + demod_soft_table_set(&q->demod, &q->mod[harq->mcs.mod]); + demod_soft_demodulate(&q->demod, q->pusch_d, q->pusch_q, harq->nof_re); /* descramble */ - scrambling_f_offset(&q->seq_pusch[subframe], q->pusch_q, 0, nof_bits_e); + scrambling_f_offset(&q->seq_pusch[harq->sf_idx], q->pusch_q, 0, harq->nof_bits); - return ulsch_decode(&q->dl_sch, q->pusch_q, data, nof_bits, nof_bits_e, harq_process, rv_idx); + return ulsch_decode(&q->dl_sch, harq, q->pusch_q, data); } else { fprintf(stderr, "Must call pusch_set_rnti() before calling pusch_decode()\n"); return LIBLTE_ERROR; @@ -280,68 +272,59 @@ int pusch_decode(pusch_t *q, cf_t *sf_symbols, cf_t *ce, float noise_estimate, u } } -int pusch_encode(pusch_t *q, uint8_t *data, cf_t *sf_symbols, uint32_t subframe, - harq_t *harq_process, uint32_t rv_idx) +int pusch_encode(pusch_t *q, harq_t *harq_process, uint8_t *data, cf_t *sf_symbols) { uci_data_t uci_data; bzero(&uci_data, sizeof(uci_data_t)); - return pusch_uci_encode(q, data, uci_data, sf_symbols, subframe, harq_process, rv_idx); + return pusch_uci_encode(q, harq_process, data, uci_data, sf_symbols); } /** Converts the PUSCH data bits to symbols mapped to the slot ready for transmission */ -int pusch_uci_encode(pusch_t *q, uint8_t *data, uci_data_t uci_data, - cf_t *sf_symbols, uint32_t subframe, - harq_t *harq_process, uint32_t rv_idx) +int pusch_uci_encode(pusch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_data, cf_t *sf_symbols) { - uint32_t nof_symbols, nof_bits_ulsch, nof_bits_e; int ret = LIBLTE_ERROR_INVALID_INPUTS; - if (q != NULL && - data != NULL && - subframe < 10 && - harq_process != NULL) + if (q != NULL && + data != NULL && + harq != NULL) { - if (q->rnti_is_set) { - nof_bits_ulsch = harq_process->mcs.tbs; - nof_symbols = 2*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB*(CP_NSYMB(q->cell.cp)-1); - nof_bits_e = nof_symbols * lte_mod_bits_x_symbol(harq_process->mcs.mod); - if (harq_process->mcs.tbs == 0) { + if (harq->mcs.tbs == 0) { return LIBLTE_ERROR_INVALID_INPUTS; } - if (nof_bits_ulsch > nof_bits_e) { - fprintf(stderr, "Invalid code rate %.2f\n", (float) nof_bits_ulsch / nof_bits_e); + if (harq->mcs.tbs > harq->nof_bits) { + fprintf(stderr, "Invalid code rate %.2f\n", (float) harq->mcs.tbs / harq->nof_bits); return LIBLTE_ERROR_INVALID_INPUTS; } - if (nof_symbols > q->max_symbols) { + if (harq->nof_re > q->max_re) { fprintf(stderr, "Error too many RE per subframe (%d). PUSCH configured for %d RE (%d PRB)\n", - nof_symbols, q->max_symbols, q->cell.nof_prb); + harq->nof_re, q->max_re, q->cell.nof_prb); return LIBLTE_ERROR_INVALID_INPUTS; } - INFO("Encoding PUSCH SF: %d, Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", - subframe, lte_mod_string(harq_process->mcs.mod), nof_bits_ulsch, nof_symbols, nof_bits_e, rv_idx); + INFO("Encoding PUSCH SF: %d, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); - if (ulsch_uci_encode(&q->dl_sch, data, uci_data, q->pusch_g, harq_process, rv_idx, q->pusch_q)) + if (ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->pusch_g, q->pusch_q)) { fprintf(stderr, "Error encoding TB\n"); return LIBLTE_ERROR; } - scrambling_b_offset_pusch(&q->seq_pusch[subframe], (uint8_t*) q->pusch_q, 0, nof_bits_e); + scrambling_b_offset_pusch(&q->seq_pusch[harq->sf_idx], (uint8_t*) q->pusch_q, 0, harq->nof_bits); - mod_modulate(&q->mod[harq_process->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, nof_bits_e); + mod_modulate(&q->mod[harq->mcs.mod], (uint8_t*) q->pusch_q, q->pusch_d, harq->nof_bits); dft_precoding(&q->dft_precoding, q->pusch_d, q->pusch_z, - harq_process->prb_alloc.slot[0].nof_prb, harq_process->N_symb_ul); + harq->prb_alloc.slot[0].nof_prb, harq->nof_symb); /* mapping to resource elements */ - pusch_put(q, q->pusch_z, sf_symbols, &harq_process->prb_alloc, subframe); + pusch_put(q, q->pusch_z, sf_symbols, &harq->prb_alloc, harq->sf_idx); ret = LIBLTE_SUCCESS; } else { diff --git a/lte/phy/lib/phch/src/sch.c b/lte/phy/lib/phch/src/sch.c index 491400737..7bab60c94 100644 --- a/lte/phy/lib/phch/src/sch.c +++ b/lte/phy/lib/phch/src/sch.c @@ -116,8 +116,7 @@ uint32_t sch_last_noi(sch_t *q) { /* Encode a transport block according to 36.212 5.3.2 * */ -static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uint32_t nb_e, - harq_t *harq_process, uint32_t rv_idx) +static int encode_tb(sch_t *q, harq_t *harq, uint8_t *data, uint8_t *e_bits, uint32_t nof_e_bits) { uint8_t parity[24]; uint8_t *p_parity = parity; @@ -125,26 +124,26 @@ static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uin uint32_t i; uint32_t cb_len, rp, wp, rlen, F, n_e; int ret = LIBLTE_ERROR_INVALID_INPUTS; - uint32_t Qm = lte_mod_bits_x_symbol(harq_process->mcs.mod); + uint32_t Qm = lte_mod_bits_x_symbol(harq->mcs.mod); if (q != NULL && data != NULL && - harq_process != NULL) + harq != NULL) { - uint32_t Gp = nb_e / Qm; - uint32_t gamma = Gp%harq_process->cb_segm.C; + uint32_t Gp = nof_e_bits / Qm; + uint32_t gamma = Gp%harq->cb_segm.C; - if (rv_idx == 0) { + if (harq->rv == 0) { /* Compute transport block CRC */ - par = crc_checksum(&q->crc_tb, data, tbs); + par = crc_checksum(&q->crc_tb, data, harq->mcs.tbs); /* parity bits will be appended later */ bit_pack(par, &p_parity, 24); if (VERBOSE_ISDEBUG()) { DEBUG("DATA: ", 0); - vec_fprint_b(stdout, data, tbs); + vec_fprint_b(stdout, data, harq->mcs.tbs); DEBUG("PARITY: ", 0); vec_fprint_b(stdout, parity, 24); } @@ -152,37 +151,37 @@ static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uin wp = 0; rp = 0; - for (i = 0; i < harq_process->cb_segm.C; i++) { + for (i = 0; i < harq->cb_segm.C; i++) { /* Get read lengths */ - if (i < harq_process->cb_segm.C2) { - cb_len = harq_process->cb_segm.K2; + if (i < harq->cb_segm.C2) { + cb_len = harq->cb_segm.K2; } else { - cb_len = harq_process->cb_segm.K1; + cb_len = harq->cb_segm.K1; } - if (harq_process->cb_segm.C > 1) { + if (harq->cb_segm.C > 1) { rlen = cb_len - 24; } else { rlen = cb_len; } if (i == 0) { - F = harq_process->cb_segm.F; + F = harq->cb_segm.F; } else { F = 0; } - if (i <= harq_process->cb_segm.C - gamma - 1) { - n_e = Qm * (Gp/harq_process->cb_segm.C); + if (i <= harq->cb_segm.C - gamma - 1) { + n_e = Qm * (Gp/harq->cb_segm.C); } else { - n_e = Qm * ((uint32_t) ceilf((float) Gp/harq_process->cb_segm.C)); + n_e = Qm * ((uint32_t) ceilf((float) Gp/harq->cb_segm.C)); } INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, cb_len, rlen - F, wp, rp, F, n_e); - if (rv_idx == 0) { + if (harq->rv == 0) { /* Copy data to another buffer, making space for the Codeblock CRC */ - if (i < harq_process->cb_segm.C - 1) { + if (i < harq->cb_segm.C - 1) { // Copy data memcpy(&q->cb_in[F], &data[rp], (rlen - F) * sizeof(uint8_t)); } else { @@ -197,7 +196,7 @@ static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uin q->cb_in[j] = 0; } /* Attach Codeblock CRC */ - if (harq_process->cb_segm.C > 1) { + if (harq->cb_segm.C > 1) { crc_attach(&q->crc_cb, q->cb_in, rlen); } /* Set the filler bits to */ @@ -214,9 +213,9 @@ static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uin } /* Rate matching */ - if (rm_turbo_tx(harq_process->pdsch_w_buff_c[i], harq_process->w_buff_size, + if (rm_turbo_tx(harq->pdsch_w_buff_c[i], harq->w_buff_size, (uint8_t*) q->cb_out, 3 * cb_len + 12, - &e_bits[wp], n_e, rv_idx)) + &e_bits[wp], n_e, harq->rv)) { fprintf(stderr, "Error in rate matching\n"); return LIBLTE_ERROR; @@ -236,59 +235,58 @@ static int encode_tb(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uin /* Decode a transport block according to 36.212 5.3.2 * */ -static int decode_tb(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint32_t nb_e, - harq_t *harq_process, uint32_t rv_idx) +static int decode_tb(sch_t *q, harq_t *harq, float *e_bits, uint8_t *data, uint32_t nof_e_bits) { uint8_t parity[24]; uint8_t *p_parity = parity; uint32_t par_rx, par_tx; uint32_t i; uint32_t cb_len, rp, wp, rlen, F, n_e; - uint32_t Qm = lte_mod_bits_x_symbol(harq_process->mcs.mod); + uint32_t Qm = lte_mod_bits_x_symbol(harq->mcs.mod); if (q != NULL && data != NULL && - harq_process != NULL) + harq != NULL) { rp = 0; rp = 0; wp = 0; - uint32_t Gp = nb_e / Qm; - uint32_t gamma = Gp%harq_process->cb_segm.C; + uint32_t Gp = nof_e_bits / Qm; + uint32_t gamma = Gp%harq->cb_segm.C; bool early_stop = true; - for (i = 0; i < harq_process->cb_segm.C && early_stop; i++) { + for (i = 0; i < harq->cb_segm.C && early_stop; i++) { /* Get read/write lengths */ - if (i < harq_process->cb_segm.C2) { - cb_len = harq_process->cb_segm.K2; + if (i < harq->cb_segm.C2) { + cb_len = harq->cb_segm.K2; } else { - cb_len = harq_process->cb_segm.K1; + cb_len = harq->cb_segm.K1; } - if (harq_process->cb_segm.C == 1) { + if (harq->cb_segm.C == 1) { rlen = cb_len; } else { rlen = cb_len - 24; } if (i == 0) { - F = harq_process->cb_segm.F; + F = harq->cb_segm.F; } else { F = 0; } - if (i <= harq_process->cb_segm.C - gamma - 1) { - n_e = Qm * (Gp/harq_process->cb_segm.C); + if (i <= harq->cb_segm.C - gamma - 1) { + n_e = Qm * (Gp/harq->cb_segm.C); } else { - n_e = Qm * ((uint32_t) ceilf((float) Gp/harq_process->cb_segm.C)); + n_e = Qm * ((uint32_t) ceilf((float) Gp/harq->cb_segm.C)); } INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, cb_len, rlen - F, wp, rp, F, n_e); /* Rate Unmatching */ - if (rm_turbo_rx(harq_process->pdsch_w_buff_f[i], harq_process->w_buff_size, + if (rm_turbo_rx(harq->pdsch_w_buff_f[i], harq->w_buff_size, &e_bits[rp], n_e, - (float*) q->cb_out, 3 * cb_len + 12, rv_idx, F)) { + (float*) q->cb_out, 3 * cb_len + 12, harq->rv, F)) { fprintf(stderr, "Error in rate matching\n"); return LIBLTE_ERROR; } @@ -311,12 +309,12 @@ static int decode_tb(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint3 tdec_iteration(&q->decoder, (float*) q->cb_out, cb_len); q->nof_iterations++; - if (harq_process->cb_segm.C > 1) { + if (harq->cb_segm.C > 1) { len_crc = cb_len; cb_in_ptr = q->cb_in; crc_ptr = &q->crc_cb; } else { - len_crc = tbs+24; + len_crc = harq->mcs.tbs+24; cb_in_ptr = &q->cb_in[F]; crc_ptr = &q->crc_tb; } @@ -339,7 +337,7 @@ static int decode_tb(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint3 // If CB CRC is not correct, early_stop will be false and wont continue with rest of CBs /* Copy data to another buffer, removing the Codeblock CRC */ - if (i < harq_process->cb_segm.C - 1) { + if (i < harq->cb_segm.C - 1) { memcpy(&data[wp], &q->cb_in[F], (rlen - F) * sizeof(uint8_t)); } else { DEBUG("Last CB, appending parity: %d to %d from %d and 24 from %d\n", @@ -362,7 +360,7 @@ static int decode_tb(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint3 INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp); // Compute transport block CRC - par_rx = crc_checksum(&q->crc_tb, data, tbs); + par_rx = crc_checksum(&q->crc_tb, data, harq->mcs.tbs); // check parity bits par_tx = bit_unpack(&p_parity, 24); @@ -385,21 +383,18 @@ static int decode_tb(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint3 } } -int dlsch_decode(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint32_t nb_e, - harq_t *harq_process, uint32_t rv_idx) +int dlsch_decode(sch_t *q, harq_t *harq, float *e_bits, uint8_t *data) { - return decode_tb(q, e_bits, data, tbs, nb_e, harq_process, rv_idx); + return decode_tb(q, harq, e_bits, data, harq->nof_bits); } -int dlsch_encode(sch_t *q, uint8_t *data, uint8_t *e_bits, uint32_t tbs, uint32_t nb_e, - harq_t *harq_process, uint32_t rv_idx) { - return encode_tb(q, data, e_bits, tbs, nb_e, harq_process, rv_idx); +int dlsch_encode(sch_t *q, harq_t *harq, uint8_t *data, uint8_t *e_bits) { + return encode_tb(q, harq, data, e_bits, harq->nof_bits); } -int ulsch_decode(sch_t *q, float *e_bits, uint8_t *data, uint32_t tbs, uint32_t nb_e, - harq_t *harq_process, uint32_t rv_idx) +int ulsch_decode(sch_t *q, harq_t *harq, float *e_bits, uint8_t *data) { - return decode_tb(q, e_bits, data, tbs, nb_e, harq_process, rv_idx); + return decode_tb(q, harq, e_bits, data, harq->nof_bits); } @@ -426,17 +421,15 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Q_m, uint32_t H_prime_total, uin } -int ulsch_encode(sch_t *q, uint8_t *data, uint8_t *g_bits, - harq_t *harq_process, uint32_t rv_idx, uint8_t *q_bits) +int ulsch_encode(sch_t *q, harq_t *harq, uint8_t *data, uint8_t *g_bits, uint8_t *q_bits) { uci_data_t uci_data; bzero(&uci_data, sizeof(uci_data_t)); - return ulsch_uci_encode(q, data, uci_data, g_bits, harq_process, rv_idx, q_bits); + return ulsch_uci_encode(q, harq, data, uci_data, g_bits, q_bits); } -int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bits, - harq_t *harq_process, uint32_t rv_idx, uint8_t *q_bits) +int ulsch_uci_encode(sch_t *q, harq_t *harq, uint8_t *data, uci_data_t uci_data, uint8_t *g_bits, uint8_t *q_bits) { int ret; @@ -444,9 +437,9 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi uint32_t Q_prime_cqi = 0; uint32_t Q_prime_ack = 0; uint32_t Q_prime_ri = 0; - uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); + uint32_t Q_m = lte_mod_bits_x_symbol(harq->mcs.mod); - uint32_t nof_symbols = 12*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB; + uint32_t nof_symbols = 12*harq->prb_alloc.slot[0].nof_prb*RE_X_RB; uint32_t nb_q = nof_symbols * Q_m; bzero(q_bits, sizeof(uint8_t) * nb_q); @@ -454,10 +447,10 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi // Encode RI if (uci_data.uci_ri_len > 0) { float beta = uci_data.beta_ri; - if (harq_process->mcs.tbs == 0) { + if (harq->mcs.tbs == 0) { beta /= uci_data.beta_cqi; } - ret = uci_encode_ri(uci_data.uci_ri, uci_data.uci_cqi_len, beta, harq_process, nb_q/Q_m, q_bits); + ret = uci_encode_ri(uci_data.uci_ri, uci_data.uci_cqi_len, beta, harq, nb_q/Q_m, q_bits); if (ret < 0) { return ret; } @@ -468,7 +461,7 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi if (uci_data.uci_cqi_len > 0) { ret = uci_encode_cqi_pusch(&q->uci_cqi, uci_data.uci_cqi, uci_data.uci_cqi_len, uci_data.beta_cqi, - Q_prime_ri, harq_process, g_bits); + Q_prime_ri, harq, g_bits); if (ret < 0) { return ret; } @@ -478,25 +471,24 @@ int ulsch_uci_encode(sch_t *q, uint8_t *data, uci_data_t uci_data, uint8_t *g_bi e_offset += Q_prime_cqi*Q_m; // Encode UL-SCH - if (harq_process->mcs.tbs > 0) { + if (harq->mcs.tbs > 0) { uint32_t G = nb_q/Q_m - Q_prime_ri - Q_prime_cqi; - ret = encode_tb(q, data, &g_bits[e_offset], harq_process->mcs.tbs, - G*Q_m, harq_process, rv_idx); + ret = encode_tb(q, harq, data, &g_bits[e_offset], G*Q_m); if (ret) { return ret; } } // Interleave UL-SCH (and RI and CQI) - ulsch_interleave(g_bits, Q_m, nb_q/Q_m, harq_process->N_symb_ul, q_bits); + ulsch_interleave(g_bits, Q_m, nb_q/Q_m, harq->nof_symb, q_bits); // Encode (and interleave) ACK if (uci_data.uci_ack_len > 0) { float beta = uci_data.beta_ack; - if (harq_process->mcs.tbs == 0) { + if (harq->mcs.tbs == 0) { beta /= uci_data.beta_cqi; } - ret = uci_encode_ack(uci_data.uci_ack, uci_data.uci_cqi_len, beta, harq_process, nb_q/Q_m, q_bits); + ret = uci_encode_ack(uci_data.uci_ack, uci_data.uci_cqi_len, beta, harq, nb_q/Q_m, q_bits); if (ret < 0) { return ret; } diff --git a/lte/phy/lib/phch/src/uci.c b/lte/phy/lib/phch/src/uci.c index 00814fd03..38d7b8d58 100644 --- a/lte/phy/lib/phch/src/uci.c +++ b/lte/phy/lib/phch/src/uci.c @@ -114,21 +114,21 @@ void uci_cqi_free(uci_cqi_pusch_t *q) { } -static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, harq_t *harq_process) { - uint32_t M_sc = harq_process->prb_alloc.slot[0].nof_prb * RE_X_RB; +static uint32_t Q_prime_cqi(uint32_t O, float beta, uint32_t Q_prime_ri, harq_t *harq) { + uint32_t M_sc = harq->prb_alloc.slot[0].nof_prb * RE_X_RB; - uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 + - harq_process->cb_segm.C2*harq_process->cb_segm.K2; + uint32_t K = harq->cb_segm.C1*harq->cb_segm.K1 + + harq->cb_segm.C2*harq->cb_segm.K2; uint32_t Q_prime = 0; if (K > 0) { - uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB; + uint32_t M_sc_init = harq->nof_prb * RE_X_RB; uint32_t L = (O<11)?0:8; - uint32_t x = (uint32_t) ceilf((float) (O+L)*M_sc_init*harq_process->N_symb_ul*beta/K); + uint32_t x = (uint32_t) ceilf((float) (O+L)*M_sc_init*harq->nof_symb*beta/K); - Q_prime = MIN(x, M_sc * harq_process->N_symb_ul - Q_prime_ri); + Q_prime = MIN(x, M_sc * harq->nof_symb - Q_prime_ri); } else { - Q_prime = 12*harq_process->prb_alloc.slot[0].nof_prb*RE_X_RB - Q_prime_ri; + Q_prime = 12*harq->prb_alloc.slot[0].nof_prb*RE_X_RB - Q_prime_ri; } return Q_prime; @@ -218,11 +218,11 @@ int uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_bits[CQI /* Encode UCI CQI/PMI as described in 5.2.2.6 of 36.212 */ int uci_encode_cqi_pusch(uci_cqi_pusch_t *q, uint8_t *cqi_data, uint32_t cqi_len, float beta, uint32_t Q_prime_ri, - harq_t *harq_process, uint8_t *q_bits) + harq_t *harq, uint8_t *q_bits) { - uint32_t Q_prime = Q_prime_cqi(cqi_len, beta, Q_prime_ri, harq_process); - uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); + uint32_t Q_prime = Q_prime_cqi(cqi_len, beta, Q_prime_ri, harq); + uint32_t Q_m = lte_mod_bits_x_symbol(harq->mcs.mod); int ret = LIBLTE_ERROR; if (cqi_len <= 11) { @@ -286,11 +286,11 @@ static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_i } -static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, harq_t *harq_process) { - uint32_t M_sc = harq_process->prb_alloc.slot[0].nof_prb * RE_X_RB; +static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, harq_t *harq) { + uint32_t M_sc = harq->prb_alloc.slot[0].nof_prb * RE_X_RB; - uint32_t K = harq_process->cb_segm.C1*harq_process->cb_segm.K1 + - harq_process->cb_segm.C2*harq_process->cb_segm.K2; + uint32_t K = harq->cb_segm.C1*harq->cb_segm.K1 + + harq->cb_segm.C2*harq->cb_segm.K2; // If not carrying UL-SCH, get Q_prime according to 5.2.4.1 if (K == 0) { @@ -301,9 +301,9 @@ static uint32_t Q_prime_ri_ack(uint32_t O, uint32_t O_cqi, float beta, harq_t *h } } - uint32_t M_sc_init = harq_process->nof_prb_pusch_init * RE_X_RB; + uint32_t M_sc_init = harq->nof_prb * RE_X_RB; - uint32_t x = (uint32_t) ceilf((float) O*M_sc_init*harq_process->N_symb_ul*beta/K); + uint32_t x = (uint32_t) ceilf((float) O*M_sc_init*harq->nof_symb*beta/K); uint32_t Q_prime = MIN(x, 4*M_sc); @@ -321,16 +321,16 @@ static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Q_m) /* Encode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212 * Currently only supporting 1-bit HARQ */ -int uci_encode_ack(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq_process, uint32_t H_prime_total, uint8_t *q_bits) +int uci_encode_ack(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq, uint32_t H_prime_total, uint8_t *q_bits) { - uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); - uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq_process); + uint32_t Q_m = lte_mod_bits_x_symbol(harq->mcs.mod); + uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq); uint8_t q_encoded_bits[6]; encode_ri_ack(data, q_encoded_bits, Q_m); for (uint32_t i=0;iN_symb_ul, harq_process->cell.cp, q_bits); + uci_ulsch_interleave_ack(q_encoded_bits, i, Q_m, H_prime_total, harq->nof_symb, harq->cell.cp, q_bits); } return (int) Qprime; @@ -340,16 +340,16 @@ int uci_encode_ack(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq_proces /* Encode UCI RI bits as described in 5.2.2.6 of 36.212 * Currently only supporting 1-bit RI */ -int uci_encode_ri(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq_process, uint32_t H_prime_total, uint8_t *q_bits) +int uci_encode_ri(uint8_t data, uint32_t O_cqi, float beta, harq_t *harq, uint32_t H_prime_total, uint8_t *q_bits) { - uint32_t Q_m = lte_mod_bits_x_symbol(harq_process->mcs.mod); - uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq_process); + uint32_t Q_m = lte_mod_bits_x_symbol(harq->mcs.mod); + uint32_t Qprime = Q_prime_ri_ack(1, O_cqi, beta, harq); uint8_t q_encoded_bits[6]; encode_ri_ack(data, q_encoded_bits, Q_m); for (uint32_t i=0;iN_symb_ul, harq_process->cell.cp, q_bits); + uci_ulsch_interleave_ri(q_encoded_bits, i, Q_m, H_prime_total, harq->nof_symb, harq->cell.cp, q_bits); } return (int) Qprime; diff --git a/lte/phy/lib/phch/test/dlsch_encode_test_mex.c b/lte/phy/lib/phch/test/dlsch_encode_test_mex.c index 0ecb723c7..c9fd94227 100644 --- a/lte/phy/lib/phch/test/dlsch_encode_test_mex.c +++ b/lte/phy/lib/phch/test/dlsch_encode_test_mex.c @@ -78,7 +78,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Field RV not found in dlsch config\n"); return; } - + char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation"); if (!strcmp(mod_str, "QPSK")) { @@ -94,24 +94,24 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mxFree(mod_str); - if (harq_setup(&harq_process, mcs, &prb_alloc)) { + if (harq_setup_dl(&harq_process, mcs, rv, 0, &prb_alloc)) { mexErrMsgTxt("Error configuring HARQ process\n"); return; } + harq_process.nof_bits = mxGetScalar(OUTLEN); - uint32_t nof_bits_e = (uint32_t) mxGetScalar(OUTLEN); - uint8_t *e_bits = vec_malloc(nof_bits_e * sizeof(uint8_t)); + uint8_t *e_bits = vec_malloc(harq_process.nof_bits* sizeof(uint8_t)); if (!e_bits) { return; } - if (dlsch_encode(&dlsch, trblkin, e_bits, mcs.tbs, nof_bits_e, &harq_process, rv)) { + if (dlsch_encode(&dlsch, &harq_process, trblkin, e_bits)) { mexErrMsgTxt("Error encoding TB\n"); return; } if (nlhs >= 1) { - mexutils_write_uint8(e_bits, &plhs[0], nof_bits_e, 1); + mexutils_write_uint8(e_bits, &plhs[0], harq_process.nof_bits, 1); } sch_free(&dlsch); diff --git a/lte/phy/lib/phch/test/pdsch_file_test.c b/lte/phy/lib/phch/test/pdsch_file_test.c index 5bda48991..538789b4a 100644 --- a/lte/phy/lib/phch/test/pdsch_file_test.c +++ b/lte/phy/lib/phch/test/pdsch_file_test.c @@ -284,12 +284,11 @@ int main(int argc, char **argv) { goto goout; } if (ra_dl.mcs.tbs > 0) { - if (harq_setup(&harq_process, ra_dl.mcs, &ra_dl.prb_alloc)) { + if (harq_setup_dl(&harq_process, ra_dl.mcs, ra_dl.rv_idx, sf_idx, &ra_dl.prb_alloc)) { fprintf(stderr, "Error configuring HARQ process\n"); goto goout; } - if (pdsch_decode(&pdsch, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), - data, sf_idx, &harq_process, ra_dl.rv_idx)) { + if (pdsch_decode(&pdsch, &harq_process, fft_buffer, ce, chest_dl_get_noise_estimate(&chest), data)) { fprintf(stderr, "Error decoding PDSCH\n"); goto goout; } else { diff --git a/lte/phy/lib/phch/test/pdsch_test.c b/lte/phy/lib/phch/test/pdsch_test.c index 1bd26d398..adbbc4057 100644 --- a/lte/phy/lib/phch/test/pdsch_test.c +++ b/lte/phy/lib/phch/test/pdsch_test.c @@ -194,17 +194,17 @@ int main(int argc, char **argv) { if (VERBOSE_ISNONE()) { printf("Decoding TBS: %d\r",mcs.tbs); } - if (harq_setup(&harq_process, mcs, &prb_alloc)) { - fprintf(stderr, "Error configuring HARQ process\n"); - goto quit; - } - for (i=0;i= 1) { diff --git a/lte/phy/lib/phch/test/pusch_test.c b/lte/phy/lib/phch/test/pusch_test.c index 662a218b8..05aaf91ee 100644 --- a/lte/phy/lib/phch/test/pusch_test.c +++ b/lte/phy/lib/phch/test/pusch_test.c @@ -160,11 +160,6 @@ int main(int argc, char **argv) { goto quit; } - if (harq_setup(&harq_process, mcs, &prb_alloc)) { - fprintf(stderr, "Error configuring HARQ process\n"); - goto quit; - } - for (uint32_t i=0;i 0) { - if (pusch_uci_encode(&pusch, data, uci_data, sf_symbols, subframe, &harq_process, rv_idx)) { + if (harq_setup_ul(&harq_process, mcs, rv_idx, subframe, &prb_alloc)) { + fprintf(stderr, "Error configuring HARQ process\n"); + goto quit; + } + + if (pusch_uci_encode(&pusch, &harq_process, data, uci_data, sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); exit(-1); } diff --git a/lte/phy/lib/phch/test/ulsch_encode_test_mex.c b/lte/phy/lib/phch/test/ulsch_encode_test_mex.c index 53b402bc9..6c219bcc3 100644 --- a/lte/phy/lib/phch/test/ulsch_encode_test_mex.c +++ b/lte/phy/lib/phch/test/ulsch_encode_test_mex.c @@ -146,38 +146,38 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexPrintf("Q_m: %d, NPRB: %d, RV: %d\n", lte_mod_bits_x_symbol(mcs.mod), prb_alloc.slot[0].nof_prb, rv); - if (harq_setup(&harq_process, mcs, &prb_alloc)) { + if (harq_setup_ul(&harq_process, mcs, 0, 0, &prb_alloc)) { mexErrMsgTxt("Error configuring HARQ process\n"); return; } - uint32_t nof_symbols = 12*harq_process.prb_alloc.slot[0].nof_prb*RE_X_RB; - uint32_t nof_q_bits = nof_symbols * lte_mod_bits_x_symbol(harq_process.mcs.mod); - - uint8_t *q_bits = vec_malloc(nof_q_bits * sizeof(uint8_t)); + uint8_t *q_bits = vec_malloc(harq_process.nof_bits * sizeof(uint8_t)); if (!q_bits) { return; } - uint8_t *g_bits = vec_malloc(nof_q_bits * sizeof(uint8_t)); + uint8_t *g_bits = vec_malloc(harq_process.nof_bits * sizeof(uint8_t)); if (!g_bits) { return; } - if (ulsch_uci_encode(&ulsch, trblkin, uci_data, g_bits, &harq_process, 0, q_bits)) + if (ulsch_uci_encode(&ulsch, &harq_process, trblkin, uci_data, g_bits, q_bits)) { mexErrMsgTxt("Error encoding TB\n"); return; } if (rv > 0) { - if (ulsch_uci_encode(&ulsch, trblkin, uci_data, g_bits, &harq_process, rv, q_bits)) - { + if (harq_setup_ul(&harq_process, mcs, rv, 0, &prb_alloc)) { + mexErrMsgTxt("Error configuring HARQ process\n"); + return; + } + if (ulsch_uci_encode(&ulsch, &harq_process, trblkin, uci_data, g_bits, q_bits)) { mexErrMsgTxt("Error encoding TB\n"); return; } } if (nlhs >= 1) { - mexutils_write_uint8(q_bits, &plhs[0], nof_q_bits, 1); + mexutils_write_uint8(q_bits, &plhs[0], harq_process.nof_bits, 1); } sch_free(&ulsch); diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 1093a6f27..5975b15d9 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -251,16 +251,15 @@ int ue_dl_decode_sib(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, ui rvidx = ra_dl.rv_idx; } if (rvidx == 0) { - if (harq_setup(&q->harq_process[0], ra_dl.mcs, &ra_dl.prb_alloc)) { + if (harq_setup_dl(&q->harq_process[0], ra_dl.mcs, rvidx, sf_idx, &ra_dl.prb_alloc)) { fprintf(stderr, "Error configuring HARQ process\n"); return LIBLTE_ERROR; } } if (q->harq_process[0].mcs.mod > 0) { - ret = pdsch_decode(&q->pdsch, q->sf_symbols, q->ce, - chest_dl_get_noise_estimate(&q->chest), - data, sf_idx, - &q->harq_process[0], rvidx); + ret = pdsch_decode(&q->pdsch, &q->harq_process[0], q->sf_symbols, + q->ce, chest_dl_get_noise_estimate(&q->chest), + data); if (ret == LIBLTE_ERROR) { q->pkt_errors++; } else if (ret == LIBLTE_ERROR_INVALID_INPUTS) {