Commit 72d0a4ff authored by Robert Schmidt's avatar Robert Schmidt

Merge branch 'integration_2022_wk21' into 'develop'

integration_2022_wk21

See merge request oai/openairinterface5g!1564
parents 5bf454c7 9228f12d
......@@ -191,67 +191,6 @@ int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275));
}
/// Target code rate tables indexed by Imcs
/* TS 38.214 table 5.1.3.1-1 - MCS index table 1 for PDSCH */
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
/* TS 38.214 table 5.1.3.1-2 - MCS index table 2 for PDSCH */
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
/* TS 38.214 table 5.1.3.1-3 - MCS index table 3 for PDSCH */
uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 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};
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 1:
return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
break;
case 2:
return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
break;
case 3:
return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
break;
default:
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
return(0);
break;
}
}
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 1:
return (nr_target_code_rate_table1[Imcs]);
break;
case 2:
return (nr_target_code_rate_table2[Imcs]);
break;
case 3:
return (nr_target_code_rate_table3[Imcs]);
break;
default:
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
return(0);
break;
}
}
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
uint8_t count=0, start=0, start_set=0;
......
......@@ -69,12 +69,6 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart);
extern uint16_t nr_target_code_rate_table1[29];
extern uint16_t nr_target_code_rate_table2[28];
extern uint16_t nr_target_code_rate_table3[29];
extern uint16_t nr_tbs_table[93];
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
int get_subband_size(int NPRB,int size);
void SLIV2SL(int SLIV,int *S,int *L);
int get_dmrs_port(int nl, uint16_t dmrs_ports);
......
......@@ -434,6 +434,9 @@ typedef struct {
uint8_t mcs;
uint8_t ndi;
uint8_t rv;
uint16_t targetCodeRate;
uint8_t qamModOrder;
uint32_t TBS;
uint8_t tb2_mcs;
uint8_t tb2_ndi;
uint8_t tb2_rv;
......
......@@ -469,18 +469,6 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int *F,
uint8_t BG);
/*!\fn uint32_t nr_compute_tbs
\brief This function returns the TBS in bits as per 6.1.4.2 of TS 38.214
*/
uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl);
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f);
......
......@@ -49,11 +49,6 @@ void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type);
void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list);
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
void nr_pdsch_codeword_scrambling(uint8_t *in,
uint32_t size,
uint8_t q,
......
......@@ -306,7 +306,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
unsigned int crc=1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
impp.Zc = &harq->Z;
float Coderate = 0.0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
uint32_t A = rel15->TBSize[0]<<3;
unsigned char *a=harq->pdu;
......@@ -369,10 +368,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
}
if (rel15->targetCodeRate[0]<1000)
Coderate = (float)rel15->targetCodeRate[0] /(float) 1024;
else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
Coderate = (float)rel15->targetCodeRate[0] /(float) 2048;
// target_code_rate is in 0.1 units
float Coderate = (float) rel15->targetCodeRate[0] / 10240.0f;
LOG_D(PHY,"DLSCH Coderate %f\n",Coderate);
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
impp.BG = 2;
......
......@@ -60,14 +60,6 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
void compute_nr_prach_seq(uint8_t short_sequence,
uint8_t num_sequences,
uint8_t rootSequenceIndex,
......
......@@ -408,12 +408,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
phy_vars_gNB->nbDecode = 0;
harq_process->processedSegments = 0;
double Coderate = 0.0;
// ------------------------------------------------------------------
uint16_t nb_rb = pusch_pdu->rb_size;
uint8_t Qm = pusch_pdu->qam_mod_order;
uint16_t R = pusch_pdu->target_code_rate;
uint8_t mcs = pusch_pdu->mcs_index;
uint8_t n_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------
......@@ -442,13 +439,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
A = (harq_process->TBS)<<3;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %d RV %d round %d\n",
harq_pid, A, G, mcs, n_layers, nb_rb, Qm, R, pusch_pdu->pusch_data.rv_index, harq_process->round);
// target_code_rate is in 0.1 units
float Coderate = (float) pusch_pdu->target_code_rate / 10240.0f;
if (R<1024)
Coderate = (float) R /(float) 1024;
else
Coderate = (float) R /(float) 2048;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d\n",
harq_pid, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round);
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
p_decParams->BG = 2;
......
......@@ -430,8 +430,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_symb_sch,
uint8_t nr_slot_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag) {
uint8_t is_crnti) {
uint32_t A,E;
uint32_t G;
uint32_t ret,offset;
......@@ -449,7 +448,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,harq_process->rvidx);
uint8_t kc;
uint16_t nb_rb;// = 30;
double Coderate;// = 0.0;
uint8_t dmrs_Type = harq_process->dmrsConfigType;
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
uint8_t nb_re_dmrs;
......@@ -499,21 +497,18 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
*/
nb_rb = harq_process->nb_rb;
harq_process->trials[harq_process->DLround]++;
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
A = harq_process->TBS;
ret = dlsch->max_ldpc_iterations + 1;
dlsch->last_iteration_cnt = ret;
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",
frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
// target_code_rate is in 0.1 units
float Coderate = (float) harq_process->R / 10240.0f;
if ((harq_process->R)<1024)
Coderate = (float) (harq_process->R) /(float) 1024;
else
Coderate = (float) (harq_process->R) /(float) 2048;
LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d Coderate %f\n",
frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, harq_process->mcs, harq_process->Nl, nb_symb_sch, nb_rb, harq_process->Qm, Coderate);
if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
p_decParams->BG = 2;
......
......@@ -260,13 +260,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return -1;
}
dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
if (dlsch0_harq->Qm == 0 || dlsch0_harq->R == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
#ifdef DEBUG_HARQ
printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode);
printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
......@@ -2600,7 +2593,7 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
}
if (dlsch1_harq) {
switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
switch (dlsch1_harq->Qm) {
case 2 :
if (rx_type==rx_standard) {
nr_dlsch_qpsk_llr(frame_parms,
......
......@@ -1013,8 +1013,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint16_t nb_symb_sch,
uint8_t nr_slot_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag);
uint8_t is_crnti);
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
......
......@@ -192,14 +192,14 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
unsigned int crc = 1;
NR_UL_UE_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
uint16_t nb_rb = harq_process->pusch_pdu.rb_size;
uint32_t A = harq_process->pusch_pdu.pusch_data.tb_size*8;
uint32_t A = harq_process->pusch_pdu.pusch_data.tb_size<<3;
uint32_t *pz = &harq_process->Z;
uint8_t mod_order = nr_get_Qm_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
uint16_t R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
uint8_t mod_order = harq_process->pusch_pdu.qam_mod_order;
uint16_t Kr=0;
uint32_t r_offset=0;
uint32_t F=0;
float Coderate = 0.0;
// target_code_rate is in 0.1 units
float Coderate = (float) harq_process->pusch_pdu.target_code_rate / 10240.0f;
///////////
/////////////////////////////////////////////////////////////////////////////////////////
......@@ -207,7 +207,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d\n", A, G, mod_order);
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G, mod_order, Coderate);
LOG_D(NR_PHY, "harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n",
harq_pid,harq_process->ndi,harq_process->pusch_pdu.pusch_data.new_data_indicator);
......@@ -264,11 +264,6 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
///////////////////////// b---->| block segmentation |---->c /////////////////////////
///////////
if (R<1024)
Coderate = (float) R /(float) 1024;
else
Coderate = (float) R /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
harq_process->BG = 2;
}
......
......@@ -315,6 +315,9 @@ void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
dlsch0_harq->mcs = dlsch_config_pdu->mcs;
dlsch0_harq->rvidx = dlsch_config_pdu->rv;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
dlsch0_harq->R = dlsch_config_pdu->targetCodeRate;
dlsch0_harq->Qm = dlsch_config_pdu->qamModOrder;
dlsch0_harq->TBS = dlsch_config_pdu->TBS;
dlsch0_harq->tbslbrm = dlsch_config_pdu->tbslbrm;
dlsch0_harq->nscid = dlsch_config_pdu->nscid;
dlsch0_harq->dlDmrsScramblingId = dlsch_config_pdu->dlDmrsScramblingId;
......
......@@ -802,8 +802,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nb_symb_sch,
nr_slot_rx,
harq_pid,
pdsch==PDSCH?1:0,
dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
pdsch==PDSCH);
LOG_T(PHY,"dlsch decoding, ret = %d\n", ret);
......@@ -879,8 +878,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nb_symb_sch,
nr_slot_rx,
harq_pid,
pdsch==PDSCH?1:0,//proc->decoder_switch,
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
pdsch==PDSCH);//proc->decoder_switch
LOG_T(PHY,"CW dlsch decoding, ret1 = %d\n", ret1);
stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
......
......@@ -47,6 +47,7 @@
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
//#define DEBUG_NR_DLSCHSIM
......@@ -430,13 +431,10 @@ int main(int argc, char **argv)
NR_gNB_DLSCH_t *dlsch = msgDataTx.dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
//time_stats_t *rm_stats, *te_stats, *i_stats;
uint8_t is_crnti = 0, llr8_flag = 0;
uint8_t is_crnti = 0;
unsigned int TBS = 8424;
unsigned int available_bits;
uint8_t nb_re_dmrs = 6; // No data in dmrs symbol
uint16_t length_dmrs = 1;
unsigned char mod_order;
uint16_t rate;
uint8_t Nl = 1;
uint8_t rvidx = 0;
dlsch->rnti = 1;
......@@ -444,9 +442,9 @@ int main(int argc, char **argv)
dlsch->harq_processes[0]->rvidx = rvidx;*/
//printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
// dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
mod_order = nr_get_Qm_dl(Imcs, mcs_table);
rate = nr_get_code_rate_dl(Imcs, mcs_table);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
unsigned char mod_order = nr_get_Qm_dl(Imcs, mcs_table);
uint16_t rate = nr_get_code_rate_dl(Imcs, mcs_table);
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
//dlsch->harq_ids[subframe]= 0;
......@@ -478,6 +476,7 @@ int main(int argc, char **argv)
harq_process->Qm = mod_order;
harq_process->rvidx = rvidx;
harq_process->R = rate;
harq_process->TBS = TBS;
harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
harq_process->dlDmrsSymbPos = 4;
harq_process->n_dmrs_cdm_groups = 1;
......@@ -551,7 +550,7 @@ int main(int argc, char **argv)
ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms,
dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch,
slot,harq_pid, is_crnti, llr8_flag);
slot,harq_pid, is_crnti);
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);
......
......@@ -47,6 +47,7 @@
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "common/utils/threadPool/thread-pool.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
//#define DEBUG_NR_ULSCHSIM
......@@ -461,7 +462,7 @@ int main(int argc, char **argv)
rel15_ul->pusch_data.rv_index = rvidx;
rel15_ul->nrOfLayers = Nl;
rel15_ul->target_code_rate = code_rate;
rel15_ul->pusch_data.tb_size = TBS/8;
rel15_ul->pusch_data.tb_size = TBS>>3;
///////////////////////////////////////////////////
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
......@@ -488,7 +489,9 @@ int main(int argc, char **argv)
harq_process_ul_ue->pusch_pdu.nr_of_symbols = nb_symb_sch;
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
harq_process_ul_ue->pusch_pdu.pusch_data.rv_index = rvidx;
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS/8;
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS>>3;
harq_process_ul_ue->pusch_pdu.target_code_rate = code_rate;
harq_process_ul_ue->pusch_pdu.qam_mod_order = mod_order;
unsigned char *test_input = harq_process_ul_ue->a;
///////////
......
......@@ -1165,6 +1165,7 @@ int main(int argc, char **argv)
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
ul_config.ul_config_list[0].pusch_config_pdu.dmrs_ports = ((1<<precod_nbr_layers)-1);
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
ul_config.ul_config_list[0].pusch_config_pdu.target_code_rate = code_rate;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
......
......@@ -62,12 +62,15 @@
#define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres"
#define CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER "dl_bler_target_upper"
#define CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER "dl_bler_target_lower"
#define CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD "dl_rd2_bler_threshold"
#define CONFIG_STRING_MACRLC_DL_MAX_MCS "dl_max_mcs"
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper"
#define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower"
#define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs"
#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max"
#define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb"
#define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* MacRLC configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
......@@ -97,8 +100,10 @@
{CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase DL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_RD2_BLER_THRESHOLD, "Threshold of RD2/RETX2 BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.01, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_DL_MAX_MCS, "Maximum DL MCS that should be used", 0, u8ptr:NULL, defintval:28, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \
{CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \
......@@ -127,10 +132,13 @@
#define MACRLC_PUSCHFAILURETHRES_IDX 21
#define MACRLC_DL_BLER_TARGET_UPPER_IDX 22
#define MACRLC_DL_BLER_TARGET_LOWER_IDX 23
#define MACRLC_DL_RD2_BLER_THRESHOLD_IDX 24
#define MACRLC_DL_MAX_MCS_IDX 25
#define MACRLC_HARQ_ROUND_MAX_IDX 26
#define MACRLC_MIN_GRANT_PRB_IDX 27
#define MACRLC_MIN_GRANT_MCS_IDX 28
#define MACRLC_DL_MAX_MCS_IDX 24
#define MACRLC_UL_BLER_TARGET_UPPER_IDX 25
#define MACRLC_UL_BLER_TARGET_LOWER_IDX 26
#define MACRLC_UL_MAX_MCS_IDX 27
#define MACRLC_HARQ_ROUND_MAX_IDX 28
#define MACRLC_MIN_GRANT_PRB_IDX 29
#define MACRLC_MIN_GRANT_MCS_IDX 30
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
......@@ -873,10 +873,14 @@ void RCconfig_nr_macrlc() {
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
}
RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr);
RC.nrmac[j]->dl_bler_target_upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
RC.nrmac[j]->dl_bler_target_lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
RC.nrmac[j]->dl_rd2_bler_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_RD2_BLER_THRESHOLD_IDX].dblptr);
RC.nrmac[j]->dl_max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
NR_bler_options_t *dl_bler_options = &RC.nrmac[j]->dl_bler;
dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr);
dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr);
dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr);
NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler;
ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr);
ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr);
ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr);
RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr);
RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr);
RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr);
......
......@@ -49,16 +49,15 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t nbp_re, nb_re;
uint32_t nr_tbs=0;
uint32_t Ninfo, Np_info, C;
uint8_t n, scale;
uint8_t n;
LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl);
nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
nb_re = min(156, nbp_re) * nb_rb;
scale = (R>1024)?11:10;
// Intermediate number of information bits
Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling;
// R is tabulated as 10 times the actual code rate
Ninfo = ((nb_re * R * Qm * Nl / 10)>>10)>>tb_scaling;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
......@@ -73,7 +72,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
if (R <= 2560) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
......
......@@ -2095,17 +2095,15 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS*dmrs_length - N_PRB_oh;
LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
uint16_t R;
uint32_t TBS=0;
uint8_t table_idx, Qm;
/*uint8_t mcs_table = config.pdsch_config.mcs_table.value;
uint8_t ss_type = params_rel15.search_space_type;
uint8_t dci_format = params_rel15.dci_format;
get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/
table_idx = 0;
R = nr_get_code_rate_dl(Imcs, table_idx);
Qm = nr_get_Qm_dl(Imcs, table_idx);
uint8_t table_idx = 0;
uint16_t R = nr_get_code_rate_dl(Imcs, table_idx);
uint8_t Qm = nr_get_Qm_dl(Imcs, table_idx);
TBS = nr_compute_tbs(Qm,
R,
......@@ -2126,25 +2124,25 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx,N_RE_prime*pdsch_rel15->rbSize*pdsch_rel15->NrOfCodewords );
}
// the following tables contain 10 times the value reported in 214 (in line with SCF specification and to avoid fractional values)
//Table 5.1.3.1-1 of 38.214
uint16_t Table_51311[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
{4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
uint16_t Table_51311[29][2] = {{2,1200},{2,1570},{2,1930},{2,2510},{2,3080},{2,3790},{2,4490},{2,5260},{2,6020},{2,6790},{4,3400},{4,3780},{4,4340},{4,4900},{4,5530},{4,6160},
{4,6580},{6,4380},{6,4660},{6,5170},{6,5670},{6,6160},{6,6660},{6,7190},{6,7720},{6,8220},{6,8730}, {6,9100}, {6,9480}};
//Table 5.1.3.1-2 of 38.214
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},
{6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}};
uint16_t Table_51312[28][2] = {{2,1200},{2,1930},{2,3080},{2,4490},{2,6020},{4,3780},{4,4340},{4,4900},{4,5530},{4,6160},{4,6580},{6,4660},{6,5170},{6,5670},{6,6160},{6,6660},
{6,7190},{6,7720},{6,8220},{6,8730},{8,6825},{8,7110},{8,7540},{8,7970},{8,8410},{8,8850},{8,9165},{8,9480}};
//Table 5.1.3.1-3 of 38.214
uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340},
{4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}};
uint16_t Table_51313[29][2] = {{2,300},{2,400},{2,500},{2,640},{2,780},{2,990},{2,1200},{2,1570},{2,1930},{2,2510},{2,3080},{2,3790},{2,4490},{2,5260},{2,6020},{4,3400},
{4,3780},{4,4340},{4,4900},{4,5530},{4,6160},{6,4380},{6,4660},{6,5170},{6,5670},{6,6160},{6,6660},{6,7190},{6,7720}};
uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},
{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}};
uint16_t Table_61411[28][2] = {{2,1200},{2,1570},{2,1930},{2,2510},{2,3080},{2,3790},{2,4490},{2,5260},{2,6020},{2,6790},{4,3400},{4,3780},{4,4340},{4,4900},{4,5530},{4,6160},
{4,6580},{6,4660},{6,5170},{6,5670},{6,6160},{6,6660},{6,7190},{6,7720},{6,8220},{6,8730},{6,9100},{6,9480}};
uint16_t Table_61412[28][2] = {{2,300},{2,400},{2,500},{2,640},{2,780},{2,990},{2,1200},{2,1570},{2,1930},{2,2510},{2,3080},{2,3790},{2,4490},{2,5260},{2,6020},{2,6790},
{4,3780},{4,4340},{4,4900},{4,5530},{4,6160},{4,6580},{4,6990},{4,7720},{6,5670},{6,6160},{6,6660},{6,7720}};
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
......
......@@ -121,6 +121,23 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset);
int get_bw_tbslbrm(NR_BWP_t *genericParameters,
......
......@@ -936,6 +936,23 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
return -1;
}
dlsch_config_pdu_1_0->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_0->mcs, dlsch_config_pdu_1_0->mcs_table);
int R = nr_get_code_rate_dl(dlsch_config_pdu_1_0->mcs, dlsch_config_pdu_1_0->mcs_table);
dlsch_config_pdu_1_0->targetCodeRate = R;
if (dlsch_config_pdu_1_0->targetCodeRate == 0 || dlsch_config_pdu_1_0->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
int nb_re_dmrs = ((dlsch_config_pdu_1_0->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? 6:4)*dlsch_config_pdu_1_0->n_dmrs_cdm_groups;
dlsch_config_pdu_1_0->TBS = nr_compute_tbs(dlsch_config_pdu_1_0->qamModOrder,
R,
dlsch_config_pdu_1_0->number_rbs,
dlsch_config_pdu_1_0->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_0->dlDmrsSymbPos),
nb_rb_oh, 0, 1);
int bw_tbslbrm;
if (mac->scc || mac->scc_SIB || mac->cg) {
NR_BWP_t genericParameters = mac->scc ? mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters :
......@@ -1353,6 +1370,25 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dl_config->number_pdus = dl_config->number_pdus + 1;
/* TODO same calculation for MCS table as done in UL */
dlsch_config_pdu_1_1->mcs_table = (pdsch_Config->mcs_Table) ? (*pdsch_Config->mcs_Table + 1) : 0;
dlsch_config_pdu_1_1->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table);
int R = nr_get_code_rate_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table);
dlsch_config_pdu_1_1->targetCodeRate = R;
if (dlsch_config_pdu_1_1->targetCodeRate == 0 || dlsch_config_pdu_1_1->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
uint8_t Nl = 0;
for (int i = 0; i < 12; i++) { // max 12 ports
if ((dlsch_config_pdu_1_1->dmrs_ports>>i)&0x01) Nl += 1;
}
int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
int nb_re_dmrs = ((dmrs_type == NULL) ? 6:4)*dlsch_config_pdu_1_1->n_dmrs_cdm_groups;
dlsch_config_pdu_1_1->TBS = nr_compute_tbs(dlsch_config_pdu_1_1->qamModOrder,
R,
dlsch_config_pdu_1_1->number_rbs,
dlsch_config_pdu_1_1->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_1->dlDmrsSymbPos),
nb_rb_oh, 0, Nl);
// TBS_LBRM according to section 5.4.2.1 of 38.212
long *maxMIMO_Layers = mac->cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers;
......
......@@ -840,8 +840,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
mappingtype, add_pos, dmrslength,
pusch_config_pdu->start_symbol_index,
mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position);
if ((mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled))
if (*dci_format != NR_UL_DCI_FORMAT_0_1) {
if (mac->ULbwp[ul_bwp_id-1] && (pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled)) {
if (*dci_format != NR_UL_DCI_FORMAT_0_1)
pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1;
}
else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled))
......@@ -891,7 +891,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
rnti_types[rnti_type]);
pusch_config_pdu->ul_dmrs_symb_pos = l_prime_mask;
pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
uint16_t R = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
pusch_config_pdu->target_code_rate = R;
pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
if (pusch_config_pdu->target_code_rate == 0 || pusch_config_pdu->qam_mod_order == 0) {
......@@ -910,14 +911,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
// Compute TBS
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
pusch_config_pdu->target_code_rate,
R,
pusch_config_pdu->rb_size,
pusch_config_pdu->nr_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
N_PRB_oh,
0, // TBR to verify tb scaling
pusch_config_pdu->nrOfLayers)/8;
pusch_config_pdu->nrOfLayers)>>3;
return 0;
}
......
......@@ -551,8 +551,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].frame_type == FDD,"Dynamic TDD not handled yet\n");
for (int slot = 0; slot < n; ++slot) {
if (RC.nrmac[Mod_idP]->common_channels[0].frame_type == FDD ||
(slot != 0))
RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dl_slots) << (slot % 64);
RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
......@@ -591,31 +589,9 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
if (CellGroup) {
if (get_softmodem_params()->sa) {
calculate_preferred_dl_tda(Mod_idP, NULL);
}
const NR_ServingCellConfig_t *servingCellConfig = NULL;
if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) {
if(CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated)
servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated;
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
if(bwpList) {
AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
for (int i = 0; i < bwpList->list.count; ++i) {
const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
calculate_preferred_dl_tda(Mod_idP, bwp);
}
}
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
if(ubwpList) {
AssertFatal(ubwpList->list.count > 0, "uplinkBWP_ToAddModList no BWPs!\n");
for (int i = 0; i < ubwpList->list.count; ++i) {
const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
calculate_preferred_ul_tda(Mod_idP, ubwp);
}
}
}
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
if (add_ue == 1 && get_softmodem_params()->phy_test) {
......
......@@ -465,27 +465,24 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
int FR = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257 ? nr_FR2 : nr_FR1;
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
uint8_t start_next_period = rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot;
int eff_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
// we can't schedule msg2 before sl_ahead since prach
int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
while ((eff_slot-rach_slot)<=sl_ahead) {
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
eff_slot += tdd_period_slot;
}
if (FR==nr_FR2) {
int num_tdd_period = *msg2_slot/tdd_period_slot;
int num_tdd_period = (eff_slot%nr_slots_per_frame[mu])/tdd_period_slot;
while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) {
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
num_tdd_period = *msg2_slot/tdd_period_slot;
eff_slot += tdd_period_slot;
num_tdd_period = (eff_slot % nr_slots_per_frame[mu])/tdd_period_slot;
}
if(tdd_beam_association[num_tdd_period] == -1)
tdd_beam_association[num_tdd_period] = beam_index;
}
*msg2_frame=(rach_frame + eff_slot/nr_slots_per_frame[mu])%1024;
*msg2_slot=eff_slot%nr_slots_per_frame[mu];
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while (*msg2_frame > frame_limit
......@@ -1109,10 +1106,11 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
int TBS = 0;
while(TBS<7) { // TBS for msg3 is 7 bytes (except for RRCResumeRequest1 currently not implemented)
mcsindex++;
pusch_pdu->target_code_rate = nr_get_code_rate_ul(mcsindex,pusch_pdu->mcs_table);
int R = nr_get_code_rate_ul(mcsindex,pusch_pdu->mcs_table);
pusch_pdu->target_code_rate = R;
pusch_pdu->qam_mod_order = nr_get_Qm_ul(mcsindex,pusch_pdu->mcs_table);
TBS = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
R,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
num_dmrs_symb*12, // nb dmrs set for no data in dmrs symbol
......@@ -1200,20 +1198,13 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
}
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
{
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
//TODO time domain assignment for msg2 needs to be improved
uint8_t time_domain_assignment;
if(cc->frame_type == TDD)
time_domain_assignment = 1;
else
time_domain_assignment = 0;
int mcsIndex = -1; // initialization value
int rbStart = 0;
int rbSize = 8;
......@@ -1253,6 +1244,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
}
// Calculate number of symbols
int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
int startSymbolIndex, nrOfSymbols;
const int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
......@@ -1799,7 +1791,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing;
pdsch_pdu_rel15->CyclicPrefix = 0;
pdsch_pdu_rel15->NrOfCodewords = 1;
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
int R = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
pdsch_pdu_rel15->targetCodeRate[0] = R;
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
......@@ -1981,8 +1974,8 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
if (harq->is_waiting == 0) {
if (harq->round == 0) {
if (stats->dlsch_errors == 0) {
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
if (stats->dl.errors == 0) {
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
UE_info->active[UE_id] = true;
UE_info->Msg4_ACKed[UE_id] = true;
......
......@@ -275,7 +275,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
__func__,
UE_id);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
ps->nrOfLayers = target_dl_Nl;
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
......@@ -435,18 +436,25 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
if (tda < 0)
return false;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
AssertFatal(tda < tdaList->list.count,
const int temp_tda = get_ul_tda(nr_mac, scc, slot);
if (temp_tda < 0)
return false;
AssertFatal(temp_tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
tda,
temp_tda,
tdaList->list.count);
int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, tda, mu);
int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, temp_tda, mu);
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
const int tda = get_ul_tda(nr_mac, scc, sched_slot);
if (tda < 0)
return false;
AssertFatal(tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
tda,
tdaList->list.count);
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
* limitations). Note that if K2 or the TDD configuration is changed, below
* conditions might exclude each other and never be true */
......
......@@ -113,18 +113,18 @@ uint8_t nr_ss_first_symb_idx_scs_120_120_mux3[4] = {4,8,2,6};
uint8_t nr_max_number_of_candidates_per_slot[4] = {44, 36, 22, 20};
uint8_t nr_max_number_of_cces_per_slot[4] = {56, 56, 48, 32};
// CQI TABLES
// CQI TABLES (10 times the value in 214 to adequately compare with R)
// Table 1 (38.214 5.2.2.1-2)
uint16_t cqi_table1[16][2] = {{0,0},{2,78},{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},
{4,490},{4,616},{6,466},{6,567},{6,666},{6,772},{6,873},{6,948}};
uint16_t cqi_table1[16][2] = {{0,0},{2,780},{2,1200},{2,1930},{2,3080},{2,4490},{2,6020},{4,3780},
{4,4900},{4,6160},{6,4660},{6,5670},{6,6660},{6,7720},{6,8730},{6,9480}};
// Table 2 (38.214 5.2.2.1-3)
uint16_t cqi_table2[16][2] = {{0,0},{2,78},{2,193},{2,449},{4,378},{4,490},{4,616},{6,466},
{6,567},{6,666},{6,772},{6,873},{8,711},{8,797},{8,885},{8,948}};
uint16_t cqi_table2[16][2] = {{0,0},{2,780},{2,1930},{2,4490},{4,3780},{4,4900},{4,6160},{6,4660},
{6,5670},{6,6660},{6,7720},{6,8730},{8,7110},{8,7970},{8,8850},{8,9480}};
// Table 2 (38.214 5.2.2.1-4)
uint16_t cqi_table3[16][2] = {{0,0},{2,30},{2,50},{2,78},{2,120},{2,193},{2,308},{2,449},
{2,602},{4,378},{4,490},{4,616},{6,466},{6,567},{6,666},{6,772}};
uint16_t cqi_table3[16][2] = {{0,0},{2,300},{2,500},{2,780},{2,1200},{2,1930},{2,3080},{2,4490},
{2,6020},{4,3780},{4,4900},{4,6160},{6,4660},{6,5670},{6,6660},{6,7720}};
static inline uint8_t get_max_candidates(uint8_t scs) {
......@@ -145,7 +145,6 @@ uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl) {
}
uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
int layers,
int N1, int N2,
......@@ -169,20 +168,19 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
AssertFatal(1==0,"More than 2 antenna ports not yet supported\n");
}
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
{
if (cqi_idx <= 0) {
LOG_E(NR_MAC, "invalid cqi_idx %d, default to MCS 9\n", cqi_idx);
return 9;
}
void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch,
NR_UE_sched_ctrl_t *sched_ctrl,
uint8_t *target_mcs,
uint8_t mcs_table_idx) {
if (sched_ctrl->set_mcs) {
// TODO for wideband case and multiple TB
int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
uint16_t target_coderate,target_qm;
if (cqi_idx>0) {
int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table;
if (cqi_table != mcs_table_idx)
LOG_W(NR_MAC,"Indices of MCS tables don't correspond yet, cri_ri_li_pmi_cqi_report.cqi_table %d, mcs_table_index %d\n",cqi_table,mcs_table_idx);
if (mcs_table != cqi_table) {
LOG_E(NR_MAC, "indices of CQI (%d) and MCS (%d) tables don't correspond yet\n", cqi_table, mcs_table);
return 9;
}
uint16_t target_coderate, target_qm;
switch (cqi_table) {
case 0:
target_qm = cqi_table1[cqi_idx][0];
......@@ -199,21 +197,16 @@ void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch,
default:
AssertFatal(1==0,"Invalid cqi table index %d\n",cqi_table);
}
int max_mcs = 28;
int R,Qm;
if (mcs_table_idx == 1)
max_mcs = 27;
for (int i=0; i<=max_mcs; i++) {
R = nr_get_code_rate_dl(i, mcs_table_idx);
Qm = nr_get_Qm_dl(i, mcs_table_idx);
if ((Qm == target_qm) && (target_coderate <= R)) {
*target_mcs = i;
break;
}
}
}
sched_ctrl->set_mcs = false;
const int max_mcs = mcs_table == 1 ? 27 : 28;
for (int i = 0; i <= max_mcs; i++) {
const int R = nr_get_code_rate_dl(i, mcs_table);
const int Qm = nr_get_Qm_dl(i, mcs_table);
if (Qm == target_qm && target_coderate <= R)
return i;
}
LOG_E(NR_MAC, "could not find maximum MCS from cqi_idx %d, default to 9\n", cqi_idx);
return 9;
}
void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) {
......@@ -768,6 +761,51 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1,
: num_dmrs_cdm_grps_no_data * 4;
}
#define BLER_UPDATE_FRAME 10
#define BLER_FILTER 0.9f
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame)
{
/* first call: everything is zero. Initialize to sensible default */
if (bler_stats->last_frame == 0 && bler_stats->mcs == 0) {
bler_stats->last_frame = frame;
bler_stats->mcs = 9;
bler_stats->bler = (bler_options->lower + bler_options->upper) / 2.0f;
}
int diff = frame - bler_stats->last_frame;
if (diff < 0) // wrap around
diff += 1024;
max_mcs = min(max_mcs, bler_options->max_mcs);
const uint8_t old_mcs = min(bler_stats->mcs, max_mcs);
if (diff < BLER_UPDATE_FRAME)
return old_mcs; // no update
// last update is longer than x frames ago
const int dtx = (int)(stats->rounds[0] - bler_stats->rounds[0]);
const int dretx = (int)(stats->rounds[1] - bler_stats->rounds[1]);
const float bler_window = dtx > 0 ? (float) dretx / dtx : bler_stats->bler;
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
int new_mcs = old_mcs;
if (bler_stats->bler < bler_options->lower && old_mcs < max_mcs && dtx > 9)
new_mcs += 1;
else if ((bler_stats->bler > bler_options->upper && old_mcs > 6) // above threshold
|| (dtx <= 3 && old_mcs > 9)) // no activity
new_mcs -= 1;
// else we are within threshold boundaries
bler_stats->last_frame = frame;
bler_stats->mcs = new_mcs;
memcpy(bler_stats->rounds, stats->rounds, sizeof(stats->rounds));
LOG_D(MAC, "frame %4d MCS %d -> %d (dtx %d, dretx %d, BLER wnd %.3f avg %.6f)\n",
frame, old_mcs, new_mcs, dtx, dretx, bler_window, bler_stats->bler);
return new_mcs;
}
void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
nr_scs_e scs_common,
nr_scs_e pdcch_scs,
......@@ -2359,7 +2397,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellG
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
memset(sched_ctrl, 0, sizeof(*sched_ctrl));
sched_ctrl->set_mcs = true;
sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
sched_ctrl->set_pmi = false;
sched_ctrl->ta_frame = 0;
sched_ctrl->ta_update = 31;
......@@ -2659,6 +2697,8 @@ void nr_csirs_scheduling(int Mod_idP,
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map;
UE_info->sched_csirs = false;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
......@@ -2691,6 +2731,7 @@ void nr_csirs_scheduling(int Mod_idP,
if((frame*n_slots_frame+slot-offset)%period == 0) {
LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d\n",frame,slot);
UE_info->sched_csirs = true;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_csirs_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
......@@ -2858,6 +2899,7 @@ void nr_csirs_scheduling(int Mod_idP,
void nr_mac_update_timers(module_id_t module_id,
frame_t frame,
sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
const NR_list_t *UE_list = &UE_info->list;
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
......@@ -2894,12 +2936,11 @@ void nr_mac_update_timers(module_id_t module_id,
cg->spCellConfig &&
cg->spCellConfig->spCellConfigDedicated ?
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
int **preferred_dl_tda = RC.nrmac[module_id]->preferred_dl_tda;
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
const uint8_t layers = set_dl_nrOfLayers(sched_ctrl);
const int tda = bwp && preferred_dl_tda[bwp->bwp_Id][slot] >= 0 ?
preferred_dl_tda[bwp->bwp_Id][slot] : (ps->time_domain_allocation >= 0 ? ps->time_domain_allocation : 0);
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
nr_set_pdsch_semi_static(sib1,
scc,
......@@ -2917,14 +2958,13 @@ void nr_mac_update_timers(module_id_t module_id,
cg->spCellConfig->spCellConfigDedicated &&
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
int **preferred_ul_tda = RC.nrmac[module_id]->preferred_ul_tda;
NR_pusch_semi_static_t *ups = &sched_ctrl->pusch_semi_static;
int dci_format = get_dci_format(sched_ctrl);
const uint8_t num_dmrs_cdm_grps_no_data = (ubwp || ubwpd) ? 1 : 2;
const uint8_t nrOfLayers = 1;
const int utda = ubwp && preferred_ul_tda[ubwp->bwp_Id][slot] >= 0 ?
preferred_ul_tda[ubwp->bwp_Id][slot] : (ups->time_domain_allocation >= 0 ? ups->time_domain_allocation : 0);
const int utda = get_ul_tda(RC.nrmac[module_id], scc, slot);
nr_set_pusch_semi_static(sib1,
scc,
......
......@@ -838,8 +838,8 @@ static void handle_dl_harq(module_id_t mod_id,
harq->round = 0;
harq->ndi ^= 1;
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
stats->dlsch_errors++;
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
stats->dl.errors++;
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dl.errors);
} else {
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
......@@ -1250,7 +1250,12 @@ void evaluate_cqi_report(uint8_t *payload,
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_2tb = temp_cqi;
LOG_D(MAC,"Wide-band CQI for the second TB %d\n", temp_cqi);
}
sched_ctrl->set_mcs = true;
// TODO for wideband case and multiple TB
const int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb;
const int mcs_table = sched_ctrl->pdsch_semi_static.mcsTableIdx;
const int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table;
sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_table, cqi_idx);
}
......
......@@ -388,13 +388,6 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
int x_overhead,
uint8_t numdmrscdmgroupnodata,
uint8_t tb_scaling);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
int NRRIV2BW(int locationAndBandwidth,int N_RB);
......@@ -514,16 +507,13 @@ uint16_t set_pm_index(NR_UE_sched_ctrl_t *sched_ctrl,
int xp_pdsch_antenna_ports,
int codebook_mode);
void set_dl_mcs(NR_sched_pdsch_t *sched_pdsch,
NR_UE_sched_ctrl_t *sched_ctrl,
uint8_t *target_mcs,
uint8_t mcs_table_idx);
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl);
int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl);
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp);
void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp);
const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
......@@ -538,6 +528,12 @@ bool nr_find_nb_rb(uint16_t Qm,
uint32_t *tbs,
uint16_t *nb_rb);
int get_mcs_from_bler(const NR_bler_options_t *bler_options,
const NR_mac_dir_stats_t *stats,
NR_bler_stats_t *bler_stats,
int max_mcs,
frame_t frame);
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
......
......@@ -102,9 +102,9 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
UE_id,
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
stats->dlsch_rounds[2], stats->dlsch_rounds[3],
stats->dlsch_errors,
stats->dl.rounds[0], stats->dl.rounds[1],
stats->dl.rounds[2], stats->dl.rounds[3],
stats->dl.errors,
stats->pucch0_DTX,
sched_ctrl->dl_bler_stats.bler,
sched_ctrl->dl_bler_stats.mcs);
......@@ -112,25 +112,27 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0;
}
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dlsch_total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n",
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dl.total_bytes);
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n",
UE_id,
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
stats->ulsch_rounds[2], stats->ulsch_rounds[3],
stats->ul.rounds[0], stats->ul.rounds[1],
stats->ul.rounds[2], stats->ul.rounds[3],
stats->ulsch_DTX,
stats->ulsch_errors);
stats->ul.errors,
sched_ctrl->ul_bler_stats.bler,
sched_ctrl->ul_bler_stats.mcs);
stroff+=sprintf(output+stroff,
"UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
UE_id,
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes);
for (int lc_id = 0; lc_id < 63; lc_id++) {
if (stats->lc_bytes_tx[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
if (stats->dl.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->dl.lc_bytes[lc_id]);
}
if (stats->lc_bytes_rx[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
if (stats->ul.lc_bytes[lc_id] > 0) {
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]);
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->ul.lc_bytes[lc_id]);
}
}
}
......
......@@ -459,13 +459,12 @@ typedef struct NR_UE_harq {
//! fixme : need to enhace for the multiple TB CQI report
typedef struct NR_DL_bler_stats {
frame_t last_frame_slot;
typedef struct NR_bler_stats {
frame_t last_frame;
float bler;
float rd2_bler;
uint8_t mcs;
uint64_t dlsch_rounds[8];
} NR_DL_bler_stats_t;
uint64_t rounds[8];
} NR_bler_stats_t;
//
/*! As per spec 38.214 section 5.2.1.4.2
......@@ -613,6 +612,9 @@ typedef struct {
NR_pdsch_semi_static_t pdsch_semi_static;
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pdsch_t sched_pdsch;
/// UE-estimated maximum MCS (from CSI-RS)
uint8_t dl_max_mcs;
/// For UL synchronization: store last UL scheduling grant
frame_t last_ul_frame;
sub_frame_t last_ul_slot;
......@@ -624,7 +626,8 @@ typedef struct {
mac_rlc_status_resp_t rlc_status[NR_MAX_NUM_LCID];
/// Estimation of HARQ from BLER
NR_DL_bler_stats_t dl_bler_stats;
NR_bler_stats_t dl_bler_stats;
NR_bler_stats_t ul_bler_stats;
uint16_t ta_frame;
int16_t ta_update;
......@@ -641,7 +644,6 @@ typedef struct {
int ul_failure;
struct CSI_Report CSI_report;
bool SR;
bool set_mcs;
bool set_pmi;
/// information about every HARQ process
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
......@@ -674,24 +676,29 @@ typedef struct {
uicc_t *uicc;
} NRUEcontext_t;
typedef struct {
uint64_t lc_bytes_tx[64];
uint64_t lc_bytes_rx[64];
uint64_t dlsch_rounds[8];
uint64_t dlsch_errors;
uint64_t dlsch_total_bytes;
int dlsch_current_bytes;
uint64_t ulsch_rounds[8];
uint64_t ulsch_errors;
typedef struct NR_mac_dir_stats {
uint64_t lc_bytes[64];
uint64_t rounds[8];
uint64_t errors;
uint64_t total_bytes;
uint32_t current_bytes;
} NR_mac_dir_stats_t;
typedef struct NR_mac_stats {
NR_mac_dir_stats_t dl;
NR_mac_dir_stats_t ul;
uint32_t ulsch_DTX;
uint64_t ulsch_total_bytes_scheduled;
uint64_t ulsch_total_bytes_rx;
int ulsch_current_bytes;
uint32_t pucch0_DTX;
int cumul_rsrp;
uint8_t num_rsrp_meas;
} NR_mac_stats_t;
typedef struct NR_bler_options {
double upper;
double lower;
uint8_t max_mcs;
} NR_bler_options_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48
......@@ -710,7 +717,8 @@ typedef struct {
// UE selected beam index
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
bool Msg4_ACKed[MAX_MOBILES_PER_GNB];
/// Sched CSI-RS: scheduling decisions
bool sched_csirs;
} NR_UE_info_t;
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
......@@ -807,15 +815,8 @@ typedef struct gNB_MAC_INST_s {
/// bitmap of DLSCH slots, can hold up to 160 slots
uint64_t dlsch_slot_bitmap[3];
/// Lookup for preferred time domain allocation for BWP, in DL, slots
/// dynamically allocated
int *preferred_dl_tda[MAX_NUM_BWP];
/// bitmap of ULSCH slots, can hold up to 160 slots
uint64_t ulsch_slot_bitmap[3];
/// Lookup for preferred time domain allocation for UL BWP, dynamically
/// allocated. The index refers to the DL slot, and the indicated TDA's k2
/// points to the right UL slot
int *preferred_ul_tda[MAX_NUM_BWP];
/// maximum number of slots before a UE will be scheduled ULSCH automatically
uint32_t ulsch_max_frame_inactivity;
......@@ -833,10 +834,8 @@ typedef struct gNB_MAC_INST_s {
int xp_pdsch_antenna_ports;
bool first_MIB;
double dl_bler_target_upper;
double dl_bler_target_lower;
double dl_rd2_bler_threshold;
uint8_t dl_max_mcs;
NR_bler_options_t dl_bler;
NR_bler_options_t ul_bler;
uint8_t harq_round_max;
uint8_t min_grant_prb;
uint8_t min_grant_mcs;
......
......@@ -321,8 +321,7 @@ void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc,
int len_coreset = 1;
if (curr_bwp < 48)
len_coreset = 2;
// setting default TDA for DL with
// setting default TDA for DL with TDA index 0
struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
// k0: Slot offset between DCI and its scheduled PDSCH (see TS 38.214 clause 5.1.2.1) When the field is absent the UE applies the value 0.
//timedomainresourceallocation->k0 = calloc(1,sizeof(*timedomainresourceallocation->k0));
......@@ -330,18 +329,20 @@ void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc,
timedomainresourceallocation->mappingType = NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
timedomainresourceallocation->startSymbolAndLength = get_SLIV(len_coreset,14-len_coreset); // basic slot configuration starting in symbol 1 til the end of the slot
ASN_SEQUENCE_ADD(&pdsch_TimeDomainAllocationList->list, timedomainresourceallocation);
// setting TDA for CSI-RS symbol with index 1
struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation1 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
timedomainresourceallocation1->mappingType = NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
timedomainresourceallocation1->startSymbolAndLength = get_SLIV(len_coreset,14-len_coreset-1); // 1 symbol CSI-RS
ASN_SEQUENCE_ADD(&pdsch_TimeDomainAllocationList->list, timedomainresourceallocation1);
if(frame_type==TDD) {
// TDD
if(scc->tdd_UL_DL_ConfigurationCommon) {
int dl_symb = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
if(dl_symb > 1) {
timedomainresourceallocation = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
// k0: Slot offset between DCI and its scheduled PDSCH (see TS 38.214 clause 5.1.2.1) When the field is absent the UE applies the value 0.
//timedomainresourceallocation->k0 = calloc(1,sizeof(*timedomainresourceallocation->k0));
//*timedomainresourceallocation->k0 = 0;
timedomainresourceallocation->mappingType = NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
timedomainresourceallocation->startSymbolAndLength = get_SLIV(len_coreset,dl_symb-len_coreset); // mixed slot configuration starting in symbol 1 til the end of the dl allocation
ASN_SEQUENCE_ADD(&pdsch_TimeDomainAllocationList->list, timedomainresourceallocation);
// mixed slot TDA with TDA index 2
struct NR_PDSCH_TimeDomainResourceAllocation *timedomainresourceallocation2 = CALLOC(1,sizeof(NR_PDSCH_TimeDomainResourceAllocation_t));
timedomainresourceallocation2->mappingType = NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA;
timedomainresourceallocation2->startSymbolAndLength = get_SLIV(len_coreset,dl_symb-len_coreset); // mixed slot configuration starting in symbol 1 til the end of the dl allocation
ASN_SEQUENCE_ADD(&pdsch_TimeDomainAllocationList->list, timedomainresourceallocation2);
}
}
}
......@@ -353,38 +354,24 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
//TODO change to accomodate for SRS
frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
int temp_min_delay = 6; // k2 = 2 or 3 won'r work as well as higher values
if(frame_type==TDD && scc->tdd_UL_DL_ConfigurationCommon) {
switch (scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms2p5: // 30kHz SCS
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms2: // 60kHz SCS
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms1p25: // 60kHz SCS
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms1: // 120kHz SCS
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p625: // 120kHz SCS
case NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5: // 120kHz SCS
temp_min_delay = 2;
break;
}
}
int k2 = (min_fb_delay<temp_min_delay)?temp_min_delay:min_fb_delay;
const int k2 = min_fb_delay;
uint8_t DELTA[4]= {2,3,4,6}; // Delta parameter for Msg3
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
// UL TDA index 0 is basic slot configuration starting in symbol 0 til the last but one symbol
struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long));
*pusch_timedomainresourceallocation->k2 = k2;
pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB;
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13); // basic slot configuration starting in symbol 0 til the last but one symbol
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13);
ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation);
if(frame_type==TDD) {
// TDD
if(scc->tdd_UL_DL_ConfigurationCommon) {
int ul_symb = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
if (ul_symb>1) {
// UL TDA index 1 for mixed slot (TDD)
pusch_timedomainresourceallocation = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long));
*pusch_timedomainresourceallocation->k2 = k2;
......@@ -392,7 +379,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(14-ul_symb,ul_symb-1); // starting in fist ul symbol til the last but one
ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation);
// for msg3 in the mixed slot
// UL TDA index 2 for msg3 in the mixed slot (TDD)
int nb_periods_per_frame = get_nb_periods_per_frame(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
int nb_slots_per_period = ((1<<mu) * 10)/nb_periods_per_frame;
struct NR_PUSCH_TimeDomainResourceAllocation *pusch_timedomainresourceallocation_msg3 = CALLOC(1,sizeof(struct NR_PUSCH_TimeDomainResourceAllocation));
......@@ -407,6 +394,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation_msg3);
}
}
}
}
......
......@@ -644,6 +644,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
break;
case USRP_X300_DEV:
case USRP_N300_DEV:
case USRP_X400_DEV:
rxshift=2;
break;
default:
......
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