mirror of https://github.com/PentHertz/srsLTE.git
Solved PDSCH Power Allocation p_b on eNB side
This commit is contained in:
parent
401cc9a20a
commit
dbf10cff17
|
@ -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);
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue