Commit 39ab3c1e authored by Raphael Defosseux's avatar Raphael Defosseux

* MR 1015: Multi-UE + more slots

This MR adds a multi-UE scheduler (proportional fair) for multiple UEs. Tested for two UEs, but should work for more. Additionally, it enables 12 DL slots and 2 UL slots (still fixed, will be read from the configuration file in a clean-up/follow-up MR).

* MR 1019: NASMESH: support for kernel version >= 5.6.0
he syntax for ndo_tx_timeout in Linux Kernel has changed since 5.6.0 i.e it has changed

* MR 1033: ue fixes
1. Write tx data to radio unit only on tx slots.
2. Fixed a bug in DL HARQ.
3. Disabled UE and some gNB side logs which were enabled (maybe by mistake) in previous MRs.
4. In UE, check if NDI toggled before reading SDU for PUSCH.
parents 403db5f6 54a2d698
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
Num_Threads_PUSCH = 8
gNBs =
......@@ -251,6 +250,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
}
);
......
......@@ -52,7 +52,7 @@
<testCase id="090102">
<class>Initialize_OAI_UE</class>
<desc>Initialize NR UE USRP</desc>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path . --dlsch-parallel 4 </Initialize_OAI_UE_args>
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --rrc_config_path . --dlsch-parallel 4 </Initialize_OAI_UE_args>
<air_interface>NR</air_interface>
</testCase>
......
......@@ -186,7 +186,7 @@ development], for FR2 does not exist yet.
3) allocate a CCE for the UE (and return if it is not possible)
4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS.
5) Mark used resources in vrb_map_UL.
* loop through all users: get a free HARQ PID using select_ul_harq_pid() and
* loop through all users: get a free HARQ PID and
update statistics. Fill nFAPI structures directly for PUSCH, and call
config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages.
......
......@@ -873,10 +873,7 @@ void init_gNB_proc(int inst) {
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
uint32_t num_threads_pusch;
paramdef_t PUSCHThreads[] = NUM_THREADS_DESC;
config_get( PUSCHThreads,sizeof(PUSCHThreads)/sizeof(paramdef_t),NULL);
int threadCnt = min(numCPU, num_threads_pusch);
int threadCnt = min(numCPU, gNB->pusch_proc_threads);
char ul_pool[80];
sprintf(ul_pool,"-1");
int s_offset = 0;
......
......@@ -642,8 +642,7 @@ void *UE_thread(void *arg) {
UE->rx_offset_diff = computeSamplesShift(UE);
readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) -
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)-
UE->rx_offset_diff;
writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff;
}
AssertFatal(readBlockSize ==
......@@ -702,13 +701,27 @@ void *UE_thread(void *arg) {
timing_advance = UE->timing_advance;
}
int flags = 0;
int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH;
uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots +
(mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0);
uint8_t first_tx_slot = tdd_period - num_UL_slots;
if (slot_tx_usrp%tdd_period==first_tx_slot)
flags=2;
else if (slot_tx_usrp%tdd_period==first_tx_slot+num_UL_slots-1)
flags = 3;
else if (slot_tx_usrp%tdd_period>first_tx_slot)
flags = 1;
if (flags || IS_SOFTMODEM_RFSIM)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
writeTimestamp,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
1),"");
flags),"");
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
memset(txp[i], 0, writeBlockSize);
......@@ -717,7 +730,7 @@ void *UE_thread(void *arg) {
msgToPush->key=slot_nr;
pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
if ( IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR")
if (IS_SOFTMODEM_RFSIM) { //getenv("RFSIMULATOR")
// FixMe: Wait previous thread is done, because race conditions seems too bad
// in case of actual RF board, the overlap between threads mitigate the issue
// We must receive one message, that proves the slot processing is done
......
......@@ -1019,6 +1019,7 @@ typedef struct
typedef struct
{
uint8_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
uint8_t tdd_period_in_slots;
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
} fapi_nr_tdd_table_t;
......
......@@ -630,30 +630,30 @@ typedef struct {
typedef struct {
// The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535.
uint16_t RNTI[MAX_DCI_CORESET];
uint16_t RNTI;
// For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured,
// otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535
uint16_t ScramblingId[MAX_DCI_CORESET];
uint16_t ScramblingId;
// For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI.
// Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535
uint16_t ScramblingRNTI[MAX_DCI_CORESET];
uint16_t ScramblingRNTI;
// CCE start Index used to send the DCI Value: 0->135
uint8_t CceIndex[MAX_DCI_CORESET];
uint8_t CceIndex;
// Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16
uint8_t AggregationLevel[MAX_DCI_CORESET];
uint8_t AggregationLevel;
// Precoding and Beamforming structure See Table 3-43
nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET];
nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming;
// PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI.
// This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1]
// Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps
uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET];
uint8_t beta_PDCCH_1_0;
// PDCCH power value used for all other PDCCH Formats.
// This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB
uint8_t powerControlOffsetSS[MAX_DCI_CORESET];
uint8_t powerControlOffsetSS;
// The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8
uint16_t PayloadSizeBits[MAX_DCI_CORESET];
uint16_t PayloadSizeBits;
// DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB
uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN];
uint8_t Payload[DCI_PAYLOAD_BYTE_LEN];
} nfapi_nr_dl_dci_pdu_t;
......@@ -698,7 +698,7 @@ typedef struct {
///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot
uint16_t numDlDci;
///DL DCI PDU
nfapi_nr_dl_dci_pdu_t dci_pdu;
nfapi_nr_dl_dci_pdu_t dci_pdu[MAX_DCI_CORESET];
} nfapi_nr_dl_tti_pdcch_pdu_rel15_t;
typedef struct {
......
......@@ -250,9 +250,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_NR_ULSCH_MAX; ULSCH_id++) {
printf("ULSCH_id %d : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
pusch_vars[ULSCH_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
pusch_vars[ULSCH_id]->rxdataF_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rxdataF_ext2 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
......@@ -269,7 +267,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
printf("ULSCH_id %d (before rx antenna alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
for (i=0; i<Prx; i++) {
pusch_vars[ULSCH_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
......@@ -286,16 +283,13 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
}
printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot);
} //ulsch_id
/*
for (ulsch_id=0; ulsch_id<NUMBER_OF_UE_MAX; ulsch_id++)
gNB->UE_stats_ptr[ulsch_id] = &gNB->UE_stats[ulsch_id];
*/
printf("After ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]);
return (0);
}
......
......@@ -95,6 +95,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
* or the rb_offset for other coresets
* in time: by its first slot and its first symbol*/
const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
......@@ -103,7 +104,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
// DMRS length is per OFDM symbol
uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE)
uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType);
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
......@@ -125,19 +126,19 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
uint16_t n_RNTI = pdcch_pdu_rel15->dci_pdu.RNTI[d];
uint16_t Nid = pdcch_pdu_rel15->dci_pdu.ScramblingId[d];
uint16_t scrambling_RNTI = pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[d];
uint16_t n_RNTI = dci_pdu->RNTI;
uint16_t Nid = dci_pdu->ScramblingId;
uint16_t scrambling_RNTI = dci_pdu->ScramblingRNTI;
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE,
pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],
pdcch_pdu_rel15->dci_pdu.AggregationLevel[d],
dci_pdu->PayloadSizeBits,
dci_pdu->AggregationLevel,
0,NULL);
polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d], (void*)encoder_output, n_RNTI,1,currentPtr);
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI,1,currentPtr);
#ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[1]);
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5);
for (int i=0; i<encoded_length>>5; i++)
......@@ -173,7 +174,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
int reg_list_index = 0;
int reg_list_order[NR_MAX_PDCCH_AGG_LEVEL] = {};
for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) {
for(int p2 = 0; p2 < pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; p2++) {
for(int p2 = 0; p2 < dci_pdu->AggregationLevel; p2++) {
if(gNB->cce_list[d][p2].reg_list[0].reg_idx == p * NR_NB_REG_PER_CCE) {
reg_list_order[reg_list_index] = p2;
reg_list_index++;
......@@ -183,7 +184,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
}
/*Mapping the encoded DCI along with the DMRS */
for (int cce_count = 0; cce_count < pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; cce_count ++) {
for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count ++) {
int8_t cce_idx = reg_list_order[cce_count];
......@@ -239,9 +240,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
} // reg_in_cce_idx
} // cce_count
LOG_D(PHY, "DCI: payloadSize = %d | payload = %llx\n",
*pdcch_pdu_rel15->dci_pdu.PayloadSizeBits,*(unsigned long long*)pdcch_pdu_rel15->dci_pdu.Payload);
LOG_D(PHY,
"DCI: payloadSize = %d | payload = %llx\n",
dci_pdu->PayloadSizeBits,
*(unsigned long long *)dci_pdu->Payload);
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
}
......
......@@ -142,7 +142,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r
AssertFatal(N_reg > 0,"N_reg cannot be 0\n");
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
int L = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d];
int L = pdcch_pdu_rel15->dci_pdu[d].AggregationLevel;
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
......@@ -153,10 +153,10 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r
C = N_reg/(bsize*R);
}
LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu.CceIndex[d]);
LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex);
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
cce = &gNB->cce_list[d][cce_idx];
cce->cce_idx = pdcch_pdu_rel15->dci_pdu.CceIndex[d] + cce_idx;
cce->cce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx;
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
......@@ -236,25 +236,24 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu.RNTI[i],gNB,SEARCH_EXIST_OR_FREE);
int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu[i].RNTI,gNB,SEARCH_EXIST_OR_FREE);
if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){
LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu.RNTI[i],dlsch_id);
LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu[i].RNTI,dlsch_id);
return;
}
dlsch = gNB->dlsch[dlsch_id][0];
int num_slots_tdd = (gNB->frame_parms.slots_per_frame)>>(7-gNB->gNB_config.tdd_table.tdd_period.value);
int harq_pid = slot % num_slots_tdd;
int harq_pid = 0;
dlsch->slot_tx[slot] = 1;
dlsch->harq_ids[frame%2][slot] = harq_pid;
dlsch->harq_ids[frame % 2][slot] = 0;
AssertFatal(harq_pid < 8 && harq_pid >= 0,
"illegal harq_pid %d\n",harq_pid);
dlsch->harq_mask |= (1<<harq_pid);
dlsch->rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i];
dlsch->rnti = pdcch_pdu_rel15->dci_pdu[i].RNTI;
// nr_fill_cce_list(gNB,0);
/*
......@@ -300,7 +299,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload;
// if there's no DL DCI then generate CCE list
// nr_fill_cce_list(gNB,0);
......
......@@ -136,8 +136,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
dlsch = gNB->dlsch[dlsch_id][0];
if (dlsch->slot_tx[slot] == 0) continue;
int harq_pid = dlsch->harq_ids[frame%2][slot];
NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid];
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
......@@ -421,15 +420,8 @@ void dump_pdsch_stats(PHY_VARS_gNB *gNB) {
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++)
if (gNB->dlsch_stats[i].rnti > 0)
LOG_I(PHY,"DLSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes TX %d\n",
LOG_D(PHY,"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n",
gNB->dlsch_stats[i].rnti,
gNB->dlsch_stats[i].round_trials[0],
(double)gNB->dlsch_stats[i].round_trials[1]/gNB->dlsch_stats[i].round_trials[0],
gNB->dlsch_stats[i].round_trials[1],
(double)gNB->dlsch_stats[i].round_trials[2]/gNB->dlsch_stats[i].round_trials[0],
gNB->dlsch_stats[i].round_trials[2],
(double)gNB->dlsch_stats[i].round_trials[3]/gNB->dlsch_stats[i].round_trials[0],
gNB->dlsch_stats[i].round_trials[3],
gNB->dlsch_stats[i].current_Qm,
gNB->dlsch_stats[i].current_RI,
gNB->dlsch_stats[i].total_bytes_tx);
......
This diff is collapsed.
......@@ -289,12 +289,12 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
AssertFatal( (dlsch_id>=0) && (dlsch_id<NUMBER_OF_NR_DLSCH_MAX),
"illegal or no dlsch_id found!!! rnti %04x dlsch_id %d\n",rel15->rnti,dlsch_id);
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[dlsch_id][0];
NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes;
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
/// DLSCH struct
memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
gNB->num_pdsch_rnti[slot]++;
AssertFatal(sdu!=NULL,"sdu is null\n");
harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu;
harq->pdu = sdu;
}
......
......@@ -393,6 +393,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
// first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->rnti = pucch_pdu->rnti;
uci_pdu->ul_cqi = cqi;
uci_pdu->timing_advance = 0xffff; // currently not valid
uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)));
......
......@@ -203,7 +203,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
return(dlsch);
}
LOG_I(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
free_nr_ue_dlsch(&dlsch,N_RB_DL);
return(NULL);
......@@ -577,7 +577,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
LOG_I(PHY,"Segment %u CRC OK\n\033[0m",r);
LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
if (r==0) {
for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
}
......@@ -617,13 +617,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
err_flag = 1;
}
}
if (err_flag == 1) {
LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
harq_process->harq_ack.ack = 0;
......@@ -639,7 +639,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if(is_crnti)
{
LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
}
......@@ -813,6 +813,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
nb_rb = harq_process->nb_rb;
harq_process->trials[harq_process->round]++;
// HARQ stats
phy_vars_ue->dl_stats[harq_process->round]++;
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*length_dmrs, nb_rb_oh, 0, harq_process->Nl);
......@@ -826,7 +829,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
G = harq_process->G;
LOG_I(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
proc->decoder_main_available = 1;
proc->decoder_thread_available = 0;
......@@ -905,7 +908,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
return((1+dlsch->max_ldpc_iterations));
}
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
LOG_D(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
notifiedFIFO_elt_t *res_dl;
......@@ -1079,7 +1082,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
LOG_I(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
/*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
inv_d[cnt] = (1)*harq_process->d[r][cnt];
......@@ -1119,7 +1122,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
ret = 2;
}
else {
LOG_I(PHY,"CRC NOK\n");
LOG_D(PHY,"CRC NOK\n");
ret = 1+dlsch->max_ldpc_iterations;
}
......@@ -1160,7 +1163,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
err_flag = 1;
}
//} //loop r
......@@ -1181,7 +1184,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
}
if(is_crnti)
{
LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
}
......@@ -1332,7 +1335,7 @@ void nr_dlsch_decoding_process(void *arg)
p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
nb_symb_sch = harq_process->nb_symbols;
LOG_I(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
LOG_D(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
nb_rb = harq_process->nb_rb;
......@@ -1351,7 +1354,7 @@ void nr_dlsch_decoding_process(void *arg)
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
if ((harq_process->R)<1024)
Coderate = (float) (harq_process->R) /(float) 1024;
......@@ -1571,12 +1574,12 @@ void nr_dlsch_decoding_process(void *arg)
ret = 2;
}
else {
LOG_I(PHY,"Segment %u CRC NOK\n",r);
LOG_D(PHY,"Segment %u CRC NOK\n",r);
ret = 1+dlsch->max_ldpc_iterations;
}
if (no_iteration_ldpc > 10)
LOG_I(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
for (int m=0; m < Kr>>3; m ++)
......
......@@ -94,8 +94,6 @@ typedef struct {
uint32_t frame;
/// Subframe where current HARQ round was sent
uint32_t subframe;
/// Index of current HARQ round for this DLSCH
uint8_t round;
/// MIMO mode for this DLSCH
MIMO_mode_t mimo_mode;
/// Concatenated sequences
......@@ -138,8 +136,8 @@ typedef struct {
} NR_gNB_SCH_STATS_t;
typedef struct {
/// Pointers to 16 HARQ processes for the DLSCH
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
/// Pointers to variables related to DLSCH harq process
NR_DL_gNB_HARQ_t harq_process;
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
int32_t *txdataF[NR_MAX_NB_LAYERS];
/// Modulated symbols buffer
......@@ -834,6 +832,7 @@ typedef struct PHY_VARS_gNB_s {
notifiedFIFO_t *respDecode;
tpool_t *threadPool;
int nbDecode;
uint8_t pusch_proc_threads;
} PHY_VARS_gNB;
......
......@@ -201,10 +201,10 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot);
nr_generate_pdsch(gNB,frame, slot);
if ((frame&127) == 0) dump_pdsch_stats(gNB);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
if ((frame&127) == 0) dump_pdsch_stats(gNB);
//apply the OFDM symbol rotation here
apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
......
......@@ -780,19 +780,15 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
if (harq_status->ack == DL_ACKNACK_NO_SET) {
LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return (0);
}
else if (harq_status->vDAI_DL == DL_DAI_NO_SET) {
LOG_E(PHY,"PUCCH Downlink DAI has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return (0);
}
else if (harq_status->vDAI_DL > NR_DL_MAX_DAI) {
LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return (0);
}
else if (harq_status->send_harq_status == 0) {
LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return(0);
LOG_D(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
}
else {
......@@ -808,6 +804,8 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
number_harq_feedback++;
ack_data[code_word][dai_current - 1] = harq_status->ack;
dai[code_word][dai_current - 1] = dai_current;
harq_status->slot_for_feedback_ack = NR_MAX_SLOTS_PER_FRAME;
harq_status->send_harq_status = 0;
}
if (do_reset == TRUE) {
init_downlink_harq_status(ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]);
......
......@@ -427,7 +427,7 @@ int main(int argc, char **argv)
UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15;
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;
unsigned int TBS = 8424;
......@@ -519,7 +519,7 @@ int main(int argc, char **argv)
//if (i<16)
// printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
if (dlsch->harq_processes[0]->f[i] == 0)
if (dlsch->harq_process.f[i] == 0)
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
else
modulated_input[i] = -1.0; ///sqrt(2);
......@@ -547,7 +547,7 @@ int main(int argc, char **argv)
else
channel_output_uncoded[i] = 0;
if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i])
if (channel_output_uncoded[i] != dlsch->harq_process.f[i])
errors_bit_uncoded = errors_bit_uncoded + 1;
}
......
......@@ -186,8 +186,7 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dm
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1;
void nr_dlsim_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd) {
sub_frame_t slot) {
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n");
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];
......@@ -203,15 +202,25 @@ void nr_dlsim_preprocessor(module_id_t module_id,
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
sched_ctrl->cce_index = 0;
/* set "any" value for PUCCH (simulator evaluates PDSCH only) */
sched_ctrl->pucch_sched_idx = 0;
sched_ctrl->pucch_occ_idx = 0;
sched_ctrl->rbStart = g_rbStart;
sched_ctrl->rbSize = g_rbSize;
sched_ctrl->mcs = g_mcsIndex;
sched_ctrl->time_domain_allocation = 2;
sched_ctrl->mcsTableIdx = g_mcsTableIdx;
/* the simulator assumes the HARQ PID is equal to the slot number */
sched_ctrl->dl_harq_pid = slot;
/* The scheduler uses lists to track whether a HARQ process is
* free/busy/awaiting retransmission, and updates the HARQ process states.
* However, in the simulation, we never get ack or nack for any HARQ process,
* thus the list and HARQ states don't match what the scheduler expects.
* Therefore, below lines just "repair" everything so that the scheduler
* won't remark that there is no HARQ feedback */
sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process
if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ...
add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available
else
add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission
sched_ctrl->harq_processes[slot].is_waiting = false;
AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart);
AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize);
AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs);
......@@ -671,6 +680,9 @@ int main(int argc, char **argv)
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
UE_info->num_UEs=1;
// stub to configure frame_parms
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
// call MAC to configure common parameters
......@@ -836,10 +848,10 @@ int main(int argc, char **argv)
scheduled_response.thread_id = UE_proc.thread_id;
nr_ue_phy_config_request(&UE_mac->phy_config);
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
snrRun = 0;
for (SNR = snr0; SNR < snr1; SNR += .2) {
varArray_t *table_tx=initVarArray(1000,sizeof(double));
......@@ -885,7 +897,7 @@ int main(int argc, char **argv)
NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid];
NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
UE_harq_process->harq_ack.ack = 0;
round = 0;
......@@ -901,15 +913,11 @@ int main(int argc, char **argv)
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
for (int i=0; i<MAX_NUM_CORESET; i++)
gNB_mac->UE_info.num_pdcch_cand[0][i] = 0;
if (css_flag == 0) {
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
const NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity);
nr_schedule_ue_spec(0, frame, slot, num_slots_per_tdd);
nr_schedule_ue_spec(0, frame, slot);
} else {
nr_schedule_css_dlsch_phytest(0,frame,slot);
}
......@@ -1053,8 +1061,8 @@ int main(int argc, char **argv)
for (i = 0; i < available_bits; i++) {
if(((gNB_dlsch->harq_processes[harq_pid]->f[i] == 0) && (UE_llr[i] <= 0)) ||
((gNB_dlsch->harq_processes[harq_pid]->f[i] == 1) && (UE_llr[i] >= 0)))
if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) ||
((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0)))
{
if(errors_scrambling == 0) {
LOG_D(PHY,"\n");
......@@ -1067,7 +1075,7 @@ int main(int argc, char **argv)
for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
test_input_bit[i] = (gNB_dlsch->harq_process.b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
if (estimated_output_bit[i] != test_input_bit[i]) {
if(errors_bit == 0)
......@@ -1107,9 +1115,9 @@ int main(int argc, char **argv)
if (print_perf==1) {
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, TBS %d, Kr %d (Zc %d))\n",
1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex,
gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3,
gNB->dlsch[0][0]->harq_processes[0]->K,
gNB->dlsch[0][0]->harq_processes[0]->K/((gNB->dlsch[0][0]->harq_processes[0]->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10));
gNB->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3,
gNB->dlsch[0][0]->harq_process.K,
gNB->dlsch[0][0]->harq_process.K/((gNB->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3)>3824?22:10));
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
......
......@@ -46,6 +46,7 @@
#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd"
#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd"
#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference"
#define CONFIG_STRING_L1_PUSCH_PROC_THREADS "pusch_proc_threads"
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* L1 configuration parameters */
......@@ -61,6 +62,7 @@
{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0} \
}
#define L1_CC_IDX 0
#define L1_TRANSPORT_N_PREFERENCE_IDX 1
......@@ -71,6 +73,7 @@
#define L1_REMOTE_N_PORTC_IDX 6
#define L1_LOCAL_N_PORTD_IDX 7
#define L1_REMOTE_N_PORTD_IDX 8
#define L1_PUSCH_PROC_THREADS 9
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
......@@ -51,7 +51,8 @@
#include "nfapi_vnf.h"
#include "nfapi_pnf.h"
#include "L1_paramdef.h"
//#include "L1_paramdef.h"
#include "L1_nr_paramdef.h"
#include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
......@@ -399,6 +400,8 @@ void RCconfig_NR_L1(void) {
RC.gNB[j]->Mod_id = j;
}
RC.gNB[j]->pusch_proc_threads = *(L1_ParamList.paramarray[j][L1_PUSCH_PROC_THREADS].uptr);
if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
//sf_ahead = 2; // Need 4 subframe gap between RX and TX
}else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
......
......@@ -82,7 +82,6 @@ typedef enum {
/* global parameters, not under a specific section */
#define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
#define GNB_CONFIG_STRING_ACTIVE_GNBS "Active_gNBs"
#define GNB_CONFIG_PUSCH_THREADS "Num_Threads_PUSCH"
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* global configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
......@@ -92,10 +91,6 @@ typedef enum {
{GNB_CONFIG_STRING_ACTIVE_GNBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0} \
}
#define NUM_THREADS_DESC { \
{GNB_CONFIG_PUSCH_THREADS, NULL, 0, uptr:&num_threads_pusch, defuintval:1, TYPE_UINT, 0} \
}
#define GNB_ASN1_VERBOSITY_IDX 0
#define GNB_ACTIVE_GNBS_IDX 1
......
......@@ -119,22 +119,22 @@ typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED;
// Long BSR for all logical channel group ID
typedef struct {
uint8_t Buffer_size7: 8;
uint8_t Buffer_size6: 8;
uint8_t Buffer_size5: 8;
uint8_t Buffer_size4: 8;
uint8_t Buffer_size3: 8;
uint8_t Buffer_size2: 8;
uint8_t Buffer_size1: 8;
uint8_t Buffer_size0: 8;
uint8_t LcgID0: 1;
uint8_t LcgID1: 1;
uint8_t LcgID2: 1;
uint8_t LcgID3: 1;
uint8_t LcgID4: 1;
uint8_t LcgID5: 1;
uint8_t LcgID6: 1;
uint8_t LcgID7: 1;
uint8_t LcgID0: 1; // octet 1 [0]
uint8_t LcgID1: 1; // octet 1 [1]
uint8_t LcgID2: 1; // octet 1 [2]
uint8_t LcgID3: 1; // octet 1 [3]
uint8_t LcgID4: 1; // octet 1 [4]
uint8_t LcgID5: 1; // octet 1 [5]
uint8_t LcgID6: 1; // octet 1 [6]
uint8_t LcgID7: 1; // octet 1 [7]
uint8_t Buffer_size0: 8; // octet 2 [7:0]
uint8_t Buffer_size1: 8; // octet 3 [7:0]
uint8_t Buffer_size2: 8; // octet 4 [7:0]
uint8_t Buffer_size3: 8; // octet 5 [7:0]
uint8_t Buffer_size4: 8; // octet 6 [7:0]
uint8_t Buffer_size5: 8; // octet 7 [7:0]
uint8_t Buffer_size6: 8; // octet 8 [7:0]
uint8_t Buffer_size7: 8; // octet 9 [7:0]
} __attribute__ ((__packed__)) NR_BSR_LONG;
typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED;
......
......@@ -2382,9 +2382,9 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
// Set the transform precoding status according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16:
// - "UE procedure for applying transform precoding on PUSCH"
uint8_t get_transformPrecoding(NR_ServingCellConfigCommon_t *scc,
NR_PUSCH_Config_t *pusch_config,
NR_BWP_Uplink_t *ubwp,
uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
const NR_PUSCH_Config_t *pusch_config,
const NR_BWP_Uplink_t *ubwp,
uint8_t *dci_format,
int rnti_type,
uint8_t configuredGrant){
......@@ -2416,8 +2416,8 @@ uint8_t get_transformPrecoding(NR_ServingCellConfigCommon_t *scc,
return -1;
}
uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
NR_CellGroupConfig_t *secondaryCellGroup,
uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
dci_pdu_rel15_t *dci_pdu,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
......
......@@ -53,8 +53,8 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
NR_CellGroupConfig_t *secondaryCellGroup,
uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
dci_pdu_rel15_t *dci_pdu,
nr_dci_format_t format,
nr_rnti_type_t rnti_type,
......@@ -150,9 +150,9 @@ uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Posi
@param rnti_type rnti type
@param configuredGrant indicates whether a configured grant was received or not
@returns transformPrecoding value */
uint8_t get_transformPrecoding(NR_ServingCellConfigCommon_t *scc,
NR_PUSCH_Config_t *pusch_config,
NR_BWP_Uplink_t *ubwp,
uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc,
const NR_PUSCH_Config_t *pusch_config,
const NR_BWP_Uplink_t *ubwp,
uint8_t *dci_format,
int rnti_type,
uint8_t configuredGrant);
......
......@@ -82,6 +82,7 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
}
int nb_slots_per_period = ((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/nb_periods_per_frame;
cfg->tdd_table.tdd_period_in_slots = nb_slots_per_period;
if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 )
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
......
......@@ -350,6 +350,8 @@ typedef struct {
RA_config_t ra;
/// SSB index from MIB decoding
uint8_t mib_ssb;
/// Last NDI of UL HARQ processes
uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES];
//// FAPI-like interface message
fapi_nr_ul_config_request_t *ul_config_request;
......
......@@ -2046,7 +2046,7 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
if (crnti) {
// MAC CE fixed subheader
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = CRNTI;
mac_pdu_ptr->LCID = UL_SCH_LCID_C_RNTI;
mac_pdu_ptr++;
// C-RNTI MAC CE (2 octets)
......
......@@ -889,7 +889,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
if (IS_SOFTMODEM_NOS1){
// Push data from MAC to PHY only when NDI toggles
if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){
// Getting IP traffic to be transmitted
data_existing = nr_ue_get_sdu(mod_id,
cc_id,
......@@ -901,6 +902,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
&access_mode);
}
mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
//Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
if (!IS_SOFTMODEM_NOS1 || !data_existing) {
//Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
......
......@@ -346,10 +346,18 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
}
RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL =
calloc(n * 275, sizeof(uint16_t));
calloc(n * MAX_BWP_SIZE, sizeof(uint16_t));
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
"could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
for (int i = 0; i < MAX_NUM_BWP; ++i) {
RC.nrmac[Mod_idP]->pucch_index_used[i] =
calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used));
AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i],
"could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n",
i);
}
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP,
......@@ -389,22 +397,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
if (add_ue == 1 && get_softmodem_params()->phy_test) {
const int UE_id = add_new_nr_ue(Mod_idP,rnti);
UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
compute_csi_bitlen (secondaryCellGroup, UE_info, UE_id);
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
AssertFatal(bwpList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList =
secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(ubwpList->list.count == 1,
"uplinkBWP_ToAddModList has %d BWP!\n",
ubwpList->list.count);
UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1];
const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
/* TODO: should check for free RA process */
......
......@@ -59,24 +59,31 @@ void clear_mac_stats(gNB_MAC_INST *gNB) {
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
}
void dump_mac_stats(gNB_MAC_INST *gNB) {
void dump_mac_stats(gNB_MAC_INST *gNB)
{
NR_UE_info_t *UE_info = &gNB->UE_info;
NR_mac_stats_t *stats;
int lc_id;
for (int UE_id=0;UE_id<MAX_MOBILES_PER_GNB;UE_id++) {
if (UE_info->active[UE_id]) {
LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]);
stats = &UE_info->mac_stats[UE_id];
LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors);
LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes);
LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors);
LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx);
for (lc_id=0;lc_id<63;lc_id++) {
if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]);
if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]);
}
int num = 1;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
const NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",
UE_id,
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors);
LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",
UE_id,
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_errors);
LOG_I(MAC,
"UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
UE_id,
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
for (int lc_id = 0; lc_id < 63; lc_id++) {
if (stats->lc_bytes_tx[lc_id] > 0)
LOG_I(MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
if (stats->lc_bytes_rx[lc_id] > 0)
LOG_I(MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
}
}
}
......@@ -89,6 +96,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***)gNB->pdcch_pdu_idx[CC_idP];
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
&gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots];
nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0];
......@@ -103,6 +111,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
DL_req[CC_idP].dl_tti_request_body.nPDUs = 0;
DL_req[CC_idP].dl_tti_request_body.nGroup = 0;
//DL_req[CC_idP].dl_tti_request_body.transmission_power_pcfich = 6000;
memset(pdcch, 0, sizeof(**pdcch) * MAX_NUM_BWP * MAX_NUM_CORESET);
UL_dci_req[CC_idP].SFN = frameP;
UL_dci_req[CC_idP].Slot = slotP;
......@@ -299,11 +308,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
int nb_periods_per_frame;
const int UE_id = 0;
const int bwp_id = 1;
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_UE_info_t *UE_info = &gNB->UE_info;
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
......@@ -360,23 +367,27 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 3);
const uint64_t ulsch_in_slot_bitmap = (1 << 8);
#define BIT(x) (1 << (x))
const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6)
| BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16);
const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id])
for (int i=0; i<MAX_NUM_CORESET; i++)
RC.nrmac[module_idP]->UE_info.num_pdcch_cand[UE_id][i] = 0;
UE_info->num_pdcch_cand[UE_id][i] = 0;
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
//mbsfn_status[CC_id] = 0;
// clear vrb_maps
memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275);
memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * MAX_BWP_SIZE);
// clear last scheduled slot's content (only)!
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
const int last_slot = (slot + num_slots - 1) % num_slots;
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL;
memset(&vrb_map_UL[last_slot * 275], 0, sizeof(uint16_t) * 275);
memset(&vrb_map_UL[last_slot * MAX_BWP_SIZE], 0, sizeof(uint16_t) * MAX_BWP_SIZE);
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
}
......@@ -410,9 +421,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedule SR
// TODO
// This schedule CSI measurement reporting
if (UE_info->active[UE_id])
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
// Schedule CSI measurement reporting: check in slot 0 for the whole frame
if (slot == 0)
nr_csi_meas_reporting(module_idP, frame, slot);
// This schedule RA procedure if not in phy_test mode
// Otherwise already consider 5G already connected
......@@ -421,19 +432,16 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// This schedules the DCI for Uplink and subsequently PUSCH
if (slot < 10) {
{
nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap);
}
// This schedules the DCI for Downlink and PDSCH
if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)
&& slot < 10) {
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
}
if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot))
nr_schedule_ue_spec(module_idP, frame, slot);
if (UE_info->active[UE_id])
nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot);
nr_schedule_pucch(module_idP, frame, slot);
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
......
......@@ -126,7 +126,12 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
mib_sdu_length);
if ((frameP & 1023) < 80){
LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length);
LOG_D(MAC,
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
module_idP,
frameP,
CC_id,
mib_sdu_length);
}
dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
......@@ -331,13 +336,19 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
dl_req->nPDUs += 1;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nr_configure_pdcch(pdcch_pdu_rel15,
gNB_mac->sched_ctrlCommon->search_space,
gNB_mac->sched_ctrlCommon->coreset,
scc,
bwp);
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
dl_req->nPDUs += 1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
......@@ -385,48 +396,50 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos);
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET);
/* Fill PDCCH DL DCI PDU */
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
pdcch_pdu_rel15->numDlDci++;
dci_pdu->RNTI = SI_RNTI;
dci_pdu->ScramblingId = *scc->physCellId;
dci_pdu->ScramblingRNTI = 0;
dci_pdu->AggregationLevel = gNB_mac->sched_ctrlCommon->aggregation_level;
dci_pdu->CceIndex = gNB_mac->sched_ctrlCommon->cce_index;
dci_pdu->beta_PDCCH_1_0 = 0;
dci_pdu->powerControlOffsetSS = 1;
dci_pdu_rel15[0].bwp_indicator.val = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id;
/* DCI payload */
dci_pdu_rel15_t dci_payload;
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
// frequency domain assignment
dci_pdu_rel15[0].frequency_domain_assignment.val =
PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
pdsch_pdu_rel15->rbStart,
gNB_mac->type0_PDCCH_CSS_config.num_rbs);
dci_pdu_rel15[0].time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
dci_pdu_rel15[0].mcs = gNB_mac->sched_ctrlCommon->mcs;
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
dci_pdu_rel15[0].harq_pid = 0;
dci_pdu_rel15[0].ndi = 0;
dci_pdu_rel15[0].dai[0].val = 0;
dci_pdu_rel15[0].tpc = 0; // table 7.2.1-1 in 38.213
dci_pdu_rel15[0].pucch_resource_indicator = 0;
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = 0;
dci_pdu_rel15[0].antenna_ports.val = 0;
dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
nr_configure_pdcch(gNB_mac,
pdcch_pdu_rel15,
SI_RNTI,
gNB_mac->sched_ctrlCommon->search_space,
gNB_mac->sched_ctrlCommon->coreset,
scc,
bwp,
gNB_mac->sched_ctrlCommon->aggregation_level,
gNB_mac->sched_ctrlCommon->cce_index);
dci_payload.bwp_indicator.val = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id;
int dci_formats[2];
int rnti_types[2];
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
rnti_types[0] = NR_RNTI_SI;
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id);
dl_req->nPDUs += 2;
// frequency domain assignment
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs);
dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
dci_payload.harq_pid = 0;
dci_payload.ndi = 0;
dci_payload.dai[0].val = 0;
dci_payload.tpc = 0; // table 7.2.1-1 in 38.213
dci_payload.pucch_resource_indicator = 0;
dci_payload.pdsch_to_harq_feedback_timing_indicator.val = 0;
dci_payload.antenna_ports.val = 0;
dci_payload.dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
int dci_format = NR_DL_DCI_FORMAT_1_0;
int rnti_type = NR_RNTI_SI;
fill_dci_pdu_rel15(scc,
secondaryCellGroup,
&pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
&dci_payload,
dci_format,
rnti_type,
pdsch_pdu_rel15->BWPSize,
gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id);
LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
......
......@@ -255,9 +255,10 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
/* schedules whole bandwidth for first user, all the time */
void nr_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd)
sub_frame_t slot)
{
if (slot != 1)
return;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
const int UE_id = 0;
const int CC_id = 0;
......@@ -328,14 +329,25 @@ void nr_preprocessor_phytest(module_id_t module_id,
__func__,
UE_id);
nr_acknack_scheduling(module_id,
const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
if (!alloc) {
LOG_D(MAC,
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
__func__,
UE_id,
rnti,
frame,
slot,
num_slots_per_tdd,
&sched_ctrl->pucch_sched_idx,
&sched_ctrl->pucch_occ_idx);
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
slot);
UE_info->num_pdcch_cand[UE_id][cid]--;
int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid];
for (int i = 0; i < sched_ctrl->aggregation_level; i++)
cce_list[sched_ctrl->cce_index + i] = 0;
return;
}
AssertFatal(alloc,
"could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
rnti, frame, slot);
sched_ctrl->rbStart = rbStart;
sched_ctrl->rbSize = rbSize;
......@@ -350,13 +362,15 @@ void nr_preprocessor_phytest(module_id_t module_id,
}
sched_ctrl->mcs = 9;
sched_ctrl->numDmrsCdmGrpsNoData = 1;
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
/* mark the corresponding RBs as used */
for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
vrb_map[rb + sched_ctrl->rbStart] = 1;
}
void nr_ul_preprocessor_phytest(module_id_t module_id,
bool nr_ul_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
......@@ -372,7 +386,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
__func__,
UE_info->num_UEs);
if (UE_info->num_UEs == 0)
return;
return false;
const int UE_id = 0;
const int CC_id = 0;
......@@ -387,15 +401,15 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
tda,
tdaList->list.count);
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
const int sched_slot = (slot + K2) % num_slots_per_tdd;
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
/* 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 */
if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
return;
return false;
const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
uint16_t rbStart = 0;
uint16_t rbSize = 50; /* due to OAI UE limitations */
if (rbSize>bw)
......@@ -411,7 +425,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
frame,
slot,
i);
return;
return false;
}
}
......@@ -438,7 +452,7 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
nr_of_candidates);
if (sched_ctrl->cce_index < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
return;
return false;
}
UE_info->num_pdcch_cand[UE_id][cid]++;
......@@ -465,6 +479,8 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
sched_pusch->mcs = mcs;
sched_pusch->rbStart = rbStart;
sched_pusch->rbSize = rbSize;
/* get the PID of a HARQ process awaiting retransmission, or -1 for "any new" */
sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
/* Calculate TBS from MCS */
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
......@@ -487,4 +503,5 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
/* mark the corresponding RBs as used */
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
vrb_map_UL[rb] = 1;
return true;
}
......@@ -64,21 +64,9 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frame_rxP, sub_frame_t slot_rxP);
int nr_generate_dlsch_pdu(module_id_t Mod_idP,
NR_UE_sched_ctrl_t *ue_sched_ctl,
unsigned char *sdus_payload,
unsigned char *mac_pdu,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char drx_cmd,
unsigned char *ue_cont_res_id,
unsigned short post_padding);
void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
sub_frame_t slot);
void schedule_control_sib1(module_id_t module_id,
int CC_id,
......@@ -92,8 +80,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subfra
/* \brief default preprocessor */
void nr_simple_dlsch_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
sub_frame_t slot);
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame);
......@@ -105,7 +92,7 @@ void nr_schedule_ulsch(module_id_t module_id,
int ul_slots,
uint64_t ulsch_in_slot_bitmap);
void nr_simple_ulsch_preprocessor(module_id_t module_id,
bool nr_simple_ulsch_preprocessor(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
......@@ -159,11 +146,10 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
* freq resources */
void nr_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
sub_frame_t slot);
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
* fixed set of resources */
void nr_ul_preprocessor_phytest(module_id_t module_id,
bool nr_ul_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
......@@ -173,22 +159,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
void nr_fill_nfapi_dl_pdu(int Mod_id,
nfapi_nr_dl_tti_request_body_t *dl_req,
rnti_t rnti,
NR_CellGroupConfig_t *secondaryCellGroup,
NR_UE_sched_ctrl_t *sched_ctrl,
NR_sched_pucch *pucch_sched,
nfapi_nr_dmrs_type_e dmrsConfigType,
uint16_t R,
uint8_t Qm,
uint32_t tbs,
int StartSymbolIndex,
int NrOfSymbols,
int harq_pid,
int ndi,
int round);
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
......@@ -199,40 +169,30 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234);
void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
void config_uldci(const NR_BWP_Uplink_t *ubwp,
const nfapi_nr_pusch_pdu_t *pusch_pdu,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id);
int dci_format,
int time_domain_assignment,
uint8_t tpc,
int n_ubwp,
int bwp_id);
void nr_schedule_pucch(int Mod_idP,
int UE_id,
int nr_ulmix_slots,
frame_t frameP,
sub_frame_t slotP);
void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
void csi_period_offset(const NR_CSI_ReportConfig_t *csirep,
int *period, int *offset);
void nr_csi_meas_reporting(int Mod_idP,
int UE_id,
frame_t frameP,
sub_frame_t slotP,
int slots_per_tdd,
int ul_slots,
int n_slots_frame);
sub_frame_t slotP);
void nr_acknack_scheduling(int Mod_idP,
bool nr_acknack_scheduling(int Mod_idP,
int UE_id,
frame_t frameP,
sub_frame_t slotP,
int slots_per_tdd,
int *pucch_id,
int *pucch_occ);
int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l);
sub_frame_t slotP);
void get_pdsch_to_harq_feedback(int Mod_idP,
int UE_id,
......@@ -271,26 +231,22 @@ void find_search_space(int ss_type,
NR_BWP_Downlink_t *bwp,
NR_SearchSpace_t *ss);
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
uint16_t rnti,
void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
NR_SearchSpace_t *ss,
NR_ControlResourceSet_t *coreset,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp,
uint8_t aggregation_level,
int CCEIndex);
NR_BWP_Downlink_t *bwp);
void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc,
NR_CellGroupConfig_t *secondaryCellGroup,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats,
int *rnti_types,
int dci_formats,
int rnti_types,
int N_RB,
int bwp_id);
void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup,
void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
dci_pdu_rel15_t *dci_pdu_rel15,
nr_dci_format_t format,
int bwp_id);
......@@ -337,14 +293,21 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
void dump_nr_ue_list(NR_UE_list_t *listP);
void add_nr_ue_list(NR_UE_list_t *listP, int UE_id);
/* Functions to manage an NR_list_t */
void dump_nr_list(NR_list_t *listP);
void create_nr_list(NR_list_t *listP, int len);
void destroy_nr_list(NR_list_t *list);
void add_nr_list(NR_list_t *listP, int id);
void remove_nr_list(NR_list_t *listP, int id);
void add_tail_nr_list(NR_list_t *listP, int id);
void add_front_nr_list(NR_list_t *listP, int id);
void remove_front_nr_list(NR_list_t *listP);
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup);
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
......@@ -438,4 +401,5 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
void find_SSB_and_RO_available(module_id_t module_idP);
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
......@@ -113,18 +113,9 @@ void mac_top_init_gNB(void)
UE_info = &nrmac->UE_info;
UE_info->num_UEs = 0;
UE_info->list.head = -1;
create_nr_list(&UE_info->list, MAX_MOBILES_PER_GNB);
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) {
UE_info->list.next[list_el] = -1;
UE_info->active[list_el] = false;
for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) {
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
}
}
}
......
......@@ -75,10 +75,20 @@
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
#define MAX_HARQ_ROUNDS 4
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
/*! \brief NR_list_t is a "list" (of users, HARQ processes, slices, ...).
* Especially useful in the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int *next;
int tail;
int len;
} NR_list_t;
typedef enum {
RA_IDLE = 0,
Msg2 = 1,
......@@ -282,7 +292,7 @@ typedef struct NR_sched_pucch {
uint8_t dai_c;
uint8_t timing_indicator;
uint8_t resource_indicator;
} NR_sched_pucch;
} NR_sched_pucch_t;
/* this struct is a helper: as long as the TDA and DCI format remain the same
* over the same uBWP and search space, there is no need to recalculate all
......@@ -326,13 +336,20 @@ typedef struct NR_sched_pusch {
uint16_t R;
uint8_t Qm;
uint32_t tb_size;
/// UL HARQ PID to use for this UE, or -1 for "any new"
int8_t ul_harq_pid;
} NR_sched_pusch_t;
typedef struct NR_UE_harq {
uint8_t is_waiting;
bool is_waiting;
uint8_t ndi;
uint8_t round;
uint16_t feedback_slot;
/* Transport block to be sent using this HARQ process */
uint32_t tb[16384];
uint32_t tb_size;
} NR_UE_harq_t;
typedef struct NR_UE_old_sched {
......@@ -350,10 +367,13 @@ typedef enum {
} NR_UL_harq_states_t;
typedef struct NR_UE_ul_harq {
bool is_waiting;
uint8_t ndi;
uint8_t round;
uint16_t last_tx_slot;
NR_UL_harq_states_t state;
uint16_t feedback_slot;
/// sched_pusch keeps information on MCS etc used for the initial transmission
NR_sched_pusch_t sched_pusch;
} NR_UE_ul_harq_t;
......@@ -387,10 +407,12 @@ typedef struct {
/// the currently active BWP in UL
NR_BWP_Uplink_t *active_ubwp;
NR_sched_pucch **sched_pucch;
/// selected PUCCH index, if scheduled
int pucch_sched_idx;
int pucch_occ_idx;
/// PUCCH scheduling information. Array of three, we assume for the moment:
/// HARQ in the first field, SR in second, CSI in third (as fixed by RRC
/// conf., i.e. if actually present). The order is important for
/// nr_acknack_scheduling()!
NR_sched_pucch_t sched_pucch[3];
NR_sched_pusch_save_t pusch_save;
NR_sched_pusch_t sched_pusch;
......@@ -404,6 +426,11 @@ typedef struct {
uint16_t rbSize;
uint16_t rbStart;
/// uplink bytes that are currently scheduled
int sched_ul_bytes;
/// estimation of the UL buffer size
int estimated_ul_buffer;
// time-domain allocation for scheduled RBs
int time_domain_allocation;
......@@ -414,6 +441,8 @@ typedef struct {
/// Retransmission-related information
NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
/// DL HARQ PID to use for this UE, or -1 for "any new"
int8_t dl_harq_pid;
uint16_t ta_frame;
int16_t ta_update;
......@@ -421,8 +450,22 @@ typedef struct {
uint8_t tpc0;
uint8_t tpc1;
uint16_t ul_rssi;
/// information about every HARQ process
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
/// HARQ processes that are free
NR_list_t available_dl_harq;
/// HARQ processes that await feedback
NR_list_t feedback_dl_harq;
/// HARQ processes that await retransmission
NR_list_t retrans_dl_harq;
/// information about every UL HARQ process
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
/// UL HARQ processes that are free
NR_list_t available_ul_harq;
/// UL HARQ processes that await feedback
NR_list_t feedback_ul_harq;
/// UL HARQ processes that await retransmission
NR_list_t retrans_ul_harq;
int dummy;
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
} NR_UE_sched_ctrl_t;
......@@ -438,22 +481,15 @@ typedef struct {
int dlsch_rounds[8];
int dlsch_errors;
int dlsch_total_bytes;
int dlsch_current_bytes;
int ulsch_rounds[8];
int ulsch_errors;
int ulsch_total_bytes_scheduled;
int ulsch_total_bytes_rx;
int ulsch_current_bytes;
} NR_mac_stats_t;
/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
* the scheduler and to keep "classes" of users. */
typedef struct {
int head;
int next[MAX_MOBILES_PER_GNB];
} NR_UE_list_t;
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
#define MAX_CSI_REPORTCONFIG 48
typedef struct {
......@@ -461,7 +497,7 @@ typedef struct {
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG];
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
NR_UE_list_t list;
NR_list_t list;
int num_UEs;
bool active[MAX_MOBILES_PER_GNB];
......@@ -477,9 +513,8 @@ typedef struct {
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd);
typedef void (*nr_pp_impl_ul)(module_id_t mod_id,
sub_frame_t slot);
typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
int num_slots_per_tdd,
......@@ -510,6 +545,10 @@ typedef struct gNB_MAC_INST_s {
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
/// NFAPI DL Config Request Structure
nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX];
/// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure
/// keeps pointers to PDCCH PDUs within DL_req so that we can easily track
/// PDCCH PDUs per CC/BWP/CORESET
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_BWP][MAX_NUM_CORESET];
/// NFAPI UL TTI Request Structure, simple pointer into structure
/// UL_tti_req_ahead for current frame/slot
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
......@@ -550,6 +589,10 @@ typedef struct gNB_MAC_INST_s {
time_stats_t schedule_pch;
/// CCE lists
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
/// PUCCH: keep track of the resources has already been used by saving the
/// highest index not yet been used in a given slot. Dynamically allocated
/// so we can have it for every slot as a function of the numerology
int *pucch_index_used[MAX_NUM_BWP];
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
......
......@@ -220,7 +220,7 @@ static void *enb_tun_read_thread(void *_)
exit(1);
}
printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
LOG_D(PDCP, "%s(): nas_sock_fd read returns len %d\n", __func__, len);
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
......@@ -264,7 +264,7 @@ static void *ue_tun_read_thread(void *_)
exit(1);
}
printf("\n\n\n########## nas_sock_fd read returns len %d\n", len);
LOG_D(PDCP, "%s(): nas_sock_fd read returns len %d\n", __func__, len);
nr_pdcp_manager_lock(nr_pdcp_ue_manager);
rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager);
......
......@@ -1581,7 +1581,7 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
}
if (entity->tx_size + size > entity->tx_maxsize) {
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
LOG_E(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__);
return;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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