diff --git a/.gitignore b/.gitignore
index 06a51f1b64..73e0407c4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
# log and exec file
cmake_targets/log/
cmake_targets/*/build/
+cmake_targets/ran_build/
log/
lte_build_oai/
-targets/bin/
\ No newline at end of file
+targets/bin/
diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 52d1924749..86e9cdf74b 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -365,7 +365,7 @@ pipeline {
stage ("Test physical simulators") {
steps {
script {
- timeout (time: 45, unit: 'MINUTES') {
+ timeout (time: 90, unit: 'MINUTES') {
try {
gitlabCommitStatus(name: "Test phy-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 83757d48ad..c6111b3195 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -821,13 +821,13 @@ class SSHConnection():
# do not reset board twice in IF4.5 case
result = re.search('^rru|^enb|^du.band', str(config_file))
if result is not None:
- self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 10)
+ self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30)
result = re.search('type: b200', str(self.ssh.before))
if result is not None:
logging.debug('Found a B2xx device --> resetting it')
self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
# Reloading FGPA bin firmware
- self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 15)
+ self.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 30)
# 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_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
@@ -4032,7 +4032,7 @@ class SSHConnection():
if result is not None:
self.UhdVersion = result.group('uhd_version')
logging.debug('UHD Version is: ' + self.UhdVersion)
- self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 12)
+ self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 30)
usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before))
count = 0
for board in usrp_boards:
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 02e031a52f..bbea199ca1 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -185,7 +185,7 @@ function variant__v3__phy_sim {
NB_PATTERN_FILES=12
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
- RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
+ RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b"
}
function variant__v4__cppcheck {
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 0182327600..2956e53a95 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1332,7 +1332,11 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+ ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
+ ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
+ ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+ ${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
#${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
@@ -1377,6 +1381,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
+ ${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/filt16a_32.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -1561,6 +1566,44 @@ set(L2_SRC_UE
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
+
+ set(LTE_NR_L2_SRC_UE
+ ${PDCP_DIR}/pdcp.c
+ ${PDCP_DIR}/pdcp_fifo.c
+ ${PDCP_DIR}/pdcp_sequence_manager.c
+ ${PDCP_DIR}/pdcp_primitives.c
+ ${PDCP_DIR}/pdcp_util.c
+ ${PDCP_DIR}/pdcp_security.c
+ ${PDCP_DIR}/pdcp_netlink.c
+ ${RLC_AM_DIR}/rlc_am.c
+ ${RLC_AM_DIR}/rlc_am_init.c
+ ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c
+ ${RLC_AM_DIR}/rlc_am_timer_reordering.c
+ ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c
+ ${RLC_AM_DIR}/rlc_am_segment.c
+ ${RLC_AM_DIR}/rlc_am_segments_holes.c
+ ${RLC_AM_DIR}/rlc_am_in_sdu.c
+ ${RLC_AM_DIR}/rlc_am_receiver.c
+ ${RLC_AM_DIR}/rlc_am_retransmit.c
+ ${RLC_AM_DIR}/rlc_am_windows.c
+ ${RLC_AM_DIR}/rlc_am_rx_list.c
+ ${RLC_AM_DIR}/rlc_am_reassembly.c
+ ${RLC_AM_DIR}/rlc_am_status_report.c
+ ${RLC_TM_DIR}/rlc_tm.c
+ ${RLC_TM_DIR}/rlc_tm_init.c
+ ${RLC_UM_DIR}/rlc_um.c
+ ${RLC_UM_DIR}/rlc_um_fsm.c
+ ${RLC_UM_DIR}/rlc_um_control_primitives.c
+ ${RLC_UM_DIR}/rlc_um_segment.c
+ ${RLC_UM_DIR}/rlc_um_reassembly.c
+ ${RLC_UM_DIR}/rlc_um_receiver.c
+ ${RLC_UM_DIR}/rlc_um_dar.c
+ ${RLC_DIR}/rlc_mac.c
+ ${RLC_DIR}/rlc.c
+ ${RLC_DIR}/rlc_rrc.c
+ ${RLC_DIR}/rlc_mpls.c
+ ${RRC_DIR}/L2_interface_common.c
+ )
set(NR_L2_SRC_UE
${NR_UE_RRC_DIR}/L2_interface_ue.c
@@ -1613,7 +1656,7 @@ set (MAC_SRC_UE
${MAC_DIR}/config_ue.c
)
-
+
set (MAC_NR_SRC_UE
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_UE_MAC_DIR}/config_ue.c
@@ -1669,6 +1712,10 @@ endif()
add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
+
+add_library ( LTE_NR_L2_UE
+ ${LTE_NR_L2_SRC_UE}
+ )
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_mac_common.c )
@@ -2499,6 +2546,8 @@ add_executable(nr-uesoftmodem-nos1
${rrc_h}
${s1ap_h}
# ${OPENAIR_BIN_DIR}/messages_xml.h
+ ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
+ ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/executables/nr-ue.c
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
@@ -2512,9 +2561,10 @@ add_executable(nr-uesoftmodem-nos1
${SHLIB_LOADER_SOURCES}
)
+
target_link_libraries (nr-uesoftmodem-nos1
-Wl,--start-group
- RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_UE PHY_RU LFDS NR_L2_UE MAC_NR_COMMON
+ RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_UE PHY_RU LFDS LTE_NR_L2_UE NR_L2_UE MAC_NR_COMMON
${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt
index b94d99bff7..10c14fd59a 100644
--- a/cmake_targets/autotests/README.txt
+++ b/cmake_targets/autotests/README.txt
@@ -96,11 +96,41 @@ Obj.# Case# Test# Description
(Test 4, 10 MHz, R3-1.FDD (MCS 16), AWGN, 12dB (70%)),
(Test 5, 20 MHz, FDD (MCS 5), AWGN, 6dB (70%)),
(Test 6, 20 MHz, FDD (MCS 16), AWGN, 12 dB (70%))
-01 51 02 pucchsim (TBD)
-01 51 03 prachsim (TBD)
-01 51 04 pdcchsim (TBD)
-01 51 05 pbchsim (TBD)
-01 51 06 mbmssim (TBD)
+01 51 02 ldpc Test cases. (Test1: block length = 3872),
+ (Test2: block length = 4224),
+ (Test3: block length = 4576),
+ (Test4: block length = 4928),
+ (Test5: block length = 5280),
+ (Test6: block length = 5632),
+ (Test7: block length = 6336),
+ (Test8: block length = 7040),
+ (Test9: block length = 7744),
+ (Test10: block length = 8448)
+01 51 03 polartest Test cases. (Test1: PBCH polar test),
+ (Test2: DCI polar test)
+01 51 04 nr_pbchsim Test cases. (Test1: PBCH-only, 106 PRB),
+ (Test2: PBCH and synchronization, 106PBR),
+ (Test3: PBCH-only, 217 PRB),
+ (Test4: PBCH and synchronization, 217 RPB),
+ (Test5: PBCH-only, 273 PRB),
+ (Test6: PBCH and synchronization, 273 PRB)
+01 51 05 nr_dlsim Test cases. (Test1: 106 PRB),
+ (Test2: 217 PRB),
+ (Test3: 273 PRB)
+01 51 06 nr_dlschsim Test cases. (Test1: 106 PRB),
+ (Test2: 217 PRB),
+ (Test3: 273 PRB)
+01 51 07 shortblocktest Test cases. (Test1: 3 bits),
+ (Test2: 6 bits),
+ (Test3: 7 bits),
+ (Test4: 11 bits)
+01 51 08 nr_ulschsim Test cases. (Test1: 106 PRB),
+ (Test2: 217 PRB),
+ (Test3: 273 PRB)
+01 51 09 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)
01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
(Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)),
(Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)),
@@ -110,8 +140,11 @@ Obj.# Case# Test# Description
(Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)),
(Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)),
(Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
- (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
- (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+ (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
+ (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+01 51 11 nr_ulsim Test cases. (Test1: MCS 9),
+ (Test2: MCS 16),
+ (Test3: MCS 28)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index d30537424b..9cfaa2b21d 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1081,7 +1081,16 @@
execution
nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
- (Test3: 273 PRB)
+ (Test3: 273 PRB),
+ (Test4: 106 PRB 12 CSET-Offset),
+ (Test5: 217 PRB 48 CSET-Offset),
+
+ (Test7: 273 PRB 28 MCS)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1090,9 +1099,18 @@
$OPENAIR_DIR/targets/bin/nr_dlsim.Rel15
-n100 -R106
-n100 -R217
- -n100 -R273
- nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3
- PDCCH test OK
+ -n100 -R273
+ -n100 -R106 -o12
+ -n100 -R217 -o48
+
+ -n100 -R273 -e28
+ nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7
+ "PDCCH test OK" "PDSCH test OK"
segmentation fault|assertion|exiting|fatal
3
@@ -1220,6 +1238,26 @@
3
+
+ execution
+ nr_ulsim Test cases. (Test1: MCS 9),
+ (Test2: MCS 16),
+ (Test3: MCS 28)
+
+ $OPENAIR_DIR/cmake_targets/build_oai
+ --phy_simulators -c
+ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
+
+ $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15
+ -f100 -m9 -s10
+ -f100 -m16 -s20
+ -f100 -m28 -s30
+ nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3
+ PUSCH test OK
+ segmentation fault|assertion|exiting|fatal
+ 3
+
+
lte-softmodem
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 80945ed989..e2212d6ea1 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -108,9 +108,9 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
extern int transmission_mode;
-uint16_t sl_ahead=4;
-uint16_t sf_ahead=4;
-//pthread_t main_gNB_thread;
+uint16_t sl_ahead=6;
+uint16_t sf_ahead=6;
+//pthread_t main_gNB_thread;
time_stats_t softmodem_stats_mt; // main thread
time_stats_t softmodem_stats_hw; // hw acquisition
@@ -185,17 +185,20 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// ****************************************
// Common RX procedures subframe n
T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx));
- /*
- // if this is IF5 or 3GPP_gNB
- if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
- wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
- }
+/*
+ // if this is IF5 or 3GPP_gNB
+ if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
+ wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
+ }
+
+ // UE-specific RX processing for subframe n
+ if (nfapi_mode == 0 || nfapi_mode == 1) */
+
+ if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) {
+ nfapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_pdu_rel15 = &gNB->ulsch[1][0]->harq_processes[0]->ulsch_pdu.ulsch_pdu_rel15;
+ phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx, ulsch_pdu_rel15->start_symbol, ulsch_pdu_rel15->start_symbol + ulsch_pdu_rel15->number_symbols);
+ }
- // UE-specific RX processing for subframe n
- if (nfapi_mode == 0 || nfapi_mode == 1) {
- phy_procedures_gNB_uespec_RX(gNB, proc, no_relay );
- }
- */
pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx;
gNB->UL_INFO.slot = slot_rx;
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 1e88ae6e6b..6234c270cc 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -654,6 +654,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
ru->nb_rx);
}
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
proc->timestamp_rx = ts-ru->ts_offset;
@@ -719,18 +720,24 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
+ //nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config;
void *txp[ru->nb_tx];
unsigned int txs;
int i;
T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(frame), T_INT(slot),
T_INT(0), T_BUFFER(&ru->common.txdata[0][slot * fp->samples_per_slot], fp->samples_per_slot * 4));
- nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame);
int sf_extension = 0;
+ //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame);
+
+ if ((slot == 0) ||
+ (slot == 1)) {
+ int siglen=fp->samples_per_slot;
+ int flags;
+ if (slot==0)
+ flags = 2;
+ else if (slot==1)
+ flags=3;
- if ((SF_type == SF_DL) ||
- (SF_type == SF_S)) {
- int siglen=fp->samples_per_slot,flags=1;
/*
if (SF_type == SF_S) {
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
@@ -1355,6 +1362,8 @@ static void *ru_thread( void *param ) {
char filename[40], threadname[40];
int print_frame = 8;
int i = 0;
+ int aa;
+
// set default return value
ru_thread_status = 0;
// set default return value
@@ -1386,9 +1395,9 @@ static void *ru_thread( void *param ) {
}
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
- fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
nr_dump_frame_parms(fp);
+ fill_rf_config(ru,ru->rf_config_file);
nr_phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
AssertFatal(ret==0,"Cannot connect to local radio\n");
@@ -1447,6 +1456,7 @@ static void *ru_thread( void *param ) {
}
// synchronization on input FH interface, acquire signals/data and block
+ LOG_D(PHY,"[RU_thread] read data: frame_rx = %d, tti_rx = %d\n", frame, slot);
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
else AssertFatal(1==0, "No fronthaul interface at south port");
@@ -1471,7 +1481,19 @@ static void *ru_thread( void *param ) {
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
// do RX front-end processing (frequency-shift, dft) if needed
- if (ru->feprx) ru->feprx(ru,proc->tti_rx);
+
+ if (proc->tti_rx == NR_UPLINK_SLOT || fp->frame_type == FDD) {
+
+ if (ru->feprx) ru->feprx(ru,proc->tti_rx);
+
+ }
+
+ LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx);
+ LOG_D(PHY,"Copying rxdataF from RU to gNB\n");
+
+ for (aa=0;aanb_rx;aa++)
+ memcpy((void*)RC.gNB[0][0]->common_vars.rxdataF[aa],
+ (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
// At this point, all information for subframe has been received on FH interface
@@ -1621,14 +1643,6 @@ int stop_rf(RU_t *ru) {
return 0;
}
-extern void fep_full(RU_t *ru,int slot);
-extern void ru_fep_full_2thread(RU_t *ru,int slot);
-extern void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
-extern void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
-extern void feptx_prec(RU_t *ru, int frame_tx,int tti_tx);
-extern void init_fep_thread(RU_t *ru);
-extern void nr_init_feptx_thread(RU_t *ru);
-
void init_RU_proc(RU_t *ru) {
int i=0;
RU_proc_t *proc;
@@ -1693,7 +1707,7 @@ void init_RU_proc(RU_t *ru) {
}
if (get_thread_worker_conf() == WORKER_ENABLE) {
- if (ru->feprx) init_fep_thread(ru);
+ if (ru->feprx) nr_init_feprx_thread(ru);
if (ru->feptx_ofdm) nr_init_feptx_thread(ru);
}
@@ -1986,8 +2000,8 @@ void set_function_spec_param(RU_t *ru) {
ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception
ru->fh_south_out = tx_rf; // send output to RF
ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously
- ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs
- ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU)
+ ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs
+ ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft only (no precoding in RRU)
ru->feptx_prec = NULL;
ru->nr_start_if = nr_start_if; // need to start the if interface for if4p5
ru->ifdevice.host_type = RRU_HOST;
@@ -2008,8 +2022,8 @@ void set_function_spec_param(RU_t *ru) {
malloc_IF4p5_buffer(ru);
} else if (ru->function == gNodeB_3GPP) {
ru->do_prach = 0; // no prach processing in RU
- ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; // RX DFTs
- ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding
+ ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs
+ ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding
ru->feptx_prec = NULL; // this is fep with idft and precoding
ru->fh_north_in = NULL; // no incoming fronthaul from north
ru->fh_north_out = NULL; // no outgoing fronthaul to north
@@ -2038,13 +2052,13 @@ void set_function_spec_param(RU_t *ru) {
case REMOTE_IF5: // the remote unit is IF5 RRU
ru->do_prach = 0;
- ru->feprx = fep_full; // this is frequency-shift + DFTs
- ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs
- ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs
- ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception
- ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission
- ru->fh_south_asynch_in = NULL; // no asynchronous UL
- ru->start_rf = NULL; // no local RF
+ ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs
+ ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs
+ ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs
+ ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception
+ ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission
+ ru->fh_south_asynch_in = NULL; // no asynchronous UL
+ ru->start_rf = NULL; // no local RF
ru->stop_rf = NULL;
ru->nr_start_if = nr_start_if; // need to start if interface for IF5
ru->ifdevice.host_type = RAU_HOST;
@@ -2099,6 +2113,7 @@ void init_NR_RU(char *rf_config_file)
{
int ru_id;
RU_t *ru;
+ PHY_VARS_gNB *gNB_RC;
PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL;
NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL;
int i;
@@ -2142,6 +2157,7 @@ void init_NR_RU(char *rf_config_file)
}
}
+ gNB_RC = RC.gNB[0][0];
gNB0 = ru->gNB_list[0];
fp = ru->nr_frame_parms;
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
@@ -2150,10 +2166,11 @@ void init_NR_RU(char *rf_config_file)
if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
AssertFatal(gNB0!=NULL,"gNB0 is null!\n");
- if (gNB0) {
- LOG_I(PHY,"Copying frame parms from gNB %d to ru %d\n",gNB0->Mod_id,ru->idx);
- memcpy((void *)fp,(void *)&gNB0->frame_parms,sizeof(NR_DL_FRAME_PARMS));
- memset((void *)ru->frame_parms, 0, sizeof(LTE_DL_FRAME_PARMS));
+ if (gNB0 && gNB_RC) {
+ LOG_I(PHY,"Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n",gNB0->Mod_id,ru->idx);
+ memset((void *)fp, 0, sizeof(NR_DL_FRAME_PARMS));
+ memcpy((void *)fp,&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS));
+ memcpy((void *)&gNB0->frame_parms,(void *)&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS));
// attach all RU to all gNBs in its list/
LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU);
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index d3c58b0077..a288dbebde 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -98,6 +98,8 @@
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_MSC "Enable the MSC tracing utility \n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
+#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
+#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
/*--------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 03a896a445..931e2c1cd4 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -474,6 +474,8 @@ static void get_options(void) {
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv = 0;
+ uint32_t noS1;
+ uint32_t nokrnmod;
paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
paramdef_t cmdline_logparams[] = CMDLINE_LOGPARAMS_DESC_NR ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
@@ -511,6 +513,7 @@ static void get_options(void) {
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
+
}
@@ -831,6 +834,30 @@ static void wait_nfapi_init(char *thread_name) {
printf( "NFAPI: got sync (%s)\n", thread_name);
}
+void init_pdcp(void) {
+ //if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
+ pdcp_layer_init();
+ uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
+ (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
+
+ if (IS_SOFTMODEM_NOS1){
+ printf("IS_SOFTMODEM_NOS1 option enabled \n");
+ pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
+ }
+
+ pdcp_module_init(pdcp_initmask);
+
+ /*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
+ pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
+ } else {*/
+ pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
+ pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
+ //}
+ /*} else {
+ pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
+ }*/
+}
+
int main( int argc, char **argv )
{
int i, ru_id, CC_id = 0;
@@ -852,6 +879,7 @@ int main( int argc, char **argv )
configure_linux();
printf("Reading in command-line options\n");
get_options ();
+ get_common_options();
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n");
@@ -914,6 +942,9 @@ init_opt();
flexran_agent_start(i);
}
+ if(IS_SOFTMODEM_NOS1)
+ init_pdcp();
+
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index 0c1fc4aac7..57d7377134 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -5,6 +5,7 @@
#include "flexran_agent.h"
#include "PHY/defs_gNB.h"
+#include "proto_agent.h"
#define DEFAULT_DLF 2680000000
@@ -17,38 +18,43 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC_GNB { \
- {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\
- {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
- {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
- {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
- {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
- {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
- {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
- {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
- {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
- {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \
- {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
- {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
- {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
- {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
- {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
- {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
- {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
- {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
- {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
- {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
- {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
- {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
- {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
- {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
- {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
-}
+ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)},\
+ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
+ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
+ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
+ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
+ {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
+ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
+ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
+ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
+ {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \
+ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
+ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
+ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
+ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
+ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
+ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
+ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
+ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
+ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
+ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
+ {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
+ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
+ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
+ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
+ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \
+ {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
+ {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0} \
+ }
+#define SOFTMODEM_NOS1_BIT (1<<0)
+#define SOFTMODEM_NOKRNMOD_BIT (1<<1)
-typedef struct {
- int *argc;
- char **argv;
-} scopeParms_t;
+#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
+#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
+
+extern uint64_t get_softmodem_optmask(void);
+extern void get_common_options(void);
extern int T_port;
extern int T_nowait;
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index de972d28f6..f6fd6412b0 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -45,6 +45,7 @@
#include "common/utils/LOG/log.h"
#include "common/utils/system.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "executables/nr-softmodem.h"
#include "T.h"
@@ -141,8 +142,10 @@ PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
memset(ue,0,sizeof(PHY_VARS_NR_UE));
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
+
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
+
// initialize all signal buffers
init_nr_ue_signal(ue,1,abstraction_flag);
// intialize transport
@@ -353,6 +356,9 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
+ uint32_t nb_rb, start_rb;
+ uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx;
+ uint16_t n_rnti;
// Process Rx data for one sub-frame
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) {
@@ -365,12 +371,38 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
scheduled_response.dl_config = &dcireq.dl_config_req;
- scheduled_response.ul_config = NULL;
+ scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = UE->Mod_id;
scheduled_response.CC_id = 0;
scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_rx;
+
+ //--------------------------Temporary configuration-----------------------------//
+ n_rnti = 0x1234;
+ nb_rb = 50;
+ start_rb = 0;
+ nb_symb_sch = 12;
+ start_symbol = 2;
+ precod_nbr_layers = 1;
+ mcs = 9;
+ harq_pid = 0;
+ rvidx = 0;
+ //------------------------------------------------------------------------------//
+
+ scheduled_response.ul_config->sfn_slot = NR_UPLINK_SLOT;
+ scheduled_response.ul_config->number_pdus = 1;
+ scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = mcs;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = rvidx;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
+ scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
nr_ue_scheduled_response(&scheduled_response);
#ifdef UE_SLOT_PARALLELISATION
@@ -381,6 +413,15 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500);
//printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
+ if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1
+ //Hardcoded rnti value
+ protocol_ctxt_t ctxt;
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
+ 0x1234, proc->frame_rx,
+ proc->nr_tti_rx, 0);
+ //pdcp_run(&ctxt);
+ pdcp_fifo_flush_sdus(&ctxt);
+ }
}
@@ -415,13 +456,14 @@ typedef struct processingData_s {
} processingData_t;
void UE_processing(void *arg) {
+ uint8_t thread_id;
processingData_t *rxtxD=(processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
processSlotRX(UE, proc);
//printf(">>> mac ended\n");
// Prepare the future Tx data
-#if 0
+/*
#ifndef NO_RAT_NR
if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT)
@@ -429,11 +471,21 @@ void UE_processing(void *arg) {
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
(UE->frame_parms.frame_type == FDD) )
#endif
+*/
+
+
+ if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){
+
+ thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
+
+
if (UE->mode != loop_through_memory)
- phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay);
+ phy_procedures_nrUE_TX(UE,proc,0,thread_id);
+
+ }
//phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay);
-#endif
+
#if 0
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
@@ -643,12 +695,12 @@ void *UE_thread(void *arg) {
//LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);
#ifdef OAI_ADRV9371_ZC706
- uint32_t total_gain_dB_prev = 0;
+ /*uint32_t total_gain_dB_prev = 0;
if (total_gain_dB_prev != UE->rx_total_gain_dB) {
total_gain_dB_prev = UE->rx_total_gain_dB;
- openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB-20;
+ openair0_cfg[0].rx_gain[0] = UE->rx_total_gain_dB;
UE->rfdevice.trx_set_gains_func(&UE->rfdevice,&openair0_cfg[0]);
- }
+ }*/
#endif
for (int i=0; iframe_parms.nb_antennas_rx; i++)
@@ -657,7 +709,7 @@ void *UE_thread(void *arg) {
slot_nr*UE->frame_parms.samples_per_slot];
for (int i=0; iframe_parms.nb_antennas_tx; i++)
- txp[i] = (void *)&UE->common_vars.txdata[i][curMsg->proc.nr_tti_tx*UE->frame_parms.samples_per_slot];
+ txp[i] = (void *)&UE->common_vars.txdata[i][((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX)%nb_slot_frame)*UE->frame_parms.samples_per_slot];
int readBlockSize, writeBlockSize;
@@ -680,16 +732,18 @@ void *UE_thread(void *arg) {
rxp,
readBlockSize,
UE->frame_parms.nb_antennas_rx),"");
+
+if (slot_nr==18)
AssertFatal( writeBlockSize ==
UE->rfdevice.trx_write_func(&UE->rfdevice,
timestamp+
- (2*UE->frame_parms.samples_per_slot) -
+ (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot) -
UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
openair0_cfg[0].tx_sample_advance,
txp,
writeBlockSize,
UE->frame_parms.nb_antennas_tx,
- 1),"");
+ 4),"");
if( slot_nr==(nb_slot_frame-1)) {
// read in first symbol of next frame and adjust for timing drift
@@ -734,7 +788,7 @@ void *UE_thread(void *arg) {
msgToPush->key=slot_nr;
pushTpool(Tpool, msgToPush);
- if (getenv("RFSIMULATOR")) {
+ if (getenv("RFSIMULATOR") || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR")
// FixMe: Wait previous thread is done, because race conditions seems too bad
// in case of actual RF board, the overlap between threads mitigate the issue
// We must receive one message, that proves the slot processing is done
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index bcde27bedc..7881783651 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -29,6 +29,7 @@
#include "PHY/defs_nr_UE.h"
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
+//#include "common/utils/threadPool/thread-pool.h"
#include "common/utils/load_module_shlib.h"
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -77,9 +78,11 @@ unsigned short config_frames[4] = {2,9,11,13};
#include
+
/* Callbacks, globals and object handlers */
extern void reset_stats( FL_OBJECT *, long );
+//extern void initTpool(char *params,tpool_t *pool, bool performanceMeas);
/* Forms and Objects */
@@ -371,6 +374,8 @@ static void get_options(void) {
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv=0;
+ //uint32_t noS1;
+ //uint32_t nokrnmod;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC_NR ;
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
@@ -626,6 +631,27 @@ void init_openair0(void) {
}
}
+void init_pdcp(void) {
+ uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
+
+ /*if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) {
+ pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
+ }*/
+
+ if (IS_SOFTMODEM_NOKRNMOD)
+ pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
+
+ /*if (rlc_module_init() != 0) {
+ LOG_I(RLC, "Problem at RLC initiation \n");
+ }
+ pdcp_layer_init();
+ nr_ip_over_LTE_DRB_preconfiguration();*/
+ pdcp_module_init(pdcp_initmask);
+ pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
+ pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
+ LOG_I(PDCP, "Before getting out from init_pdcp() \n");
+}
+
int main( int argc, char **argv ) {
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
@@ -645,6 +671,7 @@ int main( int argc, char **argv ) {
logInit();
// get options and fill parameters from configuration file
get_options (); //Command-line options, enb_properties
+ get_common_options();
#if T_TRACER
T_Config_Init();
#endif
@@ -658,18 +685,22 @@ int main( int argc, char **argv ) {
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
init_opt() ;
+ if(IS_SOFTMODEM_NOS1)
+ init_pdcp();
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd");
}
+/*
#ifdef PDCP_USE_NETLINK
netlink_init();
#if defined(PDCP_USE_NETLINK_QUEUES)
pdcp_netlink_init();
#endif
#endif
-#ifndef PACKAGE_VERSION
+*/
+ #ifndef PACKAGE_VERSION
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
@@ -695,6 +726,7 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
UE[CC_id] = PHY_vars_UE_g[0][CC_id];
+
if (phy_test==1)
UE[CC_id]->mac_enabled = 0;
else
@@ -744,6 +776,7 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706)
PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance;
+ PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance;
#else
PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160;
#endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index aad688c9d4..e85caf7690 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -586,13 +586,14 @@ typedef struct {
uint8_t start_symbol;
uint8_t nb_symbols;
uint8_t mcs_idx;
+ uint8_t mcs_table;
uint8_t ndi;
uint8_t nb_codewords;
uint8_t nb_layers;
uint16_t coding_rate;
uint8_t modulation;
uint8_t modulation_order;
- uint16_t transport_block_size;
+ uint32_t transport_block_size;
uint8_t nb_re_dmrs;
uint8_t time_alloc_list_flag;
uint8_t time_alloc_list;
@@ -694,6 +695,7 @@ typedef struct {
nr_pusch_freq_hopping_t pusch_freq_hopping;
uint8_t mcs;
uint8_t Qm;
+ uint16_t R;
uint8_t ndi;
uint8_t rv;
int8_t accumulated_delta_PUSCH;
diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
index d213a657f5..ed8dd3b49a 100644
--- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c
+++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c
@@ -130,9 +130,9 @@ int test_ldpc(short No_iteration,
double *modulated_input[MAX_NUM_DLSCH_SEGMENTS];
char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS];
unsigned int i,j,trial=0;
- short BG=0,Zc,Kb=0,nrows=0;//,ncols;
+ short BG=0,nrows=0;//,ncols;
int no_punctured_columns,removed_bit;
- int i1;
+ int i1,Zc,Kb=0;
int R_ind = 0;
//Table of possible lifting sizes
//short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
@@ -287,7 +287,7 @@ int test_ldpc(short No_iteration,
// printf("puncture:%d\n",no_punctured_columns);
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
if (ntrials==0)
- ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
+ ldpc_encoder_orig(test_input[0],channel_input[0], Zc, BG, block_length, BG, 1);
for (trial=0; trial < ntrials; trial++)
{
@@ -295,20 +295,20 @@ int test_ldpc(short No_iteration,
//// encoder
start_meas(&time);
for(j=0;jbnProcBufRes;
int8_t* llrRes = p_procBuf->llrRes;
int8_t* llrProcBuf = p_procBuf->llrProcBuf;
-
+
__m128i* p_bnProcBuf;
__m256i* p_bnProcBufRes;
__m128i* p_llrProcBuf;
@@ -1693,7 +1693,7 @@ static inline void nrLDPC_bnProc(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBu
int8_t* bnProcBuf = p_procBuf->bnProcBuf;
int8_t* bnProcBufRes = p_procBuf->bnProcBufRes;
int8_t* llrRes = p_procBuf->llrRes;
-
+
__m256i* p_bnProcBuf;
__m256i* p_bnProcBufRes;
__m256i* p_llrRes;
@@ -2775,24 +2775,35 @@ static inline void nrLDPC_llr2bit(int8_t* out, int8_t* llrOut, uint16_t numLLR)
}
/**
- \brief Performs hard-decision on output LLRs and packs the output in 32 bit values.
+ \brief Performs hard-decision on output LLRs and packs the output in byte aligned output according to TS 38.321 Section 6.1.1.
+ i = 0,1,2,...
+ IN[i] : a0, a1, a2, ..., a_{A-1}
+ OUT[i]: a7,a6,a5,a4,a3,a2,a1,a0|a15,14,...,a8|a23,a22,...,a16|a31,a30,...,a24|...
\param out Pointer hard-decision output, every int8_t contains 8 bits
\param llrOut Pointer to output LLRs
\param numLLR Number of LLRs
*/
static inline void nrLDPC_llr2bitPacked(int8_t* out, int8_t* llrOut, uint16_t numLLR)
{
+ /** Vector of indices for shuffling input */
+ const uint8_t constShuffle_256_epi8[32] __attribute__ ((aligned(32))) = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
+
__m256i* p_llrOut = (__m256i*) llrOut;
uint32_t* p_bits = (uint32_t*) out;
+ __m256i inPerm;
int8_t* p_llrOut8;
uint32_t bitsTmp = 0;
uint32_t i;
uint32_t M = numLLR>>5;
uint32_t Mr = numLLR&31;
+ const __m256i* p_shuffle = (__m256i*) constShuffle_256_epi8;
for (i=0; i640)
- Kb = 10;
- else if (block_length>560)
- Kb = 9;
- else if (block_length>192)
- Kb = 8;
- else
- Kb = 6;
}
- //find minimum value in all sets of lifting size
- Zc=0;
- for (i1=0; i1 < 51; i1++)
- {
- if (lift_size[i1] >= (double) block_length/Kb)
- {
- Zc = lift_size[i1];
- //printf("%d\n",Zc);
- break;
- }
- }
- AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
#ifdef DEBUG_LDPC
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length);
@@ -273,7 +249,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
if(tinput != NULL) start_meas(tinput);
for (i=0; i>(i&7);
+ c[i] = (test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
}
@@ -317,20 +293,18 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
return 0;
}
-int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
+int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
{
- short Zc,Kb=0,nrows=0,ncols=0;
+ short nrows=0,ncols=0;
int i,i1,j;
int no_punctured_columns,removed_bit;
- //Table of possible lifting sizes
- short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
char temp;
int simd_size;
#ifdef __AVX2__
__m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
- __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats.
+ __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats.
__m256i zero256 = _mm256_setzero_si256();
__m256i masks[8];
register __m256i c256;
@@ -350,8 +324,6 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
//if (block_length>3840)
if (BG==1)
{
- //BG=1;
- Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
@@ -362,28 +334,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
nrows=42; //parity check bits
ncols=10; // info bits
- if (block_length>640)
- Kb = 10;
- else if (block_length>560)
- Kb = 9;
- else if (block_length>192)
- Kb = 8;
- else
- Kb = 6;
}
- //find minimum value in all sets of lifting size
- Zc=0;
- for (i1=0; i1 < 51; i1++)
- {
- if (lift_size[i1] >= (double) block_length/Kb)
- {
- Zc = lift_size[i1];
- //printf("%d\n",Zc);
- break;
- }
- }
-
#ifdef DEBUG_LDPC
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
@@ -413,7 +365,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
for (i=0; i>(i&7);
+ temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << j);
}
@@ -431,7 +383,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
for (i=(block_length>>5)<<5;i>(i&7);
+ temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << j);
}
@@ -517,14 +469,13 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
return 0;
}
-int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
+int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
{
- short Zc,Kb=0,nrows=0,ncols=0;
+ short nrows=0,ncols=0;
int i,i1,j;
int no_punctured_columns,removed_bit;
//Table of possible lifting sizes
- short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
char temp;
int simd_size;
int macro_segment, macro_segment_end;
@@ -537,7 +488,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
#ifdef __AVX2__
__m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
- __m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats.
+ __m256i andmask = _mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats.
__m256i zero256 = _mm256_setzero_si256();
__m256i masks[8];
register __m256i c256;
@@ -556,38 +507,14 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
//determine number of bits in codeword
if (BG==1)
{
- BG=1;
- Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
else if (BG==2)
{
- BG=2;
nrows=42; //parity check bits
ncols=10; // info bits
-
- if (block_length>640)
- Kb = 10;
- else if (block_length>560)
- Kb = 9;
- else if (block_length>192)
- Kb = 8;
- else
- Kb = 6;
- }
-
- //find minimum value in all sets of lifting size
- Zc=0;
- for (i1=0; i1 < 51; i1++)
- {
- if (lift_size[i1] >= (double) block_length/Kb)
- {
- Zc = lift_size[i1];
- //printf("%d\n",Zc);
- break;
}
- }
#ifdef DEBUG_LDPC
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
@@ -639,7 +566,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
//for (j=0; j>(i&7);
+ temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << (j-macro_segment));
}
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
index 6a1754a6a9..235badc2e0 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
@@ -361,24 +361,19 @@ short *choose_generator_matrix(short BG,short Zc)
return Gen_shift_values;
}
-int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code)
+int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length, short BG,unsigned char gen_code)
{
unsigned char c[22*384]; //padded input, unpacked, max size
unsigned char d[68*384]; //coded output, unpacked, max size
unsigned char channel_temp,temp;
short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
- short Zc;
- //initialize for BG == 1
- short Kb = 22;
+
short nrows = 46;//parity check bits
short ncols = 22;//info bits
int i,i1,i2,i3,i4,i5,temp_prime,var;
int no_punctured_columns,removed_bit;
- //Table of possible lifting sizes
- short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
-
int nind=0;
int indlist[1000];
int indlist2[1000];
@@ -387,8 +382,6 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
//if (block_length>3840)
if (BG==1)
{
- //BG=1;
- Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
@@ -399,32 +392,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
nrows=42; //parity check bits
ncols=10; // info bits
- if (block_length>640)
- Kb = 10;
- else if (block_length>560)
- Kb = 9;
- else if (block_length>192)
- Kb = 8;
- else
- Kb = 6;
}
- //find minimum value in all sets of lifting size
- Zc=0;
- for (i1=0; i1 < 51; i1++)
- {
- if (lift_size[i1] >= (double) block_length/Kb)
- {
- Zc = lift_size[i1];
- //printf("%d\n",Zc);
- break;
- }
- }
- if (Zc==0) {
- printf("ldpc_encoder_orig: could not determine lifting size\n");
- return(-1);
- }
-
Gen_shift_values=choose_generator_matrix(BG,Zc);
if (Gen_shift_values==NULL) {
printf("ldpc_encoder_orig: could not find generator matrix\n");
@@ -460,7 +429,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
{
//c[i] = test_input[i/8]<<(i%8);
//c[i]=c[i]>>7&1;
- c[i]=(test_input[i/8]&(1<<(i&7)))>>(i&7);
+ c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7));
}
// parity check part
diff --git a/openair1/PHY/CODING/nr_compute_tbs.c b/openair1/PHY/CODING/nr_compute_tbs.c
index e1c15d4a86..055f697f41 100644
--- a/openair1/PHY/CODING/nr_compute_tbs.c
+++ b/openair1/PHY/CODING/nr_compute_tbs.c
@@ -24,73 +24,128 @@
author: Hongzhi WANG (TCL)
*/
#include "PHY/defs_nr_UE.h"
-//#include "SCHED/extern.h"
-
#define INDEX_MAX_TBS_TABLE (93)
-//Table 5.1.3.1-1
-uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
- {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
+
//Table 5.1.2.2-2
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824};
-uint32_t nr_compute_tbs(uint8_t mcs,
- uint16_t nb_rb,
- uint16_t nb_symb_sch,
- uint8_t nb_re_dmrs,
- uint16_t length_dmrs,
- uint8_t Nl)
+uint16_t NPRB_LBRM[7] = {32,66,107,135,162,217,273};
+
+uint32_t nr_compute_tbs(uint16_t Qm,
+ uint16_t R,
+ uint16_t nb_rb,
+ uint16_t nb_symb_sch,
+ uint16_t nb_dmrs_prb,
+ uint16_t nb_rb_oh,
+ uint8_t Nl)
{
- uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R;
- uint32_t nr_tbs=0;
- double Ninfo,Np_info,n,C;
- nb_rb_oh = 0; //set to 0 if not configured by higher layer
- Qm = Mcsindextable1[mcs][0];
- R = Mcsindextable1[mcs][1];
- nb_dmrs_prb = nb_re_dmrs*length_dmrs;
+ uint16_t nbp_re, nb_re;
+ uint32_t nr_tbs=0;
+ uint32_t Ninfo, Np_info, C;
+ uint8_t n, scale;
- nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
+ nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
- nb_re = min(156, nbp_re) * nb_rb;
+ nb_re = min(156, nbp_re) * nb_rb;
+
+ scale = (R>1024)?11:10;
// Intermediate number of information bits
- Ninfo = (double)((nb_re * R * Qm * Nl)/1024);
-
- //printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R);
+ Ninfo = (nb_re * R * Qm * Nl)>>scale;
if (Ninfo <=3824) {
-
n = max(3, floor(log2(Ninfo)) - 6);
- Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n)));
-
+ Np_info = max(24, (Ninfo>>n)<= Np_info){
+ if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
}
else {
- n = floor(log2(Ninfo-24)) - 5;
- Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n)));
+ n = log2(Ninfo-24)-5;
+ Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){
- C = ceil( (Np_info + 24)/8424 );
- nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
+ C = CEILIDIV((Np_info+24),8424);
+ nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
}
else {
- nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24);
- //printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 ));
+ nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
}
}
}
+ //printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", Ninfo, nbp_re, nb_re, Qm, R, nr_tbs);
+ return nr_tbs;
+}
- return nr_tbs;
+
+//tbslbrm calculation according to 5.4.2.1 of 38.212
+uint32_t nr_compute_tbslbrm(uint16_t table,
+ uint16_t nb_rb,
+ uint8_t Nl,
+ uint8_t C)
+{
+
+ uint16_t R, nb_re;
+ uint16_t nb_rb_lbrm=0;
+ uint8_t Qm;
+ int i;
+ uint32_t nr_tbs=0;
+ uint32_t Ninfo, Np_info;
+ uint8_t n;
+
+ for (i=0; i<7; i++) {
+ if (NPRB_LBRM[i] >= nb_rb){
+ nb_rb_lbrm = NPRB_LBRM[i];
+ break;
+ }
+ }
+
+ Qm = ((table == 1)? 8 : 6);
+ R = 948;
+ nb_re = 156 * nb_rb_lbrm;
+
+ // Intermediate number of information bits
+ Ninfo = (nb_re * R * Qm * Nl)>>10;
+
+ if (Ninfo <=3824) {
+ n = max(3, floor(log2(Ninfo)) - 6);
+ Np_info = max(24, (Ninfo>>n)<= Np_info){
+ nr_tbs = Tbstable_nr[i];
+ break;
+ }
+ }
+ }
+ else {
+ n = log2(Ninfo-24)-5;
+ Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1< 8424){
+ nr_tbs = (C<<3)*CEILIDIV((Np_info+24),(C<<3)) - 24;
+ }
+ else {
+ nr_tbs = ((CEILIDIV((Np_info+24),8))<<3) - 24;
+ }
+
+ }
+
+ }
+ return nr_tbs;
+
}
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 0954939a58..9d50b4678b 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -206,3 +206,4 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
return 0;
}
+
diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c
index 00616f2189..90586e24d4 100644
--- a/openair1/PHY/CODING/nr_segmentation.c
+++ b/openair1/PHY/CODING/nr_segmentation.c
@@ -30,25 +30,31 @@
//#define DEBUG_SEGMENTATION
int32_t nr_segmentation(unsigned char *input_buffer,
- unsigned char **output_buffers,
- unsigned int B,
- unsigned int *C,
- unsigned int *K,
- unsigned int *Zout, // [hna] Zout is Zc
- unsigned int *F)
+ unsigned char **output_buffers,
+ unsigned int B,
+ unsigned int *C,
+ unsigned int *K,
+ unsigned int *Zout, // [hna] Zout is Zc
+ unsigned int *F,
+ uint8_t BG)
{
- unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime;
+ unsigned int L,Bprime,Z,r,Kcb,Kb,k,s,crc,Kprime;
- if (B<=8448) {
+ if (BG==1)
+ Kcb=8448;
+ else
+ Kcb=3840;
+
+ if (B<=Kcb) {
L=0;
*C=1;
Bprime=B;
} else {
L=24;
- *C = B/(8448-L);
+ *C = B/(Kcb-L);
- if ((8448-L)*(*C) < B)
+ if ((Kcb-L)*(*C) < B)
*C=*C+1;
Bprime = B+((*C)*L);
@@ -63,27 +69,31 @@ int32_t nr_segmentation(unsigned char *input_buffer,
}
// Find K+
- Bprime_by_C = Bprime/(*C);
- if (Bprime <=192) {
- Kb = 6;
- } else if (Bprime <=560) {
- Kb = 8;
- } else if (Bprime <=640) {
- Kb = 9;
- } else if (Bprime <=3840) {
- Kb = 10;;
- } else {
- Kb = 22;
+ Kprime = Bprime/(*C);
+
+ if (BG==1)
+ Kb = 22;
+ else {
+ if (B > 640) {
+ Kb = 10;
+ } else if (B > 560) {
+ Kb = 9;
+ } else if (B > 192) {
+ Kb = 8;
+ }
+ else {
+ Kb = 6;
+ }
}
-if ((Bprime_by_C%Kb) > 0)
- Z = (Bprime_by_C/Kb)+1;
+if ((Kprime%Kb) > 0)
+ Z = (Kprime/Kb)+1;
else
- Z = (Bprime_by_C/Kb);
+ Z = (Kprime/Kb);
#ifdef DEBUG_SEGMENTATION
- printf("nr segmetation B %u Bprime %u Bprime_by_C %u z %u \n", B, Bprime, Bprime_by_C, Z);
+ printf("nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
#endif
if (Z <= 2) {
@@ -128,10 +138,15 @@ else
//msg("nr_segmentation.c: Illegal codeword size !!!\n");
return -1;
}
- *Zout = *K;
- *K = *K*Kb;
- *F = ((*K) - Bprime_by_C);
+ *Zout = *K;
+
+ if(BG==1)
+ *K = *K*22;
+ else
+ *K = *K*10;
+
+ *F = ((*K) - Kprime);
#ifdef DEBUG_SEGMENTATION
printf("final nr seg output Z %u K %u F %u \n", *Zout, *K, *F);
@@ -145,7 +160,6 @@ else
for (r=0; r<*C; r++) {
k = 0;
- Kprime = Bprime_by_C;
while (k<((Kprime - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
@@ -154,6 +168,13 @@ else
s++;
}
+ if (*C > 1) { // add CRC
+ crc = crc24b(output_buffers[r],Kprime-L)>>8;
+ output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2];
+ output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1];
+ output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0];
+ }
+
if (*F>0) {
for (k=Kprime>>3; k<(*K)>>3; k++) {
output_buffers[r][k] = 0;
@@ -161,16 +182,10 @@ else
}
}
- if (*C > 1) { // add CRC
- crc = crc24b(output_buffers[r],Kprime-L)>>8;
- output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2];
- output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1];
- output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0];
- }
}
}
- return 0;
+ return Kb;
}
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 7fdd6fba43..11871326e3 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -19,6 +19,7 @@
* contact@openairinterface.org
*/
+#include "executables/nr-softmodem-common.h"
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
@@ -30,7 +31,7 @@
#include "TDD-Config.h"
#include "MBSFN-SubframeConfigList.h"*/
#include "openair1/PHY/defs_RU.h"
-#include "LAYER2/MAC/mac_extern.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "assertions.h"
#include
@@ -38,6 +39,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "nfapi_nr_interface.h"
/*
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
@@ -207,24 +209,32 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (int UE_id=0; UE_idrxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
- pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
+ pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_estimates_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_estimates_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_mag0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_magb0 = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
+ pusch_vars[UE_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
- for (i=0; i<2; i++) {
+ for (i=0; inb_antennas_rx; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
- pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
+ pusch_vars[UE_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+ pusch_vars[UE_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+ pusch_vars[UE_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
+ pusch_vars[UE_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+ pusch_vars[UE_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
+ pusch_vars[UE_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
}
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
@@ -285,7 +295,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
- //NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
+ NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
/*LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
@@ -321,29 +331,38 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(prach_vars->prach_ifft[0]);
free_and_zero(prach_vars->rxsigF[0]);
-
- for (UE_id=0; UE_idrxdataF_ext[i]);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2[i]);
- free_and_zero(pusch_vars[UE_id]->drs_ch_estimates[i]);
- free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time[i]);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates[i]);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext[i]);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time[i]);
free_and_zero(pusch_vars[UE_id]->rxdataF_comp[i]);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_mag0[i]);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_magb0[i]);
free_and_zero(pusch_vars[UE_id]->ul_ch_mag[i]);
free_and_zero(pusch_vars[UE_id]->ul_ch_magb[i]);
+ free_and_zero(pusch_vars[UE_id]->rho[i]);
}
free_and_zero(pusch_vars[UE_id]->rxdataF_ext);
free_and_zero(pusch_vars[UE_id]->rxdataF_ext2);
- free_and_zero(pusch_vars[UE_id]->drs_ch_estimates);
- free_and_zero(pusch_vars[UE_id]->drs_ch_estimates_time);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_ext);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_estimates_time);
free_and_zero(pusch_vars[UE_id]->rxdataF_comp);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_mag0);
+ free_and_zero(pusch_vars[UE_id]->ul_ch_magb0);
free_and_zero(pusch_vars[UE_id]->ul_ch_mag);
free_and_zero(pusch_vars[UE_id]->ul_ch_magb);
+ free_and_zero(pusch_vars[UE_id]->rho);
+
free_and_zero(pusch_vars[UE_id]->llr);
free_and_zero(pusch_vars[UE_id]);
} //UE_id
-
+/*
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL;
*/
}
@@ -410,23 +429,25 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
gNB_config->sch_config.ssb_periodicity.value = phy_config->cfg->sch_config.ssb_periodicity.value;
if (phy_config->cfg->subframe_config.duplex_mode.value == 0) {
- gNB_config->subframe_config.duplex_mode.value = TDD;
- } else {
gNB_config->subframe_config.duplex_mode.value = FDD;
+ } else {
+ gNB_config->subframe_config.duplex_mode.value = TDD;
}
RC.gNB[Mod_id][CC_id]->mac_enabled = 1;
fp->dl_CarrierFreq = from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
- fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_nr_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
+ get_band(fp->dl_CarrierFreq, &gNB_config->nfapi_config.rf_bands.rf_band[0], &uplink_frequency_offset[CC_id][0], &fp->frame_type);
+ fp->ul_CarrierFreq = fp->dl_CarrierFreq + uplink_frequency_offset[CC_id][0];
fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
- LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u)\n",
+ LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,DL freq %u, UL freq %u)\n",
Mod_id,
CC_id,
gNB_config->nfapi_config.rf_bands.rf_band[0],
gNB_config->rf_config.dl_carrier_bandwidth.value,
gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value,
- fp->dl_CarrierFreq );
+ fp->dl_CarrierFreq,
+ fp->ul_CarrierFreq);
nr_init_frame_parms(gNB_config, fp);
@@ -485,6 +506,27 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
+
+ LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i);
+ // [hna] added here for RT implementation
+ uint8_t harq_pid = 0;
+ nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu;
+
+ // --------- setting rel15_ul parameters ----------
+ rel15_ul->rnti = 0x1234;
+ rel15_ul->ulsch_pdu_rel15.start_rb = 0;
+ rel15_ul->ulsch_pdu_rel15.number_rbs = 50;
+ rel15_ul->ulsch_pdu_rel15.start_symbol = 2;
+ rel15_ul->ulsch_pdu_rel15.number_symbols = 12;
+ rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6;
+ rel15_ul->ulsch_pdu_rel15.length_dmrs = 1;
+ rel15_ul->ulsch_pdu_rel15.Qm = 2;
+ rel15_ul->ulsch_pdu_rel15.R = 679;
+ rel15_ul->ulsch_pdu_rel15.mcs = 9;
+ rel15_ul->ulsch_pdu_rel15.rv = 0;
+ rel15_ul->ulsch_pdu_rel15.n_layers = 1;
+ ///////////////////////////////////////////////////
+
//////////////////////////////////////////////////////////////////////////
}
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index eb7b62ff99..0c7ce1cdd6 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -877,6 +877,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pbch_vars[eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
+ pbch_vars[eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pbch_vars[eNB_id]->llr = (int16_t *)malloc16_clear( 1920 ); //
prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
@@ -888,6 +889,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int idx = (j<<1)+i;
pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
pbch_vars[eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
+ pbch_vars[eNB_id]->dl_ch_estimates_time[idx]= (int32_t *)malloc16_clear( sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size) );
pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 );
}
}
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 00b2b6a7da..81785872f9 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -79,6 +79,32 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f
return symbol;
}
+int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot)
+{
+
+ uint8_t n_hf;
+ int rel_slot;
+
+ n_hf = cfg->sch_config.half_frame_index.value;
+
+ // if SSB periodicity is 5ms, they are transmitted in both half frames
+ if ( cfg->sch_config.ssb_periodicity.value == 5) {
+ if (slot<10)
+ n_hf=0;
+ else
+ n_hf=1;
+ }
+
+ // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be
+ rel_slot = (n_hf)? (slot-10) : slot;
+
+ if(rel_slot<10 && rel_slot>=0)
+ return 1;
+ else
+ return 0;
+
+}
+
int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
int mu,
@@ -224,6 +250,8 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->slots_per_frame = 10* fp->slots_per_subframe;
fp->nb_antenna_ports_eNB = 1; // default value until overwritten by RRCConnectionReconfiguration
+ fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
+ fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
@@ -254,7 +282,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
{
fp->eutra_band = config->nfapi_config.rf_bands.rf_band[0];
- fp->frame_type = !(config->subframe_config.duplex_mode.value);
+ fp->frame_type = config->subframe_config.duplex_mode.value;
fp->L_ssb = config->sch_config.ssb_scg_position_in_burst.value;
return nr_init_frame_parms0(fp,
config->subframe_config.numerology_index_mu.value,
@@ -286,6 +314,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
+ LOG_I(PHY,"fp->dl_CarrierFreq=%u\n",fp->dl_CarrierFreq);
+ LOG_I(PHY,"fp->ul_CarrierFreq=%u\n",fp->ul_CarrierFreq);
}
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index e136e8a770..7e0500b56c 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -378,6 +378,7 @@ void phy_config_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index);
+int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot);
int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index 40099f4739..57bca9e2ec 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -24,7 +24,7 @@
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
void nr_modulation(uint32_t *in,
- uint16_t length,
+ uint32_t length,
uint16_t mod_order,
int16_t *out)
{
@@ -120,6 +120,103 @@ void nr_layer_mapping(int16_t **mod_symbs,
}
}
+void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
+ uint8_t n_layers,
+ uint16_t n_symbs,
+ int16_t **tx_layers) {
+
+ int16_t *mod_symbs;
+
+ switch (n_layers) {
+
+ case 1:
+ mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
+ for (int i=0; i>15;
+ tx_layers[0][(i<<1)+1] = (mod_symbs[(i<<1)+1]*AMP)>>15;
+ }
+ break;
+
+ case 2:
+ case 3:
+ case 4:
+ mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
+
+ for (int i=0; i>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[((n_layers*i+l)<<1)+1]*AMP)>>15;
+ }
+ }
+ break;
+
+ case 5:
+ mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
+
+ for (int i=0; i>1; i++)
+ for (int l=0; l<2; l++) {
+ tx_layers[l][i<<1] = (mod_symbs[((i<<1)+l)<<1]*AMP)>>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<1)+l)<<1)+1]*AMP)>>15;
+ }
+
+ mod_symbs = (int16_t *)ulsch_ue[1]->d_mod;
+
+ for (int i=0; i>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
+ }
+ break;
+
+ case 6:
+ for (int q=0; q<2; q++){
+
+ mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
+
+ for (int i=0; i>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
+ }
+ }
+ break;
+
+ case 7:
+ mod_symbs = (int16_t *)ulsch_ue[1]->d_mod;
+
+ for (int i=0; i>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[((3*i+l)<<1)+1]*AMP)>>15;
+ }
+
+ mod_symbs = (int16_t *)ulsch_ue[0]->d_mod;
+
+ for (int i=0; i>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
+ }
+ break;
+
+ case 8:
+ for (int q=0; q<2; q++){
+
+ mod_symbs = (int16_t *)ulsch_ue[q]->d_mod;
+
+ for (int i=0; i>2; i++)
+ for (int l=0; l<3; l++) {
+ tx_layers[l][i<<1] = (mod_symbs[((i<<2)+l)<<1]*AMP)>>15;
+ tx_layers[l][(i<<1)+1] = (mod_symbs[(((i<<2)+l)<<1)+1]*AMP)>>15;
+ }
+ }
+ break;
+
+ default:
+ AssertFatal(0, "Invalid number of layers %d\n", n_layers);
+ }
+}
+
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
{
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index 249a92e8e3..8a6abd5de5 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -25,6 +25,7 @@
#include
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
+#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
#define DMRS_MOD_ORDER 2
@@ -36,7 +37,7 @@
*/
void nr_modulation(uint32_t *in,
- uint16_t length,
+ uint32_t length,
uint16_t mod_order,
int16_t *out);
@@ -52,6 +53,18 @@ void nr_layer_mapping(int16_t **mod_symbs,
uint16_t n_symbs,
int16_t **tx_layers);
+/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3
+ @param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct
+ @param[in] n_layers, number of layers
+ @param[in] n_symbs, number of modulated symbols
+ @param[out] tx_layers, modulated symbols for each layer
+*/
+
+void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
+ uint8_t n_layers,
+ uint16_t n_symbs,
+ int16_t **tx_layers);
+
/*!
\brief This function implements the OFDM front end processor on reception (FEP)
@@ -80,4 +93,4 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
*/
void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH);
-#endif
\ No newline at end of file
+#endif
diff --git a/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
new file mode 100644
index 0000000000..9c4d1fcc93
--- /dev/null
+++ b/openair1/PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file PHY/NR_ESTIMATION/nr_adjust_sync_gNB.c
+* \brief TA estimation for TA updates
+* \author Ahmed Hussein
+* \date 2019
+* \version 0.1
+* \company Fraunhofer IIS
+* \email: ahmed.hussein@iis.fraunhofer.de
+* \note
+* \warning
+*/
+
+#include "PHY/types.h"
+#include "PHY/defs_gNB.h"
+#include "PHY/phy_extern.h"
+#include "nr_ul_estimation.h"
+
+int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
+{
+ int temp, i, aa, max_pos = 0, max_val = 0;
+ short Re, Im;
+ uint8_t cyclic_shift = 0;
+
+ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+ NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
+ int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
+
+ int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size);
+
+ for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
+ temp = 0;
+
+ for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
+ Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
+ Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
+ temp += (Re*Re/2) + (Im*Im/2);
+ }
+
+ if (temp > max_val) {
+ max_pos = i;
+ max_val = temp;
+ }
+ }
+
+ if (max_pos > frame_parms->ofdm_symbol_size/2)
+ max_pos = max_pos - frame_parms->ofdm_symbol_size;
+
+
+ return max_pos - sync_pos;
+}
+
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
new file mode 100644
index 0000000000..0656091c78
--- /dev/null
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -0,0 +1,325 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+
+#include
+
+#include "nr_ul_estimation.h"
+#include "PHY/NR_REFSIG/nr_refsig.h"
+#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
+
+//#define DEBUG_CH
+
+
+int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
+ uint8_t gNB_offset,
+ unsigned char Ns,
+ unsigned short p,
+ unsigned char symbol,
+ unsigned short bwp_start_subcarrier,
+ unsigned short nb_rb_pusch)
+{
+ int pilot[1320] __attribute__((aligned(16)));
+ unsigned char aarx;
+ unsigned short k;
+ unsigned int pilot_cnt;
+ int16_t ch[2],*pil,*rxF,*ul_ch,*fl,*fm,*fr,*fml,*fmr,*fmm;
+ int ch_offset,symbol_offset, length_dmrs, UE_id = 0;
+ unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config
+ int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(16)));
+ int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time;
+
+#ifdef DEBUG_CH
+ FILE *debug_ch_est;
+ debug_ch_est = fopen("debug_ch_est.txt","w");
+#endif
+
+ //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
+
+ uint8_t nushift;
+ int **ul_ch_estimates = gNB->pusch_vars[UE_id]->ul_ch_estimates;
+ int **rxdataF = gNB->common_vars.rxdataF;
+
+ nushift = (p>>1)&1;
+ gNB->frame_parms.nushift = nushift;
+
+ ch_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
+
+ symbol_offset = gNB->frame_parms.ofdm_symbol_size*symbol;
+
+ k = bwp_start_subcarrier;
+ int re_offset = k;
+
+/*
+#ifdef DEBUG_CH
+ printf("PUSCH Channel Estimation : gNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", gNB_offset,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
+ gNB->frame_parms.Ncp,l,Ns,k, symbol);
+#endif
+*/
+ switch (nushift) {
+ case 0:
+ fl = filt8_l0;
+ fm = filt8_m0;
+ fr = filt8_r0;
+ fmm = filt8_mm0;
+ fml = filt8_m0;
+ fmr = filt8_mr0;
+ break;
+
+ case 1:
+ fl = filt8_l1;
+ fm = filt8_m1;
+ fr = filt8_r1;
+ fmm = filt8_mm1;
+ fml = filt8_ml1;
+ fmr = filt8_m1;
+ break;
+
+ default:
+ printf("pusch_channel_estimation: nushift=%d -> ERROR\n",nushift);
+ return(-1);
+ break;
+ }
+
+
+ //------------------generate DMRS------------------//
+
+ length_dmrs = 1; //to update from pusch config
+
+ nr_gold_pusch(gNB, symbol, n_idDMRS, length_dmrs);
+
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch[gNB_offset][Ns][0], &pilot[0], 1000, 0, nb_rb_pusch);
+
+ //------------------------------------------------//
+
+ for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
+
+ pil = (int16_t *)&pilot[0];
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
+ ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
+
+ memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
+
+#ifdef DEBUG_PUSCH
+ printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_DL);
+ printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset);
+ printf("rxF addr %p p %d\n", rxF,p);
+ printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
+#endif
+ //if ((gNB->frame_parms.N_RB_DL&1)==0) {
+
+ // Treat first 2 pilots specially (left edge)
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+#ifdef DEBUG_PUSCH
+ printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
+ printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
+ printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fl,
+ ch,
+ ul_ch,
+ 8);
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ //for (int i= 0; i<8; i++)
+ //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
+
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+#ifdef DEBUG_PUSCH
+ printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fml,
+ ch,
+ ul_ch,
+ 8);
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ //printf("ul_ch addr %p\n",ul_ch);
+
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+
+#ifdef DEBUG_PUSCH
+ printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fmm,
+ ch,
+ ul_ch,
+ 8);
+
+ //for (int i= 0; i<16; i++)
+ //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
+
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ul_ch+=8;
+
+ for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) {
+
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+#ifdef DEBUG_CH
+ fprintf(debug_ch_est, "pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+ //printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fm,
+ ch,
+ ul_ch,
+ 8);
+
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ 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);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+#ifdef DEBUG_PUSCH
+ 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
+ multadd_real_vector_complex_scalar(fmm,
+ ch,
+ ul_ch,
+ 8);
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ul_ch+=8;
+
+ }
+
+ // Treat first 2 pilots specially (right edge)
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+#ifdef DEBUG_PUSCH
+ printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fm,
+ ch,
+ ul_ch,
+ 8);
+
+ //for (int i= 0; i<8; i++)
+ //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
+
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ 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);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+#ifdef DEBUG_PUSCH
+ printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
+ printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fmr,
+ ch,
+ ul_ch,
+ 8);
+
+ pil+=2;
+ re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1);
+ rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
+ ul_ch+=8;
+
+ ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
+ ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
+#ifdef DEBUG_PUSCH
+ printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
+#endif
+ multadd_real_vector_complex_scalar(fr,
+ ch,
+ ul_ch,
+ 8);
+
+ // Convert to time domain
+ memset(temp_in_ifft_0, 0, gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t));
+ memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t));
+
+ switch (gNB->frame_parms.ofdm_symbol_size) {
+ case 128:
+ idft128((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 256:
+ idft256((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 512:
+ idft512((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 1024:
+ idft1024((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 1536:
+ idft1536((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 2048:
+ idft2048((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 4096:
+ idft4096((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ case 8192:
+ idft8192((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+
+ default:
+ idft512((int16_t*) temp_in_ifft_0,
+ (int16_t*) ul_ch_estimates_time[aarx],
+ 1);
+ break;
+ }
+ }
+
+#ifdef DEBUG_CH
+ fclose(debug_ch_est);
+#endif
+
+ return(0);
+}
\ No newline at end of file
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
new file mode 100644
index 0000000000..125c166f7d
--- /dev/null
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#ifndef __NR_UL_ESTIMATION_DEFS__H__
+#define __NR_UL_ESTIMATION_DEFS__H__
+
+
+#include "PHY/defs_gNB.h"
+/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_
+ * @{
+ */
+
+
+/*!
+\brief This function performs channel estimation including frequency interpolation
+\param gNB Pointer to gNB PHY variables
+\param Ns slot number (0..19)
+\param p
+\param symbol symbol within slot
+\param bwp_start_subcarrier, first allocated subcarrier
+\param nb_rb_pusch, number of allocated RBs for this UE
+*/
+
+ int32_t nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
+ uint8_t gNB_offset,
+ unsigned char Ns,
+ unsigned short p,
+ unsigned char symbol,
+ unsigned short bwp_start_subcarrier,
+ unsigned short nb_rb_pusch);
+
+int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
+
+#endif
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 8251a93254..182f8b6215 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -36,6 +36,8 @@
#include "refsig_defs_ue.h"
#include "PHY/defs_nr_UE.h"
+#include "nr_refsig.h"
+#include "PHY/defs_gNB.h"
/*Table 7.4.1.1.2-1/2 from 38.211 */
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
@@ -48,6 +50,60 @@ short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,2
short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170};
+int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
+ unsigned int Ns,
+ unsigned int *nr_gold_pusch,
+ int32_t *output,
+ unsigned short p,
+ unsigned char lp,
+ unsigned short nb_pusch_rb)
+{
+ int8_t w,config_type;
+ short *mod_table;
+ unsigned char idx=0;
+
+ typedef int array_of_w[2];
+ array_of_w *wf;
+ array_of_w *wt;
+
+ config_type = 0; //to be updated by higher layer
+
+ wf = (config_type==0) ? wf1 : wf2;
+ wt = (config_type==0) ? wt1 : wt2;
+
+ if (config_type > 1)
+ LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", config_type);
+
+ if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) {
+ if (gNB->frame_parms.Ncp == NORMAL) {
+
+ for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
+ ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
+ ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
+#ifdef DEBUG_PUSCH
+ printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", config_type, p, nb_pusch_rb);
+ printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
+ printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
+ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]);
+#endif
+ }
+ } else {
+ LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
+ }
+ } else {
+ LOG_E(PHY,"Illegal p %d PUSCH DMRS port\n",p);
+ }
+
+ return(0);
+}
+
+
+
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned int Ns,
unsigned int *nr_gold_pdsch,
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 1492d7f03f..48fcd04a0f 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -101,3 +101,59 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
}
}
}
+
+
+void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs)
+{
+
+ unsigned char ns,l;
+ unsigned int n,x1,x2,x2tmp0;
+ int nscid;
+ unsigned int nid;
+
+ /// to be updated from higher layer
+ //unsigned short lbar = 0;
+
+ for (nscid=0; nscid<2; nscid++) {
+ if (n_idDMRS)
+ nid = n_idDMRS[nscid];
+ else
+ nid = gNB->frame_parms.Nid_cell;
+
+ //printf("gold pdsch nid %d lbar %d\n",nid,lbar);
+
+ for (ns=0; ns<20; ns++) {
+
+ for (l=0; l>1) ^ (x2>>2) ^ (x2>>3))<<31);
+
+ // skip first 50 double words (1600 bits)
+ for (n=1; n<50; n++) {
+ x1 = (x1>>1) ^ (x1>>4);
+ x1 = x1 ^ (x1<<31) ^ (x1<<28);
+ x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
+ x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
+ //printf("x1 : %x, x2 : %x\n",x1,x2);
+ }
+
+ for (n=0; n>1) ^ (x1>>4);
+ x1 = x1 ^ (x1<<31) ^ (x1<<28);
+ x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
+ x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
+ gNB->nr_gold_pusch[nscid][ns][l][n] = x1^x2;
+ // if ((ns==2)&&(l==0))
+ //printf("n=%d : c %x\n",n,x1^x2);
+ }
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index cb165eed5e..e1bfa1420d 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -39,4 +39,13 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
+void nr_gold_pusch(PHY_VARS_gNB* gNB, unsigned short lbar,unsigned short *n_idDMRS, unsigned short length_dmrs);
+
+int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
+ unsigned int Ns,
+ unsigned int *nr_gold_pusch,
+ int32_t *output,
+ unsigned short p,
+ unsigned char lp,
+ unsigned short nb_pusch_rb);
#endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index ab3cf4af9b..6b89133913 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -130,7 +130,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
}
void nr_pdcch_scrambling(uint32_t *in,
- uint16_t size,
+ uint32_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t *out) {
@@ -162,8 +162,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config) {
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
- uint32_t dmrs_seq[NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD];
- uint16_t dmrs_offset=0;
uint16_t cset_start_sc;
uint8_t cset_start_symb, cset_nsymb;
int k,l,k_prime,dci_idx, dmrs_idx;
@@ -189,45 +187,20 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
dci_idx = 0;
LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
// DMRS length is per OFDM symbol
- uint16_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)?
+ uint32_t dmrs_length = (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS)?
(pdcch_params.n_rb*6) : (dci_alloc.L*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
- uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
+ uint32_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d\n", dmrs_length, encoded_length);
+ dmrs_length += pdcch_params.rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
/// DMRS QPSK modulation
- /*There is a need to shift from which index the pregenerated DMRS sequence is used
- * see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
- if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG) {
- for (int symb=cset_start_symb; symb>5;
-
- dmrs_offset = (pdcch_params.rb_offset*3)&0x1f;
- LOG_D(PHY, "PDCCH DMRS offset %d\n", dmrs_offset);
- }
-
for (int symb=cset_start_symb; symb>5)] |= ((gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]>>((i+dmrs_offset)&0x1f))&1)<<(i&0x1f);
-#ifdef DEBUG_PDCCH_DMRS
- //printf("out 0x%08x in 0x%08x \n", dmrs_seq[(i>>5)], gold_pdcch_dmrs[symb][(i+dmrs_offset)>>5]);
-#endif
- }
-
- nr_modulation(dmrs_seq, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
- } else
- nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
+
+ nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
for (int i=0; i>1; i++)
- if (dmrs_offset)
- printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i, dmrs_seq[i>>5],
- mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
- else
printf("symb %d i %d gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] );
@@ -278,32 +251,28 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
- uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0};
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
- uint8_t regs_per_symb = nb_regs/cset_nsymb;
for (int cce_idx=0; cce_idxgNB_config;
NR_gNB_DLSCH_t *dlsch;
+
uint16_t N_RB = params_rel15->n_RB_BWP;
uint8_t fsize=0, pos=0, cand_idx=0;
@@ -182,12 +183,12 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// Freq domain assignment
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos=fsize;
- *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<size-pos));
+ *dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<size-pos));
#ifdef DEBUG_FILL_DCI
printf("frequency-domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->frequency_domain_assignment,fsize,dci_alloc->size-pos,*dci_pdu);
#endif
// Time domain assignment
- pos+=4;
+ pos+=4;
*dci_pdu |= (((uint64_t)pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("time-domain assignment %d (3 bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,dci_alloc->size-pos,*dci_pdu);
@@ -246,22 +247,22 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// UL/SUL indicator 1 bit
pos++;
*dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos);
-
+
// SS/PBCH index 6 bits
pos+=6;
*dci_pdu |= ((pdu_rel15->ss_pbch_index&0x3f)<<(dci_alloc->size-pos));
-
+
// prach_mask_index 4 bits
pos+=4;
*dci_pdu |= ((pdu_rel15->prach_mask_index&0xf)<<(dci_alloc->size-pos));
-
+
} //end if
else {
// Time domain assignment 4bit
- pos+=4;
+ pos+=4;
*dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
#ifdef DEBUG_FILL_DCI
printf("Time domain assignment %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->time_domain_assignment,4,dci_alloc->size-pos,*dci_pdu);
@@ -286,7 +287,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos);
#ifdef DEBUG_FILL_DCI
printf("NDI %d (%d bits)=> %d (0x%lx)\n",pdu_rel15->ndi,1,dci_alloc->size-pos,*dci_pdu);
-#endif
+#endif
// Redundancy version 2bit
pos+=2;
@@ -334,7 +335,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
break;
case NFAPI_NR_RNTI_P:
-
+
// Short Messages Indicator – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->short_messages_indicator>>(1-i))&1)<<(dci_alloc->size-pos++);
@@ -351,7 +352,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// VRB to PRB mapping 1 bit
*dci_pdu |= ((uint64_t)pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
// MCS 5 bit
- for (int i=0; i<5; i++)
+ for (int i=0; i<5; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
// TB scaling 2 bit
@@ -360,7 +361,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
break;
-
+
case NFAPI_NR_RNTI_SI:
// Freq domain assignment 0-16 bit
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
@@ -377,9 +378,9 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
-
+
break;
-
+
case NFAPI_NR_RNTI_TC:
// indicating a DL DCI format 1bit
*dci_pdu |= ((uint64_t)pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
@@ -400,14 +401,14 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
+ // HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
-
+
// Downlink assignment index – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++);
-
+
// TPC command for scheduled PUCCH – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
@@ -420,7 +421,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// PDSCH-to-HARQ_feedback timing indicator – 3 bits
for (int i=0; i<3; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
-
+
break;
}
break;
@@ -448,10 +449,10 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
+ // HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
-
+
// TPC command for scheduled PUSCH – 2 bits
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
@@ -463,11 +464,11 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// UL/SUL indicator – 1 bit
if (cfg->pucch_config.pucch_GroupHopping.value)
*dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
-
+
break;
-
+
case NFAPI_NR_RNTI_TC:
-
+
// indicating a DL DCI format 1bit
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
// Freq domain assignment max 16 bit
@@ -487,7 +488,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
// Redundancy version 2bit
for (int i=0; i<2; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
- // HARQ process number 4bit
+ // HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= (((uint64_t)pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
@@ -504,7 +505,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB,
*dci_pdu |= ((uint64_t)pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
break;
- }
+ }
break;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index aa75bd6555..665e9a690c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -39,11 +39,11 @@
//#define DEBUG_DLSCH_MAPPING
void nr_pdsch_codeword_scrambling(uint8_t *in,
- uint16_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI,
- uint32_t* out) {
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI,
+ uint32_t* out) {
uint8_t reset, b_idx;
uint32_t x1, x2, s=0;
@@ -88,7 +88,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
uint16_t nb_symbols = rel15->nb_mod_symbols;
uint8_t Qm = rel15->modulation_order;
- uint16_t encoded_length = nb_symbols*Qm;
+ uint32_t encoded_length = nb_symbols*Qm;
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
@@ -121,11 +121,12 @@ printf("\n");
pdcch_params.scrambling_id : config->sch_config.physical_cell_id.value;
for (int q=0; qnb_codewords; q++)
nr_pdsch_codeword_scrambling(harq->f,
- encoded_length,
- q,
- Nid,
- n_RNTI,
- scrambled_output[q]);
+ encoded_length,
+ q,
+ Nid,
+ n_RNTI,
+ scrambled_output[q]);
+
stop_meas(dlsch_scrambling_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH scrambling:\n");
@@ -175,7 +176,7 @@ for (int l=0; lnb_layers; l++)
//to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
/// DMRS QPSK modulation
- uint16_t n_dmrs = (rel15->n_prb*rel15->nb_re_dmrs)<<1;
+ uint16_t n_dmrs = ((rel15->n_prb+rel15->start_prb)*rel15->nb_re_dmrs)<<1;
int16_t mod_dmrs[n_dmrs<<1];
uint8_t dmrs_type = config->pdsch_config.dmrs_type.value;
uint8_t mapping_type = config->pdsch_config.mapping_type.value;
@@ -220,6 +221,10 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
#endif
uint8_t k_prime=0;
uint16_t m=0, n=0, dmrs_idx=0, k=0;
+ if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
+ dmrs_idx = rel15->start_prb*6;
+ else
+ dmrs_idx = rel15->start_prb*4;
for (int l=rel15->start_symbol; lstart_symbol+rel15->nb_symbols; l++) {
k = start_sc;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
index 3419be30fa..d982a17ea7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h
@@ -54,11 +54,11 @@ void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list);
void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type);
void nr_pdsch_codeword_scrambling(uint8_t *in,
- uint16_t size,
- uint8_t q,
- uint32_t Nid,
- uint32_t n_RNTI,
- uint32_t* out);
+ uint32_t size,
+ uint8_t q,
+ uint32_t Nid,
+ uint32_t n_RNTI,
+ uint32_t* out);
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
index 14371e89e2..d001141f37 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c
@@ -283,18 +283,21 @@ int nr_dlsch_encoding(unsigned char *a,
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
uint16_t nb_rb = rel15.n_prb;
uint8_t nb_symb_sch = rel15.nb_symbols;
- uint32_t A, Z, F=0;
- uint32_t *pz = &Z;
+ uint32_t A, Z, Kb, F=0;
+ uint32_t *Zc = &Z;
uint8_t mod_order = rel15.modulation_order;
- uint16_t Kr=0,r,r_offset=0;
+ uint16_t Kr=0,r;
+ uint32_t r_offset=0;
//uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t BG=1;
uint32_t E;
- uint8_t Ilbrm = 0;
+ uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984; //max tbs
uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
+ uint16_t R=rel15.coding_rate;
uint16_t length_dmrs = 1;
float Coderate = 0.0;
+ uint8_t Nl = 4;
/*
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
@@ -310,9 +313,6 @@ int nr_dlsch_encoding(unsigned char *a,
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
-
-
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
@@ -326,38 +326,58 @@ int nr_dlsch_encoding(unsigned char *a,
printf("%02x.",a[i]);
printf("\n");
*/
- // Add 24-bit crc (polynomial A) to payload
- crc = crc24a(a,A)>>8;
- a[A>>3] = ((uint8_t*)&crc)[2];
- a[1+(A>>3)] = ((uint8_t*)&crc)[1];
- a[2+(A>>3)] = ((uint8_t*)&crc)[0];
- //printf("CRC %x (A %d)\n",crc,A);
- //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
- dlsch->harq_processes[harq_pid]->B = A+24;
- // dlsch->harq_processes[harq_pid]->b = a;
+ if (A > 3824) {
+ // Add 24-bit crc (polynomial A) to payload
+ crc = crc24a(a,A)>>8;
+ a[A>>3] = ((uint8_t*)&crc)[2];
+ a[1+(A>>3)] = ((uint8_t*)&crc)[1];
+ a[2+(A>>3)] = ((uint8_t*)&crc)[0];
+ //printf("CRC %x (A %d)\n",crc,A);
+ //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
+
+ dlsch->harq_processes[harq_pid]->B = A+24;
+ // dlsch->harq_processes[harq_pid]->b = a;
- AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES);
+ AssertFatal((A/8)+4 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,MAX_DLSCH_PAYLOAD_BYTES);
- memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
+ memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); // why is this +4 if the CRC is only 3 bytes?
+ }
+ else {
+ // Add 16-bit crc (polynomial A) to payload
+ crc = crc16(a,A)>>16;
+ a[A>>3] = ((uint8_t*)&crc)[1];
+ a[1+(A>>3)] = ((uint8_t*)&crc)[0];
+ //printf("CRC %x (A %d)\n",crc,A);
+ //printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
+
+ dlsch->harq_processes[harq_pid]->B = A+16;
+ // dlsch->harq_processes[harq_pid]->b = a;
+
+ AssertFatal((A/8)+3 <= MAX_DLSCH_PAYLOAD_BYTES,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,MAX_DLSCH_PAYLOAD_BYTES);
- nr_segmentation(dlsch->harq_processes[harq_pid]->b,
- dlsch->harq_processes[harq_pid]->c,
- dlsch->harq_processes[harq_pid]->B,
- &dlsch->harq_processes[harq_pid]->C,
- &dlsch->harq_processes[harq_pid]->K,
- pz, // [hna] pz is Zc
- &dlsch->harq_processes[harq_pid]->F);
+ memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc
+ }
+ if (R<1000)
+ Coderate = (float) R /(float) 1024;
+ else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
+ Coderate = (float) R /(float) 2048;
+
+ if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
+ BG = 2;
+ else
+ BG = 1;
+
+ Kb = nr_segmentation(dlsch->harq_processes[harq_pid]->b,
+ dlsch->harq_processes[harq_pid]->c,
+ dlsch->harq_processes[harq_pid]->B,
+ &dlsch->harq_processes[harq_pid]->C,
+ &dlsch->harq_processes[harq_pid]->K,
+ Zc,
+ &dlsch->harq_processes[harq_pid]->F,
+ BG);
F = dlsch->harq_processes[harq_pid]->F;
- Coderate = (float) A /(float) G;
-
- if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
- BG = 2;
- }
- else{
- BG = 1;
- }
Kr = dlsch->harq_processes[harq_pid]->K;
#ifdef DEBUG_DLSCH_CODING
@@ -365,7 +385,7 @@ int nr_dlsch_encoding(unsigned char *a,
Kr_bytes = Kr>>3;
#endif
- //printf("segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG);
+ //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,dlsch->harq_processes[harq_pid]->K,Kr,BG,dlsch->harq_processes[harq_pid]->C);
for (r=0; rharq_processes[harq_pid]->C; r++) {
//d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
@@ -374,32 +394,21 @@ int nr_dlsch_encoding(unsigned char *a,
printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C);
printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
- for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
+ for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){
printf("%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]);
}
printf("\n");
#endif
- //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0);
- //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,BG,NULL,NULL,NULL,NULL);
+ //ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],*Zc,Kb,Kr,BG,0);
+ //ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
}
- //for (int i=0;i<68*384;i++)
- // printf("channel_input[%d]=%d\n",i,channel_input[i]);
+ for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) {
+ ldpc_encoder_optim_8seg_multi(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,dlsch->harq_processes[harq_pid]->C,j,NULL,NULL,NULL,NULL);
+ }
-
- /*printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]);
- for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
- printf("%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]);
- }
- printf("\n");*/
-
- //ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL);
- ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL);
-
- //printf("end ldpc encoder -- output\n");
-
#ifdef DEBUG_DLSCH_CODING
write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4);
@@ -409,13 +418,14 @@ int nr_dlsch_encoding(unsigned char *a,
for (r=0; rharq_processes[harq_pid]->C; r++) {
- if (dlsch->harq_processes[harq_pid]->F>0) {
- for (int k=(Kr-F-2*(*pz)); kharq_processes[harq_pid]->d[r][k] = NR_NULL;
- //if (k<(Kr-F+8))
- //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
- }
- }
+ if (dlsch->harq_processes[harq_pid]->F>0) {
+ for (int k=(Kr-F-2*(*Zc)); kharq_processes[harq_pid]->d[r][k] = NR_NULL;
+ //if (k<(Kr-F+8))
+ //printf("r %d filler bits [%d] = %d \n", r,k, dlsch->harq_processes[harq_pid]->d[r][k]);
+ }
+ }
+
#ifdef DEBUG_DLSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n",
r,
@@ -430,26 +440,31 @@ int nr_dlsch_encoding(unsigned char *a,
E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
+ // for tbslbrm calculation according to 5.4.2.1 of 38.212
+ if (rel15.nb_layers < Nl)
+ Nl = rel15.nb_layers;
+
+ Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
- *pz,
+ *Zc,
dlsch->harq_processes[harq_pid]->d[r],
dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C,
rel15.redundancy_version,
E);
-
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
#endif
nr_interleaving_ldpc(E,
- mod_order,
- dlsch->harq_processes[harq_pid]->e+r_offset,
- dlsch->harq_processes[harq_pid]->f+r_offset);
+ mod_order,
+ dlsch->harq_processes[harq_pid]->e+r_offset,
+ dlsch->harq_processes[harq_pid]->f+r_offset);
#ifdef DEBUG_DLSCH_CODING
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
index 8d9bf00639..303282929f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
@@ -85,7 +85,7 @@ uint8_t get_delta(uint8_t ap, uint8_t config) {
return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2]));
}
-uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) {
+uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) {
uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta);
return dmrs_idx;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
index 02f454b7d0..6f07874ca0 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.h
@@ -45,6 +45,6 @@ void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config);
uint8_t get_delta(uint8_t ap, uint8_t config);
-uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
+uint16_t get_dmrs_freq_idx(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
index 07ca17cd6d..10ac17acab 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -31,32 +31,42 @@
*/
#include "nr_transport_common_proto.h"
+#include "PHY/CODING/coding_defs.h"
-/// Target code rate tables indexed by Imcs
-uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
- 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
- // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
-uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
- 616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
-uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
- 378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
-uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
- 336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
- 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
- 3104, 3240, 3368, 3496, 3624, 3752, 3824};
+//Table 5.1.3.1-1 of 38.214
+uint16_t Table_51311[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
+ {4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
-uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
+//Table 5.1.3.1-2 of 38.214
+// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
+uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{6,466},{6,517},{6,567},{6,616},{6,666},
+ {6,719},{6,772},{6,822},{6,873},{8,1365},{8,711},{8,754},{8,797},{8,841},{8,885},{8,1833},{8,948}};
+
+//Table 5.1.3.1-3 of 38.214
+uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340},
+ {4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}};
+
+//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK
+uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
+ {4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
+
+//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK
+uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},
+ {4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}};
+
+
+uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
+ case 0:
+ return (Table_51311[Imcs][0]);
+ break;
+
case 1:
- return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+ return (Table_51312[Imcs][0]);
break;
case 2:
- return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
- break;
-
- case 3:
- return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
+ return (Table_51313[Imcs][0]);
break;
default:
@@ -64,18 +74,18 @@ uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
}
}
-uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
+uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
+ case 0:
+ return (Table_51311[Imcs][1]);
+ break;
+
case 1:
- return (nr_target_code_rate_table1[Imcs]);
+ return (Table_51312[Imcs][1]);
break;
case 2:
- return (nr_target_code_rate_table2[Imcs]);
- break;
-
- case 3:
- return (nr_target_code_rate_table3[Imcs]);
+ return (Table_51313[Imcs][1]);
break;
default:
@@ -83,6 +93,60 @@ uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
}
}
+uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
+ switch(table_idx) {
+ case 0:
+ return (Table_51311[Imcs][0]);
+ break;
+
+ case 1:
+ return (Table_51312[Imcs][0]);
+ break;
+
+ case 2:
+ return (Table_51313[Imcs][0]);
+ break;
+
+ case 3:
+ return (Table_61411[Imcs][0]);
+ break;
+
+ case 4:
+ return (Table_61412[Imcs][0]);
+ break;
+
+ default:
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+ }
+}
+
+uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
+ switch(table_idx) {
+ case 0:
+ return (Table_51311[Imcs][1]);
+ break;
+
+ case 1:
+ return (Table_51312[Imcs][1]);
+ break;
+
+ case 2:
+ return (Table_51313[Imcs][1]);
+ break;
+
+ case 3:
+ return (Table_61411[Imcs][1]);
+ break;
+
+ case 4:
+ return (Table_61412[Imcs][1]);
+ break;
+
+ default:
+ AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx);
+ }
+}
+
static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) {
return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1));
}
@@ -103,16 +167,16 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8
return 1;
}
-void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
- nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
- nfapi_nr_config_request_t config) {
+void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+ nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
+ nfapi_nr_config_request_t config) {
LOG_D(MAC, "TBS calculation\n");
nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
uint8_t rnti_type = params_rel15.rnti_type;
- uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
+ uint16_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
(config.pdsch_config.x_overhead.value);
uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
@@ -120,56 +184,35 @@ void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
- uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R;
- uint8_t table_idx, Qm, n, scale;
+ uint16_t R;
+ uint32_t TBS=0;
+ uint8_t table_idx, Qm;
/*uint8_t mcs_table = config.pdsch_config.mcs_table.value;
uint8_t ss_type = params_rel15.search_space_type;
uint8_t dci_format = params_rel15.dci_format;
get_table_idx(mcs_table, dci_format, rnti_type, ss_type);*/
- table_idx = 1;
- scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
-
- N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
- R = nr_get_code_rate(Imcs, table_idx);
- Qm = nr_get_Qm(Imcs, table_idx);
- Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale;
+ table_idx = 0;
+ R = nr_get_code_rate_dl(Imcs, table_idx);
+ Qm = nr_get_Qm_dl(Imcs, table_idx);
- if (Ninfo <= 3824) {
- n = max(3, (log2(Ninfo)-6));
- Ninfo_prime = max(24, (Ninfo>>n)<= Ninfo_prime) {
- TBS = nr_tbs_table[i];
- break;
- }
- }
- else {
- n = log2(Ninfo-24)-5;
- Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<8424) {
- C = CEILIDIV((Ninfo_prime+24),8424);
- TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
- }
- else
- TBS = ((CEILIDIV((Ninfo_prime+24),8))<<3) - 24;
- }
- }
+ TBS = nr_compute_tbs(Qm,
+ R,
+ dlsch_rel15->n_prb,
+ N_sh_symb,
+ N_PRB_DMRS,
+ N_PRB_oh,
+ dlsch_rel15->nb_layers);
dlsch_rel15->coding_rate = R;
dlsch_rel15->modulation_order = Qm;
dlsch_rel15->transport_block_size = TBS;
dlsch_rel15->nb_re_dmrs = N_PRB_DMRS;
dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords;
+ dlsch_rel15->mcs_table = table_idx;
- LOG_D(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n",
- TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols);
+ LOG_D(MAC, "TBS %d : N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d R %d Qm %d table %d nb_symbols %d\n",
+ TBS, N_PRB_DMRS, N_sh_symb, N_PRB_oh, R, Qm, table_idx, dlsch_rel15->nb_mod_symbols);
}
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
index 36f3fb5c2c..6a88203f8c 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h
@@ -48,14 +48,17 @@
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
#define NR_PUSCH_y 3 // UCI placeholder bit
-/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */
-uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
+/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
+uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
+uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
-uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
+/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
+uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
+uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
-void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
- nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
- nfapi_nr_config_request_t config);
+void nr_get_tbs_dl(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
+ nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
+ nfapi_nr_config_request_t config);
/** \brief Computes available bits G. */
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 2dbef1d733..aa5d16f613 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -65,7 +65,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
*/
void nr_ulsch_extract_rbs_single(int **rxdataF,
+ int **ul_ch_estimates,
int **rxdataF_ext,
+ int **ul_ch_estimates_ext,
uint32_t rxdataF_ext_offset,
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
unsigned char symbol,
@@ -73,6 +75,54 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
unsigned short nb_rb_pusch,
NR_DL_FRAME_PARMS *frame_parms);
+void nr_ulsch_scale_channel(int32_t **ul_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_gNB_ULSCH_t **ulsch_gNB,
+ uint8_t symbol,
+ uint8_t start_symbol,
+ uint16_t nb_rb);
+
+
+/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
+ @param ul_ch_estimates_ext Channel estimates in allocated RBs
+ @param frame_parms Pointer to frame descriptor
+ @param avg Pointer to average signal strength
+ @param pilots_flag Flag to indicate pilots in symbol
+ @param nb_rb Number of allocated RBs
+*/
+void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ int32_t *avg,
+ uint8_t symbol,
+ uint32_t len,
+ unsigned short nb_rb);
+
+
+/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
+ @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
+ @param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
+ @param ul_ch_mag First Channel magnitudes (16QAM/64QAM)
+ @param ul_ch_magb Second weighted Channel magnitudes (64QAM)
+ @param rxdataF_comp Compensated received waveform
+ @param frame_parms Pointer to frame descriptor
+ @param symbol Symbol on which to operate
+ @param Qm Modulation order of allocation
+ @param nb_rb Number of RBs in allocation
+ @param output_shift Rescaling for compensated output (should be energy-normalizing)
+*/
+void nr_ulsch_channel_compensation(int **rxdataF_ext,
+ int **ul_ch_estimates_ext,
+ int **ul_ch_mag,
+ int **ul_ch_magb,
+ int **rxdataF_comp,
+ int **rho,
+ NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ uint8_t pilots,
+ unsigned char mod_order,
+ unsigned short nb_rb,
+ unsigned char output_shift);
+
/*!
\brief This function implements the idft transform precoding in PUSCH
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
@@ -102,6 +152,7 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int16_t *ulsch_llr,
+ uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol);
@@ -118,6 +169,7 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
+ uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol);
@@ -135,6 +187,7 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
+ uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order);
\ No newline at end of file
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
index 11521563e4..4942ffe2f4 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h
@@ -75,7 +75,8 @@ void nr_ulsch_unscrambling(int16_t* llr,
void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
- gNB_L1_rxtx_proc_t *proc,
+ int frame_rx,
+ int slot_rx,
int UE_id,
uint8_t harq_pid);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 6ca2733120..3b79d425ad 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -50,6 +50,7 @@
//#define DEBUG_ULSCH_DECODING
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
+#define PRINT_CRC_CHECK
static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0;
@@ -176,96 +177,96 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
unsigned char i, j;
if (ulsch) {
- ulsch->harq_mask = 0;
- ulsch->bundling = 0;
- ulsch->beta_offset_cqi_times8 = 0;
- ulsch->beta_offset_ri_times8 = 0;
- ulsch->beta_offset_harqack_times8 = 0;
- ulsch->Msg3_active = 0;
- ulsch->Msg3_flag = 0;
- ulsch->Msg3_subframe = 0;
- ulsch->Msg3_frame = 0;
- ulsch->rnti = 0;
- ulsch->rnti_type = 0;
- ulsch->cyclicShift = 0;
- ulsch->cooperation_flag = 0;
- ulsch->Mlimit = 0;
- ulsch->max_ldpc_iterations = 0;
- ulsch->last_iteration_cnt = 0;
- ulsch->num_active_cba_groups = 0;
- for (i=0;icba_rnti[i] = 0;
- for (i=0;iharq_process_id[i] = 0;
+ ulsch->harq_mask = 0;
+ ulsch->bundling = 0;
+ ulsch->beta_offset_cqi_times8 = 0;
+ ulsch->beta_offset_ri_times8 = 0;
+ ulsch->beta_offset_harqack_times8 = 0;
+ ulsch->Msg3_active = 0;
+ ulsch->Msg3_flag = 0;
+ ulsch->Msg3_subframe = 0;
+ ulsch->Msg3_frame = 0;
+ ulsch->rnti = 0;
+ ulsch->rnti_type = 0;
+ ulsch->cyclicShift = 0;
+ ulsch->cooperation_flag = 0;
+ ulsch->Mlimit = 0;
+ ulsch->max_ldpc_iterations = 0;
+ ulsch->last_iteration_cnt = 0;
+ ulsch->num_active_cba_groups = 0;
+ for (i=0;icba_rnti[i] = 0;
+ for (i=0;iharq_process_id[i] = 0;
- for (i=0; iharq_processes[i]){
- /// Nfapi ULSCH PDU
- //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
- ulsch->harq_processes[i]->frame=0;
- ulsch->harq_processes[i]->subframe=0;
- ulsch->harq_processes[i]->round=0;
- ulsch->harq_processes[i]->TPC=0;
- ulsch->harq_processes[i]->mimo_mode=0;
- ulsch->harq_processes[i]->dci_alloc=0;
- ulsch->harq_processes[i]->rar_alloc=0;
- ulsch->harq_processes[i]->status=0;
- ulsch->harq_processes[i]->subframe_scheduling_flag=0;
- ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
- ulsch->harq_processes[i]->phich_active=0;
- ulsch->harq_processes[i]->phich_ACK=0;
- ulsch->harq_processes[i]->previous_first_rb=0;
- ulsch->harq_processes[i]->handled=0;
- ulsch->harq_processes[i]->delta_TF=0;
+ for (i=0; iharq_processes[i]){
+ /// Nfapi ULSCH PDU
+ //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
+ ulsch->harq_processes[i]->frame=0;
+ ulsch->harq_processes[i]->subframe=0;
+ ulsch->harq_processes[i]->round=0;
+ ulsch->harq_processes[i]->TPC=0;
+ ulsch->harq_processes[i]->mimo_mode=0;
+ ulsch->harq_processes[i]->dci_alloc=0;
+ ulsch->harq_processes[i]->rar_alloc=0;
+ ulsch->harq_processes[i]->status=0;
+ ulsch->harq_processes[i]->subframe_scheduling_flag=0;
+ ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0;
+ ulsch->harq_processes[i]->phich_active=0;
+ ulsch->harq_processes[i]->phich_ACK=0;
+ ulsch->harq_processes[i]->previous_first_rb=0;
+ ulsch->harq_processes[i]->handled=0;
+ ulsch->harq_processes[i]->delta_TF=0;
- ulsch->harq_processes[i]->TBS=0;
- /// Pointer to the payload (38.212 V15.4.0 section 5.1)
- //uint8_t *b;
- ulsch->harq_processes[i]->B=0;
- /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
- //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
- ulsch->harq_processes[i]->K=0;
- ulsch->harq_processes[i]->F=0;
- ulsch->harq_processes[i]->C=0;
- /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
- //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
- /// LDPC processing buffer
- //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
- ulsch->harq_processes[i]->Z=0;
- /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
- //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
- ulsch->harq_processes[i]->E=0;
+ ulsch->harq_processes[i]->TBS=0;
+ /// Pointer to the payload (38.212 V15.4.0 section 5.1)
+ //uint8_t *b;
+ ulsch->harq_processes[i]->B=0;
+ /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
+ //uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
+ ulsch->harq_processes[i]->K=0;
+ ulsch->harq_processes[i]->F=0;
+ ulsch->harq_processes[i]->C=0;
+ /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
+ //int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
+ /// LDPC processing buffer
+ //t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
+ ulsch->harq_processes[i]->Z=0;
+ /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
+ //int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
+ ulsch->harq_processes[i]->E=0;
- ulsch->harq_processes[i]->n_DMRS=0;
- ulsch->harq_processes[i]->n_DMRS2=0;
- ulsch->harq_processes[i]->previous_n_DMRS=0;
+ ulsch->harq_processes[i]->n_DMRS=0;
+ ulsch->harq_processes[i]->n_DMRS2=0;
+ ulsch->harq_processes[i]->previous_n_DMRS=0;
- ulsch->harq_processes[i]->cqi_crc_status=0;
- for (j=0;jharq_processes[i]->o[j]=0;
- ulsch->harq_processes[i]->uci_format=0;
- ulsch->harq_processes[i]->Or1=0;
- ulsch->harq_processes[i]->Or2=0;
- ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0;
- ulsch->harq_processes[i]->O_RI=0;
- ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0;
- ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0;
- ulsch->harq_processes[i]->O_ACK=0;
- ulsch->harq_processes[i]->V_UL_DAI=0;
- /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
- //int8_t q[MAX_CQI_PAYLOAD];
- ulsch->harq_processes[i]->o_RCC=0;
- /// coded and interleaved CQI bits
- //int8_t o_w[(MAX_CQI_BITS+8)*3];
- /// coded CQI bits
- //int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
- for (j=0;jharq_processes[i]->q_ACK[j]=0;
- for (j=0;jharq_processes[i]->q_RI[j]=0;
- /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
- //uint8_t h[MAX_NUM_CHANNEL_BITS];
- /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
- //int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
- }
- }
+ ulsch->harq_processes[i]->cqi_crc_status=0;
+ for (j=0;jharq_processes[i]->o[j]=0;
+ ulsch->harq_processes[i]->uci_format=0;
+ ulsch->harq_processes[i]->Or1=0;
+ ulsch->harq_processes[i]->Or2=0;
+ ulsch->harq_processes[i]->o_RI[0]=0; ulsch->harq_processes[i]->o_RI[1]=0;
+ ulsch->harq_processes[i]->O_RI=0;
+ ulsch->harq_processes[i]->o_ACK[0]=0; ulsch->harq_processes[i]->o_ACK[1]=0;
+ ulsch->harq_processes[i]->o_ACK[2]=0; ulsch->harq_processes[i]->o_ACK[3]=0;
+ ulsch->harq_processes[i]->O_ACK=0;
+ ulsch->harq_processes[i]->V_UL_DAI=0;
+ /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
+ //int8_t q[MAX_CQI_PAYLOAD];
+ ulsch->harq_processes[i]->o_RCC=0;
+ /// coded and interleaved CQI bits
+ //int8_t o_w[(MAX_CQI_BITS+8)*3];
+ /// coded CQI bits
+ //int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
+ for (j=0;jharq_processes[i]->q_ACK[j]=0;
+ for (j=0;jharq_processes[i]->q_RI[j]=0;
+ /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
+ //uint8_t h[MAX_NUM_CHANNEL_BITS];
+ /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
+ //int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
+ }
+ }
}
}
@@ -287,7 +288,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
uint8_t crc_type;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
-
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
@@ -310,6 +310,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm;
+ uint16_t R = nfapi_ulsch_pdu_rel15->R;
uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs;
uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers;
uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs;
@@ -324,60 +325,42 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (!ulsch_llr) {
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
- return(ulsch->max_ldpc_iterations);
+ return (ulsch->max_ldpc_iterations + 1);
}
if (!harq_process) {
printf("ulsch_decoding.c: NULL harq_process pointer\n");
- return(ulsch->max_ldpc_iterations);
+ return (ulsch->max_ldpc_iterations + 1);
}
if (!frame_parms) {
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
- return(ulsch->max_ldpc_iterations);
+ return (ulsch->max_ldpc_iterations + 1);
}
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
-
- harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers);
+ harq_process->TBS = nr_compute_tbs(Qm, R, nb_rb, number_symbols, nb_re_dmrs*length_dmrs, 0, n_layers);
A = harq_process->TBS;
- ret = ulsch->max_ldpc_iterations;
-
- G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers);
- // G = 0;
- // G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers);
+ ret = ulsch->max_ldpc_iterations + 1;
- LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb);
+ G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers);
+
+ LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb);
if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
harq_process->B = A+24;
- // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
- nr_segmentation(NULL,
- NULL,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- &harq_process->Z, // [hna] Z is Zc
- &harq_process->F);
+ if (R<1024)
+ Coderate = (float) R /(float) 1024;
+ else
+ Coderate = (float) R /(float) 2048;
- p_decParams->Z = harq_process->Z;
-
-#ifdef DEBUG_ULSCH_DECODING
- printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z);
- if (!frame%100)
- printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
-#endif
- }
-
- Coderate = (float) A /(float) G;
-
- if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
- p_decParams->BG = 2;
- if (Coderate < 0.3333) {
+ if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
+ p_decParams->BG = 2;
+ if (Coderate < 0.3333) {
p_decParams->R = 15;
kc = 52;
}
@@ -405,8 +388,23 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
}
- //printf("coderate %f kc %d \n", Coderate, kc);
+ // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
+ nr_segmentation(NULL,
+ NULL,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ &harq_process->Z, // [hna] Z is Zc
+ &harq_process->F,
+ p_decParams->BG);
+#ifdef DEBUG_ULSCH_DECODING
+ printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
+ if (!frame%100)
+ printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, harq_process->Nl);
+#endif
+ }
+ p_decParams->Z = harq_process->Z;
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
@@ -430,21 +428,19 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling);
- return((1+ulsch->max_ldpc_iterations));
+ return (ulsch->max_ldpc_iterations + 1);
}
#ifdef DEBUG_ULSCH_DECODING
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
- opp_enabled=1;
+ //opp_enabled=1;
- Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
+ Kr = harq_process->K;
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers);
-
for (r=0; rC; r++) {
E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
@@ -494,6 +490,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
+ Tbslbrm = nr_compute_tbslbrm(0,nb_rb,nfapi_ulsch_pdu_rel15->n_layers,harq_process->C);
+
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
@@ -508,7 +506,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
stop_meas(ulsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
- return(ulsch->max_ldpc_iterations);
+ return (ulsch->max_ldpc_iterations + 1);
} else {
#if gNB_TIMING_TRACE
stop_meas(ulsch_rate_unmatching_stats);
@@ -584,19 +582,22 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
+ #ifdef PRINT_CRC_CHECK
LOG_I(PHY, "Segment %d CRC OK\n",r);
- ret = 2;
+ #endif
+ ret = no_iteration_ldpc;
} else {
+ #ifdef PRINT_CRC_CHECK
LOG_I(PHY, "CRC NOK\n");
- ret = 1+ulsch->max_ldpc_iterations;
+ #endif
+ ret = ulsch->max_ldpc_iterations + 1;
}
-
+
nb_total_decod++;
+
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
nb_error_decod++;
}
-
- ret=no_iteration_ldpc;
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
@@ -615,7 +616,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
#endif
}
- if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) {
+ if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
err_flag = 1;
@@ -642,7 +643,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// harq_process->harq_ack.harq_id = harq_pid;
// harq_process->harq_ack.send_harq_status = 1;
// harq_process->errors[harq_process->round]++;
- harq_process->round++;
+ //harq_process->round++;
if (harq_process->round >= ulsch->Mlimit) {
harq_process->status = SCH_IDLE;
@@ -657,7 +658,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
harq_process->handled = 1;
- return((1+ulsch->max_ldpc_iterations));
+ return (ulsch->max_ldpc_iterations + 1);
} else {
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index d70e61e358..e1b3c5cec9 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -3,8 +3,13 @@
#include "nr_transport_proto.h"
#include "PHY/impl_defs_top.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
+#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "PHY/defs_nr_common.h"
+//#define DEBUG_CH_COMP
+//#define DEBUG_RB_EXT
+//#define DEBUG_CH_MAG
+
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
{
@@ -216,7 +221,9 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
}
void nr_ulsch_extract_rbs_single(int **rxdataF,
+ int **ul_ch_estimates,
int **rxdataF_ext,
+ int **ul_ch_estimates_ext,
uint32_t rxdataF_ext_offset,
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
unsigned char symbol,
@@ -227,12 +234,22 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx, is_dmrs_symbol = 0;
uint32_t rxF_ext_index = 0;
+ uint32_t ul_ch0_ext_index = 0;
+ uint32_t ul_ch0_index = 0;
int16_t *rxF,*rxF_ext;
+ int *ul_ch0,*ul_ch0_ext;
+
+#ifdef DEBUG_RB_EXT
+
+ printf("--------------------symbol = %d-----------------------\n", symbol);
+ printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * nb_rb_pusch);
+
+#endif
is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config
- start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB);
+ start_re = (frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
@@ -241,19 +258,710 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
+ ul_ch0 = &ul_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; // DMRS REs are only in symbol 2 (to be updated from config)
+ ul_ch0_ext = &ul_ch_estimates_ext[aarx][symbol*nb_re_pusch];
+
for (re = 0; re < nb_re_pusch; re++) {
if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
// frame_parms->nushift should be initialized with 0
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
+ ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
+
+ #ifdef DEBUG_RB_EXT
+ printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]);
+ printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]);
+ printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index]);
+ printf("ul_ch0_ext[%d] = %d\n", 2*ul_ch0_ext_index + 1, ((int16_t *)ul_ch0_ext)[2*ul_ch0_ext_index + 1]);
+ #endif
+
rxF_ext_index = rxF_ext_index + 2;
+ ul_ch0_ext_index++;
}
+ ul_ch0_index++;
}
}
}
+void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
+ NR_DL_FRAME_PARMS *frame_parms,
+ NR_gNB_ULSCH_t **ulsch_gNB,
+ uint8_t symbol,
+ uint8_t pilots,
+ unsigned short nb_rb)
+{
+#if defined(__x86_64__)||defined(__i386__)
+
+ short rb, ch_amp;
+ unsigned char aatx,aarx;
+ __m128i *ul_ch128, ch_amp128;
+
+ // Determine scaling amplitude based the symbol
+
+ ch_amp = 1024*8; //((pilots) ? (ulsch_gNB[0]->sqrt_rho_b) : (ulsch_gNB[0]->sqrt_rho_a));
+
+ LOG_D(PHY,"Scaling PUSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n", symbol, ch_amp, pilots, nb_rb, frame_parms->Ncp, symbol);
+ // printf("Scaling PUSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
+
+ ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13
+
+ for (aatx=0; aatx < frame_parms->nb_antenna_ports_eNB; aatx++) {
+ for (aarx=0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+
+ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*nb_rb*NR_NB_SC_PER_RB];
+
+ if (pilots==1){
+ nb_rb = nb_rb>>1;
+ }
+
+
+ for (rb=0;rb>x;
+
+ for (aatx = 0; aatx < frame_parms->nb_antennas_tx; aatx++)
+ for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
+ //clear average level
+ avg128U = _mm_setzero_si128();
+
+ ul_ch128=(__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
+
+ for (rb = 0; rb < nb_rb; rb++) {
+ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[0], ul_ch128[0]), x));
+ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[1], ul_ch128[1]), x));
+ avg128U = _mm_add_epi32(avg128U, _mm_srai_epi32(_mm_madd_epi16(ul_ch128[2], ul_ch128[2]), x));
+ ul_ch128+=3;
+ }
+
+ avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
+ ((int32_t*)&avg128U)[1] +
+ ((int32_t*)&avg128U)[2] +
+ ((int32_t*)&avg128U)[3] ) / y;
+
+ }
+
+ _mm_empty();
+ _m_empty();
+
+#elif defined(__arm__)
+
+ short rb;
+ unsigned char aatx, aarx, nre = 12, symbol_mod;
+ int32x4_t avg128U;
+ int16x4_t *ul_ch128;
+
+ symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ for (aatx=0; aatxnb_antenna_ports_eNB; aatx++)
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ //clear average level
+ avg128U = vdupq_n_s32(0);
+ // 5 is always a symbol with no pilots for both normal and extended prefix
+
+ ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+
+ for (rb = 0; rb < nb_rb; rb++) {
+ // printf("rb %d : ",rb);
+ // print_shorts("ch",&ul_ch128[0]);
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[0], ul_ch128[0]));
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[1], ul_ch128[1]));
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[2], ul_ch128[2]));
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[3], ul_ch128[3]));
+
+ if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) {
+ ul_ch128+=4;
+ } else {
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[4], ul_ch128[4]));
+ avg128U = vqaddq_s32(avg128U, vmull_s16(ul_ch128[5], ul_ch128[5]));
+ ul_ch128+=6;
+ }
+
+ /*
+ if (rb==0) {
+ print_shorts("ul_ch128",&ul_ch128[0]);
+ print_shorts("ul_ch128",&ul_ch128[1]);
+ print_shorts("ul_ch128",&ul_ch128[2]);
+ }
+ */
+ }
+
+ if (symbol==2) //assume start symbol 2
+ nre=6;
+ else
+ nre=12;
+
+ avg[(aatx<<1)+aarx] = (((int32_t*)&avg128U)[0] +
+ ((int32_t*)&avg128U)[1] +
+ ((int32_t*)&avg128U)[2] +
+ ((int32_t*)&avg128U)[3] ) / (nb_rb*nre);
+ }
+
+
+#endif
+}
+
+void nr_ulsch_channel_compensation(int **rxdataF_ext,
+ int **ul_ch_estimates_ext,
+ int **ul_ch_mag,
+ int **ul_ch_magb,
+ int **rxdataF_comp,
+ int **rho,
+ NR_DL_FRAME_PARMS *frame_parms,
+ unsigned char symbol,
+ uint8_t pilots,
+ unsigned char mod_order,
+ unsigned short nb_rb,
+ unsigned char output_shift)
+{
+
+#ifdef DEBUG_CH_COMP
+ int16_t *rxF, *ul_ch;
+ int prnt_idx;
+
+
+ rxF = (int16_t *)&rxdataF_ext[0][(symbol*nb_rb*12)];
+ ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12];
+
+ printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift);
+ printf("----------------Before compansation------------------\n");
+
+ for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){
+
+ printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]);
+ printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]);
+
+ }
+
+#endif
+
+#ifdef DEBUG_CH_MAG
+ int16_t *ch_mag;
+ int print_idx;
+
+
+ ch_mag = (int16_t *)&ul_ch_mag[0][(symbol*nb_rb*12)];
+
+ printf("--------------------symbol = %d, mod_order = %d-----------------------\n", symbol, mod_order);
+ printf("----------------Before computation------------------\n");
+
+ for (print_idx=0;print_idx<50;print_idx++){
+
+ printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]);
+
+ }
+
+#endif
+
+#if defined(__i386) || defined(__x86_64)
+
+ unsigned short rb;
+ unsigned char aatx,aarx;
+ __m128i *ul_ch128,*ul_ch128_2,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128;
+ __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
+ QAM_amp128b = _mm_setzero_si128();
+
+ for (aatx=0; aatxnb_antennas_tx; aatx++) {
+
+ if (mod_order == 4) {
+ QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
+ QAM_amp128b = _mm_setzero_si128();
+ } else if (mod_order == 6) {
+ QAM_amp128 = _mm_set1_epi16(QAM64_n1); //
+ QAM_amp128b = _mm_set1_epi16(QAM64_n2);
+ }
+
+ // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
+
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+
+ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12];
+ ul_ch_mag128 = (__m128i *)&ul_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12];
+ ul_ch_mag128b = (__m128i *)&ul_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12];
+ rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12];
+ rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*nb_rb*12];
+
+
+ for (rb=0; rb2) {
+ // get channel amplitude if not QPSK
+
+ //print_shorts("ch:",(int16_t*)&ul_ch128[0]);
+
+ mmtmpD0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+
+ mmtmpD1 = _mm_madd_epi16(ul_ch128[1],ul_ch128[1]);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+
+ mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1);
+
+ // store channel magnitude here in a new field of ulsch
+
+ ul_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0);
+ ul_ch_mag128b[0] = ul_ch_mag128[0];
+ ul_ch_mag128[0] = _mm_mulhi_epi16(ul_ch_mag128[0],QAM_amp128);
+ ul_ch_mag128[0] = _mm_slli_epi16(ul_ch_mag128[0],1);
+
+ // print_ints("ch: = ",(int32_t*)&mmtmpD0);
+ // print_shorts("QAM_amp:",(int16_t*)&QAM_amp128);
+ // print_shorts("mag:",(int16_t*)&ul_ch_mag128[0]);
+
+ ul_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0);
+ ul_ch_mag128b[1] = ul_ch_mag128[1];
+ ul_ch_mag128[1] = _mm_mulhi_epi16(ul_ch_mag128[1],QAM_amp128);
+ ul_ch_mag128[1] = _mm_slli_epi16(ul_ch_mag128[1],1);
+
+ if (pilots==0) {
+ mmtmpD0 = _mm_madd_epi16(ul_ch128[2],ul_ch128[2]);
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);
+
+ ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);
+ ul_ch_mag128b[2] = ul_ch_mag128[2];
+
+ ul_ch_mag128[2] = _mm_mulhi_epi16(ul_ch_mag128[2],QAM_amp128);
+ ul_ch_mag128[2] = _mm_slli_epi16(ul_ch_mag128[2],1);
+ }
+
+ ul_ch_mag128b[0] = _mm_mulhi_epi16(ul_ch_mag128b[0],QAM_amp128b);
+ ul_ch_mag128b[0] = _mm_slli_epi16(ul_ch_mag128b[0],1);
+
+
+ ul_ch_mag128b[1] = _mm_mulhi_epi16(ul_ch_mag128b[1],QAM_amp128b);
+ ul_ch_mag128b[1] = _mm_slli_epi16(ul_ch_mag128b[1],1);
+
+ if (pilots==0) {
+ ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128b);
+ ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],1);
+ }
+ }
+
+ // multiply by conjugated channel
+ mmtmpD0 = _mm_madd_epi16(ul_ch128[0],rxdataF128[0]);
+ // print_ints("re",&mmtmpD0);
+
+ // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+ mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[0],_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
+ // print_ints("im",&mmtmpD1);
+ mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]);
+ // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ // print_ints("re(shift)",&mmtmpD0);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ // print_ints("im(shift)",&mmtmpD1);
+ mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+ mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+ // print_ints("c0",&mmtmpD2);
+ // print_ints("c1",&mmtmpD3);
+ rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+ // print_shorts("rx:",rxdataF128);
+ // print_shorts("ch:",ul_ch128);
+ // print_shorts("pack:",rxdataF_comp128);
+
+ // multiply by conjugated channel
+ mmtmpD0 = _mm_madd_epi16(ul_ch128[1],rxdataF128[1]);
+ // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+ mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[1],_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
+ mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]);
+ // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+ mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+ rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+ // print_shorts("rx:",rxdataF128+1);
+ // print_shorts("ch:",ul_ch128+1);
+ // print_shorts("pack:",rxdataF_comp128+1);
+
+ if (pilots==0) {
+ // multiply by conjugated channel
+ mmtmpD0 = _mm_madd_epi16(ul_ch128[2],rxdataF128[2]);
+ // mmtmpD0 contains real part of 4 consecutive outputs (32-bit)
+ mmtmpD1 = _mm_shufflelo_epi16(ul_ch128[2],_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+ mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate);
+ mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]);
+ // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit)
+ mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
+ mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift);
+ mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+ mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+ rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+ // print_shorts("rx:",rxdataF128+2);
+ // print_shorts("ch:",ul_ch128+2);
+ // print_shorts("pack:",rxdataF_comp128+2);
+
+ ul_ch128+=3;
+ ul_ch_mag128+=3;
+ ul_ch_mag128b+=3;
+ rxdataF128+=3;
+ rxdataF_comp128+=3;
+ } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less
+ ul_ch128+=2;
+ ul_ch_mag128+=2;
+ ul_ch_mag128b+=2;
+ rxdataF128+=2;
+ rxdataF_comp128+=2;
+ }
+
+ }
+ }
+ }
+
+ if (rho) {
+
+
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch128_2 = (__m128i *)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12];
+
+ for (rb=0; rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
+
+ if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) {
+ if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size
+ nb_rb=1+(5*nb_rb/6);
+ }
+ else {
+ pilots=1;
+ }
+ }
+
+ for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) {
+ if (mod_order == 4) {
+ QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10)
+ QAM_amp128b = vmovq_n_s16(0);
+ } else if (mod_order == 6) {
+ QAM_amp128 = vmovq_n_s16(QAM64_n1); //
+ QAM_amp128b = vmovq_n_s16(QAM64_n2);
+ }
+ // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol);
+
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch_mag128 = (int16x8_t*)&ul_ch_mag[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch_mag128b = (int16x8_t*)&ul_ch_magb[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+ rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_UL*12];
+ rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_UL*12];
+
+ for (rb=0; rb2) {
+ // get channel amplitude if not QPSK
+ mmtmpD0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
+ // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3];
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits
+ mmtmpD1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits
+ mmtmpD0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
+ mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128);
+ mmtmpD1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
+ mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128);
+ mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ }
+
+ ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b);
+ ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b);
+ ul_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128);
+ ul_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128);
+
+ if (pilots==0) {
+ ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b);
+ ul_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128);
+ }
+ }
+
+ mmtmpD0 = vmull_s16(ul_ch128[0], rxdataF128[0]);
+ //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
+ mmtmpD1 = vmull_s16(ul_ch128[1], rxdataF128[1]);
+ //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
+
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
+ //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
+ //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+ mmtmpD0 = vmull_s16(ul_ch128[2], rxdataF128[2]);
+ mmtmpD1 = vmull_s16(ul_ch128[3], rxdataF128[3]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+ if (pilots==0) {
+ mmtmpD0 = vmull_s16(ul_ch128[4], rxdataF128[4]);
+ mmtmpD1 = vmull_s16(ul_ch128[5], rxdataF128[5]);
+ mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)),
+ vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1)));
+
+ mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
+ mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
+ mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)),
+ vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b)));
+
+
+ mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128);
+ mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128);
+ rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1));
+
+
+ ul_ch128+=6;
+ ul_ch_mag128+=3;
+ ul_ch_mag128b+=3;
+ rxdataF128+=6;
+ rxdataF_comp128+=3;
+
+ } else { // we have a smaller PUSCH in symbols with pilots so skip last group of 4 REs and increment less
+ ul_ch128+=4;
+ ul_ch_mag128+=2;
+ ul_ch_mag128b+=2;
+ rxdataF128+=4;
+ rxdataF_comp128+=2;
+ }
+ }
+ }
+ }
+
+ if (rho) {
+ for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch128 = (int16x4_t*)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12];
+ ul_ch128_2 = (int16x4_t*)&ul_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_UL*12];
+ for (rb=0; rbframe_parms;
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
- uint32_t nb_re_pusch;
-
- if(symbol == rel15_ul->start_symbol)
- gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
+ uint32_t nb_re_pusch, bwp_start_subcarrier;
+ int avgs;
+ int avg[4];
- if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
+ pilots = 0;
+ first_symbol_flag = 0;
+
+ if(symbol == rel15_ul->start_symbol){
+ gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
+ first_symbol_flag = 1;
+ }
+
+ if (symbol == 2){ // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
nb_re_pusch = rel15_ul->number_rbs * 6;
- else
+ pilots = 1;
+ } else {
nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
+ pilots = 0;
+ }
+
+ bwp_start_subcarrier = (rel15_ul->start_rb*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
+
+ //----------------------------------------------------------
+ //--------------------- Channel estimation ---------------------
+ //----------------------------------------------------------
+
+ if (pilots == 1)
+ nr_pusch_channel_estimation(gNB,
+ 0,
+ nr_tti_rx,
+ 0, // p
+ symbol,
+ bwp_start_subcarrier,
+ rel15_ul->number_rbs);
//----------------------------------------------------------
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
+ gNB->pusch_vars[UE_id]->ul_ch_estimates,
gNB->pusch_vars[UE_id]->rxdataF_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
gNB->pusch_vars[UE_id]->rxdataF_ext_offset,
// rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
symbol,
@@ -288,6 +1024,44 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
rel15_ul->number_rbs,
frame_parms);
+ nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ gNB->ulsch[UE_id+1],
+ symbol,
+ pilots,
+ rel15_ul->number_rbs);
+
+ if (first_symbol_flag==1) {
+
+ nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ frame_parms,
+ avg,
+ symbol,
+ nb_re_pusch,
+ rel15_ul->number_rbs);
+ avgs = 0;
+
+ for (aatx=0;aatxnb_antennas_tx;aatx++)
+ for (aarx=0;aarxnb_antennas_rx;aarx++)
+ avgs = cmax(avgs,avg[(aatx<<1)+aarx]);
+
+ gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1;
+
+ }
+
+ nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
+ gNB->pusch_vars[UE_id]->rxdataF_comp,
+ (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL,
+ frame_parms,
+ symbol,
+ pilots,
+ rel15_ul->Qm,
+ rel15_ul->number_rbs,
+ gNB->pusch_vars[UE_id]->log2_maxh);
+
#ifdef NR_SC_FDMA
nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
@@ -296,14 +1070,15 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
//-------------------- LLRs computation --------------------
//----------------------------------------------------------
- nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
- gNB->pusch_vars[UE_id]->ul_ch_mag,
- gNB->pusch_vars[UE_id]->ul_ch_magb,
+ nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
+ gNB->pusch_vars[UE_id]->ul_ch_mag0,
+ gNB->pusch_vars[UE_id]->ul_ch_magb0,
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
+ rel15_ul->number_rbs,
nb_re_pusch,
symbol,
rel15_ul->Qm);
-
+
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
index d2d8cdd927..233ecd8de7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
@@ -30,7 +30,6 @@
* \warning
*/
-
#include "PHY/defs_nr_common.h"
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
@@ -71,23 +70,20 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int16_t *ulsch_llr,
+ uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol)
{
+
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF = (__m128i*)rxdataF_comp;
- // __m128i *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
+ __m128i *ch_mag;
__m128i llr128[2];
uint32_t *llr32;
- // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
- // else ul_ch_mag and ul_ch_magb should be used after channel estimation has benn implemented
- __m128i temp_channel;
- int16_t one_over_sqrt_2 = 23170;
-
#elif defined(__arm__)
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
- // int16x8_t *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
+ int16x8_t *ch_mag;
int16x8_t xmm0;
int16_t *llr16;
#endif
@@ -103,21 +99,16 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
llr16 = (int16_t*)ulsch_llr;
#endif
-// [hna] This should be uncommented once channel estimation is implemented
-// ------------------------------------------------------------
-// #if defined(__x86_64__) || defined(__i386__)
-// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
-// #elif defined(__arm__)
-// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
-// #endif
-// ------------------------------------------------------------
+#if defined(__x86_64__) || defined(__i386__)
+ ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
+#elif defined(__arm__)
+ ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
+#endif
len_mod4 = nb_re&3;
nb_re >>= 2; // length in quad words (4 REs)
nb_re += (len_mod4 == 0 ? 0 : 1);
- temp_channel = _mm_set1_epi16((QAM16_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
-
for (i=0; i |y_R|, registers of odd index in xmm0-> |y_I|
- xmm0 = _mm_subs_epi16(temp_channel,xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
+ xmm0 = _mm_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs
llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd and 4th REs
@@ -186,52 +177,43 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
+ uint32_t nb_rb,
uint32_t nb_re,
uint8_t symbol)
{
+
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF = (__m128i*)rxdataF_comp;
- // __m128i *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
-
- // [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
- // else ul_ch_mag and ul_ch_magb should be used after channel estimation has been implemented
- __m128i temp_channel[2];
- int16_t one_over_sqrt_2 = 23170;
-
+ __m128i *ch_mag,*ch_magb;
#elif defined(__arm__)
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
- // int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
+ int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
int16x8_t xmm1,xmm2;
#endif
int i;
unsigned char len_mod4;
-// [hna] This should be uncommented once channel estimation is implemented
-// -------------------------------------------------------------------------
-// #if defined(__x86_64__) || defined(__i386__)
-// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
-// ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
-// #elif defined(__arm__)
-// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
-// ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
-// #endif
-// -------------------------------------------------------------------------
+#if defined(__x86_64__) || defined(__i386__)
+ ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
+ ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*nb_rb*12)];
+#elif defined(__arm__)
+ ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
+ ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*nb_rb*12)];
+#endif
len_mod4 = nb_re&3;
nb_re = nb_re>>2; // length in quad words (4 REs)
nb_re += ((len_mod4 == 0) ? 0 : 1);
-
- temp_channel[0] = _mm_set1_epi16((QAM64_n1 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
- temp_channel[1] = _mm_set1_epi16((QAM64_n2 * one_over_sqrt_2)>>(2*15-AMP_SHIFT));
+
for (i=0; inb_antennas_rx; aa++) {
- Re = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
- Im = ((int16_t*)ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
+ Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
+ Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -80,7 +80,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
// do not filter to have proactive timing adjustment
//max_pos_fil = max_pos;
- if(subframe == 1)
+ if(subframe == 0)
{
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>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 513d49a25e..e9b93719c1 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -21,7 +21,7 @@
#include
-
+#include "SCHED_NR_UE/defs.h"
#include "nr_estimation.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "filt16a_32.h"
@@ -199,19 +199,23 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
- uint8_t eNB_offset,
- unsigned char Ns,
- unsigned char symbol,
- int dmrss,
- uint8_t ssb_index,
- uint8_t n_hf)
+ uint8_t eNB_offset,
+ unsigned char Ns,
+ unsigned char symbol,
+ int dmrss,
+ uint8_t ssb_index,
+ uint8_t n_hf)
{
int pilot[200] __attribute__((aligned(16)));
- unsigned char aarx;
+ unsigned char aarx,p;
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
int ch_offset,symbol_offset;
+ int slot_pbch;
+ fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config;
+ // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE)
+ uint8_t ssb_periodicity = 10;// ue->ssb_periodicity;
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
@@ -418,6 +422,59 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
+ void (*idft)(int16_t *,int16_t *, int);
+
+ switch (ue->frame_parms.ofdm_symbol_size) {
+ case 128:
+ idft = idft128;
+ break;
+
+ case 256:
+ idft = idft256;
+ break;
+
+ case 512:
+ idft = idft512;
+ break;
+
+ case 1024:
+ idft = idft1024;
+ break;
+
+ case 1536:
+ idft = idft1536;
+ break;
+
+ case 2048:
+ idft = idft2048;
+ break;
+
+ case 3072:
+ idft = idft3072;
+ break;
+
+ case 4096:
+ idft = idft4096;
+ break;
+
+ default:
+ printf("unsupported ofdm symbol size \n");
+ assert(0);
+ }
+
+ if( symbol == 3)
+ {
+ // do ifft of channel estimate
+ for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++)
+ for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) {
+ if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
+ {
+ LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, ue->current_thread_id[Ns], symbol, ch_offset);
+ idft((int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p<<1)+aarx][ch_offset],
+ (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
+ }
+ }
+ }
//}
@@ -433,7 +490,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short nb_rb_coreset)
{
int pilot[200] __attribute__((aligned(16)));
- unsigned char aarx,p;
+ unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
@@ -597,60 +654,6 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
//}
}
-
- void (*idft)(int16_t *,int16_t *, int);
-
- switch (ue->frame_parms.ofdm_symbol_size) {
- case 128:
- idft = idft128;
- break;
-
- case 256:
- idft = idft256;
- break;
-
- case 512:
- idft = idft512;
- break;
-
- case 1024:
- idft = idft1024;
- break;
-
- case 1536:
- idft = idft1536;
- break;
-
- case 2048:
- idft = idft2048;
- break;
-
- case 3072:
- idft = idft3072;
- break;
-
- case 4096:
- idft = idft4096;
- break;
-
- default:
- printf("unsupported ofdm symbol size \n");
- assert(0);
- }
-
- if( (Ns== 1) && (symbol == 0))
- {
- // do ifft of channel estimate
- for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++)
- for (p=0; pframe_parms.nb_antenna_ports_eNB; p++) {
- if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
- {
- 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);
- }
- }
- }
return(0);
}
@@ -721,11 +724,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
// generate pilot
- nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch);
+ uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
+ int config_type = 0; // needs to be updated from higher layer
+ nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
- pil = (int16_t *)&pilot[0];
+ pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)];
+ k = k&(ue->frame_parms.ofdm_symbol_size-1);
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
@@ -755,8 +761,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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));
@@ -771,8 +777,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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);
@@ -790,8 +796,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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;
@@ -811,8 +817,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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);
@@ -825,8 +831,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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;
@@ -847,8 +853,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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);
@@ -863,8 +869,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 >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 2) : (re_offset+2);
+ 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_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index 64bd81433d..092fdfd1fc 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -726,7 +726,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ch_offset = ue->frame_parms.ofdm_symbol_size*2;
-printf("testing measurements\n");
+//printf("testing measurements\n");
// signal measurements
for (eNB_id=0; eNB_idn_connected_eNB; eNB_id++) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 3f206a679c..c51309e3eb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -140,9 +140,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
}
f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L);
- //index_z = 9*reg;
- index_z = 9*(uint16_t)floor(reg/coreset_time_dur) + (9*coreset_nbr_rb)*(reg%coreset_time_dur);
- //index_llr = 9*(((uint16_t)floor(f_reg/reg_bundle_size_L)+(f_reg)%coreset_time_dur))*(coreset_nbr_rb);
+ index_z = 9*reg;
index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb)));
for (int i=0; i<9; i++) {
@@ -395,7 +393,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
if (((c_rb - n_BWP_start) % BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN)==0) {
bitcnt_coreset_freq_dom ++;
- while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom
+ while ((((coreset_freq_dom & 0x1FFFFFFFFFFF) >> (CORESET_FREQ_DOMAIN_BITMAP_SIZE - (n_BWP_start/BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN) - bitcnt_coreset_freq_dom)) & 0x1)== 0) { // 46 -> 45 is number of bits in coreset_freq_dom
// next 6 RB are not part of the CORESET within the BWP as bit in coreset_freq_dom is set to 0
bitcnt_coreset_freq_dom ++;
//c_rb_tmp = c_rb_tmp + 6;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index e9a147dce1..ce01ecbab6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -44,6 +44,7 @@
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
//#define DEBUG_DLSCH_DECODING
+//#define ENABLE_PHY_PAYLOAD_DEBUG 1
#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
@@ -238,7 +239,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
//__m128i l;
//int16_t inv_d [68*384];
uint8_t kc;
- uint8_t Ilbrm = 0;
+ uint8_t Ilbrm = 1;
uint32_t Tbslbrm; //= 950984;
uint16_t nb_rb; //= 30;
double Coderate; //= 0.0;
@@ -298,11 +299,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->trials[harq_process->round]++;
- harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
+ uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
A = harq_process->TBS;
ret = dlsch->max_ldpc_iterations + 1;
-
+ dlsch->last_iteration_cnt = ret;
+
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
G = harq_process->G;
@@ -310,29 +314,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
- if (harq_process->round == 0) {
- // This is a new packet, so compute quantities regarding segmentation
- harq_process->B = A+24;
- nr_segmentation(NULL,
- NULL,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- &harq_process->Z, // [hna] Z is Zc
- &harq_process->F);
+ if ((harq_process->R)<1024)
+ Coderate = (float) (harq_process->R) /(float) 1024;
+ else
+ Coderate = (float) (harq_process->R) /(float) 2048;
-#ifdef DEBUG_DLSCH_DECODING
- if (!frame%100)
- printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
-#endif
- }
-
- vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
-
- p_decParams->Z = harq_process->Z;
- //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
-
- Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
{
p_decParams->BG = 2;
@@ -365,6 +351,34 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
}
+
+ if (harq_process->round == 0) {
+ // This is a new packet, so compute quantities regarding segmentation
+ if (A > 3824)
+ harq_process->B = A+24;
+ else
+ harq_process->B = A+16;
+
+ nr_segmentation(NULL,
+ NULL,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ &harq_process->Z, // [hna] Z is Zc
+ &harq_process->F,
+ p_decParams->BG);
+
+#ifdef DEBUG_DLSCH_DECODING
+ if (!frame%100)
+ printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
+#endif
+ }
+
+ vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
+
+ p_decParams->Z = harq_process->Z;
+ //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z);
+
//printf("coderate %f kc %d \n", Coderate, kc);
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
@@ -401,8 +415,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
K_bytes_F = Kr_bytes-(harq_process->F>>3);
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
-
for (r=0; rC; r++) {
//printf("start rx segment %d\n",r);
@@ -446,6 +458,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
+ if ((harq_process->Nl)<4)
+ Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
+ else
+ Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
+
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
@@ -493,8 +510,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
// printf("done\n");
if (harq_process->C == 1){
- crc_type = CRC24_A;
- length_dec = harq_process->B;
+ if (A > 3824)
+ crc_type = CRC24_A;
+ else
+ crc_type = CRC16;
+
+ length_dec = harq_process->B;
+
}
else{
crc_type = CRC24_B;
@@ -543,6 +565,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
printf("\x1B[34m" "Segment %d CRC OK\n",r);
+ //Temporary hack
+ no_iteration_ldpc = dlsch->max_ldpc_iterations;
ret = no_iteration_ldpc;
}
else {
@@ -591,7 +615,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
- LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
+ LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
err_flag = 1;
}
}
@@ -605,10 +629,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
frame_rx_prev = frame_rx_prev%1024;
if (err_flag == 1) {
-#if UE_DEBUG_TRACE
+//#if UE_DEBUG_TRACE
LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_ue->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-#endif
+//#endif
harq_process->harq_ack.ack = 0;
harq_process->harq_ack.harq_id = harq_pid;
harq_process->harq_ack.send_harq_status = 1;
@@ -623,16 +647,16 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if(is_crnti)
{
- LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
+ LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
}
return((1 + dlsch->max_ldpc_iterations));
} else {
-#if UE_DEBUG_TRACE
+//#if UE_DEBUG_TRACE
LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
-#endif
+//#endif
harq_process->status = SCH_IDLE;
harq_process->round = 0;
@@ -645,7 +669,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if(is_crnti)
{
- LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
+ LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
}
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
@@ -679,6 +703,20 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->b[offset],
harq_process->F>>3,
harq_process->c[r]);
+
+ /*printf ("Printing payload bytes:");
+ for (int i = 0; i < Kr_bytes; i++){
+ printf("%d : %d \n", i, harq_process->b[i]);
+ }*/
+#endif
+
+#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
+ if (frame%100 == 0){
+ LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
+ for (int i = 0; i <10 ; i++){ //Kr_bytes
+ LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
+ }
+ }
#endif
}
@@ -721,7 +759,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
int32_t no_iteration_ldpc,length_dec;
/*uint8_t C;
uint8_t Qm;
- uint8_t Nl;
uint8_t r_thread;
uint32_t Er, Gp,GpmodC;*/
t_nrLDPC_dec_params decParams;
@@ -730,14 +767,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
t_nrLDPC_time_stats* p_procTime =&procTime ;
int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
-
+ uint8_t Nl=4;
int16_t z [68*384];
int8_t l [68*384];
//__m128i l;
int16_t inv_d [68*384];
//int16_t *p_invd =&inv_d;
uint8_t kb, kc;
- uint8_t Ilbrm = 0;
+ uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984;
uint16_t nb_rb = 30;
double Coderate = 0.0;
@@ -795,7 +832,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
nb_rb = harq_process->nb_rb;
harq_process->trials[harq_process->round]++;
- harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
+ uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
A = harq_process->TBS;
@@ -815,22 +854,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
// printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
- if (harq_process->round == 0) {
- // This is a new packet, so compute quantities regarding segmentation
- harq_process->B = A+24;
- nr_segmentation(NULL,
- NULL,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- &harq_process->Z,
- &harq_process->F);
+ if ((harq_process->R)<1024)
+ Coderate = (float) (harq_process->R) /(float) 1024;
+ else
+ Coderate = (float) (harq_process->R) /(float) 2048;
- p_decParams->Z = harq_process->Z;
-
- }
-
- Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
{
p_decParams->BG = 2;
@@ -863,6 +891,26 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
}
}
+ if (harq_process->round == 0) {
+ // This is a new packet, so compute quantities regarding segmentation
+ if (A > 3824)
+ harq_process->B = A+24;
+ else
+ harq_process->B = A+16;
+
+ nr_segmentation(NULL,
+ NULL,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ &harq_process->Z,
+ &harq_process->F,
+ p_decParams->BG);
+
+ p_decParams->Z = harq_process->Z;
+
+ }
+
//printf("coderate %f kc %d \n", Coderate, kc);
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
p_decParams->outMode= 0;
@@ -941,8 +989,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
-
E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
/*
@@ -983,6 +1029,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
harq_process->round);
#endif
+ // for tbslbrm calculation according to 5.4.2.1 of 38.212
+ if (harq_process->Nl < Nl)
+ Nl = harq_process->Nl;
+
+ Tbslbrm = nr_compute_tbslbrm(rel15.mcs_table,nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
+
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
@@ -1035,7 +1087,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
// printf("done\n");
if (harq_process->C == 1){
- crc_type = CRC24_A;
+ if (A > 3824)
+ crc_type = CRC24_A;
+ else
+ crc_type = CRC16;
+
length_dec = harq_process->B;
}
else{
@@ -1286,7 +1342,7 @@ void *nr_dlsch_decoding_process(void *arg)
int16_t inv_d [68*384];
int16_t *p_invd =&inv_d;
uint8_t kb, kc;
- uint8_t Ilbrm = 0;
+ uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984;
uint16_t nb_rb = 30; //to update
double Coderate = 0.0;
@@ -1326,8 +1382,8 @@ void *nr_dlsch_decoding_process(void *arg)
int harq_pid = proc->harq_pid;
llr8_flag1 = proc->llr8_flag;
int frame = proc->frame_rx;
- int slot = proc->nr_tti_rx;
- r = proc->num_seg;
+ int slot = proc->nr_tti_rx;
+ r = proc->num_seg;
NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0];
NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid];
@@ -1355,7 +1411,9 @@ void *nr_dlsch_decoding_process(void *arg)
harq_process->trials[harq_process->round]++;
- harq_process->TBS = nr_compute_tbs(harq_process->mcs,nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs, harq_process->Nl);
+ uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
+
+ harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl);
A = harq_process->TBS; //2072 for QPSK 1/3
@@ -1367,23 +1425,11 @@ void *nr_dlsch_decoding_process(void *arg)
LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
-
- if (harq_process->round == 0) {
- // This is a new packet, so compute quantities regarding segmentation
- harq_process->B = A+24;
+ if ((harq_process->R)<1024)
+ Coderate = (float) (harq_process->R) /(float) 1024;
+ else
+ Coderate = (float) (harq_process->R) /(float) 2048;
- nr_segmentation(NULL,
- NULL,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- &harq_process->Z,
- &harq_process->F);
- p_decParams->Z = harq_process->Z;
-
- }
-
- Coderate = (float) A /(float) G;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
{
p_decParams->BG = 2;
@@ -1414,7 +1460,29 @@ void *nr_dlsch_decoding_process(void *arg)
p_decParams->R = 89;
kc = 27;
}
- }
+ }
+
+ if (harq_process->round == 0) {
+ // This is a new packet, so compute quantities regarding segmentation
+ if (A > 3824)
+ harq_process->B = A+24;
+ else
+ harq_process->B = A+16;
+
+ nr_segmentation(NULL,
+ NULL,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ &harq_process->Z,
+ &harq_process->F,
+ p_decParams->BG);
+
+ p_decParams->Z = harq_process->Z;
+
+ }
+
+
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
p_decParams->outMode= 0;
@@ -1474,9 +1542,7 @@ void *nr_dlsch_decoding_process(void *arg)
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
-
- E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+ E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
#if UE_TIMING_TRACE
start_meas(dlsch_deinterleaving_stats);
@@ -1511,6 +1577,11 @@ void *nr_dlsch_decoding_process(void *arg)
harq_process->round);
#endif
+ if (Nl<4)
+ Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
+ else
+ Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
+
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
@@ -1555,7 +1626,11 @@ void *nr_dlsch_decoding_process(void *arg)
memset(harq_process->c[r],0,Kr_bytes);
if (harq_process->C == 1){
- crc_type = CRC24_A;
+ if (A > 3824)
+ crc_type = CRC24_A;
+ else
+ crc_type = CRC16;
+
length_dec = harq_process->B;
}
else{
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 447a527c63..8f810d36d3 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -176,7 +176,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id];
- dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm(dlsch[0]->harq_processes[harq_pid]->mcs, 1);;
+ dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
+ dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table);
//printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
@@ -275,7 +276,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
#if UE_TIMING_TRACE
- if(symbol > ue->frame_parms.symbols_per_tti>>1)
+ if(symbol > ue->frame_parms.symbols_per_slot>>1)
{
slot = 1;
}
@@ -964,7 +965,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
break;
}
if (dlsch1_harq) {
- switch (nr_get_Qm(dlsch1_harq->mcs, 1)) {
+ switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
case 2 :
if (rx_type==rx_standard) {
nr_dlsch_qpsk_llr(frame_parms,
@@ -1064,9 +1065,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if T_TRACER
T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
T_INT(nr_tti_rx), T_INT(nb_rb),
- T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti),
+ T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot),
T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0],
- 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
+ 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2));
#endif
return(0);
@@ -2379,10 +2380,13 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
unsigned char j=0;
- k = frame_parms->first_carrier_offset + 12*start_rb;
+ AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1,
+ "nushift %d is illegal\n",frame_parms->nushift);
for (aarx=0; aarxnb_antennas_rx; aarx++) {
+ k = frame_parms->first_carrier_offset + 12*start_rb;
+
if (high_speed_flag == 1)
dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))];
else
@@ -2393,65 +2397,43 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)];
rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
- //printf("extract single addr %p pilots %d symbol %d, l %d RB_DL %d nushift %d k %d\n", rxF, pilots, symbol, l, frame_parms->N_RB_DL,frame_parms->nushift,k);
-
- //if ((frame_parms->N_RB_DL&1) == 0){ // even number of RBs
-
- for (rb = start_rb; rb < nb_rb_pdsch + start_rb; rb++) {
-
- // For second half of RBs skip DC carrier
- if (k>=frame_parms->ofdm_symbol_size) {
- rxF = &rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))];
- k=k-(frame_parms->ofdm_symbol_size);
+ for (rb = 0; rb < nb_rb_pdsch; rb++) {
+ if (k>frame_parms->ofdm_symbol_size) {
+ k = k-frame_parms->ofdm_symbol_size;
+ rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))];
}
-
- //*pmi_ext = (pmi>>((rb>>2)<<1))&3;
- //memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int));
-
- /*
- printf("rb %d\n",rb);
- for (i=0;i<12;i++)
- printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]);
- printf("\n");
- */
- if (pilots==0) {
- for (i=0; i<12; i++) {
- rxF_ext[i]=rxF[i];
- dl_ch0_ext[i]=dl_ch0[i];
- /*printf("rb %ld %p: (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF,
- ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);
- printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF,
- ((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]);
- printf("re count %d\n",rb*12+i);*/
- }
-
- dl_ch0_ext+=12;
- rxF_ext+=12;
- } else {
- j=0;
-
- for (i=0; i<12; i++) {
- if ((i&1)!=frame_parms->nushift){
- rxF_ext[j]=rxF[i];
- //printf("extract rb %d, re %d => rxF (%d,%d) rxF ext (%d,%d) addr %p\n",rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i]),*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j]),rxF_ext);
- dl_ch0_ext[j]=dl_ch0[i];
- //printf("rb %ld %p: dl_ch (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]),rxF,
- //((short*)&dl_ch0[i])[0],((short*)&dl_ch0[i])[1]);
- j++;
- }
- }
-
- dl_ch0_ext+=6;
- rxF_ext+=6;
- }
-
- dl_ch0+=12;
- rxF+=12;
- k+=12;
+ if (pilots==0) {
+ memcpy((void*)rxF_ext,(void*)rxF,12*sizeof(*rxF_ext));
+ memcpy((void*)dl_ch0_ext,(void*)dl_ch0,12*sizeof(*dl_ch0_ext));
+ dl_ch0_ext+=12;
+ rxF_ext+=12;
+ } else {
+ j=0;
+
+ for (i = (1-frame_parms->nushift);
+ i<12;
+ i+=2) {
+ rxF_ext[j]=rxF[i];
+ dl_ch0_ext[j]=dl_ch0[i];
+ j++;
+ }
+
+
+ dl_ch0_ext+=6;
+ rxF_ext+=6;
}
+
+ dl_ch0+=12;
+ rxF+=12;
+ k+=12;
+ if (k>=frame_parms->ofdm_symbol_size) {
+ k=k-(frame_parms->ofdm_symbol_size);
+ rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))];
+ }
+ }
}
-
-
+
+
return(nb_rb_pdsch/frame_parms->nb_antennas_rx);
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 85e76d5177..3d8ec866c6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -611,7 +611,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
rx_ind.rx_indication_body[0].mib_pdu.ssb_index = i_ssb; // confirm with TCL
rx_ind.rx_indication_body[0].mib_pdu.ssb_length = Lmax; // confirm with TCL
rx_ind.rx_indication_body[0].mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
- rx_ind.number_pdus = 1;
+ rx_ind.number_pdus = 1; //rx_ind.number_pdus++;
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 155e08d477..7559115a29 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -1055,18 +1055,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid);
-/*! \brief Fill up NR_UE_ULSCH_t and NR_UL_UE_HARQ_t structs
- @param[in] UE, Pointer to PHY_VARS_NR_UE struct
- @param[in] thread_id, thread id
- @param[in] gNB_id, gNB id
- @param[in] harq_pid, harq id
-*/
-
-int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
- uint8_t thread_id,
- int gNB_id,
- unsigned char harq_pid);
-
/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param[in] in, Pointer to input bits
@param[in] size, of input bits
@@ -1076,7 +1064,7 @@ int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
*/
void nr_pusch_codeword_scrambling(uint8_t *in,
- uint16_t size,
+ uint32_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
@@ -1088,19 +1076,21 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
- transform precoding
*/
-uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
+void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned char harq_pid,
uint8_t slot,
uint8_t thread_id,
- int eNB_id);
+ int gNB_id);
/** \brief This function does IFFT for PUSCH
*/
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
+ uint8_t harq_pid,
uint8_t slot,
- uint8_t Nl,
+ uint8_t thread_id,
+ uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 86b551435e..39b037a600 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -159,10 +159,6 @@ typedef struct {
} NR_UL_UE_HARQ_t;
typedef struct {
- /// Current Number of Symbols
- uint8_t Nsymb_pusch;
- /// Nsc_pusch, number of allocated subcarriers for ULSCH
- uint16_t Nsc_pusch;
/// number of DMRS resource elements
uint8_t nb_re_dmrs;
/// DMRS length
@@ -269,10 +265,14 @@ typedef struct {
uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS];
/// Index of current HARQ round for this DLSCH
uint8_t round;
+ /// MCS table for this DLSCH
+ uint8_t mcs_table;
/// MCS format for this DLSCH
uint8_t mcs;
/// Qm (modulation order) for this DLSCH
uint8_t Qm;
+ /// target code rate R x 1024
+ uint16_t R;
/// Redundancy-version of the current sub-frame
uint8_t rvidx;
/// MIMO mode for this DLSCH
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index bc1f9548d4..cbe0a816ff 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -202,11 +202,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
uint8_t mod_order;
uint16_t Kr,r,r_offset;
uint8_t BG;
- uint32_t E;
+ uint32_t E,Kb;
uint8_t Ilbrm;
uint32_t Tbslbrm;
uint8_t nb_re_dmrs;
uint16_t length_dmrs;
+ uint16_t R;
float Coderate;
///////////
@@ -222,7 +223,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
nb_symb_sch = harq_process->number_of_symbols;
A = harq_process->TBS;
pz = &Z;
- mod_order = nr_get_Qm(harq_process->mcs,1);
+ mod_order = nr_get_Qm_ul(harq_process->mcs,0);
+ R = nr_get_code_rate_ul(harq_process->mcs, 0);
Kr=0;
r_offset=0;
BG = 1;
@@ -250,9 +252,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
-
-
- Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
// if (harq_process->Ndi == 1) { // this is a new packet
if (harq_process->round == 0) { // this is a new packet
@@ -287,16 +286,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
///////////////////////// b---->| block segmentation |---->c /////////////////////////
///////////
- nr_segmentation(harq_process->b,
- harq_process->c,
- harq_process->B,
- &harq_process->C,
- &harq_process->K,
- pz,
- &harq_process->F);
-
- F = harq_process->F;
- Coderate = (float) A /(float) G;
+ if (R<1024)
+ Coderate = (float) R /(float) 1024;
+ else
+ Coderate = (float) R /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
BG = 2;
@@ -305,6 +298,16 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
BG = 1;
}
+ Kb=nr_segmentation(harq_process->b,
+ harq_process->c,
+ harq_process->B,
+ &harq_process->C,
+ &harq_process->K,
+ pz,
+ &harq_process->F,
+ BG);
+
+ F = harq_process->F;
Kr = harq_process->K;
#ifdef DEBUG_DLSCH_CODING
uint16_t Kr_bytes;
@@ -314,6 +317,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
///////////
/////////////////////////////////////////////////////////////////////////////////////
+opp_enabled=0;
///////////////////////// c---->| LDCP coding |---->d /////////////////////////
///////////
@@ -348,7 +352,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
printf("\n");*/
- ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
+ ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
//stop_meas(te_stats);
//printf("end ldpc encoder -- output\n");
@@ -390,6 +394,8 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r);
+ Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->Nl,harq_process->C);
+
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
BG,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 2b59f93160..f8c9c83e78 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -43,77 +43,10 @@
#include "PHY/TOOLS/tools_defs.h"
//#define DEBUG_SCFDMA
-
-
-int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
- uint8_t thread_id,
- int gNB_id,
- unsigned char harq_pid){
-
- int N_PRB_oh, N_RE_prime, cwd_idx, length_dmrs, Nid_cell;
- int nb_rb, Nsymb_pusch, first_rb, nb_codewords,mcs,rvidx;
- uint16_t n_rnti;
-
- NR_UE_ULSCH_t *ulsch_ue;
- NR_UL_UE_HARQ_t *harq_process_ul_ue;
-
- LOG_W(PHY,"This function should not be used. Use FAPI interfaces instead\n");
-
- //--------------------------Temporary configuration-----------------------------//
- length_dmrs = 1;
- n_rnti = 0x1234;
- Nid_cell = 0;
- nb_rb = 50;
- first_rb = 30;
- Nsymb_pusch = 12;
- nb_codewords = 1;
- mcs = 9;
- rvidx = 0;
- //------------------------------------------------------------------------------//
-
- for (cwd_idx = 0; cwd_idx < nb_codewords; cwd_idx++) {
-
- ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_idx];
- harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
-
- ulsch_ue->length_dmrs = length_dmrs;
- ulsch_ue->rnti = n_rnti;
- ulsch_ue->Nid_cell = Nid_cell;
- ulsch_ue->Nsc_pusch = nb_rb*NR_NB_SC_PER_RB;
- ulsch_ue->Nsymb_pusch = Nsymb_pusch;
- ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4;
-
-
- N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
- N_RE_prime = NR_NB_SC_PER_RB*Nsymb_pusch - ulsch_ue->nb_re_dmrs - N_PRB_oh;
-
- if (harq_process_ul_ue) {
-
- harq_process_ul_ue->mcs = mcs;
- harq_process_ul_ue->Nl = nb_codewords;
- harq_process_ul_ue->nb_rb = nb_rb;
- harq_process_ul_ue->first_rb = first_rb;
- harq_process_ul_ue->number_of_symbols = Nsymb_pusch;
- harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
- harq_process_ul_ue->rvidx = rvidx;
- harq_process_ul_ue->TBS = nr_compute_tbs(harq_process_ul_ue->mcs,
- nb_rb,
- Nsymb_pusch,
- ulsch_ue->nb_re_dmrs,
- length_dmrs,
- harq_process_ul_ue->Nl);
-
- }
-
- }
-
- return 0;
-}
-
-
+//#define DEBUG_PUSCH_MAPPING
void nr_pusch_codeword_scrambling(uint8_t *in,
- uint16_t size,
+ uint32_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out) {
@@ -151,39 +84,76 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
}
-uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
+void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned char harq_pid,
uint8_t slot,
uint8_t thread_id,
- int eNB_id) {
+ int gNB_id) {
- unsigned int available_bits;
+ uint32_t available_bits;
uint8_t mod_order, cwd_index, num_of_codewords;
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
- int32_t *mod_symbols[MAX_NUM_NR_RE];
uint32_t ***pusch_dmrs;
int16_t **tx_layers;
int32_t **txdataF;
uint16_t start_sc, start_rb;
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
- uint16_t n_dmrs;
- uint8_t dmrs_type;
+ uint16_t n_dmrs,code_rate;
+ uint8_t dmrs_type, length_dmrs;
uint8_t mapping_type;
- int ap, start_symbol, i;
- int sample_offsetF;
+ int ap, start_symbol, Nid_cell, i;
+ int sample_offsetF, N_RE_prime, N_PRB_oh;
+ uint16_t n_rnti;
NR_UE_ULSCH_t *ulsch_ue;
NR_UL_UE_HARQ_t *harq_process_ul_ue;
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
- NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][eNB_id];
+ NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
num_of_codewords = 1; // tmp assumption
+ length_dmrs = 1;
+ n_rnti = 0x1234;
+ Nid_cell = 0;
+ N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
- ulsch_ue = UE->ulsch[thread_id][eNB_id][cwd_index];
+ ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
+ ulsch_ue->length_dmrs = length_dmrs;
+ ulsch_ue->rnti = n_rnti;
+ ulsch_ue->Nid_cell = Nid_cell;
+ ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4;
+
+ N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh;
+
+ harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*harq_process_ul_ue->nb_rb*num_of_codewords;
+
+ mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
+ code_rate = nr_get_code_rate_ul(harq_process_ul_ue->mcs, 0);
+
+ harq_process_ul_ue->TBS = nr_compute_tbs(mod_order,
+ code_rate,
+ harq_process_ul_ue->nb_rb,
+ harq_process_ul_ue->number_of_symbols,
+ ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs,
+ 0,
+ harq_process_ul_ue->Nl);
+
+ //-----------------------------------------------------//
+ // to be removed later when MAC is ready
+
+ if (harq_process_ul_ue != NULL){
+ for (i = 0; i < harq_process_ul_ue->TBS / 8; i++)
+ harq_process_ul_ue->a[i] = (unsigned char) rand();
+ } else {
+ LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n");
+ return;
+ }
+
+ //-----------------------------------------------------//
+
/////////////////////////ULSCH coding/////////////////////////
///////////
@@ -195,10 +165,10 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////ULSCH scrambling/////////////////////////
///////////
- mod_order = nr_get_Qm(harq_process_ul_ue->mcs, 1);
+ mod_order = nr_get_Qm_ul(harq_process_ul_ue->mcs, 0);
available_bits = nr_get_G(harq_process_ul_ue->nb_rb,
- ulsch_ue->Nsymb_pusch,
+ harq_process_ul_ue->number_of_symbols,
ulsch_ue->nb_re_dmrs,
ulsch_ue->length_dmrs,
mod_order,
@@ -224,22 +194,19 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
mod_order,
(int16_t *)ulsch_ue->d_mod);
+
// pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
///////////
////////////////////////////////////////////////////////////////////////
- mod_symbols[cwd_index] = (int32_t *)malloc16((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t*));
-
- memcpy(mod_symbols[cwd_index],ulsch_ue->d_mod,(available_bits/mod_order)*sizeof(int32_t));
}
- start_symbol = 14 - ulsch_ue->Nsymb_pusch;
+ start_symbol = 14 - harq_process_ul_ue->number_of_symbols;
/////////////////////////DMRS Modulation/////////////////////////
///////////
-
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs);
int16_t mod_dmrs[n_dmrs<<1];
@@ -249,7 +216,6 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
l0 = get_l0_ul(mapping_type, 2);
nr_modulation(pusch_dmrs[l0][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
-
///////////
////////////////////////////////////////////////////////////////////////
@@ -258,13 +224,10 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
tx_layers = (int16_t **)pusch_ue->txdataF_layers;
- nr_layer_mapping((int16_t **)mod_symbols,
+ nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id],
harq_process_ul_ue->Nl,
available_bits/mod_order,
tx_layers);
-
- for (uint32_t i = 0; i < 2*available_bits/mod_order; i++)
- tx_layers[0][i] = (tx_layers[0][i] * AMP) >> 15;
///////////
////////////////////////////////////////////////////////////////////////
@@ -280,7 +243,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
uint32_t y_offset = 0;
- for (l = start_symbol; l < start_symbol + ulsch_ue->Nsymb_pusch; l++) {
+ for (l = start_symbol; l < start_symbol + harq_process_ul_ue->number_of_symbols; l++) {
if(l == dmrs_symbol)
nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; // [hna] ulsch_ue->nb_re_dmrs = 6 in this configuration
@@ -324,7 +287,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t k_prime=0;
uint16_t m=0, n=0, dmrs_idx=0, k=0;
- for (l=start_symbol; lNsymb_pusch; l++) {
+ for (l=start_symbol; lnumber_of_symbols; l++) {
k = start_sc;
@@ -338,11 +301,12 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_PUSCH_MAPPING
- printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
+ printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
#endif
+
dmrs_idx++;
k_prime++;
k_prime&=1;
@@ -372,23 +336,37 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
///////////
////////////////////////////////////////////////////////////////////////
- return 0;
+ return;
}
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
+ uint8_t harq_pid,
uint8_t slot,
- uint8_t Nl,
+ uint8_t thread_id,
+ uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_parms) {
int tx_offset, ap;
int32_t **txdata;
int32_t **txdataF;
+ int timing_advance;
+ uint8_t Nl = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->Nl; // cw 0
/////////////////////////IFFT///////////////////////
///////////
- tx_offset = slot*frame_parms->samples_per_slot;
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+ timing_advance = UE->timing_advance;
+#else
+ timing_advance = 0;
+#endif
+
+ tx_offset = slot*frame_parms->samples_per_slot - timing_advance;
+
+ if (tx_offset < 0)
+ tx_offset += frame_parms->samples_per_frame;
+
txdata = UE->common_vars.txdata;
txdataF = UE->common_vars.txdataF;
@@ -407,7 +385,6 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
frame_parms);
}
}
-
///////////
////////////////////////////////////////////////////
return 0;
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 3a962e4931..778070b347 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -23,6 +23,7 @@
#include
#include "nr_phy_scope.h"
+#include "executables/nr-softmodem-common.h"
#define TPUT_WINDOW_LENGTH 100
int otg_enabled;
@@ -588,8 +589,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form,
time = calloc(samples_per_frame,sizeof(float));
corr = calloc(samples_per_frame,sizeof(float));
- chest_t = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_time;
- chest_f = (int16_t**) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates;
+ chest_t = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time;
+ chest_f = (int16_t**) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
@@ -696,8 +697,8 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form,
if (chest_f[(atx<<1)+arx] != NULL) {
for (k=0; kofdm_symbol_size; k++) {
freq[ind] = (float)ind;
- Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
- Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
+ Re = (float)(chest_f[(atx<<1)+arx][6144+(2*k)]);
+ Im = (float)(chest_f[(atx<<1)+arx][6144+(2*k)+1]);
chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im));
ind++;
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index 37331b511d..770006d234 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -29,7 +29,6 @@
#include
#include "common/ran_context.h"
#include
-#include
#include
#include "PHY/defs_gNB.h"
//#include "PHY/defs_nrUE.h"
@@ -67,6 +66,11 @@ typedef struct {
FL_OBJECT * button_0;
} FD_phy_scope_nrue;
+typedef struct {
+ int *argc;
+ char **argv;
+} scopeParms_t;
+
extern unsigned char scope_enb_num_ue;
FD_phy_scope_gnb * create_phy_scope_gnb( void );
FD_phy_scope_nrue * create_phy_scope_nrue( void );
@@ -82,5 +86,10 @@ void phy_scope_nrUE(FD_phy_scope_nrue *form,
int eNB_id,
int UE_id,
uint8_t subframe);
+
+
+void startScope(scopeParms_t * p);
+
+
extern RAN_CONTEXT_t RC;
#endif
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index e79f9f28ac..c8b1f44f3f 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -366,11 +366,15 @@ typedef struct {
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
- int32_t **drs_ch_estimates_time;
+ int32_t **ul_ch_estimates_time;
/// \brief Hold the channel estimates in frequency domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
- int32_t **drs_ch_estimates;
+ int32_t **ul_ch_estimates;
+ /// \brief Uplink channel estimates extracted in PRBS.
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
+ int32_t **ul_ch_estimates_ext;
/// \brief Holds the compensated signal.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
@@ -383,6 +387,28 @@ typedef struct {
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_magb;
+ /// \brief Cross-correlation of two UE signals.
+ /// - first index: rx antenna [0..nb_antennas_rx[
+ /// - second index: symbol [0..]
+ int32_t **rho;
+ /// \f$\log_2(\max|H_i|^2)\f$
+ int16_t log2_maxh;
+ /// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level).
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: ? [0..168*N_RB_UL[
+ int32_t **ul_ch_mag0;
+ /// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level).
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: ? [0..168*N_RB_UL[
+ int32_t **ul_ch_mag1[8][8];
+ /// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM level).
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: ? [0..168*N_RB_UL[
+ int32_t **ul_ch_magb0;
+ /// \brief Magnitude of Uplink Channel second layer (2nd 64QAM level).
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: ? [0..168*N_RB_UL[
+ int32_t **ul_ch_magb1[8][8];
/// measured RX power based on DRS
int ulsch_power[2];
/// \brief llr values.
@@ -643,6 +669,9 @@ typedef struct PHY_VARS_gNB_s {
/// PDSCH DMRS sequence
uint32_t ****nr_gold_pdsch_dmrs;
+
+ /// PUSCH DMRS
+ uint32_t nr_gold_pusch[2][20][2][NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD];
/// Indicator set to 0 after first SR
uint8_t first_sr[NUMBER_OF_UE_MAX];
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 075650907b..780825b88a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -810,6 +810,10 @@ typedef struct {
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..287] (hard coded)
int32_t **dl_ch_estimates_ext;
+ /// \brief Hold the channel estimates in time domain (used for tracking).
+ /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
+ /// - second index: samples? [0..2*ofdm_symbol_size[
+ int32_t **dl_ch_estimates_time;
int log2_maxh;
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint32_t pbch_a_interleaved;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 3c3cb6ff41..86d2a7531d 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -228,7 +228,7 @@ typedef struct NR_DL_FRAME_PARMS {
/// Total Number of Resource Block Groups SubSets: this is P
uint8_t N_RBGS;
/// EUTRA Band
- uint8_t eutra_band;
+ uint16_t eutra_band;
/// DL carrier frequency
uint32_t dl_CarrierFreq;
/// UL carrier frequency
diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index ee14ad36ec..88a02c45c7 100644
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -208,6 +208,7 @@
/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$)
#define QAM16_n1 20724
+
/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$)
#define QAM16_n2 10362
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index fffd8140ba..2f99973290 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -54,6 +54,44 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB,
// adjust transmit amplitude here based on NFAPI info
}
+/*void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
+ uint8_t codeword_index,
+ uint8_t *sdu)
+{
+
+ int UE_id = 0; //Hardcode UE_id for now
+ int harq_pid;
+
+ NR_gNB_DLSCH_t *dlsch0=NULL, *dlsch1=NULL;
+ NR_DL_gNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+
+ // Based on nr_fill_dci_and_dlsch only gNB->dlsch[0][0] gets filled now. So maybe we do not need dlsch1.
+ dlsch0 = gNB->dlsch[UE_id][0];
+ dlsch1 = gNB->dlsch[UE_id][1];
+
+ harq_pid = dlsch0->harq_ids[subframe];
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
+
+
+ //if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU
+ if(sdu == NULL) {
+ LOG_E(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0 \n",
+ frame,subframe,
+ proc->frame_tx,proc->slot_tx);
+ return;
+ }
+ //AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
+ // frame,subframe,
+ // proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
+ // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
+ if (codeword_index == 0) dlsch0_harq->pdu = sdu;
+ else dlsch1_harq->pdu = sdu;
+ LOG_I(PHY, "SFN/SF: %d/%d DLSCH PDU filled \n",frame, subframe);
+// }
+
+}*/
+
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
int frame, int slot,
@@ -156,7 +194,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
}
}
-
+
if (nfapi_mode && do_oai && !dont_send) {
oai_nfapi_tx_req(Sched_INFO->TX_req);
diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h
index 9157ca1632..51169660bf 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.h
+++ b/openair1/SCHED_NR/fapi_nr_l1.h
@@ -36,10 +36,13 @@
#include "nfapi_nr_interface.h"
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
+
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
int frame, int subframe,
nfapi_nr_dl_config_dci_dl_pdu *dcl_dl_pdu);
+
void handle_nr_nfapi_dlsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
uint8_t *sdu);
+void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid);
diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c
index 544a8ef1dd..3ac808fac2 100644
--- a/openair1/SCHED_NR/nr_ru_procedures.c
+++ b/openair1/SCHED_NR/nr_ru_procedures.c
@@ -34,7 +34,7 @@
#include "PHY/phy_extern.h"
#include "sched_nr.h"
#include "PHY/MODULATION/modulation_common.h"
-
+#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"
@@ -248,3 +248,177 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
}
+
+
+void nr_fep0(RU_t *ru, int first_half) {
+
+ uint8_t start_symbol, end_symbol, l, aa;
+ RU_proc_t *proc = &ru->proc;
+ NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+
+ if(first_half == 1) {
+ start_symbol = 0;
+ end_symbol = NR_SYMBOLS_PER_SLOT/2;
+ } else {
+ start_symbol = NR_SYMBOLS_PER_SLOT/2;
+ end_symbol = NR_SYMBOLS_PER_SLOT;
+ }
+
+ LOG_D(PHY,"In fep0 for slot = %d, first_half = %d, start_symbol = %d, end_symbol = %d\n", proc->tti_rx, first_half, start_symbol, end_symbol);
+ // printf("fep0: slot %d\n",slot);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 1);
+
+ // remove_7_5_kHz(ru,(slot&1)+(proc->tti_rx<<1));
+ for (l = start_symbol; l < end_symbol; l++) {
+ for (aa = 0; aa < fp->nb_antennas_rx; aa++) {
+ nr_slot_fep_ul(fp,
+ ru->common.rxdata[aa],
+ ru->common.rxdataF[aa],
+ l,
+ proc->tti_rx,
+ 0,
+ 0);
+ }
+ }
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0);
+}
+
+
+static void *nr_feprx_thread(void *param) {
+
+ RU_t *ru = (RU_t *)param;
+ RU_proc_t *proc = &ru->proc;
+
+
+ while (!oai_exit) {
+
+ if (wait_on_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"NR feprx thread")<0) break;
+
+ if (oai_exit) break;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 1 );
+
+ nr_fep0(ru, 0);
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX1, 0 );
+
+ if (release_thread(&proc->mutex_fep,&proc->instance_cnt_fep,"nr_feprx thread")<0) break;
+
+ if (pthread_cond_signal(&proc->cond_fep) != 0) {
+ printf("[gNB] ERROR pthread_cond_signal for nr_feprx thread exit\n");
+ exit_fun( "ERROR pthread_cond_signal" );
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+
+void nr_init_feprx_thread(RU_t *ru) {
+
+ RU_proc_t *proc = &ru->proc;
+
+ proc->instance_cnt_fep = -1;
+
+ pthread_mutex_init( &proc->mutex_fep, NULL);
+ pthread_cond_init( &proc->cond_fep, NULL);
+
+ threadCreate(&proc->pthread_fep, nr_feprx_thread, (void*)ru, "feprx", -1, OAI_PRIORITY_RT);
+}
+
+
+void nr_fep_full_2thread(RU_t *ru, int slot) {
+
+ RU_proc_t *proc = &ru->proc;
+
+ struct timespec wait;
+
+ // NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+
+ // if ((fp->frame_type == TDD) &&
+ // (subframe_select(fp,proc->tti_rx) != SF_UL)) return;
+
+ if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
+
+ wait.tv_sec=0;
+ wait.tv_nsec=5000000L;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
+ start_meas(&ru->ofdm_demod_stats);
+
+ if (pthread_mutex_timedlock(&proc->mutex_fep,&wait) != 0) {
+ printf("[RU] ERROR pthread_mutex_lock for nr_feprx thread (IC %d)\n", proc->instance_cnt_fep);
+ exit_fun( "error locking mutex_fep" );
+ return;
+ }
+
+ if (proc->instance_cnt_fep==0) {
+ printf("[RU] FEP thread busy\n");
+ exit_fun("FEP thread busy");
+ pthread_mutex_unlock( &proc->mutex_fep );
+ return;
+ }
+
+ ++proc->instance_cnt_fep;
+
+
+ if (pthread_cond_signal(&proc->cond_fep) != 0) {
+ printf("[RU] ERROR pthread_cond_signal for nr_feprx thread\n");
+ exit_fun( "ERROR pthread_cond_signal" );
+ return;
+ }
+ //start_meas(&ru->ofdm_demod_wakeup_stats);
+
+ pthread_mutex_unlock( &proc->mutex_fep );
+
+ // call second slot in this symbol
+ nr_fep0(ru, 1);
+
+ start_meas(&ru->ofdm_demod_wait_stats);
+ wait_on_busy_condition(&proc->mutex_fep,&proc->cond_fep,&proc->instance_cnt_fep,"nr_feprx thread");
+ stop_meas(&ru->ofdm_demod_wait_stats);
+ if(opp_enabled == 1 && ru->ofdm_demod_wakeup_stats.p_time>30*3000){
+ print_meas_now(&ru->ofdm_demod_wakeup_stats,"fep wakeup",stderr);
+ printf("delay in fep wait on codition in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->tti_rx);
+ }
+
+ stop_meas(&ru->ofdm_demod_stats);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
+}
+
+
+
+void nr_fep_full(RU_t *ru, int slot) {
+
+ RU_proc_t *proc = &ru->proc;
+ int l, aa;
+ NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+
+ // if ((fp->frame_type == TDD) &&
+ // (subframe_select(fp,proc->tti_rx) != SF_UL)) return;
+
+ start_meas(&ru->ofdm_demod_stats);
+ if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 );
+
+ // remove_7_5_kHz(ru,proc->tti_rx<<1);
+ // remove_7_5_kHz(ru,1+(proc->tti_rx<<1));
+
+ for (l = 0; l < fp->symbols_per_slot; l++) {
+ for (aa = 0; aa < fp->nb_antennas_rx; aa++) {
+ nr_slot_fep_ul(fp,
+ ru->common.rxdata[aa],
+ ru->common.rxdataF[aa],
+ l,
+ proc->tti_rx,
+ 0,
+ 0);
+ }
+ }
+
+ if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 );
+ stop_meas(&ru->ofdm_demod_stats);
+
+
+}
diff --git a/openair1/SCHED_NR/phy_procedures_nr_common.c b/openair1/SCHED_NR/phy_procedures_nr_common.c
index dd859852fd..abc1c44ce5 100755
--- a/openair1/SCHED_NR/phy_procedures_nr_common.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_common.c
@@ -31,12 +31,15 @@
*/
#include "sched_nr.h"
+#include "PHY/INIT/phy_init.h"
nr_subframe_t nr_slot_select(nfapi_nr_config_request_t *cfg,
unsigned char slot)
{
- if (cfg->subframe_config.duplex_mode.value == FDD)
+ if (cfg->subframe_config.duplex_mode.value == FDD || slot == NR_DOWNLINK_SLOT || nr_is_ssb_slot(cfg, slot) == 1)
return(SF_DL);
- LOG_E(PHY,"Not developped TDD mode\n");
+ else if (slot == NR_UPLINK_SLOT)
+ return (SF_UL);
+
return -1;
}
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index cb6cb7900e..1689a627fc 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -26,10 +26,13 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
+#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "SCHED/sched_eNB.h"
+#include "sched_nr.h"
#include "SCHED/sched_common_extern.h"
-#include "nfapi_interface.h"
-#include "SCHED/fapi_l1.h"
+#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h"
+#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
+#include "fapi_nr_l1.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/INIT/phy_init.h"
@@ -210,10 +213,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
-void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
- gNB_L1_rxtx_proc_t *proc,
- int UE_id,
- uint8_t harq_pid)
+void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int UE_id, uint8_t harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu;
@@ -249,9 +249,9 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
UE_id,
gNB->pusch_vars[UE_id]->llr,
frame_parms,
- proc->frame_rx,
+ frame_rx,
nfapi_ulsch_pdu_rel15->number_symbols,
- proc->slot_rx,
+ slot_rx,
harq_pid,
0);
@@ -261,7 +261,74 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
}
-void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
+void nr_fill_rx_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid)
+{
+ // --------------------
+ // [hna] TO BE CLEANED
+ // --------------------
+
+ // nfapi_rx_indication_pdu_t *pdu;
+
+ int timing_advance_update;
+ int sync_pos;
+
+ // pthread_mutex_lock(&gNB->UL_INFO_mutex);
+
+ // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4| slot_rx;
+ // gNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG;
+
+ // pdu = &gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus];
+
+ // pdu->rx_ue_information.handle = gNB->ulsch[UE_id+1][0]->handle;
+ // pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
+ // pdu->rx_ue_information.rnti = gNB->ulsch[UE_id+1][0]->rnti;
+ // pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG;
+ // pdu->rx_indication_rel8.length = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->TBS>>3;
+ // pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation
+ // pdu->data = gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->b;
+ // estimate timing advance for MAC
+ sync_pos = nr_est_timing_advance_pusch(gNB, UE_id);
+ timing_advance_update = sync_pos; // - gNB->frame_parms.nb_prefix_samples/4; //to check
+ // printf("\x1B[33m" "timing_advance_update = %d\n" "\x1B[0m", timing_advance_update);
+
+ switch (gNB->frame_parms.N_RB_DL) {
+ // case 6: /* nothing to do */ break;
+ // case 15: timing_advance_update /= 2; break;
+ // case 25: timing_advance_update /= 4; break;
+ // case 50: timing_advance_update /= 8; break;
+ // case 75: timing_advance_update /= 12; break;
+ case 106: timing_advance_update /= 16; break;
+ case 217: timing_advance_update /= 32; break;
+ default: abort();
+ }
+
+ // put timing advance command in 0..63 range
+ timing_advance_update += 31;
+
+ if (timing_advance_update < 0) timing_advance_update = 0;
+ if (timing_advance_update > 63) timing_advance_update = 63;
+
+ // pdu->rx_indication_rel8.timing_advance = timing_advance_update;
+
+ // estimate UL_CQI for MAC (from antenna port 0 only)
+ // int SNRtimes10 = dB_fixed_times10(gNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*gNB->measurements.n0_power_dB[0]);
+
+ // if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0;
+ // else if (SNRtimes10 > 635) pdu->rx_indication_rel8.ul_cqi=255;
+ // else pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5;
+
+ // LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
+ // harq_pid,frame,slot_rx,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
+ // timing_advance_update);
+
+ // gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++;
+ // gNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | slot_rx;
+
+ // pthread_mutex_unlock(&gNB->UL_INFO_mutex);
+}
+
+
+void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
uint8_t symbol;
unsigned char aa;
@@ -273,7 +340,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
gNB->common_vars.rxdata[aa],
gNB->common_vars.rxdataF[aa],
symbol,
- proc->slot_rx,
+ slot_rx,
0,
0);
}
@@ -282,23 +349,18 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
}
-void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end) {
+void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint8_t symbol_start, uint8_t symbol_end) {
uint8_t UE_id;
uint8_t symbol;
uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ)
// In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ)
- for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
-
+ for (UE_id = 0; UE_id < 1; UE_id++) { // temporary set to 1 untill list of connected UEs is implemented
for(symbol = symbol_start; symbol < symbol_end; symbol++) {
-
- nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
-
+ nr_rx_pusch(gNB, UE_id, frame_rx, slot_rx, symbol, harq_pid);
}
-
- nr_ulsch_procedures(gNB, proc, UE_id, harq_pid);
-
+ nr_ulsch_procedures(gNB, frame_rx, slot_rx, UE_id, harq_pid);
+ nr_fill_rx_indication(gNB, frame_rx, slot_rx, UE_id, harq_pid); // indicate SDU to MAC
}
-
}
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index b6b4b6ca1c..a8d4aa272f 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -37,14 +37,16 @@
nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot);
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
-void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc);
-void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end);
+void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
+void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint8_t symbol_start, uint8_t symbol_end);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols);
void nr_init_feptx_thread(RU_t *ru);
-void fep_full(RU_t *ru,int slot);
+void nr_init_feprx_thread(RU_t *ru);
+void nr_fep_full(RU_t *ru, int slot);
+void nr_fep_full_2thread(RU_t *ru, int slot);
void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
int nr_phy_init_RU(RU_t *ru);
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index 4635f6fb49..8e42149add 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -370,7 +370,7 @@ void nr_compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsP
void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx);
int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx);
-
+int is_pbch_in_slot(fapi_nr_pbch_config_t *pbch_config, int frame, int slot, int periodicity, uint16_t slots_per_frame);
/*@}*/
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 6802b77d8c..ced40c491a 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -123,6 +123,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
dlsch0_harq->Nl=1;
+ dlsch0_harq->mcs_table=0;
dlsch0_harq->status = ACTIVE;
LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs);
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 6a772140c2..60378d81fc 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -2464,53 +2464,28 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t gNB_id,
- uint8_t thread_id)
+ UE_nr_rxtx_proc_t *proc,
+ uint8_t gNB_id,
+ uint8_t thread_id)
{
- //NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
- NR_UE_ULSCH_t *ulsch_ue;
- NR_UL_UE_HARQ_t *harq_process_ul_ue;
//int32_t ulsch_start=0;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
- int harq_pid, i, TBS;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
- LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
+ LOG_I(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_tx);
#endif
-
- harq_pid = 0; //temporary implementation
-
- /*
- generate_ue_ulsch_params(ue,
- 0,
- gNB_id,
- harq_pid);
- */
-
- ulsch_ue = ue->ulsch[thread_id][gNB_id][0]; // cwd_index = 0
- harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
-
- TBS = nr_compute_tbs( harq_process_ul_ue->mcs, harq_process_ul_ue->nb_rb, ulsch_ue->Nsymb_pusch, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, harq_process_ul_ue->Nl);
-
-//-----------------------------------------------------//
- // to be removed later when MAC is ready
-
- for (i = 0; i < TBS / 8; i++)
- harq_process_ul_ue->a[i] = (unsigned char) rand();
-
-//-----------------------------------------------------//
+ uint8_t harq_pid = 0; //temporary implementation
nr_ue_ulsch_procedures(ue,
harq_pid,
slot_tx,
- 0,
+ thread_id,
gNB_id);
@@ -2525,11 +2500,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
nr_ue_pusch_common_procedures(ue,
+ harq_pid,
slot_tx,
- harq_process_ul_ue->Nl,
+ thread_id,
+ gNB_id,
&ue->frame_parms);
+
/*
if ((ue->UE_mode[eNB_id] == PRACH) &&
(ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
@@ -2546,7 +2524,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
}
*/
- LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
+ LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
@@ -3329,7 +3307,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
harq_processes_dest->B = current_harq_processes->B ;
harq_processes_dest->C = current_harq_processes->C ;
- harq_processes_dest->DCINdi = current_harq_processes->DCINdi ;
+ harq_processes_dest->DCINdi = current_harq_processes->DCINdi ;
harq_processes_dest->F = current_harq_processes->F ;
harq_processes_dest->G = current_harq_processes->G ;
harq_processes_dest->K = current_harq_processes->K ;
@@ -3342,6 +3320,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ;
harq_processes_dest->first_tx = current_harq_processes->first_tx ;
harq_processes_dest->mcs = current_harq_processes->mcs ;
+ harq_processes_dest->mcs_table = current_harq_processes->mcs_table ;
harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ;
harq_processes_dest->nb_rb = current_harq_processes->nb_rb ;
harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ;
@@ -3406,7 +3385,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
first_symbol_flag = 0;
#if UE_TIMING_TRACE
uint8_t slot = 0;
- if(m >= ue->frame_parms.symbols_per_tti>>1)
+ if(m >= ue->frame_parms.symbols_per_slot>>1)
slot = 1;
start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]);
#endif
@@ -3558,14 +3537,19 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4;
uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value;
uint16_t nb_symb_sch = 9;
+ nr_downlink_indication_t dl_indication;
+ fapi_nr_rx_indication_t rx_ind;
if (dlsch0==NULL)
AssertFatal(0,"dlsch0 should be defined at this level \n");
+
harq_pid = dlsch0->current_harq_pid;
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
+
+
if(dlsch1)
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
@@ -3789,6 +3773,33 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx);
+
+ LOG_I(PHY, "harq_pid: %d, TBS expected dlsch0: %d, TBS expected dlsch1: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS, dlsch1->harq_processes[harq_pid]->TBS);
+
+ if(retmax_ldpc_iterations+1){
+ // fill dl_indication message
+ dl_indication.module_id = ue->Mod_id;
+ dl_indication.cc_id = ue->CC_id;
+ dl_indication.gNB_index = eNB_id;
+ dl_indication.frame = frame_rx;
+ dl_indication.slot = nr_tti_rx;
+
+ dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance
+ dl_indication.proc=proc;
+
+ //dl_indication.rx_ind->number_pdus
+ rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
+ rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
+ LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
+ rx_ind.number_pdus = 1;
+
+ //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now
+ dl_indication.dci_ind = NULL; //&ue->dci_ind;
+ // send to mac
+ if (ue->if_inst && ue->if_inst->dl_indication)
+ ue->if_inst->dl_indication(&dl_indication);
+ }
}
@@ -3899,7 +3910,7 @@ void *UE_thread_slot1_dl_processing(void *arg) {
0);
*/
// 1- perform FFT
- for (int l=1; lframe_parms.symbols_per_tti>>1; l++)
+ for (int l=1; lframe_parms.symbols_per_slot>>1; l++)
{
//if( (l != pilot0) && (l != pilot1))
{
@@ -3931,7 +3942,7 @@ void *UE_thread_slot1_dl_processing(void *arg) {
}
// 2- perform Channel Estimation for slot1
- for (int l=1; lframe_parms.symbols_per_tti>>1; l++)
+ for (int l=1; lframe_parms.symbols_per_slot>>1; l++)
{
if(l == pilot1)
{
@@ -4019,8 +4030,8 @@ void *UE_thread_slot1_dl_processing(void *arg) {
PDSCH,
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
NULL,
- (ue->frame_parms.symbols_per_tti>>1),
- ue->frame_parms.symbols_per_tti-1,
+ (ue->frame_parms.symbols_per_slot>>1),
+ ue->frame_parms.symbols_per_slot-1,
abstraction_flag);
LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
@@ -4034,8 +4045,8 @@ void *UE_thread_slot1_dl_processing(void *arg) {
SI_PDSCH,
ue->dlsch_SI[eNB_id],
NULL,
- (ue->frame_parms.symbols_per_tti>>1),
- ue->frame_parms.symbols_per_tti-1,
+ (ue->frame_parms.symbols_per_slot>>1),
+ ue->frame_parms.symbols_per_slot-1,
abstraction_flag);
}
@@ -4047,8 +4058,8 @@ void *UE_thread_slot1_dl_processing(void *arg) {
P_PDSCH,
ue->dlsch_p[eNB_id],
NULL,
- (ue->frame_parms.symbols_per_tti>>1),
- ue->frame_parms.symbols_per_tti-1,
+ (ue->frame_parms.symbols_per_slot>>1),
+ ue->frame_parms.symbols_per_slot-1,
abstraction_flag);
}
// do procedures for RA-RNTI
@@ -4059,8 +4070,8 @@ void *UE_thread_slot1_dl_processing(void *arg) {
RA_PDSCH,
ue->dlsch_ra[eNB_id],
NULL,
- (ue->frame_parms.symbols_per_tti>>1),
- ue->frame_parms.symbols_per_tti-1,
+ (ue->frame_parms.symbols_per_slot>>1),
+ ue->frame_parms.symbols_per_slot-1,
abstraction_flag);
}
@@ -4116,10 +4127,10 @@ int is_pbch_in_slot(fapi_nr_pbch_config_t *pbch_config, int frame, int slot, int
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
- UE_nr_rxtx_proc_t *proc,
- uint8_t eNB_id,
- uint8_t do_pdcch_flag,
- runmode_t mode)
+ UE_nr_rxtx_proc_t *proc,
+ uint8_t eNB_id,
+ uint8_t do_pdcch_flag,
+ runmode_t mode)
{
int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx;
@@ -4129,6 +4140,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
uint8_t harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->current_harq_pid;
NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
uint16_t nb_symb_sch = dlsch0_harq->nb_symbols;
+ uint16_t start_symb_sch = dlsch0_harq->start_symbol;
uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration;
uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE)
uint8_t dci_cnt = 0;
@@ -4155,6 +4167,43 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
}
uint16_t coreset_nb_rb = 6 * coreset_count;
uint16_t coreset_start_rb = 6 * coreset_start;
+
+ slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame);
+
+ // looking for pbch only in slot where it is supposed to be
+ if ((ue->decode_MIB == 1) && slot_pbch)
+ {
+ LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
+
+ for (int i=1; i<4; i++) {
+
+ nr_slot_fep(ue,
+ (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),
+ nr_tti_rx,
+ 0,
+ 0);
+
+#if UE_TIMING_TRACE
+ start_meas(&ue->dlsch_channel_estimation_stats);
+#endif
+ nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config->ssb_index)&7,pbch_config->half_frame_bit);
+#if UE_TIMING_TRACE
+ stop_meas(&ue->dlsch_channel_estimation_stats);
+#endif
+
+ }
+ nr_ue_pbch_procedures(eNB_id,ue,proc,0);
+
+ if (ue->no_timing_correction==0) {
+ LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction);
+ nr_adjust_synch_ue(&ue->frame_parms,
+ ue,
+ eNB_id,
+ nr_tti_rx,
+ 0,
+ 16384);
+ }
+ }
#ifdef NR_PDCCH_SCHED
nr_gold_pdcch(ue, 0, 2);
@@ -4194,16 +4243,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (dci_cnt > 0) {
LOG_I(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n",ue->Mod_id,frame_rx,nr_tti_rx,dci_cnt);
-
- if (ue->no_timing_correction==0) {
- LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction);
- nr_adjust_synch_ue(&ue->frame_parms,
- ue,
- eNB_id,
- nr_tti_rx,
- 0,
- 16384);
- }
+
} else {
LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n",ue->Mod_id,frame_rx,nr_tti_rx);
}
@@ -4213,11 +4253,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
if (dci_cnt > 0){
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
//to update from pdsch config
- nr_gold_pdsch(ue,nb_symb_pdcch,0, 1);
+ start_symb_sch = dlsch0_harq->start_symbol;
+ nr_gold_pdsch(ue,start_symb_sch,0, 1);
nb_symb_sch = dlsch0_harq->nb_symbols;
- for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){
+ for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
nr_slot_fep(ue,
m, //to be updated from higher layer
nr_tti_rx,
@@ -4229,7 +4270,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
//set active for testing, to be removed
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1;
}
- else
+ else
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
#if UE_TIMING_TRACE
@@ -4298,37 +4339,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
}
-
- slot_pbch = is_pbch_in_slot(pbch_config, frame_rx, nr_tti_rx, ssb_periodicity, ue->frame_parms.slots_per_frame);
-
- // looking for pbch only in slot where it is supposed to be
- if ((ue->decode_MIB == 1) && slot_pbch)
- {
- LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
-
- for (int i=1; i<4; i++) {
-
- nr_slot_fep(ue,
- (ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),
- nr_tti_rx,
- 0,
- 0);
-
-#if UE_TIMING_TRACE
- start_meas(&ue->dlsch_channel_estimation_stats);
-#endif
- nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(ue->frame_parms.symbols_per_slot),i-1,(pbch_config->ssb_index)&7,pbch_config->half_frame_bit);
-#if UE_TIMING_TRACE
- stop_meas(&ue->dlsch_channel_estimation_stats);
-#endif
-
- }
- nr_ue_pbch_procedures(eNB_id,ue,proc,0);
- }
-
+
// do procedures for C-RNTI
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
+ LOG_I(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
#if UE_TIMING_TRACE
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index f0901a0048..aab762b9e2 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -53,6 +53,8 @@
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
@@ -108,6 +110,7 @@ int main(int argc, char **argv)
uint16_t nb_symb_sch = 12;
uint16_t nb_rb = 50;
uint8_t Imcs = 9;
+ uint8_t mcs_table = 0;
cpuf = get_cpu_freq_GHz();
@@ -428,6 +431,7 @@ int main(int argc, char **argv)
uint8_t nb_re_dmrs = 6;
uint16_t length_dmrs = 1;
unsigned char mod_order;
+ uint16_t rate;
uint8_t Nl = 1;
uint8_t rvidx = 0;
dlsch->rnti = 1;
@@ -435,9 +439,10 @@ int main(int argc, char **argv)
dlsch->harq_processes[0]->rvidx = rvidx;*/
//printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
// dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
- mod_order = nr_get_Qm(Imcs, 1);
+ mod_order = nr_get_Qm_dl(Imcs, mcs_table);
+ rate = nr_get_code_rate_dl(Imcs, mcs_table);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
+ TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
//dlsch->harq_ids[subframe]= 0;
rel15->n_prb = nb_rb;
@@ -446,6 +451,7 @@ int main(int argc, char **argv)
rel15->nb_layers = Nl;
rel15->nb_re_dmrs = nb_re_dmrs;
rel15->transport_block_size = TBS;
+ rel15->coding_rate = rate;
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
@@ -460,10 +466,12 @@ int main(int argc, char **argv)
NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0];
NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
harq_process->mcs = Imcs;
+ harq_process->mcs_table = mcs_table;
harq_process->Nl = Nl;
harq_process->nb_rb = nb_rb;
harq_process->Qm = mod_order;
harq_process->rvidx = rvidx;
+ harq_process->R = rate;
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
unsigned char *test_input;
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 25eeeeb5d2..e3e8eef767 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -60,6 +60,8 @@
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode=0;
uint16_t NB_UE_INST = 1;
@@ -72,6 +74,56 @@ int rrc_init_nr_global_param (void) {return(0);}
void config_common(int Mod_idP,int CC_idP,int Nid_cell,int nr_bandP,uint64_t SSB_positions,uint16_t ssb_periodicity,uint64_t dl_CarrierFreqP,uint32_t dl_BandwidthP);
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return(0);}
+uint64_t get_softmodem_optmask(void) {return 0;}
+mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, const rnti_t rntiP,
+ const eNB_index_t eNB_index, const frame_t frameP,
+ const sub_frame_t subframeP, const eNB_flag_t enb_flagP,
+ const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP,
+ const tb_size_t tb_sizeP
+ #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,const uint32_t sourceL2Id
+ ,const uint32_t destinationL2Id
+ #endif
+ ){mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;}
+tbs_size_t mac_rlc_data_req(
+ const module_id_t module_idP,
+ const rnti_t rntiP,
+ const eNB_index_t eNB_index,
+ const frame_t frameP,
+ const eNB_flag_t enb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const logical_chan_id_t channel_idP,
+ const tb_size_t tb_sizeP,
+ char *buffer_pP
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,const uint32_t sourceL2Id
+ ,const uint32_t destinationL2Id
+#endif
+ )
+{return 0;}
+int generate_dlsch_header(unsigned char *mac_header,
+ unsigned char num_sdus,
+ unsigned short *sdu_lengths,
+ unsigned char *sdu_lcids,
+ unsigned char drx_cmd,
+ unsigned short timing_advance_cmd,
+ unsigned char *ue_cont_res_id,
+ unsigned char short_padding,
+ unsigned short post_padding){return 0;}
+void nr_ip_over_LTE_DRB_preconfiguration(void){}
+void mac_rlc_data_ind (
+ const module_id_t module_idP,
+ const rnti_t rntiP,
+ const eNB_index_t eNB_index,
+ const frame_t frameP,
+ const eNB_flag_t enb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const logical_chan_id_t channel_idP,
+ char *buffer_pP,
+ const tb_size_t tb_sizeP,
+ num_tb_t num_tbP,
+ crc_t *crcs_pP)
+{}
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
@@ -115,6 +167,12 @@ int main(int argc, char **argv)
//double pbch_sinr;
//int pbch_tx_ant;
int N_RB_DL=106,mu=1;
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
+ dlsch_config.start_prb = 0;
+ dlsch_config.n_prb = 50;
+ dlsch_config.start_symbol = 2;
+ dlsch_config.nb_symbols = 9;
+ dlsch_config.mcs_idx = 9;
uint16_t ssb_periodicity = 10;
@@ -136,6 +194,7 @@ int main(int argc, char **argv)
int run_initial_sync=0;
int do_pdcch_flag=1;
+ uint16_t cset_offset = 0;
int loglvl=OAILOG_WARNING;
float target_error_rate = 0.01;
@@ -148,7 +207,7 @@ int main(int argc, char **argv)
randominit(0);
- while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:")) != -1) {
+ while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dP:IL:o:a:b:c:j:e:")) != -1) {
switch (c) {
/*case 'f':
write_output_file=1;
@@ -313,6 +372,30 @@ int main(int argc, char **argv)
loglvl = atoi(optarg);
break;
+ case 'o':
+ cset_offset = atoi(optarg);
+ break;
+
+ case 'a':
+ dlsch_config.start_prb = atoi(optarg);
+ break;
+
+ case 'b':
+ dlsch_config.n_prb = atoi(optarg);
+ break;
+
+ case 'c':
+ dlsch_config.start_symbol = atoi(optarg);
+ break;
+
+ case 'j':
+ dlsch_config.nb_symbols = atoi(optarg);
+ break;
+
+ case 'e':
+ dlsch_config.mcs_idx = atoi(optarg);
+ 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",
@@ -338,6 +421,12 @@ int main(int argc, char **argv)
//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("-o CORESET offset\n");
+ printf("-a Start PRB for PDSCH\n");
+ printf("-b Number of PRB for PDSCH\n");
+ printf("-c Start symbol for PDSCH (fixed for now)\n");
+ printf("-j Number of symbols for PDSCH (fixed for now)\n");
+ printf("-e MSC index\n");
exit (-1);
break;
}
@@ -430,7 +519,7 @@ int main(int argc, char **argv)
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
- bzero(r_re[i],frame_length_complex_samples*sizeof(int));
+ bzero(txdata[i],frame_length_complex_samples*sizeof(int));
}
@@ -494,12 +583,14 @@ int main(int argc, char **argv)
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
+ uint16_t rb_offset_count = cset_offset/6;
+ set_cset_offset(rb_offset_count);
// generate signal
if (input_fd==NULL) {
gNB->pbch_configured = 1;
for (int i=0;i<4;i++) gNB->pbch_pdu[i]=i+1;
- nr_schedule_uss_dlsch_phytest(0,frame,slot);
+ nr_schedule_uss_dlsch_phytest(0,frame,slot,&dlsch_config);
Sched_INFO.module_id = 0;
Sched_INFO.CC_id = 0;
Sched_INFO.frame = frame;
@@ -592,13 +683,15 @@ int main(int argc, char **argv)
uint64_t mask = 0x0;
uint16_t num_rbs=24;
- uint16_t rb_offset=0;
+ uint16_t rb_offset=gNB->pdcch_vars.dci_alloc[0].pdcch_params.rb_offset;
uint16_t cell_id=0;
uint16_t num_symbols=2;
for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs
mask = mask >> 1;
mask = mask | 0x100000000000;
}
+ uint16_t UE_rb_offset_count = rb_offset/6;
+ mask = mask >> UE_rb_offset_count;
dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.frequency_domain_resource = mask;
dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.rb_offset = rb_offset; // additional parameter other than coreset
@@ -609,8 +702,6 @@ int main(int argc, char **argv)
dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.cce_reg_interleaved_shift_index = cell_id;
dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE;
dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15.coreset.pdcch_dmrs_scrambling_id = cell_id;
- uint8_t gnb_start_symbol = Sched_INFO.DL_req->dl_config_request_body.dl_config_pdu_list[1].dlsch_pdu.dlsch_pdu_rel15.start_symbol;
- dl_config->dl_config_list[0].dlsch_config_pdu.dlsch_config_rel15.start_symbol = gnb_start_symbol;
uint32_t number_of_search_space_per_slot=1;
uint32_t first_symbol_index=0;
@@ -649,8 +740,10 @@ int main(int argc, char **argv)
//n_errors2 = 0;
//n_alamouti = 0;
+ n_false_positive = 0;
for (trial = 0; trial < n_trials; trial++) {
+ errors_bit = 0;
//multipath channel
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
@@ -708,7 +801,8 @@ int main(int argc, char **argv)
}
- if (UE_mac->dl_config_request.number_pdus == 0)
+ if (UE->dlsch[UE->current_thread_id[slot]][0][0]->last_iteration_cnt >=
+ UE->dlsch[UE->current_thread_id[slot]][0][0]->max_ldpc_iterations+1)
n_errors++;
//----------------------------------------------------------
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 7e0709da36..d312eb6f90 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -52,6 +52,8 @@
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode=0;
uint16_t NB_UE_INST = 1;
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 08b73948b5..757f8abb03 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -50,6 +50,8 @@ PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
openair0_config_t openair0_cfg[MAX_CARDS];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode=0;
uint16_t NB_UE_INST = 1;
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index caf2f204f3..3a0b9437da 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -52,6 +52,8 @@
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
@@ -65,7 +67,7 @@ int main(int argc, char **argv)
{
char c;
int i,sf;
- double SNR, snr0 = -2.0, snr1 = 2.0; //, SNR_lin;
+ double SNR, snr0 = -2.0, snr1 = 2.0, SNR_lin;
double snr_step = 0.1;
uint8_t snr1set = 0;
FILE *output_fd = NULL;
@@ -84,7 +86,7 @@ int main(int argc, char **argv)
//unsigned char pbch_phase = 0;
int frame = 0, subframe = 0;
NR_DL_FRAME_PARMS *frame_parms;
- //double sigma;
+ double sigma;
unsigned char qbits = 8;
int ret;
int loglvl = OAILOG_WARNING;
@@ -373,7 +375,7 @@ int main(int argc, char **argv)
uint8_t nb_re_dmrs = 6;
uint8_t length_dmrs = 1;
uint8_t N_PRB_oh;
- uint16_t N_RE_prime;
+ uint16_t N_RE_prime,code_rate;
unsigned char mod_order;
uint8_t Nl = 1;
uint8_t rvidx = 0;
@@ -384,9 +386,10 @@ int main(int argc, char **argv)
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
- mod_order = nr_get_Qm(Imcs, 1);
+ mod_order = nr_get_Qm_ul(Imcs, 0);
+ code_rate = nr_get_code_rate_ul(Imcs, 0);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl);
+ TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
@@ -399,6 +402,7 @@ int main(int argc, char **argv)
rel15_ul->n_layers = Nl;
rel15_ul->nb_re_dmrs = nb_re_dmrs;
rel15_ul->length_dmrs = length_dmrs;
+ rel15_ul->R = code_rate;
///////////////////////////////////////////////////
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
@@ -492,11 +496,15 @@ int main(int argc, char **argv)
//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
- //SNR_lin = pow(10, SNR / 10.0);
- //sigma = 1.0 / sqrt(2 * SNR_lin);
+#if 1
+ SNR_lin = pow(10, SNR / 10.0);
+ sigma = 1.0 / sqrt(2 * SNR_lin);
+ channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0,
+ modulated_input[i] + sigma * gaussdouble(0.0, 1.0),
+ qbits);
+#else
channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits);
- //channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, modulated_input[i] + sigma * gaussdouble(0.0, 1.0), qbits);
- //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
+#endif
//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
//Uncoded BER
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 15e27b3c1f..90403aa1b9 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -60,6 +60,8 @@
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+
double cpuf;
int nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
@@ -67,6 +69,23 @@ uint16_t NB_UE_INST = 1;
// dummy functions
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
+void mac_rlc_data_ind (
+ const module_id_t module_idP,
+ const rnti_t rntiP,
+ const eNB_index_t eNB_index,
+ const frame_t frameP,
+ const eNB_flag_t enb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const logical_chan_id_t channel_idP,
+ char *buffer_pP,
+ const tb_size_t tb_sizeP,
+ num_tb_t num_tbP,
+ crc_t *crcs_pP)
+{}
+uint64_t get_softmodem_optmask(void) {return 0;}
+int rlc_module_init (void) {return(0);}
+void pdcp_layer_init (void) {}
+void nr_ip_over_LTE_DRB_preconfiguration(void){}
// needed for some functions
uint16_t n_rnti = 0x1234;
@@ -83,7 +102,7 @@ int main(int argc, char **argv)
int slot = 0;
FILE *output_fd = NULL;
//uint8_t write_output_file = 0;
- int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
+ int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
uint8_t n_tx = 1, n_rx = 1;
//uint8_t transmission_mode = 1;
uint16_t Nid_cell = 0;
@@ -94,7 +113,7 @@ int main(int argc, char **argv)
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
//unsigned char frame_type = 0;
- int frame = 0;
+ int number_of_frames = 1;
int frame_length_complex_samples;
NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING;
@@ -109,10 +128,9 @@ int main(int argc, char **argv)
int tx_offset;
double txlev_float;
int32_t txlev;
- int start_rb = 30;
+ int start_rb = 0;
int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
-
cpuf = get_cpu_freq_GHz();
@@ -126,8 +144,21 @@ int main(int argc, char **argv)
//logInit();
randominit(0);
- while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) {
+ while ((c = getopt(argc, argv, "d:f:g:h:i:j:l:m:n:p:r:s:y:z:F:M:N:P:R:S:")) != -1) {
switch (c) {
+
+ /*case 'd':
+ frame_type = 1;
+ break;*/
+
+ case 'd':
+ delay = atoi(optarg);
+ break;
+
+ case 'f':
+ number_of_frames = atoi(optarg);
+ break;
+
/*case 'f':
write_output_file = 1;
output_fd = fopen(optarg, "w");
@@ -139,10 +170,6 @@ int main(int argc, char **argv)
break;*/
- /*case 'd':
- frame_type = 1;
- break;*/
-
case 'g':
switch ((char) *optarg) {
case 'A':
@@ -188,25 +215,31 @@ int main(int argc, char **argv)
interf2 = atoi(optarg);
break;*/
+ case 'l':
+ nb_symb_sch = atoi(optarg);
+ break;
+
+ case 'm':
+ Imcs = atoi(optarg);
+ break;
+
case 'n':
n_trials = atoi(optarg);
break;
+ case 'p':
+ extended_prefix_flag = 1;
+ break;
+
+ case 'r':
+ nb_rb = atoi(optarg);
+ break;
+
case 's':
snr0 = atof(optarg);
printf("Setting SNR0 to %f\n", snr0);
break;
- case 'S':
- snr1 = atof(optarg);
- snr1set = 1;
- printf("Setting SNR1 to %f\n", snr1);
- break;
-
- case 'p':
- extended_prefix_flag = 1;
- break;
-
/*
case 'r':
ricean_factor = pow(10,-.1*atof(optarg));
@@ -217,6 +250,10 @@ int main(int argc, char **argv)
break;
*/
+ /*case 'x':
+ transmission_mode = atoi(optarg);
+ break;*/
+
case 'y':
n_tx = atoi(optarg);
@@ -237,6 +274,16 @@ int main(int argc, char **argv)
break;
+ case 'F':
+ input_fd = fopen(optarg, "r");
+
+ if (input_fd == NULL) {
+ printf("Problem with filename %s\n", optarg);
+ exit(-1);
+ }
+
+ break;
+
case 'M':
SSB_positions = atoi(optarg);
break;
@@ -250,56 +297,39 @@ int main(int argc, char **argv)
N_RB_UL = N_RB_DL;
break;
- case 'F':
- input_fd = fopen(optarg, "r");
-
- if (input_fd == NULL) {
- printf("Problem with filename %s\n", optarg);
- exit(-1);
- }
-
+ case 'S':
+ snr1 = atof(optarg);
+ snr1set = 1;
+ printf("Setting SNR1 to %f\n", snr1);
break;
- case 'm':
- Imcs = atoi(optarg);
- break;
-
- case 'l':
- nb_symb_sch = atoi(optarg);
- break;
-
- case 'r':
- nb_rb = atoi(optarg);
- break;
-
- /*case 'x':
- transmission_mode = atoi(optarg);
- 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("-h This message\n");
- printf("-p Use extended prefix mode\n");
//printf("-d Use TDD\n");
- printf("-n Number of frames to simulate\n");
- printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n");
- printf("-S Ending SNR, runs from SNR0 to SNR1\n");
- printf("-t Delay spread for multipath channel\n");
+ printf("-d Introduce delay in terms of number of samples\n");
+ printf("-f Number of frames to simulate\n");
printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
+ printf("-h This message\n");
+ //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
+ //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
+ printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
+ printf("-m MCS value\n");
+ printf("-n Number of trials to simulate\n");
+ printf("-p Use extended prefix mode\n");
+ printf("-t Delay spread for multipath channel\n");
//printf("-x Transmission mode (1,2,6 for the moment)\n");
printf("-y Number of TX antennas used in eNB\n");
printf("-z Number of RX antennas used in UE\n");
- //printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
- //printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
- printf("-M Multiple SSB positions in burst\n");
- printf("-N Nid_cell\n");
- 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("-f Output filename (.txt format) for Pe/SNR results\n");
printf("-F Input filename (.txt format) for RX conformance testing\n");
+ printf("-M Multiple SSB positions in burst\n");
+ printf("-N Nid_cell\n");
+ printf("-O oversampling factor (1,2,4,8,16)\n");
+ printf("-R N_RB_DL\n");
+ printf("-S Ending SNR, runs from SNR0 to SNR1\n");
exit(-1);
break;
}
@@ -327,13 +357,6 @@ int main(int argc, char **argv)
RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0][0];
//gNB_config = &gNB->gNB_config;
- gNB_L1_rxtx_proc_t gNB_proc;
-
- gNB_proc.frame_rx = frame;
- gNB_proc.slot_rx = slot;
-
- UE_proc.nr_tti_tx = slot;
- UE_proc.frame_tx = frame;
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx;
@@ -344,7 +367,7 @@ int main(int argc, char **argv)
crcTableInit();
- nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions);
+ nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_UL, mu, Nid_cell, SSB_positions);
phy_init_nr_gNB(gNB, 0, 0);
//init_eNB_afterRU();
@@ -381,184 +404,198 @@ int main(int argc, char **argv)
}
}
-
unsigned char harq_pid = 0;
- unsigned int TBS = 8424;
+ unsigned int TBS;
unsigned int available_bits;
uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4;
uint8_t length_dmrs = 1;
unsigned char mod_order;
+ uint16_t code_rate;
- mod_order = nr_get_Qm(Imcs, 1);
+ mod_order = nr_get_Qm_ul(Imcs, 0);
+ code_rate = nr_get_code_rate_ul(Imcs, 0);
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
- TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, precod_nbr_layers);
+ TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers);
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id+1][0];
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
-
- // --------- setting rel15_ul parameters for gNB --------
- rel15_ul->rnti = n_rnti;
- rel15_ul->ulsch_pdu_rel15.start_rb = start_rb;
- rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
- rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
- rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
- rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs;
- rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs;
- rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
- rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
- rel15_ul->ulsch_pdu_rel15.rv = 0;
- rel15_ul->ulsch_pdu_rel15.ndi = 0;
- rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers;
- ///////////////////////////////////////////////////
-
- nr_scheduled_response_t scheduled_response;
- fapi_nr_ul_config_request_t ul_config;
- //fapi_nr_tx_request_t tx_request;
-
- scheduled_response.module_id = 0;
- scheduled_response.CC_id = 0;
- scheduled_response.frame = frame;
- scheduled_response.slot = slot;
- scheduled_response.dl_config = NULL;
- scheduled_response.ul_config = &ul_config;
- scheduled_response.dl_config = NULL;
-
- ul_config.sfn_slot = slot;
- ul_config.number_pdus = 1;
- ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
- ul_config.ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
- ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
- //there are plenty of other parameters that we don't seem to be using for now. e.g.
- //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0;
-
- // set FAPI parameters for UE, put them in the scheduled response and call
- nr_ue_scheduled_response(&scheduled_response);
-
unsigned char *estimated_output_bit;
unsigned char *test_input_bit;
- unsigned int errors_bit = 0;
+ uint32_t errors_decoding = 0;
uint32_t errors_scrambling = 0;
+ uint32_t is_frame_in_error = 0;
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
- /////////////////////////phy_procedures_nr_ue_TX///////////////////////
- ///////////
-
- phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);
-
- ///////////
- ////////////////////////////////////////////////////
- tx_offset = slot*frame_parms->samples_per_slot;
-
- txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
- frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
-
- txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation
-
-
+ nr_scheduled_response_t scheduled_response;
+ fapi_nr_ul_config_request_t ul_config;
printf("\n");
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
- n_errors = 0;
- n_false_positive = 0;
+ printf("-------------------\n");
+ printf("SNR %f\n", SNR);
+ printf("-------------------\n");
- //AWGN
- sigma_dB = 10*log10(txlev_float)-SNR;
- sigma = pow(10,sigma_dB/10);
+ is_frame_in_error = 0;
+ for (int frame = 0; frame < number_of_frames; frame++) {
- for (trial = 0; trial < n_trials; trial++) {
+ UE_proc.nr_tti_tx = slot;
+ UE_proc.frame_tx = frame;
- errors_scrambling = 0;
- errors_bit = 0;
+ // --------- setting rel15_ul parameters for gNB --------
+ rel15_ul->rnti = n_rnti;
+ rel15_ul->ulsch_pdu_rel15.start_rb = start_rb;
+ rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
+ rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
+ rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
+ rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = nb_re_dmrs;
+ rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs;
+ rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
+ rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
+ rel15_ul->ulsch_pdu_rel15.rv = 0;
+ rel15_ul->ulsch_pdu_rel15.ndi = 0;
+ rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers;
+ rel15_ul->ulsch_pdu_rel15.R = code_rate;
+ ///////////////////////////////////////////////////
- for (i=0; inb_antennas_rx; ap++) {
- // [hna] doesn't work with noise in case of mod_order = 6
- ((short*) gNB->common_vars.rxdata[ap])[2*i] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)])+ (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point
- ((short*) gNB->common_vars.rxdata[ap])[2*i+1] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1])+ (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP);
- }
- }
+ //fapi_nr_tx_request_t tx_request;
-
- phy_procedures_gNB_common_RX(gNB, &gNB_proc);
+ scheduled_response.module_id = 0;
+ scheduled_response.CC_id = 0;
+ scheduled_response.frame = frame;
+ scheduled_response.slot = slot;
+ scheduled_response.dl_config = NULL;
+ scheduled_response.ul_config = &ul_config;
+ scheduled_response.dl_config = NULL;
- phy_procedures_gNB_uespec_RX(gNB, &gNB_proc, rel15_ul->ulsch_pdu_rel15.start_symbol, rel15_ul->ulsch_pdu_rel15.start_symbol + rel15_ul->ulsch_pdu_rel15.number_symbols);
+ ul_config.sfn_slot = slot;
+ ul_config.number_pdus = 1;
+ ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+ ul_config.ul_config_list[0].ulsch_config_pdu.rnti = n_rnti;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_rbs = nb_rb;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_rb = start_rb;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.number_symbols = nb_symb_sch;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.start_symbol = start_symbol;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.mcs = Imcs;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.ndi = 0;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.rv = 0;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.n_layers = precod_nbr_layers;
+ ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid;
+ //there are plenty of other parameters that we don't seem to be using for now. e.g.
+ //ul_config.ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.absolute_delta_PUSCH = 0;
+ // set FAPI parameters for UE, put them in the scheduled response and call
+ nr_ue_scheduled_response(&scheduled_response);
- //----------------------------------------------------------
- //---------------------- count errors ----------------------
- //----------------------------------------------------------
+ /////////////////////////phy_procedures_nr_ue_TX///////////////////////
+ ///////////
- for (i = 0; i < available_bits; i++) {
-
- if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
- ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
- {
- if(errors_scrambling == 0) {
- printf("\n");
- printf("First bit in error in unscrambling = %d\n",i);
+ phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0);
+
+ ///////////
+ ////////////////////////////////////////////////////
+ tx_offset = slot*frame_parms->samples_per_slot;
+
+ txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
+ frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
+
+ txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation
+
+ n_errors = 0;
+ n_false_positive = 0;
+
+ //AWGN
+ sigma_dB = 10*log10(txlev_float)-SNR;
+ sigma = pow(10,sigma_dB/10);
+
+ for (trial = 0; trial < n_trials; trial++) {
+
+ errors_scrambling = 0;
+ errors_decoding = 0;
+
+ //----------------------------------------------------------
+ //------------------------ add noise -----------------------
+ //----------------------------------------------------------
+ for (i=0; inb_antennas_rx; ap++) {
+ ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point
+ ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP);
+ }
+ }
+ ////////////////////////////////////////////////////////////
+
+ //----------------------------------------------------------
+ //------------------- gNB phy procedures -------------------
+ //----------------------------------------------------------
+ phy_procedures_gNB_common_RX(gNB, frame, slot);
+
+ phy_procedures_gNB_uespec_RX(gNB, frame, slot, rel15_ul->ulsch_pdu_rel15.start_symbol, rel15_ul->ulsch_pdu_rel15.start_symbol + rel15_ul->ulsch_pdu_rel15.number_symbols);
+ ////////////////////////////////////////////////////////////
+
+ //----------------------------------------------------------
+ //----------------- count and print errors -----------------
+ //----------------------------------------------------------
+
+ for (i = 0; i < available_bits; i++) {
+
+ if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
+ ((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
+ {
+ if(errors_scrambling == 0)
+ printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);
+ errors_scrambling++;
}
- errors_scrambling++;
}
- }
-
- for (i = 0; i < TBS; i++) {
-
- estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
- test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
-
- if (estimated_output_bit[i] != test_input_bit[i]) {
- if(errors_bit == 0)
- printf("First bit in error in decoding = %d\n",i);
- errors_bit++;
+ if (errors_scrambling > 0) {
+ printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %d\n" "\x1B[0m", frame, trial, errors_scrambling);
}
-
- }
- ////////////////////////////////////////////////////////////
+ for (i = 0; i < TBS; i++) {
- if (errors_scrambling > 0) {
- if (n_trials == 1)
- printf("errors_scrambling = %d (trial %d)\n", errors_scrambling, trial);
- }
+ estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7);
+ test_input_bit[i] = (ulsch_ue[0]->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7);
- if (errors_bit > 0) {
- n_false_positive++;
- if (n_trials == 1)
- printf("errors_bit = %u (trial %d)\n", errors_bit, trial);
- }
- printf("\n");
- } // [hna] for (trial = 0; trial < n_trials; trial++)
-
- printf("*****************************************\n");
- printf("SNR %f, (false positive %f)\n", SNR,
- (float) n_false_positive / (float) n_trials);
- printf("*****************************************\n");
- printf("\n");
+ if (estimated_output_bit[i] != test_input_bit[i]) {
+ if(errors_decoding == 0)
+ printf("\x1B[34m""[frame %d][trial %d]\t1st bit in error in decoding = %d\n" "\x1B[0m", frame, trial, i);
+ errors_decoding++;
+ }
+ }
- if (errors_bit == 0) {
- printf("PUSCH test OK\n");
- printf("\n");
+ if (errors_decoding > 0) {
+ is_frame_in_error = 1;
+ n_false_positive++;
+ printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in decoding = %d\n" "\x1B[0m", frame, trial, errors_decoding);
+ } else {
+ is_frame_in_error = 0;
+ break;
+ }
+ ////////////////////////////////////////////////////////////
+ } // trial loop
+
+ if (is_frame_in_error == 1)
+ break;
+ } // frame loop
+
+ if(is_frame_in_error == 0)
break;
- }
- printf("\n");
- } // [hna] for (SNR = snr0; SNR < snr1; SNR += snr_step)
+ } // SNR loop
+ if(is_frame_in_error == 0) {
+ printf("\n");
+ printf("*************\n");
+ printf("PUSCH test OK\n");
+ printf("*************\n");
+ }
+
+ printf("\n");
for (i = 0; i < 2; i++) {
@@ -585,6 +622,9 @@ int main(int argc, char **argv)
printf("\n");
}
+ free(test_input_bit);
+ free(estimated_output_bit);
+
if (output_fd)
fclose(output_fd);
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
index fa243d1eb0..a93f0d48f3 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
@@ -119,7 +119,7 @@ void dl_phy_sync_success(module_id_t module_idP,
frame_t frameP,
unsigned char eNB_index, uint8_t first_sync){}
-uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn) { return(0);}
+uint64_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn) { return(0);}
int32_t get_uldl_offset(int nr_bandP) { return(0);}
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 710b77a41c..0392e5babf 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -805,11 +805,10 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}
NRRRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= N_RB_DL;
- if(N_RB_DL == 217) sf_ahead = 2;
- else if(N_RB_DL == 106) sf_ahead = 4;
- else sf_ahead = 4;
- /*else AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for N_RB_DL choice: 106, 217 !\n",
- RC.config_file_name, i, N_RB_DL);*/
+ //if(N_RB_DL == 217) sf_ahead = 2;
+ //else if(N_RB_DL == 106) sf_ahead = 4;
+ if ((N_RB_DL != 217) && (N_RB_DL != 106))
+ AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for N_RB_DL choice: 106, 217 !\n", RC.config_file_name, i, N_RB_DL);
/*
if ((N_RB_DL!=6) && (N_RB_DL!=15) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=75) && (N_RB_DL!=100)) {
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 80503cb93e..98389ddcfd 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -134,5 +134,7 @@ void nr_ue_process_mac_pdu(
int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len);
+void nr_ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframeP, uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index);
+
#endif
/** @}*/
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index 3688514745..c96acccf9b 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -32,6 +32,7 @@
//#include "defs.h"
#include "mac_proto.h"
+#include "executables/nr-softmodem.h"
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
@@ -45,6 +46,14 @@ nr_l2_init_ue(void)
//init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)malloc(sizeof(NR_UE_MAC_INST_t)*NB_NR_UE_MAC_INST);
+ if (IS_SOFTMODEM_NOS1){
+ if (rlc_module_init() != 0) {
+ LOG_I(RLC, "Problem at RLC initiation \n");
+ }
+ pdcp_layer_init();
+ nr_ip_over_LTE_DRB_preconfiguration();
+ }
+
return (1);
}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index ec212078dd..6b9e79d510 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -36,10 +36,27 @@
#include "assertions.h"
#include "PHY/defs_nr_UE.h"
#include "common/utils/LOG/log.h"
+#include "openair2/LAYER2/MAC/mac.h"
#include
#include
+//#define ENABLE_MAC_PAYLOAD_DEBUG 1
+
+extern void mac_rlc_data_ind (
+ const module_id_t module_idP,
+ const rnti_t rntiP,
+ const eNB_index_t eNB_index,
+ const frame_t frameP,
+ const eNB_flag_t enb_flagP,
+ const MBMS_flag_t MBMS_flagP,
+ const logical_chan_id_t channel_idP,
+ char *buffer_pP,
+ const tb_size_t tb_sizeP,
+ num_tb_t num_tbP,
+ crc_t *crcs_pP);
+
+
uint32_t get_ssb_slot(uint32_t ssb_index){
// this function now only support f <= 3GHz
return ssb_index & 0x3 ;
@@ -81,7 +98,9 @@ int8_t nr_ue_process_dlsch(module_id_t module_id,
// First we need to verify if DCI ind contains a ul-sch to be perfomred. If it does, we will handle a PUSCH in the UL_CONFIG_REQ.
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUCCH;
for (int i=0; i<10; i++) {
- if (dci_ind->dci_list[i].dci_format < 2) ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+ if(dci_ind!=NULL){
+ if (dci_ind->dci_list[i].dci_format < 2) ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+ }
}
if (ul_config->ul_config_list[ul_config->number_pdus].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) {
// fill in the elements in config request inside P5 message
@@ -207,7 +226,7 @@ int8_t nr_ue_decode_mib(
uint32_t ssb_length,
uint32_t ssb_index,
void *pduP,
- uint16_t cell_id ){
+ uint16_t cell_id ){
LOG_I(MAC,"[L2][MAC] decode mib\n");
@@ -264,7 +283,7 @@ int8_t nr_ue_decode_mib(
scs_pdcch = scs_30kHz;
}
- channel_bandwidth_t min_channel_bw = bw_40MHz; // deafult for testing
+ channel_bandwidth_t min_channel_bw = bw_10MHz; // deafult for testing
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
frequency_range_t frequency_range = FR1;
@@ -2182,3 +2201,213 @@ void nr_ue_process_mac_pdu(
AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n");
}
}
+
+//---------------------------------------------------------------------------------
+
+
+unsigned char *parse_header(unsigned char *mac_header,
+ unsigned char *num_ce,
+ unsigned char *num_sdu,
+ unsigned char *rx_ces,
+ unsigned char *rx_lcids,
+ unsigned short *rx_lengths,
+ unsigned short tb_length)
+{
+
+ unsigned char not_done = 1, num_ces = 0, num_cont_res =
+ 0, num_padding = 0, num_sdus = 0, lcid, num_sdu_cnt;
+ unsigned char *mac_header_ptr = mac_header;
+ unsigned short length, ce_len = 0;
+
+ while (not_done == 1) {
+
+ if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) {
+ // printf("E=0\n");
+ not_done = 0;
+ }
+
+ lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID;
+
+ if (lcid < UE_CONT_RES) {
+ //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]);
+ if (not_done == 0) { // last MAC SDU, length is implicit
+ mac_header_ptr++;
+ length =
+ tb_length - (mac_header_ptr - mac_header) - ce_len;
+
+ for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus;
+ num_sdu_cnt++) {
+ length -= rx_lengths[num_sdu_cnt];
+ }
+ } else {
+ if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) {
+ length =
+ ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->
+ L_MSB & 0x7f)
+ << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)->
+ L_LSB & 0xff);
+ mac_header_ptr += 3;
+#ifdef DEBUG_HEADER_PARSING
+ LOG_D(MAC, "[UE] parse long sdu, size %x \n", length);
+#endif
+
+ } else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
+ length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L;
+ mac_header_ptr += 2;
+ }
+ }
+
+#ifdef DEBUG_HEADER_PARSING
+ LOG_D(MAC, "[UE] sdu %d lcid %d length %d (offset now %ld)\n",
+ num_sdus, lcid, length, mac_header_ptr - mac_header);
+#endif
+ rx_lcids[num_sdus] = lcid;
+ rx_lengths[num_sdus] = length;
+ num_sdus++;
+ } else { // This is a control element subheader
+ if (lcid == SHORT_PADDING) {
+ num_padding++;
+ mac_header_ptr++;
+ } else {
+ rx_ces[num_ces] = lcid;
+ num_ces++;
+ mac_header_ptr++;
+
+ if (lcid == TIMING_ADV_CMD) {
+ ce_len++;
+ } else if (lcid == UE_CONT_RES) {
+
+ // FNA: check MAC Header is one of thoses defined in Annex B of 36.321
+ // Check there is only 1 Contention Resolution
+ if (num_cont_res) {
+ LOG_W(MAC,
+ "[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n");
+ // exit parsing
+ return NULL;
+
+ }
+ // UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader
+ if ((not_done == 0)
+ && ((num_sdus) || (num_ces > 1) || (num_padding))) {
+ LOG_W(MAC,
+ "[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n",
+ num_ces, num_sdus, num_padding);
+ // exit parsing
+ return NULL;
+ }
+ num_cont_res++;
+ ce_len += 6;
+ }
+ }
+
+#ifdef DEBUG_HEADER_PARSING
+ LOG_D(MAC, "[UE] ce %d lcid %d (offset now %ld)\n", num_ces,
+ lcid, mac_header_ptr - mac_header);
+#endif
+ }
+ }
+
+ *num_ce = num_ces;
+ *num_sdu = num_sdus;
+
+ return (mac_header_ptr);
+}
+
+
+//------------------------------------------------------------------------------
+void
+nr_ue_send_sdu(module_id_t module_idP,
+ uint8_t CC_id,
+ frame_t frameP,
+ sub_frame_t subframeP,
+ uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index)
+//------------------------------------------------------------------------------
+{
+
+ unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr;
+ unsigned char rx_lcids[NB_RB_MAX];
+ unsigned short rx_lengths[NB_RB_MAX];
+
+
+ //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]);
+
+
+ payload_ptr =
+ parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths,
+ sdu_len);
+
+#ifdef DEBUG_HEADER_PARSING
+ LOG_D(MAC,
+ "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",
+ module_idP, frameP, eNB_index, num_ce, num_sdu);
+#endif
+
+#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+ LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
+
+ for (i = 0; i < 32; i++) {
+ LOG_T(MAC, "%x.", sdu[i]);
+ }
+
+ LOG_T(MAC, "\n");
+#endif
+
+ if (payload_ptr != NULL) {
+
+ for (i = 0; i < num_ce; i++) {
+ // printf("ce %d : %d\n",i,rx_ces[i]);
+ switch (rx_ces[i]) {
+ case UE_CONT_RES:
+
+ break;
+
+ case TIMING_ADV_CMD:
+
+ break;
+
+ case DRX_CMD:
+
+ break;
+ }
+ }
+
+ for (i = 0; i < num_sdu; i++) {
+#ifdef DEBUG_HEADER_PARSING
+ LOG_I(MAC, "[UE] SDU %d : LCID %d, length %d\n", i,
+ rx_lcids[i], rx_lengths[i]);
+#endif
+ if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1)) {
+
+ LOG_D(MAC,
+ "[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n",
+ module_idP, frameP, rx_lcids[i], eNB_index,
+ rx_lengths[i]);
+
+#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+ LOG_I(MAC, "Printing MAC PDU contents at slot: %d \n", subframeP);
+ int j;
+ for (j = 0; j < 20; j++) //rx_lengths[i]
+ LOG_I(MAC, "%x.", (unsigned char) payload_ptr[j]);
+ LOG_I(MAC, "\n");
+#endif
+ mac_rlc_data_ind(module_idP,
+ 4660, //UE_mac_inst[module_idP].crnti //hardcode value corresponding to the one from the eNB
+ eNB_index,
+ frameP,
+ ENB_FLAG_NO,
+ MBMS_FLAG_NO,
+ rx_lcids[i],
+ (char *) payload_ptr, rx_lengths[i], 1,
+ NULL);
+ } else {
+ LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (eNB %d)\n",
+ module_idP, frameP, rx_lcids[i], eNB_index);
+ }
+ payload_ptr += rx_lengths[i];
+ }
+ } // end if (payload_ptr != NULL)
+
+}
+
+
+
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 02c27930d3..ebd6f99555 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -70,9 +70,9 @@ extern uint8_t nfapi_mode;
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
-void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
+void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
int CC_idP,
- frame_t frameP,
+ frame_t frameP,
sub_frame_t slotP){
nfapi_nr_dl_config_request_t *DL_req = &gNB->DL_req[0];
@@ -102,10 +102,10 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
}
}
/*
-void check_nr_ul_failure(module_id_t module_idP,
- int CC_id,
+void check_nr_ul_failure(module_id_t module_idP,
+ int CC_id,
int UE_id,
- frame_t frameP,
+ frame_t frameP,
sub_frame_t slotP) {
UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list;
@@ -191,13 +191,13 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
uint8_t TSFC;
uint16_t deltaTSFC; // bitmap
uint8_t srs_SubframeConfig;
-
+
// table for TSFC (Period) and deltaSFC (offset)
const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD
const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
-
+
uint16_t srsPeriodicity, srsOffset;
-
+
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
// check if SRS is enabled in this frame/subframe
@@ -212,7 +212,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
}
// Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
uint16_t tmp = (subframeP % TSFC);
-
+
if ((1 << tmp) & deltaTSFC) {
// This is an SRS subframe, loop over UEs
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
@@ -220,11 +220,11 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
-
+
AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
"physicalConfigDedicated is null for UE %d\n",
UE_id);
-
+
if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
get_srs_pos(&cc[CC_id],
@@ -256,7 +256,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
} // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
} // for (UE_id ...
} // if((1<common_channels;
+ //nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = NULL;
start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
@@ -331,13 +332,14 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
coreset,
frameP,
slotP,
- *cfg))
- nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP);
+ *cfg)){
+ nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP, NULL);
+ }
rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i);
//int spf = get_spf(cfg);
-
+
if (((frameP&127) == 0) && (slotP == 0)) {
LOG_I(MAC,
"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n",
@@ -349,32 +351,32 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
(UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 128) / 2,
(UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 128) / 2);
}
-
+
RC.gNB[module_idP][CC_id]->pusch_stats_bsr[i][to_absslot(cfg,frameP,slotP)] = -63;
-
+
if (i == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.gNB[module_idP][CC_id]->
pusch_stats_bsr[i][to_absslot(cfg,frameP,slotP)]);
-
+
// increment this, it is cleared when we receive an sdu
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
-
- LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n",
- i,
+
+ LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n",
+ i,
rnti,
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer,
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
-
+
//check_nr_ul_failure(module_idP, CC_id, i, frameP, subframeP);
-
+
if (RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) {
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++;
-
+
if(RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >=
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) {
RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0;
-
+
for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_GNB; ue_id_l++) {
if (reestablish_rnti_map[ue_id_l][0] == rnti) {
// clear currentC-RNTI from map
@@ -383,10 +385,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
break;
}
}
-
+
// Note: This should not be done in the MAC!
for (int ii=0; iiulsch[ii][0];
+ NR_gNB_ULSCH_t *ulsch = RC.gNB[module_idP][CC_id]->ulsch[ii][0];
if((ulsch != NULL) && (ulsch->rnti == rnti)){
LOG_W(MAC, "TODO: clean_eNb_ulsch UE %x \n", rnti);
clean_gNB_ulsch(ulsch);
@@ -400,7 +402,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
clean_gNB_dlsch(dlsch);
}
}
-
+
for(int j = 0; j < 10; j++){
nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
ul_req_tmp = &RC.nrmac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body;
@@ -422,9 +424,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
} //END if (RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0)
} //END if (UE_list->active[i])
} //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++)
-
+
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,NOT_A_RNTI, frameP, slotP,module_idP);
-
+
pdcp_run(&ctxt);
//rrc_rx_tx(&ctxt, CC_id);
@@ -439,8 +441,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
/*if (slotP==2)
nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/
- if (slotP==1)
- nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP);
+ if (slotP==1){
+ nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP, NULL);
+ }
/*
// Allocate CCEs for good after scheduling is done
@@ -449,6 +452,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
*/
-
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index b825b528ac..81c05d7dcf 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -33,7 +33,9 @@
#include "mac_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
+#include "executables/nr-softmodem.h"
extern RAN_CONTEXT_t RC;
+//#define ENABLE_MAC_PAYLOAD_DEBUG 1
/*Scheduling of DLSCH with associated DCI in common search space
* current version has only a DCI for type 1 PDCCH for C_RNTI*/
@@ -103,7 +105,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
pdu_rel15->vrb_to_prb_mapping = 1;
pdu_rel15->mcs = 9;
pdu_rel15->tb_scaling = 1;
-
+
pdu_rel15->ra_preamble_index = 25;
pdu_rel15->format_indicator = 1;
pdu_rel15->ndi = 1;
@@ -143,7 +145,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
params_rel15->nb_slots,
params_rel15->sfn_mod2,
params_rel15->first_slot);
- nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+ nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n",
dlsch_pdu_rel15->start_prb,
dlsch_pdu_rel15->n_prb,
@@ -168,147 +170,356 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
-
}
}
-/*Scheduling of DLSCH with associated DCI in user specific search space
- * current version has only a DCI for type 1 PDCCH for C_RNTI*/
+int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req,
+ nfapi_tx_request_pdu_t *TX_req,
+ nfapi_nr_config_request_t *cfg,
+ nfapi_nr_coreset_t* coreset,
+ nfapi_nr_search_space_t* search_space,
+ int16_t pdu_index,
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config){
+
+ nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu;
+ nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu;
+ int TBS;
+ uint16_t rnti = 0x1234;
+ int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
+
+
+ dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+ memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
+ dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
+ dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu));
+
+ dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1];
+ memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
+ dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE;
+ dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu));
+
+ nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15;
+ nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15;
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15;
+
+ dlsch_pdu_rel15->start_prb = 0;
+ dlsch_pdu_rel15->n_prb = 50;
+ dlsch_pdu_rel15->start_symbol = 2;
+ dlsch_pdu_rel15->nb_symbols = 9;
+ dlsch_pdu_rel15->rnti = rnti;
+ dlsch_pdu_rel15->nb_layers =1;
+ dlsch_pdu_rel15->nb_codewords = 1;
+ dlsch_pdu_rel15->mcs_idx = 9;
+ dlsch_pdu_rel15->ndi = 1;
+ dlsch_pdu_rel15->redundancy_version = 0;
+
+ if (dlsch_config != NULL) {
+ dlsch_pdu_rel15->start_prb = dlsch_config->start_prb;
+ dlsch_pdu_rel15->n_prb = dlsch_config->n_prb;
+ dlsch_pdu_rel15->start_symbol = dlsch_config->start_symbol;
+ dlsch_pdu_rel15->nb_symbols = dlsch_config->nb_symbols;
+ dlsch_pdu_rel15->mcs_idx = dlsch_config->mcs_idx;
+ }
+
+ nr_configure_dci_from_pdcch_config(params_rel15,
+ coreset,
+ search_space,
+ *cfg,
+ dl_carrier_bandwidth);
+
+ pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value);
+ pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV;
+ pdu_rel15->vrb_to_prb_mapping = 1;
+ pdu_rel15->mcs = dlsch_pdu_rel15->mcs_idx;
+ pdu_rel15->tb_scaling = 1;
+
+ pdu_rel15->ra_preamble_index = 25;
+ pdu_rel15->format_indicator = 1;
+ pdu_rel15->ndi = 1;
+ pdu_rel15->rv = 0;
+ pdu_rel15->harq_pid = 0;
+ pdu_rel15->dai = 2;
+ pdu_rel15->tpc = 2;
+ pdu_rel15->pucch_resource_indicator = 7;
+ pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7;
+
+ LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
+ pdu_rel15->frequency_domain_assignment,
+ pdu_rel15->time_domain_assignment,
+ pdu_rel15->vrb_to_prb_mapping,
+ pdu_rel15->mcs,
+ pdu_rel15->tb_scaling,
+ pdu_rel15->ndi,
+ pdu_rel15->rv);
+
+ params_rel15->rnti = rnti;
+ params_rel15->rnti_type = NFAPI_NR_RNTI_C;
+ params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0;
+
+ //params_rel15->aggregation_level = 1;
+ LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \
+ coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \
+ ss params : first symb %d, ss type %d\n",
+ params_rel15->rnti,
+ params_rel15->rnti_type,
+ params_rel15->config_type,
+ params_rel15->dci_format,
+ params_rel15->mux_pattern,
+ params_rel15->n_rb,
+ params_rel15->n_symb,
+ params_rel15->rb_offset,
+ params_rel15->first_symbol,
+ params_rel15->search_space_type);
+ nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+ // Hardcode it for now
+ TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size;
+ LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n",
+ dlsch_pdu_rel15->start_prb,
+ dlsch_pdu_rel15->n_prb,
+ dlsch_pdu_rel15->start_symbol,
+ dlsch_pdu_rel15->nb_symbols,
+ dlsch_pdu_rel15->nb_layers,
+ dlsch_pdu_rel15->nb_codewords,
+ dlsch_pdu_rel15->mcs_idx,
+ TBS);
+
+ dl_req->number_dci++;
+ dl_req->number_pdsch_rnti++;
+ dl_req->number_pdu+=2;
+
+ TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size/8;
+ TX_req->pdu_index = pdu_index++;
+ TX_req->num_segments = 1;
+
+ return TBS/8; //Return TBS in bytes
+}
+
+
+
+
+
+
+
void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
- sub_frame_t slotP)
+ sub_frame_t slotP,
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config)
{
+ LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest \n");
uint8_t CC_id;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
//NR_COMMON_channels_t *cc = nr_mac->common_channels;
nfapi_nr_dl_config_request_body_t *dl_req;
- nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu;
- nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu;
nfapi_tx_request_pdu_t *TX_req;
-
- nfapi_nr_config_request_t *cfg = &nr_mac->config[0];
uint16_t rnti = 0x1234;
+ nfapi_nr_config_request_t *cfg = &nr_mac->config[0];
+
uint16_t sfn_sf = frameP << 7 | slotP;
- int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
// everything here is hard-coded to 30 kHz
//int scs = get_dlscs(cfg);
//int slots_per_frame = get_spf(cfg);
+
+ int TBS;
+ int TBS_bytes;
+ int lcid;
+ int ta_len = 0;
+ int header_length_total=0;
+ int header_length_last;
+ int sdu_length_total = 0;
+ mac_rlc_status_resp_t rlc_status;
+ uint16_t sdu_lengths[NB_RB_MAX];
+ int num_sdus = 0;
+ unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
+ int offset;
+ int UE_id = 0;
+ unsigned char sdu_lcids[NB_RB_MAX];
+ int padding = 0, post_padding = 0;
+ UE_list_t *UE_list = &nr_mac->UE_list;
+
+ DLSCH_PDU DLSCH_pdu;
+ //DLSCH_PDU *DLSCH_pdu = (DLSCH_PDU*) malloc(sizeof(DLSCH_PDU));
+
+
for (CC_id=0; CC_idcoreset[CC_id][1];
- nfapi_nr_search_space_t* search_space = &nr_mac->search_space[CC_id][1];
+ LOG_D(MAC, "Scheduling UE specific search space DCI type 1 for CC_id %d\n",CC_id);
- dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body;
- dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
- memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
- dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
- dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu));
+ dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body;
+ TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus];
- dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1];
- memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
- dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE;
- dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu));
+ //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving
+ //through the LTE stack
+ if (IS_SOFTMODEM_NOS1){
- nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15;
- nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15;
- nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15;
+ memset(&DLSCH_pdu, 0, sizeof(DLSCH_pdu));
+ int ta_update = 31;
+ ta_len = 0;
- dlsch_pdu_rel15->start_prb = 0;
- dlsch_pdu_rel15->n_prb = 50;
- dlsch_pdu_rel15->start_symbol = 2;
- dlsch_pdu_rel15->nb_symbols = 9;
- dlsch_pdu_rel15->rnti = rnti;
- dlsch_pdu_rel15->nb_layers =1;
- dlsch_pdu_rel15->nb_codewords = 1;
- dlsch_pdu_rel15->mcs_idx = 9;
- dlsch_pdu_rel15->ndi = 1;
- dlsch_pdu_rel15->redundancy_version = 0;
+ // Hardcode it for now
+ TBS = 6784/8; //TBS in bytes
+ //nr_get_tbs_dl(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
+ //TBS = dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15.transport_block_size;
- nr_configure_dci_from_pdcch_config(params_rel15,
- coreset,
- search_space,
- *cfg,
- dl_carrier_bandwidth);
+ for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
+ // TODO: check if the lcid is active
- pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value);
- pdu_rel15->time_domain_assignment = 3; // row index used here instead of SLIV;
- pdu_rel15->vrb_to_prb_mapping = 1;
- pdu_rel15->mcs = 9;
- pdu_rel15->tb_scaling = 1;
+ LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
+ module_idP, frameP, lcid, TBS,
+ TBS - ta_len - header_length_total - sdu_length_total - 3);
- pdu_rel15->ra_preamble_index = 25;
- pdu_rel15->format_indicator = 1;
- pdu_rel15->ndi = 1;
- pdu_rel15->rv = 0;
- pdu_rel15->harq_pid = 0;
- pdu_rel15->dai = 2;
- pdu_rel15->tpc = 2;
- pdu_rel15->pucch_resource_indicator = 7;
- pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7;
+ if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
+ rlc_status = mac_rlc_status_ind(module_idP,
+ rnti,
+ module_idP,
+ frameP,
+ slotP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ lcid,
+ TBS - ta_len - header_length_total - sdu_length_total - 3
+ //#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,0, 0
+ //#endif
+ );
- LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
- pdu_rel15->frequency_domain_assignment,
- pdu_rel15->time_domain_assignment,
- pdu_rel15->vrb_to_prb_mapping,
- pdu_rel15->mcs,
- pdu_rel15->tb_scaling,
- pdu_rel15->ndi,
- pdu_rel15->rv);
+ if (rlc_status.bytes_in_buffer > 0) {
+ LOG_D(MAC,
+ "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n",
+ module_idP, frameP,
+ TBS - ta_len - header_length_total - sdu_length_total - 3,
+ lcid,
+ header_length_total,
+ TBS);
- params_rel15->rnti = rnti;
- params_rel15->rnti_type = NFAPI_NR_RNTI_C;
- params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0;
+ sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid,
+ TBS,
+ (char *)&dlsch_buffer[sdu_length_total]
+ //#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,0, 0
+ //#endif
+ );
- //params_rel15->aggregation_level = 1;
- LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d, config type %d\n \
- coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \
- ss params : first symb %d, ss type %d\n",
- params_rel15->rnti,
- params_rel15->rnti_type,
- params_rel15->config_type,
- params_rel15->dci_format,
- params_rel15->mux_pattern,
- params_rel15->n_rb,
- params_rel15->n_symb,
- params_rel15->rb_offset,
- params_rel15->first_symbol,
- params_rel15->search_space_type);
- nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
- LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n",
- dlsch_pdu_rel15->start_prb,
- dlsch_pdu_rel15->n_prb,
- dlsch_pdu_rel15->start_symbol,
- dlsch_pdu_rel15->nb_symbols,
- dlsch_pdu_rel15->nb_layers,
- dlsch_pdu_rel15->nb_codewords,
- dlsch_pdu_rel15->mcs_idx);
- dl_req->number_dci++;
- dl_req->number_pdsch_rnti++;
- dl_req->number_pdu+=2;
- TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus];
- TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size;
- TX_req->pdu_index = nr_mac->pdu_index[CC_id]++;
- TX_req->num_segments = 1;
+ LOG_D(MAC,
+ "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
+ module_idP, sdu_lengths[num_sdus], lcid);
- // HOT FIX for all zero pdu problem
- // ------------------------------------------------------------------------------------------------
- for(int i = 0; i < dlsch_pdu_rel15->transport_block_size/8; i++) {
- ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand();
- }
- // ------------------------------------------------------------------------------------------------
+ sdu_lcids[num_sdus] = lcid;
+ sdu_length_total += sdu_lengths[num_sdus];
+ UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++;
+ UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid;
+ UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus];
+ UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
- TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0];
- TX_req->segments[0].segment_length = dlsch_pdu_rel15->transport_block_size+2;
- nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
- nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;
- nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
- nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+ header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
+ header_length_total += header_length_last;
- }
+ num_sdus++;
+
+ UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+ }
+ } else {
+ // no TBS left
+ break;
+ }
+ }
+
+ // last header does not have length field
+ if (header_length_total) {
+ header_length_total -= header_length_last;
+ header_length_total++;
+ }
+
+
+ if (ta_len + sdu_length_total + header_length_total > 0) {
+
+
+ if (TBS - header_length_total - sdu_length_total - ta_len <= 2) {
+ padding = TBS - header_length_total - sdu_length_total - ta_len;
+ post_padding = 0;
+ } else {
+ padding = 0;
+ post_padding = 1;
+ }
+
+ offset = generate_dlsch_header((unsigned char *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0], //DLSCH_pdu.payload[0],
+ num_sdus, //num_sdus
+ sdu_lengths, //
+ sdu_lcids, 255, // no drx
+ ta_update, // timing advance
+ NULL, // contention res id
+ padding, post_padding);
+ LOG_D(MAC, "Offset bits: %d \n", offset);
+
+ // Probably there should be other actions done before that
+ // cycle through SDUs and place in dlsch_buffer
+
+ //memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total);
+ memcpy(&nr_mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total);
+
+
+ // fill remainder of DLSCH with 0
+ for (int j = 0; j < (TBS - sdu_length_total - offset); j++) {
+ //UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0;
+ nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0][offset + sdu_length_total + j] = 0;
+ }
+
+ TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config);
+
+ #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, , TBS size: %d \n \n", frameP, slotP, TBS_bytes);
+ for(int i = 0; i < 10; i++) { // TBS_bytes dlsch_pdu_rel15->transport_block_size/8 6784/8
+ LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
+ }
+ #endif
+
+ //TX_req->segments[0].segment_length = 8;
+ TX_req->segments[0].segment_length = TBS_bytes +2;
+ TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0];
+
+
+ nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
+ nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;
+ nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+ nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+ } //if (ta_len + sdu_length_total + header_length_total > 0)
+ } //if (IS_SOFTMODEM_NOS1)
+
+ //When the --NOS1 option is not enabled, DLSCH transmissions with random data
+ //occur every time that the current function is called (dlsch phytest mode)
+ else{
+ TBS_bytes = configure_fapi_dl_Tx(dl_req, TX_req, cfg, &nr_mac->coreset[CC_id][1], &nr_mac->search_space[CC_id][1], nr_mac->pdu_index[CC_id], dlsch_config);
+ // HOT FIX for all zero pdu problem
+ // ------------------------------------------------------------------------------------------------
+
+ for(int i = 0; i < TBS_bytes; i++) { //
+ ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i] = (unsigned char) rand();
+ //LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
+ }
+ #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+ if (frameP%100 == 0){
+ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes);
+ for(int i = 0; i < 10; i++) {
+ LOG_I(MAC, "%x. ", ((uint8_t *)nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]);
+ }
+ }
+ #endif
+
+ //TX_req->segments[0].segment_length = 8;
+ TX_req->segments[0].segment_length = TBS_bytes +2;
+ TX_req->segments[0].segment_data = nr_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0];
+
+ nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
+ nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;
+ nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+ nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+ // ------------------------------------------------------------------------------------------------
+ }
+ } //for (CC_id=0; CC_idmonitoring_symbols_in_slot>>(31-i))&1) {
+ int sps = get_symbolsperslot(&cfg);
+
+ for (int i=0; imonitoring_symbols_in_slot>>(sps-1-i))&1) {
pdcch_params->first_symbol=i;
break;
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index a29acee95f..429cfb4b0b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -34,6 +34,8 @@
#include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h"
+void set_cset_offset(uint16_t);
+
void mac_top_init_gNB(void);
void config_common(int Mod_idP,
@@ -72,9 +74,18 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
+int configure_fapi_dl_Tx(nfapi_nr_dl_config_request_body_t *dl_req,
+ nfapi_tx_request_pdu_t *TX_req,
+ nfapi_nr_config_request_t *cfg,
+ nfapi_nr_coreset_t* coreset,
+ nfapi_nr_search_space_t* search_space,
+ int16_t pdu_index,
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config);
+
void nr_schedule_uss_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
- sub_frame_t slotP);
+ sub_frame_t slotP,
+ nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config);
void nr_configure_css_dci_initial(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params,
nr_scs_e scs_common,
@@ -110,7 +121,7 @@ int to_absslot(nfapi_nr_config_request_t *cfg,int frame,int slot);
int get_symbolsperslot(nfapi_nr_config_request_t *cfg);
-void get_band(uint32_t downlink_frequency, uint8_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
+void get_band(uint32_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type);
uint64_t from_nrarfcn(int nr_bandP, uint32_t dl_nrarfcn);
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 8e8a556feb..9b95cd1470 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -40,9 +40,13 @@
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "common/ran_context.h"
+#include "executables/nr-softmodem.h"
extern RAN_CONTEXT_t RC;
+void set_cset_offset(uint16_t offset_bits) {
+ RC.nrmac[0]->coreset[0][1].frequency_domain_resources >>= offset_bits;
+}
void nr_init_coreset(nfapi_nr_coreset_t *coreset) {
@@ -65,7 +69,7 @@ void nr_init_search_space(nfapi_nr_search_space_t *search_space)
search_space->duration = 5;
search_space->slot_monitoring_periodicity = NFAPI_NR_SS_PERIODICITY_SL10;
search_space->slot_monitoring_offset = 1;
- search_space->monitoring_symbols_in_slot = 0xC0000000; // first 2 ofdm symbols
+ search_space->monitoring_symbols_in_slot = 0x3000; // 14 bits field
search_space->css_formats_0_0_and_1_0 = 1;
search_space->uss_dci_formats = 0; // enum to be defined-- formats 0.0 and 1.0
for (int i=0; i 0) {
-
+
RC.nrmac = (gNB_MAC_INST **) malloc16(RC.nb_nr_macrlc_inst *sizeof(gNB_MAC_INST *));
AssertFatal(RC.nrmac != NULL,"can't ALLOCATE %zu Bytes for %d gNB_MAC_INST with size %zu \n",
RC.nb_nr_macrlc_inst * sizeof(gNB_MAC_INST *),
RC.nb_nr_macrlc_inst, sizeof(gNB_MAC_INST));
-
+
for (i = 0; i < RC.nb_nr_macrlc_inst; i++) {
RC.nrmac[i] = (gNB_MAC_INST *) malloc16(sizeof(gNB_MAC_INST));
AssertFatal(RC.nrmac != NULL,"can't ALLOCATE %zu Bytes for %d gNB_MAC_INST with size %zu \n",
RC.nb_nr_macrlc_inst * sizeof(gNB_MAC_INST *),
RC.nb_nr_macrlc_inst, sizeof(gNB_MAC_INST));
-
+
LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d gNB_MAC_INST @ %p\n",sizeof(gNB_MAC_INST), RC.nb_nr_macrlc_inst, RC.mac);
bzero(RC.nrmac[i], sizeof(gNB_MAC_INST));
RC.nrmac[i]->Mod_id = i;
-
+
for (j = 0; j < MAX_NUM_CCs; j++) {
RC.nrmac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list = RC.nrmac[i]->dl_config_pdu_list[j];
RC.nrmac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list = RC.nrmac[i]->ul_config_pdu_list[j];
-
+
for (int k = 0; k < 10; k++)
RC.nrmac[i]->UL_req_tmp[j][k].ul_config_request_body.ul_config_pdu_list =RC.nrmac[i]->ul_config_pdu_list_tmp[j][k];
-
+
RC.nrmac[i]->HI_DCI0_req[j].hi_dci0_request_body.hi_dci0_pdu_list = RC.nrmac[i]->hi_dci0_pdu_list[j];
RC.nrmac[i]->TX_req[j].tx_request_body.tx_pdu_list = RC.nrmac[i]->tx_request_pdu[j];
RC.nrmac[i]->ul_handle = 0;
@@ -118,7 +122,7 @@ void mac_top_init_gNB(void)
nr_init_coreset(&RC.nrmac[i]->coreset[j][1]);
nr_init_search_space(&RC.nrmac[i]->search_space[j][1]);
}
-
+
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
@@ -127,6 +131,9 @@ void mac_top_init_gNB(void)
// These should be out of here later
pdcp_layer_init();
+ if(IS_SOFTMODEM_NOS1)
+ nr_ip_over_LTE_DRB_preconfiguration();
+
rrc_init_nr_global_param();
}else {
@@ -135,7 +142,7 @@ void mac_top_init_gNB(void)
// Initialize Linked-List for Active UEs
for (i = 0; i < RC.nb_nr_macrlc_inst; i++) {
-
+
nrmac = RC.nrmac[i];
nrmac->if_inst = NR_IF_Module_init(i);
@@ -152,6 +159,11 @@ void mac_top_init_gNB(void)
UE_list->next[list_el] = -1;
UE_list->next_ul[list_el] = -1;
+ /*memset(UE_list->DLSCH_pdu, 0, sizeof(UE_list->DLSCH_pdu));
+ memset(UE_list->UE_template, 0, sizeof(UE_list->UE_template));
+ memset(UE_list->eNB_UE_stats, 0, sizeof(UE_list->eNB_UE_stats));
+ memset(UE_list->UE_sched_ctrl, 0, sizeof(UE_list->UE_sched_ctrl));
+ memset(UE_list->active, 0, sizeof(UE_list->active));*/
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c
index 0422331fb4..495cbb1eaa 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.c
@@ -70,35 +70,47 @@ nr_bandentry_t nr_bandtable[] = {
#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
void get_band(uint32_t downlink_frequency,
- uint8_t *current_band,
+ uint16_t *current_band,
int32_t *current_offset,
lte_frame_type_t *current_type)
{
int ind;
- int64_t dl_freq_khz = downlink_frequency/1000;
+ uint64_t center_frequency_khz;
+ uint64_t center_freq_diff_khz;
+ uint64_t dl_freq_khz = downlink_frequency/1000;
+
+ center_freq_diff_khz = 999999999999999999; // 2^64
+ *current_band = 0;
+
for ( ind=0;
ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]);
ind++) {
- *current_band = nr_bandtable[ind].band;
- LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", ind, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min);
+ LOG_I(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min,nr_bandtable[ind].ul_min);
if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) {
- *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000;
- if (*current_offset == 0)
- *current_type = TDD;
- else
- *current_type = FDD;
- LOG_I( PHY, "DL frequency %"PRIu32": band %d, frame_type %d, UL frequency %"PRIu32"\n",
- downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset);
- break;
+ center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min)/2;
+
+ if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
+
+ *current_band = nr_bandtable[ind].band;
+ *current_offset = (nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min)*1000;
+ center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
+
+ if (*current_offset == 0)
+ *current_type = TDD;
+ else
+ *current_type = FDD;
+ }
}
}
- AssertFatal(ind != (sizeof(nr_bandtable) / sizeof(nr_bandtable[0])),
- "Can't find EUTRA band for frequency %d\n", downlink_frequency);
+ LOG_I( PHY, "DL frequency %"PRIu32": band %d, frame_type %d, UL frequency %"PRIu32"\n",
+ downlink_frequency, *current_band, *current_type, downlink_frequency+*current_offset);
+ AssertFatal(*current_band != 0,
+ "Can't find EUTRA band for frequency %u\n", downlink_frequency);
}
uint32_t to_nrarfcn(int nr_bandP,
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index b5a68069cc..d7cbb33c9e 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -358,7 +358,16 @@ boolean_t pdcp_data_req(
LOG_D(PDCP, "pdcp data req on drb %d, size %d, rnti %x, node_type %d \n",
rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc[ctxt_pP->module_id]->node_type);
- if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) {
+ // The check on nos1 is done only for the use case of LTE stack running over 5g-nr PHY. This should be changed
+ // before future merge of develop with develop-nr and instead of a check of IS_SOFTMODEM_NOS1, we should use a check
+ // with a new execution option capturing the nr-ip-over-LTE-stack use case.
+ ngran_node_t node_type;
+ if (IS_SOFTMODEM_NOS1)
+ node_type = ngran_gNB;
+ else
+ node_type = RC.rrc[ctxt_pP->module_id]->node_type;
+
+ if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(node_type)) { //RC.rrc[ctxt_pP->module_id]->node_type
LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type);
ret=FALSE;
} else {
@@ -510,6 +519,7 @@ pdcp_data_ind(
hashtable_rc_t h_rc;
uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0;
uint16_t pdcp_uid=0;
+
MessageDef *message_p = NULL;
uint8_t *gtpu_buffer_p = NULL;
uint32_t rx_hfn_for_count;
@@ -518,6 +528,8 @@ pdcp_data_ind(
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN);
LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP,
"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP);
+
+
#if T_TRACER
if (ctxt_pP->enb_flag != ENB_FLAG_NO)
@@ -1040,6 +1052,13 @@ pdcp_data_ind(
memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)],
&sdu_buffer_pP->data[payload_offset],
sdu_buffer_sizeP - payload_offset);
+
+ #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
+ LOG_I(PDCP, "Printing first bytes of PDCP SDU before adding it to the list: \n");
+ for (int i=0; i<30; i++){
+ LOG_I(PDCP, "%x", sdu_buffer_pP->data[i]);
+ }
+ #endif
list_add_tail_eurecom (new_sdu_p, sdu_list_p);
}
@@ -1062,6 +1081,7 @@ pdcp_data_ind(
Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset);
Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset);
+
Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number;
Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]);
@@ -1772,6 +1792,7 @@ pdcp_config_req_asn1 (
uint8_t *const kUPenc_pP)
//-----------------------------------------------------------------------------
{
+
switch (actionP) {
case CONFIG_ACTION_ADD:
DevAssert(pdcp_pP != NULL);
@@ -2170,6 +2191,9 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
if(UE_NAS_USE_TUN) {
int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1;
netlink_init_tun("ue",num_if);
+ //Add --nr-ip-over-lte option check for next line
+ if (IS_SOFTMODEM_NOS1)
+ nas_config(1, 1, 2, "ue");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("enb",1);
@@ -2217,6 +2241,103 @@ void pdcp_module_cleanup (void)
{
}
+void nr_ip_over_LTE_DRB_preconfiguration(void){
+
+ // Addition for the use-case of 4G stack on top of 5G-NR.
+ // We need to configure pdcp and rlc instances without having an actual
+ // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic
+ // on top of the LTE stack.
+ protocol_ctxt_t ctxt;
+ LTE_DRB_ToAddModList_t* DRB_configList=NULL;
+ DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t));
+ struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL;
+ struct LTE_RLC_Config *DRB_rlc_config = NULL;
+ struct LTE_PDCP_Config *DRB_pdcp_config = NULL;
+ struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL;
+
+ struct LTE_DRB_ToAddMod *DRB_config = NULL;
+ struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL;
+ long *logicalchannelgroup_drb;
+
+
+ //Static preconfiguration of DRB
+ DRB_config = CALLOC(1, sizeof(*DRB_config));
+
+ DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
+ // allowed value 5..15, value : x+4
+ *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation
+ // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
+ // 1 + drb_identiy_index;
+ DRB_config->drb_Identity = 1;
+ DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
+ *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
+
+ DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
+ DRB_config->rlc_Config = DRB_rlc_config;
+
+ DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
+ DRB_config->pdcp_Config = DRB_pdcp_config;
+ DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
+ *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity;
+ DRB_pdcp_config->rlc_AM = NULL;
+ DRB_pdcp_config->rlc_UM = NULL;
+
+ DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional;
+ DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
+ DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10;
+ DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35;
+ // PDCP
+ PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
+ DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
+ PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
+
+ DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed;
+
+ DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
+ DRB_config->logicalChannelConfig = DRB_lchan_config;
+ DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
+ DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
+
+ DRB_ul_SpecificParameters->priority= 4;
+
+ DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
+ //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+ DRB_ul_SpecificParameters->bucketSizeDuration =
+ LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
+
+ logicalchannelgroup_drb = CALLOC(1, sizeof(long));
+ *logicalchannelgroup_drb = 1;//(i+1) % 3;
+ DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
+
+ ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config);
+
+ if (ENB_NAS_USE_TUN){
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0);
+ }
+ else{
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0);
+ }
+
+ rrc_pdcp_config_asn1_req(&ctxt,
+ (LTE_SRB_ToAddModList_t *) NULL,
+ DRB_configList,
+ (LTE_DRB_ToReleaseList_t *) NULL,
+ 0xff, NULL, NULL, NULL
+ //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+ , (LTE_PMCH_InfoList_r9_t *) NULL
+ //#endif
+ ,NULL);
+
+ rrc_rlc_config_asn1_req(&ctxt,
+ (LTE_SRB_ToAddModList_t*)NULL,
+ DRB_configList,
+ (LTE_DRB_ToReleaseList_t*)NULL
+ //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+ ,(LTE_PMCH_InfoList_r9_t *)NULL
+ , 0, 0
+ //#endif
+ );
+}
//-----------------------------------------------------------------------------
void pdcp_layer_init(void)
//-----------------------------------------------------------------------------
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 8d741c1bb5..14507f2589 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -92,6 +92,8 @@ extern int pdcp_instance_cnt;
#define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\
(pDCP_Pp->is_srb) ? "SRB" : "DRB",\
pDCP_Pp->rb_id
+//#define ENABLE_PDCP_PAYLOAD_DEBUG 1
+
int init_pdcp_thread(void);
void cleanup_pdcp_thread(void);
@@ -397,6 +399,7 @@ void pdcp_run (
const protocol_ctxt_t *const ctxt_pP);
uint64_t pdcp_module_init (uint64_t pdcp_optmask);
void pdcp_module_cleanup (void);
+void nr_ip_over_LTE_DRB_preconfiguration (void);
void pdcp_layer_init (void);
void pdcp_layer_cleanup (void);
#define PDCP2NW_DRIVER_FIFO 21
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 3d8c42bc8c..bc3474a369 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -111,7 +111,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
int ret=0;
while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
- ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
+ ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
@@ -135,6 +135,13 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
} // PDCP_USE_NETLINK
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
+
+ #if defined(ENABLE_PDCP_PAYLOAD_DEBUG)
+ LOG_I(PDCP, "Printing first bytes of PDCP SDU before removing it from the list: \n");
+ for (int i=0; i<30; i++){
+ LOG_I(PDCP, "%x", sdu_p->data[i]);
+ }
+ #endif
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu_p, __func__);
pdcp_nb_sdu_sent ++;
@@ -166,7 +173,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
ctxt.enb_flag=ENB_FLAG_YES;
ctxt.module_id=0;
- key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES);
+ key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
}
@@ -276,12 +283,13 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
if (h_rc == HASH_TABLE_OK) {
- LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n",
+ LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d for rnti: %d \n",
ctxt.frame,
pdcp_read_header_g.inst,
len,
nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr),
- pdcp_read_header_g.rb_id);
+ pdcp_read_header_g.rb_id,
+ ctxt.rnti);
MSC_LOG_RX_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
index f37626ae4c..c8faa08358 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
@@ -723,7 +723,6 @@ void rlc_um_check_timer_dar_time_out(
signed int in_window;
rlc_usn_t old_vr_ur;
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_UM_CHECK_TIMER_DAR_TIME_OUT,VCD_FUNCTION_IN);
if ((rlc_pP->t_reordering.running)) {
@@ -1130,12 +1129,12 @@ rlc_um_receive_process_dar (
if (in_window < 0) {
in_window = in_window + rlc_pP->rx_sn_modulo;
}
-
rlc_um_try_reassembly(ctxt_pP, rlc_pP, rlc_pP->vr_ur, in_window);
}
if (rlc_um_in_reordering_window(ctxt_pP, rlc_pP, rlc_pP->vr_ur) < 0) {
+ //LOG_I(RLC, "[rlc_um_receive_process_dar] Problematic case 4 \n");
#if TRACE_RLC_UM_DAR
LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" VR(UR) %d OUTSIDE REORDERING WINDOW SET TO VR(UH) – UM_Window_Size = %d\n",
PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
@@ -1158,9 +1157,8 @@ rlc_um_receive_process_dar (
do {
rlc_pP->vr_ur = (rlc_pP->vr_ur+1) % rlc_pP->rx_sn_modulo;
} while (rlc_um_get_pdu_from_dar_buffer(ctxt_pP, rlc_pP, rlc_pP->vr_ur) && (rlc_pP->vr_ur != rlc_pP->vr_uh));
-
rlc_um_try_reassembly(ctxt_pP, rlc_pP, sn, rlc_pP->vr_ur);
- }
+ }
// -if t-Reordering is running:
// -if VR(UX) <= VR(UR); or
diff --git a/openair2/NETWORK_DRIVER/MESH/classifier.c b/openair2/NETWORK_DRIVER/MESH/classifier.c
index 15ac51158c..32d60917f6 100644
--- a/openair2/NETWORK_DRIVER/MESH/classifier.c
+++ b/openair2/NETWORK_DRIVER/MESH/classifier.c
@@ -597,7 +597,7 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) {
#ifdef NAS_DEBUG_SEND
printk("[NAS][CLASS][SEND] Got packet from kernel:\n");
- for (i=0; i<256; i++)
+ for (int i=0; i<256; i++)
printk("%2x ",((unsigned char *)skb->data)[i]);
printk("\n");
diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c
index 741cc8fa22..493236cb30 100644
--- a/openair2/NETWORK_DRIVER/MESH/common.c
+++ b/openair2/NETWORK_DRIVER/MESH/common.c
@@ -386,6 +386,9 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct class
pdcph.data_size = skb->len;
pdcph.rb_id = (gc->rb)->rab_id;
pdcph.inst = inst;
+ pdcph.sourceL2Id = 0;
+ pdcph.destinationL2Id = 0;
+
#ifdef PDCP_USE_NETLINK
diff --git a/openair2/NETWORK_DRIVER/MESH/netlink.c b/openair2/NETWORK_DRIVER/MESH/netlink.c
index 9ac44453a9..4908e00758 100644
--- a/openair2/NETWORK_DRIVER/MESH/netlink.c
+++ b/openair2/NETWORK_DRIVER/MESH/netlink.c
@@ -161,7 +161,7 @@ int nas_netlink_send(unsigned char *data,unsigned int len)
int status;
- // printk("[NAS][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
+ //printk("[NAS][NETLINK] Sending %d bytes (%d)\n",len,NLMSG_SPACE(len));
skb_put(nl_skb, NLMSG_SPACE(len));
memcpy(NLMSG_DATA(nlh),data,len);
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 8feac5b029..eb7527ff44 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -35,6 +35,7 @@
#include "assertions.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
+#include "executables/nr-softmodem.h"
#include
@@ -70,8 +71,14 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr
}
// L2 Abstraction Layer
-int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len){
+int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len, frame_t frame, int slot){
+ LOG_I(MAC, "handle_dlsch at MAC layer \n");
+ if (IS_SOFTMODEM_NOS1)
+ nr_ue_send_sdu(module_id, 0, frame, slot,
+ pduP,
+ pdu_len,
+ 0);
return 0;
/*
return nr_ue_process_dlsch( module_id,
@@ -209,7 +216,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info){
}
if(dl_info->rx_ind != NULL){
- LOG_I(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND]\n");
+ LOG_I(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
for(i=0; irx_ind->number_pdus; ++i){
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
case FAPI_NR_RX_PDU_TYPE_MIB:
@@ -220,6 +227,14 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info){
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_index,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length,
(dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;
+ LOG_I(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
+ /*ret_mask |= (handle_bcch_bch( dl_info->proc,
+ dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+ dl_info->rx_ind->rx_indication_body[i].mib_pdu.pdu,
+ dl_info->rx_ind->rx_indication_body[i].mib_pdu.additional_bits,
+ dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_index,
+ dl_info->rx_ind->rx_indication_body[i].mib_pdu.ssb_length,
+ dl_info->rx_ind->rx_indication_body[i].mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;*/
break;
case FAPI_NR_RX_PDU_TYPE_SIB:
ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
@@ -231,8 +246,21 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info){
// ret_mask |= (0) << FAPI_NR_RX_PDU_TYPE_DLSCH;
ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
- (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+ (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+ LOG_I(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus);
+
+ /*
+ // dl_config structure just stores what was received - not really needed
+ dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
+ dl_config->number_pdus = dl_config->number_pdus + 1;
+ */
+
+ /*ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
+ dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu,
+ dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+
+ */
break;
default:
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index 3f642cac4b..5873c84d8f 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -52,6 +52,7 @@ typedef struct {
int slot;
fapi_nr_dl_config_request_t dl_config_req;
+ fapi_nr_ul_config_request_t ul_config_req;
} nr_dcireq_t;
typedef struct {
@@ -91,6 +92,8 @@ typedef struct {
uint32_t slot;
/// ssb_index, if ssb is not present in current TTI, thie value set to -1
int ssb_index;
+ /// dci reception indication structure
+ fapi_nr_dci_indication_t *dci_ind;
} nr_uplink_indication_t;
// Downlink subframe P7
diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c
index a2d90abb3e..ab4dbfc119 100644
--- a/openair2/RRC/NAS/nas_config.c
+++ b/openair2/RRC/NAS/nas_config.c
@@ -254,7 +254,7 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
if(!returnValue)
- bringInterfaceUp(interfaceName, 1);
+ returnValue=bringInterfaceUp(interfaceName, 1);
if(!returnValue)
LOG_I(OIP,"Interface %s successfuly configured, ip address %s, mask %s broadcast address %s\n",
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index a608bbcc75..e0e10fd899 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -512,6 +512,7 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
first_packet_state = false;
last_packet_state = true;
}
+
s->tx_md.has_time_spec = true;
s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state;
s->tx_md.end_of_burst = last_packet_state;
@@ -613,7 +614,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
((__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] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[2*j],4);
((__m128i *)buff[i])[2*j+1] = _mm_srai_epi16(((__m128i*)buff_tmp[i])[2*j+1],4);
}
#else
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 4b9ce28225..e4ccd98d54 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -490,10 +490,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
t->nextTimestamp+=nsamps;
-
- if ( ((t->nextTimestamp/nsamps)%100) == 0)
- LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
-
+ LOG_D(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
*ptimestamp = t->nextTimestamp-nsamps;
pthread_mutex_unlock(&Sockmutex);
return nsamps;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf
new file mode 100644
index 0000000000..5610694d7d
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.adrv9371zc706.conf
@@ -0,0 +1,288 @@
+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 = 0;
+ 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 = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.100.8";
+
+ }
+);
+
+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 26f6eddf52..a11bf9d515 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
@@ -31,7 +31,7 @@ gNBs =
UL_prefix_type = "NORMAL";
eutra_band = 78;
downlink_frequency = 3510000000L;
- uplink_frequency_offset = -120000000;
+ uplink_frequency_offset = 0;
Nid_cell = 0;
N_RB_DL = 106;
nb_antenna_ports = 1;
diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c
index 756133a8d6..6bd8835a92 100644
--- a/targets/RT/USER/lte-softmodem-common.c
+++ b/targets/RT/USER/lte-softmodem-common.c
@@ -92,6 +92,7 @@ void get_common_options(void) {
}
if (nokrnmod) {
+ printf("nokrnmod bit enabled \n");
set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT);
}