Merge remote-tracking branch 'origin/NR_UL_scheduling' into NR_RRCConfiguration_FR2

This commit is contained in:
Rakesh
2020-08-21 13:52:51 +02:00
93 changed files with 2973 additions and 1592 deletions
+3 -2
View File
@@ -1256,7 +1256,7 @@ set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c
@@ -1551,7 +1551,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
#${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
@@ -2984,6 +2984,7 @@ target_link_libraries(nr_ulschsim
add_executable(nr_ulsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c
+6
View File
@@ -105,3 +105,9 @@ char *itoa(int i) {
return strdup(buffer);
}
void *memcpy1(void *dst,const void *src,size_t n) {
void *ret=dst;
asm volatile("rep movsb" : "+D" (dst) : "c"(n), "S"(src) : "cc","memory");
return(ret);
}
+3
View File
@@ -15,6 +15,9 @@ int hex_char_to_hex_value (char c);
// Converts an hexadecimal ASCII coded string into its value.**
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
void *memcpy1(void *dst,const void *src,size_t n);
char *itoa(int i);
#define findInList(keY, result, list, element_type) {\
+1 -4
View File
@@ -1123,9 +1123,6 @@ int restart_L1L2(module_id_t enb_id) {
sync_var = -1;
pthread_mutex_unlock(&sync_mutex);
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this eNB */
memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
/* reset the list of connected UEs in the MAC, since in this process with
* loose all UEs (have to reconnect) */
init_UE_info(&RC.mac[enb_id]->UE_info);
@@ -1348,7 +1345,7 @@ int main ( int argc, char **argv ) {
// end of CI modifications
//getchar();
if(IS_SOFTMODEM_DOFORMS)
load_softscope("enb");
load_softscope("enb", NULL);
itti_wait_tasks_end();
oai_exit=1;
-3
View File
@@ -726,9 +726,6 @@ int restart_L1L2(module_id_t gnb_id) {
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this gNB */
memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS));
set_function_spec_param(RC.ru[gnb_id]);
LOG_I(GNB_APP, "attempting to create ITTI tasks\n");
// No more rrc thread, as many race conditions are hidden behind
+1 -9
View File
@@ -35,9 +35,7 @@
#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
#include "SCHED_NR/phy_frame_config_nr.h"
//#endif
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "SCHED_NR_UE/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -577,12 +575,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
if (IS_SOFTMODEM_RFSIM) {
LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 &&
UE->rx_offset > 0 ) {
+61 -8
View File
@@ -310,15 +310,68 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
{
uint32_t EQm;
EQm = E/Qm;
for (int j = 0; j< EQm; j++){
for (int i = 0; i< Qm; i++){
e[(i*EQm + j)] = f[(i+j*Qm)];
}
int j2;
int16_t *e1,*e2,*e3,*e4,*e5,*e6,*e7;
switch(Qm) {
case 2:
e1=e+(E/2);
for (int j = 0,j2=0; j< E/2; j+=2,j2+=4){
e[j] = f[j2];
e1[j] = f[j2+1];
e[j+1] = f[j2+2];
e1[j+1] = f[j2+3];
}
break;
case 4:
e1=e+(E/4);
e2=e1+(E/4);
e3=e2+(E/4);
for (int j = 0,j2=0; j< E/4; j++,j2+=4){
e[j] = f[j2];
e1[j] = f[j2+1];
e2[j] = f[j2+2];
e3[j] = f[j2+3];
}
break;
case 6:
e1=e+(E/6);
e2=e1+(E/6);
e3=e2+(E/6);
e4=e3+(E/6);
e5=e4+(E/6);
for (int j = 0,j2=0; j< E/6; j++,j2+=6){
e[j] = f[j2];
e1[j] = f[j2+1];
e2[j] = f[j2+2];
e3[j] = f[j2+3];
e4[j] = f[j2+4];
e5[j] = f[j2+5];
}
break;
case 8:
e1=e+(E/6);
e2=e1+(E/6);
e3=e2+(E/6);
e4=e3+(E/6);
e5=e4+(E/6);
e6=e5+(E/6);
e7=e6+(E/6);
for (int j = 0,j2=0; j< E/8; j++,j2+=8){
e[j] = f[j2];
e1[j] = f[j2+1];
e2[j] = f[j2+2];
e3[j] = f[j2+3];
e4[j] = f[j2+4];
e5[j] = f[j2+5];
e6[j] = f[j2+6];
e7[j] = f[j2+7];
}
break;
default:
AssertFatal(1==0,"Should not get here : Qm %d\n",Qm);
break;
}
}
-1
View File
@@ -186,7 +186,6 @@ void phy_free_RU(RU_t *ru) {
int i,j,p;
RU_CALIBRATION *calibration = &ru->calibration;
LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
free_and_zero(ru->frame_parms);
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]);
+11
View File
@@ -199,6 +199,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t));
}
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
common_vars->debugBuff_sample_offset = 0;
// Channel estimates for SRS
@@ -504,6 +506,15 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_I(PHY, "Initialise nr transport\n");
uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value;
memset(gNB->num_pdsch_rnti, 0, sizeof(uint16_t)*80);
for (i=0; i <NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_I(PHY,"Initializing PDCCH list for PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->pdcch_pdu[i].frame=-1;
LOG_I(PHY,"Initializing UL PDCCH list for UL PDCCH %d/%d\n",i,NUMBER_OF_NR_PDCCH_MAX);
gNB->ul_pdcch_pdu[i].frame=-1;
}
for (i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for PUCCH %d/%d\n",i,NUMBER_OF_NR_PUCCH_MAX);
gNB->pucch[i] = new_gNB_pucch();
+3 -3
View File
@@ -121,9 +121,9 @@ int nr_phy_init_RU(RU_t *ru) {
LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst);
int beam_count = 0;
if (ru->nb_log_antennas>1) {
if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01)
if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
beam_count++;
}
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
@@ -131,7 +131,7 @@ int nr_phy_init_RU(RU_t *ru) {
int l_ind = 0;
for (i=0; i<RC.nb_nr_L1_inst; i++) {
for (p=0;p<ru->nb_log_antennas;p++) {
if ((fp->L_ssb >> p) & 0x01) {
if ((fp->L_ssb >> (63-p)) & 0x01) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
+2 -2
View File
@@ -308,7 +308,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value;
for (int p=0; p<num_tx_ant; p++)
fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01);
return 0;
@@ -389,7 +389,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->N_ssb = 0;
for (int p=0; p<fp->Lmax; p++)
fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01);
return 0;
}
+1 -1
View File
@@ -155,7 +155,7 @@ int nr_beam_precoding(int32_t **txdataF,
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
for (p=0; p<nb_antenna_ports; p++) {
if ((frame_parms->L_ssb >> p) & 0x01) {
if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size],
(int16_t*)beam_weights[p][aa],
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
+3 -1
View File
@@ -27,6 +27,7 @@
This section deals with basic functions for OFDM Modulation.
*/
#include "PHY/defs_eNB.h"
@@ -47,6 +48,7 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
PHY_ofdm_mod(txdataF, // input
txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
@@ -177,7 +179,7 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
/*for (j=0; j<fftsize ; j++) {
output_ptr[j] = temp_ptr[j];
}*/
memcpy((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
memcpy1((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
}
j=fftsize;
@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
/*! \file PHY/NR_ESTIMATION/nr_measurements_gNB.c
* \brief TA estimation for TA updates
* \author Ahmed Hussein
* \date 2019
@@ -69,3 +69,37 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
return max_pos - sync_pos;
}
void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_COMMON *common_vars = &gNB->common_vars;
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
uint32_t *rb_mask = gNB->rb_mask_ul;
int symbol = gNB->ulmask_symb;
int rb, offset, nb_rb;
uint32_t n0_power_tot, n0_subband_power_temp=0;
int32_t *ul_ch;
if (symbol>-1) {
n0_power_tot = 0;
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
nb_rb = 0;
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
nb_rb++;
offset = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
offset += (symbol*frame_parms->ofdm_symbol_size);
ul_ch = &common_vars->rxdataF[aarx][offset];
//TODO what about DC?
n0_subband_power_temp += signal_energy_nodc(ul_ch,12);
}
}
measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
n0_power_tot += measurements->n0_power[aarx];
}
measurements->n0_power_tot_dB = dB_fixed(n0_power_tot);
}
}
@@ -34,6 +34,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
unsigned short p,
unsigned char symbol,
int ul_id,
unsigned short bwp_start_subcarrier,
nfapi_nr_pusch_pdu_t *pusch_pdu) {
@@ -43,8 +44,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned int pilot_cnt,re_cnt;
int16_t ch[2],ch_r[2],ch_l[2],*pil,*rxF,*ul_ch;
int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh;
int ch_offset,symbol_offset, UE_id = 0;
int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time;
int ch_offset,symbol_offset ;
int32_t **ul_ch_estimates_time = gNB->pusch_vars[ul_id]->ul_ch_estimates_time;
__m128i *ul_ch_128;
#ifdef DEBUG_CH
@@ -55,7 +56,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
uint8_t nushift;
int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates;
int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates;
int **rxdataF = gNB->common_vars.rxdataF;
nushift = (p>>1)&1;
@@ -338,7 +339,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8);
}
}
#ifdef DEBUG_PDSCH
#ifdef DEBUG_PUSCH
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI+=2) {
@@ -43,9 +43,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
unsigned short p,
unsigned char symbol,
int ul_id,
unsigned short bwp_start_subcarrier,
nfapi_nr_pusch_pdu_t *pusch_pdu);
void gNB_I0_measurements(PHY_VARS_gNB *gNB);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
#endif
+1
View File
@@ -55,5 +55,6 @@ void init_scrambling_luts(void);
extern __m64 byte2m64_re[256];
extern __m64 byte2m64_im[256];
extern __m128i byte2m128i[256];
#endif
+17 -1
View File
@@ -32,6 +32,8 @@
__m64 byte2m64_re[256];
__m64 byte2m64_im[256];
__m128i byte2m128i[256];
void init_byte2m64(void) {
for (int s=0;s<256;s++) {
@@ -54,10 +56,24 @@ void init_byte2m64(void) {
}
}
void init_byte2m128i(void) {
for (int s=0;s<256;s++) {
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*(s&1)),0);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>1)&1)),1);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>2)&1)),2);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>3)&1)),3);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>4)&1)),4);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>5)&1)),5);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>6)&1)),6);
byte2m128i[s] = _mm_insert_epi16(byte2m128i[s],(1-2*((s>>7)&1)),7);
}
}
void init_scrambling_luts(void) {
init_byte2m64();
init_byte2m128i();
}
#endif
+10 -5
View File
@@ -154,8 +154,10 @@ void nr_pdcch_scrambling(uint32_t *in,
}
uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu,
uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu,
uint32_t **gold_pdcch_dmrs,
int32_t *txdataF,
int16_t amp,
@@ -180,15 +182,17 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
if (pdcch_pdu) pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15;
else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu_rel15;
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
// compute rb_offset and n_prb based on frequency allocation
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = frame_parms.first_carrier_offset + (frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB +
rb_offset)*NR_NB_SC_PER_RB;
cset_start_sc = frame_parms.first_carrier_offset +
(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + rb_offset)*NR_NB_SC_PER_RB;
} else
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
@@ -324,6 +328,7 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
k -= frame_parms.ofdm_symbol_size;
} // m
} // reg_idx
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
return 0;
}
+13 -6
View File
@@ -29,9 +29,10 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB);
uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu,
uint32_t **gold_pdcch_dmrs,
uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
nfapi_nr_dl_tti_pdcch_pdu *ul_pdcch_pdu,
uint32_t **gold_pdcch_dmrs,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS frame_parms);
@@ -42,15 +43,21 @@ void nr_pdcch_scrambling(uint32_t *in,
uint32_t n_RNTI,
uint32_t *out);
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
void nr_fill_dci(PHY_VARS_gNB *gNB,
int frame,
int slot);
int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu);
int16_t find_nr_ul_dci(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
int frame,
int slot);
int slot,
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu);
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m);
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *);
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
+60 -8
View File
@@ -118,11 +118,11 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint16_t n_shift, uint8_t m) {
*/
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15) {
nr_cce_t* cce;
nr_reg_t* reg;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15;
int bsize = pdcch_pdu_rel15->RegBundleSize;
int R = pdcch_pdu_rel15->InterleaverSize;
int n_shift = pdcch_pdu_rel15->ShiftIndex;
@@ -139,6 +139,8 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
int N_reg = n_rb * pdcch_pdu_rel15->DurationSymbols;
int C=-1;
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];
@@ -200,14 +202,38 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) {
ret |= ((field>>i)&1)<<(size-i-1);
return ret;
}*/
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->pdcch_pdu[i].frame,gNB->pdcch_pdu[i].slot,first_free_index);
if ((gNB->pdcch_pdu[i].frame == frame) &&
(gNB->pdcch_pdu[i].slot==slot)) return i;
else if ( gNB->pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_dci(PHY_VARS_gNB *gNB,
int frame,
int slot) {
int slot,
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->pdcch_pdu->pdcch_pdu_rel15;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
NR_gNB_DLSCH_t *dlsch;
int pdcch_id = find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for PDCCH, exiting\n");
memcpy((void*)&gNB->pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->pdcch_pdu[pdcch_id].frame = frame;
gNB->pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
@@ -230,7 +256,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
dlsch->harq_mask |= (1<<harq_pid);
dlsch->rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i];
nr_fill_cce_list(gNB,0);
// nr_fill_cce_list(gNB,0);
/*
LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
@@ -239,19 +265,45 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
}
}
int16_t find_nr_ul_dci(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_PDCCH_MAX; i++) {
LOG_D(PHY,"searching for frame.slot %d.%d : ul_pdcch_index %d frame.slot %d.%d, first_free_index %d\n", frame,slot,i,gNB->ul_pdcch_pdu[i].frame,gNB->ul_pdcch_pdu[i].slot,first_free_index);
if ((gNB->ul_pdcch_pdu[i].frame == frame) &&
(gNB->ul_pdcch_pdu[i].slot==slot)) return i;
else if (gNB->ul_pdcch_pdu[i].frame==-1 && first_free_index==-1) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
return first_free_index;
}
void nr_fill_ul_dci(PHY_VARS_gNB *gNB,
int frame,
int slot) {
int slot,
nfapi_nr_ul_dci_request_pdus_t *pdcch_pdu) {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
int pdcch_id = find_nr_ul_dci(frame,slot,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal(pdcch_id>=0 && pdcch_id<NUMBER_OF_NR_PDCCH_MAX,"Cannot find space for UL PDCCH, exiting\n");
memcpy((void*)&gNB->ul_pdcch_pdu[pdcch_id].pdcch_pdu,(void*)pdcch_pdu,sizeof(*pdcch_pdu));
gNB->ul_pdcch_pdu[pdcch_id].frame = frame;
gNB->ul_pdcch_pdu[pdcch_id].slot = slot;
for (int i=0;i<pdcch_pdu_rel15->numDlDci;i++) {
//uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i];
// if there's no DL DCI then generate CCE list
if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0);
// nr_fill_cce_list(gNB,0);
/*
LOG_D(PHY, "DCI PDU: [0]->0x%lx \t [1]->0x%lx \n",dci_pdu[0], dci_pdu[1]);
LOG_D(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
+6 -3
View File
@@ -61,7 +61,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
@@ -150,7 +150,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
@@ -326,7 +326,8 @@ int nr_dlsch_encoding(unsigned char *a,
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15;
uint16_t nb_rb = rel15->rbSize;
uint8_t nb_symb_sch = rel15->NrOfSymbols;
uint32_t A, Z, Kb, F=0;
uint32_t A, Kb, F=0;
static uint32_t Z = 0;
uint32_t *Zc = &Z;
uint8_t mod_order = rel15->qamModOrder[0];
uint16_t Kr=0,r;
@@ -347,6 +348,8 @@ int nr_dlsch_encoding(unsigned char *a,
float Coderate = 0.0;
uint8_t Nl = 4;
dlsch->harq_processes[harq_pid]->round = nr_rv_round_map[rel15->rvIndex[0]];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
A = rel15->TBSize[0]<<3;
+1 -1
View File
@@ -291,7 +291,7 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes;
/// DLSCH struct
memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu));
gNB->num_pdsch_rnti++;
gNB->num_pdsch_rnti[slot]++;
AssertFatal(sdu!=NULL,"sdu is null\n");
harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu;
-1
View File
@@ -37,7 +37,6 @@
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
extern const char *prachfmt[9];
void init_prach_list(PHY_VARS_gNB *gNB) {
@@ -157,6 +157,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms);
@@ -342,9 +343,15 @@ void nr_decode_pucch1(int32_t **rxdataF,
uint8_t timeDomainOCC,
uint8_t nr_bit);
void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int slot,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu);
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int slot,
int slot,
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu);
#endif /*__NR_TRANSPORT__H__*/
+35 -1
View File
@@ -33,7 +33,7 @@
#include <stdint.h>
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
@@ -103,3 +103,37 @@ void nr_ulsch_unscrambling(int16_t* llr,
llr[i] = -llr[i];
}
}
void nr_ulsch_unscrambling_optim(int16_t* llr,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI) {
#if defined(__x86_64__) || defined(__i386__)
uint8_t reset;
uint32_t x1, x2, s=0;
x2 = (n_RNTI<<15) + Nid;
uint8_t *s8=(uint8_t *)&s;
__m128i *llr128 = (__m128i*)llr;
int j=0;
s = lte_gold_generic(&x1, &x2, 1);
for (int i=0; i<((size>>5)+((size&0x1f) > 0 ? 1 : 0)); i++,j+=4) {
llr128[j] = _mm_mullo_epi16(llr128[j],byte2m128i[s8[0]]);
llr128[j+1] = _mm_mullo_epi16(llr128[j+1],byte2m128i[s8[1]]);
llr128[j+2] = _mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]);
llr128[j+3] = _mm_mullo_epi16(llr128[j+3],byte2m128i[s8[3]]);
s = lte_gold_generic(&x1, &x2, 0);
}
#else
nr_ulsch_unscrambling(llr,
size,
q,
Nid,
n_RNTI);
#endif
}
+6
View File
@@ -75,6 +75,12 @@ void nr_ulsch_unscrambling(int16_t* llr,
uint32_t n_RNTI);
void nr_ulsch_unscrambling_optim(int16_t* llr,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI);
void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
int frame_rx,
int slot_rx,
+12 -15
View File
@@ -67,7 +67,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
if (ulsch) {
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
@@ -119,11 +119,10 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint16_t N_RB_UL, uint
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment
ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));
if (ulsch) {
@@ -360,19 +359,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
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);
if (harq_process->round == 0) {
// 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 (R<1024)
Coderate = (float) R /(float) 1024;
@@ -409,6 +402,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
}
if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
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)
nr_segmentation(NULL,
NULL,
@@ -438,7 +438,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (nb_rb != 273) {
a_segments = a_segments*nb_rb;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
if (harq_process->C > a_segments) {
@@ -479,7 +479,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
#ifdef DEBUG_ULSCH_DECODING
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,
@@ -489,7 +488,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
n_layers,
pusch_pdu->pusch_data.rv_index,
harq_process->round);
#endif
//////////////////////////////////////////////////////////////////////////////////////////
@@ -573,7 +571,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
AssertFatal(kc!=255,"");
j+=(harq_process->F>>3);
// for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
@@ -683,7 +680,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->status = SCH_IDLE;
harq_process->round = 0;
// harq_process->handled = 0;
ulsch->harq_mask &= ~(1 << harq_pid);
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;
+129 -80
View File
@@ -226,6 +226,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms)
{
@@ -238,7 +239,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
uint32_t ul_ch0_index = 0;
uint32_t ul_ch0_ptrs_ext_index = 0;
uint32_t ul_ch0_ptrs_index = 0;
uint8_t is_ptrs_symbol_flag,k_prime;
uint8_t k_prime;
uint16_t n=0, num_ptrs_symbols;
int16_t *rxF,*rxF_ext;
int *ul_ch0,*ul_ch0_ext;
@@ -253,20 +254,25 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
#endif
uint8_t is_dmrs_re;
uint8_t is_dmrs_re=0,is_ptrs_re=0;
start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
is_ptrs_symbol_flag = 0;
#ifdef __AVX2__
int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
#else
int nb_re_pusch2 = nb_re_pusch;
#endif
num_ptrs_symbols = 0;
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
ul_ch0 = &pusch_vars->ul_ch_estimates[aarx][pusch_vars->dmrs_symbol*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch];
ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2];
ul_ch0_ptrs = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
@@ -275,63 +281,73 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
n = 0;
k_prime = 0;
for (re = 0; re < nb_re_pusch; re++) {
if (is_dmrs_symbol)
is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
else
is_dmrs_re = 0;
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
if(is_ptrs_symbol(symbol, pusch_vars->ptrs_symbols))
is_ptrs_symbol_flag = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
n_rnti,
aarx,
pusch_pdu->dmrs_config_type,
K_ptrs,
pusch_pdu->rb_size,
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
start_re,
frame_parms->ofdm_symbol_size);
if (is_ptrs_symbol_flag == 1)
num_ptrs_symbols++;
if (is_dmrs_symbol == 0 && is_ptrs_symbol == 0) {
//
//rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) memcpy1((void*)rxF_ext,
(void*)&rxF[start_re*2],
nb_re_pusch*sizeof(int32_t));
else {
int neg_length = frame_parms->ofdm_symbol_size-start_re;
int pos_length = nb_re_pusch-neg_length;
memcpy1((void*)rxF_ext,(void*)&rxF[start_re*2],neg_length*sizeof(int32_t));
memcpy1((void*)&rxF_ext[2*neg_length],(void*)rxF,pos_length*sizeof(int32_t));
}
#ifdef DEBUG_RB_EXT
printf("re = %d, is_ptrs_symbol_flag = %d, symbol = %d\n", re, is_ptrs_symbol_flag, symbol);
#endif
if ( is_dmrs_re == 0 && is_ptrs_symbol_flag == 0) {
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
#ifdef DEBUG_RB_EXT
printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]);
#endif
ul_ch0_ext_index++;
ul_ch0_ptrs_ext_index++;
rxF_ext_index +=2;
} else {
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
}
ul_ch0_index++;
ul_ch0_ptrs_index++;
memcpy1((void*)ul_ch0_ext,(void*)ul_ch0,nb_re_pusch*sizeof(int32_t));
}
}
else {
for (re = 0; re < nb_re_pusch; re++) {
if (is_dmrs_symbol) is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
if (is_ptrs_symbol) {
K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
is_ptrs_re = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
n_rnti,
aarx,
pusch_pdu->dmrs_config_type,
K_ptrs,
pusch_pdu->rb_size,
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
start_re,
frame_parms->ofdm_symbol_size);
num_ptrs_symbols+=is_ptrs_re;
}
#ifdef DEBUG_RB_EXT
printf("re = %d, ptrs_symbol_flag = %d, symbol = %d\n", re, ptrs_symbol_flag, symbol);
#endif
if ( is_dmrs_re == 0 && is_ptrs_re == 0) {
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
#ifdef DEBUG_RB_EXT
printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]);
#endif
ul_ch0_ext_index++;
ul_ch0_ptrs_ext_index++;
rxF_ext_index +=2;
} else {
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
}
ul_ch0_index++;
ul_ch0_ptrs_index++;
}
} // is_dmrs_symbol ==0 && is_ptrs_symbol == 0
}
pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols;
}
void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
NR_gNB_ULSCH_t **ulsch_gNB,
@@ -356,10 +372,16 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
#ifdef __AVX2__
int off = ((nb_rb&1) == 1)? 4:0;
#else
int off = 0;
#endif
for (aatx=0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) {
for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB];
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*(off+(nb_rb*NR_NB_SC_PER_RB))];
if (is_dmrs_symbol==1){
if (pusch_dmrs_type == pusch_dmrs_type1)
@@ -408,12 +430,18 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
int16_t x = factor2(len);
int16_t y = (len)>>x;
#ifdef __AVX2__
int off = ((nb_rb&1) == 1)? 4:0;
#else
int off = 0;
#endif
for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++)
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
//clear average level
avg128U = _mm_setzero_si128();
ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
for (rb = 0; rb < len/12; rb++) {
avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
@@ -501,13 +529,13 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
unsigned short nb_rb,
unsigned char output_shift) {
#ifdef DEBUG_CH_COMP
int16_t *rxF, *ul_ch;
int prnt_idx;
rxF = (int16_t *)&rxdataF_ext[0][(symbol*nb_rb*12)];
ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12];
rxF = (int16_t *)&rxdataF_ext[0][symbol*(off+(nb_rb*12))];
ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*(off+(nb_rb*1))2];
printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift);
printf("----------------Before compensation------------------\n");
@@ -526,7 +554,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
int print_idx;
ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)];
ch_mag = (int16_t *)&ul_ch_mag[0][symbol*(off+(nb_rb*12))];
printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order);
printf("----------------Before computation------------------\n");
@@ -539,7 +567,13 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
#endif
#if defined(__i386) || defined(__x86_64)
#ifdef __AVX2__
int off = ((nb_rb&1) == 1)? 4:0;
#else
int off = 0;
#endif
#if defined(__i386) || defined(__x86_64__)
unsigned short rb;
unsigned char aatx,aarx;
@@ -561,11 +595,11 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12];
ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12];
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*(off+(nb_rb*12))];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*(off+(nb_rb*12))];
for (rb=0; rb<nb_rb; rb++) {
@@ -981,7 +1015,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
#ifdef DEBUG_CH_COMP
rxF = (int16_t *)&rxdataF_comp[0][(symbol*nb_rb*12)];
rxF = (int16_t *)&rxdataF_comp[0][(symbol*(off+(nb_rb*12)))];
printf("----------------After compansation------------------\n");
@@ -996,7 +1030,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
#ifdef DEBUG_CH_MAG
ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)];
ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))];
printf("----------------After computation------------------\n");
@@ -1019,6 +1053,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
{
uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
uint8_t ptrs_symbol_flag; // a flag to indicate PTRS REs in current symbol
uint32_t nb_re_pusch, bwp_start_subcarrier;
uint8_t L_ptrs = 0; // PTRS parameter
int avgs;
@@ -1027,6 +1062,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
dmrs_symbol_flag = 0;
ptrs_symbol_flag = 0;
gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
if(symbol == rel15_ul->start_symbol_index){
@@ -1046,6 +1083,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
}
}
bwp_start_subcarrier = (rel15_ul->rb_start*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
@@ -1068,22 +1106,32 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
}
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols)) {
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
ptrs_symbol_flag = 1;
}
}
//----------------------------------------------------------
//--------------------- Channel estimation ---------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_channel_estimation_stats);
if (dmrs_symbol_flag == 1)
if (dmrs_symbol_flag == 1) {
nr_pusch_channel_estimation(gNB,
nr_tti_rx,
0, // p
symbol,
ulsch_id,
bwp_start_subcarrier,
rel15_ul);
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size],
rel15_ul->rb_size*12);
if (gNB->pusch_vars[ulsch_id]->ulsch_power[aarx]==1) return (1);
}
}
stop_meas(&gNB->ulsch_channel_estimation_stats);
//----------------------------------------------------------
//--------------------- RBs extraction ---------------------
@@ -1096,6 +1144,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[ulsch_id],
symbol,
dmrs_symbol_flag,
ptrs_symbol_flag,
rel15_ul,
frame_parms);
stop_meas(&gNB->ulsch_rbs_extraction_stats);
@@ -1124,7 +1173,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+1;
gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+3;
gNB->pusch_vars[ulsch_id]->cl_done = 1;
}
@@ -1144,11 +1193,6 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
stop_meas(&gNB->ulsch_channel_compensation_stats);
int rxsig = signal_energy(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][(symbol*rel15_ul->rb_size*12)],
rel15_ul->rb_size*12);
if (rxsig==1) return (rxsig);
#ifdef NR_SC_FDMA
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
@@ -1158,7 +1202,12 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
//----------------------------------------------------------
start_meas(&gNB->ulsch_llr_stats);
AssertFatal(gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB],
#ifdef __AVX2__
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
int off = 0;
#endif
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off+(rel15_ul->rb_size * NR_NB_SC_PER_RB))],
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
&gNB->pusch_vars[ulsch_id]->llr[gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
@@ -34,9 +34,6 @@
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
__m128i xmm0 __attribute__ ((aligned(32)));
__m128i xmm1 __attribute__ ((aligned(32)));
__m128i xmm2 __attribute__ ((aligned(32)));
//----------------------------------------------------------------------------------------------
@@ -47,20 +44,19 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
uint32_t nb_re,
uint8_t symbol)
{
int i;
uint32_t *rxF = (uint32_t*)rxdataF_comp;
uint32_t *llr32 = (uint32_t*)ulsch_llr;
if (!llr32) {
LOG_E(PHY,"nr_ulsch_qpsk_llr: llr is null, symbol %d, llr32 = %p\n",symbol, llr32);
}
/*
for (i = 0; i < nb_re; i++) {
*llr32 = *rxF;
rxF++;
llr32++;
}
}*/
memcpy1((void*)llr32,(void*)rxF,nb_re<<2);
}
//----------------------------------------------------------------------------------------------
@@ -76,9 +72,17 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
{
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
__m256i *rxF = (__m256i*)rxdataF_comp;
__m256i *ch_mag;
__m256i llr256[2];
register __m256i xmm0;
#else
__m128i *rxF = (__m128i*)rxdataF_comp;
__m128i *ch_mag;
__m128i llr128[2];
register __m128i xmm0;
#endif
uint32_t *llr32;
#elif defined(__arm__)
@@ -90,7 +94,12 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int i;
unsigned char len_mod4 = 0;
#ifdef __AVX2__
int off = ((nb_rb&1) == 1)? 4:0;
#else
int off = 0;
#endif
#if defined(__x86_64__) || defined(__i386__)
@@ -100,22 +109,69 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
#endif
#if defined(__x86_64__) || defined(__i386__)
ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
#ifdef __AVX2__
ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))];
#else
ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))];
#endif
#elif defined(__arm__)
ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
#endif
len_mod4 = nb_re&3;
#ifdef __AVX2__
unsigned char len_mod8 = nb_re&7;
nb_re >>= 3; // length in quad words (4 REs)
nb_re += (len_mod8 == 0 ? 0 : 1);
#else
unsigned char len_mod4 = nb_re&3;
nb_re >>= 2; // length in quad words (4 REs)
nb_re += (len_mod4 == 0 ? 0 : 1);
#endif
for (i=0; i<nb_re; i++) {
#if defined(__x86_64__) || defined(__i386)
#ifdef __AVX2__
xmm0 = _mm256_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
xmm0 = _mm256_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
llr256[0] = _mm256_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs
llr256[1] = _mm256_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs
// 1st RE
llr32[0] = _mm256_extract_epi32(llr256[0],0); // llr32[0] low 16 bits-> y_R , high 16 bits-> y_I
llr32[1] = _mm256_extract_epi32(llr256[0],1); // llr32[1] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 2nd RE
llr32[2] = _mm256_extract_epi32(llr256[0],2); // llr32[2] low 16 bits-> y_R , high 16 bits-> y_I
llr32[3] = _mm256_extract_epi32(llr256[0],3); // llr32[3] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 3rd RE
llr32[4] = _mm256_extract_epi32(llr256[1],0); // llr32[4] low 16 bits-> y_R , high 16 bits-> y_I
llr32[5] = _mm256_extract_epi32(llr256[1],1); // llr32[5] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 4th RE
llr32[6] = _mm256_extract_epi32(llr256[1],2); // llr32[6] low 16 bits-> y_R , high 16 bits-> y_I
llr32[7] = _mm256_extract_epi32(llr256[1],3); // llr32[7] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 5th RE
llr32[8] = _mm256_extract_epi32(llr256[0],4); // llr32[8] low 16 bits-> y_R , high 16 bits-> y_I
llr32[9] = _mm256_extract_epi32(llr256[0],5); // llr32[9] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 6th RE
llr32[10] = _mm256_extract_epi32(llr256[0],6); // llr32[10] low 16 bits-> y_R , high 16 bits-> y_I
llr32[11] = _mm256_extract_epi32(llr256[0],7); // llr32[11] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 7th RE
llr32[12] = _mm256_extract_epi32(llr256[1],4); // llr32[12] low 16 bits-> y_R , high 16 bits-> y_I
llr32[13] = _mm256_extract_epi32(llr256[1],5); // llr32[13] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
// 8th RE
llr32[14] = _mm256_extract_epi32(llr256[1],6); // llr32[14] low 16 bits-> y_R , high 16 bits-> y_I
llr32[15] = _mm256_extract_epi32(llr256[1],7); // llr32[15] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
llr32+=16;
#else
xmm0 = _mm_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs
@@ -138,6 +194,7 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
llr32[7] = _mm_extract_epi32(llr128[1],3); // llr32[7] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
llr32+=8;
#endif
#elif defined(__arm__)
xmm0 = vabsq_s16(rxF[i]);
xmm0 = vqsubq_s16((*(__m128i*)&ones[0]),xmm0);
@@ -182,40 +239,69 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
uint8_t symbol)
{
#ifdef __AVX2__
int off = ((nb_rb&1) == 1)? 4:0;
#else
int off = 0;
#endif
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
__m256i *rxF = (__m256i*)rxdataF_comp;
__m256i *ch_mag,*ch_magb;
register __m256i xmm0,xmm1,xmm2;
#else
__m128i *rxF = (__m128i*)rxdataF_comp;
__m128i *ch_mag,*ch_magb;
register __m128i xmm0,xmm1,xmm2;
#endif
#elif defined(__arm__)
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
int16x8_t xmm1,xmm2;
int16x8_t xmm0,xmm1,xmm2;
#endif
int i;
unsigned char len_mod4;
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
ch_mag = (__m256i*)&ul_ch_mag[0][(symbol*(off+(nb_rb*12)))];
ch_magb = (__m256i*)&ul_ch_magb[0][(symbol*(off+(nb_rb*12)))];
#else
ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)];
#endif
#elif defined(__arm__)
ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)];
#endif
len_mod4 = nb_re&3;
#ifdef __AVX2__
int len_mod8 = nb_re&7;
nb_re = nb_re>>3; // length in quad words (4 REs)
nb_re += ((len_mod8 == 0) ? 0 : 1);
#else
int len_mod4 = nb_re&3;
nb_re = nb_re>>2; // length in quad words (4 REs)
nb_re += ((len_mod4 == 0) ? 0 : 1);
#endif
for (i=0; i<nb_re; i++) {
xmm0 = rxF[i];
#if defined(__x86_64__) || defined(__i386__)
xmm1 = _mm_abs_epi16(rxF[i]);
#ifdef __AVX2__
xmm1 = _mm256_abs_epi16(xmm0);
xmm1 = _mm256_subs_epi16(ch_mag[i],xmm1);
xmm2 = _mm256_abs_epi16(xmm1);
xmm2 = _mm256_subs_epi16(ch_magb[i],xmm2);
#else
xmm1 = _mm_abs_epi16(xmm0);
xmm1 = _mm_subs_epi16(ch_mag[i],xmm1);
xmm2 = _mm_abs_epi16(xmm1);
xmm2 = _mm_subs_epi16(ch_magb[i],xmm2);
#endif
#elif defined(__arm__)
xmm1 = vabsq_s16(rxF[i]);
xmm1 = vabsq_s16(xmm0);
xmm1 = vsubq_s16(ch_mag[i],xmm1);
xmm2 = vabsq_s16(xmm1);
xmm2 = vsubq_s16(ch_magb[i],xmm2);
@@ -224,14 +310,25 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
// ---------------------------------------
// 1st RE
// ---------------------------------------
ulsch_llr[0] = ((short *)&rxF[i])[0];
ulsch_llr[1] = ((short *)&rxF[i])[1];
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
ulsch_llr[0] = _mm256_extract_epi16(xmm0,0);
ulsch_llr[1] = _mm256_extract_epi16(xmm0,1);
ulsch_llr[2] = _mm256_extract_epi16(xmm1,0);
ulsch_llr[3] = _mm256_extract_epi16(xmm1,1);
ulsch_llr[4] = _mm256_extract_epi16(xmm2,0);
ulsch_llr[5] = _mm256_extract_epi16(xmm2,1);
#else
ulsch_llr[0] = _mm_extract_epi16(xmm0,0);
ulsch_llr[1] = _mm_extract_epi16(xmm0,1);
ulsch_llr[2] = _mm_extract_epi16(xmm1,0);
ulsch_llr[3] = _mm_extract_epi16(xmm1,1);
ulsch_llr[4] = _mm_extract_epi16(xmm2,0);
ulsch_llr[5] = _mm_extract_epi16(xmm2,1);
#endif
#elif defined(__arm__)
ulsch_llr[0] = vgetq_lane_s16(xmm0,0);
ulsch_llr[1] = vgetq_lane_s16(xmm0,1);
ulsch_llr[2] = vgetq_lane_s16(xmm1,0);
ulsch_llr[3] = vgetq_lane_s16(xmm1,1);
ulsch_llr[4] = vgetq_lane_s16(xmm2,0);
@@ -244,14 +341,25 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
// ---------------------------------------
// 2nd RE
// ---------------------------------------
ulsch_llr[0] = ((short *)&rxF[i])[2];
ulsch_llr[1] = ((short *)&rxF[i])[3];
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
ulsch_llr[0] = _mm256_extract_epi16(xmm0,2);
ulsch_llr[1] = _mm256_extract_epi16(xmm0,3);
ulsch_llr[2] = _mm256_extract_epi16(xmm1,2);
ulsch_llr[3] = _mm256_extract_epi16(xmm1,3);
ulsch_llr[4] = _mm256_extract_epi16(xmm2,2);
ulsch_llr[5] = _mm256_extract_epi16(xmm2,3);
#else
ulsch_llr[0] = _mm_extract_epi16(xmm0,2);
ulsch_llr[1] = _mm_extract_epi16(xmm0,3);
ulsch_llr[2] = _mm_extract_epi16(xmm1,2);
ulsch_llr[3] = _mm_extract_epi16(xmm1,3);
ulsch_llr[4] = _mm_extract_epi16(xmm2,2);
ulsch_llr[5] = _mm_extract_epi16(xmm2,3);
#endif
#elif defined(__arm__)
ulsch_llr[2] = vgetq_lane_s16(xmm0,2);
ulsch_llr[3] = vgetq_lane_s16(xmm0,3);
ulsch_llr[2] = vgetq_lane_s16(xmm1,2);
ulsch_llr[3] = vgetq_lane_s16(xmm1,3);
ulsch_llr[4] = vgetq_lane_s16(xmm2,2);
@@ -264,14 +372,25 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
// ---------------------------------------
// 3rd RE
// ---------------------------------------
ulsch_llr[0] = ((short *)&rxF[i])[4];
ulsch_llr[1] = ((short *)&rxF[i])[5];
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
ulsch_llr[0] = _mm256_extract_epi16(xmm0,4);
ulsch_llr[1] = _mm256_extract_epi16(xmm0,5);
ulsch_llr[2] = _mm256_extract_epi16(xmm1,4);
ulsch_llr[3] = _mm256_extract_epi16(xmm1,5);
ulsch_llr[4] = _mm256_extract_epi16(xmm2,4);
ulsch_llr[5] = _mm256_extract_epi16(xmm2,5);
#else
ulsch_llr[0] = _mm_extract_epi16(xmm0,4);
ulsch_llr[1] = _mm_extract_epi16(xmm0,5);
ulsch_llr[2] = _mm_extract_epi16(xmm1,4);
ulsch_llr[3] = _mm_extract_epi16(xmm1,5);
ulsch_llr[4] = _mm_extract_epi16(xmm2,4);
ulsch_llr[5] = _mm_extract_epi16(xmm2,5);
#endif
#elif defined(__arm__)
ulsch_llr[0] = vgetq_lane_s16(xmm0,4);
ulsch_llr[1] = vgetq_lane_s16(xmm0,5);
ulsch_llr[2] = vgetq_lane_s16(xmm1,4);
ulsch_llr[3] = vgetq_lane_s16(xmm1,5);
ulsch_llr[4] = vgetq_lane_s16(xmm2,4);
@@ -284,14 +403,25 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
// ---------------------------------------
// 4th RE
// ---------------------------------------
ulsch_llr[0] = ((short *)&rxF[i])[6];
ulsch_llr[1] = ((short *)&rxF[i])[7];
#if defined(__x86_64__) || defined(__i386__)
#ifdef __AVX2__
ulsch_llr[0] = _mm256_extract_epi16(xmm0,6);
ulsch_llr[1] = _mm256_extract_epi16(xmm0,7);
ulsch_llr[2] = _mm256_extract_epi16(xmm1,6);
ulsch_llr[3] = _mm256_extract_epi16(xmm1,7);
ulsch_llr[4] = _mm256_extract_epi16(xmm2,6);
ulsch_llr[5] = _mm256_extract_epi16(xmm2,7);
#else
ulsch_llr[0] = _mm_extract_epi16(xmm0,6);
ulsch_llr[1] = _mm_extract_epi16(xmm0,7);
ulsch_llr[2] = _mm_extract_epi16(xmm1,6);
ulsch_llr[3] = _mm_extract_epi16(xmm1,7);
ulsch_llr[4] = _mm_extract_epi16(xmm2,6);
ulsch_llr[5] = _mm_extract_epi16(xmm2,7);
#endif
#elif defined(__arm__)
ulsch_llr[0] = vgetq_lane_s16(xmm0,6);
ulsch_llr[1] = vgetq_lane_s16(xmm0,7);
ulsch_llr[2] = vgetq_lane_s16(xmm1,6);
ulsch_llr[3] = vgetq_lane_s16(xmm1,7);
ulsch_llr[4] = vgetq_lane_s16(xmm2,6);
@@ -300,6 +430,37 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
// ---------------------------------------
ulsch_llr+=6;
#ifdef __AVX2__
ulsch_llr[0] = _mm256_extract_epi16(xmm0,8);
ulsch_llr[1] = _mm256_extract_epi16(xmm0,9);
ulsch_llr[2] = _mm256_extract_epi16(xmm1,8);
ulsch_llr[3] = _mm256_extract_epi16(xmm1,9);
ulsch_llr[4] = _mm256_extract_epi16(xmm2,8);
ulsch_llr[5] = _mm256_extract_epi16(xmm2,9);
ulsch_llr[6] = _mm256_extract_epi16(xmm0,10);
ulsch_llr[7] = _mm256_extract_epi16(xmm0,11);
ulsch_llr[8] = _mm256_extract_epi16(xmm1,10);
ulsch_llr[9] = _mm256_extract_epi16(xmm1,11);
ulsch_llr[10] = _mm256_extract_epi16(xmm2,10);
ulsch_llr[11] = _mm256_extract_epi16(xmm2,11);
ulsch_llr[12] = _mm256_extract_epi16(xmm0,12);
ulsch_llr[13] = _mm256_extract_epi16(xmm0,13);
ulsch_llr[14] = _mm256_extract_epi16(xmm1,12);
ulsch_llr[15] = _mm256_extract_epi16(xmm1,13);
ulsch_llr[16] = _mm256_extract_epi16(xmm2,12);
ulsch_llr[17] = _mm256_extract_epi16(xmm2,13);
ulsch_llr[18] = _mm256_extract_epi16(xmm0,14);
ulsch_llr[19] = _mm256_extract_epi16(xmm0,15);
ulsch_llr[20] = _mm256_extract_epi16(xmm1,14);
ulsch_llr[21] = _mm256_extract_epi16(xmm1,15);
ulsch_llr[22] = _mm256_extract_epi16(xmm2,14);
ulsch_llr[23] = _mm256_extract_epi16(xmm2,15);
ulsch_llr+=24;
#endif
}
#if defined(__x86_64__) || defined(__i386__)
+33 -16
View File
@@ -315,7 +315,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int16_t xr[24] __attribute__((aligned(32)));
//int16_t xrt[24] __attribute__((aligned(32)));
int32_t xrtmag=0;
int maxpos=0;
uint8_t maxpos=0;
int n2=0;
uint8_t index=0;
memset((void*)xr,0,24*sizeof(int16_t));
@@ -339,7 +339,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
#endif
}
}
int32_t corr_re,corr_im,temp;
int32_t corr_re,corr_im,temp,no_corr=0;
int seq_index;
for(i=0;i<nr_sequences;i++){
@@ -359,63 +359,77 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im));
#endif
if ((temp=corr_re*corr_re + corr_im*corr_im)>xrtmag) {
temp=corr_re*corr_re + corr_im*corr_im;
no_corr+=temp;
if (temp>xrtmag) {
xrtmag=temp;
maxpos=i;
}
}
no_corr-=xrtmag;
if (nr_sequences>1)
no_corr/=(nr_sequences-1);
uint8_t xrtmag_dB = dB_fixed(xrtmag);
//#ifdef DEBUG_NR_PUCCH_RX
#ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH 0 : maxpos %d\n",maxpos);
//#endif
#endif
index=maxpos;
#endif
// estimate CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(signal_energy(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12)) - (10*gNB->measurements.n0_power_tot_dB);
int cqi;
if (SNRtimes10 < -640) cqi=0;
else if (SNRtimes10 > 635) cqi=255;
else cqi=(640+SNRtimes10)/5;
// first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1);
uci_pdu->pucch_format = 0; // format 0
uci_pdu->ul_cqi = 0xff; // currently not valid
uci_pdu->ul_cqi = cqi; // currently not valid
uci_pdu->timing_advance = 0xffff; // currently not valid
uci_pdu->rssi = 0xffff; // currently not valid
if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
if (xrtmag_dB>(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)) {
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+gNB->measurements.n0_power_tot_dB)) ? 1 : 0;
if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) {
uci_pdu->sr->sr_indication = 1;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
} else {
uci_pdu->sr->sr_indication = 0;
uci_pdu->sr->sr_confidence_level = (gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres)-xrtmag_dB;
}
}
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 1;
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
}
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
uci_pdu->harq->harq_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
LOG_I(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = xrtmag_dB-(gNB->measurements.n0_subband_power_tot_dB[pucch_pdu->prb_start]+gNB->pucch0_thres);
uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0;
}
}
}
@@ -1047,6 +1061,8 @@ void init_pucch2_luts() {
bit = (i&0x80) > 0 ? 0 : 1;
*lut_num_i = _mm_insert_epi16(*lut_num_i,bit,7);
*lut_den_i = _mm_insert_epi16(*lut_den_i,1-bit,7);
#ifdef DEBUG_NR_PUCCH_RX
printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
((int16_t *)lut_num_i)[0],
((int16_t *)lut_num_i)[1],
@@ -1056,6 +1072,7 @@ void init_pucch2_luts() {
((int16_t *)lut_num_i)[5],
((int16_t *)lut_num_i)[6],
((int16_t *)lut_num_i)[7]);
#endif
}
}
@@ -68,7 +68,7 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
if (dlsch) {
if (N_RB_DL != 273) {
a_segments = a_segments*N_RB_DL;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
@@ -266,8 +266,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
double Coderate;// = 0.0;
uint8_t dmrs_Type = harq_process->dmrsConfigType;
AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type);
uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; // should be changed based on MAC parameters
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
uint8_t nb_re_dmrs;
if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
}
else {
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
}
uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
@@ -277,7 +283,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
__m128i *pl = (__m128i*)&l;
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
//NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];
if (!dlsch_llr) {
@@ -409,7 +415,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if (nb_rb != 273) {
a_segments = a_segments*nb_rb;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
if (harq_process->C > a_segments) {
@@ -657,7 +663,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
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++; // [hna] uncomment this line when HARQ is implemented
harq_process->round++; // [hna] uncomment this line when HARQ is implemented
// printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
if (harq_process->round >= dlsch->Mlimit) {
@@ -805,7 +811,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4;
uint8_t nb_re_dmrs;
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
else
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos);
uint32_t i,j;
@@ -947,7 +958,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
if (nb_rb != 273) {
a_segments = a_segments*nb_rb;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
if (harq_process->C > a_segments) {
@@ -1525,7 +1536,7 @@ void nr_dlsch_decoding_process(void *arg)
if (nb_rb != 273) {
a_segments = a_segments*nb_rb;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
if (harq_process->C > a_segments) {
@@ -134,7 +134,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int avgs = 0;// rb;
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
uint8_t beamforming_mode;
uint8_t beamforming_mode = 0;
int32_t **rxdataF_comp_ptr;
int32_t **dl_ch_mag_ptr;
@@ -162,24 +162,34 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
pdsch_vars = ue->pdsch_vars_SI;
dlsch = &ue->dlsch_SI[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
break;
case RA_PDSCH:
pdsch_vars = ue->pdsch_vars_ra;
dlsch = &ue->dlsch_ra[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
beamforming_mode = 0;
// WIP TBR Hotfix
memcpy((void*)&pdsch_vars[eNB_id]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], (void*)&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], ue->frame_parms.ofdm_symbol_size*sizeof(int32_t));
break;
case PDSCH:
pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]];
dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id];
break;
default:
LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
return -1;
break;
}
if (dlsch1_harq){
//printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
@@ -191,27 +201,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming both TBs are active\n");
printf("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1);
#endif
} else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) {
codeword_TB0 = dlsch0_harq->codeword;
codeword_TB1 = -1;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
dlsch1_harq = NULL;
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB0 is active\n");
printf("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0);
#endif
} else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){
codeword_TB0 = -1;
codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = NULL;
dlsch1_harq = dlsch[1]->harq_processes[codeword_TB1];
dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword);
printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1);
#endif
LOG_E(PHY, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n");
@@ -221,14 +229,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return(-1);
}
} else if (dlsch0_harq) {
if (dlsch0_harq->status == ACTIVE)
codeword_TB0 = dlsch0_harq->codeword;
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
break;
default:
LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type);
return(-1);
break;
#ifdef DEBUG_HARQ
printf("[DEMOD] I am assuming only TB0 is active\n");
#endif
} else {
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx);
return (-1);
}
if (dlsch0_harq == NULL) {
@@ -336,9 +347,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch0_harq->pmi_alloc,
pdsch_vars[eNB_id_i]->pmi_ext,
symbol,
pilots,
start_rb,
nb_rb_pdsch,
pilots,
start_rb,
nb_rb_pdsch,
nr_tti_rx,
ue->high_speed_flag,
frame_parms,
@@ -351,9 +362,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch0_harq->pmi_alloc,
pdsch_vars[eNB_id_i]->pmi_ext,
symbol,
pilots,
start_rb,
nb_rb_pdsch,
pilots,
start_rb,
nb_rb_pdsch,
nr_tti_rx,
ue->high_speed_flag,
frame_parms,
@@ -513,7 +524,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
(aatx>1) ? pdsch_vars[eNB_id]->rho : NULL,
frame_parms,
symbol,
pilots,
pilots,
first_symbol_flag,
dlsch0_harq->Qm,
nb_rb,
@@ -1144,7 +1155,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
int **rho,
NR_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
uint8_t pilots,
uint8_t pilots,
uint8_t first_symbol_flag,
unsigned char mod_order,
unsigned short nb_rb,
@@ -2380,7 +2391,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
k = frame_parms->first_carrier_offset + 12*start_rb;
k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
if (high_speed_flag == 1)
dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))];
+13 -20
View File
@@ -44,18 +44,8 @@
//#define NR_PRACH_DEBUG 1
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
extern uint16_t NCS_unrestricted_delta_f_RA_5[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14];
extern uint16_t NCS_unrestricted_delta_f_RA_15[16];
extern uint16_t prach_root_sequence_map_0_3[838];
extern uint16_t prach_root_sequence_map_abc[138];
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
extern const char *prachfmt[9];
@@ -118,7 +108,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
else
samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
#if defined (OAI_USRP)
#ifdef OAI_USRP
prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
#else //normal case (simulation)
prach_start = slot*samp_count - ue->N_TA_offset;
@@ -208,14 +198,17 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
// now generate PRACH signal
#ifdef NR_PRACH_DEBUG
if (NCS>0)
LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id,
rootSequenceIndex,
preamble_index,
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n",
Mod_id,
slot,
rootSequenceIndex,
preamble_index,
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
NCS,
N_ZC,
preamble_offset,
preamble_shift);
preamble_shift,
n_ra_prb);
#endif
// nsymb = (frame_parms->Ncp==0) ? 14:12;
@@ -383,8 +376,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
} else {
//LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol);
switch (prach_fmt_id) {
case 0: //A1
Ncp = 288/(1<<mu);
@@ -419,7 +410,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
}
}
LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen);
#ifdef NR_PRACH_DEBUG
LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen);
#endif
if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL);
@@ -844,7 +837,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
//}
//printf(" \n");
#if defined(PRACH_WRITE_OUTPUT_DEBUG)
#ifdef PRACH_WRITE_OUTPUT_DEBUG
LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
#endif
@@ -1074,11 +1074,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
*/
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
uint8_t harq_pid,
uint8_t slot,
uint8_t thread_id,
uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_parms);
NR_DL_FRAME_PARMS *frame_parms,
uint8_t Nl);
@@ -292,6 +292,8 @@ typedef struct {
uint16_t dlDmrsSymbPos;
/// DMRS Configuration Type
uint8_t dmrsConfigType;
// Number of DMRS CDM groups with no data
uint8_t n_dmrs_cdm_groups;
/// Starting Symbol number
uint16_t start_symbol;
/// Current subband PMI allocation
@@ -57,7 +57,7 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
@@ -114,7 +114,7 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
if (N_RB_UL != 273) {
a_segments = a_segments*N_RB_UL;
a_segments = a_segments/273;
a_segments = a_segments/273 +1;
}
uint16_t ulsch_bytes = a_segments*1056; // allocated bytes per segment
@@ -225,8 +225,9 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
unsigned int crc;
NR_UL_UE_HARQ_t *harq_process;
uint16_t nb_rb ;
uint32_t A, Z, F;
uint32_t *pz;
uint32_t A, F;
static uint32_t Z = 0;
uint32_t *pz = &Z;
uint8_t mod_order;
uint16_t Kr,r;
uint32_t r_offset;
@@ -258,6 +259,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Ilbrm = 0;
Tbslbrm = 950984; //max tbs
Coderate = 0.0;
harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index];
///////////
/////////////////////////////////////////////////////////////////////////////////////////
@@ -409,6 +411,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
///////////////////////////////////////////////////////////////////////////////
}
F = harq_process->F;
Kr = harq_process->K;
for (r=0; r<harq_process->C; r++) { // looping over C segments
+3 -57
View File
@@ -100,7 +100,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
uint32_t available_bits, TBS;
uint32_t available_bits;
uint8_t mod_order, cwd_index, num_of_codewords, l;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
uint32_t ***pusch_dmrs;
@@ -113,7 +113,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
int ap, start_symbol, Nid_cell, i;
int sample_offsetF, N_RE_prime, N_PRB_oh;
uint16_t ul_dmrs_symb_pos;
uint8_t data_existing =0;
uint8_t L_ptrs, K_ptrs; // PTRS parameters
uint16_t beta_ptrs; // PTRS parameter related to power control
@@ -121,7 +120,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
// ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
num_of_codewords = 1; // tmp assumption
@@ -171,54 +169,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
0,
harq_process_ul_ue->pusch_pdu.nrOfLayers);
uint8_t access_mode = SCHEDULED_ACCESS;
//-----------------------------------------------------//
// to be removed later when MAC is ready
if (harq_process_ul_ue != NULL){
TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size;
data_existing = 0;
if (IS_SOFTMODEM_NOS1){
data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame,
slot, 0, ulsch_input_buffer, TBS/8, &access_mode);
//IP traffic to be transmitted
if(data_existing){
//harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8);
}
}
//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
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "Random data to be tranmsitted: \n");
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
harq_process_ul_ue->a[0] = 0x31;
for (i = 1; i < TBS / 8; i++) {
harq_process_ul_ue->a[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
}
#ifdef DEBUG_MAC_PDU
LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8);
for (i = 0; i < TBS / 8; i++) {
printf("%02x",harq_process_ul_ue->a[i]);
}
printf("\n");
#endif
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return;
}
//-----------------------------------------------------//
/////////////////////////ULSCH coding/////////////////////////
///////////
@@ -471,22 +421,18 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
////////////////////////////////////////////////////////////////////////
LOG_D(PHY, "Is data existing ?: %d \n", data_existing);
}
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
uint8_t harq_pid,
uint8_t slot,
uint8_t thread_id,
uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_parms) {
NR_DL_FRAME_PARMS *frame_parms,
uint8_t Nl) {
int tx_offset, ap;
int32_t **txdata;
int32_t **txdataF;
int timing_advance;
uint8_t Nl = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers; // cw 0
/////////////////////////IFFT///////////////////////
///////////
+5 -5
View File
@@ -113,7 +113,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
// if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!!
// if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1;
nr_group_sequence_hopping(pucch_GroupHopping,hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
alpha = nr_cyclic_shift_hopping(hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l);
#endif
@@ -963,7 +963,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
uint64_t b[16]; // limit to 1024-bit encoded length
// M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit;
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,(void*)b,&M_bit);
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b[0],&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
@@ -985,7 +985,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
/*
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
*/
nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,b,btilde);
nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,&b[0],btilde);
/*
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
* btilde shall be modulated as described in subclause 5.1 using QPSK
@@ -1154,7 +1154,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
//nrofPRB = 2; // only for test purposes
if (fmt == pucch_format4_nr) nrofPRB = 1;
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,(void*)b,&M_bit);
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b[0],&M_bit);
/*
* Implementing TS 38.211
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
@@ -1176,7 +1176,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
/*
* Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4
*/
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,&b[0],btilde);
/*
* Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4
*
+2 -1
View File
@@ -401,7 +401,8 @@ static void *scope_thread_gNB(void *arg) {
// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
//#endif
size_t stksize=0;
pthread_attr_t atr= {0};
pthread_attr_t atr;
pthread_attr_init(&atr);
pthread_attr_getstacksize(&atr, &stksize);
pthread_attr_setstacksize(&atr,32*1024*1024 );
sleep(3); // no clean interthread barriers
-1
View File
@@ -1094,5 +1094,4 @@ static inline int release_thread(pthread_mutex_t *mutex,
return(0);
}
#endif // __PHY_DEFS_COMMON_H__
+23 -3
View File
@@ -112,6 +112,17 @@ typedef struct {
uint32_t F;
} NR_DL_gNB_HARQ_t;
typedef struct {
int frame;
int slot;
nfapi_nr_dl_tti_pdcch_pdu pdcch_pdu;
} NR_gNB_PDCCH_t;
typedef struct {
int frame;
int slot;
nfapi_nr_ul_dci_request_pdus_t pdcch_pdu;
} NR_gNB_UL_PDCCH_t;
typedef struct {
/// Pointers to 16 HARQ processes for the DLSCH
@@ -365,6 +376,8 @@ typedef struct {
/// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
/// - third index: sample [0..]
int32_t **txdataF;
int32_t *debugBuff;
int32_t debugBuff_sample_offset;
} NR_gNB_COMMON;
@@ -674,17 +687,19 @@ typedef struct PHY_VARS_gNB_s {
nfapi_nr_ul_tti_request_t UL_tti_req;
nfapi_nr_uci_indication_t uci_indication;
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
int num_pdsch_rnti;
uint16_t num_pdsch_rnti[80];
NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars;
NR_gNB_PUSCH *pusch_vars[NUMBER_OF_NR_ULSCH_MAX];
NR_gNB_PUCCH_t *pucch[NUMBER_OF_NR_PUCCH_MAX];
NR_gNB_PDCCH_t pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
NR_gNB_UL_PDCCH_t ul_pdcch_pdu[NUMBER_OF_NR_PDCCH_MAX];
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords]
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
@@ -715,6 +730,10 @@ typedef struct PHY_VARS_gNB_s {
/// PUSCH DMRS
uint32_t ****nr_gold_pusch_dmrs;
// Mask of occupied RBs
uint32_t rb_mask_ul[9];
int ulmask_symb;
/// Indicator set to 0 after first SR
uint8_t first_sr[NUMBER_OF_NR_SR_MAX];
@@ -769,6 +788,7 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_interleaving_stats;
time_stats_t dlsch_segmentation_stats;
time_stats_t rx_pusch_stats;
time_stats_t ulsch_decoding_stats;
time_stats_t ulsch_rate_unmatching_stats;
time_stats_t ulsch_ldpc_decoding_stats;
+3
View File
@@ -111,6 +111,9 @@
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB
#define MAX_NUM_NR_RE (14*273*12)
extern const uint8_t nr_rv_round_map[4];
extern const uint8_t nr_rv_round_map_ue[4];
typedef enum {
NR_MU_0=0,
NR_MU_1,
+6 -7
View File
@@ -94,9 +94,9 @@ void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
LOG_D(PHY,"Frame %d, Slot %d: DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, pdcch_pdu->pdcch_pdu_rel15.numDlDci);
// copy dci configuration into gNB structure
gNB->pdcch_pdu = pdcch_pdu;
// gNB->pdcch_pdu = pdcch_pdu;
nr_fill_dci(gNB,frame,slot);
nr_fill_dci(gNB,frame,slot,pdcch_pdu);
@@ -109,9 +109,9 @@ void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
LOG_D(PHY,"Frame %d, Slot %d: UL DCI processing - proc:slot_tx:%d pdcch_pdu_rel15->numDlDci:%d\n",frame,slot, slot, ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci);
// copy dci configuration into gNB structure
gNB->ul_dci_pdu = ul_dci_request_pdu;
// gNB->ul_dci_pdu = ul_dci_request_pdu;
nr_fill_ul_dci(gNB,frame,slot);
nr_fill_ul_dci(gNB,frame,slot,ul_dci_request_pdu);
}
@@ -154,13 +154,12 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
number_ul_dci_pdu,number_ul_tti_pdu);
int pdcch_received=0;
gNB->num_pdsch_rnti=0;
gNB->num_pdsch_rnti[slot]=0;
for (int i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
gNB->dlsch[i][0]->rnti=0;
gNB->dlsch[i][0]->harq_mask=0;
}
gNB->pdcch_pdu = NULL;
gNB->ul_dci_pdu = NULL;
gNB->pbch_configured=0;
for (int i=0;i<number_dl_pdu;i++) {
+2 -71
View File
@@ -29,11 +29,9 @@
*
************************************************************************/
#include "SCHED_NR_UE/defs.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/impl_defs_top.h"
#include "SCHED_NR/phy_frame_config_nr.h"
/*******************************************************************
*
@@ -369,73 +367,6 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti)
}
}
/*******************************************************************
*
* NAME : nr_ue_slot_select
*
* DESCRIPTION : function for the UE equivalent to nr_slot_select
*
*********************************************************************/
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
/* for FFD all slot can be considered as an uplink */
int mu = cfg->ssb_config.scs_common, check_slot = 0;
if (cfg->cell_config.frame_duplex_type == FDD) {
return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
}
if (nr_frame%2 == 0) {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
} else {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
}
}
/*******************************************************************
*
* NAME : free_tdd_configuration_nr
+2 -4
View File
@@ -32,7 +32,6 @@
#ifndef PHY_FRAME_CONFIG_NR_H
#define PHY_FRAME_CONFIG_NR_H
#include <nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h>
/************** DEFINE ********************************************/
#define TDD_CONFIG_NB_FRAMES (2)
@@ -77,10 +76,9 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
* @param frame_parms NR DL Frame parameters
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns nr_slot_t : downlink or uplink */
@returns int : downlink, uplink or mixed slot type*/
nr_slot_t nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti);
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti);
int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
+144 -40
View File
@@ -26,6 +26,7 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "SCHED/sched_eNB.h"
@@ -160,41 +161,53 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
int pdcch_pdu_id=find_nr_pdcch(frame,slot,gNB,SEARCH_EXIST);
int ul_pdcch_pdu_id=find_nr_ul_dci(frame,slot,gNB,SEARCH_EXIST);
if (gNB->pdcch_pdu || gNB->ul_dci_pdu) {
LOG_D(PHY,"[gNB %d] Frame %d slot %d, pdcch_pdu_id %d, ul_pdcch_pdu_id %d\n",
gNB->Mod_id,frame,slot,pdcch_pdu_id,ul_pdcch_pdu_id);
if (pdcch_pdu_id >= 0 || ul_pdcch_pdu_id >= 0) {
LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n",
gNB->Mod_id, frame, slot,
gNB->ul_dci_pdu==NULL?0:gNB->ul_dci_pdu->pdcch_pdu.pdcch_pdu_rel15.numDlDci,
gNB->pdcch_pdu==NULL?0:gNB->pdcch_pdu->pdcch_pdu_rel15.numDlDci);
gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci,
gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
nr_generate_dci_top(gNB->pdcch_pdu,
gNB->ul_dci_pdu,
nr_generate_dci_top(gNB,
pdcch_pdu_id>=0 ? &gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu : NULL,
ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL,
gNB->nr_gold_pdcch_dmrs[slot],
&gNB->common_vars.txdataF[0][txdataF_offset],
AMP, *fp);
// free up entry in pdcch tables
if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
if (ul_pdcch_pdu_id>=0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
if (pdcch_pdu_id >= 0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1;
if (ul_pdcch_pdu_id >= 0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1;
}
for (int i=0; i<gNB->num_pdsch_rnti; i++) {
for (int i=0; i<gNB->num_pdsch_rnti[slot]; i++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti);
LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot);
nr_generate_pdsch(gNB->dlsch[i][0],
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
AMP, frame, slot, fp, 0,
&gNB->dlsch_encoding_stats,
&gNB->dlsch_scrambling_stats,
&gNB->dlsch_modulation_stats,
&gNB->tinput,
&gNB->tprep,
&gNB->tparity,
&gNB->toutput,
&gNB->dlsch_rate_matching_stats,
&gNB->dlsch_interleaving_stats,
&gNB->dlsch_segmentation_stats);
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
AMP, frame, slot, fp, 0,
&gNB->dlsch_encoding_stats,
&gNB->dlsch_scrambling_stats,
&gNB->dlsch_modulation_stats,
&gNB->tinput,
&gNB->tprep,
&gNB->tparity,
&gNB->toutput,
&gNB->dlsch_rate_matching_stats,
&gNB->dlsch_interleaving_stats,
&gNB->dlsch_segmentation_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
@@ -244,11 +257,11 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
start_meas(&gNB->ulsch_unscrambling_stats);
nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
G,
0,
pusch_pdu->data_scrambling_id,
pusch_pdu->rnti);
nr_ulsch_unscrambling_optim(gNB->pusch_vars[ULSCH_id]->llr,
G,
0,
pusch_pdu->data_scrambling_id,
pusch_pdu->rnti);
stop_meas(&gNB->ulsch_unscrambling_stats);
//----------------------------------------------------------
//--------------------- ULSCH decoding ---------------------
@@ -310,10 +323,12 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
if (timing_advance_update < 0) timing_advance_update = 0;
if (timing_advance_update > 63) timing_advance_update = 63;
LOG_D(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
LOG_I(PHY, "Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", sync_pos,timing_advance_update);
// estimate UL_CQI for MAC (from antenna port 0 only)
int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]);
int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0]) - (10*gNB->measurements.n0_power_dB[0]);
LOG_I(PHY, "Estimated SNR for PUSCH is = %d dB\n", SNRtimes10/10);
if (SNRtimes10 < -640) cqi=0;
else if (SNRtimes10 > 635) cqi=255;
@@ -359,6 +374,71 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
pthread_mutex_unlock(&gNB->UL_INFO_mutex);
}
// Function to fill UL RB mask to be used for N0 measurements
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
int rb2, rb, nb_rb;
for (int symbol=0;symbol<14;symbol++) {
if (gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol].slot_config.value==1){
nb_rb = 0;
for (int m=0;m<9;m++) gNB->rb_mask_ul[m] = 0;
gNB->ulmask_symb = -1;
for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
if (pucch) {
if ((pucch->active == 1) &&
(pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) {
gNB->ulmask_symb = symbol;
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
if ((symbol>=pucch_pdu->start_symbol_index) &&
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
for (rb=0; rb<pucch_pdu->prb_size; rb++) {
rb2 = rb+pucch_pdu->prb_start;
gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
}
nb_rb+=pucch_pdu->prb_size;
}
}
}
}
for (int ULSCH_id=0;ULSCH_id<NUMBER_OF_NR_ULSCH_MAX;ULSCH_id++) {
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
int harq_pid;
NR_UL_gNB_HARQ_t *ulsch_harq;
if ((ulsch) &&
(ulsch->rnti > 0)) {
for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) {
ulsch_harq = ulsch->harq_processes[harq_pid];
AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
if ((ulsch_harq->status == NR_ACTIVE) &&
(ulsch_harq->frame == frame_rx) &&
(ulsch_harq->slot == slot_rx) &&
(ulsch_harq->handled == 0)){
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
gNB->ulmask_symb = symbol;
if ((symbol>=symbol_start) &&
(symbol<symbol_end)){
for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) {
rb2 = rb+ulsch_harq->ulsch_pdu.rb_start;
gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
}
nb_rb+=ulsch_harq->ulsch_pdu.rb_size;
}
}
}
}
//TODO Add check for PRACH as well?
}
if (nb_rb<gNB->frame_parms.N_RB_UL)
return;
}
}
}
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
uint8_t symbol;
@@ -385,6 +465,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
fill_ul_rb_mask(gNB, frame_rx, slot_rx);
gNB_I0_measurements(gNB);
for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
if (pucch) {
@@ -424,44 +507,65 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
for (int ULSCH_id=0;ULSCH_id<NUMBER_OF_NR_ULSCH_MAX;ULSCH_id++) {
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
int harq_pid;
//int no_sig;
int no_sig;
NR_UL_gNB_HARQ_t *ulsch_harq;
if ((ulsch) &&
(ulsch->rnti > 0)) {
// for for an active HARQ process
for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) {
ulsch_harq = ulsch->harq_processes[harq_pid];
ulsch_harq = ulsch->harq_processes[harq_pid];
AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
if ((ulsch_harq->status == NR_ACTIVE) &&
(ulsch_harq->frame == frame_rx) &&
(ulsch_harq->slot == slot_rx) &&
(ulsch_harq->handled == 0)){
LOG_I(PHY, "PUSCH generation started in frame %d slot %d\n",
frame_rx,slot_rx);
#ifdef DEBUG_RXDATA
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
RU_t *ru = gNB->RU_list[0];
int slot_offset = frame_parms->get_samples_slot_timestamp(slot_rx,frame_parms,0);
slot_offset -= ru->N_TA_offset;
char name[128];
FILE *f;
sprintf(name, "rxdata.%d.%d.raw", frame_rx,slot_rx);
f = fopen(name, "w"); if (f == NULL) exit(1);
fwrite(&ru->common.rxdata[0][slot_offset],2,frame_parms->get_samples_per_slot(slot_rx,frame_parms)*2, f);
fclose(f);
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[0]=(int16_t)ulsch->rnti;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[1]=(int16_t)ulsch_harq->ulsch_pdu.rb_size;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[2]=(int16_t)ulsch_harq->ulsch_pdu.rb_start;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[3]=(int16_t)ulsch_harq->ulsch_pdu.nr_of_symbols;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[4]=(int16_t)ulsch_harq->ulsch_pdu.start_symbol_index;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[5]=(int16_t)ulsch_harq->ulsch_pdu.mcs_index;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[6]=(int16_t)ulsch_harq->ulsch_pdu.pusch_data.rv_index;
((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[7]=(int16_t)harq_pid;
memcpy(&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset+4],&ru->common.rxdata[0][slot_offset],frame_parms->get_samples_per_slot(slot_rx,frame_parms)*sizeof(int32_t));
gNB->common_vars.debugBuff_sample_offset+=(frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+4);
if(gNB->common_vars.debugBuff_sample_offset>((frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+2)*20)) {
FILE *f;
f = fopen("rxdata_buff.raw", "w"); if (f == NULL) exit(1);
fwrite((int16_t*)gNB->common_vars.debugBuff,2,(frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+4)*20*2, f);
fclose(f);
exit(-1);
}
#endif
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
}
start_meas(&gNB->rx_pusch_stats);
for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
if (no_sig) {
LOG_I(PHY, "PUSCH not detected in symbol %d\n",symbol);
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
return;
}
}
stop_meas(&gNB->rx_pusch_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0);
//LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
//LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,1);
nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,0);
break;
}
+1 -1
View File
@@ -34,7 +34,7 @@
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "phy_frame_config_nr.h"
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
+25 -7
View File
@@ -106,6 +106,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol;
dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos;
dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType;
dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups;
dlsch0_harq->mcs = dlsch_config_pdu->mcs;
dlsch0_harq->rvidx = dlsch_config_pdu->rv;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
@@ -147,12 +148,32 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
// pusch config pdu
pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id;
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu;
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid];
memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
if (harq_process_ul_ue){
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;
memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t));
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
if (scheduled_response->tx_request){
fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body;
//harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
harq_process_ul_ue->status = ACTIVE;
}
} else {
LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
return -1;
}
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
ulsch0->harq_processes[current_harq_pid]->status = ACTIVE;
break;
case (FAPI_NR_UL_CONFIG_TYPE_PUCCH):
@@ -214,9 +235,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
} else {
}
if (scheduled_response->tx_request != NULL){
} else {
}
}
return 0;
+9 -1
View File
@@ -62,10 +62,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
* @param frame_parms NR DL Frame parameters
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns nr_slot_t : downlink or uplink */
@returns int : downlink or uplink */
int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti);
/** \brief This function checks nr UE slot direction : downlink or uplink
* @param cfg : FAPI Config Request
* @param nr_frame : frame number
* @param nr_tti : slot number
@returns int : downlink, uplink or mixed slot type */
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti);
/** \brief This function frees tdd configuration for nr
* @param frame_parms NR DL Frame parameters
@returns none */
@@ -0,0 +1,99 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/***********************************************************************
*
* FILENAME : phy_frame_configuration_nr_ue.c
*
* DESCRIPTION : functions related to FDD/TDD configuration for NR
* see TS 38.213 11.1 Slot configuration
* and TS 38.331 for RRC configuration
*
************************************************************************/
#include "PHY/defs_nr_UE.h"
/*******************************************************************
*
* NAME : nr_ue_slot_select
*
* DESCRIPTION : function for the UE equivalent to nr_slot_select
*
*********************************************************************/
int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) {
/* for FFD all slot can be considered as an uplink */
int mu = cfg->ssb_config.scs_common, check_slot = 0;
if (cfg->cell_config.frame_duplex_type == FDD) {
return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT);
}
if (nr_frame%2 == 0) {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
} else {
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_UPLINK_SLOT);
}
check_slot = 0;
for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
if (cfg->tdd_table.max_tdd_periodicity_list[((1<<mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) + nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) {
check_slot++;
}
}
if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
return (NR_DOWNLINK_SLOT);
} else {
return (NR_MIXED_SLOT);
}
}
}
+22 -11
View File
@@ -86,6 +86,8 @@ fifo_dump_emos_UE emos_dump_UE;
char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
const uint8_t nr_rv_round_map_ue[4] = {0, 2, 1, 3};
extern double cpuf;
/*
@@ -2250,26 +2252,24 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
*/
if (get_softmodem_params()->usim_test==0) {
LOG_D(PHY, "Sending PUCCH\n");
LOG_I(PHY, "Generating PUCCH\n");
pucch_procedures_ue_nr(ue,
gNB_id,
proc,
TRUE);
FALSE);
}
LOG_D(PHY, "Sending data \n");
LOG_I(PHY, "Sending Uplink data \n");
nr_ue_pusch_common_procedures(ue,
harq_pid,
slot_tx,
thread_id,
gNB_id,
&ue->frame_parms);
&ue->frame_parms,1);
//ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers);
}
//LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
/* RACH */
if (get_softmodem_params()->do_ra==1) {
if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
if ((ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) {
nr_ue_prach_procedures(ue, proc, gNB_id, mode);
}
}
@@ -3289,9 +3289,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH *pdsch_vars;
uint8_t is_cw0_active = 0;
uint8_t is_cw1_active = 0;
uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; // TODO: should changed my mac
uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value;
uint8_t dmrs_type, nb_re_dmrs;
uint16_t length_dmrs = 1;
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind;
@@ -3316,6 +3315,13 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
else {
nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
}
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -3371,6 +3377,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
}
// exit dlsch procedures as there are no active dlsch
if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE)
return;
// start ldpc decode for CW 0
dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
@@ -4603,6 +4612,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
if (ue->prach_cnt == 3)
ue->prach_cnt = 0;
} else if (nr_prach == 2) {
nr_ra_succeeded(mod_id, ue->CC_id, gNB_id);
}
// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+1
View File
@@ -729,6 +729,7 @@ int main(int argc, char **argv) {
channel_model,
N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
30e-9,
forgetting_factor,
delay,
0);
+2 -1
View File
@@ -478,8 +478,9 @@ int main(int argc, char **argv)
harq_process->Qm = mod_order;
harq_process->rvidx = rvidx;
harq_process->R = rate;
harq_process->dmrsConfigType = 1;
harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
harq_process->dlDmrsSymbPos = 4;
harq_process->n_dmrs_cdm_groups = 1;
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
unsigned char *test_input;
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
+4 -3
View File
@@ -192,7 +192,8 @@ int main(int argc, char **argv)
int cyclic_prefix_type = NFAPI_CP_NORMAL;
int run_initial_sync=0;
int do_pdcch_flag=1;
int pusch_tgt_snrx10 = 200;
int pucch_tgt_snrx10 = 200;
int loglvl=OAILOG_INFO;
float target_error_rate = 0.01;
@@ -529,9 +530,9 @@ int main(int argc, char **argv)
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
// stub to configure frame_parms
+53 -13
View File
@@ -36,6 +36,7 @@
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
@@ -55,6 +56,8 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
// needed for some functions
PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}};
@@ -78,11 +81,11 @@ int main(int argc, char **argv)
//int freq_offset;
//int subframe_offset;
//char fname[40], vname[40];
int trial,n_trials=100,n_errors=0,ack_nack_errors=0;
int trial,n_trials=100,n_errors=0,ack_nack_errors=0,sr_errors=0;
uint8_t transmission_mode = 1,n_tx=1,n_rx=1;
uint16_t Nid_cell=0;
uint64_t SSB_positions=0x01;
channel_desc_t *gNB2UE;
channel_desc_t *UE2gNB;
int format=0;
//uint8_t extended_prefix_flag=0;
FILE *input_fd=NULL;
@@ -98,6 +101,8 @@ int main(int argc, char **argv)
uint16_t nrofPRB=2;
uint8_t timeDomainOCC=0;
SCM_t channel_model=AWGN;//Rayleigh1_anticorr;
double DS_TDL = .03;
int N_RB_DL=273,mu=1;
float target_error_rate=0.001;
@@ -160,6 +165,20 @@ int main(int argc, char **argv)
case 'G':
channel_model=ETU;
break;
case 'H':
channel_model = TDL_C;
DS_TDL = .030; // 30 ns
break;
case 'I':
channel_model = TDL_C;
DS_TDL = .3; // 300ns
break;
case 'J':
channel_model=TDL_D;
DS_TDL = .03;
break;
default:
printf("Unsupported channel model!\n");
@@ -400,9 +419,9 @@ int main(int argc, char **argv)
printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO);
}
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, 0, 0, 0);
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0);
if (gNB2UE==NULL) {
if (UE2gNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
exit(-1);
}
@@ -475,6 +494,7 @@ int main(int argc, char **argv)
for(SNR=snr0;SNR<=snr1;SNR=SNR+1){
ack_nack_errors=0;
sr_errors=0;
n_errors = 0;
for (trial=0; trial<n_trials; trial++) {
bzero(txdataF[aa],frame_parms->ofdm_symbol_size*sizeof(int));
@@ -503,6 +523,15 @@ int main(int argc, char **argv)
}
int rxlev = signal_energy(&rxdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size);
// noise measurement
gNB->ulmask_symb = startingSymbolIndex;
for (int rb=0; rb<nrofPRB; rb++) {
int rb2 = rb+startingPRB;
gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
}
gNB_I0_measurements(gNB);
if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12));
if(format==0){
nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
@@ -520,15 +549,23 @@ int main(int argc, char **argv)
pucch_pdu.start_symbol_index = startingSymbolIndex;
pucch_pdu.prb_start = startingPRB;
nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu);
if(nr_bit==1)
ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
else
ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
free(uci_pdu.harq->harq_list);
if(sr_flag==1){
if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1)
sr_errors+=1;
}
if(nr_bit>0){
if(nr_bit==1)
ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value);
else
ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value));
free(uci_pdu.harq->harq_list);
}
}
else if (format==1) {
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id,
&(payload_received),frame_parms,amp,nr_tti_tx,
m0,nrofSymbols,startingSymbolIndex,startingPRB,
startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
if(nr_bit==1)
ack_nack_errors+=((actual_payload^payload_received)&1);
else
@@ -567,8 +604,11 @@ int main(int argc, char **argv)
}
n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
}
printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
if((float)ack_nack_errors/(float)(n_trials)<=target_error_rate){
if (sr_flag == 1)
printf("SR: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,sr_errors);
if(nr_bit > 0)
printf("ACK/NACK: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
if((float)(ack_nack_errors+sr_errors)/(float)(n_trials)<=target_error_rate){
printf("PUCCH test OK\n");
break;
}
+231 -123
View File
@@ -104,6 +104,13 @@ int rrc_init_nr_global_param(void){return(0);}
// needed for some functions
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3};
channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX];
double s_re0[122880],s_im0[122880],r_re0[122880],r_im0[122880];
double s_re1[122880],s_im1[122880],r_re1[122880],r_im1[122880];
double r_re2[122880],r_im2[122880];
double r_re3[122880],r_im3[122880];
int main(int argc, char **argv)
{
@@ -115,23 +122,31 @@ int main(int argc, char **argv)
uint8_t snr1set = 0;
int slot = 8, frame = 0;
FILE *output_fd = NULL;
double *s_re[2]= {s_re0,s_re1};
double *s_im[2]= {s_im0,s_im1};
double *r_re[4]= {r_re0,r_re1,r_re2,r_re3};
double *r_im[4]= {r_im0,r_im1,r_im2,r_im3};
//uint8_t write_output_file = 0;
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
int trial, n_trials = 1, n_false_positive = 0, delay = 0;
double maxDoppler = 0.0;
uint8_t n_tx = 1, n_rx = 1;
//uint8_t transmission_mode = 1;
//uint16_t Nid_cell = 0;
channel_desc_t *gNB2UE;
channel_desc_t *UE2gNB;
uint8_t extended_prefix_flag = 0;
//int8_t interf1 = -21, interf2 = -21;
FILE *input_fd = NULL;
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
double tx_gain=1.0;
double N0=30;
//unsigned char frame_type = 0;
NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING;
//uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12;
int start_symbol = 2;
int start_symbol = 0;
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
uint8_t precod_nbr_layers = 1;
@@ -146,10 +161,18 @@ int main(int argc, char **argv)
int print_perf = 0;
cpuf = get_cpu_freq_GHz();
int msg3_flag = 0;
uint8_t rv_index = 0;
float roundStats[50];
float effRate;
float eff_tp_check = 0.7;
uint8_t snrRun;
UE_nr_rxtx_proc_t UE_proc;
FILE *scg_fd=NULL;
double DS_TDL = .03;
int pusch_tgt_snrx10 = 200;
int pucch_tgt_snrx10 = 200;
int ibwps=24;
int ibwp_rboffset=41;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
@@ -228,7 +251,22 @@ int main(int argc, char **argv)
case 'G':
channel_model = ETU;
break;
case 'H':
channel_model = TDL_C;
DS_TDL = .030; // 30 ns
break;
case 'I':
channel_model = TDL_C;
DS_TDL = .3; // 300ns
break;
case 'J':
channel_model=TDL_D;
DS_TDL = .03;
break;
default:
printf("Unsupported channel model!\n");
exit(-1);
@@ -274,6 +312,9 @@ int main(int argc, char **argv)
printf("Setting SNR0 to %f\n", snr0);
break;
case 't':
eff_tp_check = (float)atoi(optarg)/100;
break;
/*
case 'r':
ricean_factor = pow(10,-.1*atof(optarg));
@@ -372,6 +413,7 @@ int main(int argc, char **argv)
printf("-N Nid_cell\n");
printf("-O oversampling factor (1,2,4,8,16)\n");
printf("-R N_RB_DL\n");
printf("-t Acceptable effective throughput (in percentage)\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-P Print ULSCH performances\n");
exit(-1);
@@ -391,13 +433,27 @@ int main(int argc, char **argv)
if (snr1set == 0)
snr1 = snr0 + 10;
double sampling_frequency;
double bandwidth;
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
if (N_RB_UL >= 217) sampling_frequency = 122.88;
else if (N_RB_UL >= 106) sampling_frequency = 61.44;
else { printf("Need at least 106 PRBs\b"); exit(-1); }
if (N_RB_UL == 273) bandwidth = 100;
else if (N_RB_UL == 217) bandwidth = 80;
else if (N_RB_UL == 106) bandwidth = 40;
else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
sampling_frequency,
bandwidth,
DS_TDL,
0, 0, 0);
if (gNB2UE == NULL) {
UE2gNB->max_Doppler = maxDoppler;
if (UE2gNB == NULL) {
printf("Problem generating channel model. Exiting.\n");
exit(-1);
}
@@ -453,14 +509,13 @@ int main(int argc, char **argv)
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
// common configuration
rrc_mac_config_req_gNB(0,0,1,scc,0,0,NULL);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,1,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
//crcTableInit();
@@ -535,7 +590,7 @@ int main(int argc, char **argv)
unsigned char *estimated_output_bit;
unsigned char *test_input_bit;
uint32_t errors_decoding = 0;
uint32_t errors_scrambling = 0;
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
@@ -556,12 +611,16 @@ int main(int argc, char **argv)
uint16_t n_rb1 = 75;
uint8_t mcs_table = 0;
uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS;
uint8_t max_rounds = 4;
uint8_t crc_status = 0;
uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs); // [hna] remove dmrs struct
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
if (input_fd != NULL) max_rounds=1;
if(1<<ptrs_time_density >= nb_symb_sch)
pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
@@ -574,11 +633,30 @@ int main(int argc, char **argv)
printf("\n");
for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
snrRun = 0;
int n_errs;
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
varArray_t *table_rx=initVarArray(1000,sizeof(double));
int error_flag = 0;
n_false_positive = 0;
effRate = 0;
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};
varArray_t *table_rx=initVarArray(1000,sizeof(double));
for (trial = 0; trial < n_trials; trial++) {
uint8_t round = 0;
crc_status = 1;
errors_decoding = 0;
while (round<max_rounds && crc_status) {
round_trials[round]++;
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);
@@ -658,9 +736,9 @@ int main(int argc, char **argv)
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
pusch_pdu->start_symbol_index = start_symbol;
pusch_pdu->nr_of_symbols = nb_symb_sch;
pusch_pdu->pusch_data.rv_index = 0;
pusch_pdu->pusch_data.rv_index = rv_index;
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 0;
pusch_pdu->pusch_data.new_data_indicator = trial & 0x1;
pusch_pdu->pusch_data.num_cb = 0;
pusch_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density;
pusch_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
@@ -678,7 +756,8 @@ int main(int argc, char **argv)
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
scheduled_response.dl_config = NULL;
scheduled_response.tx_request = (fapi_nr_tx_request_t *) malloc(sizeof(fapi_nr_tx_request_t));
scheduled_response.tx_request->tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t));
ul_config.slot = slot;
ul_config.number_pdus = 1;
@@ -694,8 +773,8 @@ int main(int argc, char **argv)
ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = 0;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
@@ -721,7 +800,6 @@ int main(int argc, char **argv)
if (input_fd == NULL) {
if (SNR==snr0) {
// set FAPI parameters for UE, put them in the scheduled response and call
nr_ue_scheduled_response(&scheduled_response);
@@ -746,37 +824,40 @@ int main(int argc, char **argv)
txlev_float = (double)txlev/scale; // output of signal_energy is fixed point representation
//AWGN
}
}
else n_trials = 1;
if (input_fd == NULL ) {
sigma_dB = 10*log10(txlev_float)-SNR;
sigma = pow(10,sigma_dB/10);
printf("txlev_float %f, sigma_dB %f\n",10*log10(txlev_float),sigma_dB);
sigma_dB = N0;
sigma = pow(10,sigma_dB/10);
n_errors = 0;
n_false_positive = 0;
tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/txlev_float);
if(n_trials==1) printf("txlev_float %f, sigma_dB %f, tx_gain %f tx_offset %d, slot_offset %d\n",10*log10(txlev_float),sigma_dB,tx_gain,tx_offset,slot_offset);
errors_scrambling = 0;
errors_decoding = 0;
int error_flag;
for (trial = 0; trial < n_trials; trial++) {
error_flag = 0;
//----------------------------------------------------------
//------------------------ add noise -----------------------
//----------------------------------------------------------
if (input_fd == NULL ) {
for (i=0; i<slot_length; i++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)])/sqrt(scale) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)+1])/sqrt(scale) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
}
for (i=0; i<slot_length; i++) {
for (int aa=0; aa<1; aa++) {
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
}
}
if (UE2gNB->max_Doppler == 0) {
multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
slot_length,0,(n_trials==1)?1:0);
} else {
multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
2*slot_length,0);
}
for (i=0; i<slot_length; i++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
}
}
}
else {
AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
@@ -786,7 +867,7 @@ int main(int argc, char **argv)
int ta_offset=1600;
if (N_RB_DL <217) ta_offset=800;
else if (N_RB_DL < 106) ta_offset = 400;
fseek(input_fd,(slot_length<<2)+2000,SEEK_SET);
fread((void*)&gNB->common_vars.rxdata[0][slot_offset],
sizeof(int16_t),
slot_length<<1,
@@ -808,14 +889,14 @@ int main(int argc, char **argv)
start_meas(&gNB->phy_proc_rx);
phy_procedures_gNB_common_RX(gNB, frame, slot);
if (n_trials==1) {
if (n_trials==1 && round==0) {
LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][0],frame_parms->samples_per_subframe*10,1,1);
LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
}
phy_procedures_gNB_uespec_RX(gNB, frame, slot);
if (n_trials == 1) {
if (n_trials == 1 && round==0) {
LOG_M("rxsigF0_ext.m","rxsF0_ext",
&gNB->pusch_vars[0]->rxdataF_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
LOG_M("chestF0.m","chF0",
@@ -824,95 +905,122 @@ int main(int argc, char **argv)
&gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
LOG_M("rxsigF0_comp.m","rxsF0_comp",
&gNB->pusch_vars[0]->rxdataF_comp[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
LOG_M("rxsigF0_llr.m","rxsF0_llr",
&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
}
start_meas(&gNB->phy_proc_rx);
////////////////////////////////////////////////////////////
if (gNB->ulsch[0][0]->last_iteration_cnt >=
gNB->ulsch[0][0]->max_ldpc_iterations+1) {
error_flag = 1;
n_errors++;
n_errors[round]++;
crc_status = 1;
} else {
crc_status = 0;
}
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
for (i = 0; i < available_bits; i++) {
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
{
/*if(errors_scrambling == 0)
printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
errors_scrambling[round]++;
}
}
round++;
} // round
//----------------------------------------------------------
//----------------- count and print errors -----------------
//----------------------------------------------------------
for (i = 0; i < available_bits; i++) {
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
{
/*if(errors_scrambling == 0)
printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
errors_scrambling++;
}
}
if (errors_scrambling > 0) {
if (n_trials==1)
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling);
}
for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
if (estimated_output_bit[i] != test_input_bit[i]) {
/*if(errors_decoding == 0)
printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);*/
errors_decoding++;
}
}
if (n_trials == 1) {
for (int r=0;r<ulsch_ue[0]->harq_processes[harq_pid]->C;r++)
for (int i=0;i<ulsch_ue[0]->harq_processes[harq_pid]->K>>3;i++) {
if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i],
i,ulsch_gNB->harq_processes[harq_pid]->c[r][i],
ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);
}
}
if (errors_decoding > 0 && error_flag == 0) {
n_false_positive++;
if (n_trials==1)
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %u\n" "\x1B[0m", frame, trial, errors_decoding);
}
} // trial loop
printf("*****************************************\n");
printf("SNR %f: n_errors (negative CRC) = %d/%d, false_positive %d/%d, errors_scrambling %u/%u\n", SNR, n_errors, n_trials, n_false_positive, n_trials, errors_scrambling, available_bits*n_trials);
printf("\n");
printf("SNR %f: Channel BLER %e, Channel BER %e\n", SNR,(double)n_errors/n_trials,(double)errors_scrambling/available_bits/n_trials);
printf("*****************************************\n");
printf("\n");
if (print_perf==1) {
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
printStatIndent(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
printStatIndent(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
printStatIndent(&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");
printf("\n");
}
if(n_trials==1)
break;
if ((float)n_errors/(float)n_trials <= target_error_rate) {
printf("*************\n");
printf("PUSCH test OK\n");
printf("*************\n");
break;
}
if (n_trials == 1 && errors_scrambling[0] > 0) {
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling);
}
for (i = 0; i < TBS; i++) {
estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
if (estimated_output_bit[i] != test_input_bit[i]) {
/*if(errors_decoding == 0)
printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);*/
errors_decoding++;
}
}
if (n_trials == 1) {
for (int r=0;r<ulsch_ue[0]->harq_processes[harq_pid]->C;r++)
for (int i=0;i<ulsch_ue[0]->harq_processes[harq_pid]->K>>3;i++) {
/*if ((ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]) != 0) printf("************");
printf("r %d: in[%d] %x, out[%d] %x (%x)\n",r,
i,ulsch_ue[0]->harq_processes[harq_pid]->c[r][i],
i,ulsch_gNB->harq_processes[harq_pid]->c[r][i],
ulsch_ue[0]->harq_processes[harq_pid]->c[r][i]^ulsch_gNB->harq_processes[harq_pid]->c[r][i]);*/
}
}
if (errors_decoding > 0 && error_flag == 0) {
n_false_positive++;
if (n_trials==1)
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %u\n" "\x1B[0m", frame, trial, errors_decoding);
}
roundStats[snrRun] += ((float)round);
if (!crc_status) effRate += ((float)TBS)/round;
} // trial loop
roundStats[snrRun]/=((float)n_trials);
effRate /= n_trials;
printf("*****************************************\n");
printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n", SNR, n_errors[0], round_trials[0],n_errors[1], round_trials[1],n_errors[2], round_trials[2],n_errors[3], round_trials[3], n_false_positive, n_trials, errors_scrambling[0],available_bits*n_trials,errors_scrambling[1],available_bits*n_trials,errors_scrambling[2],available_bits*n_trials,errors_scrambling[3],available_bits*n_trials);
printf("\n");
printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR,
(double)n_errors[0]/round_trials[0],
(double)n_errors[1]/round_trials[0],
(double)n_errors[2]/round_trials[0],
(double)n_errors[3]/round_trials[0],
(double)errors_scrambling[0]/available_bits/round_trials[0],
(double)errors_scrambling[1]/available_bits/round_trials[0],
(double)errors_scrambling[2]/available_bits/round_trials[0],
(double)errors_scrambling[3]/available_bits/round_trials[0],
roundStats[snrRun],effRate,effRate/TBS*100,TBS);
printf("*****************************************\n");
printf("\n");
if (print_perf==1) {
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
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");
printf("\n");
}
if(n_trials==1)
break;
if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
printf("*************\n");
printf("PUSCH test OK\n");
printf("*************\n");
break;
}
snrRun++;
n_errs = n_errors[0];
} // SNR loop
printf("\n");
@@ -928,5 +1036,5 @@ int main(int argc, char **argv)
if (scg_fd)
fclose(scg_fd);
return (n_errors);
return (n_errs);
}
+2 -2
View File
@@ -180,7 +180,7 @@ void do_DL_sig(sim_t *sim,
//RU2UE[eNB_id][UE_id]->path_loss_dB = 0;
multipath_channel(sim->RU2UE[ru_id][UE_id][CC_id],s_re,s_im,r_re0,r_im0,
length,hold_channel);
length,hold_channel,0);
#ifdef DEBUG_SIM
rx_pwr = signal_energy_fp2(sim->RU2UE[ru_id][UE_id][CC_id]->ch[0],
sim->RU2UE[ru_id][UE_id][CC_id]->channel_length)*sim->RU2UE[ru_id][UE_id][CC_id]->channel_length;
@@ -394,7 +394,7 @@ void do_UL_sig(sim_t *sim,
multipath_channel(sim->UE2RU[UE_id][ru_id][CC_id],s_re,s_im,r_re0,r_im0,
frame_parms->samples_per_tti,hold_channel);
frame_parms->samples_per_tti,hold_channel,0);
rx_pwr = signal_energy_fp2(sim->UE2RU[UE_id][ru_id][CC_id]->ch[0],
+14 -7
View File
@@ -44,7 +44,8 @@ void multipath_channel(channel_desc_t *desc,
double rx_sig_re[2][30720*2],
double rx_sig_im[2][30720*2],
uint32_t length,
uint8_t keep_channel)
uint8_t keep_channel,
int log_channel)
{
int i,ii,j,l;
@@ -150,7 +151,8 @@ void multipath_channel(channel_desc_t *desc,
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
uint8_t keep_channel,
int log_channel)
{
int i,ii,j,l;
@@ -196,16 +198,21 @@ void multipath_channel(channel_desc_t *desc,
rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
if (i==0 && log_channel == 1) {
printf("channel[%d][%d][%d] = %f dB (%e,%e)\n",ii,j,l,10*log10(pow(desc->ch[ii+(j*desc->nb_rx)][l].x,2.0)+pow(desc->ch[ii+(j*desc->nb_rx)][l].y,2.0)),
desc->ch[ii+(j*desc->nb_rx)][l].x,
desc->ch[ii+(j*desc->nb_rx)][l].y);
}
} //l
} // j
rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
/* if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
+327 -6
View File
@@ -178,6 +178,223 @@ double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6
double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
double tdl_a_delays[] = {0.0000,
0.3819,
0.4025,
0.5868,
0.4610,
0.5375,
0.6708,
0.5750,
0.7618,
1.5375,
1.8978,
2.2242,
2.1718,
2.4942,
2.5119,
3.0582,
4.0810,
4.4579,
4.5695,
4.7966,
5.0066,
5.3043,
9.6586};
double tdl_a_amps_dB[] = {-13.4,
0,
-2.2,
-4,
-6,
-8.2,
-9.9,
-10.5,
-7.5,
-15.9,
-6.6,
-16.7,
-12.4,
-15.2,
-10.8,
-11.3,
-12.7,
-16.2,
-18.3,
-18.9,
-16.6,
-19.9,
-29.7};
#define TDL_A_PATHS 23
double tdl_b_delays[] = {0.0000,
0.1072,
0.2155,
0.2095,
0.2870,
0.2986,
0.3752,
0.5055,
0.3681,
0.3697,
0.5700,
0.5283,
1.1021,
1.2756,
1.5474,
1.7842,
2.0169,
2.8294,
3.0219,
3.6187,
4.1067,
4.2790,
4.7834};
double tdl_b_amps_dB[] = {0,
-2.2,
-4,
-3.2,
-9.8,
-1.2,
-3.4,
-5.2,
-7.6,
-3,
-8.9,
-9,
-4.8,
-5.7,
-7.5,
-1.9,
-7.6,
-12.2,
-9.8,
-11.4,
-14.9,
-9.2,
-11.3};
#define TDL_B_PATHS 23
double tdl_c_delays[] = {0,
0.2099,
0.2219,
0.2329,
0.2176,
0.6366,
0.6448,
0.6560,
0.6584,
0.7935,
0.8213,
0.9336,
1.2285,
1.3083,
2.1704,
2.7105,
4.2589,
4.6003,
5.4902,
5.6077,
6.3065,
6.6374,
7.0427,
8.6523};
double tdl_c_amps_dB[] = {-4.4,
-1.2,
-3.5,
-5.2,
-2.5,
0,
-2.2,
-3.9,
-7.4,
-7.1,
-10.7,
-11.1,
-5.1,
-6.8,
-8.7,
-13.2,
-13.9,
-13.9,
-15.8,
-17.1,
-16,
-15.7,
-21.6,
-22.8};
#define TDL_C_PATHS 24
double tdl_d_delays[] = {//0,
0,
0.035,
0.612,
1.363,
1.405,
1.804,
2.596,
1.775,
4.042,
7.937,
9.424,
9.708,
12.525};
double tdl_d_amps_dB[] = {//-0.2,
//-13.5,
-.00147,
-18.8,
-21,
-22.8,
-17.9,
-20.1,
-21.9,
-22.9,
-27.8,
-23.6,
-24.8,
-30.0,
-27.7};
#define TDL_D_PATHS 13
#define TDL_D_RICEAN_FACTOR .046774
double tdl_e_delays[] = {0,
0.5133,
0.5440,
0.5630,
0.5440,
0.7112,
1.9092,
1.9293,
1.9589,
2.6426,
3.7136,
5.4524,
12.0034,
20.6519};
double tdl_e_amps_dB[] = {//-0.03,
//-22.03,
-.00433,
-15.8,
-18.1,
-19.8,
-22.9,
-22.4,
-18.6,
-20.8,
-22.6,
-22.3,
-25.6,
-20.2,
-29.8,
-29.2};
#define TDL_E_PATHS 14
#define TDL_E_RICEAN_FACTOR 0.0063096
double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41};
double epa_amps_dB[] = {0.0,-1.0,-2.0,-3.0,-8.0,-17.2,-20.8};
@@ -282,7 +499,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
SCM_t channel_model,
double sampling_rate,
double channel_bandwidth,
double forgetting_factor,
double DS_TDL,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
@@ -300,6 +518,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint16_t i,j;
double sum_amps;
double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps;
chan_desc->modelid = channel_model;
chan_desc->nb_tx = nb_tx;
@@ -313,6 +532,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->ip = 0.0;
LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
int tdl_paths=0;
double tdl_ricean_factor = 1;
double *tdl_amps_dB;
double *tdl_delays;
switch (channel_model) {
case SCM_A:
LOG_W(OCM,"channel model not yet supported\n");
@@ -442,7 +666,105 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
}
break;
<<<<<<< HEAD
case TDL_A:
case TDL_B:
case TDL_C:
case TDL_D:
case TDL_E:
if (channel_model == TDL_A) {
tdl_paths=TDL_A_PATHS;
tdl_delays=tdl_a_delays;
tdl_amps_dB=tdl_a_amps_dB;
}else if (channel_model == TDL_B) {
tdl_paths=TDL_B_PATHS;
tdl_delays=tdl_b_delays;
tdl_amps_dB=tdl_b_amps_dB;
}
else if (channel_model == TDL_C) {
tdl_paths=TDL_C_PATHS;
tdl_delays=tdl_c_delays;
tdl_amps_dB=tdl_c_amps_dB;
printf("Initializing TDL_C channel with %d paths\n",TDL_C_PATHS);
} else if (channel_model == TDL_D) {
tdl_paths=TDL_D_PATHS;
tdl_delays=tdl_d_delays;
tdl_amps_dB=tdl_d_amps_dB;
tdl_ricean_factor = TDL_D_RICEAN_FACTOR;
} else if (channel_model == TDL_E) {
tdl_paths=TDL_E_PATHS-1;
tdl_delays=tdl_e_delays+1;
tdl_amps_dB=tdl_e_amps_dB;
tdl_ricean_factor = TDL_E_RICEAN_FACTOR;
}
int tdl_pathsby3 = tdl_paths/3;
if ((tdl_paths%3)>0) tdl_pathsby3++;
chan_desc->nb_taps = tdl_paths;
chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL;
printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]);
sum_amps += chan_desc->amps[i];
}
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] /= sum_amps;
tdl_delays[i] *= DS_TDL;
}
chan_desc->delays = tdl_delays;
chan_desc->ricean_factor = tdl_ricean_factor;
chan_desc->aoa = 0;
chan_desc->random_aoa = 0;
chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
for (i = 0; i<chan_desc->nb_taps; i++)
chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
if (nb_tx==2 && nb_rx==2) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else if (nb_tx==2 && nb_rx==1) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
} else if (nb_tx==1 && nb_rx==2) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
for (i = 0; i<(tdl_pathsby3); i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
}
LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
}
}
break;
=======
>>>>>>> origin/develop
case EPA:
chan_desc->nb_taps = 7;
chan_desc->Td = .410;
@@ -1462,15 +1784,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x;
desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y;
// printf("l %d : desc->ch.x %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x);
// printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
} //nb_taps
#ifdef DEBUG_CH
k=0;
printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y);
printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y);
#endif
}
} //channel_length
} //channel_length
}
} //aatx
} //aarx
+17 -25
View File
@@ -178,6 +178,11 @@ typedef enum {
EVA,
ETU,
MBSFN,
TDL_A,
TDL_B,
TDL_C,
TDL_D,
TDL_E,
Rayleigh8,
Rayleigh1,
Rayleigh1_800,
@@ -208,6 +213,11 @@ typedef enum {
{"EVA",EVA},\
{"ETU",ETU},\
{"MBSFN",MBSFN},\
{"TDL_A",TDL_A},\
{"TDL_B",TDL_B},\
{"TDL_C",TDL_C},\
{"TDL_D",TDL_D},\
{"TDL_E",TDL_E},\
{"Rayleigh8",Rayleigh8},\
{"Rayleigh1",Rayleigh1},\
{"Rayleigh1_800",Rayleigh1_800},\
@@ -262,33 +272,12 @@ typedef struct {
} sim_t;
/**
\brief This routine initializes a new channel descriptor
\param nb_tx Number of TX antennas
\param nb_rx Number of RX antennas
\param nb_taps Number of taps
\param channel_length Length of the interpolated channel impulse response
\param amps Linear amplitudes of the taps (length(amps)=channel_length). The values should sum up to 1.
\param delays Delays of the taps. If delays==NULL the taps are assumed to be spaced equidistantly between 0 and t_max.
\param R_sqrt Channel correlation matrix. If R_sqrt==NULL, no channel correlation is applied.
\param Td Maximum path delay in mus.
\param BW Channel bandwidth in MHz.
\param ricean_factor Ricean factor applied to all taps.
\param aoa Anlge of arrival
\param forgetting_factor This parameter (0...1) allows for simple 1st order temporal variation
\param max_Doppler This is the maximum Doppler frequency for Jakes' Model
\param channel_offset This is a time delay to apply to channel
\param path_loss_dB This is the path loss in dB
\param random_aoa If set to 1, AoA of ricean component is randomized
*/
//channel_desc_t *new_channel_desc(uint8_t nb_tx,uint8_t nb_rx, uint8_t nb_taps, uint8_t channel_length, double *amps, double* delays, struct complex** R_sqrt, double Td, double BW, double ricean_factor, double aoa, double forgetting_factor, double max_Doppler, int32_t channel_offset, double path_loss_dB,uint8_t random_aoa);
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
double sampling_rate,
double channel_bandwidth,
double TDL_DS,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB);
@@ -316,7 +305,8 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
double rx_sig_re[2],
double rx_sig_im[2],
uint32_t length,
uint8_t keep_channel)
uint8_t keep_channel,
int log_channel)
\brief This function generates and applys a random frequency selective random channel model.
@param desc Pointer to channel descriptor
@@ -326,6 +316,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
@param rx_sig_im output signal (imaginary component)
@param length Length of input signal
@param keep_channel Set to 1 to keep channel constant for null-B/F
@param log_channel=1 make channel coefficients come out for first sample of input
*/
void multipath_channel(channel_desc_t *desc,
@@ -334,7 +325,8 @@ void multipath_channel(channel_desc_t *desc,
double *rx_sig_re[2],
double *rx_sig_im[2],
uint32_t length,
uint8_t keep_channel);
uint8_t keep_channel,
int log_channel);
/*
\fn double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
+2 -2
View File
@@ -101,9 +101,9 @@
#define NUMBER_OF_NR_DLSCH_MAX 2//16
#define NUMBER_OF_NR_ULSCH_MAX 2//16
#define NUMBER_OF_NR_PUCCH_MAX 2
#define NUMBER_OF_NR_PUCCH_MAX 16
#define NUMBER_OF_NR_SR_MAX 16
#define NUMBER_OF_NR_PDCCH_MAX 16
#define MAX_MANAGED_ENB_PER_MOBILE 2
#define MAX_MANAGED_GNB_PER_MOBILE 2
+4 -2
View File
@@ -403,8 +403,10 @@ typedef struct NRRrcConfigurationReq_s {
uint16_t mnc[PLMN_LIST_MAX_SIZE];
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
NR_ServingCellConfigCommon_t *scc;
int ssb_SubcarrierOffset;
int pdsch_AntennaPorts;
int ssb_SubcarrierOffset;
int pdsch_AntennaPorts;
int pusch_TargetSNRx10;
int pucch_TargetSNRx10;
} gNB_RrcConfigurationReq;
+1 -5
View File
@@ -38,8 +38,7 @@
/* cell configuration section name */
#define GNB_CONFIG_STRING_GNB_LIST "gNBs"
#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset"
#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts"
#define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon"
#define GNB_CONFIG_STRING_PHYSCELLID "physCellId"
#define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset"
@@ -223,9 +222,6 @@
#define GNB_CONFIG_DLCARRIERBANDWIDTH_IDX 10
#define SSBPARAMS_DESC {{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,NULL,0,iptr:&ssb_SubcarrierOffset,defintval:0,TYPE_INT,0}}
#define PDSCHANTENNAPARAMS_DESC {{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,NULL,0,iptr:&pdsch_AntennaPorts,defintval:1,TYPE_INT,0}}
#define SCCPARAMS_DESC(scc) { \
{GNB_CONFIG_STRING_PHYSCELLID,NULL,0,i64ptr:scc->physCellId,defint64val:0,TYPE_INT64,0/*0*/}, \
{GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET,NULL,0,i64ptr:scc->n_TimingAdvanceOffset,defint64val:NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0,TYPE_INT64,0/*1*/},\
+10 -25
View File
@@ -520,17 +520,11 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t));
int ssb_SubcarrierOffset = 31;
int pdsch_AntennaPorts = 1;
uint64_t ssb_bitmap=0xff;
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
prepare_scc(scc);
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
paramdef_t SSBsParams[] = SSBPARAMS_DESC;
paramlist_def_t SSBsParamList = {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0};
paramdef_t PDSCHANTENNAParams[] = PDSCHANTENNAPARAMS_DESC;
paramlist_def_t PDSCHANTENNAParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0};
////////// Physical parameters
@@ -579,12 +573,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
config_getlist(&SSBsParamList, NULL, 0, aprefix);
if (SSBsParamList.numelt > 0) config_get(SSBsParams,sizeof(SSBsParams)/sizeof(paramdef_t),aprefix);
config_getlist(&PDSCHANTENNAParamList, NULL, 0, aprefix);
if (PDSCHANTENNAParamList.numelt > 0) config_get(PDSCHANTENNAParams,sizeof(PDSCHANTENNAParams)/sizeof(paramdef_t),aprefix);
config_getlist(&SCCsParamList, NULL, 0, aprefix);
if (SCCsParamList.numelt > 0) {
@@ -660,15 +648,16 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
(NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d",
NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l]);
}
// Parse optional physical parameters
sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k),
printf("SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr;
printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr;
printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr;
printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr);
NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr;
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
printf("SSB SCO %d\n",ssb_SubcarrierOffset);
NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = ssb_SubcarrierOffset;
printf("pdsch_AntennaPorts %d\n",pdsch_AntennaPorts);
NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = pdsch_AntennaPorts;
NRRRC_CONFIGURATION_REQ (msg_p).scc = scc;
}//
}//End for (k=0; k <num_gnbs ; k++)
@@ -777,11 +766,7 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) {
if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt>0) {
// Output a list of all gNBs.
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
if (GNBParamList.numelt > 0) {
for (k = 0; k < GNBParamList.numelt; k++) {
if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) {
+14
View File
@@ -113,6 +113,11 @@ typedef enum {
#define GNB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc"
#define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd"
#define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd"
#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset"
#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts"
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
typedef struct ccparams_nr_x2 {
char *frame_type;
@@ -156,7 +161,12 @@ typedef struct ccparams_nr_x2 {
{GNB_CONFIG_STRING_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \
{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PUSCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
{GNB_CONFIG_STRING_PUCCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \
}
#define GNB_GNB_ID_IDX 0
#define GNB_CELL_TYPE_IDX 1
#define GNB_GNB_NAME_IDX 2
@@ -171,6 +181,10 @@ typedef struct ccparams_nr_x2 {
#define GNB_REMOTE_S_PORTC_IDX 11
#define GNB_LOCAL_S_PORTD_IDX 12
#define GNB_REMOTE_S_PORTD_IDX 13
#define GNB_SSB_SUBCARRIEROFFSET_IDX 14
#define GNB_PDSCH_ANTENNAPORTS_IDX 15
#define GNB_PUSCH_TARGETPOW_X10_IDX 16
#define GNB_PUCCH_TARGETPOW_X10_IDX 17
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define GNBPARAMS_CHECK { \
+1 -1
View File
@@ -2240,7 +2240,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
uint8_t first_ue_total[MAX_NUM_CCs][20];
uint8_t first_ue_id[MAX_NUM_CCs][20];
uint8_t ul_inactivity_num[MAX_NUM_CCs];
uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={0};
uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={{0}};
// LTE_DL_FRAME_PARMS *frame_parms;
uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
uint16_t saved_ulsch_dci[MAX_NUM_CCs];
@@ -1151,8 +1151,9 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
if (NCS == 0) return nb_preambles;
else {
r = L_ra/NCS;
printf(" found_sequences %u\n", (nb_preambles/r));
return (nb_preambles/r);
found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r)
printf(" found_sequences %u\n", found_sequences);
return (found_sequences);
}
}
else{
+82 -6
View File
@@ -34,7 +34,6 @@
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC-CellGroupConfig.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
int mu,
@@ -326,6 +325,84 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
}
/** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and
\brief performs assert checks on the relevant RRC configuration.
@param NR_UE_MAC_INST_t mac: pointer to local MAC instance
@returns void
*/
void config_control_ue(NR_UE_MAC_INST_t *mac){
uint8_t bwp_id = 1, coreset_id = 1, ss_id;
NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Common;
AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");
NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Dedicated;
AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");
NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n");
AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n");
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
AssertFatal(commonSearchSpaceList != NULL, "commonSearchSpaceList is null\n");
AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");
struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");
AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);
AssertFatal(controlResourceSetToAddModList->list.array[0] != NULL, "coreset[0][0] is null\n");
struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
AssertFatal(searchSpacesToAddModList->list.count > 0, "list of UE specifically configured Search Spaces is empty\n");
AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);
struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n");
AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count);
// check pdcch_Config, pdcch_ConfigCommon and DL BWP
mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
mac->coreset[bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0];
// Check dedicated UL BWP and pass to MAC
mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[0];
AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");
// check available Search Spaces in the searchSpacesToAddModList and pass to MAC
// note: the network configures at most 10 Search Spaces per BWP per cell (including UE-specific and common Search Spaces).
for (ss_id = 0; ss_id < searchSpacesToAddModList->list.count; ss_id++) {
NR_SearchSpace_t *ss = searchSpacesToAddModList->list.array[ss_id];
AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
AssertFatal(*ss->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
AssertFatal(ss->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
AssertFatal(ss->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
mac->SSpace[0][0][ss_id] = ss;
}
// Check available CSSs in the commonSearchSpaceList (list of additional common search spaces)
// note: commonSearchSpaceList SIZE(1..4)
for (int css_id = 0; css_id < commonSearchSpaceList->list.count; css_id++) {
NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id];
AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(*css->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
AssertFatal(css->searchSpaceId != 0, "css->searchSpaceId is 0\n");
AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n");
AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
mac->SSpace[0][0][ss_id] = css;
ss_id++;
}
}
int nr_rrc_mac_config_req_ue(
module_id_t module_id,
int cc_idP,
@@ -338,16 +415,16 @@ int nr_rrc_mac_config_req_ue(
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
// NR_ServingCellConfig_t *serving_cell_config = spcell_configP->spCellConfigDedicated;
// TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc.
if(mibP != NULL){
mac->mib = mibP; // update by every reception
}
if(cell_group_config != NULL ){
mac->scg = cell_group_config;
mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex;
config_control_ue(mac);
if (cell_group_config->spCellConfig->reconfigurationWithSync) {
mac->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
@@ -355,7 +432,6 @@ int nr_rrc_mac_config_req_ue(
mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
}
mac->scg = cell_group_config;
/*
if(mac_cell_group_configP != NULL){
@@ -420,8 +496,8 @@ int nr_rrc_mac_config_req_ue(
}
}
*/
}
}
return 0;
}
-6
View File
@@ -178,7 +178,6 @@ typedef struct {
SFN_C_TYPE type0_pdcch_ss_sfn_c;
uint32_t type0_pdcch_ss_n_c;
uint32_t type0_pdcch_consecutive_slots;
int rnti_type;
/* PDUs */
/// Outgoing CCCH pdu for PHY
@@ -222,11 +221,6 @@ typedef struct {
uint32_t RA_tx_frame;
/// Random-access variable for window calculation (subframe of last change in window counter)
uint8_t RA_tx_subframe;
/// Scheduled RX frame for RA Msg2
uint16_t msg2_rx_frame;
/// Scheduled RX slot for RA Msg2
uint16_t msg2_rx_slot;
/// Random-access Group B maximum path-loss
/// Random-access variable for backoff (frame of last change in backoff counter)
uint32_t RA_backoff_frame;
/// Random-access variable for backoff (subframe of last change in backoff counter)
+19 -20
View File
@@ -62,9 +62,8 @@
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern const uint16_t nr_slots_per_frame[5];
extern const uint8_t nr_slots_per_frame[5];
//extern uint8_t nfapi_mode;
@@ -364,7 +363,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH && prach_resources->init_msg1) {
if (UE_mode < PUSCH && prach_resources->init_msg1) {
LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active);
@@ -449,7 +448,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
nr_get_RA_window(mac);
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
if (mac->generate_nr_prach == 1)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated);
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
@@ -471,7 +470,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
}
}
} else { // RACH is active
} else if (mac->RA_window_cnt != -1) { // RACH is active
////////////////////////////////////////////////////////////////
/////* Random Access Response reception (5.1.4 TS 38.321) */////
@@ -482,7 +481,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
// - handle beam failure recovery request
// - handle DL assignment on PDCCH for RA-RNTI
// - handle backoff and raResponseWindow params
// - disabled contention resolution as OAI NSA is contention-free based
// LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
// mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe);
@@ -495,12 +493,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
// mac->ra_state = WAIT_CONTENTION_RESOLUTION;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
mac->RA_window_cnt = -1;
mac->ra_state = RA_SUCCEEDED;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR successfully received \n", mod_id, frame, nr_tti_tx);
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception failed \n", mod_id, frame, nr_tti_tx);
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception failed \n", mod_id, frame, nr_tti_tx);
mac->ra_state = RA_UE_IDLE;
mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
@@ -572,21 +571,21 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
// mac->RA_tx_subframe = nr_tti_tx;
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
if (mac->generate_nr_prach == 1)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
} else {
mac->RA_window_cnt--;
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n",
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception not successful, (RA window count %d) \n",
mod_id,
frame,
nr_tti_tx,
mac->RA_window_cnt);
// Fill in preamble and PRACH resources
if (mac->generate_nr_prach)
if (mac->generate_nr_prach == 1)
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
}
@@ -616,28 +615,28 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
switch (ra_ResponseWindow) {
case 0:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
mac->RA_window_cnt += 1;
break;
case 1:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
mac->RA_window_cnt += 2;
break;
case 2:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
mac->RA_window_cnt += 4;
break;
case 3:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
mac->RA_window_cnt += 8;
break;
case 4:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
mac->RA_window_cnt += 10;
break;
case 5:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
mac->RA_window_cnt += 20;
break;
case 6:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
mac->RA_window_cnt += 40;
break;
case 7:
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
mac->RA_window_cnt += 80;
break;
}
@@ -46,6 +46,8 @@
#endif
#define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a)
// #define DEBUG_DCI
dci_pdu_rel15_t *def_dci_pdu_rel15;
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
@@ -62,217 +64,261 @@ 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){
uint16_t monitoringSymbolsWithinSlot;
uint8_t bwp_id = 1, coreset_id = 1;
int sps;
def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t));
AssertFatal(mac->scc != NULL, "scc is null\n");
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_BWP_DownlinkCommon_t *bwp_Common = mac->DLbwp[bwp_id - 1]->bwp_Common;
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;
for (int i = 0; i < 6; i++)
rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];
rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
} else {
rel15->coreset.RegBundleSize = 0;
rel15->coreset.InterleaverSize = 0;
rel15->coreset.ShiftIndex = 0;
}
rel15->coreset.CoreSetType = 1;
rel15->coreset.precoder_granularity = coreset->precoderGranularity;
// Scrambling RNTI
if (coreset->pdcch_DMRS_ScramblingID) {
rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
rel15->coreset.scrambling_rnti = mac->t_crnti;
} else {
rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
rel15->coreset.scrambling_rnti = 0;
}
#ifdef DEBUG_DCI
LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: ss_id %d bwp %p bwp_Id %d controlResourceSetId %d\n", ss_id, mac->DLbwp[bwp_id - 1], mac->DLbwp[bwp_id - 1]->bwp_Id, coreset->controlResourceSetId);
#endif
// loop over RNTI type and configure resource allocation for DCI
switch(rnti_type) {
case NR_RNTI_C:
// we use DL BWP dedicated
sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
// for SPS=14 8 MSBs in positions 13 down to 6
monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = mac->crnti;
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);
break;
case NR_RNTI_RA:
// we use the initial DL BWP
sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = mac->ra_rnti;
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);
break;
case NR_RNTI_P:
break;
case NR_RNTI_CS:
break;
case NR_RNTI_TC:
break;
case NR_RNTI_SP_CSI:
break;
case NR_RNTI_SI:
break;
case NR_RNTI_SFI:
break;
case NR_RNTI_INT:
break;
case NR_RNTI_TPC_PUSCH:
break;
case NR_RNTI_TPC_PUCCH:
break;
case NR_RNTI_TPC_SRS:
break;
default:
break;
}
for (int i = 0; i < sps; i++) {
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
}
}
#ifdef DEBUG_DCI
LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: rnti_type %d BWPSize %d BWPStart %d rel15->SubcarrierSpacing %d rel15->dci_format %d rel15->dci_length %d sps %d monitoringSymbolsWithinSlot %d \n",
rnti_type,
rel15->BWPSize,
rel15->BWPStart,
rel15->SubcarrierSpacing,
rel15->dci_format,
rel15->dci_length,
sps,
monitoringSymbolsWithinSlot);
#endif
// add DCI
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
dl_config->number_pdus = dl_config->number_pdus + 1;
}
void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) {
def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t));
NR_BWP_Downlink_t *bwp;
NR_BWP_DownlinkCommon_t *bwp_Common;
NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated;
NR_SetupRelease_PDCCH_Config_t *pdcch_Config;
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon;
struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList;
struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList;
struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList;
NR_SearchSpace_t *NR_SearchSpace;
NR_ControlResourceSet_t *coreset;
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
int ss_id;
uint8_t bwp_id = 1, coreset_id = 1;
NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated;
NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1];
uint8_t bwp_id = 1;
int ss_id, sps;
#ifdef DEBUG_DCI
LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &mac->ra_rnti, mac->ra_rnti, &mac->crnti, mac->crnti, &mac->t_crnti, mac->t_crnti);
#endif
// get PDCCH configuration(s) (Coreset, SearchSpace, etc...) from BWP Dedicated in serving cell config dedicated (scd)
// get BWP 1, Coreset ID 0, SearchSpace ID 0 (i.e. configured in MIB and in ServingCellConfigCommon)
// loop over all available SS for BWP ID 1, CORESET ID 1
for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id] != NULL; ss_id++){
NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common;
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
struct NR_PhysicalCellGroupConfig *phy_cgc = mac->scg->physicalCellGroupConfig;
switch (ss->searchSpaceType->present){
case NR_SearchSpace__searchSpaceType_PR_common:
// this is for CSSs, we use BWP common and pdcch_ConfigCommon
// Check dedicated DL BWP
if (mac->DLbwp[0] == NULL) {
NR_SearchSpace_t *ss;
int ss_id = 0;
AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n");
AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count);
mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
dl_bwp_Dedicated = mac->DLbwp[0]->bwp_Dedicated;
AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n");
bwp_Common = mac->DLbwp[0]->bwp_Common;
AssertFatal(bwp_Common != NULL, "bwp_Common is null\n");
pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n");
pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n");
AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n");
controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList;
AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n");
AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count);
mac->coreset[0][0] = controlResourceSetToAddModList->list.array[0];
coreset = mac->coreset[0][0];
AssertFatal(coreset != NULL, "coreset[0][0] is null\n");
searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n");
AssertFatal(searchSpacesToAddModList->list.count > 0, "searchSpacesToAddModList is empty\n");
AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count);
for (int i = 0; i < searchSpacesToAddModList->list.count; i++) {
ss = searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n");
AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
mac->SSpace[0][0][ss_id] = ss;
ss_id++;
}
}
// Check dedicated UL BWP
if (mac->ULbwp[0] == NULL) {
uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList;
AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n");
AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count);
mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[bwp_id - 1];
AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n");
}
bwp = mac->DLbwp[0];
bwp_Common = bwp->bwp_Common;
pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
dl_bwp_Dedicated = bwp->bwp_Dedicated;
pdcch_Config = dl_bwp_Dedicated->pdcch_Config;
searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList;
// check USSs
ss_id = 0;
NR_SearchSpace = mac->SSpace[0][0][ss_id];
while(NR_SearchSpace != NULL && ss_id < searchSpacesToAddModList->list.count) {
AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n");
AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n");
ss_id++;
}
if (mac->crnti > 0) {
NR_SearchSpace_t *css;
NR_SearchSpace_t *uss = NULL;
NR_ServingCellConfigCommon_t *scc;
NR_SearchSpaceId_t ra_SearchSpaceId;
rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
uint16_t monitoringSymbolsWithinSlot;
uint8_t add_dci = 1;
AssertFatal(mac->scc != NULL, "scc is null\n");
scc = mac->scc;
rel15->dci_format = NR_DL_DCI_FORMAT_1_1;
// CoReSet configuration
coreset = mac->coreset[0][0];
rel15->coreset.duration = coreset->duration;
for (int i = 0; i < 6; i++)
rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];
rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) {
struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved;
rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize);
rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize);
AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n");
rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId;
} else {
rel15->coreset.RegBundleSize = 0;
rel15->coreset.InterleaverSize = 0;
rel15->coreset.ShiftIndex = 0;
}
rel15->coreset.CoreSetType = 1;
rel15->coreset.precoder_granularity = coreset->precoderGranularity;
if (mac->ra_state == WAIT_RAR){
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n");
ra_SearchSpaceId = *pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
// fetch the CSS for RA from the CSS list
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
css = commonSearchSpaceList->list.array[i];
if(css->searchSpaceId == ra_SearchSpaceId)
break;
}
// check CSSs
if(css != NULL) {
AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
}
if (frame == mac->msg2_rx_frame && slot == mac->msg2_rx_slot){
sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = mac->ra_rnti;
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_C,rel15->BWPSize,bwp_id);
for (int i = 0; i < sps; i++)
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
}
fill_dci_search_candidates(css, rel15);
} else {
add_dci = 0;
// Fetch configuration for searchSpaceZero
// note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero).
if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){
LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n");
LOG_W(MAC, "[DCI_CONFIG] This should not be available yet...");
}
} else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){
rel15->rnti = mac->t_crnti;
} else {
rel15->rnti = mac->crnti;
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);
// get UE-specific search space
for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id] != NULL; ss_id++){
uss = mac->SSpace[0][0][ss_id];
if (uss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break;
}
AssertFatal(ss_id < FAPI_NR_MAX_SS_PER_CORESET, "couldn't find a UE-specific SS\n");
sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
// for SPS=14 8 MSBs in positions 13 down to 6
monitoringSymbolsWithinSlot = (uss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (uss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
for (int i = 0; i < sps; i++)
if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) {
rel15->coreset.StartSymbolIndex = i;
break;
if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){
// check available SS IDs
if (pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
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);
fill_dci_search_candidates(ss, rel15);
break;
case WAIT_CONTENTION_RESOLUTION:
rel15->rnti = mac->t_crnti;
break;
default:
break;
}
}
}
fill_dci_search_candidates(uss, rel15);
}
if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
// Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
}
}
if (pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){
// Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG
LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
}
}
if (pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->pagingSearchSpace){
// Configure monitoring of PDCCH candidates in Type2-PDCCH common search space on the MCG
LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet...");
}
}
if (phy_cgc){
if (phy_cgc->cs_RNTI){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
}
if (phy_cgc->ext1){
if (phy_cgc->ext1->mcs_C_RNTI){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
}
}
}
} // end DCI 00 and 01
// DCI 2_0
if (ss->searchSpaceType->choice.common->dci_Format2_0){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_0 with CRC scrambled by SFI-RNTI \n");
LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
}
// DCI 2_1
if (ss->searchSpaceType->choice.common->dci_Format2_1){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_1 with CRC scrambled by INT-RNTI \n");
LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
}
// DCI 2_2
if (ss->searchSpaceType->choice.common->dci_Format2_2){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_2 with CRC scrambled by TPC-RNTI \n");
LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
}
// DCI 2_3
if (ss->searchSpaceType->choice.common->dci_Format2_3){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_3 with CRC scrambled by TPC-SRS-RNTI \n");
LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet...");
}
// Scrambling RNTI
if (coreset->pdcch_DMRS_ScramblingID) {
rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID;
rel15->coreset.scrambling_rnti = mac->t_crnti;
} else {
rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId;
rel15->coreset.scrambling_rnti = 0;
}
break;
case NR_SearchSpace__searchSpaceType_PR_ue_Specific:
// this is an USS
if (ss->searchSpaceType->choice.ue_Specific){
if(ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1){
// 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);
fill_dci_search_candidates(ss, rel15);
if (add_dci){
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI;
dl_config->number_pdus = dl_config->number_pdus + 1;
#ifdef DEBUG_DCI
LOG_D(MAC, "[DCI_CONFIG] ss %d ue_Specific %p searchSpaceType->present %d dci_Formats %d\n",
ss_id,
ss->searchSpaceType->choice.ue_Specific,
ss->searchSpaceType->present,
ss->searchSpaceType->choice.ue_Specific->dci_Formats);
#endif
}
if (phy_cgc){
if (phy_cgc->cs_RNTI){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n");
LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
}
if (phy_cgc->sp_CSI_RNTI){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by SP-CSI-RNTI...\n");
LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
}
if (phy_cgc->ext1){
if (phy_cgc->ext1->mcs_C_RNTI){
LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n");
LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet...");
}
}
}
}
}
break;
default:
AssertFatal(1 == 0, "[DCI_CONFIG] Unrecognized search space type...");
break;
}
}
}
+184 -185
View File
@@ -757,193 +757,183 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
}
*/
}
} else if (ul_info && ul_info->slot_tx == 8) {
module_id_t mod_id = ul_info->module_id;
uint32_t gNB_index = ul_info->gNB_index;
int cc_id = ul_info->cc_id;
frame_t rx_frame = ul_info->frame_rx;
slot_t rx_slot = ul_info->slot_rx;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
} else if (ul_info) {
// program PUSCH. this should actually be done upon reception of an UL DCI
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
if (get_softmodem_params()->phy_test && ul_info->slot_tx == 8) { // ULSCH is handled only in phy-test mode (consistently with OAI gNB)
//--------------------------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;
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;
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
uint8_t dmrs_config_type = 0;
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);
//------------------------------------------------------------------------------//
uint8_t nb_dmrs_re_per_rb;
uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
uint8_t data_existing = 0;
uint16_t TBS_bytes;
uint32_t TBS;
int i;
dcireq.module_id = mod_id;
dcireq.gNB_index = gNB_index;
dcireq.cc_id = cc_id;
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
module_id_t mod_id = ul_info->module_id;
uint32_t gNB_index = ul_info->gNB_index;
int cc_id = ul_info->cc_id;
frame_t rx_frame = ul_info->frame_rx;
slot_t rx_slot = ul_info->slot_rx;
frame_t frame_tx = ul_info->frame_tx;
slot_t slot_tx = ul_info->slot_tx;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint8_t access_mode = SCHEDULED_ACCESS;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
// program PUSCH. this should actually be done upon reception of an UL DCI
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
fapi_nr_tx_request_t tx_req;
fapi_nr_tx_request_body_t tx_req_body;
scheduled_response.ul_config->slot = ul_info->slot_tx;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
//--------------------------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;
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;
uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
uint8_t dmrs_config_type = 0;
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);
uint8_t no_data_in_dmrs = 1;
uint16_t number_dmrs_symbols = 0;
uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
//------------------------------------------------------------------------------//
if (1 << ptrs_time_density >= nr_of_symbols) {
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
for (i = start_symbol_index; i < start_symbol_index + nr_of_symbols; i++) {
if((ul_dmrs_symb_pos >> i) & 0x01)
number_dmrs_symbols += 1;
}
if(no_data_in_dmrs)
nb_dmrs_re_per_rb = 12;
else
nb_dmrs_re_per_rb = ((dmrs_config_type == pusch_dmrs_type1) ? 6:4);
TBS = nr_compute_tbs(nr_get_Qm_ul(mcs_index, 0),
nr_get_code_rate_ul(mcs_index, 0),
rb_size,
nr_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
0,
0,
nrOfLayers);
TBS_bytes = TBS/8;
if (IS_SOFTMODEM_NOS1){
// Getting IP traffic to be transmitted
data_existing = nr_ue_get_sdu(mod_id,
cc_id,
frame_tx,
slot_tx,
0,
ulsch_input_buffer,
TBS_bytes,
&access_mode);
}
//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
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "Random data to be tranmsitted: \n");
//Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
//in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
//have a valid LCID (nr_process_mac_pdu function)
ulsch_input_buffer[0] = 0x31;
for (i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
//printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
}
}
#ifdef DEBUG_MAC_PDU
LOG_D(PHY, "Is data existing ?: %d \n", data_existing);
LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes);
for (i = 0; i < TBS_bytes; i++) {
printf("%02x", ulsch_input_buffer[i]);
}
printf("\n");
#endif
dcireq.module_id = mod_id;
dcireq.gNB_index = gNB_index;
dcireq.cc_id = cc_id;
dcireq.frame = rx_frame;
dcireq.slot = rx_slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
// Config UL TX PDU
tx_req.slot = slot_tx;
tx_req.sfn = frame_tx;
// tx_req->tx_config // TbD
tx_req.number_of_pdus = 1;
tx_req_body.pdu_length = TBS_bytes;
tx_req_body.pdu_index = 0;
tx_req_body.pdu = ulsch_input_buffer;
scheduled_response.tx_request = &tx_req;
scheduled_response.tx_request->tx_request_body = &tx_req_body;
scheduled_response.module_id = mod_id;
scheduled_response.CC_id = cc_id;
scheduled_response.frame = rx_frame;
scheduled_response.slot = rx_slot;
scheduled_response.ul_config->slot = ul_info->slot_tx;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
if (1 << ptrs_time_density >= nr_of_symbols) {
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
// TODO: expand
// Note: Contention resolution is currently not active
if (mac->RA_contention_resolution_timer_active == 1)
ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
}
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
mac->if_module->scheduled_response(&scheduled_response);
}
// TODO: expand
// Note: Contention resolution is currently not active
if (mac->RA_contention_resolution_timer_active == 1)
ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
}
return UE_CONNECTION_OK;
}
// Notes:
// - Type1-PDCCH CSS configuration from ra-SearchSpace.
// - Msg2 is scheduled in the mixed slot or in the last dl slot if they are allowed by the Type 1 Common Search Space configuration
// todo:
// - if Type1-PDCCH CSS is not configured in RRC message (Coreset and SearchSpace), UE searches in Type 0 PDCCH CSS.
void nr_ue_msg2_scheduler(module_id_t mod_id,
uint16_t rach_frame,
uint16_t rach_slot,
uint16_t *msg2_frame,
uint16_t *msg2_slot){
uint8_t bwp_id = 1;
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_CellGroupConfig_t *scg = mac->scg;
NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id - 1];
NR_SearchSpace_t *ss;
struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
uint8_t mu = *scc->ssbSubcarrierSpacing;
uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow;
uint8_t slot_window, slot_limit, frame_limit;
uint16_t start_next_period, monitoring_slot_period, monitoring_offset;
// number of mixed slot or of last dl slot if there is no mixed slot
uint16_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots;
uint16_t nr_dl_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols;
uint16_t nr_ul_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols;
// lenght of tdd period in slots
uint16_t tdd_period_slot = last_dl_slot_period + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH common SearchSpace list has 0 elements\n");
LOG_D(MAC, "Frame %d, Slot %d: Scheduling Msg2 reception \n", rach_frame, rach_slot);
// Common searchspace list
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
ss = commonSearchSpaceList->list.array[i];
if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
// retrieving ra pdcch monitoring period and offset
find_monitoring_periodicity_offset_common(ss, &monitoring_slot_period, &monitoring_offset);
}
if (nr_dl_symbols == 0)
last_dl_slot_period--;
if ((nr_dl_symbols > 0) || (nr_ul_symbols > 0))
tdd_period_slot++;
// computing start of next period
start_next_period = (rach_slot - (rach_slot % tdd_period_slot) + tdd_period_slot) % nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot > rach_slot) ? rach_frame : (rach_frame +1);
switch(response_window){
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
slot_window = 1;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
slot_window = 2;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
slot_window = 4;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
slot_window = 8;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
slot_window = 10;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
slot_window = 20;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
slot_window = 40;
break;
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
slot_window = 80;
break;
default:
AssertFatal(1==0,"Invalid response window value %d\n",response_window);
}
AssertFatal(slot_window<=nr_slots_per_frame[mu], "Msg2 response window needs to be lower or equal to 10ms");
// slot and frame limit to transmit msg2 according to response window
slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while ((*msg2_slot > slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu] + *msg2_slot - monitoring_offset) % monitoring_slot_period != 0)) {
if((*msg2_slot % tdd_period_slot) > 0)
(*msg2_slot)--;
else
AssertFatal(1 == 0, "No available DL slot to schedule reception of msg2 has been found");
}
LOG_D(MAC, "Scheduled Msg2 reception in Frame %d, Slot %d: \n", *msg2_frame, *msg2_slot);
}
// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x
// It fills the PRACH PDU per each FD occasion.
// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3.
@@ -969,6 +959,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
mac->RA_offset = 2; // to compensate the rx frame offset at the gNB
mac->generate_nr_prach = 0; // Reset flag for PRACH generation
if (is_nr_UL_slot(scc, slotP)) {
@@ -1090,8 +1081,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
}
}
}
} else {
mac->generate_nr_prach = 0;
} else if (mac->ra_state == RA_SUCCEEDED){
mac->generate_nr_prach = 2;
}
mac->scheduled_response.ul_config = ul_config;
}
@@ -2320,7 +2311,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
const uint16_t n_RB_DLBWP = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
const uint16_t n_RB_DLBWP = (mac->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
const uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275);
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);
@@ -2761,7 +2752,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
dlsch_config_pdu_1_0->number_symbols);
dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 1 : 2;
dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
/* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
if (dlsch_config_pdu_1_0->number_symbols == 2)
dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1;
else
dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 2;
/* VRB_TO_PRB_MAPPING */
dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
/* MCS */
@@ -2822,10 +2818,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
dlsch_config_pdu_1_0->pucch_resource_id,
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind);
if (mac->ra_rnti == rnti)
if (mac->RA_window_cnt >= 0 && rnti == mac->ra_rnti){
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
else
} else {
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
}
// dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
@@ -2880,7 +2877,10 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc
dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
dlsch_config_pdu_1_1->number_symbols);
dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 1 : 2;
dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
/* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1;
/* VRB_TO_PRB_MAPPING */
if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0)
dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
@@ -3133,6 +3133,7 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
case NR_DL_DCI_FORMAT_1_0:
switch(rnti_type) {
case NR_RNTI_RA:
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); // TBR hotfix
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
@@ -3167,8 +3168,6 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
#endif
break;
mac->rnti_type = rnti_type;
case NR_RNTI_C:
// indicating a DL DCI format 1bit
+6 -3
View File
@@ -107,9 +107,10 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
uint8_t n_subPDUs = 0; // number of RAR payloads
uint8_t n_subheaders = 0; // number of MAC RAR subheaders
//uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req;
uint16_t ta_command = 0, msg3_f_alloc, bwp_size;
int f_alloc, mask;
//unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req; // WIP
//uint16_t ta_command = 0, msg3_f_alloc, bwp_size; // WIP
uint16_t ta_command = 0;
//int f_alloc, mask; // WIP
AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n");
@@ -143,6 +144,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
// LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
// mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#if 0 // TbD WIP Msg3 development ongoing
if (ue_mac->RA_RAPID_found) {
// TC-RNTI
*t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
@@ -200,6 +202,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id,
ue_mac->t_crnti = 0;
ta_command = (0xffff);
}
#endif
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1);
+5 -3
View File
@@ -328,11 +328,12 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_tgt_snrx10,
int pucch_tgt_snrx10,
NR_ServingCellConfigCommon_t *scc,
int add_ue,
uint32_t rnti,
NR_CellGroupConfig_t *secondaryCellGroup
){
NR_CellGroupConfig_t *secondaryCellGroup){
if (scc != NULL ) {
AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
@@ -353,7 +354,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
}
}
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = 0;
+94 -72
View File
@@ -288,6 +288,26 @@ void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
}
*/
void nr_schedule_pusch(int Mod_idP,
int UE_id,
frame_t frameP,
sub_frame_t slotP) {
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
NR_sched_pusch *pusch = UE_list->UE_sched_ctrl[UE_id].sched_pusch;
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
UL_tti_req->SFN = pusch->frame;
UL_tti_req->Slot = pusch->slot;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
UL_tti_req->n_pdus+=1;
memset((void *) UE_list->UE_sched_ctrl[UE_id].sched_pusch,
0, sizeof(NR_sched_pusch));
}
}
void nr_schedule_pucch(int Mod_idP,
int UE_id,
frame_t frameP,
@@ -413,71 +433,91 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
*ulsch_in_slot_bitmap = 0x00;
}
// Check if there are downlink symbols in the slot,
if (is_nr_DL_slot(cc->ServingCellConfigCommon,slot_txP)) {
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
for (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, 100);
memset(cc[CC_id].vrb_map_UL, 0, 100);
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
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
//mbsfn_status[CC_id] = 0;
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
}
// clear vrb_maps
memset(cc[CC_id].vrb_map, 0, 100);
memset(cc[CC_id].vrb_map_UL, 0, 100);
// refresh UE list based on UEs dropped by PHY in previous subframe
/*
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i]) {
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP);
}
nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
// refresh UE list based on UEs dropped by PHY in previous subframe
/*
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
if (UE_list->active[i]) {
nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id];
rnti = 0;//UE_RNTI(module_idP, i);
CC_id = 0;//UE_PCCID(module_idP, i);
rnti = 0;//UE_RNTI(module_idP, i);
CC_id = 0;//UE_PCCID(module_idP, i);
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
*/
// This schedules MIB
if((slot_txP == 0) && (frame_txP & 7) == 0){
schedule_nr_mib(module_idP, frame_txP, slot_txP);
// This schedules MIB
if((slot_txP == 0) && (frame_txP & 7) == 0){
schedule_nr_mib(module_idP, frame_txP, slot_txP);
}
// This schedule PRACH if we are not in phy_test mode
if (get_softmodem_params()->phy_test == 0)
schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
// This schedule SR
// TODO
// This schedule CSI
// TODO
// This schedule RA procedure if not in phy_test mode
// Otherwise already consider 5G already connected
if (get_softmodem_params()->phy_test == 0) {
nr_schedule_RA(module_idP, frame_txP, slot_txP);
nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
}
else
UE_list->fiveG_connected[UE_id] = true;
if (get_softmodem_params()->phy_test) {
// TbD once RACH is available, start ta_timer when UE is connected
if (ue_sched_ctl->ta_timer)
ue_sched_ctl->ta_timer--;
if (ue_sched_ctl->ta_timer == 0) {
gNB->ta_command = ue_sched_ctl->ta_update;
/* if time is up, then set the timer to not send it for 5 frames
// regardless of the TA value */
ue_sched_ctl->ta_timer = 100;
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
/* MAC CE flag indicating TA length */
gNB->ta_len = 2;
}
}
if (get_softmodem_params()->phy_test == 0)
nr_schedule_RA(module_idP, frame_txP, slot_txP);
else
UE_list->fiveG_connected[UE_id] = true;
// This schedules the DCI for Uplink and subsequently PUSCH
if (UE_list->fiveG_connected[UE_id]) {
int tda = 1; // time domain assignment hardcoded for now
schedule_fapi_ul_pdu(module_idP, frame_txP, slot_txP, num_slots_per_tdd, tda);
nr_schedule_pusch(module_idP, UE_id, frame_rxP, slot_rxP);
}
// Phytest scheduling
if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) {
ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd;
nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched);
nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
// resetting ta flag
gNB->ta_len = 0;
}
if (get_softmodem_params()->phy_test) {
// TbD once RACH is available, start ta_timer when UE is connected
if (ue_sched_ctl->ta_timer)
ue_sched_ctl->ta_timer--;
if (ue_sched_ctl->ta_timer == 0) {
gNB->ta_command = ue_sched_ctl->ta_update;
/* if time is up, then set the timer to not send it for 5 frames
// regardless of the TA value */
ue_sched_ctl->ta_timer = 100;
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
/* MAC CE flag indicating TA length */
gNB->ta_len = 2;
}
}
if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) {
ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd;
nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched);
nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL);
// resetting ta flag
gNB->ta_len = 0;
}
if (UE_list->fiveG_connected[UE_id])
nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
/*
// Allocate CCEs for good after scheduling is done
@@ -485,24 +525,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
allocate_CCEs(module_idP, CC_id, subframeP, 0);
*/
} //is_nr_DL_slot
if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) {
if (get_softmodem_params()->phy_test == 0) {
if (UE_list->fiveG_connected[UE_id])
nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP);
nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP);
}
if (get_softmodem_params()->phy_test){
nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP);
if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)){
nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP);
}
}
}
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
+112 -107
View File
@@ -42,8 +42,7 @@
#include "SIMULATION/TOOLS/sim.h" // for taus
extern RAN_CONTEXT_t RC;
const uint8_t nr_slots_per_frame_mac[5] = {10, 20, 40, 80, 160};
extern const uint8_t nr_slots_per_frame[5];
uint8_t DELTA[4]= {2,3,4,6};
@@ -54,115 +53,117 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol;
uint16_t format;
if (is_nr_UL_slot(scc,slotP)) {
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol;
uint16_t format;
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur) ) {
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM;
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
if ( get_nr_prach_info_from_index(config_index,
(int)frameP,
(int)slotP,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
mu,
cc->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur) ) {
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int n=0; n<(1<<fdm); n++) { // one structure per frequency domain occasion
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM;
uint16_t format0 = format&0xff; // first column of format from table
uint16_t format1 = (format>>8)&0xff; // second column of format from table
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = n;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 9;
break;
case 0xa2:
prach_pdu->prach_format = 10;
break;
case 0xa3:
prach_pdu->prach_format = 11;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
for (int n=0; n<(1<<fdm); n++) { // one structure per frequency domain occasion
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
UL_tti_req->n_pdus+=1;
// filling the prach fapi structure
prach_pdu->phys_cell_id = *scc->physCellId;
prach_pdu->num_prach_ocas = N_t_slot;
prach_pdu->prach_start_symbol = start_symbol;
prach_pdu->num_ra = n;
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
if (format1!=0xff) {
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 9;
break;
case 0xa2:
prach_pdu->prach_format = 10;
break;
case 0xa3:
prach_pdu->prach_format = 11;
break;
default:
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
}
}
}
else{
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 0;
break;
case 0xa2:
prach_pdu->prach_format = 1;
break;
case 0xa3:
prach_pdu->prach_format = 2;
break;
case 0xb1:
prach_pdu->prach_format = 3;
break;
case 0xb2:
prach_pdu->prach_format = 4;
break;
case 0xb3:
prach_pdu->prach_format = 5;
break;
case 0xb4:
prach_pdu->prach_format = 6;
break;
case 0xc0:
prach_pdu->prach_format = 7;
break;
case 0xc2:
prach_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
else{
switch(format0) {
case 0xa1:
prach_pdu->prach_format = 0;
break;
case 0xa2:
prach_pdu->prach_format = 1;
break;
case 0xa3:
prach_pdu->prach_format = 2;
break;
case 0xb1:
prach_pdu->prach_format = 3;
break;
case 0xb2:
prach_pdu->prach_format = 4;
break;
case 0xb3:
prach_pdu->prach_format = 5;
break;
case 0xb4:
prach_pdu->prach_format = 6;
break;
case 0xc0:
prach_pdu->prach_format = 7;
break;
case 0xc2:
prach_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
break;
default:
AssertFatal(1==0,"Invalid PRACH format");
}
}
}
}
}
}
void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint16_t *msg2_frame, uint16_t *msg2_slot,
NR_ServingCellConfigCommon_t *scc,
@@ -185,7 +186,7 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
tdd_period_slot++;
// computing start of next period
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame_mac[mu];
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
@@ -217,16 +218,16 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
default:
AssertFatal(1==0,"Invalid response window value %d\n",response_window);
}
AssertFatal(slot_window<=nr_slots_per_frame_mac[mu],"Msg2 response window needs to be lower or equal to 10ms");
AssertFatal(slot_window<=nr_slots_per_frame[mu],"Msg2 response window needs to be lower or equal to 10ms");
// slot and frame limit to transmit msg2 according to response window
uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame_mac[mu];
uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
//uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
// go to previous slot if the current scheduled slot is beyond the response window
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame_mac[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
if((*msg2_slot%tdd_period_slot) > 0)
(*msg2_slot)--;
else
@@ -397,11 +398,11 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
ra->Msg3_slot = temp_slot%nr_slots_per_frame_mac[mu];
if (nr_slots_per_frame_mac[mu]>temp_slot)
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
if (nr_slots_per_frame[mu]>temp_slot)
ra->Msg3_frame = current_frame;
else
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame_mac[mu]);
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
ra->msg3_nb_rb = 18;
ra->msg3_first_rb = 0;
@@ -601,7 +602,11 @@ void nr_generate_Msg2(module_id_t module_idP,
LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
mcsIndex = 0; // Qm>2 not allowed for RAR
// Qm>2 not allowed for RAR
if (get_softmodem_params()->do_ra)
mcsIndex = 9;
else
mcsIndex = 0;
pdsch_pdu_rel15->pduBitmap = 0;
pdsch_pdu_rel15->rnti = RA_rnti;
+297 -248
View File
@@ -53,7 +53,10 @@
#include "NR_SearchSpace.h"
#include "NR_ControlResourceSet.h"
//#define UL_HARQ_PRINT
extern RAN_CONTEXT_t RC;
const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3};
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
//uint8_t mac_pdu[MAX_NR_DLSCH_PAYLOAD_BYTES];
@@ -314,7 +317,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
pdsch_pdu_rel15->qamModOrder[0] = 2;
pdsch_pdu_rel15->mcsIndex[0] = mcs;
pdsch_pdu_rel15->mcsTable[0] = 0;
pdsch_pdu_rel15->rvIndex[0] = (get_softmodem_params()->phy_test==1) ? 0 : UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round;
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round];
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
@@ -372,7 +375,7 @@ int configure_fapi_dl_pdu(int Mod_idP,
dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3;
// TPC for PUCCH
dci_pdu_rel15[0].tpc = 1; // table 7.2.1-1 in 38.213
dci_pdu_rel15[0].tpc = UE_list->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213
// PUCCH resource indicator
dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator;
// PDSCH to HARQ TI
@@ -474,7 +477,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats, int *rnti_types,
int time_domain_assignment,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id) {
switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) {
@@ -491,7 +494,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
dci_pdu_rel15->ndi = 1;
dci_pdu_rel15->rv = 0;
dci_pdu_rel15->harq_pid = 0;
dci_pdu_rel15->tpc = 2;
dci_pdu_rel15->tpc = 1;
break;
case NR_UL_DCI_FORMAT_0_1:
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
@@ -516,7 +519,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
// mcs
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
// tpc command for pusch
dci_pdu_rel15->tpc = 2; //TODO
dci_pdu_rel15->tpc = tpc;
// SRS resource indicator
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
if (*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook)
@@ -773,10 +776,41 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
}
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
void nr_schedule_uss_ulsch_phytest(int Mod_idP,
frame_t frameP,
sub_frame_t slotP) {
uint8_t hrq_id;
uint8_t max_ul_harq_pids = 3; // temp: for testing
// schedule active harq processes
NR_UE_ul_harq_t cur_harq;
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq.state==ACTIVE_NOT_SCHED) {
#ifdef UL_HARQ_PRINT
printf("[SCHED] Found ulharq id %d, scheduling it for retransmission\n",hrq_id);
#endif
return hrq_id;
}
}
// schedule new harq processes
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
if (cur_harq.state==INACTIVE) {
#ifdef UL_HARQ_PRINT
printf("[SCHED] Found new ulharq id %d, scheduling it\n",hrq_id);
#endif
return hrq_id;
}
}
LOG_E(MAC,"All UL HARQ processes are busy. Cannot schedule ULSCH\n");
return -1;
}
void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
int time_domain_assignment) {
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
@@ -796,40 +830,11 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
uint16_t rnti = UE_list->rnti[UE_id];
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
UL_tti_req->SFN = frameP;
UL_tti_req->Slot = slotP;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
UL_tti_req->n_pdus+=1;
LOG_D(MAC, "Scheduling UE specific PUSCH\n");
//UL_tti_req = &nr_mac->UL_tti_req[CC_id];
//Resource Allocation in time domain
int startSymbolAndLength=0;
int time_domain_assignment=1;
int StartSymbolIndex,NrOfSymbols,K2,mapping_type;
AssertFatal(time_domain_assignment<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count,
"time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count);
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols);
pusch_pdu->start_symbol_index = StartSymbolIndex;
pusch_pdu->nr_of_symbols = NrOfSymbols;
mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
int K2;
if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2 != NULL)
K2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2;
else {
@@ -838,225 +843,269 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP,
else K2=3;
}
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = rnti;
pusch_pdu->handle = 0; //not yet used
if (is_xlsch_in_slot(UE_list->UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap,(slotP+K2)%num_slots_per_tdd)) {
//nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
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;
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
uint16_t rnti = UE_list->rnti[UE_id];
NR_sched_pusch *pusch_sched = UE_list->UE_sched_ctrl[UE_id].sched_pusch;
pusch_sched->frame = frameP;
pusch_sched->slot = slotP + K2;
pusch_sched->active = true;
nfapi_nr_pusch_pdu_t *pusch_pdu = &pusch_sched->pusch_pdu;
memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
LOG_D(MAC, "Scheduling UE specific PUSCH\n");
//UL_tti_req = &nr_mac->UL_tti_req[CC_id];
//Resource Allocation in time domain
int startSymbolAndLength=0;
int StartSymbolIndex,NrOfSymbols,mapping_type;
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols);
pusch_pdu->start_symbol_index = StartSymbolIndex;
pusch_pdu->nr_of_symbols = NrOfSymbols;
mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = rnti;
pusch_pdu->handle = 0; //not yet used
pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_pdu->cyclic_prefix = 0;
//pusch information always include
//this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined.
pusch_pdu->mcs_index = 9;
pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
if (pusch_Config->transformPrecoder == NULL) {
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
}
else
pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder;
if (pusch_Config->dataScramblingIdentityPUSCH != NULL)
pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH;
else
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = 0;
pusch_pdu->rb_size = 50;
}
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
pusch_pdu->vrb_to_prb_mapping = 0;
if (pusch_Config->frequencyHopping==NULL)
pusch_pdu->frequency_hopping = 0;
else
pusch_pdu->frequency_hopping = 1;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
//pusch_pdu->uplink_frequency_shift_7p5khz = 0;
// --------------------
// ------- DMRS -------
// --------------------
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
else
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (NR_DMRS_UplinkConfig->dmrs_Type == NULL)
pusch_pdu->dmrs_config_type = 0;
else
pusch_pdu->dmrs_config_type = 1;
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
if (pusch_pdu->transform_precoding) { // transform precoding disabled
long *scramblingid;
if (pusch_pdu->scid == 0)
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
else
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
if (scramblingid == NULL)
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
else
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
}
else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
else
pusch_pdu->pusch_identity = *scc->physCellId;
}
pusch_dmrs_AdditionalPosition_t additional_pos;
if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL)
additional_pos = 2;
else {
if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3)
additional_pos = 3;
else
additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition;
}
pusch_maxLength_t pusch_maxLength;
if (NR_DMRS_UplinkConfig->maxLength == NULL)
pusch_maxLength = 1;
else
pusch_maxLength = 2;
uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength);
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index;
pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
pusch_pdu->dmrs_ports = 1;
// --------------------------------------------------------------------------------------------------------------------------------------------
// --------------------
// ------- PTRS -------
// --------------------
if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
// TODO to be fixed from RRC config
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
pusch_pdu->pdu_bit_map &= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
}
else{
// if(1<<pusch_pdu->pusch_ptrs.ptrs_time_density >= pusch_pdu->nr_of_symbols)
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
// --------------------------------------------------------------------------------------------------------------------------------------------
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
//Optional Data only included if indicated in pduBitmap
// TODO from harq function as in pdsch
pusch_pdu->pusch_data.rv_index = 0;
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 1;
uint8_t num_dmrs_symb = 0;
for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
uint8_t N_PRB_DMRS;
if (pusch_pdu->dmrs_config_type == 0) {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6;
}
else {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4;
}
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
N_PRB_DMRS * num_dmrs_symb,
0, //nb_rb_oh
0,
pusch_pdu->nrOfLayers)>>3;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
//pusch_pdu->pusch_uci;
//pusch_pdu->pusch_ptrs;
//pusch_pdu->dfts_ofdm;
//beamforming
//pusch_pdu->beamforming; //not used for now
ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus];
memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
int dci_formats[2];
int rnti_types[2];
NR_SearchSpace_t *ss;
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
int found=0;
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
if (ss->searchSpaceType->present == target_ss) {
found=1;
break;
pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
pusch_pdu->cyclic_prefix = 0;
//pusch information always include
//this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined.
pusch_pdu->mcs_index = 9;
pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ;
if (pusch_Config->transformPrecoder == NULL) {
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
}
}
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
else
pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder;
if (pusch_Config->dataScramblingIdentityPUSCH != NULL)
pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH;
else
pusch_pdu->data_scrambling_id = *scc->physCellId;
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
else
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
pusch_pdu->nrOfLayers = 1;
rnti_types[0] = NR_RNTI_C;
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = 0;
if (get_softmodem_params()->phy_test==1)
pusch_pdu->rb_size = 50;
else
pusch_pdu->rb_size = 5;
}
else
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
int ret = nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_list->rnti[UE_id],
1, // ue-specific,
ss,
scc,
bwp);
pusch_pdu->vrb_to_prb_mapping = 0;
if (ret < 0) {
LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n");
UL_tti_req->n_pdus-=1;
return;
}
else {
if (pusch_Config->frequencyHopping==NULL)
pusch_pdu->frequency_hopping = 0;
else
pusch_pdu->frequency_hopping = 1;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
//pusch_pdu->uplink_frequency_shift_7p5khz = 0;
// --------------------
// ------- DMRS -------
// --------------------
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
else
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
if (NR_DMRS_UplinkConfig->dmrs_Type == NULL)
pusch_pdu->dmrs_config_type = 0;
else
pusch_pdu->dmrs_config_type = 1;
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
if (pusch_pdu->transform_precoding) { // transform precoding disabled
long *scramblingid;
if (pusch_pdu->scid == 0)
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
else
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
if (scramblingid == NULL)
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
else
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
}
else {
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
else
pusch_pdu->pusch_identity = *scc->physCellId;
}
pusch_dmrs_AdditionalPosition_t additional_pos;
if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL)
additional_pos = 2;
else {
if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3)
additional_pos = 3;
else
additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition;
}
pusch_maxLength_t pusch_maxLength;
if (NR_DMRS_UplinkConfig->maxLength == NULL)
pusch_maxLength = 1;
else
pusch_maxLength = 2;
uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength);
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index;
pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
pusch_pdu->dmrs_ports = 1;
// --------------------------------------------------------------------------------------------------------------------------------------------
// --------------------
// ------- PTRS -------
// --------------------
if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
// TODO to be fixed from RRC config
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
}
else{
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
}
// --------------------------------------------------------------------------------------------------------------------------------------------
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
//Optional Data only included if indicated in pduBitmap
int8_t harq_id = select_ul_harq_pid(&UE_list->UE_sched_ctrl[UE_id]);
if (harq_id < 0) return;
NR_UE_ul_harq_t *cur_harq = &UE_list->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
pusch_pdu->pusch_data.harq_process_id = harq_id;
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
cur_harq->state = ACTIVE_SCHED;
cur_harq->last_tx_slot = pusch_sched->slot;
uint8_t num_dmrs_symb = 0;
for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
uint8_t N_PRB_DMRS;
if (pusch_pdu->dmrs_config_type == 0) {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6;
}
else {
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4;
}
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
N_PRB_DMRS * num_dmrs_symb,
0, //nb_rb_oh
0,
pusch_pdu->nrOfLayers)>>3;
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
//pusch_pdu->pusch_data.cb_present_and_position;
//pusch_pdu->pusch_uci;
//pusch_pdu->pusch_ptrs;
//pusch_pdu->dfts_ofdm;
//beamforming
//pusch_pdu->beamforming; //not used for now
ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus];
memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
UL_dci_req->numPdus+=1;
int dci_formats[2];
int rnti_types[2];
NR_SearchSpace_t *ss;
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
"searchPsacesToAddModList is empty\n");
int found=0;
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
if (ss->searchSpaceType->present == target_ss) {
found=1;
break;
}
}
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
else
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
rnti_types[0] = NR_RNTI_C;
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
int ret = nr_configure_pdcch(nr_mac,
pdcch_pdu_rel15,
UE_list->rnti[UE_id],
1, // ue-specific,
ss,
scc,
bwp);
if (ret < 0) {
LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n");
pusch_sched->active = false;
return;
}
else {
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,n_ubwp,bwp_id);
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_list->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id);
free(dci_pdu_rel15);
}
}
}
@@ -1466,6 +1466,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
0,
sizeof(NR_UE_sched_ctrl_t));
UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch));
UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(sizeof(NR_sched_pusch));
LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP,
UE_id,
@@ -1482,6 +1483,18 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
return -1;
}
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
// al values passed to this function are x10
int snrx10 = (cqi*5) - 640;
if (snrx10 > target + incr) return 0; // decrease 1dB
if (snrx10 < target - incr) return 2; // increase 1dB
if (snrx10 < target - (3*incr)) return 3; // increase 3dB
return 1; // no change
}
void get_pdsch_to_harq_feedback(int Mod_idP,
int UE_id,
NR_SearchSpace__searchSpaceType_PR ss_type,
@@ -276,6 +276,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
gNB_mac = RC.nrmac[gnb_mod_idP];
UE_list = &gNB_mac->UE_list;
int target_snrx10 = gNB_mac->pusch_target_snrx10;
if (UE_id != -1) {
UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
@@ -291,17 +292,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
ul_cqi);
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");
for (int i = 0; i < sdu_lenP ; i++) {
LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");
for (int i = 0; i < sdu_lenP ; 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 ",(unsigned char)sduP[i]);
}
printf("\n");
}
printf("\n");
#endif
if (sduP != NULL){
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
UE_scheduling_control->ta_update = timing_advance;
LOG_I(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
LOG_D(MAC, "Received PDU at MAC gNB \n");
nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP);
}
+16 -4
View File
@@ -50,6 +50,8 @@ void config_common(int Mod_idP,
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_tgt_snrx10,
int pucch_tgt_snrx10,
NR_ServingCellConfigCommon_t *scc,
int nsa_flag,
uint32_t rnti,
@@ -137,7 +139,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
dci_pdu_rel15_t *dci_pdu_rel15,
int *dci_formats, int *rnti_types,
int time_domain_assignment,
int time_domain_assignment, uint8_t tpc,
int n_ubwp, int bwp_id);
void configure_fapi_dl_Tx(module_id_t Mod_idP,
@@ -154,9 +156,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
NR_sched_pucch *pucch_sched,
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config);
void nr_schedule_uss_ulsch_phytest(int Mod_idP,
frame_t frameP,
sub_frame_t slotP);
void nr_schedule_pusch(int Mod_idP,
int UE_id,
frame_t frameP,
sub_frame_t slotP);
void nr_update_pucch_scheduling(int Mod_idP,
int UE_id,
@@ -227,6 +230,8 @@ void find_aggregation_candidates(uint8_t *aggregation_level,
uint8_t *nr_of_candidates,
NR_SearchSpace_t *ss);
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
int get_spf(nfapi_nr_config_request_scf_t *cfg);
int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot);
@@ -288,6 +293,11 @@ void nr_generate_Msg2(module_id_t module_idP,
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP);
void schedule_fapi_ul_pdu(int Mod_idP,
frame_t frameP,
sub_frame_t slotP,
int num_slots_per_tdd,
int time_domain_assignment);
void nr_process_mac_pdu(
module_id_t module_idP,
@@ -298,6 +308,8 @@ void nr_process_mac_pdu(
int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
/* \brief Function to indicate a received SDU on ULSCH.
@param Mod_id Instance ID of gNB
+3
View File
@@ -117,6 +117,9 @@ void mac_top_init_gNB(void)
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0;
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0;
UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0;
UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0;
}
}
+28
View File
@@ -253,6 +253,13 @@ typedef struct NR_sched_pucch {
uint8_t resource_indicator;
} NR_sched_pucch;
typedef struct NR_sched_pusch {
int frame;
int slot;
bool active;
nfapi_nr_pusch_pdu_t pusch_pdu;
} NR_sched_pusch;
typedef struct NR_UE_harq {
uint8_t is_waiting;
uint8_t ndi;
@@ -260,15 +267,32 @@ typedef struct NR_UE_harq {
uint16_t feedback_slot;
} NR_UE_harq_t;
typedef enum {
INACTIVE = 0,
ACTIVE_NOT_SCHED,
ACTIVE_SCHED
} NR_UL_harq_states_t;
typedef struct NR_UE_ul_harq {
uint8_t ndi;
uint8_t round;
uint16_t last_tx_slot;
NR_UL_harq_states_t state;
} NR_UE_ul_harq_t;
/*! \brief scheduling control information set through an API */
typedef struct {
uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch
uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch
NR_sched_pucch *sched_pucch;
NR_sched_pusch *sched_pusch;
uint16_t ta_timer;
int16_t ta_update;
uint8_t tpc0;
uint8_t tpc1;
uint8_t current_harq_pid;
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
int dummy;
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
} NR_UE_sched_ctrl_t;
@@ -313,6 +337,10 @@ typedef struct gNB_MAC_INST_s {
NR_TAG_t *tag;
/// Pointer to IF module instance for PHY
NR_IF_Module_t *if_inst;
/// Pusch target SNR
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
/// TA command
int ta_command;
/// MAC CE flag indicating TA length
+53 -10
View File
@@ -41,6 +41,7 @@
#include "executables/softmodem-common.h"
#define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT
NR_IF_Module_t *if_inst[MAX_IF_MODULES];
NR_Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
@@ -77,7 +78,7 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
}
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int target_snrx10) {
// TODO
int max_harq_rounds = 4; // TODO define macro
int num_ucis = UL_info->uci_ind.num_ucis;
@@ -88,22 +89,27 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
case NFAPI_NR_UCI_PDCCH_PDU_TYPE: break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
if (get_softmodem_params()->phy_test == 0) {
//if (get_softmodem_params()->phy_test == 0) {
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
// handle harq
int harq_idx_s = 0;
// tpc (power control)
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) {
// search for the right harq process
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
// if the gNB received ack with a good confidence or if the max harq rounds was reached
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
if (uci_pdu->harq->harq_list[harq_bit].harq_value == 0)
sched_ctrl->harq_processes[harq_idx].round++;
if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) ||
(sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) {
if (((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) &&
(uci_pdu->harq->harq_confidence_level == 0)) ||
(sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) {
// toggle NDI and reset round
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
sched_ctrl->harq_processes[harq_idx].round = 0;
}
else
sched_ctrl->harq_processes[harq_idx].round++;
sched_ctrl->harq_processes[harq_idx].is_waiting = 0;
harq_idx_s = harq_idx + 1;
break;
@@ -120,7 +126,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
}
}
}
}
//}
break;
}
@@ -131,8 +137,43 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
UL_info->uci_ind.num_ucis = 0;
}
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, uint8_t crc_status) {
void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
int max_harq_rounds = 4; // TODO define macro
for (uint8_t hrq_id = 0; hrq_id < NR_MAX_NB_HARQ_PROCESSES; hrq_id++) {
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
if ((cur_harq->last_tx_slot == slot-1) && cur_harq->state==ACTIVE_SCHED) {
if (!crc_status) {
cur_harq->ndi ^= 1;
cur_harq->round = 0;
cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant
#ifdef UL_HARQ_PRINT
printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id);
#endif
} else {
cur_harq->round++;
cur_harq->state = ACTIVE_NOT_SCHED;
#ifdef UL_HARQ_PRINT
printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id);
#endif
}
if (!(cur_harq->round<max_harq_rounds)) {
cur_harq->ndi ^= 1;
cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive
cur_harq->round = 0;
#ifdef UL_HARQ_PRINT
printf("[HARQ HANDLER] Ulharq id %d crc failed in all round, freeing it for scheduler\n",hrq_id);
#endif
}
return;
}
}
}
void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) {
if(nfapi_mode == 1) {
if (UL_info->crc_ind.number_crcs>0) {
//LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
@@ -159,6 +200,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) {
UL_info->rx_ind.pdu_list[i].rnti) {
LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status);
handle_nr_ul_harq(UL_info->slot, sched_ctrl, UL_info->crc_ind.crc_list[j].tb_crc_status);
if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
@@ -230,10 +273,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
// clear DL/UL info for new scheduling round
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
handle_nr_rach(UL_info);
handle_nr_uci(UL_info, &mac->UE_list.UE_sched_ctrl[0]);
handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],mac->pucch_target_snrx10);
// clear HI prior to handling ULSCH
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0]);
if (nfapi_mode != 1) {
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
+1 -8
View File
@@ -117,13 +117,6 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx);
if (mac->generate_nr_prach){
//uint16_t monitoring_slot_period, monitoring_offset;
uint16_t rach_frame = mac->scheduled_response.ul_config->sfn;
uint16_t rx_rach_frame = (rach_frame + mac->RA_offset) % MAX_FRAME_NUMBER; // compensate 2 frames offset delay at gNB side
uint16_t rach_slot = mac->scheduled_response.ul_config->slot;
nr_ue_msg2_scheduler(module_id, rx_rach_frame, rach_slot, &mac->msg2_rx_frame, &mac->msg2_rx_slot);
}
}
switch(ret){
@@ -154,7 +147,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request;
if (!dl_info->dci_ind && !dl_info->rx_ind) {
// UL indication to schedule reception DCI reception
// UL indication to schedule DCI reception
nr_ue_scheduler(dl_info, NULL);
} else {
// UL indication after reception of DCI or DL PDU
+2
View File
@@ -379,6 +379,8 @@ typedef struct {
NR_BCCH_BCH_Message_t mib;
int ssb_SubcarrierOffset;
int pdsch_AntennaPorts;
int pusch_TargetSNRx10;
int pucch_TargetSNRx10;
NR_BCCH_DL_SCH_Message_t *siblock1;
NR_ServingCellConfigCommon_t *servingcellconfigcommon;
NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS];
+4
View File
@@ -186,6 +186,8 @@ static void init_NR_SI(gNB_RRC_INST *rrc) {
rrc_mac_config_req_gNB(rrc->module_id,
rrc->carrier.ssb_SubcarrierOffset,
rrc->carrier.pdsch_AntennaPorts,
rrc->carrier.pusch_TargetSNRx10,
rrc->carrier.pucch_TargetSNRx10,
(NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon,
0,
0, // WIP hardcoded rnti
@@ -265,6 +267,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu
rrc->carrier.servingcellconfigcommon = configuration->scc;
rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset;
rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts;
rrc->carrier.pusch_TargetSNRx10 = configuration->pusch_TargetSNRx10;
rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10;
/// System Information INIT
LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt));
init_NR_SI(rrc);
+2
View File
@@ -238,6 +238,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
rrc_mac_config_req_gNB(rrc->module_id,
rrc->carrier.ssb_SubcarrierOffset,
rrc->carrier.pdsch_AntennaPorts,
rrc->carrier.pusch_TargetSNRx10,
rrc->carrier.pucch_TargetSNRx10,
NULL,
1, // add_ue flag
ue_context_p->ue_id_rnti,
+13 -9
View File
@@ -184,10 +184,12 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
bridge->channelmod,
bridge->sample_rate,
bridge->tx_bw,
30e-9, // TDL delay-spread parameter
bridge->chan_forgetfact, // forgetting_factor
bridge->chan_offset, // maybe used for TA
bridge->chan_pathloss); // path_loss in dB
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
random_channel(ptr->channel_model,false);
}
}
@@ -705,7 +707,8 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
random_channel(ptr->channel_model,0);
if (t->poll_telnetcmdq)
t->poll_telnetcmdq(t->telnetcmd_qid,t);
for (int a=0; a<nbAnt; a++) {
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
if ( ptr->channel_model != NULL ) // apply a channel model
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
a,
@@ -716,15 +719,16 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
);
else { // no channel modeling
sample_t *out=(sample_t *)samplesVoid[a];
const int64_t base=t->nextTimestamp*nbAnt+a;
for ( int i=0; i < nsamps; i++ ) {
const int idx=(i*nbAnt+base)%CirSize;
out[i].r+=ptr->circularBuf[idx].r;
out[i].i+=ptr->circularBuf[idx].i;
}
int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
//LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
for (int i=0; i < nsamps; i++) {//loop over nsamps
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++){//sum up signals from nbAnt_tx antennas
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
} // end for a_tx
} // end for i (number of samps)
} // end of no channel modeling
} // end for a...
} // end for a (number of rx antennas)
}
}
@@ -248,7 +248,9 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
#beamforming 1x4 matrix:
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
}
);
@@ -235,7 +235,7 @@ MACRLCs = (
THREAD_STRUCT = (
{
parallel_config = "PARALLEL_RU_L1_TRX_SPLITaaaaaa";
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
worker_config = "ENABLE";
}
);
@@ -23,7 +23,9 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -132,12 +134,12 @@ gNBs =
# pusch-ConfigCommon (up to 16 elements)
initialULBWPk2_0 = 2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_0 = 55;
initialULBWPk2_1 = 2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_1 = 69;
initialULBWPk2_2 = 7;
@@ -266,8 +268,8 @@ RUs = (
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
//parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
parallel_config = "PARALLEL_SINGLE_THREAD";
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
//parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
-3
View File
@@ -438,9 +438,6 @@ int restart_L1L2(module_id_t enb_id) {
}
RC.ru_mask |= (1 << ru->idx);
/* copy the changed frame parameters to the RU */
/* TODO this should be done for all RUs associated to this eNB */
memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
set_function_spec_param(RC.ru[enb_id]);
/* reset the list of connected UEs in the MAC, since in this process with
* loose all UEs (have to reconnect) */