Solved PDSCH Power Allocation p_b on eNB side

This commit is contained in:
Xavier Arteaga 2017-11-22 18:01:13 +01:00
parent 401cc9a20a
commit dbf10cff17
11 changed files with 125 additions and 4 deletions

View file

@ -88,6 +88,7 @@ typedef struct SRSLTE_API {
float sss_signal5[SRSLTE_SSS_LEN];
float tx_amp;
float rho_b;
uint8_t tmp[1024*128];
@ -122,6 +123,14 @@ SRSLTE_API int srslte_enb_dl_set_cell(srslte_enb_dl_t *q,
SRSLTE_API void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q,
uint32_t cfi);
SRSLTE_API void srslte_enb_dl_set_power_allocation(srslte_enb_dl_t *q,
float rho_a,
float rho_b);
SRSLTE_API void srslte_enb_dl_apply_power_allocation(srslte_enb_dl_t *q);
SRSLTE_API void srslte_enb_dl_prepare_power_allocation(srslte_enb_dl_t *q);
SRSLTE_API void srslte_enb_dl_set_amp(srslte_enb_dl_t *q,
float amp);

View file

@ -213,6 +213,70 @@ void srslte_enb_dl_set_cfi(srslte_enb_dl_t *q, uint32_t cfi)
srslte_regs_set_cfi(&q->regs, cfi);
}
void srslte_enb_dl_set_power_allocation(srslte_enb_dl_t *q, float rho_a, float rho_b)
{
if (q) {
q->rho_b = rho_b;
srslte_pdsch_set_power_allocation(&q->pdsch, rho_a);
}
}
void srslte_enb_dl_apply_power_allocation(srslte_enb_dl_t *q)
{
uint32_t nof_symbols_slot = SRSLTE_CP_NSYMB(q->cell.cp);
uint32_t nof_re_symbol = SRSLTE_NRE * q->cell.nof_prb;
if (q->rho_b != 0.0f && q->rho_b != 1.0f) {
float scaling = q->rho_b;
for (uint32_t i = 0; i < q->cell.nof_ports; i++) {
for (uint32_t j = 0; j < 2; j++) {
cf_t *ptr;
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 0);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
if (q->cell.cp == SRSLTE_CP_NORM) {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 4);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
} else {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 3);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
}
if (q->cell.nof_ports == 4) {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 1);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
}
}
}
}
}
void srslte_enb_dl_prepare_power_allocation(srslte_enb_dl_t *q)
{
uint32_t nof_symbols_slot = SRSLTE_CP_NSYMB(q->cell.cp);
uint32_t nof_re_symbol = SRSLTE_NRE * q->cell.nof_prb;
if (q->rho_b != 0.0f && q->rho_b != 1.0f) {
float scaling = 1.0f / q->rho_b;
for (uint32_t i = 0; i < q->cell.nof_ports; i++) {
for (uint32_t j = 0; j < 2; j++) {
cf_t *ptr;
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 0);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
if (q->cell.cp == SRSLTE_CP_NORM) {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 4);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
} else {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 3);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
}
if (q->cell.nof_ports == 4) {
ptr = q->sf_symbols[i] + nof_re_symbol * (j * nof_symbols_slot + 1);
srslte_vec_sc_prod_cfc(ptr, scaling, ptr, nof_re_symbol);
}
}
}
}
}
void srslte_enb_dl_clear_sf(srslte_enb_dl_t *q)
{
for (int i=0;i<q->cell.nof_ports;i++) {

View file

@ -818,6 +818,12 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
}
}
/* Set scaling configured by Power Allocation */
float scaling = 1.0f;
if (q->rho_a != 0.0f) {
scaling = q->rho_a;
}
// Layer mapping & precode if necessary
if (q->cell.nof_ports > 1) {
int nof_symbols;
@ -841,9 +847,13 @@ int srslte_pdsch_encode(srslte_pdsch_t *q,
/* Precode */
srslte_precoding_type(x, q->symbols, cfg->nof_layers, q->cell.nof_ports, cfg->codebook_idx,
nof_symbols, 1.0f, cfg->mimo_type);
nof_symbols, scaling, cfg->mimo_type);
} else {
memcpy(q->symbols[0], q->d[0], cfg->nbits[0].nof_re * sizeof(cf_t));
if (scaling == 1.0f) {
memcpy(q->symbols[0], q->d[0], cfg->nbits[0].nof_re * sizeof(cf_t));
} else {
srslte_vec_sc_prod_cfc(q->d[0], scaling, q->symbols[0], cfg->nbits[0].nof_re);
}
}
/* mapping to resource elements */

View file

@ -68,6 +68,7 @@ typedef struct {
uint32_t pci;
uint32_t nof_ports;
uint32_t transmission_mode;
float p_a;
}enb_args_t;
typedef struct {

View file

@ -72,6 +72,7 @@ public:
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg;
srslte_pusch_hopping_cfg_t hopping_cfg;
srslte_pucch_cfg_t pucch_cfg;
uint8_t pdsch_p_b;
phy_args_t params;
srslte::radio *radio;

View file

@ -80,6 +80,7 @@ typedef struct {
LIBLTE_RRC_MAC_MAIN_CONFIG_STRUCT mac_cnfg;
LIBLTE_RRC_PUSCH_CONFIG_DEDICATED_STRUCT pusch_cfg;
LIBLTE_RRC_ANTENNA_INFO_DEDICATED_STRUCT antenna_info;
LIBLTE_RRC_PDSCH_CONFIG_P_A_ENUM pdsch_cfg;
rrc_cfg_sr_t sr_cfg;
rrc_cfg_cqi_t cqi_cfg;
rrc_cfg_qci_t qci_cfg[MAX_NOF_QCI];

View file

@ -866,6 +866,18 @@ int enb::parse_rr(all_args_t* args, rrc_cfg_t* rrc_cfg)
rrc_cfg->antenna_info.codebook_subset_restriction_present = true;
}
/* Parse power allocation */
rrc_cfg->pdsch_cfg = LIBLTE_RRC_PDSCH_CONFIG_P_A_N_ITEMS;
for (int i = 0; i < LIBLTE_RRC_PDSCH_CONFIG_P_A_N_ITEMS; i++) {
if (args->enb.p_a == liblte_rrc_pdsch_config_p_a_num[i]) {
rrc_cfg->pdsch_cfg = (LIBLTE_RRC_PDSCH_CONFIG_P_A_ENUM) i;
}
}
if (rrc_cfg->pdsch_cfg == LIBLTE_RRC_PDSCH_CONFIG_P_A_N_ITEMS) {
ERROR("Invalid p_a value (%f) only -6, -4.77, -3, -1.77, 0, 1, 2, 3 values allowed.", args->enb.p_a);
return SRSLTE_ERROR;
}
/* MAC config section */
parser::section mac_cnfg("mac_cnfg");

View file

@ -79,6 +79,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB")
("enb.nof_ports", bpo::value<uint32_t>(&args->enb.nof_ports)->default_value(1), "Number of ports")
("enb.tm", bpo::value<uint32_t>(&args->enb.transmission_mode)->default_value(1), "Transmission mode (1-8)")
("enb.p_a", bpo::value<float>(&args->enb.p_a)->default_value(0.0f), "Power allocation rho_a (-6, -4.77, -3, -1.77, 0, 1, 2, 3)")
("enb_files.sib_config", bpo::value<string>(&args->enb_files.sib_config)->default_value("sib.conf"), "SIB configuration files")
("enb_files.rr_config", bpo::value<string>(&args->enb_files.rr_config)->default_value("rr.conf"), "RR configuration files")

View file

@ -776,6 +776,10 @@ int phch_worker::encode_pdcch_dl(srslte_enb_dl_pdsch_t *grants, uint32_t nof_gra
}
int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants) {
/* Scales the Resources Elements affected by the power allocation (p_b) */
srslte_enb_dl_prepare_power_allocation(&enb_dl);
for (uint32_t i = 0; i < nof_grants; i++) {
uint16_t rnti = grants[i].rnti;
if (rnti) {
@ -871,6 +875,18 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
int rv[SRSLTE_MAX_CODEWORDS] = {grants[i].grant.rv_idx, grants[i].grant.rv_idx_1};
/* Set power allocation */
float rho_a = 1.0f, rho_b = 1.0f;
if (ue_db[rnti].dedicated.pdsch_cnfg_ded < LIBLTE_RRC_PDSCH_CONFIG_P_A_N_ITEMS) {
float rho_a_db = liblte_rrc_pdsch_config_p_a_num[ue_db[rnti].dedicated.pdsch_cnfg_ded];
rho_a = powf(10.0f, rho_a_db / 20.0f) * ((enb_dl.cell.nof_ports == 1) ? 1.0f : sqrtf(2.0f));
}
if (phy->pdsch_p_b < 4) {
uint32_t idx0 = (phy->cell.nof_ports == 1) ? 0 : 1;
float cell_specific_ratio = pdsch_cfg_cell_specific_ratio_table[idx0][phy->pdsch_p_b];
rho_b = sqrtf(cell_specific_ratio);
}
srslte_enb_dl_set_power_allocation(&enb_dl, rho_a, rho_b);
if (srslte_enb_dl_put_pdsch(&enb_dl, &phy_grant, grants[i].softbuffers, rnti, rv, sf_tx, grants[i].data, mimo_type)) {
fprintf(stderr, "Error putting PDSCH %d\n", i);
return SRSLTE_ERROR;
@ -880,6 +896,9 @@ int phch_worker::encode_pdsch(srslte_enb_dl_pdsch_t *grants, uint32_t nof_grants
ue_db[rnti].metrics_dl(phy_grant.mcs[0].idx);
}
}
srslte_enb_dl_apply_power_allocation(&enb_dl);
return SRSLTE_SUCCESS;
}

View file

@ -80,7 +80,10 @@ void phy::parse_config(phy_cfg_t* cfg)
workers_common.pucch_cfg.N_cs = cfg->pucch_cnfg.n_cs_an;
workers_common.pucch_cfg.n_rb_2 = cfg->pucch_cnfg.n_rb_cqi;
workers_common.pucch_cfg.srs_configured = false;
workers_common.pucch_cfg.n1_pucch_an = cfg->pucch_cnfg.n1_pucch_an;;
workers_common.pucch_cfg.n1_pucch_an = cfg->pucch_cnfg.n1_pucch_an;
// PDSCH configuration
workers_common.pdsch_p_b = cfg->pdsch_cnfg.p_b;
}
bool phy::init(phy_args_t *args,

View file

@ -1148,7 +1148,7 @@ void rrc::ue::send_connection_setup(bool is_setup)
phy_cfg->ul_pwr_ctrl_ded.p_srs_offset = 3;
phy_cfg->pdsch_cnfg_ded_present = true;
phy_cfg->pdsch_cnfg_ded = LIBLTE_RRC_PDSCH_CONFIG_P_A_DB_0;
phy_cfg->pdsch_cnfg_ded = parent->cfg.pdsch_cfg;
phy_cfg->cqi_report_cnfg_present = true;
if(parent->cfg.cqi_cfg.mode == RRC_CFG_CQI_MODE_APERIODIC) {