SRSUE: Added procedure for multiplexing UCI in NR-PUSCH

This commit is contained in:
Xavier Arteaga 2021-03-08 18:56:18 +01:00 committed by Xavier Arteaga
parent e43f555fc0
commit 6f6c20e194
9 changed files with 195 additions and 7 deletions

View File

@ -178,11 +178,22 @@ struct phy_cfg_nr_t {
// betaOffsetACK-Index1: 9
// betaOffsetACK-Index2: 9
// betaOffsetACK-Index3: 9
pusch.beta_offsets.ack_index1 = 9;
pusch.beta_offsets.ack_index2 = 9;
pusch.beta_offsets.ack_index3 = 9;
// betaOffsetCSI-Part1-Index1: 6
// betaOffsetCSI-Part1-Index2: 6
pusch.beta_offsets.csi1_index1 = 6;
pusch.beta_offsets.csi1_index2 = 6;
// betaOffsetCSI-Part2-Index1: 6
// betaOffsetCSI-Part2-Index2: 6
pusch.beta_offsets.csi2_index1 = 6;
pusch.beta_offsets.csi2_index2 = 6;
// scaling: f1 (3)
pusch.scaling = 1;
// pucch-Config: setup (1)
// setup

View File

@ -144,6 +144,20 @@ typedef struct SRSLTE_API {
srslte_sch_tb_t tb[SRSLTE_MAX_TB];
} srslte_sch_grant_nr_t;
/**
* @brief Beta offset configuration provided from upper layers
* @remark Configure according to TS 38.331 BetaOffsets
*/
typedef struct {
uint32_t ack_index1; ///< Use for up to 2 HARQ-ACK bits. Set to 11 if absent.
uint32_t ack_index2; ///< Use for up to 11 HARQ-ACK bits. Set to 11 if absent.
uint32_t ack_index3; ///< Use for more than 11 HARQ-ACK bits. Set to 11 if absent.
uint32_t csi1_index1; ///< Use for up to 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_index2; ///< Use for more than 11 CSI bits. Set to 13 if absent.
} srslte_beta_offsets_t;
/**
* @brief flatten SCH configuration parameters provided by higher layers
* @remark Described in TS 38.331 V15.10.0 Section PDSCH-Config
@ -188,6 +202,10 @@ typedef struct SRSLTE_API {
bool rbg_size_cfg_1; ///< RBG size configuration (1 or 2)
srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters
/// PUSCH only
srslte_beta_offsets_t beta_offsets; /// Semi-static only.
float scaling; /// Indicates a scaling factor to limit the number of resource elements assigned to UCI on PUSCH.
} srslte_sch_hl_cfg_nr_t;
/**
@ -207,6 +225,7 @@ typedef struct SRSLTE_API {
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;
} srslte_sch_cfg_nr_t;

View File

@ -115,6 +115,7 @@ SRSLTE_API uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q,
SRSLTE_API uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q,
const srslte_sch_cfg_nr_t* cfg,
const srslte_sch_grant_nr_t* grant,
const srslte_uci_value_nr_t* uci_value,
char* str,
uint32_t str_len);

View File

@ -121,4 +121,18 @@ SRSLTE_API int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrie
srslte_sch_cfg_nr_t* pusch_cfg,
srslte_sch_grant_nr_t* pusch_grant);
/**
* @brief Setups the Uplink Control Information configuration for a PUSCH transmission
*
* @remark Implement procedure described in TS 38.213 9.3 UCI reporting in physical uplink shared channel
*
* @param pusch_hl_cfg PUSCH configuration provided by higher layers
* @param uci_cfg Uplink Control Information configuration for this PUSCH transmission
* @param pusch_cfg PUSCH configuration after applying the procedure
* @return SRSLTE_SUCCESS if the procedure is successful, SRSLTE_ERROR code otherwise
*/
SRSLTE_API int srslte_ra_ul_set_grant_uci_nr(const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg,
const srslte_uci_cfg_nr_t* uci_cfg,
srslte_sch_cfg_nr_t* pusch_cfg);
#endif // SRSLTE_RA_NR_H

View File

@ -67,8 +67,11 @@ SRSLTE_API int srslte_ue_ul_nr_encode_pucch(srslte_ue_ul_nr_t*
SRSLTE_API void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q);
SRSLTE_API int
srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len);
SRSLTE_API int srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q,
const srslte_sch_cfg_nr_t* cfg,
const srslte_uci_value_nr_t* uci_value,
char* str,
uint32_t str_len);
SRSLTE_API int srslte_ue_ul_nr_pucch_info(const srslte_pucch_nr_resource_t* resource,
const srslte_uci_data_nr_t* uci_data,

View File

@ -1284,6 +1284,10 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q,
{
uint32_t len = 0;
if (q == NULL || cfg == NULL || grant == NULL || str == NULL || str_len == 0) {
return 0;
}
len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len);
if (q->evm_buffer != NULL) {
@ -1302,6 +1306,11 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q,
}
if (res != NULL) {
srslte_uci_data_nr_t uci_data = {};
uci_data.cfg = cfg->uci;
uci_data.value = res[0].uci;
len += srslte_uci_nr_info(&uci_data, &str[len], str_len - len);
len = srslte_print_check(str, str_len, len, ",crc={", 0);
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
if (grant->tb[i].enabled) {
@ -1326,13 +1335,25 @@ uint32_t srslte_pusch_nr_rx_info(const srslte_pusch_nr_t* q,
uint32_t srslte_pusch_nr_tx_info(const srslte_pusch_nr_t* q,
const srslte_sch_cfg_nr_t* cfg,
const srslte_sch_grant_nr_t* grant,
const srslte_uci_value_nr_t* uci_value,
char* str,
uint32_t str_len)
{
uint32_t len = 0;
if (q == NULL || cfg == NULL || grant == NULL || str == NULL || str_len == 0) {
return 0;
}
len += srslte_pusch_nr_grant_info(cfg, grant, &str[len], str_len - len);
if (uci_value != NULL) {
srslte_uci_data_nr_t uci_data = {};
uci_data.cfg = cfg->uci;
uci_data.value = *uci_value;
len += srslte_uci_nr_info(&uci_data, &str[len], str_len - len);
}
if (q->meas_time_en) {
len = srslte_print_check(str, str_len, len, ", t=%d us", q->meas_time_us);
}

View File

@ -11,6 +11,7 @@
*/
#include "srslte/phy/phch/ra_nr.h"
#include "srslte/phy/phch/csi.h"
#include "srslte/phy/phch/pdsch_nr.h"
#include "srslte/phy/phch/ra_dl_nr.h"
#include "srslte/phy/phch/ra_ul_nr.h"
@ -26,6 +27,8 @@ typedef struct {
#define RA_NR_MCS_SIZE_TABLE2 28
#define RA_NR_MCS_SIZE_TABLE3 29
#define RA_NR_TBS_SIZE_TABLE 93
#define RA_NR_BETA_OFFSET_HARQACK_SIZE 32
#define RA_NR_BETA_OFFSET_CSI_SIZE 32
#define RA_NR_READ_TABLE(N) \
static double srslte_ra_nr_R_from_mcs_table##N(uint32_t mcs_idx) \
@ -108,6 +111,23 @@ static const uint32_t ra_nr_tbs_table[RA_NR_TBS_SIZE_TABLE] = {
1192, 1224, 1256, 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216,
2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, 3104, 3240, 3368, 3496, 3624, 3752, 3824};
/**
* TS 38.213 V15.10.0 Table 9.3-1: Mapping of beta_offset values for HARQ-ACK information and the index signalled by
* higher layers
*/
static const float ra_nr_beta_offset_ack_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] = {
1.000f, 2.000f, 2.500f, 3.125f, 4.000f, 5.000f, 6.250f, 8.000f, 10.000f, 12.625f, 15.875f,
20.000f, 31.000f, 50.000f, 80.000f, 126.000f, NAN, NAN, NAN, NAN, NAN, NAN,
NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN};
/**
* TS 38.213 V15.10.0 Table 9.3-2: Mapping of beta_offset values for CSI and the index signalled by higher layers
*/
static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] = {
1.125f, 1.250f, 1.375f, 1.625f, 1.750f, 2.000f, 2.250f, 2.500f, 2.875f, 3.125f, 3.500f,
4.000f, 5.000f, 6.250f, 8.000f, 10.000f, 12.625f, 15.875f, 20.000f, NAN, NAN, NAN,
NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN};
typedef enum { ra_nr_table_1 = 0, ra_nr_table_2, ra_nr_table_3 } ra_nr_table_t;
static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srslte_mcs_table_t mcs_table,
@ -636,3 +656,94 @@ int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
return SRSLTE_SUCCESS;
}
/*
* Implements clauses related to HARQ-ACK beta offset selection from the section `9.3 UCI reporting in physical uplink
* shared channel`
*/
static float ra_ul_beta_offset_ack_semistatic(const srslte_beta_offsets_t* beta_offsets,
const srslte_uci_cfg_nr_t* uci_cfg)
{
// Select Beta Offset index from the number of HARQ-ACK bits
uint32_t beta_offset_index = beta_offsets->ack_index1;
if (uci_cfg->o_ack > 11) {
beta_offset_index = beta_offsets->ack_index3;
} else if (uci_cfg->o_ack > 2) {
beta_offset_index = beta_offsets->ack_index1;
}
// Protect table boundary
if (beta_offset_index > RA_NR_BETA_OFFSET_HARQACK_SIZE) {
ERROR("Beta offset index for HARQ-ACK (%d) for O_ack=%d exceeds table size (%d)",
beta_offset_index,
uci_cfg->o_ack,
RA_NR_BETA_OFFSET_HARQACK_SIZE);
return NAN;
}
// Select beta offset from Table 9.3-1
return ra_nr_beta_offset_ack_table[beta_offset_index];
}
/*
* Implements clauses related to HARQ-ACK beta offset selection from the section `9.3 UCI reporting in physical uplink
* shared channel`
*/
static float ra_ul_beta_offset_csi_semistatic(const srslte_beta_offsets_t* beta_offsets,
const srslte_uci_cfg_nr_t* uci_cfg,
bool part2)
{
// Calculate number of CSI bits; CSI part 2 is not supported.
uint32_t O_csi = part2 ? 0 : srslte_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
// Select Beta Offset index from the number of HARQ-ACK bits
uint32_t beta_offset_index = part2 ? beta_offsets->csi2_index1 : beta_offsets->csi1_index1;
if (O_csi > 11) {
beta_offset_index = part2 ? beta_offsets->csi2_index2 : beta_offsets->csi1_index2;
}
// Protect table boundary
if (beta_offset_index > RA_NR_BETA_OFFSET_CSI_SIZE) {
ERROR("Beta offset index for CSI (%d) for O_csi=%d exceeds table size (%d)",
beta_offset_index,
O_csi,
RA_NR_BETA_OFFSET_CSI_SIZE);
return NAN;
}
// Select beta offset from Table 9.3-1
return ra_nr_beta_offset_csi_table[beta_offset_index];
}
int srslte_ra_ul_set_grant_uci_nr(const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg,
const srslte_uci_cfg_nr_t* uci_cfg,
srslte_sch_cfg_nr_t* pusch_cfg)
{
// Select beta offsets
pusch_cfg->beta_harq_ack_offset = ra_ul_beta_offset_ack_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg);
if (!isnormal(pusch_cfg->beta_harq_ack_offset)) {
return SRSLTE_ERROR;
}
pusch_cfg->beta_csi_part1_offset = ra_ul_beta_offset_csi_semistatic(&pusch_hl_cfg->beta_offsets, uci_cfg, false);
if (!isnormal(pusch_cfg->beta_csi_part1_offset)) {
return SRSLTE_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 SRSLTE_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 SRSLTE_ERROR;
}
// Copy UCI configuration
pusch_cfg->uci = *uci_cfg;
return SRSLTE_SUCCESS;
}

View File

@ -230,12 +230,16 @@ void srslte_ue_ul_nr_free(srslte_ue_ul_nr_t* q)
SRSLTE_MEM_ZERO(q, srslte_ue_ul_nr_t, 1);
}
int srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q, const srslte_sch_cfg_nr_t* cfg, char* str, uint32_t str_len)
int srslte_ue_ul_nr_pusch_info(const srslte_ue_ul_nr_t* q,
const srslte_sch_cfg_nr_t* cfg,
const srslte_uci_value_nr_t* uci_value,
char* str,
uint32_t str_len)
{
int len = 0;
// Append PDSCH info
len += srslte_pusch_nr_tx_info(&q->pusch, cfg, &cfg->grant, &str[len], str_len - len);
len += srslte_pusch_nr_tx_info(&q->pusch, cfg, &cfg->grant, uci_value, &str[len], str_len - len);
return len;
}

View File

@ -283,14 +283,18 @@ bool cc_worker::work_ul()
mac_ul_grant.rnti = pusch_cfg.grant.rnti;
mac_ul_grant.tti = ul_slot_cfg.idx;
mac_ul_grant.tbs = pusch_cfg.grant.tb[0].tbs;
phy->stack->new_grant_ul(0, mac_ul_grant, &ul_action);
// Assignning MAC provided values to PUSCH config structs
// Set UCI configuration following procedures
srslte_ra_ul_set_grant_uci_nr(&phy->cfg.pusch, &uci_data.cfg, &pusch_cfg);
// Assigning MAC provided values to PUSCH config structs
pusch_cfg.grant.tb[0].softbuffer.tx = ul_action.tb.softbuffer;
// Setup data for encoding
srslte_pusch_data_nr_t data = {};
data.payload = ul_action.tb.payload->msg;
data.uci = uci_data.value;
// Encode PUSCH transmission
if (srslte_ue_ul_nr_encode_pusch(&ue_ul, &ul_slot_cfg, &pusch_cfg, &data) < SRSLTE_SUCCESS) {
@ -301,7 +305,7 @@ bool cc_worker::work_ul()
// PUSCH Logging
if (logger.info.enabled()) {
std::array<char, 512> str;
srslte_ue_ul_nr_pusch_info(&ue_ul, &pusch_cfg, str.data(), str.size());
srslte_ue_ul_nr_pusch_info(&ue_ul, &pusch_cfg, &data.uci, str.data(), str.size());
logger.info(ul_action.tb.payload->msg,
pusch_cfg.grant.tb[0].tbs / 8,
"PUSCH (NR): cc=%d, %s, tti_tx=%d",