mirror of https://github.com/PentHertz/srsLTE.git
Multiple NR-PUSCH fixes
This commit is contained in:
parent
7e06e789d5
commit
abfc1da921
|
@ -164,6 +164,11 @@ typedef struct {
|
||||||
uint32_t csi1_index2; ///< Use for more than 11 CSI bits. Set to 13 if absent.
|
uint32_t csi1_index2; ///< Use for more than 11 CSI bits. Set to 13 if absent.
|
||||||
uint32_t csi2_index1; ///< Use for up to 11 CSI bits. Set to 13 if absent.
|
uint32_t csi2_index1; ///< Use for up to 11 CSI bits. Set to 13 if absent.
|
||||||
uint32_t csi2_index2; ///< Use for more than 11 CSI bits. Set to 13 if absent.
|
uint32_t csi2_index2; ///< Use for more than 11 CSI bits. Set to 13 if absent.
|
||||||
|
|
||||||
|
/// Fix values for testing purposes
|
||||||
|
float fix_ack; ///< Set to a non-zero value for fixing a beta offset value
|
||||||
|
float fix_csi1;
|
||||||
|
float fix_csi2;
|
||||||
} srsran_beta_offsets_t;
|
} srsran_beta_offsets_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,13 +243,11 @@ typedef struct SRSRAN_API {
|
||||||
/// PUSCH only parameters
|
/// PUSCH only parameters
|
||||||
srsran_uci_cfg_nr_t uci; ///< Uplink Control Information configuration
|
srsran_uci_cfg_nr_t uci; ///< Uplink Control Information configuration
|
||||||
bool enable_transform_precoder;
|
bool enable_transform_precoder;
|
||||||
float beta_harq_ack_offset;
|
|
||||||
float beta_csi_part1_offset;
|
|
||||||
float beta_csi_part2_offset;
|
|
||||||
float scaling;
|
|
||||||
bool freq_hopping_enabled;
|
bool freq_hopping_enabled;
|
||||||
} srsran_sch_cfg_nr_t;
|
} srsran_sch_cfg_nr_t;
|
||||||
|
|
||||||
SRSRAN_API uint32_t srsran_phch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len);
|
SRSRAN_API uint32_t srsran_sch_cfg_nr_nof_re(const srsran_sch_cfg_nr_t* sch_cfg);
|
||||||
|
|
||||||
|
SRSRAN_API uint32_t srsran_sch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len);
|
||||||
|
|
||||||
#endif // SRSRAN_PHCH_CFG_NR_H
|
#endif // SRSRAN_PHCH_CFG_NR_H
|
||||||
|
|
|
@ -51,7 +51,6 @@ typedef struct SRSRAN_API {
|
||||||
bool meas_time_en;
|
bool meas_time_en;
|
||||||
uint32_t meas_time_us;
|
uint32_t meas_time_us;
|
||||||
srsran_re_pattern_t dmrs_re_pattern;
|
srsran_re_pattern_t dmrs_re_pattern;
|
||||||
srsran_uci_cfg_nr_t uci_cfg; ///< Internal UCI bits configuration
|
|
||||||
uint8_t* g_ulsch; ///< Temporal Encoded UL-SCH data
|
uint8_t* g_ulsch; ///< Temporal Encoded UL-SCH data
|
||||||
uint8_t* g_ack; ///< Temporal Encoded HARQ-ACK bits
|
uint8_t* g_ack; ///< Temporal Encoded HARQ-ACK bits
|
||||||
uint8_t* g_csi1; ///< Temporal Encoded CSI part 1 bits
|
uint8_t* g_csi1; ///< Temporal Encoded CSI part 1 bits
|
||||||
|
|
|
@ -128,12 +128,14 @@ SRSRAN_API int srsran_ra_ul_dci_to_grant_nr(const srsran_carrier_nr_t* carrie
|
||||||
*
|
*
|
||||||
* @remark Implement procedure described in TS 38.213 9.3 UCI reporting in physical uplink shared channel
|
* @remark Implement procedure described in TS 38.213 9.3 UCI reporting in physical uplink shared channel
|
||||||
*
|
*
|
||||||
|
* @param carrier Carrier information struct
|
||||||
* @param pusch_hl_cfg PUSCH configuration provided by higher layers
|
* @param pusch_hl_cfg PUSCH configuration provided by higher layers
|
||||||
* @param uci_cfg Uplink Control Information configuration for this PUSCH transmission
|
* @param uci_cfg Uplink Control Information configuration for this PUSCH transmission
|
||||||
* @param pusch_cfg PUSCH configuration after applying the procedure
|
* @param pusch_cfg PUSCH configuration after applying the procedure
|
||||||
* @return SRSRAN_SUCCESS if the procedure is successful, SRSRAN_ERROR code otherwise
|
* @return SRSRAN_SUCCESS if the procedure is successful, SRSRAN_ERROR code otherwise
|
||||||
*/
|
*/
|
||||||
SRSRAN_API int srsran_ra_ul_set_grant_uci_nr(const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg,
|
SRSRAN_API int srsran_ra_ul_set_grant_uci_nr(const srsran_carrier_nr_t* carrier,
|
||||||
|
const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg,
|
||||||
const srsran_uci_cfg_nr_t* uci_cfg,
|
const srsran_uci_cfg_nr_t* uci_cfg,
|
||||||
srsran_sch_cfg_nr_t* pusch_cfg);
|
srsran_sch_cfg_nr_t* pusch_cfg);
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ typedef struct SRSRAN_API {
|
||||||
int rv; ///< Redundancy version
|
int rv; ///< Redundancy version
|
||||||
int ndi; ///< New Data Indicator
|
int ndi; ///< New Data Indicator
|
||||||
int pid; ///< HARQ Process ID
|
int pid; ///< HARQ Process ID
|
||||||
uint32_t nof_re; ///< Number of available resource elements to send, known as N_RE
|
uint32_t nof_re; ///< Number of available resource elements to transmit ULSCH (data) and UCI (control)
|
||||||
uint32_t nof_bits; ///< Number of available bits to send, known as G
|
uint32_t nof_bits; ///< Number of available bits to send ULSCH
|
||||||
uint32_t cw_idx;
|
uint32_t cw_idx;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ typedef struct {
|
||||||
float alpha; ///< Higher layer parameter scaling
|
float alpha; ///< Higher layer parameter scaling
|
||||||
float beta_harq_ack_offset;
|
float beta_harq_ack_offset;
|
||||||
float beta_csi1_offset;
|
float beta_csi1_offset;
|
||||||
|
float beta_csi2_offset;
|
||||||
uint32_t nof_re;
|
uint32_t nof_re;
|
||||||
bool csi_part2_present;
|
bool csi_part2_present;
|
||||||
} srsran_uci_nr_pusch_cfg_t;
|
} srsran_uci_nr_pusch_cfg_t;
|
||||||
|
|
|
@ -216,28 +216,26 @@ static uint32_t phch_cfg_rvd_to_str(const srsran_re_pattern_list_t* pattern_list
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t phch_cfg_uci_to_str(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len)
|
static uint32_t phch_cfg_uci_to_str(const srsran_uci_cfg_nr_t* uci, char* str, uint32_t str_len)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
|
|
||||||
if (srsran_uci_nr_total_bits(&sch_cfg->uci) == 0) {
|
if (srsran_uci_nr_total_bits(uci) == 0) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = srsran_print_check(str, str_len, len, " UCI:\n", sch_cfg->scaling);
|
len = srsran_print_check(str, str_len, len, " UCI:\n");
|
||||||
len = srsran_print_check(str, str_len, len, " scaling=%.2f\n", sch_cfg->scaling);
|
len = srsran_print_check(str, str_len, len, " alpha=%.2f\n", uci->pusch.alpha);
|
||||||
len = srsran_print_check(str, str_len, len, " beta_csi_part1_offset=%.2f\n", sch_cfg->beta_csi_part1_offset);
|
len = srsran_print_check(str, str_len, len, " beta_harq_ack_offset=%.2f\n", uci->pusch.beta_harq_ack_offset);
|
||||||
len = srsran_print_check(str, str_len, len, " beta_csi_part2_offset=%.2f\n", sch_cfg->beta_csi_part2_offset);
|
len = srsran_print_check(str, str_len, len, " beta_csi_part1_offset=%.2f\n", uci->pusch.beta_csi1_offset);
|
||||||
len = srsran_print_check(str, str_len, len, " beta_harq_ack_offset=%.2f\n", sch_cfg->beta_harq_ack_offset);
|
len = srsran_print_check(str, str_len, len, " beta_csi_part2_offset=%.2f\n", uci->pusch.beta_csi1_offset);
|
||||||
|
len = srsran_print_check(str, str_len, len, " o_csi1=%d\n", srsran_csi_part1_nof_bits(uci->csi, uci->nof_csi));
|
||||||
len = srsran_print_check(
|
len = srsran_print_check(str, str_len, len, " o_ack=%d\n", uci->o_ack);
|
||||||
str, str_len, len, " o_csi1=%d\n", srsran_csi_part1_nof_bits(sch_cfg->uci.csi, sch_cfg->uci.nof_csi));
|
|
||||||
len = srsran_print_check(str, str_len, len, " o_ack=%d\n", sch_cfg->uci.o_ack);
|
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t srsran_phch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len)
|
uint32_t srsran_sch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len)
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
|
|
||||||
|
@ -258,7 +256,7 @@ uint32_t srsran_phch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str,
|
||||||
len += phch_cfg_rvd_to_str(&sch_cfg->rvd_re, &str[len], str_len - len);
|
len += phch_cfg_rvd_to_str(&sch_cfg->rvd_re, &str[len], str_len - len);
|
||||||
|
|
||||||
// UCI configuration
|
// UCI configuration
|
||||||
len += phch_cfg_uci_to_str(sch_cfg, &str[len], str_len - len);
|
len += phch_cfg_uci_to_str(&sch_cfg->uci, &str[len], str_len - len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,121 +328,6 @@ pusch_nr_cinit(const srsran_carrier_nr_t* carrier, const srsran_sch_cfg_nr_t* cf
|
||||||
return cinit;
|
return cinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pusch_nr_fill_uci_cfg(srsran_pusch_nr_t* q, const srsran_sch_cfg_nr_t* cfg)
|
|
||||||
{
|
|
||||||
if (cfg->grant.nof_prb == 0) {
|
|
||||||
ERROR("Invalid number of PRB (%d)", cfg->grant.nof_prb);
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initially, copy all fields
|
|
||||||
q->uci_cfg = cfg->uci;
|
|
||||||
|
|
||||||
// Reset UCI PUSCH configuration
|
|
||||||
SRSRAN_MEM_ZERO(&q->uci_cfg.pusch, srsran_uci_nr_pusch_cfg_t, 1);
|
|
||||||
|
|
||||||
// Get DMRS symbol indexes
|
|
||||||
uint32_t nof_dmrs_l = 0;
|
|
||||||
uint32_t dmrs_l[SRSRAN_DMRS_SCH_MAX_SYMBOLS] = {};
|
|
||||||
int n = srsran_dmrs_sch_get_symbols_idx(&cfg->dmrs, &cfg->grant, dmrs_l);
|
|
||||||
if (n < SRSRAN_SUCCESS) {
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
nof_dmrs_l = (uint32_t)n;
|
|
||||||
|
|
||||||
// Find OFDM symbol index of the first OFDM symbol after the first set of consecutive OFDM symbol(s) carrying DMRS
|
|
||||||
// Starts at first OFDM symbol carrying DMRS
|
|
||||||
for (uint32_t l = dmrs_l[0], dmrs_l_idx = 0; l < cfg->grant.S + cfg->grant.L; l++) {
|
|
||||||
// Check if it is not carrying DMRS...
|
|
||||||
if (l != dmrs_l[dmrs_l_idx]) {
|
|
||||||
// Set value and stop iterating
|
|
||||||
q->uci_cfg.pusch.l0 = l;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next DMRS OFDM symbol index
|
|
||||||
if (dmrs_l_idx < nof_dmrs_l) {
|
|
||||||
dmrs_l_idx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find OFDM symbol index of the first OFDM symbol that does not carry DMRS
|
|
||||||
// Starts at first OFDM symbol of the PUSCH transmission
|
|
||||||
for (uint32_t l = cfg->grant.S, dmrs_l_idx = 0; l < cfg->grant.S + cfg->grant.L; l++) {
|
|
||||||
// Check if it is not carrying DMRS...
|
|
||||||
if (l != dmrs_l[dmrs_l_idx]) {
|
|
||||||
q->uci_cfg.pusch.l1 = l;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next DMRS OFDM symbol index
|
|
||||||
if (dmrs_l_idx < nof_dmrs_l) {
|
|
||||||
dmrs_l_idx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number of DMRS per PRB
|
|
||||||
uint32_t n_sc_dmrs = SRSRAN_DMRS_SCH_SC(cfg->grant.nof_dmrs_cdm_groups_without_data, cfg->dmrs.type);
|
|
||||||
|
|
||||||
// Set UCI RE number of candidates per OFDM symbol according to TS 38.312 6.3.2.4.2.1
|
|
||||||
for (uint32_t l = 0, dmrs_l_idx = 0; l < SRSRAN_NSYMB_PER_SLOT_NR; l++) {
|
|
||||||
// Skip if OFDM symbol is outside of the PUSCH transmission
|
|
||||||
if (l < cfg->grant.S || l >= (cfg->grant.S + cfg->grant.L)) {
|
|
||||||
q->uci_cfg.pusch.M_pusch_sc[l] = 0;
|
|
||||||
q->uci_cfg.pusch.M_uci_sc[l] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OFDM symbol carries DMRS
|
|
||||||
if (l == dmrs_l[dmrs_l_idx]) {
|
|
||||||
// Calculate PUSCH RE candidates
|
|
||||||
q->uci_cfg.pusch.M_pusch_sc[l] = cfg->grant.nof_prb * (SRSRAN_NRE - n_sc_dmrs);
|
|
||||||
|
|
||||||
// The Number of RE candidates for UCI are 0
|
|
||||||
q->uci_cfg.pusch.M_uci_sc[l] = 0;
|
|
||||||
|
|
||||||
// Advance DMRS symbol index
|
|
||||||
dmrs_l_idx++;
|
|
||||||
|
|
||||||
// Skip to next symbol
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number of RE for Phase Tracking Reference Signals (PT-RS)
|
|
||||||
uint32_t M_ptrs_sc = 0; // Not implemented yet
|
|
||||||
|
|
||||||
// Number of RE given by the grant
|
|
||||||
q->uci_cfg.pusch.M_pusch_sc[l] = cfg->grant.nof_prb * SRSRAN_NRE;
|
|
||||||
|
|
||||||
// Calculate the number of UCI candidates
|
|
||||||
q->uci_cfg.pusch.M_uci_sc[l] = q->uci_cfg.pusch.M_pusch_sc[l] - M_ptrs_sc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate SCH Transport block information
|
|
||||||
srsran_sch_nr_tb_info_t sch_tb_info = {};
|
|
||||||
if (srsran_sch_nr_fill_tb_info(&q->carrier, &cfg->sch_cfg, &cfg->grant.tb[0], &sch_tb_info) < SRSRAN_SUCCESS) {
|
|
||||||
ERROR("Generating TB info");
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the sum of codeblock sizes
|
|
||||||
for (uint32_t i = 0; i < sch_tb_info.C; i++) {
|
|
||||||
// Accumulate codeblock size if mask is enabled
|
|
||||||
q->uci_cfg.pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set other PUSCH parameters
|
|
||||||
q->uci_cfg.pusch.modulation = cfg->grant.tb[0].mod;
|
|
||||||
q->uci_cfg.pusch.nof_layers = cfg->grant.nof_layers;
|
|
||||||
q->uci_cfg.pusch.R = (float)cfg->grant.tb[0].R;
|
|
||||||
q->uci_cfg.pusch.alpha = cfg->scaling;
|
|
||||||
q->uci_cfg.pusch.beta_harq_ack_offset = cfg->beta_harq_ack_offset;
|
|
||||||
q->uci_cfg.pusch.beta_csi1_offset = cfg->beta_csi_part1_offset;
|
|
||||||
q->uci_cfg.pusch.nof_re = cfg->grant.tb[0].nof_re;
|
|
||||||
|
|
||||||
return SRSRAN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implements TS 38.212 6.2.7 Data and control multiplexing (for NR-PUSCH)
|
// Implements TS 38.212 6.2.7 Data and control multiplexing (for NR-PUSCH)
|
||||||
static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* cfg)
|
static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* cfg)
|
||||||
{
|
{
|
||||||
|
@ -479,7 +364,7 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t*
|
||||||
if (cfg->o_ack <= 2) {
|
if (cfg->o_ack <= 2) {
|
||||||
// the number of reserved resource elements for potential HARQ-ACK transmission is calculated according to Clause
|
// the number of reserved resource elements for potential HARQ-ACK transmission is calculated according to Clause
|
||||||
// 6.3.2.4.2.1, by setting O_ACK = 2 ;
|
// 6.3.2.4.2.1, by setting O_ACK = 2 ;
|
||||||
G_ack_rvd = srsran_uci_nr_pusch_ack_nof_bits(&q->uci_cfg.pusch, 2);
|
G_ack_rvd = srsran_uci_nr_pusch_ack_nof_bits(&cfg->pusch, 2);
|
||||||
|
|
||||||
// Disable non reserved HARQ-ACK bits
|
// Disable non reserved HARQ-ACK bits
|
||||||
G_ack = 0;
|
G_ack = 0;
|
||||||
|
@ -695,7 +580,7 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode HARQ-ACK bits
|
// Encode HARQ-ACK bits
|
||||||
int E_uci_ack = srsran_uci_nr_encode_pusch_ack(&q->uci, &q->uci_cfg, uci, q->g_ack);
|
int E_uci_ack = srsran_uci_nr_encode_pusch_ack(&q->uci, &cfg->uci, uci, q->g_ack);
|
||||||
if (E_uci_ack < SRSRAN_SUCCESS) {
|
if (E_uci_ack < SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding HARQ-ACK bits");
|
ERROR("Error encoding HARQ-ACK bits");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
|
@ -703,7 +588,7 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
q->G_ack = (uint32_t)E_uci_ack;
|
q->G_ack = (uint32_t)E_uci_ack;
|
||||||
|
|
||||||
// Encode CSI part 1
|
// Encode CSI part 1
|
||||||
int E_uci_csi1 = srsran_uci_nr_encode_pusch_csi1(&q->uci, &q->uci_cfg, uci, q->g_csi1);
|
int E_uci_csi1 = srsran_uci_nr_encode_pusch_csi1(&q->uci, &cfg->uci, uci, q->g_csi1);
|
||||||
if (E_uci_csi1 < SRSRAN_SUCCESS) {
|
if (E_uci_csi1 < SRSRAN_SUCCESS) {
|
||||||
ERROR("Error encoding HARQ-ACK bits");
|
ERROR("Error encoding HARQ-ACK bits");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
|
@ -715,7 +600,7 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
q->G_csi2 = 0;
|
q->G_csi2 = 0;
|
||||||
|
|
||||||
// Generate PUSCH UCI/UL-SCH multiplexing
|
// Generate PUSCH UCI/UL-SCH multiplexing
|
||||||
if (pusch_nr_gen_mux_uci(q, &q->uci_cfg) < SRSRAN_SUCCESS) {
|
if (pusch_nr_gen_mux_uci(q, &cfg->uci) < SRSRAN_SUCCESS) {
|
||||||
ERROR("Error generating PUSCH mux tables");
|
ERROR("Error generating PUSCH mux tables");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -727,6 +612,7 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiplex UL-SCH with UCI only if it is necessary
|
// Multiplex UL-SCH with UCI only if it is necessary
|
||||||
|
uint32_t nof_bits = tb->nof_re * srsran_mod_bits_x_symbol(tb->mod);
|
||||||
uint8_t* b = q->g_ulsch;
|
uint8_t* b = q->g_ulsch;
|
||||||
if (q->uci_mux) {
|
if (q->uci_mux) {
|
||||||
// Change b location
|
// Change b location
|
||||||
|
@ -755,15 +641,15 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
|
|
||||||
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("b=");
|
DEBUG("b=");
|
||||||
srsran_vec_fprint_b(stdout, b, tb->nof_bits);
|
srsran_vec_fprint_b(stdout, b, nof_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.1.1 Scrambling
|
// 7.3.1.1 Scrambling
|
||||||
uint32_t cinit = pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx);
|
uint32_t cinit = pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx);
|
||||||
srsran_sequence_apply_bit(b, q->b[tb->cw_idx], tb->nof_bits, cinit);
|
srsran_sequence_apply_bit(b, q->b[tb->cw_idx], nof_bits, cinit);
|
||||||
|
|
||||||
// Special Scrambling condition
|
// Special Scrambling condition
|
||||||
if (q->uci_cfg.o_ack <= 2) {
|
if (cfg->uci.o_ack <= 2) {
|
||||||
for (uint32_t i = 0; i < q->G_ack; i++) {
|
for (uint32_t i = 0; i < q->G_ack; i++) {
|
||||||
uint32_t idx = q->pos_ack[i];
|
uint32_t idx = q->pos_ack[i];
|
||||||
if (q->g_ack[i] == (uint8_t)UCI_BIT_REPETITION) {
|
if (q->g_ack[i] == (uint8_t)UCI_BIT_REPETITION) {
|
||||||
|
@ -777,7 +663,7 @@ static inline int pusch_nr_encode_codeword(srsran_pusch_nr_t* q,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3.1.2 Modulation
|
// 7.3.1.2 Modulation
|
||||||
srsran_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], tb->nof_bits);
|
srsran_mod_modulate(&q->modem_tables[tb->mod], q->b[tb->cw_idx], q->d[tb->cw_idx], nof_bits);
|
||||||
|
|
||||||
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("d=");
|
DEBUG("d=");
|
||||||
|
@ -795,6 +681,7 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q,
|
||||||
{
|
{
|
||||||
// Check input pointers
|
// Check input pointers
|
||||||
if (!q || !cfg || !grant || !data || !sf_symbols) {
|
if (!q || !cfg || !grant || !data || !sf_symbols) {
|
||||||
|
ERROR("Invalid inputs");
|
||||||
return SRSRAN_ERROR_INVALID_INPUTS;
|
return SRSRAN_ERROR_INVALID_INPUTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,12 +702,6 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q,
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill UCI configuration for PUSCH configuration
|
|
||||||
if (pusch_nr_fill_uci_cfg(q, cfg) < SRSRAN_SUCCESS) {
|
|
||||||
ERROR("Error filling UCI configuration for PUSCH");
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7.3.1.1 and 7.3.1.2
|
// 7.3.1.1 and 7.3.1.2
|
||||||
uint32_t nof_cw = 0;
|
uint32_t nof_cw = 0;
|
||||||
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
|
||||||
|
@ -895,8 +776,11 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
srsran_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
|
srsran_vec_fprint_c(stdout, q->d[tb->cw_idx], tb->nof_re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total number of bits
|
||||||
|
uint32_t nof_bits = tb->nof_re * srsran_mod_bits_x_symbol(tb->mod);
|
||||||
|
|
||||||
// Calculate HARQ-ACK bits
|
// Calculate HARQ-ACK bits
|
||||||
int n = srsran_uci_nr_pusch_ack_nof_bits(&q->uci_cfg.pusch, q->uci_cfg.o_ack);
|
int n = srsran_uci_nr_pusch_ack_nof_bits(&cfg->uci.pusch, cfg->uci.o_ack);
|
||||||
if (n < SRSRAN_SUCCESS) {
|
if (n < SRSRAN_SUCCESS) {
|
||||||
ERROR("Calculating G_ack");
|
ERROR("Calculating G_ack");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
|
@ -904,7 +788,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
q->G_ack = (uint32_t)n;
|
q->G_ack = (uint32_t)n;
|
||||||
|
|
||||||
// Calculate CSI part 1 bits
|
// Calculate CSI part 1 bits
|
||||||
n = srsran_uci_nr_pusch_csi1_nof_bits(&q->uci_cfg);
|
n = srsran_uci_nr_pusch_csi1_nof_bits(&cfg->uci);
|
||||||
if (n < SRSRAN_SUCCESS) {
|
if (n < SRSRAN_SUCCESS) {
|
||||||
ERROR("Calculating G_csi1");
|
ERROR("Calculating G_csi1");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
|
@ -916,7 +800,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
q->G_csi2 = 0;
|
q->G_csi2 = 0;
|
||||||
|
|
||||||
// Generate PUSCH UCI/UL-SCH multiplexing
|
// Generate PUSCH UCI/UL-SCH multiplexing
|
||||||
if (pusch_nr_gen_mux_uci(q, &q->uci_cfg) < SRSRAN_SUCCESS) {
|
if (pusch_nr_gen_mux_uci(q, &cfg->uci) < SRSRAN_SUCCESS) {
|
||||||
ERROR("Error generating PUSCH mux tables");
|
ERROR("Error generating PUSCH mux tables");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -929,16 +813,15 @@ 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[tb->cw_idx] =
|
res->evm[tb->cw_idx] = srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, nof_bits);
|
||||||
srsran_evm_run_b(q->evm_buffer, &q->modem_tables[tb->mod], q->d[tb->cw_idx], llr, tb->nof_bits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Descrambling
|
// Descrambling
|
||||||
srsran_sequence_apply_c(llr, llr, tb->nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx));
|
srsran_sequence_apply_c(llr, llr, nof_bits, pusch_nr_cinit(&q->carrier, cfg, rnti, tb->cw_idx));
|
||||||
|
|
||||||
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
|
||||||
DEBUG("b=");
|
DEBUG("b=");
|
||||||
srsran_vec_fprint_bs(stdout, llr, tb->nof_bits);
|
srsran_vec_fprint_bs(stdout, llr, nof_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demultiplex UCI only if necessary
|
// Demultiplex UCI only if necessary
|
||||||
|
@ -948,7 +831,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
for (uint32_t i = 0; i < q->G_ulsch; i++) {
|
for (uint32_t i = 0; i < q->G_ulsch; i++) {
|
||||||
g_ulsch[i] = -llr[q->pos_ulsch[i]];
|
g_ulsch[i] = -llr[q->pos_ulsch[i]];
|
||||||
}
|
}
|
||||||
for (uint32_t i = q->G_ulsch; i < tb->nof_bits; i++) {
|
for (uint32_t i = q->G_ulsch; i < nof_bits; i++) {
|
||||||
g_ulsch[i] = 0;
|
g_ulsch[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -972,7 +855,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
|
|
||||||
// Decode HARQ-ACK
|
// Decode HARQ-ACK
|
||||||
if (q->G_ack) {
|
if (q->G_ack) {
|
||||||
if (srsran_uci_nr_decode_pusch_ack(&q->uci, &q->uci_cfg, g_ack, &res->uci)) {
|
if (srsran_uci_nr_decode_pusch_ack(&q->uci, &cfg->uci, g_ack, &res->uci)) {
|
||||||
ERROR("Error in UCI decoding");
|
ERROR("Error in UCI decoding");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +863,7 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
|
|
||||||
// Decode CSI part 1
|
// Decode CSI part 1
|
||||||
if (q->G_csi1) {
|
if (q->G_csi1) {
|
||||||
if (srsran_uci_nr_decode_pusch_csi1(&q->uci, &q->uci_cfg, g_csi1, &res->uci)) {
|
if (srsran_uci_nr_decode_pusch_csi1(&q->uci, &cfg->uci, g_csi1, &res->uci)) {
|
||||||
ERROR("Error in UCI decoding");
|
ERROR("Error in UCI decoding");
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -992,13 +875,13 @@ static inline int pusch_nr_decode_codeword(srsran_pusch_nr_t* q,
|
||||||
// Change LLR pointer
|
// Change LLR pointer
|
||||||
llr = g_ulsch;
|
llr = g_ulsch;
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t i = 0; i < tb->nof_bits; i++) {
|
for (uint32_t i = 0; i < nof_bits; i++) {
|
||||||
llr[i] *= -1;
|
llr[i] *= -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode Ul-SCH
|
// Decode Ul-SCH
|
||||||
if (tb->nof_bits != 0) {
|
if (nof_bits != 0) {
|
||||||
if (srsran_ulsch_nr_decode(&q->sch, &cfg->sch_cfg, tb, llr, &res->tb[tb->cw_idx]) < 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;
|
||||||
|
@ -1037,12 +920,6 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill UCI configuration for PUSCH configuration
|
|
||||||
if (pusch_nr_fill_uci_cfg(q, cfg) < SRSRAN_SUCCESS) {
|
|
||||||
ERROR("Error filling UCI configuration for PUSCH");
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t nof_cw = 0;
|
uint32_t nof_cw = 0;
|
||||||
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;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "srsran/phy/phch/pdsch_nr.h"
|
#include "srsran/phy/phch/pdsch_nr.h"
|
||||||
#include "srsran/phy/phch/ra_dl_nr.h"
|
#include "srsran/phy/phch/ra_dl_nr.h"
|
||||||
#include "srsran/phy/phch/ra_ul_nr.h"
|
#include "srsran/phy/phch/ra_ul_nr.h"
|
||||||
|
#include "srsran/phy/phch/uci_nr.h"
|
||||||
#include "srsran/phy/utils/debug.h"
|
#include "srsran/phy/utils/debug.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -814,6 +815,10 @@ int srsran_ra_ul_dci_to_grant_nr(const srsran_carrier_nr_t* carrier,
|
||||||
static float ra_ul_beta_offset_ack_semistatic(const srsran_beta_offsets_t* beta_offsets,
|
static float ra_ul_beta_offset_ack_semistatic(const srsran_beta_offsets_t* beta_offsets,
|
||||||
const srsran_uci_cfg_nr_t* uci_cfg)
|
const srsran_uci_cfg_nr_t* uci_cfg)
|
||||||
{
|
{
|
||||||
|
if (isnormal(beta_offsets->fix_ack)) {
|
||||||
|
return beta_offsets->fix_ack;
|
||||||
|
}
|
||||||
|
|
||||||
// Select Beta Offset index from the number of HARQ-ACK bits
|
// Select Beta Offset index from the number of HARQ-ACK bits
|
||||||
uint32_t beta_offset_index = beta_offsets->ack_index1;
|
uint32_t beta_offset_index = beta_offsets->ack_index1;
|
||||||
if (uci_cfg->o_ack > 11) {
|
if (uci_cfg->o_ack > 11) {
|
||||||
|
@ -843,6 +848,11 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_
|
||||||
const srsran_uci_cfg_nr_t* uci_cfg,
|
const srsran_uci_cfg_nr_t* uci_cfg,
|
||||||
bool part2)
|
bool part2)
|
||||||
{
|
{
|
||||||
|
float fix_beta_offset = part2 ? beta_offsets->fix_csi2 : beta_offsets->fix_csi1;
|
||||||
|
if (isnormal(fix_beta_offset)) {
|
||||||
|
return fix_beta_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate number of CSI bits; CSI part 2 is not supported.
|
// Calculate number of CSI bits; CSI part 2 is not supported.
|
||||||
uint32_t O_csi = part2 ? 0 : srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
|
uint32_t O_csi = part2 ? 0 : srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
|
||||||
|
|
||||||
|
@ -865,35 +875,162 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_
|
||||||
return ra_nr_beta_offset_csi_table[beta_offset_index];
|
return ra_nr_beta_offset_csi_table[beta_offset_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
int srsran_ra_ul_set_grant_uci_nr(const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg,
|
int srsran_ra_ul_set_grant_uci_nr(const srsran_carrier_nr_t* carrier,
|
||||||
|
const srsran_sch_hl_cfg_nr_t* pusch_hl_cfg,
|
||||||
const srsran_uci_cfg_nr_t* uci_cfg,
|
const srsran_uci_cfg_nr_t* uci_cfg,
|
||||||
srsran_sch_cfg_nr_t* pusch_cfg)
|
srsran_sch_cfg_nr_t* pusch_cfg)
|
||||||
{
|
{
|
||||||
// Select beta offsets
|
if (pusch_cfg->grant.nof_prb == 0) {
|
||||||
pusch_cfg->beta_harq_ack_offset = ra_ul_beta_offset_ack_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg);
|
ERROR("Invalid number of PRB (%d)", pusch_cfg->grant.nof_prb);
|
||||||
if (!isnormal(pusch_cfg->beta_harq_ack_offset)) {
|
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pusch_cfg->beta_csi_part1_offset = ra_ul_beta_offset_csi_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg, false);
|
// Initially, copy all fields
|
||||||
if (!isnormal(pusch_cfg->beta_csi_part1_offset)) {
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
pusch_cfg->beta_csi_part2_offset = ra_ul_beta_offset_csi_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg, true);
|
|
||||||
if (!isnormal(pusch_cfg->beta_csi_part2_offset)) {
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pusch_cfg->beta_csi_part2_offset = pusch_hl_cfg->beta_offset_csi2;
|
|
||||||
pusch_cfg->scaling = pusch_hl_cfg->scaling;
|
|
||||||
if (!isnormal(pusch_cfg->scaling)) {
|
|
||||||
ERROR("Invalid Scaling (%f)", pusch_cfg->scaling);
|
|
||||||
return SRSRAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy UCI configuration
|
|
||||||
pusch_cfg->uci = *uci_cfg;
|
pusch_cfg->uci = *uci_cfg;
|
||||||
|
|
||||||
|
// Reset UCI PUSCH configuration
|
||||||
|
SRSRAN_MEM_ZERO(&pusch_cfg->uci.pusch, srsran_uci_nr_pusch_cfg_t, 1);
|
||||||
|
|
||||||
|
// Get DMRS symbol indexes
|
||||||
|
uint32_t nof_dmrs_l = 0;
|
||||||
|
uint32_t dmrs_l[SRSRAN_DMRS_SCH_MAX_SYMBOLS] = {};
|
||||||
|
int n = srsran_dmrs_sch_get_symbols_idx(&pusch_cfg->dmrs, &pusch_cfg->grant, dmrs_l);
|
||||||
|
if (n < SRSRAN_SUCCESS) {
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
nof_dmrs_l = (uint32_t)n;
|
||||||
|
|
||||||
|
// Find OFDM symbol index of the first OFDM symbol after the first set of consecutive OFDM symbol(s) carrying DMRS
|
||||||
|
// Starts at first OFDM symbol carrying DMRS
|
||||||
|
for (uint32_t l = dmrs_l[0], dmrs_l_idx = 0; l < pusch_cfg->grant.S + pusch_cfg->grant.L; l++) {
|
||||||
|
// Check if it is not carrying DMRS...
|
||||||
|
if (l != dmrs_l[dmrs_l_idx]) {
|
||||||
|
// Set value and stop iterating
|
||||||
|
pusch_cfg->uci.pusch.l0 = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next DMRS OFDM symbol index
|
||||||
|
if (dmrs_l_idx < nof_dmrs_l) {
|
||||||
|
dmrs_l_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find OFDM symbol index of the first OFDM symbol that does not carry DMRS
|
||||||
|
// Starts at first OFDM symbol of the PUSCH transmission
|
||||||
|
for (uint32_t l = pusch_cfg->grant.S, dmrs_l_idx = 0; l < pusch_cfg->grant.S + pusch_cfg->grant.L; l++) {
|
||||||
|
// Check if it is not carrying DMRS...
|
||||||
|
if (l != dmrs_l[dmrs_l_idx]) {
|
||||||
|
pusch_cfg->uci.pusch.l1 = l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next DMRS OFDM symbol index
|
||||||
|
if (dmrs_l_idx < nof_dmrs_l) {
|
||||||
|
dmrs_l_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of DMRS per PRB
|
||||||
|
uint32_t n_sc_dmrs = SRSRAN_DMRS_SCH_SC(pusch_cfg->grant.nof_dmrs_cdm_groups_without_data, pusch_cfg->dmrs.type);
|
||||||
|
|
||||||
|
// Set UCI RE number of candidates per OFDM symbol according to TS 38.312 6.3.2.4.2.1
|
||||||
|
for (uint32_t l = 0, dmrs_l_idx = 0; l < SRSRAN_NSYMB_PER_SLOT_NR; l++) {
|
||||||
|
// Skip if OFDM symbol is outside of the PUSCH transmission
|
||||||
|
if (l < pusch_cfg->grant.S || l >= (pusch_cfg->grant.S + pusch_cfg->grant.L)) {
|
||||||
|
pusch_cfg->uci.pusch.M_pusch_sc[l] = 0;
|
||||||
|
pusch_cfg->uci.pusch.M_uci_sc[l] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFDM symbol carries DMRS
|
||||||
|
if (l == dmrs_l[dmrs_l_idx]) {
|
||||||
|
// Calculate PUSCH RE candidates
|
||||||
|
pusch_cfg->uci.pusch.M_pusch_sc[l] = pusch_cfg->grant.nof_prb * (SRSRAN_NRE - n_sc_dmrs);
|
||||||
|
|
||||||
|
// The Number of RE candidates for UCI are 0
|
||||||
|
pusch_cfg->uci.pusch.M_uci_sc[l] = 0;
|
||||||
|
|
||||||
|
// Advance DMRS symbol index
|
||||||
|
dmrs_l_idx++;
|
||||||
|
|
||||||
|
// Skip to next symbol
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of RE for Phase Tracking Reference Signals (PT-RS)
|
||||||
|
uint32_t M_ptrs_sc = 0; // Not implemented yet
|
||||||
|
|
||||||
|
// Number of RE given by the grant
|
||||||
|
pusch_cfg->uci.pusch.M_pusch_sc[l] = pusch_cfg->grant.nof_prb * SRSRAN_NRE;
|
||||||
|
|
||||||
|
// Calculate the number of UCI candidates
|
||||||
|
pusch_cfg->uci.pusch.M_uci_sc[l] = pusch_cfg->uci.pusch.M_pusch_sc[l] - M_ptrs_sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate SCH Transport block information
|
||||||
|
srsran_sch_nr_tb_info_t sch_tb_info = {};
|
||||||
|
if (srsran_sch_nr_fill_tb_info(carrier, &pusch_cfg->sch_cfg, &pusch_cfg->grant.tb[0], &sch_tb_info) <
|
||||||
|
SRSRAN_SUCCESS) {
|
||||||
|
ERROR("Generating TB info");
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the sum of codeblock sizes
|
||||||
|
for (uint32_t i = 0; i < sch_tb_info.C; i++) {
|
||||||
|
// Accumulate codeblock size if mask is enabled
|
||||||
|
pusch_cfg->uci.pusch.K_sum += (sch_tb_info.mask[i]) ? sch_tb_info.Kr : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set other PUSCH parameters
|
||||||
|
pusch_cfg->uci.pusch.modulation = pusch_cfg->grant.tb[0].mod;
|
||||||
|
pusch_cfg->uci.pusch.nof_layers = pusch_cfg->grant.nof_layers;
|
||||||
|
pusch_cfg->uci.pusch.R = (float)pusch_cfg->grant.tb[0].R;
|
||||||
|
pusch_cfg->uci.pusch.nof_re = pusch_cfg->grant.tb[0].nof_re;
|
||||||
|
|
||||||
|
// Select beta offsets
|
||||||
|
pusch_cfg->uci.pusch.beta_harq_ack_offset = ra_ul_beta_offset_ack_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg);
|
||||||
|
if (!isnormal(pusch_cfg->uci.pusch.beta_harq_ack_offset)) {
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pusch_cfg->uci.pusch.beta_csi1_offset = ra_ul_beta_offset_csi_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg, false);
|
||||||
|
if (!isnormal(pusch_cfg->uci.pusch.beta_csi1_offset)) {
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pusch_cfg->uci.pusch.beta_csi2_offset = ra_ul_beta_offset_csi_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg, true);
|
||||||
|
if (!isnormal(pusch_cfg->uci.pusch.beta_csi2_offset)) {
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pusch_cfg->uci.pusch.alpha = pusch_hl_cfg->scaling;
|
||||||
|
if (!isnormal(pusch_cfg->uci.pusch.alpha)) {
|
||||||
|
ERROR("Invalid Scaling (%f)", pusch_cfg->uci.pusch.alpha);
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate number of UCI encoded bits
|
||||||
|
int Gack = 0;
|
||||||
|
if (pusch_cfg->uci.o_ack > 2) {
|
||||||
|
Gack = srsran_uci_nr_pusch_ack_nof_bits(&pusch_cfg->uci.pusch, pusch_cfg->uci.o_ack);
|
||||||
|
if (Gack < SRSRAN_SUCCESS) {
|
||||||
|
ERROR("Error calculating Qdack");
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int Gcsi1 = srsran_uci_nr_pusch_csi1_nof_bits(&pusch_cfg->uci);
|
||||||
|
if (Gcsi1 < SRSRAN_SUCCESS) {
|
||||||
|
ERROR("Error calculating Qdack");
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
int Gcsi2 = 0; // NOT supported
|
||||||
|
|
||||||
|
// Update Number of TB encoded bits
|
||||||
|
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
|
||||||
|
pusch_cfg->grant.tb[i].nof_bits =
|
||||||
|
pusch_cfg->grant.tb[i].nof_re * srsran_mod_bits_x_symbol(pusch_cfg->grant.tb[i].mod) - Gack - Gcsi1 - Gcsi2;
|
||||||
|
}
|
||||||
|
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,9 +187,11 @@ int main(int argc, char** argv)
|
||||||
mcs_end = SRSRAN_MIN(mcs + 1, mcs_end);
|
mcs_end = SRSRAN_MIN(mcs + 1, mcs_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
pusch_cfg.scaling = 0.5f;
|
srsran_sch_hl_cfg_nr_t sch_hl_cfg = {};
|
||||||
pusch_cfg.beta_harq_ack_offset = 2.0f;
|
sch_hl_cfg.scaling = 1.0f;
|
||||||
pusch_cfg.beta_csi_part1_offset = 2.0f;
|
sch_hl_cfg.beta_offsets.fix_ack = 12.625f;
|
||||||
|
sch_hl_cfg.beta_offsets.fix_csi1 = 2.25f;
|
||||||
|
sch_hl_cfg.beta_offsets.fix_csi2 = 2.25f;
|
||||||
|
|
||||||
if (srsran_chest_dl_res_init(&chest, carrier.nof_prb) < SRSRAN_SUCCESS) {
|
if (srsran_chest_dl_res_init(&chest, carrier.nof_prb) < SRSRAN_SUCCESS) {
|
||||||
ERROR("Initiating chest");
|
ERROR("Initiating chest");
|
||||||
|
@ -245,6 +247,11 @@ int main(int argc, char** argv)
|
||||||
data_rx.uci.csi[0].none = csi_report_rx;
|
data_rx.uci.csi[0].none = csi_report_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srsran_ra_ul_set_grant_uci_nr(&carrier, &sch_hl_cfg, &pusch_cfg.uci, &pusch_cfg) < SRSRAN_SUCCESS) {
|
||||||
|
ERROR("Setting UCI");
|
||||||
|
goto clean_exit;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -345,7 +352,7 @@ int main(int argc, char** argv)
|
||||||
srsran_pusch_nr_rx_info(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &data_rx, str, (uint32_t)sizeof(str));
|
srsran_pusch_nr_rx_info(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &data_rx, str, (uint32_t)sizeof(str));
|
||||||
|
|
||||||
char str_extra[2048];
|
char str_extra[2048];
|
||||||
srsran_phch_cfg_nr_info(&pusch_cfg, str_extra, (uint32_t)sizeof(str_extra));
|
srsran_sch_cfg_nr_info(&pusch_cfg, str_extra, (uint32_t)sizeof(str_extra));
|
||||||
INFO("PUSCH: %s\n%s", str, str_extra);
|
INFO("PUSCH: %s\n%s", str, str_extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -385,14 +385,16 @@ static int uci_nr_decode_1_bit(srsran_uci_nr_t* q,
|
||||||
// Correlate LLR
|
// Correlate LLR
|
||||||
float corr = 0.0f;
|
float corr = 0.0f;
|
||||||
float pwr = 0.0f;
|
float pwr = 0.0f;
|
||||||
|
uint32_t count = 0;
|
||||||
for (uint32_t i = 0; i < E; i += Qm) {
|
for (uint32_t i = 0; i < E; i += Qm) {
|
||||||
float t = (float)llr[i];
|
float t = (float)llr[i];
|
||||||
corr += t;
|
corr += t;
|
||||||
pwr += t * t;
|
pwr += t * t;
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalise correlation
|
// Normalise correlation
|
||||||
float norm_corr = Qm * corr / (E * sqrtf(pwr));
|
float norm_corr = fabsf(corr) / sqrtf(pwr * count);
|
||||||
|
|
||||||
// Take decoded decision with threshold
|
// Take decoded decision with threshold
|
||||||
*decoded_ok = (norm_corr > q->one_bit_threshold);
|
*decoded_ok = (norm_corr > q->one_bit_threshold);
|
||||||
|
|
|
@ -453,7 +453,7 @@ int main(int argc, char** argv)
|
||||||
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str, (uint32_t)sizeof(str));
|
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str, (uint32_t)sizeof(str));
|
||||||
|
|
||||||
char str_extra[2048];
|
char str_extra[2048];
|
||||||
srsran_phch_cfg_nr_info(&pdsch_cfg, str_extra, (uint32_t)sizeof(str_extra));
|
srsran_sch_cfg_nr_info(&pdsch_cfg, str_extra, (uint32_t)sizeof(str_extra));
|
||||||
INFO("PDSCH: %s\n%s", str, str_extra);
|
INFO("PDSCH: %s\n%s", str, str_extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ bool cc_worker::work_dl()
|
||||||
|
|
||||||
if (logger.debug.enabled()) {
|
if (logger.debug.enabled()) {
|
||||||
str_extra_t str_extra;
|
str_extra_t str_extra;
|
||||||
srsran_phch_cfg_nr_info(&pdsch_cfg, str_extra.data(), (uint32_t)str_extra.size());
|
srsran_sch_cfg_nr_info(&pdsch_cfg, str_extra.data(), (uint32_t)str_extra.size());
|
||||||
logger.info(pdsch_res.tb[0].payload,
|
logger.info(pdsch_res.tb[0].payload,
|
||||||
pdsch_cfg.grant.tb[0].tbs / 8,
|
pdsch_cfg.grant.tb[0].tbs / 8,
|
||||||
"PDSCH: cc=%d, %s\n%s",
|
"PDSCH: cc=%d, %s\n%s",
|
||||||
|
@ -392,7 +392,7 @@ bool cc_worker::work_ul()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set UCI configuration following procedures
|
// Set UCI configuration following procedures
|
||||||
srsran_ra_ul_set_grant_uci_nr(&phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
|
srsran_ra_ul_set_grant_uci_nr(&phy->carrier, &phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
|
||||||
|
|
||||||
// Assigning MAC provided values to PUSCH config structs
|
// Assigning MAC provided values to PUSCH config structs
|
||||||
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
|
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
|
||||||
|
@ -415,7 +415,7 @@ bool cc_worker::work_ul()
|
||||||
|
|
||||||
if (logger.debug.enabled()) {
|
if (logger.debug.enabled()) {
|
||||||
str_extra_t str_extra;
|
str_extra_t str_extra;
|
||||||
srsran_phch_cfg_nr_info(&pusch_cfg, str_extra.data(), (uint32_t)str_extra.size());
|
srsran_sch_cfg_nr_info(&pusch_cfg, str_extra.data(), (uint32_t)str_extra.size());
|
||||||
logger.info(ul_action.tb.payload->msg,
|
logger.info(ul_action.tb.payload->msg,
|
||||||
pusch_cfg.grant.tb[0].tbs / 8,
|
pusch_cfg.grant.tb[0].tbs / 8,
|
||||||
"PUSCH: cc=%d %s tti_tx=%d\n%s",
|
"PUSCH: cc=%d %s tti_tx=%d\n%s",
|
||||||
|
|
Loading…
Reference in New Issue