From e4e3456d768aa7cca9e9c572ee95c7d13b8a5396 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 14 Apr 2021 20:23:17 +0200 Subject: [PATCH] Refactored PDSCH/PUSCH decoder for LDPC early stopping --- .../srsran/phy/fec/ldpc/ldpc_decoder.h | 20 ++ lib/include/srsran/phy/phch/pdsch_nr.h | 10 +- lib/include/srsran/phy/phch/pusch_nr.h | 11 +- lib/include/srsran/phy/phch/sch_nr.h | 18 +- lib/src/phy/fec/ldpc/ldpc_decoder.c | 24 ++- lib/src/phy/phch/pdsch_nr.c | 64 +++---- lib/src/phy/phch/pusch_nr.c | 20 +- lib/src/phy/phch/sch_nr.c | 175 ++++++++++-------- lib/src/phy/phch/test/pdsch_nr_test.c | 24 +-- lib/src/phy/phch/test/pusch_nr_test.c | 60 +++--- lib/src/phy/phch/test/sch_nr_test.c | 7 +- lib/src/phy/ue/ue_dl_nr.c | 2 +- lib/test/phy/phy_dl_nr_test.c | 32 ++-- srsue/src/phy/nr/cc_worker.cc | 22 +-- 14 files changed, 266 insertions(+), 223 deletions(-) diff --git a/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h b/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h index 3ae49164a..1188b89e1 100644 --- a/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h +++ b/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h @@ -150,4 +150,24 @@ srsran_ldpc_decoder_decode_s(srsran_ldpc_decoder_t* q, const int16_t* llrs, uint SRSRAN_API int srsran_ldpc_decoder_decode_c(srsran_ldpc_decoder_t* q, const int8_t* llrs, uint8_t* message, uint32_t cdwd_rm_length); +/*! + * Carries out the actual decoding with 8-bit integer-valued LLRs. It is + * recommended to use a 7-bit representation for the LLRs, given that all + * values exceeding \f$ 2^{7}-1 \f$ (in magnitude) will be considered as infinity. + * \param[in] q A pointer to the LDPC decoder (a srsran_ldpc_decoder_t structure + * instance) that carries out the decoding. + * \param[in] llrs The LLRs obtained from the channel samples that correspond to + * the codeword to be decoded. + * \param[out] message The message (uncoded bits) resulting from the decoding + * operation. + * \param[in] cdwd_rm_length The number of bits forming the codeword (after rate matching). + * \param[in,out] crc Code-block CRC object for early stop. Set for NULL to disable check + * \return -1 if an error occurred, the number of used iterations, and 0 if CRC is provided and did not match + */ +SRSRAN_API int srsran_ldpc_decoder_decode_crc_c(srsran_ldpc_decoder_t* q, + const int8_t* llrs, + uint8_t* message, + uint32_t cdwd_rm_length, + srsran_crc_t* crc); + #endif // SRSRAN_LDPCDECODER_H diff --git a/lib/include/srsran/phy/phch/pdsch_nr.h b/lib/include/srsran/phy/phch/pdsch_nr.h index 3e299d931..b8e166105 100644 --- a/lib/include/srsran/phy/phch/pdsch_nr.h +++ b/lib/include/srsran/phy/phch/pdsch_nr.h @@ -64,13 +64,11 @@ typedef struct SRSRAN_API { } srsran_pdsch_nr_t; /** - * + * @brief Groups NR-PDSCH data for reception */ typedef struct { - uint8_t* payload; - bool crc; - float evm; - uint32_t fec_iters; + srsran_sch_tb_res_nr_t tb[SRSRAN_MAX_TB]; ///< SCH payload + float evm[SRSRAN_MAX_CODEWORDS]; ///< EVM measurement if configured through arguments } srsran_pdsch_res_nr_t; SRSRAN_API int srsran_pdsch_nr_init_enb(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* args); @@ -92,7 +90,7 @@ SRSRAN_API int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q, const srsran_sch_grant_nr_t* grant, srsran_chest_dl_res_t* channel, cf_t* sf_symbols[SRSRAN_MAX_PORTS], - srsran_pdsch_res_nr_t data[SRSRAN_MAX_TB]); + srsran_pdsch_res_nr_t* res); SRSRAN_API uint32_t srsran_pdsch_nr_rx_info(const srsran_pdsch_nr_t* q, const srsran_sch_cfg_nr_t* cfg, diff --git a/lib/include/srsran/phy/phch/pusch_nr.h b/lib/include/srsran/phy/phch/pusch_nr.h index 6eb894c92..ee06daf18 100644 --- a/lib/include/srsran/phy/phch/pusch_nr.h +++ b/lib/include/srsran/phy/phch/pusch_nr.h @@ -70,18 +70,17 @@ typedef struct SRSRAN_API { * @brief Groups NR-PUSCH data for transmission */ typedef struct { - uint8_t* payload; ///< SCH payload - srsran_uci_value_nr_t uci; ///< UCI payload + uint8_t* payload[SRSRAN_MAX_TB]; ///< SCH payload + srsran_uci_value_nr_t uci; ///< UCI payload } srsran_pusch_data_nr_t; /** * @brief Groups NR-PUSCH data for reception */ typedef struct { - uint8_t* payload; ///< SCH payload - srsran_uci_value_nr_t uci; ///< UCI payload - bool crc; ///< CRC match - float evm; ///< EVM measurement if configured through arguments + srsran_sch_tb_res_nr_t tb[SRSRAN_MAX_TB]; ///< SCH payload + srsran_uci_value_nr_t uci; ///< UCI payload + float evm[SRSRAN_MAX_CODEWORDS]; ///< EVM measurement if configured through arguments } srsran_pusch_res_nr_t; SRSRAN_API int srsran_pusch_nr_init_gnb(srsran_pusch_nr_t* q, const srsran_pusch_nr_args_t* args); diff --git a/lib/include/srsran/phy/phch/sch_nr.h b/lib/include/srsran/phy/phch/sch_nr.h index d3eaa4bf9..68819b863 100644 --- a/lib/include/srsran/phy/phch/sch_nr.h +++ b/lib/include/srsran/phy/phch/sch_nr.h @@ -32,6 +32,15 @@ #define SRSRAN_SCH_NR_MAX_NOF_CB_LDPC \ ((SRSRAN_SLOT_MAX_NOF_BITS_NR + (SRSRAN_LDPC_BG2_MAX_LEN_CB - 1)) / SRSRAN_LDPC_BG2_MAX_LEN_CB) +/** + * @brief Groups NR-PUSCH data for reception + */ +typedef struct { + uint8_t* payload; ///< SCH payload + bool crc; ///< CRC match + float avg_iter; ///< Average iterations +} srsran_sch_tb_res_nr_t; + typedef struct SRSRAN_API { srsran_carrier_nr_t carrier; @@ -153,8 +162,7 @@ SRSRAN_API int srsran_dlsch_nr_decode(srsran_sch_nr_t* q, const srsran_sch_cfg_t* sch_cfg, const srsran_sch_tb_t* tb, int8_t* e_bits, - uint8_t* data, - bool* crc_ok); + srsran_sch_tb_res_nr_t* res); SRSRAN_API int srsran_ulsch_nr_encode(srsran_sch_nr_t* q, const srsran_sch_cfg_t* cfg, @@ -166,9 +174,9 @@ SRSRAN_API int srsran_ulsch_nr_decode(srsran_sch_nr_t* q, const srsran_sch_cfg_t* sch_cfg, const srsran_sch_tb_t* tb, int8_t* e_bits, - uint8_t* data, - bool* crc_ok); + srsran_sch_tb_res_nr_t* res); -SRSRAN_API int srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, char* str, uint32_t str_len); +SRSRAN_API int +srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, const srsran_sch_tb_res_nr_t* res, char* str, uint32_t str_len); #endif // SRSRAN_SCH_NR_H \ No newline at end of file diff --git a/lib/src/phy/fec/ldpc/ldpc_decoder.c b/lib/src/phy/fec/ldpc/ldpc_decoder.c index 11a52dbc1..d3ffc378b 100644 --- a/lib/src/phy/fec/ldpc/ldpc_decoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_decoder.c @@ -73,11 +73,24 @@ update_ldpc_check_to_var_##SUFFIX(q->ptr, i_layer, this_pcm, these_var_indices); \ \ update_ldpc_soft_bits_##SUFFIX(q->ptr, i_layer, these_var_indices); \ + } \ + \ + if (crc != NULL) { \ + extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \ + \ + if (srsran_crc_match(crc, message, q->liftK - crc->order)) { \ + return i_iteration + 1; \ + } \ } \ } \ \ - extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \ + /* If reached here, and CRC is being checked, it has failed */ \ + if (crc != NULL) { \ + return 0; \ + } \ \ + /* Without CRC, extract message and return the maximum number of iterations */ \ + extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \ return q->max_nof_iter; \ } #define LDPC_DECODER_TEMPLATE_FLOOD(LLR_TYPE, SUFFIX) \ @@ -638,3 +651,12 @@ int srsran_ldpc_decoder_decode_c(srsran_ldpc_decoder_t* q, { return q->decode_c(q, llrs, message, cdwd_rm_length, NULL); } + +int srsran_ldpc_decoder_decode_crc_c(srsran_ldpc_decoder_t* q, + const int8_t* llrs, + uint8_t* message, + uint32_t cdwd_rm_length, + srsran_crc_t* crc) +{ + return q->decode_c(q, llrs, message, cdwd_rm_length, crc); +} diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index f87f32bcb..257a961b5 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -462,7 +462,8 @@ static inline int pdsch_nr_decode_codeword(srsran_pdsch_nr_t* q, // EVM if (q->evm_buffer != NULL) { - res->evm = srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); + res->evm[tb->cw_idx] = + srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); } // Change LLR sign and set to zero the LLR that are not used @@ -477,7 +478,7 @@ static inline int pdsch_nr_decode_codeword(srsran_pdsch_nr_t* q, } // Decode SCH - if (srsran_dlsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSRAN_SUCCESS) { + if (srsran_dlsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, &res->tb[tb->cw_idx]) < SRSRAN_SUCCESS) { ERROR("Error in DL-SCH encoding"); return SRSRAN_ERROR; } @@ -566,10 +567,12 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q, return SRSRAN_SUCCESS; } -static uint32_t srsran_pdsch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, - const srsran_sch_grant_nr_t* grant, - char* str, - uint32_t str_len) +static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q, + const srsran_sch_cfg_nr_t* cfg, + const srsran_sch_grant_nr_t* grant, + const srsran_pdsch_res_nr_t* res, + char* str, + uint32_t str_len) { uint32_t len = 0; len = srsran_print_check(str, str_len, len, "rnti=0x%x ", grant->rnti); @@ -606,7 +609,15 @@ static uint32_t srsran_pdsch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, // Append TB info for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) { - len += srsran_sch_nr_tb_info(&grant->tb[i], &str[len], str_len - len); + len += srsran_sch_nr_tb_info(&grant->tb[i], &res->tb[i], &str[len], str_len - len); + + if (res != NULL) { + if (grant->tb[i].enabled && !isnan(res->evm[i])) { + len = srsran_print_check(str, str_len, len, "evm=%.2f ", res->evm[i]); + if (i < SRSRAN_MAX_CODEWORDS - 1) { + } + } + } } return len; @@ -615,52 +626,21 @@ static uint32_t srsran_pdsch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, uint32_t srsran_pdsch_nr_rx_info(const srsran_pdsch_nr_t* q, const srsran_sch_cfg_nr_t* cfg, const srsran_sch_grant_nr_t* grant, - const srsran_pdsch_res_nr_t res[SRSRAN_MAX_CODEWORDS], + const srsran_pdsch_res_nr_t* res, char* str, uint32_t str_len) { uint32_t len = 0; - len += srsran_pdsch_nr_grant_info(cfg, grant, &str[len], str_len - len); + len += pdsch_nr_grant_info(q, cfg, grant, res, &str[len], str_len - len); if (cfg->rvd_re.count != 0) { - len = srsran_print_check(str, str_len, len, ", Reserved={"); + len = srsran_print_check(str, str_len, len, "Reserved: "); len += srsran_re_pattern_list_info(&cfg->rvd_re, &str[len], str_len - len); - len = srsran_print_check(str, str_len, len, "}"); - } - - if (q->evm_buffer != NULL) { - len = srsran_print_check(str, str_len, len, ",evm={", 0); - for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - if (grant->tb[i].enabled && !isnan(res[i].evm)) { - len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm); - if (i < SRSRAN_MAX_CODEWORDS - 1) { - if (grant->tb[i + 1].enabled) { - len = srsran_print_check(str, str_len, len, ",", 0); - } - } - } - } - len = srsran_print_check(str, str_len, len, "}", 0); - } - - if (res != NULL) { - len = srsran_print_check(str, str_len, len, ",crc={", 0); - for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - if (grant->tb[i].enabled) { - len = srsran_print_check(str, str_len, len, "%s", res[i].crc ? "OK" : "KO"); - if (i < SRSRAN_MAX_CODEWORDS - 1) { - if (grant->tb[i + 1].enabled) { - len = srsran_print_check(str, str_len, len, ",", 0); - } - } - } - } - len = srsran_print_check(str, str_len, len, "}", 0); } if (q->meas_time_en) { - len = srsran_print_check(str, str_len, len, ", t=%d us", q->meas_time_us); + len = srsran_print_check(str, str_len, len, " t=%d us", q->meas_time_us); } return len; diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 561514268..60050f532 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -961,7 +961,7 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q, for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { nof_cw += grant->tb[tb].enabled ? 1 : 0; - if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data[tb].payload, &data[0].uci, grant->rnti) < + if (pusch_nr_encode_codeword(q, cfg, &grant->tb[tb], data->payload[tb], &data[0].uci, grant->rnti) < SRSRAN_SUCCESS) { ERROR("Error encoding TB %d", tb); return SRSRAN_ERROR; @@ -1064,7 +1064,8 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q, // EVM if (q->evm_buffer != NULL) { - res->evm = srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); + res->evm[tb->cw_idx] = + srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits); } // Descrambling @@ -1133,7 +1134,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q, // Decode Ul-SCH if (tb->nof_bits != 0) { - if (srsran_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, res->payload, &res->crc) < SRSRAN_SUCCESS) { + if (srsran_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, &res->tb[tb->cw_idx]) < SRSRAN_SUCCESS) { ERROR("Error in SCH decoding"); return SRSRAN_ERROR; } @@ -1231,6 +1232,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q, static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, const srsran_sch_grant_nr_t* grant, + const srsran_pusch_res_nr_t* res, char* str, uint32_t str_len) { @@ -1267,7 +1269,7 @@ static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, // Append TB info for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) { - len += srsran_sch_nr_tb_info(&grant->tb[i], &str[len], str_len - len); + len += srsran_sch_nr_tb_info(&grant->tb[i], &res->tb[i], &str[len], str_len - len); } return len; @@ -1276,7 +1278,7 @@ static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg, uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q, const srsran_sch_cfg_nr_t* cfg, const srsran_sch_grant_nr_t* grant, - const srsran_pusch_res_nr_t res[SRSRAN_MAX_CODEWORDS], + const srsran_pusch_res_nr_t* res, char* str, uint32_t str_len) { @@ -1286,12 +1288,12 @@ uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q, return 0; } - len += srsran_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); + len += srsran_pusch_nr_grant_info(cfg, grant, res, &str[len], str_len - len); if (q->evm_buffer != NULL) { len = srsran_print_check(str, str_len, len, ",evm={", 0); for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - if (grant->tb[i].enabled && !isnan(res[i].evm)) { + if (grant->tb[i].enabled && !isnan(res->evm[i])) { len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm); if (i < SRSRAN_MAX_CODEWORDS - 1) { if (grant->tb[i + 1].enabled) { @@ -1312,7 +1314,7 @@ uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q, len = srsran_print_check(str, str_len, len, ",crc={", 0); for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { if (grant->tb[i].enabled) { - len = srsran_print_check(str, str_len, len, "%s", res[i].crc ? "OK" : "KO"); + len = srsran_print_check(str, str_len, len, "%s", res->tb[i].crc ? "OK" : "KO"); if (i < SRSRAN_MAX_CODEWORDS - 1) { if (grant->tb[i + 1].enabled) { len = srsran_print_check(str, str_len, len, ",", 0); @@ -1343,7 +1345,7 @@ uint32_t srsran_pusch_nr_tx_info(const srsran_pusch_nr_t* q, return 0; } - len += srsran_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len); + len += srsran_pusch_nr_grant_info(cfg, grant, NULL, &str[len], str_len - len); if (uci_value != NULL) { srsran_uci_data_nr_t uci_data = {}; diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 523fd4202..0a42f133f 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -509,19 +509,19 @@ static inline int sch_nr_encode(srsran_sch_nr_t* q, return SRSRAN_SUCCESS; } -int sch_nr_decode(srsran_sch_nr_t* q, - const srsran_sch_cfg_t* sch_cfg, - const srsran_sch_tb_t* tb, - int8_t* e_bits, - uint8_t* data, - bool* crc_ok) +static int sch_nr_decode(srsran_sch_nr_t* q, + const srsran_sch_cfg_t* sch_cfg, + const srsran_sch_tb_t* tb, + int8_t* e_bits, + srsran_sch_tb_res_nr_t* res) { // Pointer protection - if (!q || !sch_cfg || !tb || !data || !e_bits || !crc_ok) { + if (!q || !sch_cfg || !tb || !e_bits || !res) { return SRSRAN_ERROR_INVALID_INPUTS; } - int8_t* input_ptr = e_bits; + int8_t* input_ptr = e_bits; + uint32_t nof_iter_sum = 0; srsran_sch_nr_tb_info_t cfg = {}; if (srsran_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSRAN_SUCCESS) { @@ -599,27 +599,25 @@ int sch_nr_decode(srsran_sch_nr_t* q, return SRSRAN_ERROR; } - // Decode - srsran_ldpc_decoder_decode_c(decoder, rm_buffer, q->temp_cb, n_llr); - - // Compute CB CRC - uint32_t cb_len = cfg.Kp - cfg.L_cb; + // Select CB or TB early stop CRC + srsran_crc_t* crc = (cfg.L_tb == 16) ? &q->crc_tb_16 : &q->crc_tb_24; if (cfg.L_cb) { - uint8_t* ptr = q->temp_cb + cb_len; - uint32_t checksum1 = srsran_crc_checksum(&q->crc_cb, q->temp_cb, (int)cb_len); - uint32_t checksum2 = srsran_bit_pack(&ptr, cfg.L_cb); - tb->softbuffer.rx->cb_crc[r] = (checksum1 == checksum2); - - SCH_INFO_RX("CB %d/%d: CRC={%06x, %06x} ... %s", - r, - cfg.C, - checksum1, - checksum2, - tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO"); - } else { - tb->softbuffer.rx->cb_crc[r] = true; + crc = &q->crc_cb; } + // Decode + int n_iter = srsran_ldpc_decoder_decode_crc_c(decoder, rm_buffer, q->temp_cb, n_llr, crc); + if (n_iter < SRSRAN_SUCCESS) { + ERROR("Error decoding CB"); + return SRSRAN_ERROR; + } + nof_iter_sum += ((n_iter == 0) ? decoder->max_nof_iter : (uint32_t)n_iter); + + // Compute CB CRC only if LDPC decoder reached the end + uint32_t cb_len = cfg.Kp - cfg.L_cb; + tb->softbuffer.rx->cb_crc[r] = (n_iter != 0); + SCH_INFO_RX("CB %d/%d CRC=%s", r, cfg.C, tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO"); + // Pack and count CRC OK only if CRC is match if (tb->softbuffer.rx->cb_crc[r]) { srsran_bit_pack_vector(q->temp_cb, tb->softbuffer.rx->data[r], cb_len); @@ -629,51 +627,64 @@ int sch_nr_decode(srsran_sch_nr_t* q, input_ptr += E; } - // All CB are decoded - if (cb_ok == cfg.C) { - uint32_t checksum2 = 0; - uint8_t* output_ptr = data; + // Not all CB are decoded, skip TB union and CRC check + if (cb_ok != cfg.C) { + return SRSRAN_SUCCESS; + } - for (uint32_t r = 0; r < cfg.C; r++) { - uint32_t cb_len = cfg.Kp - cfg.L_cb; + uint32_t checksum2 = 0; + uint8_t* output_ptr = res->payload; - // Subtract TB CRC from the last code block - if (r == cfg.C - 1) { - cb_len -= cfg.L_tb; - } + for (uint32_t r = 0; r < cfg.C; r++) { + uint32_t cb_len = cfg.Kp - cfg.L_cb; - srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8); - output_ptr += cb_len / 8; + // Subtract TB CRC from the last code block + if (r == cfg.C - 1) { + cb_len -= cfg.L_tb; + } - if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { - DEBUG("CB %d:", r); - srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8); - } - if (r == cfg.C - 1) { - uint8_t tb_crc_unpacked[24] = {}; - uint8_t* tb_crc_unpacked_ptr = tb_crc_unpacked; - srsran_bit_unpack_vector(&tb->softbuffer.rx->data[r][cb_len / 8], tb_crc_unpacked, cfg.L_tb); - checksum2 = srsran_bit_pack(&tb_crc_unpacked_ptr, cfg.L_tb); - } + // Append CB + srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8); + output_ptr += cb_len / 8; + + // CB Debug trace + if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { + DEBUG("CB %d/%d:", r, cfg.C); + srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8); } - // Check if TB is all zeros - bool all_zeros = true; - for (uint32_t i = 0; i < tb->tbs / 8 && all_zeros; i++) { - all_zeros = (data[i] == 0); + // Compute TB CRC for last block + if (cfg.C > 1 && r == cfg.C - 1) { + uint8_t tb_crc_unpacked[24] = {}; + uint8_t* tb_crc_unpacked_ptr = tb_crc_unpacked; + srsran_bit_unpack_vector(&tb->softbuffer.rx->data[r][cb_len / 8], tb_crc_unpacked, cfg.L_tb); + checksum2 = srsran_bit_pack(&tb_crc_unpacked_ptr, cfg.L_tb); } + } - // Calculate TB CRC from packed data - uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, data, tb->tbs); - *crc_ok = (checksum1 == checksum2 && !all_zeros); + // Check if TB is all zeros + bool all_zeros = true; + for (uint32_t i = 0; i < tb->tbs / 8 && all_zeros; i++) { + all_zeros = (res->payload[i] == 0); + } - SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2); - if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { - DEBUG("Decode: "); - srsran_vec_fprint_byte(stdout, data, tb->tbs / 8); - } + // Calculate TB CRC from packed data + if (cfg.C == 1) { + res->crc = !all_zeros; + SCH_INFO_RX("TB: TBS=%d; CRC=%s", tb->tbs, tb->softbuffer.rx->cb_crc[0] ? "OK" : "KO"); } else { - *crc_ok = false; + // More than one + uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, res->payload, tb->tbs); + res->crc = (checksum1 == checksum2 && !all_zeros); + SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2); + } + + // Set average number of iterations + res->avg_iter = (float)nof_iter_sum / (float)cfg.C; + + if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) { + DEBUG("Decode: "); + srsran_vec_fprint_byte(stdout, res->payload, tb->tbs / 8); } return SRSRAN_SUCCESS; @@ -692,10 +703,9 @@ int srsran_dlsch_nr_decode(srsran_sch_nr_t* q, const srsran_sch_cfg_t* sch_cfg, const srsran_sch_tb_t* tb, int8_t* e_bits, - uint8_t* data, - bool* crc_ok) + srsran_sch_tb_res_nr_t* res) { - return sch_nr_decode(q, sch_cfg, tb, e_bits, data, crc_ok); + return sch_nr_decode(q, sch_cfg, tb, e_bits, res); } int srsran_ulsch_nr_encode(srsran_sch_nr_t* q, @@ -711,30 +721,33 @@ int srsran_ulsch_nr_decode(srsran_sch_nr_t* q, const srsran_sch_cfg_t* sch_cfg, const srsran_sch_tb_t* tb, int8_t* e_bits, - uint8_t* data, - bool* crc_ok) + srsran_sch_tb_res_nr_t* res) { - return sch_nr_decode(q, sch_cfg, tb, e_bits, data, crc_ok); + return sch_nr_decode(q, sch_cfg, tb, e_bits, res); } -int srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, char* str, uint32_t str_len) +int srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, const srsran_sch_tb_res_nr_t* res, char* str, uint32_t str_len) { int len = 0; if (tb->enabled) { - len += srsran_print_check(str, - str_len, - len, - "CW0: mod=%s Nl=%d tbs=%d R=%.3f rv=%d Nre=%d Nbit=%d cw=%d", - srsran_mod_string(tb->mod), - tb->N_L, - tb->tbs / 8, - tb->R, - tb->rv, - tb->nof_re, - tb->nof_bits, - tb->cw_idx); + len = srsran_print_check(str, + str_len, + len, + "CW%d: mod=%s Nl=%d tbs=%d R=%.3f rv=%d Nre=%d Nbit=%d ", + tb->cw_idx, + srsran_mod_string(tb->mod), + tb->N_L, + tb->tbs / 8, + tb->R, + tb->rv, + tb->nof_re, + tb->nof_bits); + + if (res != NULL) { + len = srsran_print_check(str, str_len, len, "CRC=%s iter=%.1f ", res->crc ? "OK" : "KO", res->avg_iter); + } } return len; -} +} \ No newline at end of file diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index 42a58b169..a644f8768 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -75,12 +75,12 @@ int parse_args(int argc, char** argv) int main(int argc, char** argv) { - int ret = SRSRAN_ERROR; - srsran_pdsch_nr_t pdsch_tx = {}; - srsran_pdsch_nr_t pdsch_rx = {}; - srsran_chest_dl_res_t chest = {}; - srsran_pdsch_res_nr_t pdsch_res[SRSRAN_MAX_TB] = {}; - srsran_random_t rand_gen = srsran_random_init(1234); + int ret = SRSRAN_ERROR; + srsran_pdsch_nr_t pdsch_tx = {}; + srsran_pdsch_nr_t pdsch_rx = {}; + srsran_chest_dl_res_t chest = {}; + srsran_pdsch_res_nr_t pdsch_res = {}; + srsran_random_t rand_gen = srsran_random_init(1234); uint8_t* data_tx[SRSRAN_MAX_TB] = {}; uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {}; @@ -133,7 +133,7 @@ int main(int argc, char** argv) goto clean_exit; } - pdsch_res[i].payload = data_rx[i]; + pdsch_res.tb[i].payload = data_rx[i]; } srsran_softbuffer_tx_t softbuffer_tx = {}; @@ -224,14 +224,14 @@ int main(int argc, char** argv) } chest.nof_re = pdsch_cfg.grant.tb->nof_re; - if (srsran_pdsch_nr_decode(&pdsch_rx, &pdsch_cfg, &pdsch_cfg.grant, &chest, sf_symbols, pdsch_res) < + if (srsran_pdsch_nr_decode(&pdsch_rx, &pdsch_cfg, &pdsch_cfg.grant, &chest, sf_symbols, &pdsch_res) < SRSRAN_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } - if (pdsch_res->evm > 0.001f) { - ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm); + if (pdsch_res.evm[0] > 0.001f) { + ERROR("Error PDSCH EVM is too high %f", pdsch_res.evm[0]); goto clean_exit; } @@ -256,7 +256,7 @@ int main(int argc, char** argv) goto clean_exit; } - if (!pdsch_res[0].crc) { + if (!pdsch_res.tb[0].crc) { ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs); goto clean_exit; } @@ -270,7 +270,7 @@ int main(int argc, char** argv) goto clean_exit; } - INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs, pdsch_res[0].evm); + INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs, pdsch_res.evm[0]); } } diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index 65cff977a..9a0fd39d4 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -90,8 +90,8 @@ int main(int argc, char** argv) srsran_chest_dl_res_t chest = {}; srsran_random_t rand_gen = srsran_random_init(1234); - srsran_pusch_data_nr_t data_tx[SRSRAN_MAX_TB] = {}; - srsran_pusch_res_nr_t data_rx[SRSRAN_MAX_CODEWORDS] = {}; + srsran_pusch_data_nr_t data_tx = {}; + srsran_pusch_res_nr_t data_rx = {}; cf_t* sf_symbols[SRSRAN_MAX_LAYERS_NR] = {}; // Set default PUSCH configuration @@ -134,9 +134,9 @@ int main(int argc, char** argv) } for (uint32_t i = 0; i < pusch_tx.max_cw; i++) { - data_tx[i].payload = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); - data_rx[i].payload = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); - if (data_tx[i].payload == NULL || data_rx[i].payload == NULL) { + data_tx.payload[i] = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); + data_rx.tb[i].payload = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); + if (data_tx.payload[i] == NULL || data_rx.tb[i].payload == NULL) { ERROR("Error malloc"); goto clean_exit; } @@ -212,12 +212,12 @@ int main(int argc, char** argv) // Generate SCH payload for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { // Skip TB if no allocated - if (data_tx[tb].payload == NULL) { + if (data_tx.payload[tb] == NULL) { continue; } for (uint32_t i = 0; i < pusch_cfg.grant.tb[tb].tbs; i++) { - data_tx[tb].payload[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); + data_tx.payload[tb][i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); } pusch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx; } @@ -226,7 +226,7 @@ int main(int argc, char** argv) if (nof_ack_bits > 0) { pusch_cfg.uci.o_ack = nof_ack_bits; for (uint32_t i = 0; i < nof_ack_bits; i++) { - data_tx->uci.ack[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); + data_tx.uci.ack[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); } } @@ -237,15 +237,15 @@ int main(int argc, char** argv) pusch_cfg.uci.csi[0].quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE; pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits; pusch_cfg.uci.nof_csi = 1; - data_tx->uci.csi[0].none = csi_report_tx; + data_tx.uci.csi[0].none = csi_report_tx; for (uint32_t i = 0; i < nof_csi_bits; i++) { csi_report_tx[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); } - data_rx->uci.csi[0].none = csi_report_rx; + data_rx.uci.csi[0].none = csi_report_rx; } - if (srsran_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_cfg.grant, data_tx, sf_symbols) < SRSRAN_SUCCESS) { + if (srsran_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_cfg.grant, &data_tx, sf_symbols) < SRSRAN_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } @@ -260,14 +260,14 @@ int main(int argc, char** argv) } chest.nof_re = pusch_cfg.grant.tb->nof_re; - if (srsran_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &chest, sf_symbols, data_rx) < + if (srsran_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &chest, sf_symbols, &data_rx) < SRSRAN_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } - if (data_rx[0].evm > 0.001f) { - ERROR("Error PUSCH EVM is too high %f", data_rx[0].evm); + if (data_rx.evm[0] > 0.001f) { + ERROR("Error PUSCH EVM is too high %f", data_rx.evm[0]); goto clean_exit; } @@ -293,24 +293,24 @@ int main(int argc, char** argv) } // Validate UL-SCH CRC check - if (!data_rx[0].crc) { + if (!data_rx.tb[0].crc) { ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_cfg.grant.tb[0].tbs); goto clean_exit; } // Validate UL-SCH payload - if (memcmp(data_tx[0].payload, data_rx[0].payload, pusch_cfg.grant.tb[0].tbs / 8) != 0) { + if (memcmp(data_tx.payload[0], data_rx.tb[0].payload, pusch_cfg.grant.tb[0].tbs / 8) != 0) { ERROR("Failed to match Tx/Rx data; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_cfg.grant.tb[0].tbs); printf("Tx data: "); - srsran_vec_fprint_byte(stdout, data_tx[0].payload, pusch_cfg.grant.tb[0].tbs / 8); + srsran_vec_fprint_byte(stdout, data_tx.payload[0], pusch_cfg.grant.tb[0].tbs / 8); printf("Rx data: "); - srsran_vec_fprint_byte(stdout, data_tx[0].payload, pusch_cfg.grant.tb[0].tbs / 8); + srsran_vec_fprint_byte(stdout, data_tx.payload[0], pusch_cfg.grant.tb[0].tbs / 8); goto clean_exit; } // Validate UCI is decoded successfully if (nof_ack_bits > 0 || nof_csi_bits > 0) { - if (!data_rx[0].uci.valid) { + if (!data_rx.uci.valid) { ERROR("UCI data was not decoded ok"); goto clean_exit; } @@ -318,29 +318,29 @@ int main(int argc, char** argv) // Validate HARQ-ACK is decoded successfully if (nof_ack_bits > 0) { - if (memcmp(data_tx[0].uci.ack, data_rx[0].uci.ack, nof_ack_bits) != 0) { + if (memcmp(data_tx.uci.ack, data_rx.uci.ack, nof_ack_bits) != 0) { ERROR("UCI HARQ-ACK bits are unmatched"); printf("Tx data: "); - srsran_vec_fprint_byte(stdout, data_tx[0].uci.ack, nof_ack_bits); + srsran_vec_fprint_byte(stdout, data_tx.uci.ack, nof_ack_bits); printf("Rx data: "); - srsran_vec_fprint_byte(stdout, data_rx[0].uci.ack, nof_ack_bits); + srsran_vec_fprint_byte(stdout, data_rx.uci.ack, nof_ack_bits); goto clean_exit; } } // Validate CSI is decoded successfully if (nof_csi_bits > 0) { - if (memcmp(data_tx[0].uci.csi[0].none, data_rx[0].uci.csi[0].none, nof_csi_bits) != 0) { + if (memcmp(data_tx.uci.csi[0].none, data_rx.uci.csi[0].none, nof_csi_bits) != 0) { ERROR("UCI CSI bits are unmatched"); printf("Tx data: "); - srsran_vec_fprint_byte(stdout, data_tx[0].uci.csi[0].none, nof_csi_bits); + srsran_vec_fprint_byte(stdout, data_tx.uci.csi[0].none, nof_csi_bits); printf("Rx data: "); - srsran_vec_fprint_byte(stdout, data_rx[0].uci.csi[0].none, nof_csi_bits); + srsran_vec_fprint_byte(stdout, data_rx.uci.csi[0].none, nof_csi_bits); goto clean_exit; } } - printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_cfg.grant.tb[0].tbs, data_rx[0].evm); + printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_cfg.grant.tb[0].tbs, data_rx.evm[0]); } } @@ -352,11 +352,11 @@ clean_exit: srsran_pusch_nr_free(&pusch_tx); srsran_pusch_nr_free(&pusch_rx); for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - if (data_tx[i].payload) { - free(data_tx[i].payload); + if (data_tx.payload[i]) { + free(data_tx.payload[i]); } - if (data_rx[i].payload) { - free(data_rx[i].payload); + if (data_rx.tb[i].payload) { + free(data_rx.tb[i].payload); } } for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) { diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index a3517a327..cc338a567 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -206,14 +206,15 @@ int main(int argc, char** argv) tb.softbuffer.rx = &softbuffer_rx; srsran_softbuffer_rx_reset(tb.softbuffer.rx); - bool crc = false; - if (srsran_dlsch_nr_decode(&sch_nr_rx, &pdsch_cfg.sch_cfg, &tb, llr, data_rx, &crc) < SRSRAN_SUCCESS) { + srsran_sch_tb_res_nr_t res = {}; + res.payload = data_rx; + if (srsran_dlsch_nr_decode(&sch_nr_rx, &pdsch_cfg.sch_cfg, &tb, llr, &res) < SRSRAN_SUCCESS) { ERROR("Error encoding"); goto clean_exit; } if (rv == 0) { - if (!crc) { + if (!res.crc) { ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, tb.tbs); goto clean_exit; } diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index 9439ce170..2e4db9fcf 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -585,7 +585,7 @@ int srsran_ue_dl_nr_pdsch_info(const srsran_ue_dl_nr_t* q, len += srsran_pdsch_nr_rx_info(&q->pdsch, cfg, &cfg->grant, res, &str[len], str_len - len); // Append channel estimator info - len = srsran_print_check(str, str_len, len, ",SNR=%+.1f", q->chest.snr_db); + len = srsran_print_check(str, str_len, len, "SNR=%+.1f", q->chest.snr_db); return len; } diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index f9214a2ca..4a90602ca 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -184,16 +184,16 @@ static int work_ue_dl(srsran_ue_dl_nr_t* ue_dl, srsran_slot_cfg_t* slot, srsran_ int main(int argc, char** argv) { - int ret = SRSRAN_ERROR; - srsran_enb_dl_nr_t enb_dl = {}; - srsran_ue_dl_nr_t ue_dl = {}; - srsran_pdsch_res_nr_t pdsch_res[SRSRAN_MAX_TB] = {}; - srsran_random_t rand_gen = srsran_random_init(1234); - srsran_slot_cfg_t slot = {}; - struct timeval t[3] = {}; - uint64_t pdsch_encode_us = 0; - uint64_t pdsch_decode_us = 0; - uint64_t nof_bits = 0; + int ret = SRSRAN_ERROR; + srsran_enb_dl_nr_t enb_dl = {}; + srsran_ue_dl_nr_t ue_dl = {}; + srsran_pdsch_res_nr_t pdsch_res = {}; + srsran_random_t rand_gen = srsran_random_init(1234); + srsran_slot_cfg_t slot = {}; + struct timeval t[3] = {}; + uint64_t pdsch_encode_us = 0; + uint64_t pdsch_decode_us = 0; + uint64_t nof_bits = 0; uint8_t* data_tx[SRSRAN_MAX_TB] = {}; uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {}; @@ -296,7 +296,7 @@ int main(int argc, char** argv) goto clean_exit; } - pdsch_res[i].payload = data_rx[i]; + pdsch_res.tb[i].payload = data_rx[i]; } srsran_softbuffer_tx_t softbuffer_tx = {}; @@ -418,7 +418,7 @@ int main(int argc, char** argv) } gettimeofday(&t[1], NULL); - if (work_ue_dl(&ue_dl, &slot, pdsch_res) < SRSRAN_SUCCESS) { + if (work_ue_dl(&ue_dl, &slot, &pdsch_res) < SRSRAN_SUCCESS) { ERROR("Error running UE DL"); goto clean_exit; } @@ -426,14 +426,14 @@ int main(int argc, char** argv) get_time_interval(t); pdsch_decode_us += (size_t)(t[0].tv_sec * 1e6 + t[0].tv_usec); - if (pdsch_res->evm > 0.02f) { - ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm); + if (pdsch_res.evm[0] > 0.02f) { + ERROR("Error PDSCH EVM is too high %f", pdsch_res.evm[0]); goto clean_exit; } // Check CRC only for RV=0 if (rv_idx == 0) { - if (!pdsch_res[0].crc) { + if (!pdsch_res.tb[0].crc) { ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs); goto clean_exit; } @@ -448,7 +448,7 @@ int main(int argc, char** argv) } } - INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs, pdsch_res[0].evm); + INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs, pdsch_res.evm[0]); // Count the Tx/Rx'd number of bits nof_bits += pdsch_cfg.grant.tb[0].tbs; diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 41e7a28f1..7b80e54da 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -253,12 +253,12 @@ bool cc_worker::work_dl() srsran_softbuffer_rx_reset(&softbuffer_rx); // Initialise PDSCH Result - std::array pdsch_res = {}; - pdsch_res[0].payload = data->msg; - pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx; + srsran_pdsch_res_nr_t pdsch_res = {}; + pdsch_res.tb[0].payload = data->msg; + pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx; // Decode actual PDSCH transmission - if (srsran_ue_dl_nr_decode_pdsch(&ue_dl, &dl_slot_cfg, &pdsch_cfg, pdsch_res.data()) < SRSRAN_SUCCESS) { + if (srsran_ue_dl_nr_decode_pdsch(&ue_dl, &dl_slot_cfg, &pdsch_cfg, &pdsch_res) < SRSRAN_SUCCESS) { ERROR("Error decoding PDSCH"); return false; } @@ -266,17 +266,17 @@ bool cc_worker::work_dl() // Logging if (logger.info.enabled()) { std::array str; - srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, pdsch_res.data(), str.data(), str.size()); - logger.info(pdsch_res[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d, %s", cc_idx, str.data()); + srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str.data(), str.size()); + logger.info(pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d, %s", cc_idx, str.data()); } // Enqueue PDSCH ACK information only if the RNTI is type C if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_c) { - phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res[0].crc); + phy->set_pending_ack(dl_slot_cfg.idx, ack_resource, pdsch_res.tb[0].crc); } // Notify MAC about PDSCH decoding result - if (pdsch_res[0].crc) { + if (pdsch_res.tb[0].crc) { // Prepare grant mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {}; mac_nr_grant.tb[0] = std::move(data); @@ -294,8 +294,8 @@ bool cc_worker::work_dl() // Generate DL metrics dl_metrics_t dl_m = {}; dl_m.mcs = pdsch_cfg.grant.tb[0].mcs; - dl_m.fec_iters = pdsch_res[0].fec_iters; - dl_m.evm = pdsch_res[0].evm; + dl_m.fec_iters = pdsch_res.tb[0].avg_iter; + dl_m.evm = pdsch_res.evm[0]; phy->set_dl_metrics(dl_m); // Generate Synch metrics @@ -386,7 +386,7 @@ bool cc_worker::work_ul() // Setup data for encoding srsran_pusch_data_nr_t data = {}; - data.payload = ul_action.tb.payload->msg; + data.payload[0] = ul_action.tb.payload->msg; data.uci = uci_data.value; // Encode PUSCH transmission