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_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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -70,7 +70,7 @@ typedef struct SRSRAN_API {
|
|||
* @brief Groups NR-PUSCH data for transmission
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t* payload; ///< SCH payload
|
||||
uint8_t* payload[SRSRAN_MAX_TB]; ///< SCH payload
|
||||
srsran_uci_value_nr_t uci; ///< UCI payload
|
||||
} srsran_pusch_data_nr_t;
|
||||
|
||||
|
@ -78,10 +78,9 @@ typedef struct {
|
|||
* @brief Groups NR-PUSCH data for reception
|
||||
*/
|
||||
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
|
||||
bool crc; ///< CRC match
|
||||
float evm; ///< EVM measurement if configured through arguments
|
||||
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);
|
||||
|
|
|
@ -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
|
|
@ -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; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* 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);
|
||||
}
|
||||
|
|
|
@ -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,8 +567,10 @@ 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,
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
uint8_t* data,
|
||||
bool* crc_ok)
|
||||
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;
|
||||
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,10 +627,13 @@ int sch_nr_decode(srsran_sch_nr_t* q,
|
|||
input_ptr += E;
|
||||
}
|
||||
|
||||
// All CB are decoded
|
||||
if (cb_ok == cfg.C) {
|
||||
// Not all CB are decoded, skip TB union and CRC check
|
||||
if (cb_ok != cfg.C) {
|
||||
return SRSRAN_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t checksum2 = 0;
|
||||
uint8_t* output_ptr = data;
|
||||
uint8_t* output_ptr = res->payload;
|
||||
|
||||
for (uint32_t r = 0; r < cfg.C; r++) {
|
||||
uint32_t cb_len = cfg.Kp - cfg.L_cb;
|
||||
|
@ -642,14 +643,18 @@ int sch_nr_decode(srsran_sch_nr_t* q,
|
|||
cb_len -= 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:", r);
|
||||
DEBUG("CB %d/%d:", r, cfg.C);
|
||||
srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8);
|
||||
}
|
||||
if (r == cfg.C - 1) {
|
||||
|
||||
// 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);
|
||||
|
@ -660,20 +665,26 @@ int sch_nr_decode(srsran_sch_nr_t* q,
|
|||
// 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);
|
||||
all_zeros = (res->payload[i] == 0);
|
||||
}
|
||||
|
||||
// Calculate TB CRC from packed data
|
||||
uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, data, tb->tbs);
|
||||
*crc_ok = (checksum1 == checksum2 && !all_zeros);
|
||||
|
||||
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 {
|
||||
// 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, data, tb->tbs / 8);
|
||||
}
|
||||
} else {
|
||||
*crc_ok = false;
|
||||
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,29 +721,32 @@ 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,
|
||||
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",
|
||||
"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,
|
||||
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;
|
||||
|
|
|
@ -79,7 +79,7 @@ int main(int argc, char** argv)
|
|||
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_pdsch_res_nr_t pdsch_res = {};
|
||||
srsran_random_t rand_gen = srsran_random_init(1234);
|
||||
|
||||
uint8_t* data_tx[SRSRAN_MAX_TB] = {};
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ 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_pdsch_res_nr_t pdsch_res = {};
|
||||
srsran_random_t rand_gen = srsran_random_init(1234);
|
||||
srsran_slot_cfg_t slot = {};
|
||||
struct timeval t[3] = {};
|
||||
|
@ -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;
|
||||
|
|
|
@ -253,12 +253,12 @@ bool cc_worker::work_dl()
|
|||
srsran_softbuffer_rx_reset(&softbuffer_rx);
|
||||
|
||||
// Initialise PDSCH Result
|
||||
std::array<srsran_pdsch_res_nr_t, SRSRAN_MAX_CODEWORDS> pdsch_res = {};
|
||||
pdsch_res[0].payload = data->msg;
|
||||
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<char, 512> 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
|
||||
|
|
Loading…
Reference in New Issue