Commit edf903f7 authored by Francesco Mani's avatar Francesco Mani

pucch power control and handling of missed reception using confidence level

parent ffae55f6
......@@ -50,7 +50,7 @@
#include "T.h"
#define DEBUG_NR_PUCCH_RX 1
//#define DEBUG_NR_PUCCH_RX 1
NR_gNB_PUCCH_t *new_gNB_pucch(void){
NR_gNB_PUCCH_t *pucch;
......@@ -315,7 +315,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int16_t xr[24] __attribute__((aligned(32)));
//int16_t xrt[24] __attribute__((aligned(32)));
int32_t xrtmag=0;
int maxpos=0;
uint8_t maxpos=0;
int n2=0;
uint8_t index=0;
memset((void*)xr,0,24*sizeof(int16_t));
......@@ -339,7 +339,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
#endif
}
}
int32_t corr_re,corr_im,temp;
int32_t corr_re,corr_im,temp,no_corr=0;
int seq_index;
for(i=0;i<nr_sequences;i++){
......@@ -359,64 +359,76 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
#endif
if ((temp=corr_re*corr_re + corr_im*corr_im)>xrtmag) {
temp=corr_re*corr_re + corr_im*corr_im;
if (temp>xrtmag) {
xrtmag=temp;
maxpos=i;
}
else no_corr+=temp;
}
if (nr_sequences>1)
no_corr/=(nr_sequences-1);
uint8_t xrtmag_dB = dB_fixed(xrtmag);
//#ifdef DEBUG_NR_PUCCH_RX
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH 0 : maxpos %d\n",maxpos);
//#endif
#endif
index=maxpos;
#endif
// estimate CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(signal_energy(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)) - (10*gNB->measurements.n0_power_tot_dB);
int cqi;
if (SNRtimes10 < -640) cqi=0;
else if (SNRtimes10 > 635) cqi=255;
else cqi=(640+SNRtimes10)/5;
// first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = 0xff; // currently not valid
uci_pdu->ul_cqi = cqi; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid
uci_pdu->rssi = 0xffff; // currently not valid
if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB+gNB->pucch0_thres)) {
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) {
uci_pdu->sr->sr_indication = 1;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres);
} else {
uci_pdu->sr->sr_indication = 0;
uci_pdu->sr->sr_confidence_level = (gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres)-xrtmag_dB;
}
}
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 1;
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres);
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres);
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
}
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres);
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
LOG_I(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_power_tot_dB+11+gNB->pucch0_thres);
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
}
}
}
......
......@@ -192,7 +192,8 @@ int main(int argc, char **argv)
int cyclic_prefix_type = NFAPI_CP_NORMAL;
int run_initial_sync=0;
int do_pdcch_flag=1;
int pusch_tgt_snrx10 = 200;
int pucch_tgt_snrx10 = 200;
int loglvl=OAILOG_INFO;
float target_error_rate = 0.01;
......@@ -529,9 +530,9 @@ int main(int argc, char **argv)
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
// stub to configure frame_parms
......
......@@ -81,7 +81,7 @@ int main(int argc, char **argv)
//int freq_offset;
//int subframe_offset;
//char fname[40], vname[40];
int trial,n_trials=100,n_errors=0,ack_nack_errors=0;
int trial,n_trials=100,n_errors=0,ack_nack_errors=0,sr_errors=0;
uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
uint16_t Nid_cell=0;
uint64_t SSB_positions=0x01;
......@@ -494,6 +494,7 @@ int main(int argc, char **argv)
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0;
sr_errors=0;
n_errors = 0;
for (trial=0; trial<n_trials; trial++) {
bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
......@@ -548,15 +549,23 @@ int main(int argc, char **argv)
pucch_pdu.start_symbol_index = startingSymbolIndex;
pucch_pdu.prb_start = startingPRB;
nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
if(nr_bit==1)
ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
else
ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
free(uci_pdu.harq->harq_list);
if(sr_flag==1){
if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1)
sr_errors+=1;
}
if(nr_bit>0){
if(nr_bit==1)
ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
else
ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
free(uci_pdu.harq->harq_list);
}
}
else if (format==1) {
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,
&(payload_received),frame_parms,amp,nr_tti_tx,
m0,nrofSymbols,startingSymbolIndex,startingPRB,
startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
if(nr_bit==1)
ack_nack_errors+=((actual_payload^payload_received)&1);
else
......@@ -595,8 +604,11 @@ int main(int argc, char **argv)
}
n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
}
printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
if((float)ack_nack_errors/(float)(n_trials)<=target_error_rate){
if (sr_flag == 1)
printf("SR: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,sr_errors);
if(nr_bit > 0)
printf("ACK/NACK: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
if((float)(ack_nack_errors+sr_errors)/(float)(n_trials)<=target_error_rate){
printf("PUCCH test OK\n");
break;
}
......
......@@ -171,7 +171,8 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
double DS_TDL = .03;
int pusch_tgt_snrx10 = 200;
int pucch_tgt_snrx10 = 200;
int ibwps=24;
int ibwp_rboffset=41;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
......@@ -508,9 +509,9 @@ int main(int argc, char **argv)
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,200,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,200,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
......
......@@ -406,6 +406,7 @@ typedef struct NRRrcConfigurationReq_s {
int ssb_SubcarrierOffset;
int pdsch_AntennaPorts;
int pusch_TargetSNRx10;
int pucch_TargetSNRx10;
} gNB_RrcConfigurationReq;
......
......@@ -41,6 +41,7 @@
#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset"
#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts"
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
#define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon"
#define GNB_CONFIG_STRING_PHYSCELLID "physCellId"
#define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset"
......@@ -226,7 +227,9 @@
#define SSBPARAMS_DESC {{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,NULL,0,iptr:&ssb_SubcarrierOffset,defintval:0,TYPE_INT,0}}
#define PDSCHANTENNAPARAMS_DESC {{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,NULL,0,iptr:&pdsch_AntennaPorts,defintval:1,TYPE_INT,0}}
#define TARGETPOWER_DESC {{GNB_CONFIG_STRING_PUSCHTARGETPOWX10,NULL,0,iptr:&pusch_TargetSNRx10,defintval:200,TYPE_INT,0}}
#define TARGETPOWER_DESC { \
{GNB_CONFIG_STRING_PUSCHTARGETPOWX10,NULL,0,iptr:&pusch_TargetSNRx10,defintval:200,TYPE_INT,0},\
{GNB_CONFIG_STRING_PUCCHTARGETPOWX10,NULL,0,iptr:&pucch_TargetSNRx10,defintval:200,TYPE_INT,0}}
#define SCCPARAMS_DESC(scc) { \
{GNB_CONFIG_STRING_PHYSCELLID,NULL,0,i64ptr:scc->physCellId,defint64val:0,TYPE_INT64,0/*0*/}, \
......
......@@ -523,6 +523,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
int ssb_SubcarrierOffset = 31;
int pdsch_AntennaPorts = 1;
int pusch_TargetSNRx10 = 200;
int pucch_TargetSNRx10 = 200;
uint64_t ssb_bitmap=0xff;
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
prepare_scc(scc);
......@@ -675,6 +676,8 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = pdsch_AntennaPorts;
printf("pusch_TargetSNRx10 %d\n",pusch_TargetSNRx10);
NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = pusch_TargetSNRx10;
printf("pucch_TargetSNRx10 %d\n",pucch_TargetSNRx10);
NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = pucch_TargetSNRx10;
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
}//
......
......@@ -329,6 +329,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_tgt_snrx10,
int pucch_tgt_snrx10,
NR_ServingCellConfigCommon_t *scc,
int add_ue,
uint32_t rnti,
......@@ -354,7 +355,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
}
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = 0;
......
......@@ -375,7 +375,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
// TPC for PUCCH
dci_pdu_rel15[0].tpc = 1; // table 7.2.1-1 in 38.213
dci_pdu_rel15[0].tpc = UE_list->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
// PUCCH resource indicator
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
// PDSCH to HARQ TI
......
......@@ -50,7 +50,8 @@ void config_common(int Mod_idP,
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int tgt_snrx10,
int pusch_tgt_snrx10,
int pucch_tgt_snrx10,
NR_ServingCellConfigCommon_t *scc,
int nsa_flag,
uint32_t rnti,
......
......@@ -339,6 +339,8 @@ typedef struct gNB_MAC_INST_s {
NR_IF_Module_t *if_inst;
/// Pusch target SNR
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
/// TA command
int ta_command;
/// MAC CE flag indicating TA length
......
......@@ -78,7 +78,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
}
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int target_snrx10) {
// TODO
int max_harq_rounds = 4; // TODO define macro
int num_ucis = UL_info->uci_ind.num_ucis;
......@@ -93,18 +93,23 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
// handle harq
int harq_idx_s = 0;
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) {
// search for the right harq process
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
// if the gNB received ack with a good confidence or if the max harq rounds was reached
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
if (uci_pdu->harq->harq_list[harq_bit].harq_value == 0)
sched_ctrl->harq_processes[harq_idx].round++;
if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) ||
(sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) {
if (((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) &&
(uci_pdu->harq->harq_confidence_level == 0)) ||
(sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) {
// toggle NDI and reset round
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
sched_ctrl->harq_processes[harq_idx].round = 0;
}
else
sched_ctrl->harq_processes[harq_idx].round++;
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
harq_idx_s = harq_idx + 1;
break;
......@@ -268,7 +273,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
// clear DL/UL info for new scheduling round
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info);
handle_nr_uci(UL_info, &mac->UE_list.UE_sched_ctrl[0]);
handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],mac->pucch_target_snrx10);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0]);
......
......@@ -380,6 +380,7 @@ typedef struct {
int ssb_SubcarrierOffset;
int pdsch_AntennaPorts;
int pusch_TargetSNRx10;
int pucch_TargetSNRx10;
NR_BCCH_DL_SCH_Message_t *siblock1;
NR_ServingCellConfigCommon_t *servingcellconfigcommon;
NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS];
......
......@@ -187,6 +187,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
rrc->carrier.ssb_SubcarrierOffset,
rrc->carrier.pdsch_AntennaPorts,
rrc->carrier.pusch_TargetSNRx10,
rrc->carrier.pucch_TargetSNRx10,
(NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
0,
0, // WIP hardcoded rnti
......@@ -267,6 +268,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10;
rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10;
/// System Information INIT
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
init_NR_SI(rrc);
......
......@@ -239,6 +239,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
rrc->carrier.ssb_SubcarrierOffset,
rrc->carrier.pdsch_AntennaPorts,
rrc->carrier.pusch_TargetSNRx10,
rrc->carrier.pucch_TargetSNRx10,
NULL,
1, // add_ue flag
ue_context_p->ue_id_rnti,
......
......@@ -24,6 +24,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
servingCellConfigCommon = (
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment