Commit 62dbda5c authored by Francesco Mani's avatar Francesco Mani

Merge remote-tracking branch 'origin/develop' into NR_RA_updates

parents 5f1fe21c 0fe3e5fd
......@@ -131,12 +131,12 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPk2_0 = 6;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2;
initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
......
......@@ -2792,6 +2792,7 @@ add_executable(nr-softmodem
${s1ap_h}
# ${OPENAIR_BIN_DIR}/messages_xml.h
${OPENAIR_DIR}/executables/nr-gnb.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/executables/nr-ru.c
${OPENAIR_DIR}/executables/nr-softmodem.c
${OPENAIR_DIR}/executables/softmodem-common.c
......@@ -3053,6 +3054,7 @@ target_link_libraries(nr_prachsim
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
......@@ -3067,6 +3069,7 @@ target_link_libraries(nr_ulschsim
add_executable(nr_ulsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
......
cmake_minimum_required(VERSION 2.8)
project (OpenAirInterface)
set ( CMAKE_BUILD_TYPE )
set ( CFLAGS_PROCESSOR_USER "" )
set ( UE_EXPANSION False )
set ( PRE_SCD_THREAD False )
set ( UESIM_EXPANSION False )
set ( ENABLE_VCD_FIFO False )
set ( RF_BOARD "OAI_USRP")
set ( RF_BOARD "None")
set ( TRANSP_PRO "None")
set ( PACKAGE_NAME "")
set ( DEADLINE_SCHEDULER "False" )
......
......@@ -597,6 +597,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
int i;
struct timespec abstime;
int time_ns = 50000;
int wait_timer = 0;
bool do_last_check = 1;
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
for (i=0; i<gNB->num_RU; i++) {
......@@ -617,22 +619,36 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
}
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_nsec = abstime.tv_nsec + time_ns;
if (abstime.tv_nsec >= 1000*1000*1000) {
abstime.tv_nsec -= 1000*1000*1000;
abstime.tv_sec += 1;
}
// wake up TX for subframe n+sf_ahead
// lock the TX mutex and make sure the thread is ready
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
while (wait_timer < 200) {
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_nsec = abstime.tv_nsec + time_ns;
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
return(-1);
if (abstime.tv_nsec >= 1000*1000*1000) {
abstime.tv_nsec -= 1000*1000*1000;
abstime.tv_sec += 1;
}
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
wait_timer += 50;
usleep(50);
}
else {
do_last_check = 0;
break;
}
}
if (do_last_check) {
AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
return (-1);
}
}
++L1_proc->instance_cnt;
......@@ -845,6 +861,12 @@ void init_gNB_proc(int inst) {
pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
sync_phy_proc.phy_proc_CC_id = 0;
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
char ul_pool[] = "-1,-1";
initTpool(ul_pool, gNB->threadPool, false);
initNotifiedFIFO(gNB->respDecode);
}
......
......@@ -839,6 +839,23 @@ void init_NR_UE(int nb_inst, char* rrc_config_path) {
AssertFatal((rrc_inst = nr_l3_init_ue(rrc_config_path)) != NULL, "can not initialize RRC module\n");
AssertFatal((mac_inst = nr_l2_init_ue(rrc_inst)) != NULL, "can not initialize L2 module\n");
AssertFatal((mac_inst->if_module = nr_ue_if_module_init(inst)) != NULL, "can not initialize IF module\n");
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
if (mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
}
else if (mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac_inst->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
}
if (pusch_TimeDomainAllocationList) {
for(int i = 0; i < pusch_TimeDomainAllocationList->list.count; i++) {
AssertFatal(*pusch_TimeDomainAllocationList->list.array[i]->k2 >= DURATION_RX_TO_TX,
"Slot offset K2 (%ld) cannot be less than DURATION_RX_TO_TX (%d)\n",
*pusch_TimeDomainAllocationList->list.array[i]->k2,
DURATION_RX_TO_TX);
}
}
}
}
......
......@@ -415,8 +415,14 @@ typedef struct {
uint8_t number_of_candidates;
uint16_t CCE[64];
uint8_t L[64];
uint8_t dci_length;
uint8_t dci_format;
// 3GPP TS 38.212 Sec. 7.3.1.0, 3GPP TS 138.131 sec. 6.3.2 (SearchSpace)
// The maximum number of DCI lengths allowed by the spec are 4, with max 3 for C-RNTI.
// But a given search space may only support a maximum of 2 DCI formats at a time
// depending on its search space type configured by RRC. Hence for blind decoding, UE
// needs to monitor only upto 2 DCI lengths for a given search space.
uint8_t num_dci_options; // Num DCIs the UE actually needs to decode (1 or 2)
uint8_t dci_length_options[2];
uint8_t dci_format_options[2];
} fapi_nr_dl_config_dci_dl_pdu_rel15_t;
typedef struct {
......
......@@ -483,8 +483,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
uint32_t nr_compute_tbslbrm(uint16_t table,
uint16_t nb_rb,
uint8_t Nl,
uint8_t C);
uint8_t Nl);
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
......
......@@ -425,7 +425,7 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
}
}
else {
if (E + F <= Ncb-ind) { //E+F doesn't contain all coded bits
if (E <= Ncb-ind) { //E+F doesn't contain all coded bits
memcpy((void*)(e),(void*)(w+ind),E);
k=E;
}
......
......@@ -527,7 +527,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
if (rel15->nrOfLayers < Nl)
Nl = rel15->nrOfLayers;
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
start_meas(dlsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
......
......@@ -31,6 +31,7 @@
*/
#include "PHY/defs_gNB.h"
#include "common/utils/threadPool/thread-pool.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
......
......@@ -52,9 +52,6 @@
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
//#define PRINT_CRC_CHECK
static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;
//extern double cpuf;
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
......@@ -286,7 +283,177 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
static uint32_t prnt_crc_cnt = 0;
#endif
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
void nr_processULSegment(void* arg) {
ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
int length_dec;
int no_iteration_ldpc;
int Kr;
int Kr_bytes;
int K_bytes_F;
uint8_t crc_type;
int i;
int j;
int r = rdata->segment_r;
int A = rdata->A;
int E = rdata->E;
int Qm = rdata->Qm;
int rv_index = rdata->rv_index;
int r_offset = rdata->r_offset;
uint8_t kc = rdata->Kc;
uint32_t Tbslbrm = rdata->Tbslbrm;
short* ulsch_llr = rdata->ulsch_llr;
int max_ldpc_iterations = p_decoderParms->numMaxIter;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
int16_t z [68*384];
int8_t l [68*384];
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
uint8_t Ilbrm = 0;
Kr = ulsch_harq->K;
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(ulsch_harq->F>>3);
t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats* p_procTime = &procTime ;
//start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
nr_deinterleaving_ldpc(E,
Qm,
ulsch_harq->e[r],
ulsch_llr+r_offset);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
/*LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
ulsch_harq->TBS,
Qm,
nb_rb,
n_layers,
pusch_pdu->pusch_data.rv_index,
ulsch_harq->round);*/
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
//start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decoderParms->BG,
p_decoderParms->Z,
ulsch_harq->d[r],
ulsch_harq->e[r],
ulsch_harq->C,
rv_index,
(ulsch_harq->round==0)?1:0,
E,
ulsch_harq->F,
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
rdata->decodeIterations = max_ldpc_iterations + 1;
return;
} else {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
}
memset(ulsch_harq->c[r],0,Kr_bytes);
if (ulsch_harq->C == 1) {
if (A > 3824)
crc_type = CRC24_A;
else
crc_type = CRC16;
length_dec = ulsch_harq->B;
}
else {
crc_type = CRC24_B;
length_dec = (ulsch_harq->B+24*ulsch_harq->C)/ulsch_harq->C;
}
//start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
memset(pv,0,2*ulsch_harq->Z*sizeof(int16_t));
memset((pv+K_bytes_F),127,ulsch_harq->F*sizeof(int16_t));
for (i=((2*p_decoderParms->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
}
AssertFatal(kc!=255,"");
j+=(ulsch_harq->F>>3);
for (i=Kr_bytes; i < ((kc*p_decoderParms->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
}
for (i=0, j=0; j < ((kc*p_decoderParms->Z)>>4); i+=2, j++) {
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
(int8_t*)&pl[0],
llrProcBuf,
ulsch_harq->p_nrLDPC_procBuf[r],
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
rdata->decodeIterations = no_iteration_ldpc;
} else {
#ifdef PRINT_CRC_CHECK
LOG_I(PHY, "CRC NOK\n");
#endif
rdata->decodeIterations = max_ldpc_iterations + 1;
}
for (int m=0; m < Kr>>3; m ++) {
ulsch_harq->c[r][m]= (uint8_t) llrProcBuf[m];
}
//stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
}
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
......@@ -296,36 +463,36 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
uint8_t harq_pid,
uint32_t G) {
uint32_t A,E;
uint32_t ret, offset;
int32_t no_iteration_ldpc, length_dec;
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
uint8_t crc_type;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
uint32_t A;
uint32_t r;
uint32_t r_offset;
uint32_t offset;
int kc;
int Tbslbrm;
int E;
#ifdef PRINT_CRC_CHECK
prnt_crc_cnt++;
#endif
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0];
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats* p_procTime = &procTime ;
int Kr;
int Kr_bytes;
phy_vars_gNB->nbDecode = 0;
harq_process->processedSegments = 0;
if (!harq_process) {
printf("ulsch_decoding.c: NULL harq_process pointer\n");
return (ulsch->max_ldpc_iterations + 1);
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
return 1;
}
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
int16_t z [68*384];
int8_t l [68*384];
uint8_t kc = 255;
uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984;
double Coderate = 0.0;
// ------------------------------------------------------------------
......@@ -336,30 +503,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
uint8_t n_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------
uint32_t i,j;
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
if (!ulsch_llr) {
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
return (ulsch->max_ldpc_iterations + 1);
LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
return 1;
}
if (!frame_parms) {
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
return (ulsch->max_ldpc_iterations + 1);
}
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];
A = (harq_process->TBS)<<3;
ret = ulsch->max_ldpc_iterations + 1;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
......@@ -401,12 +554,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
NR_gNB_SCH_STATS_t *stats=NULL;
int first_free=-1;
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++) {
if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
if (phy_vars_gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
first_free = i;
stats=&gNB->ulsch_stats[i];
stats=&phy_vars_gNB->ulsch_stats[i];
}
if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
stats=&gNB->ulsch_stats[i];
if (phy_vars_gNB->ulsch_stats[i].rnti == ulsch->rnti) {
stats=&phy_vars_gNB->ulsch_stats[i];
break;
}
}
......@@ -420,13 +573,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
stats->current_RI = n_layers;
stats->total_bytes_tx += harq_process->TBS;
}
// This is a new packet, so compute quantities regarding segmentation
if (A > 3824)
harq_process->B = A+24;
else
harq_process->B = A+16;
}
if (A > 3824)
harq_process->B = A+24;
else
harq_process->B = A+16;
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
nr_segmentation(NULL,
NULL,
harq_process->B,
......@@ -437,18 +590,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
p_decParams->BG);
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
#endif
}
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers);
p_decParams->Z = harq_process->Z;
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
p_decParams->outMode= 0;
err_flag = 0;
r_offset = 0;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
......@@ -460,284 +613,48 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
if (harq_process->C > a_segments) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
return (ulsch->max_ldpc_iterations + 1);
return 1;
}
#ifdef DEBUG_ULSCH_DECODING
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
//opp_enabled=1;
Kr = harq_process->K;
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
offset = 0;
void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
start_meas(&gNB->ulsch_deinterleaving_stats);
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
nr_deinterleaving_ldpc(E,
Qm,
harq_process->e[r],
ulsch_llr+r_offset);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
stop_meas(&gNB->ulsch_deinterleaving_stats);
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rvidx %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
harq_process->TBS,
Qm,
nb_rb,
n_layers,
pusch_pdu->pusch_data.rv_index,
harq_process->round);
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
start_meas(&gNB->ulsch_rate_unmatching_stats);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
p_decParams->Z,
harq_process->d[r],
harq_process->e[r],
harq_process->C,
pusch_pdu->pusch_data.rv_index,
(harq_process->round==0)?1:0,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
stop_meas(&gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
return (ulsch->max_ldpc_iterations + 1);
} else {
stop_meas(&gNB->ulsch_rate_unmatching_stats);
}
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment_ptr);
ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);
rdata->gNB = phy_vars_gNB;
rdata->ulsch_harq = harq_process;
rdata->decoderParms = decParams;
rdata->ulsch_llr = ulsch_llr;
rdata->Kc = kc;
rdata->harq_pid = harq_pid;
rdata->segment_r = r;
rdata->nbSegments = harq_process->C;
rdata->E = E;
rdata->A = A;
rdata->Qm = Qm;
rdata->r_offset = r_offset;
rdata->Kr_bytes = Kr_bytes;
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
rdata->Tbslbrm = Tbslbrm;
rdata->offset = offset;
rdata->ulsch = ulsch;
rdata->ulsch_id = UE_id;
pushTpool(phy_vars_gNB->threadPool,req);
phy_vars_gNB->nbDecode++;
LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode);
r_offset += E;
#ifdef DEBUG_ULSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
}
printf("decoder input(segment %u) :", r);
int i;
for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,harq_process->d[r][i]);
printf("\n");
#endif
// printf("Clearing c, %p\n",harq_process->c[r]);
memset(harq_process->c[r],0,Kr_bytes);
// printf("done\n");
if (harq_process->C == 1) {
if (A > 3824)
crc_type = CRC24_A;
else
crc_type = CRC16;
length_dec = harq_process->B;
}
else {
crc_type = CRC24_B;
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
}
if (err_flag == 0) {
start_meas(&gNB->ulsch_ldpc_decoding_stats);
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
AssertFatal(kc!=255,"");
j+=(harq_process->F>>3);
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
(int8_t*)&pl[0],
llrProcBuf,
p_nrLDPC_procBuf[r],
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt % 10 == 0)
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
ret = no_iteration_ldpc;
} else {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt%10 == 0)
LOG_I(PHY, "CRC NOK\n");
#endif
ret = ulsch->max_ldpc_iterations + 1;
}
nb_total_decod++;
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
nb_error_decod++;
}
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
}
#ifdef DEBUG_ULSCH_DECODING
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int k=0;k<A>>3;k++)
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
#endif
stop_meas(&gNB->ulsch_ldpc_decoding_stats);
}
if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
err_flag = 1;
}
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
//////////////////////////////////////////////////////////////////////////////////////////
}
int32_t frame_rx_prev = frame;
int32_t tti_rx_prev = nr_tti_rx - 1;
if (tti_rx_prev < 0) {
frame_rx_prev--;
tti_rx_prev += frame_parms->slots_per_frame;
}
frame_rx_prev = frame_rx_prev%1024;
if (err_flag == 1) {
#ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n",
gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
#endif
// harq_process->harq_ack.ack = 0;
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
// harq_process->errors[harq_process->round]++;
//harq_process->round++;
if (harq_process->round >= ulsch->Mlimit) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
}
// LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
// gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
harq_process->handled = 1;
ret = ulsch->max_ldpc_iterations + 1;
} else {
#ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
gNB->Mod_id,nr_tti_rx,harq_process->TBS);
#endif
harq_process->status = SCH_IDLE;
harq_process->round = 0;
// harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
// harq_process->harq_ack.ack = 1;
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
// LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
// Reassembly of Transport block here
offset = 0;
Kr = harq_process->K;
Kr_bytes = Kr>>3;
for (r=0; r<harq_process->C; r++) {
memcpy(harq_process->b+offset,
harq_process->c[r],
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
#ifdef DEBUG_ULSCH_DECODING
printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes);
printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)), harq_pid);
printf("b[0] = %x, c[%d] = %x\n", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]);
#endif
}
if (stats) stats->total_bytes_rx += harq_process->TBS;
}
#ifdef DEBUG_ULSCH_DECODING
LOG_I(PHY, "Decoder output (payload) at SFN/SF: %d/%d TBS: %d\n", frame, nr_tti_rx,harq_process->TBS);
for (i = 0; i < harq_process->TBS; i++) {
//harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
printf("%02x ",harq_process->b[i]);
}
#endif
ulsch->last_iteration_cnt = ret;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
return(ret);
return 1;
}
......@@ -845,7 +845,6 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
for (int i=0;i<pdcch_vars->nb_search_space;i++) {
rel15 = &pdcch_vars->pdcch_config[i];
int dci_length = rel15->dci_length;
//int gNB_id = 0;
int16_t tmp_e[16*108];
rnti_t n_rnti;
......@@ -853,41 +852,47 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
for (int j=0;j<rel15->number_of_candidates;j++) {
int CCEind = rel15->CCE[j];
int L = rel15->L[j];
uint64_t dci_estimation[2]= {0};
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
// Loop over possible DCI lengths
for (int k = 0; k < rel15->num_dci_options; k++) {
int dci_length = rel15->dci_length_options[k];
uint64_t dci_estimation[2]= {0};
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
#ifdef DEBUG_DCI_DECODING
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
for (int index_z = 0; index_z < 96; index_z++){
for (int i=0; i<9; i++) {
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
#ifdef DEBUG_DCI_DECODING
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
for (int index_z = 0; index_z < 96; index_z++){
for (int i=0; i<9; i++) {
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
}
}
#endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
n_rnti = rel15->rnti;
if (crc == n_rnti) {
LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
dci_ind->SFN = frame;
dci_ind->slot = slot;
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
break; // If DCI is found, no need to check for remaining DCI lengths
} else {
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
}
#endif
uint16_t crc = polar_decoder_int16(tmp_e,
dci_estimation,
1,
currentPtrDCI);
n_rnti = rel15->rnti;
if (crc == n_rnti) {
LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
dci_ind->SFN = frame;
dci_ind->slot = slot;
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format;
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
dci_ind->number_of_dcis++;
} else {
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
}
}
}
......
......@@ -478,9 +478,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
if ((harq_process->Nl)<4)
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
else
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
if (nr_rate_matching_ldpc_rx(Ilbrm,
......@@ -1069,7 +1069,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
if (harq_process->Nl < Nl)
Nl = harq_process->Nl;
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
......@@ -1610,9 +1610,9 @@ void nr_dlsch_decoding_process(void *arg)
#endif
if (Nl<4)
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
else
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
......
......@@ -392,6 +392,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
encoder_implemparams_t impp;
impp.n_segments=harq_process->C;
impp.macro_num=0;
impp.tinput = NULL;
impp.tprep = NULL;
impp.tparity = NULL;
impp.toutput = NULL;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
......@@ -439,7 +443,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
E = nr_get_E(G, harq_process->C, mod_order, harq_process->pusch_pdu.nrOfLayers, r);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers,harq_process->C);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
nr_rate_matching_ldpc(Ilbrm,
......
......@@ -263,6 +263,8 @@ typedef struct {
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
uint32_t E;
/// Number of segments processed so far
uint32_t processedSegments;
//////////////////////////////////////////////////////////////
......@@ -475,7 +477,6 @@ typedef struct {
uint8_t cl_done;
} NR_gNB_PUSCH;
/// Context data structure for RX/TX portion of slot processing
typedef struct {
/// Component Carrier index
......@@ -822,7 +823,45 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t rx_dft_stats;
time_stats_t ulsch_freq_offset_estimation_stats;
*/
notifiedFIFO_t *respDecode;
tpool_t *threadPool;
int nbDecode;
} PHY_VARS_gNB;
typedef struct LDPCDecode_s {
PHY_VARS_gNB *gNB;
NR_UL_gNB_HARQ_t *ulsch_harq;
t_nrLDPC_dec_params decoderParms;
NR_gNB_ULSCH_t *ulsch;
short* ulsch_llr;
int ulsch_id;
int harq_pid;
int rv_index;
int A;
int E;
int Kc;
int Qm;
int Kr_bytes;
int nbSegments;
int segment_r;
int r_offset;
int offset;
int Tbslbrm;
int decodeIterations;
} ldpcDecode_t;
struct ldpcReqId {
uint16_t rnti;
uint16_t frame;
uint8_t subframe;
uint8_t codeblock;
uint16_t spare;
} __attribute__((packed));
union ldpcReqUnion {
struct ldpcReqId s;
uint64_t p;
};
#endif
......@@ -213,12 +213,74 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
*/
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
int r = rdata->segment_r;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
ulsch_harq->processedSegments++;
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
gNB->nbDecode--;
LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode);
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpool(gNB->threadPool, req->key);
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
gNB->nbDecode-=nb;
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
}
}
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess) {
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
gNB->Mod_id,ulsch_harq->slot,ulsch_harq->TBS);
ulsch_harq->status = SCH_IDLE;
ulsch_harq->round = 0;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
LOG_D(PHY, "ULSCH received ok \n");
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0);
} else {
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d\n",
gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot,
rdata->harq_pid,ulsch_harq->status, ulsch_harq->round,ulsch_harq->TBS,r);
if (ulsch_harq->round >= ulsch->Mlimit) {
ulsch_harq->status = SCH_IDLE;
ulsch_harq->round = 0;
ulsch_harq->handled = 0;
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
}
ulsch_harq->handled = 1;
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1);
}
ulsch->last_iteration_cnt = rdata->decodeIterations;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
}
}
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
uint8_t ret;
uint8_t l, number_dmrs_symbols = 0;
uint32_t G;
uint16_t start_symbol, number_symbols, nb_re_dmrs;
......@@ -270,25 +332,22 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
//----------------------------------------------------------
start_meas(&gNB->ulsch_decoding_stats);
ret = nr_ulsch_decoding(gNB,
ULSCH_id,
gNB->pusch_vars[ULSCH_id]->llr,
frame_parms,
pusch_pdu,
frame_rx,
slot_rx,
harq_pid,
G);
stop_meas(&gNB->ulsch_decoding_stats);
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
}
else if(gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->b!=NULL){
LOG_D(PHY, "ULSCH received ok \n");
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 0);
nr_ulsch_decoding(gNB,
ULSCH_id,
gNB->pusch_vars[ULSCH_id]->llr,
frame_parms,
pusch_pdu,
frame_rx,
slot_rx,
harq_pid,
G);
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
}
stop_meas(&gNB->ulsch_decoding_stats);
}
......
......@@ -93,6 +93,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
if (dlsch0_harq){
dlsch0_harq->status = ACTIVE;
dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
......
......@@ -198,7 +198,7 @@ int main(int argc, char **argv)
int frame=1,slot=1;
int frame_length_complex_samples;
int frame_length_complex_samples_no_prefix;
//int frame_length_complex_samples_no_prefix;
NR_DL_FRAME_PARMS *frame_parms;
UE_nr_rxtx_proc_t UE_proc;
NR_Sched_Rsp_t Sched_INFO;
......@@ -210,7 +210,7 @@ int main(int argc, char **argv)
int pucch_tgt_snrx10 = 200;
int loglvl=OAILOG_INFO;
float target_error_rate = 0.01;
//float target_error_rate = 0.01;
int css_flag=0;
cpuf = get_cpu_freq_GHz();
......@@ -372,7 +372,7 @@ int main(int argc, char **argv)
case 'I':
run_initial_sync=1;
target_error_rate=0.1;
//target_error_rate=0.1;
slot = 0;
break;
......@@ -598,7 +598,7 @@ int main(int argc, char **argv)
}
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
s_re = malloc(2*sizeof(double*));
s_im = malloc(2*sizeof(double*));
......
......@@ -45,6 +45,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 "common/utils/threadPool/thread-pool.h"
//#define DEBUG_NR_ULSCHSIM
......@@ -67,6 +68,44 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
int r = rdata->segment_r;
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
ulsch_harq->processedSegments++;
gNB->nbDecode--;
if (decodeSuccess) {
memcpy(ulsch_harq->b+rdata->offset,
ulsch_harq->c[r],
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
} else {
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
int nb=abortTpool(gNB->threadPool, req->key);
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
gNB->nbDecode-=nb;
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
ulsch_harq->processedSegments, nb, rdata->nbSegments);
ulsch_harq->processedSegments=rdata->nbSegments;
return 1;
}
}
// if all segments are done
if (rdata->nbSegments == ulsch_harq->processedSegments) {
if (decodeSuccess) {
return 0;
} else {
return 1;
}
}
ulsch->last_iteration_cnt = rdata->decodeIterations;
return 0;
}
int main(int argc, char **argv)
{
char c;
......@@ -92,7 +131,7 @@ int main(int argc, char **argv)
NR_DL_FRAME_PARMS *frame_parms;
double sigma;
unsigned char qbits = 8;
int ret;
int ret=0;
int loglvl = OAILOG_WARNING;
uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
......@@ -338,6 +377,11 @@ int main(int argc, char **argv)
gNB = RC.gNB[0];
//gNB_config = &gNB->gNB_config;
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
char tp_param[] = "n";
initTpool(tp_param, gNB->threadPool, true);
initNotifiedFIFO(gNB->respDecode);
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx;
......@@ -531,10 +575,15 @@ int main(int argc, char **argv)
rel15_ul->qam_mod_order,
rel15_ul->nrOfLayers);
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
frame, subframe, harq_pid, G);
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
ret = nr_postDecode_sim(gNB, req);
delNotifiedFIFO_elt(req);
}
if (ret > ulsch_gNB->max_ldpc_iterations)
if (ret)
n_errors++;
//count errors
......
......@@ -55,6 +55,8 @@
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/threadPool/thread-pool.h"
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
......@@ -199,6 +201,7 @@ int main(int argc, char **argv)
int pucch_tgt_snrx10 = 200;
int ibwps=24;
int ibwp_rboffset=41;
int params_from_file = 0;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
}
......@@ -435,6 +438,10 @@ int main(int argc, char **argv)
}
break;
case 'Q':
params_from_file = 1;
break;
default:
case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
......@@ -456,7 +463,7 @@ int main(int argc, char **argv)
printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
printf("-F Input filename (.txt format) for RX conformance testing\n");
printf("-G raw file containing RRC configuration (generated by gNB)\n");
printf("-G Offset of samples to read from file (0 default)\n");
printf("-M Multiple SSB positions in burst\n");
printf("-N Nid_cell\n");
printf("-O oversampling factor (1,2,4,8,16)\n");
......@@ -466,6 +473,7 @@ int main(int argc, char **argv)
printf("-P Print ULSCH performances\n");
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
printf("-Q If -F used, read parameters from file\n");
exit(-1);
break;
......@@ -512,6 +520,11 @@ int main(int argc, char **argv)
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
char tp_param[] = "n";
initTpool(tp_param, gNB->threadPool, true);
initNotifiedFIFO(gNB->respDecode);
//gNB_config = &gNB->gNB_config;
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
......@@ -734,6 +747,7 @@ int main(int argc, char **argv)
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
snrRun = 0;
int n_errs = 0;
int read_errors=0;
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
......@@ -743,35 +757,39 @@ int main(int argc, char **argv)
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
printf("rnti %x\n",n_rnti);
fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
printf("nb_rb %d\n",nb_rb);
int16_t dummy;
fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("rb_start %d\n",start_rb);
fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("nb_symb_sch %d\n",nb_symb_sch);
fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
printf("start_symbol %d\n",start_symbol);
fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
printf("mcs %d\n",Imcs);
fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
printf("rv_index %d\n",rv_index);
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("harq_pid %d\n",harq_pid);
fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
sizeof(int16_t),
slot_length<<1,
input_fd);
if (params_from_file) {
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
printf("rnti %x\n",n_rnti);
read_errors+=fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
printf("nb_rb %d\n",nb_rb);
int16_t dummy;
read_errors+=fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("rb_start %d\n",start_rb);
read_errors+=fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("nb_symb_sch %d\n",nb_symb_sch);
read_errors+=fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
printf("start_symbol %d\n",start_symbol);
read_errors+=fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
printf("mcs %d\n",Imcs);
read_errors+=fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
printf("rv_index %d\n",rv_index);
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
read_errors+=fread((void*)&dummy,sizeof(int16_t),1,input_fd);
printf("harq_pid %d\n",harq_pid);
}
fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
sizeof(int16_t),
slot_length<<1,
input_fd);
if (read_errors==0) exit(1);
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
slot_offset,
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
slot_offset,
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
}
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
......@@ -782,6 +800,17 @@ int main(int argc, char **argv)
int n_errors[4] = {0,0,0,0};;
int round_trials[4]={0,0,0,0};
uint32_t errors_scrambling[4] = {0,0,0,0};
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->ulsch_deinterleaving_stats);
reset_meas(&gNB->ulsch_rate_unmatching_stats);
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
reset_meas(&gNB->ulsch_unscrambling_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
reset_meas(&gNB->ulsch_llr_stats);
reset_meas(&gNB->ulsch_channel_compensation_stats);
reset_meas(&gNB->ulsch_rbs_extraction_stats);
clear_pusch_stats(gNB);
for (trial = 0; trial < n_trials; trial++) {
......@@ -795,19 +824,6 @@ int main(int argc, char **argv)
ulsch_ue[0]->harq_processes[harq_pid]->round = round;
gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
rv_index = nr_rv_round_map[round];
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->ulsch_deinterleaving_stats);
reset_meas(&gNB->ulsch_rate_unmatching_stats);
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
reset_meas(&gNB->ulsch_unscrambling_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
reset_meas(&gNB->ulsch_ptrs_processing_stats);
reset_meas(&gNB->ulsch_llr_stats);
reset_meas(&gNB->ulsch_mrc_stats);
reset_meas(&gNB->ulsch_channel_compensation_stats);
reset_meas(&gNB->ulsch_rbs_extraction_stats);
UE_proc.nr_tti_tx = slot;
UE_proc.frame_tx = frame;
......@@ -1142,9 +1158,9 @@ int main(int argc, char **argv)
printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
//printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
//printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
//printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
printf("\n");
}
......
......@@ -211,7 +211,7 @@ schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
msi_pos++;
while((non_mbsfn_SubframeConfig & (0x100 >> msi_pos)) == (0x100>>msi_pos))
msi_pos++;
mbms_mch_i=0;
mbms_mch_i=0;
if((subframeP==0)){
x=0;
......
......@@ -89,9 +89,8 @@ uint32_t nr_compute_tbs(uint16_t Qm,
//tbslbrm calculation according to 5.4.2.1 of 38.212
uint32_t nr_compute_tbslbrm(uint16_t table,
uint16_t nb_rb,
uint8_t Nl,
uint8_t C)
uint16_t nb_rb,
uint8_t Nl)
{
uint16_t R, nb_re;
......@@ -99,7 +98,7 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
uint8_t Qm;
int i;
uint32_t nr_tbs=0;
uint32_t Ninfo, Np_info;
uint32_t Ninfo, Np_info, C;
uint8_t n;
for (i=0; i<7; i++) {
......@@ -117,27 +116,34 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
Ninfo = (nb_re * R * Qm * Nl)>>10;
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
} else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, (Ninfo>>n)<<n);
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
}
else {
n = log2(Ninfo-24)-5;
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
if (R <= 256) {
C = CEILIDIV((Np_info+24),3816);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
if (Np_info > 8424){
C = CEILIDIV((Np_info+24),8424);
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
if (R <= 256) {
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
if (Np_info > 8424){
nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
} else {
nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
}
return nr_tbs;
}
......@@ -174,7 +174,7 @@ int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index,
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot);
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
uint8_t dci_length,
uint16_t rnti,
......
......@@ -64,7 +64,7 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
}
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id, uint8_t dci_format){
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id){
uint16_t monitoringSymbolsWithinSlot = 0;
uint8_t bwp_id = 1, coreset_id = 1;
......@@ -76,9 +76,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
// DCI format configuration
rel15->dci_format = dci_format;
// CORESET configuration
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1];
rel15->coreset.duration = coreset->duration;
......@@ -123,7 +120,9 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_C, rel15->BWPSize, bwp_id);
for (int i = 0; i < rel15->num_dci_options; i++) {
rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
}
break;
case NR_RNTI_RA:
// we use the initial DL BWP
......@@ -133,7 +132,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
rel15->dci_length = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_RA, rel15->BWPSize, bwp_id);
rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
break;
case NR_RNTI_P:
break;
......@@ -214,7 +213,9 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n");
switch(mac->ra_state){
case WAIT_RAR:
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id, NR_DL_DCI_FORMAT_1_0);
rel15->num_dci_options = 1;
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
fill_dci_search_candidates(ss, rel15);
break;
case WAIT_CONTENTION_RESOLUTION:
......@@ -285,7 +286,10 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
// Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
if (get_softmodem_params()->phy_test == 1 && mac->crnti > 0) {
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n");
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id, NR_DL_DCI_FORMAT_1_1);
rel15->num_dci_options = 2;
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1;
rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_1;
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id);
fill_dci_search_candidates(ss, rel15);
#ifdef DEBUG_DCI
......
......@@ -794,7 +794,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint8_t access_mode = SCHEDULED_ACCESS;
// program PUSCH. this should actually be done upon reception of an UL DCI
// program PUSCH with UL DCI parameters
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
......@@ -802,30 +802,41 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req;
nfapi_nr_ue_ptrs_ports_t ptrs_ports_list;
//--------------------------Temporary configuration-----------------------------//
uint16_t rnti = 0x1234;
uint32_t rb_size = 50;
uint32_t rb_start = 0;
uint8_t nr_of_symbols = 11;
uint8_t start_symbol_index = 0;
fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0];
uint16_t rnti = ulcfg_pdu->pusch_config_pdu.rnti;
uint32_t rb_size = ulcfg_pdu->pusch_config_pdu.rb_size;
uint32_t rb_start = ulcfg_pdu->pusch_config_pdu.rb_start;
uint8_t nr_of_symbols = ulcfg_pdu->pusch_config_pdu.nr_of_symbols;
uint8_t start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index;
uint8_t nrOfLayers = 1;
uint8_t mcs_index = 9;
uint8_t mcs_table = 0;
uint8_t harq_process_id = 0;
uint8_t rv_index = 0;
uint8_t mcs_index = ulcfg_pdu->pusch_config_pdu.mcs_index;
uint8_t mcs_table = ulcfg_pdu->pusch_config_pdu.mcs_table;
uint8_t harq_process_id = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id;
uint8_t rv_index = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index;
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
uint8_t dmrs_config_type = 0;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
// These should come from RRC config!!!
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
uint16_t n_rb0 = 25;
uint16_t n_rb1 = 75;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
uint16_t number_dmrs_symbols = 0;
uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
//------------------------------------------------------------------------------//
#ifdef DEBUG_DCI
LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n",
rnti, rb_size);
LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \
mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n",
rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index,
mcs_table, harq_process_id, ndi, num_cb, rv_index);
#endif
// PTRS ports configuration
// TbD: ptrs_dmrs_port and ptrs_port_index are not initialised!
ptrs_ports_list.ptrs_re_offset = 0;
......@@ -2383,13 +2394,22 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
*/
if(pusch_config_pdu != NULL){
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL;
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config)
if (mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup;
}
else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) {
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
}
if (pusch_TimeDomainAllocationList) {
AssertFatal(pusch_TimeDomainAllocationList->list.count > time_domain_ind,
"time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n",
time_domain_ind,pusch_TimeDomainAllocationList->list.count);
if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
time_domain_ind, pusch_TimeDomainAllocationList->list.count);
pusch_config_pdu->start_symbol_index=0;
pusch_config_pdu->nr_of_symbols=0;
return -1;
}
int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength;
int S,L;
SLIV2SL(startSymbolAndLength,&S,&L);
......@@ -2417,8 +2437,8 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci->dci_format));
int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15);
return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format));
}
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){
......@@ -2439,6 +2459,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
LOG_D(MAC,"nr_ue_process_dci at MAC layer with dci_format=%d (DL BWP %d, UL BWP %d)\n",dci_format,n_RB_DLBWP,n_RB_ULBWP);
NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup;
switch(dci_format){
case NR_UL_DCI_FORMAT_0_0:
......@@ -2545,6 +2566,23 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
pusch_config_pdu_0_1->frequency_hopping = dci->frequency_hopping_flag.val;
/* MCS */
pusch_config_pdu_0_1->mcs_index = dci->mcs;
/* MCS TABLE */
if (pusch_config->transformPrecoder == NULL) {
if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_config_pdu_0_1->transform_precoding = 1;
else
pusch_config_pdu_0_1->transform_precoding = 0;
}
else
pusch_config_pdu_0_1->transform_precoding = *pusch_config->transformPrecoder;
if (pusch_config_pdu_0_1->transform_precoding == transform_precoder_disabled)
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_Table, 0,
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
else
pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1,
dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false);
/* NDI */
pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi;
/* RV */
......@@ -3250,7 +3288,7 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
}
void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int dci_format,
uint8_t dci_size,
uint16_t rnti,
......@@ -3274,6 +3312,33 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int pos=0;
int fsize=0;
if (rnti_type == NR_RNTI_C) {
// First find out the DCI format from the first bit (UE performed blind decoding)
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
#endif
if (dci_format == NR_UL_DCI_FORMAT_0_0 || dci_format == NR_DL_DCI_FORMAT_1_0) {
if (dci_pdu_rel15->format_indicator == 0)
dci_format = NR_UL_DCI_FORMAT_0_0;
else
dci_format = NR_DL_DCI_FORMAT_1_0;
}
else if (dci_format == NR_UL_DCI_FORMAT_0_1 || dci_format == NR_DL_DCI_FORMAT_1_1) {
// In case the sizes of formats 0_1 and 1_1 happen to be the same
if (dci_pdu_rel15->format_indicator == 0)
dci_format = NR_UL_DCI_FORMAT_0_1;
else
dci_format = NR_DL_DCI_FORMAT_1_1;
}
}
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC, "DCI format is %d\n", dci_format);
#endif
switch(dci_format) {
case NR_DL_DCI_FORMAT_1_0:
......@@ -3315,13 +3380,6 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
case NR_RNTI_C:
// indicating a DL DCI format 1bit
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
#endif
// Freq domain assignment (275rb >> fsize = 16)
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos+=fsize;
......@@ -3522,18 +3580,16 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
switch(rnti_type)
{
case NR_RNTI_C:
// indicating a DL DCI format 1bit
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
// Freq domain assignment max 16 bit
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
pos+=fsize;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
// Time domain assignment 4bit
pos+=4;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
// Frequency hopping flag – 1 bit
pos++;
dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// This is not supported yet - Skip for now
// Frequency hopping flag – 1 bit
//pos++;
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// MCS 5 bit
pos+=5;
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
......@@ -3597,89 +3653,203 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
break;
case NR_DL_DCI_FORMAT_1_1:
// Format indicator
pos=1;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Frequency domain resource assignment
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
// Time domain resource assignment
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
// VRB-to-PRB mapping
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
// PRB bundling size indicator
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
// Rate matching indicator
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
// ZP CSI-RS trigger
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
//TB1
// MCS 5bit
pos+=5;
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos+=1;
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
//TB2
// MCS 5bit
pos+=dci_pdu_rel15->mcs2.nbits;
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
// New data indicator 1bit
pos+=dci_pdu_rel15->ndi2.nbits;
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
// Redundancy version 2bit
pos+=dci_pdu_rel15->rv2.nbits;
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// TPC command for scheduled PUCCH 2bit
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
// PUCCH resource indicator 3bit
pos+=3;
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
// PDSCH-to-HARQ_feedback timing indicator
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// TCI
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// CBG flushing out information
pos+=dci_pdu_rel15->cbgfi.nbits;
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
// DMRS sequence init
pos+=1;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
break;
switch(rnti_type)
{
case NR_RNTI_C:
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Frequency domain resource assignment
pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->frequency_domain_assignment.nbits)-1);
// Time domain resource assignment
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->time_domain_assignment.nbits)-1);
// VRB-to-PRB mapping
pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits;
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->vrb_to_prb_mapping.nbits)-1);
// PRB bundling size indicator
pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits;
dci_pdu_rel15->prb_bundling_size_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->prb_bundling_size_indicator.nbits)-1);
// Rate matching indicator
pos+=dci_pdu_rel15->rate_matching_indicator.nbits;
dci_pdu_rel15->rate_matching_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rate_matching_indicator.nbits)-1);
// ZP CSI-RS trigger
pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits;
dci_pdu_rel15->zp_csi_rs_trigger.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->zp_csi_rs_trigger.nbits)-1);
//TB1
// MCS 5bit
pos+=5;
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos+=1;
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&0x1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&0x3;
//TB2
// MCS 5bit
pos+=dci_pdu_rel15->mcs2.nbits;
dci_pdu_rel15->mcs2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->mcs2.nbits)-1);
// New data indicator 1bit
pos+=dci_pdu_rel15->ndi2.nbits;
dci_pdu_rel15->ndi2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ndi2.nbits)-1);
// Redundancy version 2bit
pos+=dci_pdu_rel15->rv2.nbits;
dci_pdu_rel15->rv2.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->rv2.nbits)-1);
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// TPC command for scheduled PUCCH 2bit
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&0x3;
// PUCCH resource indicator 3bit
pos+=3;
dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&0x3;
// PDSCH-to-HARQ_feedback timing indicator
pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits;
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// TCI
pos+=dci_pdu_rel15->transmission_configuration_indication.nbits;
dci_pdu_rel15->transmission_configuration_indication.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->transmission_configuration_indication.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// CBG flushing out information
pos+=dci_pdu_rel15->cbgfi.nbits;
dci_pdu_rel15->cbgfi.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgfi.nbits)-1);
// DMRS sequence init
pos+=1;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&0x1;
break;
}
break;
}
case NR_UL_DCI_FORMAT_0_1:
switch(rnti_type)
{
case NR_RNTI_C:
// Carrier indicator
pos+=dci_pdu_rel15->carrier_indicator.nbits;
dci_pdu_rel15->carrier_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->carrier_indicator.nbits)-1);
// UL/SUL Indicator
pos+=dci_pdu_rel15->ul_sul_indicator.nbits;
dci_pdu_rel15->ul_sul_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ul_sul_indicator.nbits)-1);
// BWP Indicator
pos+=dci_pdu_rel15->bwp_indicator.nbits;
dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->bwp_indicator.nbits)-1);
// Freq domain assignment max 16 bit
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
pos+=fsize;
//pos+=dci_pdu_rel15->frequency_domain_assignment.nbits;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
// Time domain assignment 4bit
//pos+=4;
pos+=dci_pdu_rel15->time_domain_assignment.nbits;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0x3;
// Not supported yet - skip for now
// Frequency hopping flag – 1 bit
//pos++;
//dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
// MCS 5 bit
pos+=5;
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
// New data indicator 1bit
pos++;
dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1;
// Redundancy version 2bit
pos+=2;
dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3;
// HARQ process number 4bit
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
// 1st Downlink assignment index
pos+=dci_pdu_rel15->dai[0].nbits;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[0].nbits)-1);
// 2nd Downlink assignment index
pos+=dci_pdu_rel15->dai[1].nbits;
dci_pdu_rel15->dai[1].val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dai[1].nbits)-1);
// TPC command for scheduled PUSCH – 2 bits
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
// SRS resource indicator
pos+=dci_pdu_rel15->srs_resource_indicator.nbits;
dci_pdu_rel15->srs_resource_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_resource_indicator.nbits)-1);
// Precoding info and n. of layers
pos+=dci_pdu_rel15->precoding_information.nbits;
dci_pdu_rel15->precoding_information.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->precoding_information.nbits)-1);
// Antenna ports
pos+=dci_pdu_rel15->antenna_ports.nbits;
dci_pdu_rel15->antenna_ports.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->antenna_ports.nbits)-1);
// SRS request
pos+=dci_pdu_rel15->srs_request.nbits;
dci_pdu_rel15->srs_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->srs_request.nbits)-1);
// CSI request
pos+=dci_pdu_rel15->csi_request.nbits;
dci_pdu_rel15->csi_request.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->csi_request.nbits)-1);
// CBG transmission information
pos+=dci_pdu_rel15->cbgti.nbits;
dci_pdu_rel15->cbgti.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->cbgti.nbits)-1);
// PTRS DMRS association
pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits;
dci_pdu_rel15->ptrs_dmrs_association.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->ptrs_dmrs_association.nbits)-1);
// Beta offset indicator
pos+=dci_pdu_rel15->beta_offset_indicator.nbits;
dci_pdu_rel15->beta_offset_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->beta_offset_indicator.nbits)-1);
// DMRS sequence initialization
pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits;
dci_pdu_rel15->dmrs_sequence_initialization.val = (*dci_pdu>>(dci_size-pos))&((1<<dci_pdu_rel15->dmrs_sequence_initialization.nbits)-1);
// UL-SCH indicator
pos+=1;
dci_pdu_rel15->ulsch_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
// UL/SUL indicator – 1 bit
/* commented for now (RK): need to get this from BWP descriptor
if (cfg->pucch_config.pucch_GroupHopping.value)
dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ul_sul_indicator&1)<<(dci_size-pos++);
*/
break;
}
break;
}
return dci_format;
}
......
......@@ -864,7 +864,8 @@ void schedule_fapi_ul_pdu(int Mod_idP,
* conditions might exclude each other and never be true */
const int slot_idx = (slotP + K2) % num_slots_per_tdd;
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx)
&& (!get_softmodem_params()->phy_test || slotP == 6)) {
&& (!get_softmodem_params()->phy_test || slot_idx == 8)) {
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
UL_dci_req->SFN = frameP;
UL_dci_req->Slot = slotP;
......@@ -976,7 +977,7 @@ void schedule_fapi_ul_pdu(int Mod_idP,
if (get_softmodem_params()->phy_test==1)
pusch_pdu->rb_size = 50;
else
pusch_pdu->rb_size = 5;
pusch_pdu->rb_size = pusch_pdu->bwp_size;
}
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
......
......@@ -1633,7 +1633,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
UE_info->num_UEs);
dump_nr_ue_list(&UE_info->list);
for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) {
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_info->active[i])
continue;
......@@ -1684,7 +1684,8 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (!UE_info->active[i])
if (UE_info->active[i] != TRUE)
continue;
if (UE_info->rnti[i] != rnti)
continue;
......
......@@ -357,9 +357,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
return;
}
if (UE_id != -1) {
UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
gnb_mod_idP,
......
......@@ -1736,7 +1736,7 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
uint32_t stream,
S1AP_S1AP_PDU_t *pdu){
LOG_W(S1AP, "Implementation of S1AP E-RAB Modification confirm handler is pending...\n");
LOG_I(S1AP, "Received S1AP E-RAB Modification confirm message \n");
return 0;
}
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