diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7292924f87a4a80e37889bdf604b8d13d1fe1a46..49850adb712a4611a2dfed808754814335e8addb 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -829,6 +829,85 @@ class SSHConnection(): self.CreateHtmlTabFooter(False) sys.exit(1) + def InitializeOAIeNB(self): + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + #initialize_OAI_eNB_flag = True + #pStatus = self.CheckOAIeNBProcessExist(initialize_OAI_eNB_flag) + #if (pStatus < 0): + # self.CreateHtmlTestRow(self.Initialize_OAI_eNB_args, 'KO', pStatus) + # self.CreateHtmlTabFooter(False) + # sys.exit(1) + self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('cd ' + self.eNBSourceCodePath, '\$', 5) + if self.air_interface == 'lte': + nodeB_prefix = 'e' + else: + nodeB_prefix = 'g' + # Initialize_OAI_eNB_args usually start with -C and followed by the location in repository + #full_config_file = self.Initialize_OAI_eNB_args.replace('-O ','') + #extIdx = full_config_file.find('.conf') + #if (extIdx > 0): + # extra_options = full_config_file[extIdx + 5:] + # # if tracer options is on, compiling and running T Tracer + # result = re.search('T_stdout', str(extra_options)) + ## if result is not None: + # logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') + # self.command('cd common/utils/T/tracer', '\$', 5) + # self.command('make', '\$', 10) + # self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5) + # self.command('cd ' + self.eNBSourceCodePath, '\$', 5) + # full_config_file = full_config_file[:extIdx + 5] + # config_path, config_file = os.path.split(full_config_file) + #ci_full_config_file = config_path + '/ci-' + config_file + #rruCheck = False + #result = re.search('rru', str(config_file)) + #if result is not None: + # rruCheck = True + ## Make a copy and adapt to EPC / eNB IP addresses + #self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) + #self.command('sed -i -e \'s/CI_eNB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); + # Launch eNB with the modified config file + self.command('source oaienv', '\$', 5) + self.command('cd cmake_targets/ran_build/build', '\$', 5) + self.eNBLogFile = 'enb_' + self.testCase_id + '.log' + self.command('echo "ulimit -c unlimited && ./' + self.air_interface + '-softmodem ' + self.Initialize_OAI_eNB_args + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log', '\$', 5) + #use nohup instead of daemon + self.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh' + ' > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log' + ' 2>&1 &', self.eNBUserName, 5) + #self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets/ran_build/build -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + time.sleep(6) + self.command('cd ../..', '\$', 5) + doLoop = True + loopCounter = 10 + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # In case of T tracer recording, we may need to kill it + #result = re.search('T_stdout', str(self.Initialize_OAI_eNB_args)) + #if result is not None: + # self.command('killall --signal SIGKILL record', '\$', 5) + self.close() + doLoop = False + logging.error('\u001B[1;37;41m ' + nodeB_prefix + 'NB logging system did not show got sync! \u001B[0m') + self.CreateHtmlTestRow(self.Initialize_OAI_eNB_args, 'KO', ALL_PROCESSES_OK, 'OAI eNB') + self.CreateHtmlTabFooter(False) + ## In case of T tracer recording, we need to kill tshark on EPC side + #result = re.search('T_stdout', str(self.Initialize_OAI_eNB_args)) + #if result is not None: + # self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + # logging.debug('\u001B[1m Stopping tshark \u001B[0m') + # self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) + # self.close() + # time.sleep(1) + # pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap' + # copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') + # if (copyin_res == 0): + # self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + sys.exit(1) + def checkDevTTYisUnlocked(self): self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) count = 0 @@ -2737,8 +2816,25 @@ class SSHConnection(): mib_found = False frequency_found = False plmn_found = False + nrUEFlag = False + nrDecodeMib = 0 + nrFoundDCI = 0 + nrCRCOK = 0 self.htmlUEFailureMsg = '' for line in ue_log_file.readlines(): + result = re.search('nr_synchro_time', str(line)) + if result is not None: + nrUEFlag = True + if nrUEFlag: + result = re.search('decode mib', str(line)) + if result is not None: + nrDecodeMib += 1 + result = re.search('found 1 DCIs', str(line)) + if result is not None: + nrFoundDCI += 1 + result = re.search('CRC OK', str(line)) + if result is not None: + nrCRCOK += 1 result = re.search('Exiting OAI softmodem', str(line)) if result is not None: exitSignalReceived = True @@ -2857,6 +2953,19 @@ class SSHConnection(): statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' logging.debug('\033[94m' + statMsg + '\033[0m') self.htmlUEFailureMsg += statMsg + '\n' + if nrUEFlag: + if nrDecodeMib > 0: + statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if nrFoundDCI > 0: + statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if nrCRCOK > 0: + statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' if uciStatMsgCount > 0: statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -4125,4 +4234,4 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re else: Usage() sys.exit('Invalid mode') -sys.exit(0) +sys.exit(0) \ No newline at end of file diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml index f9d068c5b2e377fd369d0047b399d5775b1d13a5..12d06ac45618c5292e6bcd3ed5f7b510085afb5b 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml @@ -25,7 +25,7 @@ <htmlTabName>run OAI gNB and OAI NR UE USRP</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> -090101 000001 090102 000001 090108 090109 +090101 000001 090102 000002 090108 090109 </TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> @@ -42,6 +42,12 @@ <idle_sleep_time_in_sec>5</idle_sleep_time_in_sec> </testCase> + <testCase id="000002"> + <class>IdleSleep</class> + <desc>Waiting for NR UE to synchronize w/ gNB</desc> + <idle_sleep_time_in_sec>180</idle_sleep_time_in_sec> + </testCase> + <testCase id="090102"> <class>Initialize_OAI_UE</class> <desc>Initialize NR UE USRP</desc> diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 7c1c9af29cadd684aa9c80451930a3a706e6bffc..d890570171a33678ce2dc6c613f9d9889b95339b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1410,7 +1410,7 @@ set(PHY_SRC_UE ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} ${PHY_LDPCSRC} - ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c # added by prasanth + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/pucch_rx.c ) set(PHY_NR_UE_SRC diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 929831fc23e6ce45bf956c5a64193a2c3615b69f..ba4ebf6e3a414ff072c6fd96ffd6dba576e9e3eb 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1160,6 +1160,29 @@ <nruns>3</nruns> </testCase> + <testCase id="015109"> + <class>execution</class> + <desc>nr_nr_pucchsim Test cases. (Test1: Format 0 ACK miss 106 PRB), + (Test2: Format 1 ACK miss 106 PRB), + (Test3: Format 1 ACK miss 273 PRB), + (Test4: Format 1 NACKtoACK 106 PRB)</desc> + <pre_compile_prog></pre_compile_prog> + <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> + <compile_prog_args> --phy_simulators -c </compile_prog_args> + <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> + <pre_exec_args></pre_exec_args> + <main_exec> $OPENAIR_DIR/targets/bin/nr_pucchsim.Rel15</main_exec> + <main_exec_args>-R 106 -i 1 -P 0 -b 1 -s3 -n100 + -R 106 -i 14 -P 1 -b 1 -s-6 -n 100 + -R 273 -i 14 -P 1 -b 1 -s-6 -n100 + -R 106 -i 14 -P 1 -b 1 -s-6 -T 0.001 -n1000</main_exec_args> + <tags>nr_pucchsim.test1 nr_pucchsim.test2 nr_pucchsim.test3 nr_pucchsim.test4</tags> + <search_expr_true>PUCCH test OK</search_expr_true> + <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> + <nruns>3</nruns> + </testCase> + + <testCase id="015110"> <class>execution</class> <desc>dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ed9744b5ae6f34cf2b8917e8d89e5a8474524ff0..d51c8049b6882d30f3566dcc5bdedc3d7531a3b0 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1080,10 +1080,18 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->rx_bw = 40e6; } } else if(N_RB == 106) { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; + if (fp->threequarter_fs) { + cfg->sample_rate=46.08e6; + cfg->samples_per_frame = 460800; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } + else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 20e6; + cfg->rx_bw = 20e6; + } } else { AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); } @@ -1212,16 +1220,17 @@ static void *ru_thread_tx( void *param ) { int i = 0; int ret; - - if(ru->if_south == LOCAL_RF) - { - //uhd_set_thread_prio(); - LOG_I(PHY,"set ru_thread_tx uhd priority"); - } wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); printf( "ru_thread_tx ready\n"); + + if(ru->rfdevice.uhd_set_thread_priority != NULL) + { + LOG_I(PHY,"set ru_thread_tx uhd priority \n"); + ru->rfdevice.uhd_set_thread_priority(); + } + while (!oai_exit) { if (oai_exit) break; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 63f588519c621bcf98d57d916444abaa7dba2dc2..7c28d887bfcfc5a026aed2cd9f4181084074dd26 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -631,8 +631,9 @@ void *UE_thread(void *arg) { processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush); curMsg->UE=UE; // update thread index for received subframe - curMsg->proc.nr_tti_rx= slot_nr; curMsg->UE->current_thread_id[slot_nr] = thread_idx; + curMsg->proc.CC_id = 0; + curMsg->proc.nr_tti_rx= slot_nr; curMsg->proc.subframe_rx=table_sf_slot[slot_nr]; curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index be4782fec83a4e989208754f97029716105f56b7..ef7766de36eeb1c22bbd1610a615029a4bad0686 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -555,8 +555,27 @@ void init_openair0(void) { for (card=0; card<MAX_CARDS; card++) { openair0_cfg[card].configFilename = NULL; + openair0_cfg[card].threequarter_fs = frame_parms[0]->threequarter_fs; - if(frame_parms[0]->N_RB_DL == 106) { + if(frame_parms[0]->N_RB_DL == 217) { + if (numerology==1) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=92.16e6; + openair0_cfg[card].samples_per_frame = 921600; + openair0_cfg[card].tx_bw = 40e6; + openair0_cfg[card].rx_bw = 40e6; + } + else { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 1228800; + openair0_cfg[card].tx_bw = 40e6; + openair0_cfg[card].rx_bw = 40e6; + } + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + }else if(frame_parms[0]->N_RB_DL == 106) { if (numerology==0) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; @@ -569,14 +588,22 @@ void init_openair0(void) { openair0_cfg[card].tx_bw = 10e6; openair0_cfg[card].rx_bw = 10e6; } - } else if (numerology==1) { - openair0_cfg[card].sample_rate=61.44e6; - openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; + } else if (numerology==1) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=46.08e6; + openair0_cfg[card].samples_per_frame = 480800; + openair0_cfg[card].tx_bw = 20e6; + openair0_cfg[card].rx_bw = 20e6; + } + else { + openair0_cfg[card].sample_rate=61.44e6; + openair0_cfg[card].samples_per_frame = 614400; + openair0_cfg[card].tx_bw = 20e6; + openair0_cfg[card].rx_bw = 20e6; + } } else if (numerology==2) { openair0_cfg[card].sample_rate=122.88e6; - openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].samples_per_frame = 1228800; openair0_cfg[card].tx_bw = 40e6; openair0_cfg[card].rx_bw = 40e6; } else { @@ -599,6 +626,10 @@ void init_openair0(void) { openair0_cfg[card].tx_bw = 1.5e6; openair0_cfg[card].rx_bw = 1.5e6; } + else { + LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); + exit(-1); + } if (frame_parms[0]->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; @@ -711,6 +742,7 @@ int main( int argc, char **argv ) { frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + frame_parms[CC_id]->threequarter_fs = threequarter_fs; LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band, &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type); } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index b93f6be2502943d66f34851043319b6c657cb2ae..c00fef592994b2b0065e534ea359889905769d82 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -89,6 +89,10 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, dft = dft2048; break; + case 3072: + dft = dft3072; + break; + case 4096: dft = dft4096; break; @@ -98,8 +102,8 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, break; default: - dft = dft512; - break; + printf("unsupported ofdm symbol size \n"); + assert(0); } if (no_prefix) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index ead8e3cda5757eea1ee3cb71fc54b32af3f88a51..bb114fa3900c6017b1caf00d3f30f7c33bc8b194 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -239,7 +239,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, uint8_t nushift; uint32_t unscrambling_mask; uint64_t a_reversed=0; - LOG_I(PHY, "PBCH generation started\n"); + LOG_D(PHY, "PBCH generation started\n"); ///Payload generation memset((void *)pbch, 0, sizeof(NR_gNB_PBCH)); pbch->pbch_a=0; @@ -267,7 +267,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, else pbch->pbch_a |= ((config->sch_config.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) - LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); + LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); // Payload interleaving diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 3513c198cbc87325556560cea23beffc1c9d3687..b74b078dfd6ffcd63faa97b59314335405e0f546 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -21,7 +21,7 @@ void nr_decode_pucch0( int32_t **rxdataF, pucch_GroupHopping_t pucch_GroupHopping, uint32_t n_id, // hoppingID higher layer parameter - uint8_t *payload, + uint64_t *payload, NR_DL_FRAME_PARMS *frame_parms, int16_t amp, int nr_tti_tx, @@ -86,7 +86,7 @@ void nr_decode_pucch0( int32_t **rxdataF, // if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1; nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value alpha = nr_cyclic_shift_hopping(n_id,m0,mcs[i],l,startingSymbolIndex,nr_tti_tx); - #ifdef DEBUG_NR_PUCCH_TX + #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); #endif for (n=0; n<12; n++){ @@ -94,7 +94,7 @@ void nr_decode_pucch0( int32_t **rxdataF, - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)))>>15); // Re part of base sequence shifted by alpha x_n_im[i][(12*l)+n] =(int16_t)((int32_t)(amp)* (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)))>>15); // Im part of base sequence shifted by alpha - #ifdef DEBUG_NR_PUCCH_TX + #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); #endif @@ -129,7 +129,7 @@ void nr_decode_pucch0( int32_t **rxdataF, } r_re[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[0]; r_im[(12*l)+n]=((int16_t *)&rxdataF[0][re_offset])[1]; - #ifdef DEBUG_NR_PUCCH_TX + #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, l,n,((int16_t *)&rxdataF[0][re_offset])[0],((int16_t *)&rxdataF[0][re_offset])[1]); @@ -158,6 +158,486 @@ void nr_decode_pucch0( int32_t **rxdataF, max_corr=corr[i]; } } - *payload=(uint8_t)index; // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits + *payload=(uint64_t)index; // payload bits 00..b3b2b0, b0 is the SR bit and b3b2 are HARQ bits +} + + + + + +void nr_decode_pucch1( int32_t **rxdataF, + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter + uint64_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit) { +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); +#endif + /* + * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation + * + */ + // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): + int16_t d_re=0, d_im=0,d1_re=0,d1_im=0; +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); +#endif + /* + * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + */ + // alpha is cyclic shift + double alpha; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission + //uint8_t lnormal = 0 ; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] + uint8_t lprime = startingSymbolIndex; + // mcs = 0 except for PUCCH format 0 + uint8_t mcs=0; + // r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by d(0) + // r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS. + int16_t r_u_v_alpha_delta_re[12],r_u_v_alpha_delta_im[12],r_u_v_alpha_delta_dmrs_re[12],r_u_v_alpha_delta_dmrs_im[12]; + /* + * in TS 38.213 Subclause 9.2.1 it is said that: + * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift + * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift + */ + /* + * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) + */ + // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u=0,v=0;//,delta=0; + // if frequency hopping is disabled, intraSlotFrequencyHopping is not provided + // n_hop = 0 + // if frequency hopping is enabled, intraSlotFrequencyHopping is provided + // n_hop = 0 for first hop + // n_hop = 1 for second hop + uint8_t n_hop = 0; + // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, + // regardless of whether the frequency-hop distance is zero or not, + // otherwise no intra-slot frequency hopping shall be assumed + //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers + uint8_t intraSlotFrequencyHopping = 0; + + if (startingPRB != startingPRB_intraSlotHopping) { + intraSlotFrequencyHopping=1; + } + +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping); +#endif + /* + * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources + */ + //int32_t *txptr; + uint32_t re_offset=0; + int i=0; +#define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n + int16_t z_re_rx[MAX_SIZE_Z],z_im_rx[MAX_SIZE_Z],z_re_temp,z_im_temp; + int16_t z_dmrs_re_rx[MAX_SIZE_Z],z_dmrs_im_rx[MAX_SIZE_Z],z_dmrs_re_temp,z_dmrs_im_temp; + memset(z_re_rx,0,MAX_SIZE_Z*sizeof(int16_t)); + memset(z_im_rx,0,MAX_SIZE_Z*sizeof(int16_t)); + memset(z_dmrs_re_rx,0,MAX_SIZE_Z*sizeof(int16_t)); + memset(z_dmrs_im_rx,0,MAX_SIZE_Z*sizeof(int16_t)); + int l=0; + for(l=0;l<nrofSymbols;l++){ //extracting data and dmrs from rxdataF + if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB + startingPRB = startingPRB + startingPRB_intraSlotHopping; + } + + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + + if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); + } + + if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + + if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; + } + + if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + } + + //txptr = &txdataF[0][re_offset]; + for (int n=0; n<12; n++) { + if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) + re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + } + + if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 + z_re_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[0]; + z_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1]; +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); +#endif + } + + if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 + z_dmrs_re_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[0]; + z_dmrs_im_rx[i+n] = ((int16_t *)&rxdataF[0][re_offset])[1]; +// printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]); +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, + l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); +#endif +// printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]); + } + + re_offset++; + } + if (l%2 == 1) i+=12; + } + int16_t y_n_re[12],y_n_im[12],y1_n_re[12],y1_n_im[12]; + memset(y_n_re,0,12*sizeof(int16_t)); + memset(y_n_im,0,12*sizeof(int16_t)); + memset(y1_n_re,0,12*sizeof(int16_t)); + memset(y1_n_im,0,12*sizeof(int16_t)); + //generating transmitted sequence and dmrs + for (l=0; l<nrofSymbols; l++) { +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n", + l,lprime); +#endif + // y_n contains the complex value d multiplied by the sequence r_u_v + if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop + +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", + n_hop,nr_tti_tx); +#endif + nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(n_id,m0,mcs,l,lprime,nr_tti_tx); + + for (int n=0; n<12; n++) { // generating low papr sequences + if(l%2==1){ + r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha + r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha + } + else{ + r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) + - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha + r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) + + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha + r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15); + r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15); + } +// printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]); + // PUCCH sequence = DM-RS sequence multiplied by d(0) +/* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) + - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) + y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) + + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */ +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", + u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); +#endif + } + /* + * The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + * The block of complex-valued symbols r_u_v_alpha_dmrs_delta(n) for DM-RS shall be block-wise spread with the orthogonal sequence wi(m) + * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) + * z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) + * + */ + // the orthogonal sequence index for wi(m) defined in TS 38.213 Subclause 9.2.1 + // the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211] + // and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC + // In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field + uint8_t w_index = timeDomainOCC; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime_PUCCH_DMRS_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_1; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + uint8_t N_SF_mprime0_PUCCH_DMRS_1; + // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping + uint8_t mprime = 0; + + if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping disabled\n", + intraSlotFrequencyHopping); +#endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", + w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); +#endif + if(l%2==1){ + for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { + if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){ + for (int n=0; n<12 ; n++) { + z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_re_temp; + z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_im_temp; +// printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#endif + // multiplying with conjugate of low papr sequence + z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; + z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; +/* if(z_re_temp<0){ + printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)); + } + printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */ + } + } + } + } + + else{ + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { + if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){ + for (int n=0; n<12 ; n++) { + z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; + z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; +// printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#endif + //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays + z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); +/* if(z_dmrs_re_temp<0){ + printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)); + }*/ + z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; + z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; +// printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n]; + z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */ + } + } + } + } + } + + if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping enabled\n", + intraSlotFrequencyHopping); +#endif + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", + w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); +#endif + + for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1} + if(l%2==1){ + for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { + if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){ + for (int n=0; n<12 ; n++) { + z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; + z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#endif + z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) + - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); + z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; + z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; + } + } + } + } + + else{ + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { + if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){ + for (int n=0; n<12 ; n++) { + z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; + z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; +#ifdef DEBUG_NR_PUCCH_RX + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#endif + //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays + z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) + - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); + z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; + z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; + + /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n]; + z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */ + } + } + } + } + + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) + } + } + } + int16_t H_re[12],H_im[12],H1_re[12],H1_im[12]; + memset(H_re,0,12*sizeof(int16_t)); + memset(H_im,0,12*sizeof(int16_t)); + memset(H1_re,0,12*sizeof(int16_t)); + memset(H1_im,0,12*sizeof(int16_t)); + //averaging channel coefficients + for(l=0;l<=ceil(nrofSymbols/2);l++){ + if(intraSlotFrequencyHopping==0){ + for(int n=0;n<12;n++){ + H_re[n]=round(z_dmrs_re_rx[l*12+n]/ceil(nrofSymbols/2))+H_re[n]; + H_im[n]=round(z_dmrs_im_rx[l*12+n]/ceil(nrofSymbols/2))+H_im[n]; + } + } + else{ + if(l<round(nrofSymbols/4)){ + for(int n=0;n<12;n++){ + H_re[n]=round(z_dmrs_re_rx[l*12+n]/round(nrofSymbols/4))+H_re[n]; + H_im[n]=round(z_dmrs_im_rx[l*12+n]/round(nrofSymbols/4))+H_im[n]; + } + } + else{ + for(int n=0;n<12;n++){ + H1_re[n]=round(z_dmrs_re_rx[l*12+n]/(ceil(nrofSymbols/2)-round(nrofSymbols/4)))+H1_re[n]; + H1_im[n]=round(z_dmrs_im_rx[l*12+n]/(ceil(nrofSymbols/2))-round(nrofSymbols/4))+H1_im[n]; + } + } + } + } + //averaging information sequences + for(l=0;l<floor(nrofSymbols/2);l++){ + if(intraSlotFrequencyHopping==0){ + for(int n=0;n<12;n++){ + y_n_re[n]=round(z_re_rx[l*12+n]/floor(nrofSymbols/2))+y_n_re[n]; + y_n_im[n]=round(z_im_rx[l*12+n]/floor(nrofSymbols/2))+y_n_im[n]; + } + } + else{ + if(l<floor(nrofSymbols/4)){ + for(int n=0;n<12;n++){ + y_n_re[n]=round(z_re_rx[l*12+n]/floor(nrofSymbols/4))+y_n_re[n]; + y_n_im[n]=round(z_im_rx[l*12+n]/floor(nrofSymbols/4))+y_n_im[n]; + } + } + else{ + for(int n=0;n<12;n++){ + y1_n_re[n]=round(z_re_rx[l*12+n]/round(nrofSymbols/4))+y1_n_re[n]; + y1_n_im[n]=round(z_im_rx[l*12+n]/round(nrofSymbols/4))+y1_n_im[n]; + } + } + } + } + // mrc combining to obtain z_re and z_im + if(intraSlotFrequencyHopping==0){ + for(int n=0;n<12;n++){ + d_re = round(((int16_t)(((((int32_t)(H_re[n])*y_n_re[n])>>15) + (((int32_t)(H_im[n])*y_n_im[n])>>15))>>1))/12)+d_re; + d_im = round(((int16_t)(((((int32_t)(H_re[n])*y_n_im[n])>>15) - (((int32_t)(H_im[n])*y_n_re[n])>>15))>>1))/12)+d_im; + } + } + else{ + for(int n=0;n<12;n++){ + d_re = round(((int16_t)(((((int32_t)(H_re[n])*y_n_re[n])>>15) + (((int32_t)(H_im[n])*y_n_im[n])>>15))>>1))/12)+d_re; + d_im = round(((int16_t)(((((int32_t)(H_re[n])*y_n_im[n])>>15) - (((int32_t)(H_im[n])*y_n_re[n])>>15))>>1))/12)+d_im; + d1_re = round(((int16_t)(((((int32_t)(H1_re[n])*y1_n_re[n])>>15) + (((int32_t)(H1_im[n])*y1_n_im[n])>>15))>>1))/12)+d1_re; + d1_im = round(((int16_t)(((((int32_t)(H1_re[n])*y1_n_im[n])>>15) - (((int32_t)(H1_im[n])*y1_n_re[n])>>15))>>1))/12)+d1_im; + } + d_re=round(d_re/2); + d_im=round(d_im/2); + d1_re=round(d1_re/2); + d1_im=round(d1_im/2); + d_re=d_re+d1_re; + d_im=d_im+d1_im; + } + //Decoding QPSK or BPSK symbols to obtain payload bits + if(nr_bit==1){ + if((d_re+d_im)>0){ + *payload=0; + } + else{ + *payload=1; + } + } + else if(nr_bit==2){ + if((d_re>0)&&(d_im>0)){ + *payload=0; + } + else if((d_re<0)&&(d_im>0)){ + *payload=1; + } + else if((d_re>0)&&(d_im<0)){ + *payload=2; + } + else{ + *payload=3; + } + } } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 1728d93b695930ab280c2216b0502e465d41b4dd..6df9e0c20e32dbedf075b250dc0256e194857c94 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -98,7 +98,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -113,7 +114,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; current_ssb->c_re +=ch[0]; @@ -124,7 +126,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) { @@ -135,7 +138,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -149,7 +153,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -163,7 +168,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]); #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -178,7 +184,8 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, #endif pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; } @@ -303,7 +310,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; //for (int i= 0; i<8; i++) @@ -321,7 +329,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -336,7 +345,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; @@ -348,7 +358,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) if (dmrss == 1 && pilot_cnt == 12) { pilot_cnt=48; - re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch += 288; } @@ -367,7 +378,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i)); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -382,7 +394,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; @@ -398,7 +411,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 16); pil+=2; - re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)]; dl_ch+=24; @@ -611,9 +625,17 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, idft = idft2048; break; - default: - idft = idft512; + case 3072: + idft = idft3072; + break; + + case 4096: + idft = idft4096; break; + + default: + printf("unsupported ofdm symbol size \n"); + assert(0); } if( (Ns== 1) && (symbol == 0)) @@ -623,7 +645,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) { if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx]) { - LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); + LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol); idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx][0], (int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1); } @@ -734,7 +756,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //for (int i= 0; i<8; i++) //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); @@ -749,7 +772,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; //printf("dl_ch addr %p\n",dl_ch); @@ -767,7 +791,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -787,7 +812,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -800,7 +826,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; @@ -821,7 +848,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i)); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -836,7 +864,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); pil+=2; - re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + //re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1); + re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2); rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; dl_ch+=8; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 641b27b081abd6a3e1b6fe478dfed7696e81b267..cac9ae92ac7dcc819fa2e5021d3fbf055743501f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -103,8 +103,9 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); - } + //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); + rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); + } rxF_ext+=9; } else { //symbol 2 @@ -125,11 +126,12 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); + //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); + rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); } rxF_ext+=9; - } else rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1); + } else rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 12) : (rx_offset+12);//rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index a88095986478a2becf0a723001f99d58d44e4c08..c9fb3007063a5b48d7adf66c03e9bec50d446f0a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -89,6 +89,10 @@ void *get_idft(int ofdm_symbol_size) idft = idft2048; break; + case 3072: + idft = idft3072; + break; + case 4096: idft = idft4096; break; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 2771874bd3f66d83f7c88bbfdf479afcc676a576..e838b4b7476d29e95036b7ddf6d376e7aeff5004 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -195,7 +195,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, int16_t amp, int nr_tti_tx, uint8_t m0, - uint8_t mcs, + uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB) { @@ -366,7 +366,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); } } - +// printf("d_re=%d\td_im=%d\n",(int)d_re,(int)d_im); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); #endif @@ -451,11 +451,13 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15); r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15); +// printf("symbol=%d\tr_u_v_re=%d\tr_u_v_im=%d\n",l,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n]); // PUCCH sequence = DM-RS sequence multiplied by d(0) y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) +// printf("symbol=%d\tr_u_v_dmrs_re=%d\tr_u_v_dmrs_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n],r_u_v_alpha_delta_dmrs_im[n]); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); @@ -520,10 +522,10 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { for (int n=0; n<12 ; n++) { - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, @@ -531,7 +533,8 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); #endif - } +// printf("gNB entering l=%d\tdmrs_re=%d\tdmrs_im=%d\n",l,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n],z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n]); + } } } @@ -549,43 +552,41 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); #endif - for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { - for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1} - for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { - for (int n=0; n<12 ; n++) { - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); -#ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - } + for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1} + for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { + for (int n=0; n<12 ; n++) { + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); + z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); +#ifdef DEBUG_NR_PUCCH_TX + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], + z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); +#endif } + } - for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { - for (int n=0; n<12 ; n++) { - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); + for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { + for (int n=0; n<12 ; n++) { + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) + - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); + z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) + + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", + mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], + table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], + z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); #endif - } } - - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) - N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) } + + N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) } } @@ -638,8 +639,9 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); #endif +// printf("gNb l=%d\ti=%d\treoffset=%d\tre=%d\tim=%d\n",l,i,re_offset,z_dmrs_re[i+n],z_dmrs_im[i+n]); } - + re_offset++; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h index bc7bfad82bbac7950804963deaef347a40b6002a..e8cd147526be502ba16ab3e0e88e9c490e1c43b9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -42,10 +42,25 @@ #include "T.h" #define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) +void nr_decode_pucch1( int32_t **rxdataF, + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter + uint64_t *payload, + NR_DL_FRAME_PARMS *frame_parms, + int16_t amp, + int nr_tti_tx, + uint8_t m0, + uint8_t nrofSymbols, + uint8_t startingSymbolIndex, + uint16_t startingPRB, + uint16_t startingPRB_intraSlotHopping, + uint8_t timeDomainOCC, + uint8_t nr_bit); + void nr_decode_pucch0( int32_t **rxdataF, pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, //PHY_VARS_gNB *gNB, generally rxdataf is in gNB->common_vars - uint8_t *payload, + uint64_t *payload, NR_DL_FRAME_PARMS *frame_parms, int16_t amp, int nr_tti_tx, @@ -74,7 +89,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, int16_t amp, int nr_tti_tx, uint8_t m0, - uint8_t mcs, + uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 2dea7c1deda3433909ce95dba5ec6c3c1640859c..2c96f33495b0e9a3033ef36b8f849c404ab80189 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -83,65 +83,58 @@ PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}}; int main(int argc, char **argv) { - char c; - int i; + int i,aa=0;//,l; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double cfo=0; uint8_t snr1set=0; int **txdata; double **s_re,**s_im,**r_re,**r_im; - // int sync_pos, sync_pos_slot; - // FILE *rx_frame_file; + //int sync_pos, sync_pos_slot; + //FILE *rx_frame_file; FILE *output_fd = NULL; //uint8_t write_output_file=0; //int result; //int freq_offset; //int subframe_offset; //char fname[40], vname[40]; - int trial,n_trials=1,n_errors=0; + int trial,n_trials=100,n_errors=0,ack_nack_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; - - //uint8_t extended_prefix_flag=0; - //int8_t interf1=-21,interf2=-21; - - FILE *input_fd=NULL,*pbch_file_fd=NULL; - - //uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; - //char input_val_str[50],input_val_str2[50]; - //uint8_t frame_mod4,num_pdcch_symbols = 0; - //double pbch_sinr; - //int pbch_tx_ant; - + int format=0; + uint8_t extended_prefix_flag=0; + FILE *input_fd=NULL; + uint8_t nacktoack_flag=0; + int16_t amp=0x7FFF; + int nr_tti_tx=0; + uint64_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 for pucch format 0 + int nr_bit=1; // maximum value possible is 2 + uint8_t m0=0;// higher layer paramater initial cyclic shift + uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 + uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided + uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided + uint8_t timeDomainOCC=0; SCM_t channel_model=AWGN;//Rayleigh1_anticorr; - - + int N_RB_DL=273,mu=1; - - //unsigned char frame_type = 0; - unsigned char pbch_phase = 0; - - //int frame=0,subframe=0; + float target_error_rate=0.01; int frame_length_complex_samples; - //int frame_length_complex_samples_no_prefix; + int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; - //nfapi_nr_config_request_t *gNB_config; - + unsigned char frame_type = 0; int loglvl=OAILOG_WARNING; cpuf = get_cpu_freq_GHz(); - if ( load_configmodule(argc,argv,0) == 0) { + if ( load_configmodule(argc,argv) == 0) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } randominit(0); - while ((c = getopt (argc, argv, "f:hA:f:g:n:o:s:S:t:x:y:z:N:F:GR:P:IL:")) != -1) { + while ((c = getopt (argc, argv, "f:hA:pf:g:i:P:b:T:n:o:s:S:t:x:y:z:N:F:GR:d:IL")) != -1) { switch (c) { case 'f': //write_output_file=1; @@ -151,12 +144,11 @@ int main(int argc, char **argv) printf("Error opening %s\n",optarg); exit(-1); } - break; - /*case 'd': + case 'd': frame_type = 1; - break;*/ + break; case 'g': switch((char)*optarg) { @@ -192,17 +184,8 @@ int main(int argc, char **argv) msg("Unsupported channel model!\n"); exit(-1); } - - break; - - /*case 'i': - interf1=atoi(optarg); break; - case 'j': - interf2=atoi(optarg); - break;*/ - case 'n': n_trials = atoi(optarg); break; @@ -227,12 +210,12 @@ int main(int argc, char **argv) case 't': Td= atof(optarg); break; - + */ case 'p': extended_prefix_flag=1; break; - + /* case 'r': ricean_factor = pow(10,-.1*atof(optarg)); if (ricean_factor>1) { @@ -250,7 +233,6 @@ int main(int argc, char **argv) msg("Unsupported transmission mode %d\n",transmission_mode); exit(-1); } - break; case 'y': @@ -260,7 +242,6 @@ int main(int argc, char **argv) msg("Unsupported number of tx antennas %d\n",n_tx); exit(-1); } - break; case 'z': @@ -270,7 +251,6 @@ int main(int argc, char **argv) msg("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } - break; case 'N': @@ -288,25 +268,27 @@ int main(int argc, char **argv) printf("Problem with filename %s\n",optarg); exit(-1); } - - break; - - case 'P': - pbch_phase = atoi(optarg); - - if (pbch_phase>3) - printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); - break; case 'L': loglvl = atoi(optarg); break; - + case 'i': + nrofSymbols=(uint8_t)atoi(optarg); + break; + case 'P': + format=atoi(optarg); + break; + case 'b': + nr_bit=atoi(optarg); + break; + case 'T': + nacktoack_flag=(uint8_t)atoi(optarg); + target_error_rate=0.001; + break; default: case 'h': - printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", - argv[0]); + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]); printf("-h This message\n"); printf("-p Use extended prefix mode\n"); printf("-d Use TDD\n"); @@ -325,20 +307,22 @@ int main(int argc, char **argv) printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); printf("-f Output filename (.txt format) for Pe/SNR results\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); + printf("-i Enter number of ofdm symbols for pucch\n"); + printf("-P Enter the format of PUCCH\n"); + printf("-b number of HARQ bits (1-2)\n"); + printf("-T to check nacktoack miss for format 1"); exit (-1); break; } - } - + } logInit(); set_glog(loglvl); T_stdout = 1; - if (snr1set==0) - snr1 = snr0+10; + if (snr1set==0) snr1 = snr0+10; printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); @@ -346,7 +330,6 @@ int main(int argc, char **argv) RC.gNB[0] = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); gNB = RC.gNB[0][0]; - //gNB_config = &gNB->gNB_config; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; @@ -395,14 +378,7 @@ 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); + gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, 0, 0, 0); if (gNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); @@ -410,7 +386,7 @@ int main(int argc, char **argv) } frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; s_re = malloc(2*sizeof(double*)); s_im = malloc(2*sizeof(double*)); @@ -435,9 +411,6 @@ int main(int argc, char **argv) bzero(r_re[i],frame_length_complex_samples*sizeof(int)); } - if (pbch_file_fd!=NULL) { - load_pbch_desc(pbch_file_fd); - } //configure UE @@ -455,64 +428,91 @@ int main(int argc, char **argv) printf("Error at UE NR initialisation\n"); exit(-1); } - int16_t amp=0x1FFF; - int nr_tti_tx=0; //According to standards it is Slot number within a frame for subcarrier spacing configuration μ but not sure why he made the variable name so 4.3.2,38.211 - nr_gold_pbch(UE); - // generate signal -// pucch_config_common_nr should assign values for this if not done before structure in ue being used by functions - uint8_t actual_payload=0,payload_received;//payload bits b7b6...b2b1b0 where b7..b3=0 b2b1=HARQ b0 is SR. payload maximum value is 7 - uint8_t mcs; - int nr_bit=1; // maximum value possible is 2 -/*if(nr_bit==1){ - mcs=table1_mcs[actual_payload]; - } - else{ - mcs=table2_mcs[actual_payload]; - }*/ - uint8_t m0=0;// higher layer paramater initial cyclic shift - uint8_t nrofSymbols=1; //number of OFDM symbols can be 1-2 for format 1 - uint8_t startingSymbolIndex=0; // resource allocated see 9.2.1, 38.213 for more info.should be actually present in the resource set provided - uint16_t startingPRB=5; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided + uint8_t mcs=0; + startingPRB_intraSlotHopping=N_RB_DL-1; pucch_GroupHopping_t PUCCH_GroupHopping=UE->pucch_config_common_nr->pucch_GroupHopping; uint32_t n_id=UE->pucch_config_common_nr->hoppingId; - printf("\nsnr1=%f\n",snr1); + if((format!=0) && (format!=1)){ + printf("format not supported\n"); + exit(0); + } + if(nacktoack_flag==0){ + if(format==0){ + if(nr_bit==1){ + actual_payload=2; + mcs=table1_mcs[actual_payload]; + } + else if(nr_bit==2){ + actual_payload=6; + mcs=table2_mcs[actual_payload]; + } + else{ + printf("Number of HARQ bits possible is 1-2\n"); + exit(0); + } + } + else { + if(nr_bit==1) + actual_payload=1; + else if(nr_bit==2) + actual_payload=3; + else{ + printf("number of bits carried by PUCCH format1 is 1-2\n"); + } + } + } for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ + ack_nack_errors=0; n_errors = 0; sigma2_dB = 20*log10((double)amp/32767)-SNR; sigma2 = pow(10,sigma2_dB/10); - printf("entering SNR value %f\n",SNR); for (trial=0; trial<n_trials; trial++) { bzero(txdata[0],frame_length_complex_samples*sizeof(int)); - actual_payload=trial%4; - if(nr_bit==1){ - mcs=table1_mcs[actual_payload]; + if(format==0){ + nr_generate_pucch0(UE,txdata,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); } else{ - mcs=table2_mcs[actual_payload]; - } - nr_generate_pucch0(UE,txdata,frame_parms,UE->pucch_config_dedicated,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); - - for (i=0; i<frame_length_complex_samples; i++) { - r_re[0][i]=((double)(((int16_t *)txdata[0])[(i<<1)])/32767 + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - r_im[0][i]=((double)(((int16_t *)txdata[0])[(i<<1)+1])/32767 + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - if(r_re[0][i]<-1) - r_re[0][i]=-1; - else if(r_re[0][i]>1) - r_re[0][i]=1; - if(r_im[0][i]<-1) - r_im[0][i]=-1; - else if(r_im[0][i]>1) - r_im[0][0]=1; - ((int16_t *)txdata[0])[(i<<1)] = (int16_t)round(r_re[0][i]*32767); - ((int16_t *)txdata[0])[(i<<1)+1] =(int16_t)round(r_im[0][i]*32767); - + nr_generate_pucch1(UE,txdata,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); + } + for(i=0; i<frame_length_complex_samples; i++) { + r_re[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)])/32767 + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + r_im[aa][i]=((double)(((int16_t *)txdata[0])[(i<<1)+1])/32767+ sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + r_re[aa][i]=r_re[0][i]/(sqrt(sigma2/2)+1); + r_im[aa][i]=r_im[0][i]/(sqrt(sigma2/2)+1); + if(r_re[aa][i]<-1) + r_re[aa][i]=-1; + else if(r_re[aa][i]>1) + r_re[aa][i]=1; + if(r_im[aa][i]<-1) + r_im[aa][i]=-1; + else if(r_im[aa][i]>1) + r_im[aa][i]=1; + ((int16_t *)txdata[aa])[(i<<1)] = (int16_t)round(r_re[aa][i]*32767); + ((int16_t *)txdata[aa])[(i<<1)+1] =(int16_t)round(r_im[aa][i]*32767); + } + if(format==0){ + nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit); + if(nr_bit==1) + ack_nack_errors+=(((actual_payload^payload_received)&2)>>1); + else + ack_nack_errors+=(((actual_payload^payload_received)&2)>>1) + (((actual_payload^payload_received)&4)>>2); + } + else{ + nr_decode_pucch1(txdata,PUCCH_GroupHopping,n_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 + ack_nack_errors+=((actual_payload^payload_received)&1) + (((actual_payload^payload_received)&2)>>1); } - nr_decode_pucch0(txdata,PUCCH_GroupHopping,n_id,&(payload_received),frame_parms,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,nr_bit); n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; - //printf("actual_payload=%x,payload_received=%x",actual_payload,payload_received); } printf("SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,n_errors); + if((float)ack_nack_errors/(float)(nr_bit*n_trials)<=target_error_rate){ + printf("PUCCH test OK\n"); + break; + } } + for (i=0; i<2; i++) { free(s_re[i]); free(s_im[i]); @@ -520,19 +520,14 @@ int main(int argc, char **argv) free(r_im[i]); free(txdata[i]); } - free(s_re); free(s_im); free(r_re); free(r_im); free(txdata); - if (output_fd) - fclose(output_fd); - - if (input_fd) - fclose(input_fd); + if (output_fd) fclose(output_fd); + if (input_fd) fclose(input_fd); return(n_errors); - } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index da2da96c502bd1ecb3d435f3bfae13401bcb75e5..f9cddb432799d422dfb61ccd791ec0ec5091113b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -583,6 +583,9 @@ int8_t nr_ue_decode_mib( mac->type0_pdcch_ss_n_c = n_c; // fill in the elements in config request inside P5 message + mac->phy_config.Mod_id = module_id; + mac->phy_config.CC_id = cc_id; + mac->phy_config.config_req.pbch_config.system_frame_number = frame; // after calculation mac->phy_config.config_req.pbch_config.subcarrier_spacing_common = mac->mib->subCarrierSpacingCommon; mac->phy_config.config_req.pbch_config.ssb_subcarrier_offset = ssb_subcarrier_offset; // after calculation diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index 3ced5ca833a972d1e8f021733dbf1c2ab71cdb16..f6ac1fc6e186e7ee84819f960519ba19fe2198df 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -53,17 +53,20 @@ int num_devices=0; * \param device RF frontend parameters set by application * \returns 0 on success */ -int trx_brf_init(openair0_device *device) { +int trx_brf_init(openair0_device *device) +{ return 0; } + /*! \brief get current timestamp *\param device the hardware to use *\param module the bladeRf module *\returns timestamp of BladeRF */ - -openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) { +openair0_timestamp trx_get_timestamp(openair0_device *device, + bladerf_module module) +{ int status; struct bladerf_metadata meta; brf_state_t *brf = (brf_state_t*)device->priv; @@ -77,11 +80,13 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod return meta.timestamp; } + /*! \brief Start BladeRF * \param device the hardware to use * \returns 0 on success */ -int trx_brf_start(openair0_device *device) { +int trx_brf_start(openair0_device *device) +{ brf_state_t *brf = (brf_state_t*)device->priv; int status; @@ -119,6 +124,7 @@ int trx_brf_start(openair0_device *device) { return 0; } + /*! \brief Called to send samples to the BladeRF RF target \param device pointer to the device structure specific to the RF hardware target \param timestamp The timestamp at whicch the first sample MUST be sent @@ -128,8 +134,13 @@ int trx_brf_start(openair0_device *device) { \param flags Ignored for the moment \returns 0 on success */ -static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc, int flags) { - +static int trx_brf_write(openair0_device *device, + openair0_timestamp ptimestamp, + void **buff, + int nsamps, + int cc, + int flags) +{ int status; brf_state_t *brf = (brf_state_t*)device->priv; /* BRF has only 1 rx/tx chaine : is it correct? */ @@ -169,6 +180,7 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, return nsamps; //brf->meta_tx.actual_count; } + /*! \brief Receive samples from hardware. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for * the first channel. *ptimestamp is the time at which the first sample @@ -180,8 +192,12 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, * \param cc Index of component carrier * \returns number of samples read */ -static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - +static int trx_brf_read(openair0_device *device, + openair0_timestamp *ptimestamp, + void **buff, + int nsamps, + int cc) +{ int status=0; brf_state_t *brf = (brf_state_t*)device->priv; @@ -222,10 +238,12 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, } + /*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources * \param device the hardware to use */ -void trx_brf_end(openair0_device *device) { +void trx_brf_end(openair0_device *device) +{ int status; brf_state_t *brf = (brf_state_t*)device->priv; // Disable RX module, shutting down our underlying RX stream @@ -239,44 +257,47 @@ void trx_brf_end(openair0_device *device) { exit(1); } + /*! \brief print the BladeRF statistics * \param device the hardware to use * \returns 0 on success */ -int trx_brf_get_stats(openair0_device* device) { - +int trx_brf_get_stats(openair0_device* device) +{ return(0); - } + /*! \brief Reset the BladeRF statistics * \param device the hardware to use * \returns 0 on success */ -int trx_brf_reset_stats(openair0_device* device) { - +int trx_brf_reset_stats(openair0_device* device) +{ return(0); - } + /*! \brief Stop BladeRF * \param card the hardware to use * \returns 0 in success */ -int trx_brf_stop(openair0_device* device) { - +int trx_brf_stop(openair0_device* device) +{ return(0); - } + /*! \brief Set frequencies (TX/RX) * \param device the hardware to use * \param openair0_cfg1 openair0 Config structure (ignored. It is there to comply with RF common API) * \param exmimo_dump_config (ignored) * \returns 0 in success */ -int trx_brf_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1,int exmimo_dump_config) { - +int trx_brf_set_freq(openair0_device* device, + openair0_config_t *openair0_cfg1, + int exmimo_dump_config) +{ int status; brf_state_t *brf = (brf_state_t *)device->priv; openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; @@ -298,19 +319,19 @@ int trx_brf_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1,i } + /*! \brief Set Gains (TX/RX) * \param device the hardware to use * \param openair0_cfg openair0 Config structure * \returns 0 in success */ -int trx_brf_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { - +int trx_brf_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) +{ return(0); - } - #define RXDCLENGTH 16384 int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447}; int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448}; @@ -323,12 +344,14 @@ rx_gain_calib_table_t calib_table_fx4[] = { {-1,0} }; + /*! \brief set RX gain offset from calibration table * \param openair0_cfg RF frontend parameters set by application * \param chain_index RF chain ID */ -void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { - +void set_rx_gain_offset(openair0_config_t *openair0_cfg, + int chain_index) +{ int i=0; // loop through calibration table to find best adjustment factor for RX frequency double min_diff = 6e9,diff; @@ -348,11 +371,12 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { } + /*! \brief Calibrate LMSSDR RF * \param device the hardware to use */ -void calibrate_rf(openair0_device *device) { - +void calibrate_rf(openair0_device *device) +{ /* TODO: this function does not seem to work. Disabled until fixed. */ return; @@ -925,12 +949,15 @@ void calibrate_rf(openair0_device *device) { // LOG_M("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); } + /*! \brief Initialize Openair BLADERF target. It returns 0 if OK * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \returns 0 on success */ -int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { +int device_init(openair0_device *device, + openair0_config_t *openair0_cfg) +{ int status; brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); memset(brf, 0, sizeof(brf_state_t)); @@ -1120,6 +1147,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_gains_func = trx_brf_set_gains; device->openair0_cfg = openair0_cfg; device->priv = (void *)brf; + device->uhd_set_thread_priority = NULL; calibrate_rf(device); @@ -1137,11 +1165,13 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } + /*! \brief bladeRF error report * \param status * \returns 0 on success */ -int brf_error(int status) { +int brf_error(int status) +{ fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status)); exit(-1); return status; // or status error code @@ -1152,8 +1182,8 @@ int brf_error(int status) { * \param serial name of serial port on which to open BladeRF device * \returns bladerf device structure */ -struct bladerf * open_bladerf_from_serial(const char *serial) { - +struct bladerf * open_bladerf_from_serial(const char *serial) +{ int status; struct bladerf *dev; struct bladerf_devinfo info; @@ -1179,12 +1209,13 @@ struct bladerf * open_bladerf_from_serial(const char *serial) { } } + /*! \brief Get BladeRF log level * \param log_level log level * \returns log level of BLADERF device */ -int get_brf_log_level(int log_level) { - +int get_brf_log_level(int log_level) +{ int level=BLADERF_LOG_LEVEL_INFO; return BLADERF_LOG_LEVEL_INFO; switch(log_level) { diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 0f31c082f760f037571c4f4624ea6269837dbaf8..c6cb4a50c1f778635d6201de2ef6768545514dbc 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -112,9 +112,9 @@ typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ int load_lib(openair0_device *device, - openair0_config_t *openair0_cfg, - eth_params_t *cfg, - uint8_t flag) + openair0_config_t *openair0_cfg, + eth_params_t *cfg, + uint8_t flag) { loader_shlibfunc_t shlib_fdesc[1]; int ret=0; @@ -129,9 +129,8 @@ int load_lib(openair0_device *device, if (getenv("RFSIMULATOR") != NULL) libname="rfsimulator"; else - libname=OAI_RF_LIBNAME; - shlib_fdesc[0].fname="device_init"; - //shlib_fdesc[1].fname="uhd_set_thread_priority"; + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; } else { libname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; @@ -142,32 +141,10 @@ int load_lib(openair0_device *device, LOG_E(HW,"Library %s couldn't be loaded\n",libname); } else { ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); -//uhd_set_thread_priority_fun = (set_prio_func_t)shlib_fdesc[1].fptr; - } + } return ret; } -/* -void uhd_set_thread_prio(void) { - - loader_shlibfunc_t shlib_fdesc[1]; - int ret = 0; - - char *libname; - if (getenv("RFSIMULATOR") != NULL) - libname="rfsimulator"; - else - libname=OAI_RF_LIBNAME; - //shlib_fdesc[0].fname="uhd_set_thread_priority"; - ret=load_module_shlib(libname,shlib_fdesc,1,NULL); - if (ret < 0) { - LOG_E(HW,"Library %s couldn't be loaded\n",libname); - } else { - //(set_prio_func_t)shlib_fdesc[0].fptr(); - } - //return ret; -} -*/ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) @@ -185,6 +162,7 @@ int openair0_device_load(openair0_device *device, return rc; } + int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params) diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index a558b5a5ddbfb266885e358a16be4e66d9eda71f..f16ebed66ceca2856923cf53aab4ed930ab15996 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -406,6 +406,10 @@ struct openair0_device_t { * \param arg pointer to capabilities or configuration */ void (*configure_rru)(int idx, void *arg); + + /*! \brief set UHD thread priority + */ + void (*uhd_set_thread_priority)(void); }; /* type of device init function, implemented in shared lib */ @@ -491,9 +495,7 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open #define gettid() syscall(__NR_gettid) /*@}*/ - void uhd_set_thread_prio(void); - typedef void(*set_prio_func_t)(void); - //set_prio_func_t uhd_set_thread_priority_fun; + #ifdef __cplusplus } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index a05cc48fbd6ed09c7d8bc8c92201d65b6f1c464e..259b1fc277c5e8a7e9cb9adbccdcdf63e172af33 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -53,8 +53,8 @@ struct sockaddr_in dest_addr[MAX_INST]; int dest_addr_len[MAX_INST]; -int trx_eth_start(openair0_device *device) { - +int trx_eth_start(openair0_device *device) +{ eth_state_t *eth = (eth_state_t*)device->priv; /* initialize socket */ @@ -153,8 +153,8 @@ int trx_eth_start(openair0_device *device) { } -void trx_eth_end(openair0_device *device) { - +void trx_eth_end(openair0_device *device) +{ eth_state_t *eth = (eth_state_t*)device->priv; /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ if ( close(eth->sockfdd) <0 ) { @@ -166,29 +166,42 @@ void trx_eth_end(openair0_device *device) { } -int trx_eth_stop(openair0_device *device) { +int trx_eth_stop(openair0_device *device) +{ return(0); } -int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { + +int trx_eth_set_freq(openair0_device* device, + openair0_config_t *openair0_cfg, + int exmimo_dump_config) +{ return(0); } -int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { + +int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) +{ return(0); } -int trx_eth_get_stats(openair0_device* device) { + +int trx_eth_get_stats(openair0_device* device) +{ return(0); } -int trx_eth_reset_stats(openair0_device* device) { + +int trx_eth_reset_stats(openair0_device* device) +{ return(0); } -int ethernet_tune(openair0_device *device, unsigned int option, int value) { - +int ethernet_tune(openair0_device *device, + unsigned int option, + int value) +{ eth_state_t *eth = (eth_state_t*)device->priv; struct timeval timeout; struct ifreq ifr; @@ -363,8 +376,10 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { } -int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { - +int transport_init(openair0_device *device, + openair0_config_t *openair0_cfg, + eth_params_t * eth_params ) +{ eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); memset(eth, 0, sizeof(eth_state_t)); @@ -402,6 +417,7 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth device->trx_stop_func = trx_eth_stop; device->trx_set_freq_func = trx_eth_set_freq; device->trx_set_gains_func = trx_eth_set_gains; + device->uhd_set_thread_priority = NULL; if (eth->flags == ETH_RAW_MODE) { device->trx_write_func = trx_eth_write_raw; @@ -470,8 +486,11 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth /************************************************************************************************************************** * DEBUGING-RELATED FUNCTIONS * **************************************************************************************************************************/ -void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag) { - +void dump_packet(char *title, + unsigned char* pkt, + int bytes, + unsigned int tx_rx_flag) +{ static int numSend = 1; static int numRecv = 1; int num, k; @@ -484,8 +503,10 @@ void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_ printf("%s-%s (%06d): %s 0x%04X\n", title,(tx_rx_flag)? "TX":"RX", num, tmp, cksum); } -unsigned short calc_csum (unsigned short *buf, int nwords) { +unsigned short calc_csum (unsigned short *buf, + int nwords) +{ unsigned long sum; for (sum = 0; nwords > 0; nwords--) sum += *buf++; @@ -494,8 +515,9 @@ unsigned short calc_csum (unsigned short *buf, int nwords) { return ~sum; } -void dump_dev(openair0_device *device) { +void dump_dev(openair0_device *device) +{ eth_state_t *eth = (eth_state_t*)device->priv; printf("Ethernet device interface %i configuration:\n" ,device->openair0_cfg->Mod_id); @@ -511,21 +533,28 @@ void dump_dev(openair0_device *device) { } -void inline dump_txcounters(openair0_device *device) { + +void inline dump_txcounters(openair0_device *device) +{ eth_state_t *eth = (eth_state_t*)device->priv; printf(" Ethernet device interface %i, tx counters:\n" ,device->openair0_cfg->Mod_id); printf(" Sent packets: %llu send errors: %i\n", (long long unsigned int)eth->tx_count, eth->num_tx_errors); } -void inline dump_rxcounters(openair0_device *device) { +void inline dump_rxcounters(openair0_device *device) +{ eth_state_t *eth = (eth_state_t*)device->priv; printf(" Ethernet device interface %i rx counters:\n" ,device->openair0_cfg->Mod_id); printf(" Received packets: %llu missed packets errors: %i\n", (long long unsigned int)eth->rx_count, eth->num_underflows); } -void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag, int nsamps) { +void inline dump_buff(openair0_device *device, + char *buff, + unsigned int tx_rx_flag, + int nsamps) +{ char *strptr; eth_state_t *eth = (eth_state_t*)device->priv; /*need to add ts number of iqs in printf need to fix dump iqs call */ @@ -544,7 +573,10 @@ void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_fla } -void dump_iqs(char * buff, int iq_cnt) { + +void dump_iqs(char * buff, + int iq_cnt) +{ int i; for (i=0; i<iq_cnt; i++) { printf("s%02i: Q=%+ij I=%+i%s",i, diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index a57ebf8b6d85b5c8b1e28fccef6aa06ac448f120..c563569506d15f2999222eaa0a28a6158dc6c432 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -405,6 +405,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg){ device->trx_stop_func = trx_lms_stop; device->trx_set_freq_func = trx_lms_set_freq; device->trx_set_gains_func = trx_lms_set_gains; + device->uhd_set_thread_priority = NULL; device->openair0_cfg = openair0_cfg; diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp index 6f1afe47c0da98cda5b3bcea704d48d66fbd3f36..9b11415631fb7faa2ecea5eefc57f25fd9e9ea55 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/sodera_lib.cpp @@ -706,6 +706,7 @@ int openair0_dev_init_sodera(openair0_device* device, openair0_config_t *openair device->trx_stop_func = trx_sodera_stop; device->trx_set_freq_func = trx_sodera_set_freq; device->trx_set_gains_func = trx_sodera_set_gains; + device->uhd_set_thread_priority = NULL; s->sample_rate = openair0_cfg[0].sample_rate; s->channelscount = openair0_cfg[0].rx_num_channels; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 59b48c8a45f2258b2b4289bf85ede4bb52d34024..b423607c09201842356b4b0b7361c8908d7203a5 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -600,7 +600,15 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp for (int j=0; j<nsamps2; j++) { #if defined(__x86_64__) || defined(__i386__) #ifdef __AVX2__ - ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + // FK: in some cases the buffer might not be 32 byte aligned, so we cannot use avx2 + + if ((((uintptr_t) buff[i])&0x1F)==0) { + ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); + } + else { + ((__m128i *)buff[i])[2*j] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[j],4); + ((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[2*j+1],4); + } #else ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); #endif @@ -852,6 +860,10 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ if (bw_gain_adjust==1) { switch ((int)openair0_cfg[0].sample_rate) { + + case 46080000: + break; + case 30720000: break; @@ -877,7 +889,7 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ default: LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); + //exit(-1); break; } } @@ -914,6 +926,12 @@ int trx_usrp_reset_stats(openair0_device *device) { return(0); } +/*! \brief Set uhd priority + */ +static void uhd_set_thread_priority(void) { + uhd::set_thread_priority_safe(1.0); +} + #if defined(USRP_REC_PLAY) extern "C" { /*! \brief Initializer for USRP record/playback config @@ -1047,6 +1065,7 @@ extern "C" { device->trx_set_freq_func = trx_usrp_set_freq; device->trx_set_gains_func = trx_usrp_set_gains; device->openair0_cfg = openair0_cfg; + device->uhd_set_thread_priority = uhd_set_thread_priority; std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops. Use mmap=" << use_mmap << std::endl; } else { @@ -1162,6 +1181,13 @@ extern "C" { openair0_cfg[0].rx_bw = 40e6; break; + case 46080000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + case 30720000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; @@ -1214,7 +1240,15 @@ extern "C" { } switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: + case 46080000: + s->usrp->set_master_clock_rate(46.08e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 40e6; + openair0_cfg[0].rx_bw = 40e6; + break; + + case 30720000: s->usrp->set_master_clock_rate(30.72e6); //openair0_cfg[0].samples_per_packet = 1024; openair0_cfg[0].tx_sample_advance = 115; @@ -1366,6 +1400,7 @@ extern "C" { device->trx_set_freq_func = trx_usrp_set_freq; device->trx_set_gains_func = trx_usrp_set_gains; device->openair0_cfg = openair0_cfg; + device->uhd_set_thread_priority = uhd_set_thread_priority; s->sample_rate = openair0_cfg[0].sample_rate; // TODO: @@ -1468,9 +1503,6 @@ extern "C" { return 0; } - void uhd_set_thread_priority(void) { - uhd::set_thread_priority_safe(1.0); - } } /*@}*/ diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 651dba3f94469744c6d4bedbbff42100143619de..37a512f8fc192499f1e62f4fb2a117a74694b439 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -646,6 +646,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_gains_func = rfsimulator_set_gains; device->trx_write_func = rfsimulator_write; device->trx_read_func = rfsimulator_read; + device->uhd_set_thread_priority = NULL; /* let's pretend to be a b2x0 */ device->type = USRP_B200_DEV; device->openair0_cfg=&openair0_cfg[0]; diff --git a/targets/ARCH/tcp_bridge/tcp_bridge.c b/targets/ARCH/tcp_bridge/tcp_bridge.c index 8b287acfa14b24f009e5b30a653504e57c832269..3e2979f8499aef567f6418c8b939cd6cde895383 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge.c @@ -267,6 +267,7 @@ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) device->trx_set_gains_func = tcp_bridge_set_gains; device->trx_write_func = tcp_bridge_write; device->trx_read_func = tcp_bridge_read; + device->uhd_set_thread_priority = NULL; device->priv = tcp_bridge; diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index c3d5355876cde1e976f52f3ace43452ab35a1f63..7c06d14360f86bc3120a20e69d944fffdd1627f7 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -413,6 +413,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { device->trx_set_freq_func = tcp_bridge_set_freq; device->trx_set_gains_func = tcp_bridge_set_gains; device->trx_write_func = tcp_bridge_write; + device->uhd_set_thread_priority = NULL; if (tcp_bridge->is_enb) { device->trx_read_func = tcp_bridge_read; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..fdc4894da64a9606bf69b59fb1440d64e55278f4 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -0,0 +1,298 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_gNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + DL_prefix_type = "NORMAL"; + UL_prefix_type = "NORMAL"; + eutra_band = 78; + downlink_frequency = 3510000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 106; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + MIB_subCarrierSpacingCommon = 30; + MIB_ssb_SubcarrierOffset = 0; + MIB_dmrs_TypeA_Position = 2; + pdcch_ConfigSIB1 = 0; + SIB1_frequencyOffsetSSB = "khz5"; + SIB1_ssb_PeriodicityServingCell = 5; + SIB1_ss_PBCH_BlockPower = -60; + absoluteFrequencySSB = 0; + DL_FreqBandIndicatorNR = 15; + DL_absoluteFrequencyPointA = 15; + DL_offsetToCarrier = 15; + DL_SCS_SubcarrierSpacing = "kHz30"; + DL_SCS_SpecificCarrier_k0 = 0; + DL_carrierBandwidth = 15; + DL_locationAndBandwidth = 15; + DL_BWP_SubcarrierSpacing = "kHz30"; + DL_BWP_prefix_type = "NORMAL"; + UL_FreqBandIndicatorNR = 15; + UL_absoluteFrequencyPointA = 13; + UL_additionalSpectrumEmission = 3; + UL_p_Max = -1; + UL_frequencyShift7p5khz = "TRUE"; + UL_offsetToCarrier = 10; + UL_SCS_SubcarrierSpacing = "kHz30"; + UL_SCS_SpecificCarrier_k0 = 0; + UL_carrierBandwidth = 15; + UL_locationAndBandwidth = 15; + UL_BWP_SubcarrierSpacing = "kHz30"; + UL_BWP_prefix_type = "NORMAL"; + UL_timeAlignmentTimerCommon = "infinity"; + ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" + ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_dmrs_TypeA_Position = 2; + NIA_SubcarrierSpacing = "kHz15"; + ServingCellConfigCommon_ss_PBCH_BlockPower = -60; + referenceSubcarrierSpacing = "kHz15"; + dl_UL_TransmissionPeriodicity = "ms0p5"; + nrofDownlinkSlots = 10; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 10; + nrofUplinkSymbols = 10; + rach_totalNumberOfRA_Preambles = 63; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth"; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2; + rach_groupBconfigured = "ENABLE"; + rach_ra_Msg3SizeGroupA = 56; + rach_messagePowerOffsetGroupB = "dB0"; + rach_numberOfRA_PreamblesGroupA = 32; + rach_ra_ContentionResolutionTimer = 8; + rsrp_ThresholdSSB = 64; + rsrp_ThresholdSSB_SUL = 64; + prach_RootSequenceIndex_choice = "l839"; + prach_RootSequenceIndex_l839 = 0; + prach_RootSequenceIndex_l139 = 0; + prach_msg1_SubcarrierSpacing = "kHz30"; + restrictedSetConfig = "unrestrictedSet"; + msg3_transformPrecoding = "ENABLE"; + prach_ConfigurationIndex = 10; + prach_msg1_FDM = "one"; + prach_msg1_FrequencyStart = 10; + zeroCorrelationZoneConfig = 10; + preambleReceivedTargetPower = -150; + preambleTransMax = 6; + powerRampingStep = "dB0"; + ra_ResponseWindow = 8; + groupHoppingEnabledTransformPrecoding = "ENABLE"; + msg3_DeltaPreamble = 0; + p0_NominalWithGrant = 0; + PUSCH_TimeDomainResourceAllocation_k2 = 0; + PUSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + pucch_ResourceCommon = 0; + pucch_GroupHopping = "neither"; + hoppingId = 0; + p0_nominal = -30; + PDSCH_TimeDomainResourceAllocation_k0 = 2; + PDSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + rateMatchPatternId = 0; + RateMatchPattern_patternType = "bitmaps"; + symbolsInResourceBlock = "oneSlot"; + periodicityAndPattern = 2; + RateMatchPattern_controlResourceSet = 5; + RateMatchPattern_subcarrierSpacing = "kHz30"; + RateMatchPattern_mode = "dynamic"; + controlResourceSetZero = 0; + searchSpaceZero = 0; + searchSpaceSIB1 = 10; + searchSpaceOtherSystemInformation = 10; + pagingSearchSpace = 10; + ra_SearchSpace = 10; + PDCCH_common_controlResourceSetId = 5; + PDCCH_common_ControlResourceSet_duration = 2; + PDCCH_cce_REG_MappingType = "nonInterleaved"; + PDCCH_reg_BundleSize = 3; + PDCCH_interleaverSize = 3; + PDCCH_shiftIndex = 10; + PDCCH_precoderGranularity = "sameAsREG-bundle"; + PDCCH_TCI_StateId = 32; + tci_PresentInDCI = "ENABLE"; + PDCCH_DMRS_ScramblingID = 0; + SearchSpaceId = 10; + commonSearchSpaces_controlResourceSetId = 5; + SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1"; + SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; + SearchSpace_duration = 2; + SearchSpace_nrofCandidates_aggregationLevel1 = 0; + SearchSpace_nrofCandidates_aggregationLevel2 = 0; + SearchSpace_nrofCandidates_aggregationLevel4 = 0; + SearchSpace_nrofCandidates_aggregationLevel8 = 0; + SearchSpace_nrofCandidates_aggregationLevel16 = 0; + SearchSpace_searchSpaceType = "common"; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1; + Common_dci_Format2_3_monitoringPeriodicity = 1; + Common_dci_Format2_3_nrofPDCCH_Candidates = 1; + ue_Specific__dci_Formats = "formats0-0-And-1-0"; + RateMatchPatternLTE_CRS_carrierFreqDL = 6; + RateMatchPatternLTE_CRS_carrierBandwidthDL = 6; + RateMatchPatternLTE_CRS_nrofCRS_Ports = 1; + RateMatchPatternLTE_CRS_v_Shift = 0; + RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1; + RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; + RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame"; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "type=b200"; + + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 8b896fc58ac9adfeb545bd940a2a04f3c0787965..26f6eddf520ddfe20290c99adf2304a86654c103 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -262,7 +262,7 @@ 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_SINGLE_THREAD"; + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_DISABLE"; }