mirror of https://github.com/PentHertz/srsLTE.git
Refactored PDSCH/PUSCH decoder for LDPC early stopping
This commit is contained in:
parent
6c5e28bc19
commit
e4e3456d76
|
@ -150,4 +150,24 @@ srsran_ldpc_decoder_decode_s(srsran_ldpc_decoder_t* q, const int16_t* llrs, uint
|
||||||
SRSRAN_API int
|
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);
|
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
|
#endif // SRSRAN_LDPCDECODER_H
|
||||||
|
|
|
@ -64,13 +64,11 @@ typedef struct SRSRAN_API {
|
||||||
} srsran_pdsch_nr_t;
|
} srsran_pdsch_nr_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @brief Groups NR-PDSCH data for reception
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* payload;
|
srsran_sch_tb_res_nr_t tb[SRSRAN_MAX_TB]; ///< SCH payload
|
||||||
bool crc;
|
float evm[SRSRAN_MAX_CODEWORDS]; ///< EVM measurement if configured through arguments
|
||||||
float evm;
|
|
||||||
uint32_t fec_iters;
|
|
||||||
} srsran_pdsch_res_nr_t;
|
} 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);
|
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,
|
const srsran_sch_grant_nr_t* grant,
|
||||||
srsran_chest_dl_res_t* channel,
|
srsran_chest_dl_res_t* channel,
|
||||||
cf_t* sf_symbols[SRSRAN_MAX_PORTS],
|
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,
|
SRSRAN_API uint32_t srsran_pdsch_nr_rx_info(const srsran_pdsch_nr_t* q,
|
||||||
const srsran_sch_cfg_nr_t* cfg,
|
const srsran_sch_cfg_nr_t* cfg,
|
||||||
|
|
|
@ -70,18 +70,17 @@ typedef struct SRSRAN_API {
|
||||||
* @brief Groups NR-PUSCH data for transmission
|
* @brief Groups NR-PUSCH data for transmission
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* payload; ///< SCH payload
|
uint8_t* payload[SRSRAN_MAX_TB]; ///< SCH payload
|
||||||
srsran_uci_value_nr_t uci; ///< UCI payload
|
srsran_uci_value_nr_t uci; ///< UCI payload
|
||||||
} srsran_pusch_data_nr_t;
|
} srsran_pusch_data_nr_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Groups NR-PUSCH data for reception
|
* @brief Groups NR-PUSCH data for reception
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* payload; ///< SCH payload
|
srsran_sch_tb_res_nr_t tb[SRSRAN_MAX_TB]; ///< SCH payload
|
||||||
srsran_uci_value_nr_t uci; ///< UCI payload
|
srsran_uci_value_nr_t uci; ///< UCI payload
|
||||||
bool crc; ///< CRC match
|
float evm[SRSRAN_MAX_CODEWORDS]; ///< EVM measurement if configured through arguments
|
||||||
float evm; ///< EVM measurement if configured through arguments
|
|
||||||
} srsran_pusch_res_nr_t;
|
} 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);
|
SRSRAN_API int srsran_pusch_nr_init_gnb(srsran_pusch_nr_t* q, const srsran_pusch_nr_args_t* args);
|
||||||
|
|
|
@ -32,6 +32,15 @@
|
||||||
#define SRSRAN_SCH_NR_MAX_NOF_CB_LDPC \
|
#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)
|
((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 {
|
typedef struct SRSRAN_API {
|
||||||
srsran_carrier_nr_t carrier;
|
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_cfg_t* sch_cfg,
|
||||||
const srsran_sch_tb_t* tb,
|
const srsran_sch_tb_t* tb,
|
||||||
int8_t* e_bits,
|
int8_t* e_bits,
|
||||||
uint8_t* data,
|
srsran_sch_tb_res_nr_t* res);
|
||||||
bool* crc_ok);
|
|
||||||
|
|
||||||
SRSRAN_API int srsran_ulsch_nr_encode(srsran_sch_nr_t* q,
|
SRSRAN_API int srsran_ulsch_nr_encode(srsran_sch_nr_t* q,
|
||||||
const srsran_sch_cfg_t* cfg,
|
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_cfg_t* sch_cfg,
|
||||||
const srsran_sch_tb_t* tb,
|
const srsran_sch_tb_t* tb,
|
||||||
int8_t* e_bits,
|
int8_t* e_bits,
|
||||||
uint8_t* data,
|
srsran_sch_tb_res_nr_t* res);
|
||||||
bool* crc_ok);
|
|
||||||
|
|
||||||
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
|
#endif // SRSRAN_SCH_NR_H
|
|
@ -73,11 +73,24 @@
|
||||||
update_ldpc_check_to_var_##SUFFIX(q->ptr, i_layer, this_pcm, these_var_indices); \
|
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); \
|
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; \
|
return q->max_nof_iter; \
|
||||||
}
|
}
|
||||||
#define LDPC_DECODER_TEMPLATE_FLOOD(LLR_TYPE, SUFFIX) \
|
#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);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -462,7 +462,8 @@ static inline int pdsch_nr_decode_codeword(srsran_pdsch_nr_t* q,
|
||||||
|
|
||||||
// EVM
|
// EVM
|
||||||
if (q->evm_buffer != NULL) {
|
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
|
// 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
|
// 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");
|
ERROR("Error in DL-SCH encoding");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -566,10 +567,12 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q,
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t srsran_pdsch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg,
|
static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q,
|
||||||
const srsran_sch_grant_nr_t* grant,
|
const srsran_sch_cfg_nr_t* cfg,
|
||||||
char* str,
|
const srsran_sch_grant_nr_t* grant,
|
||||||
uint32_t str_len)
|
const srsran_pdsch_res_nr_t* res,
|
||||||
|
char* str,
|
||||||
|
uint32_t str_len)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
len = srsran_print_check(str, str_len, len, "rnti=0x%x ", grant->rnti);
|
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
|
// Append TB info
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
|
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;
|
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,
|
uint32_t srsran_pdsch_nr_rx_info(const srsran_pdsch_nr_t* q,
|
||||||
const srsran_sch_cfg_nr_t* cfg,
|
const srsran_sch_cfg_nr_t* cfg,
|
||||||
const srsran_sch_grant_nr_t* grant,
|
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,
|
char* str,
|
||||||
uint32_t str_len)
|
uint32_t str_len)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
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) {
|
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_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) {
|
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;
|
return len;
|
||||||
|
|
|
@ -961,7 +961,7 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q,
|
||||||
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
||||||
nof_cw += grant->tb[tb].enabled ? 1 : 0;
|
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) {
|
SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding TB %d", tb);
|
ERROR("Error encoding TB %d", tb);
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
|
@ -1064,7 +1064,8 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
|
|
||||||
// EVM
|
// EVM
|
||||||
if (q->evm_buffer != NULL) {
|
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
|
// Descrambling
|
||||||
|
@ -1133,7 +1134,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
|
|
||||||
// Decode Ul-SCH
|
// Decode Ul-SCH
|
||||||
if (tb->nof_bits != 0) {
|
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");
|
ERROR("Error in SCH decoding");
|
||||||
return SRSRAN_ERROR;
|
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,
|
static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg,
|
||||||
const srsran_sch_grant_nr_t* grant,
|
const srsran_sch_grant_nr_t* grant,
|
||||||
|
const srsran_pusch_res_nr_t* res,
|
||||||
char* str,
|
char* str,
|
||||||
uint32_t str_len)
|
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
|
// Append TB info
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
|
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;
|
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,
|
uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q,
|
||||||
const srsran_sch_cfg_nr_t* cfg,
|
const srsran_sch_cfg_nr_t* cfg,
|
||||||
const srsran_sch_grant_nr_t* grant,
|
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,
|
char* str,
|
||||||
uint32_t str_len)
|
uint32_t str_len)
|
||||||
{
|
{
|
||||||
|
@ -1286,12 +1288,12 @@ uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q,
|
||||||
return 0;
|
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) {
|
if (q->evm_buffer != NULL) {
|
||||||
len = srsran_print_check(str, str_len, len, ",evm={", 0);
|
len = srsran_print_check(str, str_len, len, ",evm={", 0);
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
|
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);
|
len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm);
|
||||||
if (i < SRSRAN_MAX_CODEWORDS - 1) {
|
if (i < SRSRAN_MAX_CODEWORDS - 1) {
|
||||||
if (grant->tb[i + 1].enabled) {
|
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);
|
len = srsran_print_check(str, str_len, len, ",crc={", 0);
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
|
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
|
||||||
if (grant->tb[i].enabled) {
|
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 (i < SRSRAN_MAX_CODEWORDS - 1) {
|
||||||
if (grant->tb[i + 1].enabled) {
|
if (grant->tb[i + 1].enabled) {
|
||||||
len = srsran_print_check(str, str_len, len, ",", 0);
|
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;
|
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) {
|
if (uci_value != NULL) {
|
||||||
srsran_uci_data_nr_t uci_data = {};
|
srsran_uci_data_nr_t uci_data = {};
|
||||||
|
|
|
@ -509,19 +509,19 @@ static inline int sch_nr_encode(srsran_sch_nr_t* q,
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sch_nr_decode(srsran_sch_nr_t* q,
|
static int sch_nr_decode(srsran_sch_nr_t* q,
|
||||||
const srsran_sch_cfg_t* sch_cfg,
|
const srsran_sch_cfg_t* sch_cfg,
|
||||||
const srsran_sch_tb_t* tb,
|
const srsran_sch_tb_t* tb,
|
||||||
int8_t* e_bits,
|
int8_t* e_bits,
|
||||||
uint8_t* data,
|
srsran_sch_tb_res_nr_t* res)
|
||||||
bool* crc_ok)
|
|
||||||
{
|
{
|
||||||
// Pointer protection
|
// 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;
|
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 = {};
|
srsran_sch_nr_tb_info_t cfg = {};
|
||||||
if (srsran_sch_nr_fill_tb_info(&q->carrier, sch_cfg, tb, &cfg) < SRSRAN_SUCCESS) {
|
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;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode
|
// Select CB or TB early stop CRC
|
||||||
srsran_ldpc_decoder_decode_c(decoder, rm_buffer, q->temp_cb, n_llr);
|
srsran_crc_t* crc = (cfg.L_tb == 16) ? &q->crc_tb_16 : &q->crc_tb_24;
|
||||||
|
|
||||||
// Compute CB CRC
|
|
||||||
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
|
||||||
if (cfg.L_cb) {
|
if (cfg.L_cb) {
|
||||||
uint8_t* ptr = q->temp_cb + cb_len;
|
crc = &q->crc_cb;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// Pack and count CRC OK only if CRC is match
|
||||||
if (tb->softbuffer.rx->cb_crc[r]) {
|
if (tb->softbuffer.rx->cb_crc[r]) {
|
||||||
srsran_bit_pack_vector(q->temp_cb, tb->softbuffer.rx->data[r], cb_len);
|
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;
|
input_ptr += E;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All CB are decoded
|
// Not all CB are decoded, skip TB union and CRC check
|
||||||
if (cb_ok == cfg.C) {
|
if (cb_ok != cfg.C) {
|
||||||
uint32_t checksum2 = 0;
|
return SRSRAN_SUCCESS;
|
||||||
uint8_t* output_ptr = data;
|
}
|
||||||
|
|
||||||
for (uint32_t r = 0; r < cfg.C; r++) {
|
uint32_t checksum2 = 0;
|
||||||
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
uint8_t* output_ptr = res->payload;
|
||||||
|
|
||||||
// Subtract TB CRC from the last code block
|
for (uint32_t r = 0; r < cfg.C; r++) {
|
||||||
if (r == cfg.C - 1) {
|
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
||||||
cb_len -= cfg.L_tb;
|
|
||||||
}
|
|
||||||
|
|
||||||
srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8);
|
// Subtract TB CRC from the last code block
|
||||||
output_ptr += cb_len / 8;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if TB is all zeros
|
// Append CB
|
||||||
bool all_zeros = true;
|
srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8);
|
||||||
for (uint32_t i = 0; i < tb->tbs / 8 && all_zeros; i++) {
|
output_ptr += cb_len / 8;
|
||||||
all_zeros = (data[i] == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate TB CRC from packed data
|
// CB Debug trace
|
||||||
uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, data, tb->tbs);
|
|
||||||
*crc_ok = (checksum1 == checksum2 && !all_zeros);
|
|
||||||
|
|
||||||
SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2);
|
|
||||||
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("Decode: ");
|
DEBUG("CB %d/%d:", r, cfg.C);
|
||||||
srsran_vec_fprint_byte(stdout, data, tb->tbs / 8);
|
srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 {
|
} 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;
|
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_cfg_t* sch_cfg,
|
||||||
const srsran_sch_tb_t* tb,
|
const srsran_sch_tb_t* tb,
|
||||||
int8_t* e_bits,
|
int8_t* e_bits,
|
||||||
uint8_t* data,
|
srsran_sch_tb_res_nr_t* res)
|
||||||
bool* crc_ok)
|
|
||||||
{
|
{
|
||||||
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,
|
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_cfg_t* sch_cfg,
|
||||||
const srsran_sch_tb_t* tb,
|
const srsran_sch_tb_t* tb,
|
||||||
int8_t* e_bits,
|
int8_t* e_bits,
|
||||||
uint8_t* data,
|
srsran_sch_tb_res_nr_t* res)
|
||||||
bool* crc_ok)
|
|
||||||
{
|
{
|
||||||
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;
|
int len = 0;
|
||||||
|
|
||||||
if (tb->enabled) {
|
if (tb->enabled) {
|
||||||
len += srsran_print_check(str,
|
len = srsran_print_check(str,
|
||||||
str_len,
|
str_len,
|
||||||
len,
|
len,
|
||||||
"CW0: mod=%s Nl=%d tbs=%d R=%.3f rv=%d Nre=%d Nbit=%d cw=%d",
|
"CW%d: mod=%s Nl=%d tbs=%d R=%.3f rv=%d Nre=%d Nbit=%d ",
|
||||||
srsran_mod_string(tb->mod),
|
tb->cw_idx,
|
||||||
tb->N_L,
|
srsran_mod_string(tb->mod),
|
||||||
tb->tbs / 8,
|
tb->N_L,
|
||||||
tb->R,
|
tb->tbs / 8,
|
||||||
tb->rv,
|
tb->R,
|
||||||
tb->nof_re,
|
tb->rv,
|
||||||
tb->nof_bits,
|
tb->nof_re,
|
||||||
tb->cw_idx);
|
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;
|
return len;
|
||||||
}
|
}
|
|
@ -75,12 +75,12 @@ int parse_args(int argc, char** argv)
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int ret = SRSRAN_ERROR;
|
int ret = SRSRAN_ERROR;
|
||||||
srsran_pdsch_nr_t pdsch_tx = {};
|
srsran_pdsch_nr_t pdsch_tx = {};
|
||||||
srsran_pdsch_nr_t pdsch_rx = {};
|
srsran_pdsch_nr_t pdsch_rx = {};
|
||||||
srsran_chest_dl_res_t chest = {};
|
srsran_chest_dl_res_t chest = {};
|
||||||
srsran_pdsch_res_nr_t pdsch_res[SRSRAN_MAX_TB] = {};
|
srsran_pdsch_res_nr_t pdsch_res = {};
|
||||||
srsran_random_t rand_gen = srsran_random_init(1234);
|
srsran_random_t rand_gen = srsran_random_init(1234);
|
||||||
|
|
||||||
uint8_t* data_tx[SRSRAN_MAX_TB] = {};
|
uint8_t* data_tx[SRSRAN_MAX_TB] = {};
|
||||||
uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {};
|
uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {};
|
||||||
|
@ -133,7 +133,7 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdsch_res[i].payload = data_rx[i];
|
pdsch_res.tb[i].payload = data_rx[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
srsran_softbuffer_tx_t softbuffer_tx = {};
|
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;
|
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) {
|
SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdsch_res->evm > 0.001f) {
|
if (pdsch_res.evm[0] > 0.001f) {
|
||||||
ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm);
|
ERROR("Error PDSCH EVM is too high %f", pdsch_res.evm[0]);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
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);
|
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,8 +90,8 @@ int main(int argc, char** argv)
|
||||||
srsran_chest_dl_res_t chest = {};
|
srsran_chest_dl_res_t chest = {};
|
||||||
srsran_random_t rand_gen = srsran_random_init(1234);
|
srsran_random_t rand_gen = srsran_random_init(1234);
|
||||||
|
|
||||||
srsran_pusch_data_nr_t data_tx[SRSRAN_MAX_TB] = {};
|
srsran_pusch_data_nr_t data_tx = {};
|
||||||
srsran_pusch_res_nr_t data_rx[SRSRAN_MAX_CODEWORDS] = {};
|
srsran_pusch_res_nr_t data_rx = {};
|
||||||
cf_t* sf_symbols[SRSRAN_MAX_LAYERS_NR] = {};
|
cf_t* sf_symbols[SRSRAN_MAX_LAYERS_NR] = {};
|
||||||
|
|
||||||
// Set default PUSCH configuration
|
// 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++) {
|
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_tx.payload[i] = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR);
|
||||||
data_rx[i].payload = 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[i].payload == NULL || data_rx[i].payload == NULL) {
|
if (data_tx.payload[i] == NULL || data_rx.tb[i].payload == NULL) {
|
||||||
ERROR("Error malloc");
|
ERROR("Error malloc");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
@ -212,12 +212,12 @@ int main(int argc, char** argv)
|
||||||
// Generate SCH payload
|
// Generate SCH payload
|
||||||
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
||||||
// Skip TB if no allocated
|
// Skip TB if no allocated
|
||||||
if (data_tx[tb].payload == NULL) {
|
if (data_tx.payload[tb] == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pusch_cfg.grant.tb[tb].tbs; i++) {
|
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;
|
pusch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ int main(int argc, char** argv)
|
||||||
if (nof_ack_bits > 0) {
|
if (nof_ack_bits > 0) {
|
||||||
pusch_cfg.uci.o_ack = nof_ack_bits;
|
pusch_cfg.uci.o_ack = nof_ack_bits;
|
||||||
for (uint32_t i = 0; i < nof_ack_bits; i++) {
|
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].quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE;
|
||||||
pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits;
|
pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits;
|
||||||
pusch_cfg.uci.nof_csi = 1;
|
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++) {
|
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);
|
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");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
@ -260,14 +260,14 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
chest.nof_re = pusch_cfg.grant.tb->nof_re;
|
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) {
|
SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_rx[0].evm > 0.001f) {
|
if (data_rx.evm[0] > 0.001f) {
|
||||||
ERROR("Error PUSCH EVM is too high %f", data_rx[0].evm);
|
ERROR("Error PUSCH EVM is too high %f", data_rx.evm[0]);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,24 +293,24 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate UL-SCH CRC check
|
// 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);
|
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pusch_cfg.grant.tb[0].tbs);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate UL-SCH payload
|
// 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);
|
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: ");
|
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: ");
|
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;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate UCI is decoded successfully
|
// Validate UCI is decoded successfully
|
||||||
if (nof_ack_bits > 0 || nof_csi_bits > 0) {
|
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");
|
ERROR("UCI data was not decoded ok");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
@ -318,29 +318,29 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
// Validate HARQ-ACK is decoded successfully
|
// Validate HARQ-ACK is decoded successfully
|
||||||
if (nof_ack_bits > 0) {
|
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");
|
ERROR("UCI HARQ-ACK bits are unmatched");
|
||||||
printf("Tx data: ");
|
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: ");
|
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;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate CSI is decoded successfully
|
// Validate CSI is decoded successfully
|
||||||
if (nof_csi_bits > 0) {
|
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");
|
ERROR("UCI CSI bits are unmatched");
|
||||||
printf("Tx data: ");
|
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: ");
|
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;
|
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_tx);
|
||||||
srsran_pusch_nr_free(&pusch_rx);
|
srsran_pusch_nr_free(&pusch_rx);
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
|
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
|
||||||
if (data_tx[i].payload) {
|
if (data_tx.payload[i]) {
|
||||||
free(data_tx[i].payload);
|
free(data_tx.payload[i]);
|
||||||
}
|
}
|
||||||
if (data_rx[i].payload) {
|
if (data_rx.tb[i].payload) {
|
||||||
free(data_rx[i].payload);
|
free(data_rx.tb[i].payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
|
for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) {
|
||||||
|
|
|
@ -206,14 +206,15 @@ int main(int argc, char** argv)
|
||||||
tb.softbuffer.rx = &softbuffer_rx;
|
tb.softbuffer.rx = &softbuffer_rx;
|
||||||
srsran_softbuffer_rx_reset(tb.softbuffer.rx);
|
srsran_softbuffer_rx_reset(tb.softbuffer.rx);
|
||||||
|
|
||||||
bool crc = false;
|
srsran_sch_tb_res_nr_t res = {};
|
||||||
if (srsran_dlsch_nr_decode(&sch_nr_rx, &pdsch_cfg.sch_cfg, &tb, llr, data_rx, &crc) < SRSRAN_SUCCESS) {
|
res.payload = data_rx;
|
||||||
|
if (srsran_dlsch_nr_decode(&sch_nr_rx, &pdsch_cfg.sch_cfg, &tb, llr, &res) < SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding");
|
ERROR("Error encoding");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == 0) {
|
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);
|
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, tb.tbs);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
len += srsran_pdsch_nr_rx_info(&q->pdsch, cfg, &cfg->grant, res, &str[len], str_len - len);
|
||||||
|
|
||||||
// Append channel estimator info
|
// 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;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int ret = SRSRAN_ERROR;
|
int ret = SRSRAN_ERROR;
|
||||||
srsran_enb_dl_nr_t enb_dl = {};
|
srsran_enb_dl_nr_t enb_dl = {};
|
||||||
srsran_ue_dl_nr_t ue_dl = {};
|
srsran_ue_dl_nr_t ue_dl = {};
|
||||||
srsran_pdsch_res_nr_t pdsch_res[SRSRAN_MAX_TB] = {};
|
srsran_pdsch_res_nr_t pdsch_res = {};
|
||||||
srsran_random_t rand_gen = srsran_random_init(1234);
|
srsran_random_t rand_gen = srsran_random_init(1234);
|
||||||
srsran_slot_cfg_t slot = {};
|
srsran_slot_cfg_t slot = {};
|
||||||
struct timeval t[3] = {};
|
struct timeval t[3] = {};
|
||||||
uint64_t pdsch_encode_us = 0;
|
uint64_t pdsch_encode_us = 0;
|
||||||
uint64_t pdsch_decode_us = 0;
|
uint64_t pdsch_decode_us = 0;
|
||||||
uint64_t nof_bits = 0;
|
uint64_t nof_bits = 0;
|
||||||
|
|
||||||
uint8_t* data_tx[SRSRAN_MAX_TB] = {};
|
uint8_t* data_tx[SRSRAN_MAX_TB] = {};
|
||||||
uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {};
|
uint8_t* data_rx[SRSRAN_MAX_CODEWORDS] = {};
|
||||||
|
@ -296,7 +296,7 @@ int main(int argc, char** argv)
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdsch_res[i].payload = data_rx[i];
|
pdsch_res.tb[i].payload = data_rx[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
srsran_softbuffer_tx_t softbuffer_tx = {};
|
srsran_softbuffer_tx_t softbuffer_tx = {};
|
||||||
|
@ -418,7 +418,7 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
gettimeofday(&t[1], NULL);
|
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");
|
ERROR("Error running UE DL");
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
@ -426,14 +426,14 @@ int main(int argc, char** argv)
|
||||||
get_time_interval(t);
|
get_time_interval(t);
|
||||||
pdsch_decode_us += (size_t)(t[0].tv_sec * 1e6 + t[0].tv_usec);
|
pdsch_decode_us += (size_t)(t[0].tv_sec * 1e6 + t[0].tv_usec);
|
||||||
|
|
||||||
if (pdsch_res->evm > 0.02f) {
|
if (pdsch_res.evm[0] > 0.02f) {
|
||||||
ERROR("Error PDSCH EVM is too high %f", pdsch_res->evm);
|
ERROR("Error PDSCH EVM is too high %f", pdsch_res.evm[0]);
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check CRC only for RV=0
|
// Check CRC only for RV=0
|
||||||
if (rv_idx == 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);
|
ERROR("Failed to match CRC; n_prb=%d; mcs=%d; TBS=%d;", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs);
|
||||||
goto clean_exit;
|
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
|
// Count the Tx/Rx'd number of bits
|
||||||
nof_bits += pdsch_cfg.grant.tb[0].tbs;
|
nof_bits += pdsch_cfg.grant.tb[0].tbs;
|
||||||
|
|
|
@ -253,12 +253,12 @@ bool cc_worker::work_dl()
|
||||||
srsran_softbuffer_rx_reset(&softbuffer_rx);
|
srsran_softbuffer_rx_reset(&softbuffer_rx);
|
||||||
|
|
||||||
// Initialise PDSCH Result
|
// Initialise PDSCH Result
|
||||||
std::array<srsran_pdsch_res_nr_t, SRSRAN_MAX_CODEWORDS> pdsch_res = {};
|
srsran_pdsch_res_nr_t pdsch_res = {};
|
||||||
pdsch_res[0].payload = data->msg;
|
pdsch_res.tb[0].payload = data->msg;
|
||||||
pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx;
|
pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer_rx;
|
||||||
|
|
||||||
// Decode actual PDSCH transmission
|
// 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");
|
ERROR("Error decoding PDSCH");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -266,17 +266,17 @@ bool cc_worker::work_dl()
|
||||||
// Logging
|
// Logging
|
||||||
if (logger.info.enabled()) {
|
if (logger.info.enabled()) {
|
||||||
std::array<char, 512> str;
|
std::array<char, 512> str;
|
||||||
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, pdsch_res.data(), str.data(), str.size());
|
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, 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());
|
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
|
// Enqueue PDSCH ACK information only if the RNTI is type C
|
||||||
if (pdsch_cfg.grant.rnti_type == srsran_rnti_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
|
// Notify MAC about PDSCH decoding result
|
||||||
if (pdsch_res[0].crc) {
|
if (pdsch_res.tb[0].crc) {
|
||||||
// Prepare grant
|
// Prepare grant
|
||||||
mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {};
|
mac_interface_phy_nr::mac_nr_grant_dl_t mac_nr_grant = {};
|
||||||
mac_nr_grant.tb[0] = std::move(data);
|
mac_nr_grant.tb[0] = std::move(data);
|
||||||
|
@ -294,8 +294,8 @@ bool cc_worker::work_dl()
|
||||||
// Generate DL metrics
|
// Generate DL metrics
|
||||||
dl_metrics_t dl_m = {};
|
dl_metrics_t dl_m = {};
|
||||||
dl_m.mcs = pdsch_cfg.grant.tb[0].mcs;
|
dl_m.mcs = pdsch_cfg.grant.tb[0].mcs;
|
||||||
dl_m.fec_iters = pdsch_res[0].fec_iters;
|
dl_m.fec_iters = pdsch_res.tb[0].avg_iter;
|
||||||
dl_m.evm = pdsch_res[0].evm;
|
dl_m.evm = pdsch_res.evm[0];
|
||||||
phy->set_dl_metrics(dl_m);
|
phy->set_dl_metrics(dl_m);
|
||||||
|
|
||||||
// Generate Synch metrics
|
// Generate Synch metrics
|
||||||
|
@ -386,7 +386,7 @@ bool cc_worker::work_ul()
|
||||||
|
|
||||||
// Setup data for encoding
|
// Setup data for encoding
|
||||||
srsran_pusch_data_nr_t data = {};
|
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;
|
data.uci = uci_data.value;
|
||||||
|
|
||||||
// Encode PUSCH transmission
|
// Encode PUSCH transmission
|
||||||
|
|
Loading…
Reference in New Issue