Merge branch '409-merge-ulschsim-containing-pusch-encoding-and-decoding' into 'develop-nr'
Resolve "Merge ulschsim containing PUSCH encoding and decoding" See merge request oai/openairinterface5g!532
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
cmake_targets/log/
|
cmake_targets/log/
|
||||||
cmake_targets/ran_build/
|
cmake_targets/*/build/
|
||||||
targets/bin/
|
targets/bin/
|
||||||
|
|
||||||
|
|||||||
@@ -252,9 +252,9 @@ case $key in
|
|||||||
VM_NAME=ci-phy-sim
|
VM_NAME=ci-phy-sim
|
||||||
ARCHIVES_LOC=phy_sim
|
ARCHIVES_LOC=phy_sim
|
||||||
LOG_PATTERN=.Rel15.txt
|
LOG_PATTERN=.Rel15.txt
|
||||||
NB_PATTERN_FILES=8
|
NB_PATTERN_FILES=9
|
||||||
BUILD_OPTIONS="--phy_simulators"
|
BUILD_OPTIONS="--phy_simulators"
|
||||||
VM_MEMORY=4096
|
VM_MEMORY=8192
|
||||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||||
NBARGS=$[$NBARGS+256]
|
NBARGS=$[$NBARGS+256]
|
||||||
shift
|
shift
|
||||||
@@ -331,9 +331,9 @@ case $key in
|
|||||||
VM_NAME=ci-phy-sim
|
VM_NAME=ci-phy-sim
|
||||||
ARCHIVES_LOC=phy_sim
|
ARCHIVES_LOC=phy_sim
|
||||||
LOG_PATTERN=.Rel15.txt
|
LOG_PATTERN=.Rel15.txt
|
||||||
NB_PATTERN_FILES=8
|
NB_PATTERN_FILES=9
|
||||||
BUILD_OPTIONS="--phy_simulators"
|
BUILD_OPTIONS="--phy_simulators"
|
||||||
VM_MEMORY=4096
|
VM_MEMORY=8192
|
||||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||||
NBARGS=$[$NBARGS+256]
|
NBARGS=$[$NBARGS+256]
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -671,7 +671,7 @@ add_boolean_option(EXMIMO_IOT True "????")
|
|||||||
add_boolean_option(LOCALIZATION False "???")
|
add_boolean_option(LOCALIZATION False "???")
|
||||||
add_integer_option(MAX_NUM_CCs 1 "????")
|
add_integer_option(MAX_NUM_CCs 1 "????")
|
||||||
add_boolean_option(MU_RECEIVER False "????")
|
add_boolean_option(MU_RECEIVER False "????")
|
||||||
add_boolean_option(PHYSIM True "for L1 simulators (dlsim, ulsim, ...)")
|
add_boolean_option(PHYSIM False "for L1 simulators (dlsim, ulsim, ...)")
|
||||||
add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim")
|
add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim")
|
||||||
add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim")
|
add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim")
|
||||||
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
|
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
|
||||||
@@ -1275,6 +1275,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
|
||||||
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||||
@@ -1304,6 +1305,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
|
||||||
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||||
@@ -2526,6 +2528,12 @@ add_executable(nr_dlsim
|
|||||||
${T_SOURCE})
|
${T_SOURCE})
|
||||||
target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
|
target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
|
||||||
|
|
||||||
|
add_executable(nr_ulschsim
|
||||||
|
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||||
|
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||||
|
${T_SOURCE})
|
||||||
|
target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
|
||||||
|
|
||||||
|
|
||||||
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
|
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
|
||||||
|
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ function main() {
|
|||||||
echo_info "Compiling unitary tests simulators"
|
echo_info "Compiling unitary tests simulators"
|
||||||
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
||||||
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
||||||
simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim"
|
simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim"
|
||||||
for f in $simlist ; do
|
for f in $simlist ; do
|
||||||
compilations \
|
compilations \
|
||||||
phy_simulators $f \
|
phy_simulators $f \
|
||||||
|
|||||||
@@ -673,4 +673,45 @@ typedef struct {
|
|||||||
nfapi_vendor_extension_tlv_t vendor_extension;
|
nfapi_vendor_extension_tlv_t vendor_extension;
|
||||||
} nfapi_nr_dl_config_request_t;
|
} nfapi_nr_dl_config_request_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
|
||||||
|
nr_pusch_freq_hopping_enabled = 1
|
||||||
|
} nr_pusch_freq_hopping_t;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint8_t aperiodicSRS_ResourceTrigger;
|
||||||
|
} nfapi_nr_ul_srs_config_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t bandwidth_part_ind;
|
||||||
|
uint16_t number_rbs;
|
||||||
|
uint16_t start_rb;
|
||||||
|
uint8_t frame_offset;
|
||||||
|
uint16_t number_symbols;
|
||||||
|
uint16_t start_symbol;
|
||||||
|
nr_pusch_freq_hopping_t pusch_freq_hopping;
|
||||||
|
uint8_t mcs;
|
||||||
|
uint8_t Qm;
|
||||||
|
uint8_t ndi;
|
||||||
|
uint8_t rv;
|
||||||
|
uint8_t harq_process_nbr;
|
||||||
|
int8_t accumulated_delta_PUSCH;
|
||||||
|
int8_t absolute_delta_PUSCH;
|
||||||
|
uint8_t n_layers;
|
||||||
|
uint8_t tpmi;
|
||||||
|
uint8_t n_dmrs_cdm_groups;
|
||||||
|
uint8_t dmrs_ports[4];
|
||||||
|
uint8_t n_front_load_symb;
|
||||||
|
nfapi_nr_ul_srs_config_t srs_config;
|
||||||
|
uint8_t csi_reportTriggerSize;
|
||||||
|
uint8_t maxCodeBlockGroupsPerTransportBlock;
|
||||||
|
uint8_t ptrs_dmrs_association_port;
|
||||||
|
uint8_t beta_offset_ind;
|
||||||
|
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t rnti;
|
||||||
|
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
|
||||||
|
} nfapi_nr_ul_config_ulsch_pdu;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "coding_defs.h"
|
#include "coding_defs.h"
|
||||||
|
#include "assertions.h"
|
||||||
|
|
||||||
/*ref 36-212 v8.6.0 , pp 8-9 */
|
/*ref 36-212 v8.6.0 , pp 8-9 */
|
||||||
/* the highest degree is set by default */
|
/* the highest degree is set by default */
|
||||||
@@ -275,7 +276,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
crc_len=3;
|
AssertFatal(1,"Invalid crc_type \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<crc_len; i++)
|
for (int i=0; i<crc_len; i++)
|
||||||
@@ -309,6 +310,9 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
|||||||
crc = crc8(decoded_bytes,
|
crc = crc8(decoded_bytes,
|
||||||
n-8)>>24;
|
n-8)>>24;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
AssertFatal(1,"Invalid crc_type \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crc == oldcrc)
|
if (crc == oldcrc)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
|||||||
unsigned int B,
|
unsigned int B,
|
||||||
unsigned int *C,
|
unsigned int *C,
|
||||||
unsigned int *K,
|
unsigned int *K,
|
||||||
unsigned int *Zout,
|
unsigned int *Zout, // [hna] Zout is Zc
|
||||||
unsigned int *F)
|
unsigned int *F)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
+29
-14
@@ -33,6 +33,7 @@
|
|||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||||
#include "SCHED_NR/fapi_nr_l1.h"
|
#include "SCHED_NR/fapi_nr_l1.h"
|
||||||
@@ -82,7 +83,9 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
||||||
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
||||||
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
|
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
|
||||||
|
|
||||||
int i, UE_id;
|
int i, UE_id;
|
||||||
|
|
||||||
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
|
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
|
||||||
gNB->total_dlsch_bitrate = 0;
|
gNB->total_dlsch_bitrate = 0;
|
||||||
gNB->total_transmitted_bits = 0;
|
gNB->total_transmitted_bits = 0;
|
||||||
@@ -110,7 +113,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
init_dfts();
|
init_dfts();
|
||||||
// PBCH DMRS gold sequences generation
|
// PBCH DMRS gold sequences generation
|
||||||
nr_init_pbch_dmrs(gNB);
|
nr_init_pbch_dmrs(gNB);
|
||||||
// Polar encoder init for PBCH
|
|
||||||
//PDCCH DMRS init
|
//PDCCH DMRS init
|
||||||
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||||
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
||||||
@@ -148,6 +150,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
||||||
|
|
||||||
/// Transport init necessary for NR synchro
|
/// Transport init necessary for NR synchro
|
||||||
init_nr_transport(gNB);
|
init_nr_transport(gNB);
|
||||||
|
|
||||||
@@ -171,7 +174,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
|
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
|
||||||
|
|
||||||
for (i=0;i<15;i++){
|
for (i=0;i<15;i++){
|
||||||
common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) );
|
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); // [hna] samples_per_frame without CP
|
||||||
|
|
||||||
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
|
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
|
||||||
i,common_vars->txdataF[i],
|
i,common_vars->txdataF[i],
|
||||||
fp->samples_per_frame_wCP*sizeof(int32_t));
|
fp->samples_per_frame_wCP*sizeof(int32_t));
|
||||||
@@ -422,6 +426,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
|||||||
gNB_config->rf_config.ul_carrier_bandwidth.value,
|
gNB_config->rf_config.ul_carrier_bandwidth.value,
|
||||||
gNB_config->sch_config.physical_cell_id.value,
|
gNB_config->sch_config.physical_cell_id.value,
|
||||||
fp->dl_CarrierFreq );
|
fp->dl_CarrierFreq );
|
||||||
|
|
||||||
nr_init_frame_parms(gNB_config, fp);
|
nr_init_frame_parms(gNB_config, fp);
|
||||||
|
|
||||||
if (RC.gNB[Mod_id][CC_id]->configured == 1) {
|
if (RC.gNB[Mod_id][CC_id]->configured == 1) {
|
||||||
@@ -441,6 +446,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
|||||||
LOG_I(PHY, "Initialise nr transport\n");
|
LOG_I(PHY, "Initialise nr transport\n");
|
||||||
|
|
||||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||||
|
|
||||||
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
||||||
|
|
||||||
for (j=0; j<2; j++) {
|
for (j=0; j<2; j++) {
|
||||||
@@ -450,29 +456,38 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
|||||||
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}/* else {
|
}/* else {
|
||||||
|
|
||||||
gNB->dlsch[i][j]->rnti=0;
|
gNB->dlsch[i][j]->rnti=0;
|
||||||
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
|
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
|
||||||
}*/
|
}*/
|
||||||
}
|
|
||||||
|
|
||||||
//LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
///////////////////////// Initializing gNB ULSCH /////////////////////////
|
||||||
//gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
|
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||||
/*if (!gNB->ulsch[1+i]) {
|
|
||||||
|
// ULSCH for RA
|
||||||
|
if(i==0) {
|
||||||
|
gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
|
||||||
|
|
||||||
|
if (!gNB->ulsch[i][j]) {
|
||||||
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ULSCH for data
|
||||||
|
gNB->ulsch[i+1][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
|
||||||
|
|
||||||
|
if (!gNB->ulsch[i+1][j]) {
|
||||||
|
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
}
|
||||||
|
|
||||||
// this is the transmission mode for the signalling channels
|
// this is the transmission mode for the signalling channels
|
||||||
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
|
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
|
||||||
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
|
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ULSCH for RA
|
|
||||||
//gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
|
|
||||||
/*if (!gNB->ulsch[0]) {
|
|
||||||
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
|
||||||
exit(-1);
|
|
||||||
}*/
|
|
||||||
gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
||||||
LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI);
|
LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI);
|
||||||
gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
||||||
|
|||||||
@@ -361,8 +361,13 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
|
|||||||
uint16_t max_harq_tx )
|
uint16_t max_harq_tx )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int num_of_threads,num_of_code_words;
|
||||||
|
|
||||||
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
|
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
|
||||||
phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
|
|
||||||
|
for (num_of_threads=0;num_of_threads<RX_NB_TH_MAX;num_of_threads++)
|
||||||
|
for (num_of_code_words=0;num_of_code_words<NR_MAX_NB_CODEWORDS;num_of_code_words++)
|
||||||
|
phy_vars_ue->ulsch[eNB_id][num_of_threads][num_of_code_words]->Mlimit = max_harq_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint16_t beta_cqi[16];
|
extern uint16_t beta_cqi[16];
|
||||||
@@ -921,12 +926,12 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
|
|||||||
for (j=0; j<2; j++) {
|
for (j=0; j<2; j++) {
|
||||||
for (k=0; k<RX_NB_TH_MAX; k++) {
|
for (k=0; k<RX_NB_TH_MAX; k++) {
|
||||||
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
|
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
|
||||||
|
|
||||||
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
|
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
|
AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NUMBER_OF_HARQ_PID_MAX, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
|
||||||
|
LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
||||||
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dlsch->harq_processes[i]->b) {
|
if (dlsch->harq_processes[i]->b) {
|
||||||
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
|
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES
|
||||||
dlsch->harq_processes[i]->b = NULL;
|
dlsch->harq_processes[i]->b = NULL;
|
||||||
#ifdef DEBUG_DLSCH_FREE
|
#ifdef DEBUG_DLSCH_FREE
|
||||||
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
|
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
|
||||||
@@ -195,8 +195,11 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
|
|||||||
if (abstraction_flag==0) {
|
if (abstraction_flag==0) {
|
||||||
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
|
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
|
||||||
// account for filler in first segment and CRCs for multiple segment case
|
// account for filler in first segment and CRCs for multiple segment case
|
||||||
|
// [hna] 8448 is the maximum CB size in NR
|
||||||
|
// 68*348 = 68*(maximum size of Zc)
|
||||||
|
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
|
||||||
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
|
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
|
||||||
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384);
|
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
|
||||||
if (dlsch->harq_processes[i]->c[r]) {
|
if (dlsch->harq_processes[i]->c[r]) {
|
||||||
bzero(dlsch->harq_processes[i]->c[r],8448);
|
bzero(dlsch->harq_processes[i]->c[r],8448);
|
||||||
} else {
|
} else {
|
||||||
@@ -272,7 +275,6 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
|
|
||||||
unsigned int G;
|
unsigned int G;
|
||||||
unsigned int crc=1;
|
unsigned int crc=1;
|
||||||
|
|
||||||
uint8_t harq_pid = dlsch->harq_ids[slot];
|
uint8_t harq_pid = dlsch->harq_ids[slot];
|
||||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
|
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;
|
uint16_t nb_rb = rel15.n_prb;
|
||||||
@@ -302,8 +304,10 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
A = rel15.transport_block_size;
|
A = rel15.transport_block_size;
|
||||||
|
|
||||||
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
|
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);
|
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);
|
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]->Ndi == 1) { // this is a new packet
|
||||||
@@ -328,6 +332,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
|
|
||||||
dlsch->harq_processes[harq_pid]->B = A+24;
|
dlsch->harq_processes[harq_pid]->B = A+24;
|
||||||
// dlsch->harq_processes[harq_pid]->b = a;
|
// dlsch->harq_processes[harq_pid]->b = a;
|
||||||
|
|
||||||
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
||||||
|
|
||||||
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
|
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
|
||||||
@@ -335,7 +340,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
dlsch->harq_processes[harq_pid]->B,
|
dlsch->harq_processes[harq_pid]->B,
|
||||||
&dlsch->harq_processes[harq_pid]->C,
|
&dlsch->harq_processes[harq_pid]->C,
|
||||||
&dlsch->harq_processes[harq_pid]->K,
|
&dlsch->harq_processes[harq_pid]->K,
|
||||||
pz,
|
pz, // [hna] pz is Zc
|
||||||
&dlsch->harq_processes[harq_pid]->F);
|
&dlsch->harq_processes[harq_pid]->F);
|
||||||
|
|
||||||
F = dlsch->harq_processes[harq_pid]->F;
|
F = dlsch->harq_processes[harq_pid]->F;
|
||||||
@@ -388,6 +393,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
//stop_meas(te_stats);
|
//stop_meas(te_stats);
|
||||||
//printf("end ldpc encoder -- output\n");
|
//printf("end ldpc encoder -- output\n");
|
||||||
|
|
||||||
|
//write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#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_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);
|
write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||||
@@ -429,6 +435,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
rel15.redundancy_version,
|
rel15.redundancy_version,
|
||||||
E);
|
E);
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
for (int i =0; i<16; i++)
|
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);
|
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
|
||||||
@@ -442,6 +449,7 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
dlsch->harq_processes[harq_pid]->f+r_offset);
|
dlsch->harq_processes[harq_pid]->f+r_offset);
|
||||||
//stop_meas(i_stats);
|
//stop_meas(i_stats);
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_CODING
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
for (int i =0; i<16; i++)
|
for (int i =0; i<16; i++)
|
||||||
printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
|
printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
|
||||||
@@ -455,5 +463,5 @@ int nr_dlsch_encoding(unsigned char *a,
|
|||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||||
|
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
|
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
|
||||||
|
|
||||||
#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
|
#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
|
||||||
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
|
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
|
||||||
|
|
||||||
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
|
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
|
||||||
#define MAX_NUM_NR_RE (14*273*12)
|
#define MAX_NUM_NR_RE (14*273*12)
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \file PHY/NR_TRANSPORT/nr_ulsch.h
|
||||||
|
* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB
|
||||||
|
* \author Ahmed Hussein
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company Fraunhofer IIS
|
||||||
|
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/defs_gNB.h"
|
||||||
|
|
||||||
|
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
|
||||||
|
|
||||||
|
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||||
|
uint8_t UE_id,
|
||||||
|
short *ulsch_llr,
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
uint32_t frame,
|
||||||
|
uint16_t nb_symb_sch,
|
||||||
|
uint8_t nr_tti_rx,
|
||||||
|
uint8_t harq_pid,
|
||||||
|
uint8_t is_crnti,
|
||||||
|
uint8_t llr8_flag);
|
||||||
|
|
||||||
@@ -0,0 +1,611 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding.c
|
||||||
|
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
|
||||||
|
* \author Ahmed Hussein
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company Fraunhofer IIS
|
||||||
|
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// [from gNB coding]
|
||||||
|
#include "PHY/defs_gNB.h"
|
||||||
|
#include "PHY/phy_extern.h"
|
||||||
|
#include "PHY/CODING/coding_extern.h"
|
||||||
|
#include "PHY/CODING/coding_defs.h"
|
||||||
|
#include "PHY/CODING/lte_interleaver_inline.h"
|
||||||
|
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||||
|
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||||
|
#include "SCHED_NR/sched_nr.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
#include "common/utils/LOG/log.h"
|
||||||
|
#include <syscall.h>
|
||||||
|
//#define DEBUG_ULSCH_DECODING
|
||||||
|
|
||||||
|
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||||
|
|
||||||
|
static uint64_t nb_total_decod =0;
|
||||||
|
static uint64_t nb_error_decod =0;
|
||||||
|
|
||||||
|
//extern double cpuf;
|
||||||
|
|
||||||
|
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
||||||
|
{
|
||||||
|
|
||||||
|
int i,r;
|
||||||
|
|
||||||
|
if (ulsch) {
|
||||||
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]) {
|
||||||
|
if (ulsch->harq_processes[i]->b) {
|
||||||
|
free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
|
||||||
|
ulsch->harq_processes[i]->b = NULL;
|
||||||
|
}
|
||||||
|
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
|
||||||
|
free16(ulsch->harq_processes[i]->c[r],(8448)*sizeof(uint8_t));
|
||||||
|
ulsch->harq_processes[i]->c[r] = NULL;
|
||||||
|
}
|
||||||
|
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
|
||||||
|
if (ulsch->harq_processes[i]->d[r]) {
|
||||||
|
free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t));
|
||||||
|
ulsch->harq_processes[i]->d[r] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) {
|
||||||
|
if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){
|
||||||
|
nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]);
|
||||||
|
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t));
|
||||||
|
ulsch->harq_processes[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free16(ulsch,sizeof(NR_gNB_ULSCH_t));
|
||||||
|
ulsch = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *ulsch;
|
||||||
|
uint8_t exit_flag = 0,i,r;
|
||||||
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
|
switch (N_RB_UL) {
|
||||||
|
case 106:
|
||||||
|
bw_scaling =2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bw_scaling =1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t));
|
||||||
|
|
||||||
|
if (ulsch) {
|
||||||
|
|
||||||
|
memset(ulsch,0,sizeof(NR_gNB_ULSCH_t));
|
||||||
|
|
||||||
|
ulsch->max_ldpc_iterations = max_ldpc_iterations;
|
||||||
|
ulsch->Mlimit = 4;
|
||||||
|
|
||||||
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
|
|
||||||
|
ulsch->harq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16(sizeof(NR_UL_gNB_HARQ_t));
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]) {
|
||||||
|
|
||||||
|
memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t));
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->b)
|
||||||
|
memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
else
|
||||||
|
exit_flag=3;
|
||||||
|
|
||||||
|
if (abstraction_flag == 0) {
|
||||||
|
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling; r++) {
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem();
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448*sizeof(uint8_t));
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->c[r])
|
||||||
|
memset(ulsch->harq_processes[i]->c[r],0,8448*sizeof(uint8_t));
|
||||||
|
else
|
||||||
|
exit_flag=2;
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16((68*384)*sizeof(int16_t));
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->d[r])
|
||||||
|
memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t));
|
||||||
|
else
|
||||||
|
exit_flag=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
exit_flag=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exit_flag==0)
|
||||||
|
return(ulsch);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
|
||||||
|
free_gNB_ulsch(ulsch);
|
||||||
|
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||||
|
uint8_t UE_id,
|
||||||
|
short *ulsch_llr,
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
uint32_t frame,
|
||||||
|
uint16_t nb_symb_sch,
|
||||||
|
uint8_t nr_tti_rx,
|
||||||
|
uint8_t harq_pid,
|
||||||
|
uint8_t is_crnti,
|
||||||
|
uint8_t llr8_flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32_t A,E;
|
||||||
|
uint32_t G;
|
||||||
|
uint32_t ret,offset;
|
||||||
|
int32_t no_iteration_ldpc, length_dec;
|
||||||
|
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
|
||||||
|
uint8_t crc_type;
|
||||||
|
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||||
|
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
|
||||||
|
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
|
||||||
|
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
|
||||||
|
|
||||||
|
t_nrLDPC_dec_params decParams;
|
||||||
|
t_nrLDPC_dec_params* p_decParams = &decParams;
|
||||||
|
t_nrLDPC_time_stats procTime;
|
||||||
|
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||||
|
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
|
||||||
|
|
||||||
|
int16_t z [68*384];
|
||||||
|
int8_t l [68*384];
|
||||||
|
int16_t inv_d [68*384];
|
||||||
|
uint8_t kc;
|
||||||
|
uint8_t Ilbrm = 0;
|
||||||
|
uint32_t Tbslbrm = 950984;
|
||||||
|
uint16_t nb_rb = 30; //to update
|
||||||
|
uint8_t nb_re_dmrs = 6;
|
||||||
|
uint16_t length_dmrs = 1;
|
||||||
|
double Coderate = 0.0;
|
||||||
|
|
||||||
|
uint32_t i,j;
|
||||||
|
|
||||||
|
__m128i *pv = (__m128i*)&z;
|
||||||
|
__m128i *pl = (__m128i*)&l;
|
||||||
|
|
||||||
|
|
||||||
|
if (!ulsch_llr) {
|
||||||
|
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||||
|
return(ulsch->max_ldpc_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!harq_process) {
|
||||||
|
printf("ulsch_decoding.c: NULL harq_process pointer\n");
|
||||||
|
return(ulsch->max_ldpc_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!frame_parms) {
|
||||||
|
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
|
||||||
|
return(ulsch->max_ldpc_iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
|
||||||
|
|
||||||
|
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
|
||||||
|
|
||||||
|
harq_process->TBS = nr_compute_tbs(nfapi_ulsch_pdu_rel15->mcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->n_layers);
|
||||||
|
|
||||||
|
A = harq_process->TBS;
|
||||||
|
ret = ulsch->max_ldpc_iterations;
|
||||||
|
|
||||||
|
harq_process->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);
|
||||||
|
G = harq_process->G;
|
||||||
|
|
||||||
|
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, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->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);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
p_decParams->R = 15;
|
||||||
|
kc = 52;
|
||||||
|
}
|
||||||
|
else if (Coderate <0.6667) {
|
||||||
|
p_decParams->R = 13;
|
||||||
|
kc = 32;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p_decParams->R = 23;
|
||||||
|
kc = 17;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p_decParams->BG = 1;
|
||||||
|
if (Coderate < 0.6667) {
|
||||||
|
p_decParams->R = 13;
|
||||||
|
kc = 68;
|
||||||
|
}
|
||||||
|
else if (Coderate <0.8889) {
|
||||||
|
p_decParams->R = 23;
|
||||||
|
kc = 35;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p_decParams->R = 89;
|
||||||
|
kc = 27;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("coderate %f kc %d \n", Coderate, kc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
|
||||||
|
p_decParams->outMode= 0;
|
||||||
|
|
||||||
|
err_flag = 0;
|
||||||
|
r_offset = 0;
|
||||||
|
|
||||||
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
|
switch (frame_parms->N_RB_UL) {
|
||||||
|
|
||||||
|
case 106:
|
||||||
|
bw_scaling =2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bw_scaling =1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
opp_enabled=1;
|
||||||
|
|
||||||
|
Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
|
||||||
|
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; r<harq_process->C; r++) {
|
||||||
|
|
||||||
|
E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
|
||||||
|
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
start_meas(ulsch_deinterleaving_stats);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
|
||||||
|
|
||||||
|
nr_deinterleaving_ldpc(E,
|
||||||
|
nfapi_ulsch_pdu_rel15->Qm,
|
||||||
|
harq_process->e[r],
|
||||||
|
ulsch_llr+r_offset);
|
||||||
|
|
||||||
|
//for (int i =0; i<16; i++)
|
||||||
|
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
|
||||||
|
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
stop_meas(ulsch_deinterleaving_stats);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
start_meas(ulsch_rate_unmatching_stats);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||||
|
harq_pid,r, G,
|
||||||
|
Kr*3,
|
||||||
|
harq_process->TBS,
|
||||||
|
nfapi_ulsch_pdu_rel15->Qm,
|
||||||
|
nfapi_ulsch_pdu_rel15->number_rbs,
|
||||||
|
nfapi_ulsch_pdu_rel15->n_layers,
|
||||||
|
nfapi_ulsch_pdu_rel15->rv,
|
||||||
|
harq_process->round);
|
||||||
|
#endif
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
|
||||||
|
|
||||||
|
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||||
|
Tbslbrm,
|
||||||
|
p_decParams->BG,
|
||||||
|
p_decParams->Z,
|
||||||
|
harq_process->d[r],
|
||||||
|
harq_process->e[r],
|
||||||
|
harq_process->C,
|
||||||
|
nfapi_ulsch_pdu_rel15->rv,
|
||||||
|
(harq_process->round==0)?1:0,
|
||||||
|
E)==-1) {
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
stop_meas(ulsch_rate_unmatching_stats);
|
||||||
|
#endif
|
||||||
|
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||||
|
return(ulsch->max_ldpc_iterations);
|
||||||
|
} else {
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
stop_meas(ulsch_rate_unmatching_stats);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
r_offset += E;
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
if (r==0) {
|
||||||
|
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
|
||||||
|
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("decoder input(segment %d) :",r);
|
||||||
|
int i;
|
||||||
|
for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||||
|
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||||
|
memset(harq_process->c[r],0,Kr_bytes);
|
||||||
|
|
||||||
|
// printf("done\n");
|
||||||
|
if (harq_process->C == 1) {
|
||||||
|
crc_type = CRC24_A;
|
||||||
|
length_dec = harq_process->B;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
crc_type = CRC24_B;
|
||||||
|
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err_flag == 0) {
|
||||||
|
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
start_meas(ulsch_turbo_decoding_stats);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
|
||||||
|
|
||||||
|
|
||||||
|
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
||||||
|
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
||||||
|
|
||||||
|
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
|
||||||
|
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
|
||||||
|
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
|
||||||
|
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||||
|
|
||||||
|
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||||
|
(int8_t*)&pl[0],
|
||||||
|
llrProcBuf,
|
||||||
|
p_nrLDPC_procBuf[r],
|
||||||
|
p_procTime);
|
||||||
|
|
||||||
|
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
||||||
|
printf("Segment %d CRC OK\n",r);
|
||||||
|
ret = 2;
|
||||||
|
} else {
|
||||||
|
printf("CRC NOK\n");
|
||||||
|
ret = 1+ulsch->max_ldpc_iterations;
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||||
|
for (int k=0;k<A>>3;k++)
|
||||||
|
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||||
|
printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret);
|
||||||
|
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if gNB_TIMING_TRACE
|
||||||
|
stop_meas(ulsch_turbo_decoding_stats);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((err_flag == 0) && (ret>=(1+ulsch->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);
|
||||||
|
err_flag = 1;
|
||||||
|
}
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t frame_rx_prev = frame;
|
||||||
|
int32_t tti_rx_prev = nr_tti_rx - 1;
|
||||||
|
if (tti_rx_prev < 0) {
|
||||||
|
frame_rx_prev--;
|
||||||
|
tti_rx_prev += 10*frame_parms->ttis_per_subframe;
|
||||||
|
}
|
||||||
|
frame_rx_prev = frame_rx_prev%1024;
|
||||||
|
|
||||||
|
if (err_flag == 1) {
|
||||||
|
|
||||||
|
#if gNB_DEBUG_TRACE
|
||||||
|
LOG_I(PHY,"[gNB %d] ULSCH: 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_gNB->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
|
||||||
|
|
||||||
|
// harq_process->harq_ack.ack = 0;
|
||||||
|
// harq_process->harq_ack.harq_id = harq_pid;
|
||||||
|
// harq_process->harq_ack.send_harq_status = 1;
|
||||||
|
// harq_process->errors[harq_process->round]++;
|
||||||
|
harq_process->round++;
|
||||||
|
|
||||||
|
if (harq_process->round >= ulsch->Mlimit) {
|
||||||
|
harq_process->status = SCH_IDLE;
|
||||||
|
harq_process->round = 0;
|
||||||
|
harq_process->handled = 0;
|
||||||
|
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_crnti) {
|
||||||
|
LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||||
|
phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
|
||||||
|
}
|
||||||
|
|
||||||
|
harq_process->handled = 1;
|
||||||
|
return((1+ulsch->max_ldpc_iterations));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
#if gNB_DEBUG_TRACE
|
||||||
|
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
||||||
|
phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
harq_process->status = SCH_IDLE;
|
||||||
|
harq_process->round = 0;
|
||||||
|
// harq_process->handled = 0;
|
||||||
|
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||||
|
// harq_process->harq_ack.ack = 1;
|
||||||
|
// harq_process->harq_ack.harq_id = harq_pid;
|
||||||
|
// harq_process->harq_ack.send_harq_status = 1;
|
||||||
|
|
||||||
|
if(is_crnti)
|
||||||
|
{
|
||||||
|
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reassembly of Transport block here
|
||||||
|
offset = 0;
|
||||||
|
Kr = harq_process->K;
|
||||||
|
Kr_bytes = Kr>>3;
|
||||||
|
|
||||||
|
for (r=0; r<harq_process->C; r++) {
|
||||||
|
|
||||||
|
memcpy(harq_process->b+offset,
|
||||||
|
harq_process->c[r],
|
||||||
|
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||||
|
|
||||||
|
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
|
||||||
|
printf("copied %d bytes to b sequence (harq_pid %d)\n",
|
||||||
|
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||||
|
printf("b[0] = %x,c[%d] = %x\n",
|
||||||
|
harq_process->b[offset],
|
||||||
|
harq_process->F>>3,
|
||||||
|
harq_process->c[r]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ulsch->last_iteration_cnt = ret;
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
@@ -309,8 +309,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
harq_process->B,
|
harq_process->B,
|
||||||
&harq_process->C,
|
&harq_process->C,
|
||||||
&harq_process->K,
|
&harq_process->K,
|
||||||
&harq_process->Z,
|
&harq_process->Z, // [hna] Z is Zc
|
||||||
&harq_process->F);
|
&harq_process->F);
|
||||||
|
|
||||||
p_decParams->Z = harq_process->Z;
|
p_decParams->Z = harq_process->Z;
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_DECODING
|
#ifdef DEBUG_DLSCH_DECODING
|
||||||
@@ -319,8 +320,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
|
printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Coderate = (float) A /(float) G;
|
Coderate = (float) A /(float) G;
|
||||||
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
|
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
|
||||||
|
{
|
||||||
p_decParams->BG = 2;
|
p_decParams->BG = 2;
|
||||||
if (Coderate < 0.3333){
|
if (Coderate < 0.3333){
|
||||||
p_decParams->R = 15;
|
p_decParams->R = 15;
|
||||||
@@ -356,14 +359,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
|
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
|
||||||
p_decParams->outMode= 0;
|
p_decParams->outMode= 0;
|
||||||
|
|
||||||
|
|
||||||
err_flag = 0;
|
err_flag = 0;
|
||||||
r_offset = 0;
|
r_offset = 0;
|
||||||
|
|
||||||
unsigned char bw_scaling =1;
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
switch (frame_parms->N_RB_DL) {
|
switch (frame_parms->N_RB_DL) {
|
||||||
|
|
||||||
case 106:
|
case 106:
|
||||||
bw_scaling =2;
|
bw_scaling =2;
|
||||||
break;
|
break;
|
||||||
@@ -377,13 +378,14 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling);
|
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling);
|
||||||
return((1+dlsch->max_ldpc_iterations));
|
return((1+dlsch->max_ldpc_iterations));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH_DECODING
|
#ifdef DEBUG_DLSCH_DECODING
|
||||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
opp_enabled=1;
|
opp_enabled=1;
|
||||||
|
|
||||||
Kr = harq_process->K;
|
Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb"
|
||||||
Kr_bytes = Kr>>3;
|
Kr_bytes = Kr>>3;
|
||||||
|
|
||||||
K_bytes_F = Kr_bytes-(harq_process->F>>3);
|
K_bytes_F = Kr_bytes-(harq_process->F>>3);
|
||||||
@@ -400,7 +402,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
#endif
|
#endif
|
||||||
nr_deinterleaving_ldpc(E,
|
nr_deinterleaving_ldpc(E,
|
||||||
harq_process->Qm,
|
harq_process->Qm,
|
||||||
harq_process->w[r],
|
harq_process->w[r], // [hna] w is e
|
||||||
dlsch_llr+r_offset);
|
dlsch_llr+r_offset);
|
||||||
|
|
||||||
//for (int i =0; i<16; i++)
|
//for (int i =0; i<16; i++)
|
||||||
@@ -441,8 +443,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
#endif
|
#endif
|
||||||
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
|
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
|
||||||
return(dlsch->max_ldpc_iterations);
|
return(dlsch->max_ldpc_iterations);
|
||||||
} else
|
} else {
|
||||||
{
|
|
||||||
#if UE_TIMING_TRACE
|
#if UE_TIMING_TRACE
|
||||||
stop_meas(dlsch_rate_unmatching_stats);
|
stop_meas(dlsch_rate_unmatching_stats);
|
||||||
#endif
|
#endif
|
||||||
@@ -460,12 +461,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("decoder input(segment %d) :",r);
|
printf("decoder input(segment %d) :",r);
|
||||||
int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
int i;
|
||||||
|
for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||||
memset(harq_process->c[r],0,Kr_bytes);
|
memset(harq_process->c[r],0,Kr_bytes);
|
||||||
|
|
||||||
@@ -489,7 +490,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
|
|
||||||
//printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
|
//printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
|
||||||
|
|
||||||
|
|
||||||
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
||||||
//memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
|
//memset(pl,0,2*p_decParams->Z*sizeof(int8_t));
|
||||||
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
||||||
@@ -506,9 +506,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
|
|
||||||
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++)
|
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++)
|
||||||
{
|
{
|
||||||
|
|
||||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||||
@@ -527,7 +525,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
ret = 1+dlsch->max_ldpc_iterations;
|
ret = 1+dlsch->max_ldpc_iterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nb_total_decod++;
|
nb_total_decod++;
|
||||||
if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
|
if (no_iteration_ldpc > dlsch->max_ldpc_iterations){
|
||||||
nb_error_decod++;
|
nb_error_decod++;
|
||||||
@@ -792,6 +789,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
&harq_process->K,
|
&harq_process->K,
|
||||||
&harq_process->Z,
|
&harq_process->Z,
|
||||||
&harq_process->F);
|
&harq_process->F);
|
||||||
|
|
||||||
p_decParams->Z = harq_process->Z;
|
p_decParams->Z = harq_process->Z;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -883,7 +881,6 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
|
|||||||
LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id );
|
LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id );
|
||||||
exit_fun("nothing to add");
|
exit_fun("nothing to add");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td);
|
LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td);
|
||||||
@@ -916,7 +913,6 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
|
|||||||
LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id );
|
LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id );
|
||||||
exit_fun("nothing to add");
|
exit_fun("nothing to add");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread 1 busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td1);
|
LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread 1 busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td1);
|
||||||
@@ -1112,9 +1108,7 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
|
|||||||
|
|
||||||
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++)
|
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++)
|
||||||
{
|
{
|
||||||
|
|
||||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||||
@@ -1163,9 +1157,7 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
|
|||||||
|
|
||||||
for (int j=0; j < Kr>>3; j ++)
|
for (int j=0; j < Kr>>3; j ++)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf(" %d \n", ullrProcBuf[j]);
|
printf(" %d \n", ullrProcBuf[j]);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf(" \n");*/
|
printf(" \n");*/
|
||||||
//printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
//printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
|
|||||||
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
|
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
|
||||||
|
|
||||||
|
|
||||||
void free_ue_ulsch(NR_UE_ULSCH_t *ulsch);
|
void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch);
|
||||||
|
|
||||||
|
|
||||||
NR_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
|
NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
|
||||||
|
|
||||||
void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
|
void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
|
||||||
|
|
||||||
@@ -1006,6 +1006,25 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
uint8_t is_crnti,
|
uint8_t is_crnti,
|
||||||
uint8_t llr8_flag);
|
uint8_t llr8_flag);
|
||||||
|
|
||||||
|
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||||
|
NR_DL_FRAME_PARMS* frame_parms,
|
||||||
|
uint8_t 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
|
||||||
|
@param[in] Nid cell id
|
||||||
|
@param[in] n_RNTI CRNTI
|
||||||
|
@param[out] out the scrambled bits
|
||||||
|
*/
|
||||||
|
|
||||||
|
void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||||
|
uint16_t size,
|
||||||
|
uint32_t Nid,
|
||||||
|
uint32_t n_RNTI,
|
||||||
|
uint32_t* out);
|
||||||
|
|
||||||
|
|
||||||
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
int eNB_id,
|
int eNB_id,
|
||||||
|
|||||||
@@ -102,6 +102,8 @@ typedef struct {
|
|||||||
uint16_t first_rb;
|
uint16_t first_rb;
|
||||||
/// Current Number of RBs
|
/// Current Number of RBs
|
||||||
uint16_t nb_rb;
|
uint16_t nb_rb;
|
||||||
|
/// number of layers
|
||||||
|
uint8_t Nl;
|
||||||
/// Last TPC command
|
/// Last TPC command
|
||||||
uint8_t TPC;
|
uint8_t TPC;
|
||||||
/// Transport block size
|
/// Transport block size
|
||||||
@@ -110,20 +112,24 @@ typedef struct {
|
|||||||
uint32_t B;
|
uint32_t B;
|
||||||
/// Length of ACK information (bits)
|
/// Length of ACK information (bits)
|
||||||
uint8_t O_ACK;
|
uint8_t O_ACK;
|
||||||
/// Pointer to the payload
|
|
||||||
uint8_t *b;
|
|
||||||
/// Pointers to transport block segments
|
|
||||||
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
|
|
||||||
/// Index of current HARQ round for this ULSCH
|
/// Index of current HARQ round for this ULSCH
|
||||||
uint8_t round;
|
uint8_t round;
|
||||||
/// MCS format of this ULSCH
|
/// MCS format of this ULSCH
|
||||||
uint8_t mcs;
|
uint8_t mcs;
|
||||||
/// Redundancy-version of the current sub-frame
|
/// Redundancy-version of the current sub-frame
|
||||||
uint8_t rvidx;
|
uint8_t rvidx;
|
||||||
|
/// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
|
||||||
|
unsigned char *a;
|
||||||
|
/// Pointer to the payload + CRC
|
||||||
|
uint8_t *b;
|
||||||
|
/// Pointers to transport block segments
|
||||||
|
uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
/// LDPC-code outputs
|
/// LDPC-code outputs
|
||||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
|
||||||
/// Interleaver outputs
|
/// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17)
|
||||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||||
|
/// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30)
|
||||||
|
uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||||
/// Number of code segments
|
/// Number of code segments
|
||||||
uint32_t C;
|
uint32_t C;
|
||||||
/// Number of bits in code segments
|
/// Number of bits in code segments
|
||||||
@@ -158,6 +164,8 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/// Current Number of Symbols
|
/// Current Number of Symbols
|
||||||
uint8_t Nsymb_pusch;
|
uint8_t Nsymb_pusch;
|
||||||
|
/// number of DMRS resource elements
|
||||||
|
uint8_t nb_re_dmrs;
|
||||||
/// SRS active flag
|
/// SRS active flag
|
||||||
uint8_t srs_active;
|
uint8_t srs_active;
|
||||||
//#if defined(UPGRADE_RAT_NR)
|
//#if defined(UPGRADE_RAT_NR)
|
||||||
@@ -168,6 +176,7 @@ typedef struct {
|
|||||||
// UL number of harq processes
|
// UL number of harq processes
|
||||||
uint8_t number_harq_processes_for_pusch;
|
uint8_t number_harq_processes_for_pusch;
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
/// Pointer to CQI data (+1 for 8 bits crc)
|
/// Pointer to CQI data (+1 for 8 bits crc)
|
||||||
uint8_t o[1+MAX_CQI_BYTES];
|
uint8_t o[1+MAX_CQI_BYTES];
|
||||||
/// Length of CQI data (bits)
|
/// Length of CQI data (bits)
|
||||||
@@ -180,22 +189,25 @@ typedef struct {
|
|||||||
uint8_t O_RI;
|
uint8_t O_RI;
|
||||||
/// Pointer to ACK
|
/// Pointer to ACK
|
||||||
uint8_t o_ACK[4];
|
uint8_t o_ACK[4];
|
||||||
|
*/
|
||||||
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
|
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
|
||||||
uint8_t O_CQI_MIN;
|
uint8_t O_CQI_MIN;
|
||||||
/// ACK/NAK Bundling flag
|
/// ACK/NAK Bundling flag
|
||||||
uint8_t bundling;
|
uint8_t bundling;
|
||||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// Concatenated "g"-sequences (for definition see 36-212 V15.4.0 2018-12, p.31)
|
||||||
uint8_t e[MAX_NUM_CHANNEL_BITS];
|
uint8_t g[MAX_NUM_NR_CHANNEL_BITS];
|
||||||
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||||
uint8_t h[MAX_NUM_CHANNEL_BITS];
|
uint8_t h[MAX_NUM_NR_CHANNEL_BITS];
|
||||||
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||||
uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
|
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
|
||||||
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||||
int32_t d[MAX_NUM_RE];
|
int32_t d[MAX_NUM_NR_RE];
|
||||||
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
|
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
|
||||||
int32_t z[MAX_NUM_RE];
|
int32_t z[MAX_NUM_NR_RE];
|
||||||
|
/*
|
||||||
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||||
uint8_t q[MAX_CQI_PAYLOAD];
|
uint8_t q[MAX_CQI_PAYLOAD];
|
||||||
|
|
||||||
/// coded and interleaved CQI bits
|
/// coded and interleaved CQI bits
|
||||||
uint8_t o_w[(MAX_CQI_BITS+8)*3];
|
uint8_t o_w[(MAX_CQI_BITS+8)*3];
|
||||||
/// coded CQI bits
|
/// coded CQI bits
|
||||||
@@ -204,6 +216,7 @@ typedef struct {
|
|||||||
uint8_t q_ACK[MAX_ACK_PAYLOAD];
|
uint8_t q_ACK[MAX_ACK_PAYLOAD];
|
||||||
/// coded RI bits
|
/// coded RI bits
|
||||||
uint8_t q_RI[MAX_RI_PAYLOAD];
|
uint8_t q_RI[MAX_RI_PAYLOAD];
|
||||||
|
*/
|
||||||
/// beta_offset_cqi times 8
|
/// beta_offset_cqi times 8
|
||||||
uint16_t beta_offset_cqi_times8;
|
uint16_t beta_offset_cqi_times8;
|
||||||
/// beta_offset_ri times 8
|
/// beta_offset_ri times 8
|
||||||
@@ -229,9 +242,9 @@ typedef struct {
|
|||||||
/// num active cba group
|
/// num active cba group
|
||||||
uint8_t num_active_cba_groups;
|
uint8_t num_active_cba_groups;
|
||||||
/// num dci found for cba
|
/// num dci found for cba
|
||||||
uint8_t num_cba_dci[10];
|
//uint8_t num_cba_dci[10];
|
||||||
/// allocated CBA RNTI
|
/// allocated CBA RNTI
|
||||||
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
||||||
/// UL max-harq-retransmission
|
/// UL max-harq-retransmission
|
||||||
uint8_t Mlimit;
|
uint8_t Mlimit;
|
||||||
} NR_UE_ULSCH_t;
|
} NR_UE_ULSCH_t;
|
||||||
|
|||||||
@@ -0,0 +1,453 @@
|
|||||||
|
/*
|
||||||
|
* 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_UE_TRANSPORT/nr_ulsch_coding.c
|
||||||
|
* \brief Top-level routines for coding the ULSCH transport channel as described in 38.212 V15.4 2018-12
|
||||||
|
* \author Khalid Ahmed
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company Fraunhofer IIS
|
||||||
|
* \email: khalid.ahmed@iis.fraunhofer.de
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/defs_UE.h"
|
||||||
|
#include "PHY/phy_extern_ue.h"
|
||||||
|
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||||
|
#include "PHY/CODING/coding_defs.h"
|
||||||
|
#include "PHY/CODING/coding_extern.h"
|
||||||
|
#include "PHY/CODING/lte_interleaver_inline.h"
|
||||||
|
#include "PHY/CODING/nrLDPC_encoder/defs.h"
|
||||||
|
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||||
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (ulsch) {
|
||||||
|
#ifdef DEBUG_ULSCH_FREE
|
||||||
|
printf("Freeing ulsch %p\n",ulsch);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) {
|
||||||
|
if (ulsch->harq_processes[i]) {
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->a) {
|
||||||
|
free16(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES);
|
||||||
|
ulsch->harq_processes[i]->a = NULL;
|
||||||
|
}
|
||||||
|
if (ulsch->harq_processes[i]->b) {
|
||||||
|
free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES);
|
||||||
|
ulsch->harq_processes[i]->b = NULL;
|
||||||
|
}
|
||||||
|
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS; r++) {
|
||||||
|
if (ulsch->harq_processes[i]->c[r]) {
|
||||||
|
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
|
||||||
|
ulsch->harq_processes[i]->c[r] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->d[r]) {
|
||||||
|
free16(ulsch->harq_processes[i]->d[r],68*384);
|
||||||
|
ulsch->harq_processes[i]->d[r] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
free16(ulsch->harq_processes[i],sizeof(NR_UL_UE_HARQ_t));
|
||||||
|
ulsch->harq_processes[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free16(ulsch,sizeof(NR_UE_ULSCH_t));
|
||||||
|
ulsch = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
NR_UE_ULSCH_t *ulsch;
|
||||||
|
unsigned char exit_flag = 0,i,j,r;
|
||||||
|
unsigned char bw_scaling =1;
|
||||||
|
|
||||||
|
switch (N_RB_UL) {
|
||||||
|
|
||||||
|
case 106:
|
||||||
|
bw_scaling =2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
bw_scaling =1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulsch = (NR_UE_ULSCH_t *)malloc16(sizeof(NR_UE_ULSCH_t));
|
||||||
|
|
||||||
|
if (ulsch) {
|
||||||
|
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
|
||||||
|
|
||||||
|
ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES;
|
||||||
|
ulsch->Mlimit = 4; // maximum harq retransmissions
|
||||||
|
|
||||||
|
//for (i=0; i<10; i++)
|
||||||
|
//ulsch->harq_ids[i] = 0;
|
||||||
|
|
||||||
|
for (i=0; i<number_of_harq_pids; i++) {
|
||||||
|
|
||||||
|
ulsch->harq_processes[i] = (NR_UL_UE_HARQ_t *)malloc16(sizeof(NR_UL_UE_HARQ_t));
|
||||||
|
|
||||||
|
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
|
||||||
|
if (ulsch->harq_processes[i]) {
|
||||||
|
memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t));
|
||||||
|
ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
ulsch->harq_processes[i]->a = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->a) {
|
||||||
|
bzero(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
} else {
|
||||||
|
printf("Can't allocate PDU\n");
|
||||||
|
exit_flag=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->b)
|
||||||
|
bzero(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling);
|
||||||
|
else {
|
||||||
|
LOG_E(PHY,"Can't get b\n");
|
||||||
|
exit_flag=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abstraction_flag==0) {
|
||||||
|
for (r=0; r<MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling; r++) {
|
||||||
|
// account for filler in first segment and CRCs for multiple segment case
|
||||||
|
ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
|
||||||
|
ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
|
||||||
|
|
||||||
|
if (ulsch->harq_processes[i]->c[r]) {
|
||||||
|
bzero(ulsch->harq_processes[i]->c[r],8448);
|
||||||
|
} else {
|
||||||
|
printf("Can't get c\n");
|
||||||
|
exit_flag=2;
|
||||||
|
}
|
||||||
|
if (ulsch->harq_processes[i]->d[r]) {
|
||||||
|
bzero(ulsch->harq_processes[i]->d[r],(68*384));
|
||||||
|
} else {
|
||||||
|
printf("Can't get d\n");
|
||||||
|
exit_flag=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
|
||||||
|
ulsch->harq_processes[i]->first_tx = 1;
|
||||||
|
} else {
|
||||||
|
LOG_E(PHY,"Can't get harq_p %d\n",i);
|
||||||
|
exit_flag=3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exit_flag==0) {
|
||||||
|
for (i=0; i<number_of_harq_pids; i++) {
|
||||||
|
ulsch->harq_processes[i]->round=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ulsch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
|
||||||
|
free_nr_ue_ulsch(ulsch);
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||||
|
NR_DL_FRAME_PARMS* frame_parms,
|
||||||
|
uint8_t harq_pid)
|
||||||
|
{
|
||||||
|
|
||||||
|
/////////////////////////parameters and variables declaration/////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
unsigned int G,crc;
|
||||||
|
NR_UL_UE_HARQ_t *harq_process;
|
||||||
|
uint16_t nb_rb ;
|
||||||
|
uint8_t nb_symb_sch ;
|
||||||
|
uint32_t A, Z, F;
|
||||||
|
uint32_t *pz;
|
||||||
|
uint8_t mod_order;
|
||||||
|
uint16_t Kr,r,r_offset,Kr_bytes;
|
||||||
|
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
|
||||||
|
uint8_t BG;
|
||||||
|
uint32_t E;
|
||||||
|
uint8_t Ilbrm;
|
||||||
|
uint32_t Tbslbrm;
|
||||||
|
uint8_t nb_re_dmrs;
|
||||||
|
uint16_t length_dmrs;
|
||||||
|
int i;
|
||||||
|
float Coderate;
|
||||||
|
|
||||||
|
///////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////parameters and variables initialization/////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
crc = 1;
|
||||||
|
harq_process = ulsch->harq_processes[harq_pid];
|
||||||
|
nb_rb = harq_process->nb_rb;
|
||||||
|
nb_symb_sch = harq_process->nb_symbols;
|
||||||
|
A = harq_process->TBS;
|
||||||
|
pz = &Z;
|
||||||
|
mod_order = nr_get_Qm(harq_process->mcs,1);
|
||||||
|
Kr=0;
|
||||||
|
r_offset=0;
|
||||||
|
BG = 1;
|
||||||
|
F=0;
|
||||||
|
Ilbrm = 0;
|
||||||
|
Tbslbrm = 950984; //max tbs
|
||||||
|
nb_re_dmrs = ulsch->nb_re_dmrs;
|
||||||
|
length_dmrs = 1;
|
||||||
|
Coderate = 0.0;
|
||||||
|
|
||||||
|
///////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char
|
||||||
|
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||||
|
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
||||||
|
|
||||||
|
printf("ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs);
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
printf("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
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
printf("encoding thinks this is a new packet \n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////// a---->| add CRC |---->b /////////////////////////
|
||||||
|
///////////
|
||||||
|
/*
|
||||||
|
int i;
|
||||||
|
printf("ulsch (tx): \n");
|
||||||
|
for (i=0;i<(A>>3);i++)
|
||||||
|
printf("%02x.",a[i]);
|
||||||
|
printf("\n");
|
||||||
|
*/
|
||||||
|
// Add 24-bit crc (polynomial A) to payload
|
||||||
|
crc = crc24a(harq_process->a,A)>>8;
|
||||||
|
harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
|
||||||
|
harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1];
|
||||||
|
harq_process->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)]);
|
||||||
|
|
||||||
|
harq_process->B = A+24;
|
||||||
|
|
||||||
|
memcpy(harq_process->b,harq_process->a,(A/8)+4);
|
||||||
|
|
||||||
|
///////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////// 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 ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
|
||||||
|
BG = 2;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
BG = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Kr = harq_process->K;
|
||||||
|
Kr_bytes = Kr>>3;
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////// c---->| LDCP coding |---->d /////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
//printf("segment Z %d k %d Kr %d BG %d\n", *pz,harq_process->K,Kr,BG);
|
||||||
|
|
||||||
|
//start_meas(te_stats);
|
||||||
|
for (r=0; r<harq_process->C; r++) {
|
||||||
|
d_tmp[r] = &harq_process->d[r][0];
|
||||||
|
//channel_input[r] = &harq_process->d[r][0];
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
|
||||||
|
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
|
||||||
|
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||||
|
for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
|
||||||
|
printf("%d ", harq_process->c[r][cnt]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//ldpc_encoder_orig((unsigned char*)harq_process->c[r],harq_process->d[r],Kr,BG,0);
|
||||||
|
//ldpc_encoder_optim((unsigned char*)harq_process->c[r],(unsigned char*)&harq_process->d[r][0],Kr,BG,NULL,NULL,NULL,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//for (int i=0;i<68*384;i++)
|
||||||
|
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
|
||||||
|
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
|
||||||
|
printf("%d \n", harq_process->d[0][cnt]);
|
||||||
|
}
|
||||||
|
printf("\n");*/
|
||||||
|
|
||||||
|
//ldpc_encoder_optim_8seg(harq_process->c,d_tmp,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
|
||||||
|
ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
|
||||||
|
|
||||||
|
//stop_meas(te_stats);
|
||||||
|
//printf("end ldpc encoder -- output\n");
|
||||||
|
//write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||||
|
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (r=0; r<harq_process->C; r++) { // looping over C segments
|
||||||
|
|
||||||
|
if (harq_process->F>0) {
|
||||||
|
for (int k=(Kr-F-2*(*pz)); k<Kr-2*(*pz); k++) {
|
||||||
|
harq_process->d[r][k] = NR_NULL;
|
||||||
|
//if (k<(Kr-F+8))
|
||||||
|
//printf("r %d filler bits [%d] = %d \n", r,k, harq_process->d[r][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
|
||||||
|
r,
|
||||||
|
G,
|
||||||
|
Kr*3,
|
||||||
|
mod_order,nb_rb);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//start_meas(rm_stats);
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
printf("rvidx in encoding = %d\n", harq_process->rvidx);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////// d---->| Rate matching bit selection |---->e /////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r);
|
||||||
|
|
||||||
|
nr_rate_matching_ldpc(Ilbrm,
|
||||||
|
Tbslbrm,
|
||||||
|
BG,
|
||||||
|
*pz,
|
||||||
|
harq_process->d[r],
|
||||||
|
harq_process->e+r_offset,
|
||||||
|
harq_process->C,
|
||||||
|
harq_process->rvidx,
|
||||||
|
E);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
for (int i =0; i<16; i++)
|
||||||
|
printf("output ratematching e[%d]= %d r_offset %d\n", i,harq_process->e[i+r_offset], r_offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////// e---->| Rate matching bit interleaving |---->f /////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
//stop_meas(rm_stats);
|
||||||
|
|
||||||
|
//start_meas(i_stats);
|
||||||
|
nr_interleaving_ldpc(E,
|
||||||
|
mod_order,
|
||||||
|
harq_process->e+r_offset,
|
||||||
|
harq_process->f+r_offset);
|
||||||
|
//stop_meas(i_stats);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_DLSCH_CODING
|
||||||
|
for (int i =0; i<16; i++)
|
||||||
|
printf("output interleaving f[%d]= %d r_offset %d\n", i,harq_process->f[i+r_offset], r_offset);
|
||||||
|
|
||||||
|
if (r==harq_process->C-1)
|
||||||
|
write_output("enc_output.m","enc",harq_process->f,G,1,4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
r_offset += E;
|
||||||
|
|
||||||
|
///////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ulsch->g,harq_process->f,G>>3); // g is the concatenated code block
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
+179
-2
@@ -38,6 +38,10 @@
|
|||||||
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||||
|
#include "PHY/impl_defs_top.h"
|
||||||
|
#include "PHY/defs_common.h"
|
||||||
|
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||||
|
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||||
|
|
||||||
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
||||||
|
|
||||||
@@ -72,6 +76,7 @@ typedef struct {
|
|||||||
uint64_t dci_pdu[2];
|
uint64_t dci_pdu[2];
|
||||||
} NR_gNB_DCI_ALLOC_t;
|
} NR_gNB_DCI_ALLOC_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t num_dci;
|
uint8_t num_dci;
|
||||||
uint8_t num_pdsch_rnti;
|
uint8_t num_pdsch_rnti;
|
||||||
@@ -79,6 +84,14 @@ typedef struct {
|
|||||||
} NR_gNB_PDCCH;
|
} NR_gNB_PDCCH;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NR_SCH_IDLE,
|
||||||
|
NR_ACTIVE,
|
||||||
|
NR_CBA_ACTIVE,
|
||||||
|
NR_DISABLED
|
||||||
|
} NR_SCH_status_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// Nfapi DLSCH PDU
|
/// Nfapi DLSCH PDU
|
||||||
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
|
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
|
||||||
@@ -114,7 +127,6 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
/// Pointers to 16 HARQ processes for the DLSCH
|
/// Pointers to 16 HARQ processes for the DLSCH
|
||||||
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||||
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
|
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
|
||||||
@@ -160,6 +172,170 @@ typedef struct {
|
|||||||
} NR_gNB_DLSCH_t;
|
} NR_gNB_DLSCH_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/// Nfapi ULSCH PDU
|
||||||
|
nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
|
||||||
|
/// Frame where current HARQ round was sent
|
||||||
|
uint32_t frame;
|
||||||
|
/// Subframe where current HARQ round was sent
|
||||||
|
uint32_t subframe;
|
||||||
|
/// Index of current HARQ round for this DLSCH
|
||||||
|
uint8_t round;
|
||||||
|
/// Last TPC command
|
||||||
|
uint8_t TPC;
|
||||||
|
/// MIMO mode for this DLSCH
|
||||||
|
MIMO_mode_t mimo_mode;
|
||||||
|
/// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK)
|
||||||
|
uint8_t dci_alloc;
|
||||||
|
/// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI)
|
||||||
|
uint8_t rar_alloc;
|
||||||
|
/// Status Flag indicating for this ULSCH (idle,active,disabled)
|
||||||
|
NR_SCH_status_t status;
|
||||||
|
/// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
|
||||||
|
uint8_t subframe_scheduling_flag;
|
||||||
|
/// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator)
|
||||||
|
uint8_t subframe_cba_scheduling_flag;
|
||||||
|
/// PHICH active flag
|
||||||
|
uint8_t phich_active;
|
||||||
|
/// PHICH ACK
|
||||||
|
uint8_t phich_ACK;
|
||||||
|
/// First Allocated RB - previous scheduling. This is needed for PHICH generation which is done after a new scheduling
|
||||||
|
uint16_t previous_first_rb;
|
||||||
|
/// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around
|
||||||
|
uint8_t handled;
|
||||||
|
/// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up)
|
||||||
|
// int calibration_flag;
|
||||||
|
/// delta_TF for power control
|
||||||
|
int32_t delta_TF;
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////// ulsch decoding ///////////////////////
|
||||||
|
/// Transport block size (This is A from 38.212 V15.4.0 section 5.1)
|
||||||
|
uint32_t TBS;
|
||||||
|
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||||
|
uint8_t *b;
|
||||||
|
/// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1)
|
||||||
|
uint32_t B;
|
||||||
|
/// 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];
|
||||||
|
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
|
||||||
|
uint32_t K;
|
||||||
|
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||||
|
uint32_t F;
|
||||||
|
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
|
||||||
|
uint32_t C;
|
||||||
|
/// 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];
|
||||||
|
/// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
|
||||||
|
uint32_t Z;
|
||||||
|
/// 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];
|
||||||
|
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||||
|
uint32_t E;
|
||||||
|
/// Number of soft channel bits after code block concatenation (38.212 V15.4.0 section 5.5)
|
||||||
|
uint32_t G;
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////// DMRS /////////////////////////////
|
||||||
|
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
|
||||||
|
uint8_t n_DMRS;
|
||||||
|
/// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
|
||||||
|
uint8_t n_DMRS2;
|
||||||
|
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling
|
||||||
|
/// This is needed for PHICH generation which
|
||||||
|
/// is done after a new scheduling
|
||||||
|
uint8_t previous_n_DMRS;
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////// UCI multiplexing ///////////////////////
|
||||||
|
/// CQI CRC status
|
||||||
|
uint8_t cqi_crc_status;
|
||||||
|
/// Pointer to CQI data
|
||||||
|
uint8_t o[MAX_CQI_BYTES];
|
||||||
|
/// Format of CQI data
|
||||||
|
UCI_format_t uci_format;
|
||||||
|
/// Length of CQI data under RI=1 assumption(bits)
|
||||||
|
uint8_t Or1;
|
||||||
|
/// Length of CQI data under RI=2 assumption(bits)
|
||||||
|
uint8_t Or2;
|
||||||
|
/// Rank information
|
||||||
|
uint8_t o_RI[2];
|
||||||
|
/// Length of rank information (bits)
|
||||||
|
uint8_t O_RI;
|
||||||
|
/// Pointer to ACK
|
||||||
|
uint8_t o_ACK[4];
|
||||||
|
/// Length of ACK information (bits)
|
||||||
|
uint8_t O_ACK;
|
||||||
|
/// The value of DAI in DCI format 0
|
||||||
|
uint8_t V_UL_DAI;
|
||||||
|
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||||
|
int8_t q[MAX_CQI_PAYLOAD];
|
||||||
|
/// number of coded CQI bits after interleaving
|
||||||
|
uint8_t o_RCC;
|
||||||
|
/// 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)];
|
||||||
|
/// coded ACK bits
|
||||||
|
int16_t q_ACK[MAX_ACK_PAYLOAD];
|
||||||
|
/// coded RI bits
|
||||||
|
int16_t q_RI[MAX_RI_PAYLOAD];
|
||||||
|
/// 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)];
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
} NR_UL_gNB_HARQ_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/// Pointers to 16 HARQ processes for the ULSCH
|
||||||
|
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
|
||||||
|
/// Current HARQ process id
|
||||||
|
int harq_process_id[NR_MAX_SLOTS_PER_FRAME];
|
||||||
|
/// HARQ process mask, indicates which processes are currently active
|
||||||
|
uint16_t harq_mask;
|
||||||
|
/// ACK/NAK Bundling flag
|
||||||
|
uint8_t bundling;
|
||||||
|
/// beta_offset_cqi times 8
|
||||||
|
uint16_t beta_offset_cqi_times8;
|
||||||
|
/// beta_offset_ri times 8
|
||||||
|
uint16_t beta_offset_ri_times8;
|
||||||
|
/// beta_offset_harqack times 8
|
||||||
|
uint16_t beta_offset_harqack_times8;
|
||||||
|
/// Flag to indicate that gNB awaits UE Msg3
|
||||||
|
uint8_t Msg3_active;
|
||||||
|
/// Flag to indicate that gNB should decode UE Msg3
|
||||||
|
uint8_t Msg3_flag;
|
||||||
|
/// Subframe for Msg3
|
||||||
|
uint8_t Msg3_subframe;
|
||||||
|
/// Frame for Msg3
|
||||||
|
uint32_t Msg3_frame;
|
||||||
|
/// Allocated RNTI for this ULSCH
|
||||||
|
uint16_t rnti;
|
||||||
|
/// RNTI type
|
||||||
|
uint8_t rnti_type;
|
||||||
|
/// cyclic shift for DM RS
|
||||||
|
uint8_t cyclicShift;
|
||||||
|
/// for cooperative communication
|
||||||
|
uint8_t cooperation_flag;
|
||||||
|
/// Maximum number of HARQ rounds
|
||||||
|
uint8_t Mlimit;
|
||||||
|
/// Maximum number of LDPC iterations
|
||||||
|
uint8_t max_ldpc_iterations;
|
||||||
|
/// number of iterations used in last LDPC decoding
|
||||||
|
uint8_t last_iteration_cnt;
|
||||||
|
/// num active cba group
|
||||||
|
uint8_t num_active_cba_groups;
|
||||||
|
/// num active cba group
|
||||||
|
uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
|
||||||
|
} NR_gNB_ULSCH_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// \brief Pointers (dynamic) to the received data in the time domain.
|
/// \brief Pointers (dynamic) to the received data in the time domain.
|
||||||
/// - first index: rx antenna [0..nb_antennas_rx[
|
/// - first index: rx antenna [0..nb_antennas_rx[
|
||||||
@@ -399,7 +575,8 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||||
LTE_eNB_PRACH prach_vars;
|
LTE_eNB_PRACH prach_vars;
|
||||||
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
|
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
|
||||||
LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA
|
||||||
|
// LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
||||||
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
|
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
|
||||||
NR_gNB_DLSCH_t *dlsch_MCH;
|
NR_gNB_DLSCH_t *dlsch_MCH;
|
||||||
NR_gNB_DLSCH_t *dlsch_PCH;
|
NR_gNB_DLSCH_t *dlsch_PCH;
|
||||||
|
|||||||
@@ -1054,8 +1054,8 @@ typedef struct {
|
|||||||
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
|
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads
|
||||||
NR_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words
|
||||||
NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX];
|
NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||||
|
|||||||
@@ -87,10 +87,10 @@
|
|||||||
#define NR_MAX_CSET_DURATION 3
|
#define NR_MAX_CSET_DURATION 3
|
||||||
|
|
||||||
#define NR_MAX_NB_RBG 18
|
#define NR_MAX_NB_RBG 18
|
||||||
#define NR_MAX_NB_LAYERS 8
|
#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
|
||||||
#define NR_MAX_NB_CODEWORDS 2
|
#define NR_MAX_NB_CODEWORDS 2
|
||||||
#define NR_MAX_NB_HARQ_PROCESSES 16
|
#define NR_MAX_NB_HARQ_PROCESSES 16
|
||||||
#define NR_MAX_PDSCH_ENCODED_LENGTH 950984
|
#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!)
|
||||||
#define NR_MAX_PDSCH_TBS 3824
|
#define NR_MAX_PDSCH_TBS 3824
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
|
|||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch)
|
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch)
|
||||||
{
|
{
|
||||||
NR_UE_ULSCH_t *ulsch;
|
NR_UE_ULSCH_t *ulsch;
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
|
|||||||
|
|
||||||
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
|
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
|
||||||
|
|
||||||
ue->ulsch[gNB_id] = ulsch;
|
ue->ulsch[thread_id][gNB_id][code_word_idx] = ulsch;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
|
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
|
||||||
@@ -185,7 +185,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int slot_tx = 0; slot_tx < NR_MAX_SLOTS_PER_FRAME; slot_tx++) {
|
for (int slot_tx = 0; slot_tx < NR_MAX_SLOTS_PER_FRAME; slot_tx++) {
|
||||||
ue->ulsch[gNB_id]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES;
|
ue->ulsch[thread_id][gNB_id][code_word_idx]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,9 +202,9 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
|
|||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id)
|
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx)
|
||||||
{
|
{
|
||||||
NR_UE_ULSCH_t *ulsch = ue->ulsch[gNB_id];
|
NR_UE_ULSCH_t *ulsch = ue->ulsch[thread_id][gNB_id][code_word_idx];
|
||||||
|
|
||||||
for (int process_id = 0; process_id < ulsch->number_harq_processes_for_pusch; process_id++) {
|
for (int process_id = 0; process_id < ulsch->number_harq_processes_for_pusch; process_id++) {
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id)
|
|||||||
|
|
||||||
free16(ulsch, sizeof(NR_UE_ULSCH_t));
|
free16(ulsch, sizeof(NR_UE_ULSCH_t));
|
||||||
|
|
||||||
ue->ulsch[gNB_id] = NULL;
|
ue->ulsch[thread_id][gNB_id][code_word_idx] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
|||||||
@@ -83,17 +83,21 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
|
|||||||
/** \brief This function configures uplink HARQ context
|
/** \brief This function configures uplink HARQ context
|
||||||
@param PHY_VARS_NR_UE ue context
|
@param PHY_VARS_NR_UE ue context
|
||||||
@param gNB_id gNodeB identifier
|
@param gNB_id gNodeB identifier
|
||||||
|
@param thread_id RXTX thread index
|
||||||
|
@param code_word_idx code word index
|
||||||
@param number_harq_processes_pusch maximum number of uplink HARQ processes
|
@param number_harq_processes_pusch maximum number of uplink HARQ processes
|
||||||
@returns none */
|
@returns none */
|
||||||
|
|
||||||
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch);
|
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch);
|
||||||
|
|
||||||
/** \brief This function releases uplink HARQ context
|
/** \brief This function releases uplink HARQ context
|
||||||
@param PHY_VARS_NR_UE ue context
|
@param PHY_VARS_NR_UE ue context
|
||||||
@param gNB_id gNodeB identifier
|
@param gNB_id gNodeB identifier
|
||||||
|
@param thread_id RXTX thread index
|
||||||
|
@param code_word_idx code word index
|
||||||
@returns none */
|
@returns none */
|
||||||
|
|
||||||
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id);
|
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx);
|
||||||
|
|
||||||
/** \brief This function stores slot for transmission in HARQ context
|
/** \brief This function stores slot for transmission in HARQ context
|
||||||
@param ulsch uplink context
|
@param ulsch uplink context
|
||||||
|
|||||||
@@ -409,7 +409,7 @@ int main(int argc, char **argv) {
|
|||||||
r_im[i] = malloc(frame_length_complex_samples * sizeof(double));
|
r_im[i] = malloc(frame_length_complex_samples * sizeof(double));
|
||||||
bzero(r_im[i], frame_length_complex_samples * sizeof(double));
|
bzero(r_im[i], frame_length_complex_samples * sizeof(double));
|
||||||
txdata[i] = malloc(frame_length_complex_samples * sizeof(int));
|
txdata[i] = malloc(frame_length_complex_samples * sizeof(int));
|
||||||
bzero(r_re[i], frame_length_complex_samples * sizeof(int));
|
bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pbch_file_fd != NULL) {
|
if (pbch_file_fd != NULL) {
|
||||||
@@ -485,7 +485,7 @@ int main(int argc, char **argv) {
|
|||||||
rel15->nb_layers = Nl;
|
rel15->nb_layers = Nl;
|
||||||
rel15->nb_re_dmrs = nb_re_dmrs;
|
rel15->nb_re_dmrs = nb_re_dmrs;
|
||||||
rel15->transport_block_size = TBS;
|
rel15->transport_block_size = TBS;
|
||||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384);
|
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_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
|
||||||
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
|
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
|
||||||
double errors_bit_uncoded = 0;
|
double errors_bit_uncoded = 0;
|
||||||
|
|||||||
@@ -0,0 +1,744 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include "common/config/config_userapi.h"
|
||||||
|
#include "common/utils/LOG/log.h"
|
||||||
|
#include "common/ran_context.h"
|
||||||
|
|
||||||
|
#include "SIMULATION/TOOLS/sim.h"
|
||||||
|
#include "SIMULATION/RF/rf.h"
|
||||||
|
|
||||||
|
#include "PHY/types.h"
|
||||||
|
#include "PHY/defs_nr_common.h"
|
||||||
|
#include "PHY/defs_nr_UE.h"
|
||||||
|
#include "PHY/defs_gNB.h"
|
||||||
|
#include "PHY/INIT/phy_init.h"
|
||||||
|
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||||
|
#include "PHY/NR_REFSIG/nr_mod_table.h"
|
||||||
|
#include "PHY/MODULATION/modulation_eNB.h"
|
||||||
|
#include "PHY/MODULATION/modulation_UE.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||||
|
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||||
|
|
||||||
|
#include "SCHED_NR/sched_nr.h"
|
||||||
|
|
||||||
|
//#include "PHY/MODULATION/modulation_common.h"
|
||||||
|
//#include "common/config/config_load_configmodule.h"
|
||||||
|
//#include "UTIL/LISTS/list.h"
|
||||||
|
//#include "common/ran_context.h"
|
||||||
|
|
||||||
|
//#define DEBUG_ULSCHSIM
|
||||||
|
|
||||||
|
PHY_VARS_gNB *gNB;
|
||||||
|
PHY_VARS_NR_UE *UE;
|
||||||
|
RAN_CONTEXT_t RC;
|
||||||
|
|
||||||
|
double cpuf;
|
||||||
|
|
||||||
|
// dummy functions
|
||||||
|
int nfapi_mode = 0;
|
||||||
|
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_earfcn) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
int32_t get_uldl_offset(int eutra_bandP) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NR_IF_Module_t *
|
||||||
|
NR_IF_Module_init(int Mod_id) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
||||||
|
const char *msg = s == NULL ? "no comment" : s;
|
||||||
|
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// needed for some functions
|
||||||
|
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
|
||||||
|
uint16_t n_rnti = 0x1234;
|
||||||
|
|
||||||
|
char quantize(double D, double x, unsigned char B) {
|
||||||
|
double qxd;
|
||||||
|
short maxlev;
|
||||||
|
qxd = floor(x / D);
|
||||||
|
maxlev = 1 << (B - 1); //(char)(pow(2,B-1));
|
||||||
|
|
||||||
|
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||||
|
|
||||||
|
if (qxd <= -maxlev)
|
||||||
|
qxd = -maxlev;
|
||||||
|
else if (qxd >= maxlev)
|
||||||
|
qxd = maxlev - 1;
|
||||||
|
|
||||||
|
return ((char) qxd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
char c;
|
||||||
|
int i,sf; //,j,l,aa;
|
||||||
|
double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0;
|
||||||
|
double snr_step = 0.1;
|
||||||
|
uint8_t snr1set = 0;
|
||||||
|
int **txdata;
|
||||||
|
double **s_re, **s_im, **r_re, **r_im;
|
||||||
|
// int sync_pos, sync_pos_slot;
|
||||||
|
// FILE *rx_frame_file;
|
||||||
|
FILE *output_fd = NULL;
|
||||||
|
uint8_t write_output_file = 0;
|
||||||
|
// int subframe_offset;
|
||||||
|
// char fname[40], vname[40];
|
||||||
|
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
|
||||||
|
uint8_t transmission_mode = 1, n_tx = 1, n_rx = 1;
|
||||||
|
uint16_t Nid_cell = 0;
|
||||||
|
channel_desc_t *gNB2UE;
|
||||||
|
uint8_t extended_prefix_flag = 0;
|
||||||
|
int8_t interf1 = -21, interf2 = -21;
|
||||||
|
FILE *input_fd = NULL, *pbch_file_fd = NULL;
|
||||||
|
//char input_val_str[50],input_val_str2[50];
|
||||||
|
//uint16_t NB_RB=25;
|
||||||
|
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
|
||||||
|
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
|
||||||
|
unsigned char frame_type = 0;
|
||||||
|
unsigned char pbch_phase = 0;
|
||||||
|
int frame = 0, subframe = 0;
|
||||||
|
int frame_length_complex_samples;
|
||||||
|
//int frame_length_complex_samples_no_prefix;
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms;
|
||||||
|
//nfapi_nr_config_request_t *gNB_config;
|
||||||
|
// uint8_t Kmimo = 0;
|
||||||
|
uint32_t Nsoft = 0;
|
||||||
|
double sigma;
|
||||||
|
unsigned char qbits = 8;
|
||||||
|
int ret;
|
||||||
|
//int run_initial_sync=0;
|
||||||
|
int loglvl = OAILOG_WARNING;
|
||||||
|
float target_error_rate = 0.01;
|
||||||
|
uint64_t SSB_positions=0x01;
|
||||||
|
uint16_t nb_symb_sch = 12;
|
||||||
|
uint16_t nb_rb = 50;
|
||||||
|
uint8_t Imcs = 9;
|
||||||
|
|
||||||
|
cpuf = get_cpu_freq_GHz();
|
||||||
|
|
||||||
|
if (load_configmodule(argc, argv) == 0) {
|
||||||
|
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//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) {
|
||||||
|
switch (c) {
|
||||||
|
case 'f':
|
||||||
|
write_output_file = 1;
|
||||||
|
output_fd = fopen(optarg, "w");
|
||||||
|
|
||||||
|
if (output_fd == NULL) {
|
||||||
|
printf("Error opening %s\n", optarg);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
frame_type = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
switch ((char) *optarg) {
|
||||||
|
case 'A':
|
||||||
|
channel_model = SCM_A;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
channel_model = SCM_B;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'C':
|
||||||
|
channel_model = SCM_C;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
channel_model = SCM_D;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'E':
|
||||||
|
channel_model = EPA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
channel_model = EVA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'G':
|
||||||
|
channel_model = ETU;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
msg("Unsupported channel model!\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
interf1 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
interf2 = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
n_trials = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
snr0 = atof(optarg);
|
||||||
|
msg("Setting SNR0 to %f\n", snr0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
snr1 = atof(optarg);
|
||||||
|
snr1set = 1;
|
||||||
|
msg("Setting SNR1 to %f\n", snr1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
extended_prefix_flag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case 'r':
|
||||||
|
ricean_factor = pow(10,-.1*atof(optarg));
|
||||||
|
if (ricean_factor>1) {
|
||||||
|
printf("Ricean factor must be between 0 and 1\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
|
case 'y':
|
||||||
|
n_tx = atoi(optarg);
|
||||||
|
|
||||||
|
if ((n_tx == 0) || (n_tx > 2)) {
|
||||||
|
msg("Unsupported number of tx antennas %d\n", n_tx);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
n_rx = atoi(optarg);
|
||||||
|
|
||||||
|
if ((n_rx == 0) || (n_rx > 2)) {
|
||||||
|
msg("Unsupported number of rx antennas %d\n", n_rx);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
SSB_positions = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
Nid_cell = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
N_RB_DL = atoi(optarg);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
pbch_phase = atoi(optarg);
|
||||||
|
|
||||||
|
if (pbch_phase > 3)
|
||||||
|
printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase);
|
||||||
|
|
||||||
|
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("-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("-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");
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logInit();
|
||||||
|
set_glog(loglvl);
|
||||||
|
T_stdout = 1;
|
||||||
|
|
||||||
|
if (snr1set == 0)
|
||||||
|
snr1 = snr0 + 10;
|
||||||
|
|
||||||
|
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
|
||||||
|
61.44e6, //N_RB2sampling_rate(N_RB_DL),
|
||||||
|
40e6, //N_RB2channel_bandwidth(N_RB_DL),
|
||||||
|
0, 0, 0);
|
||||||
|
|
||||||
|
if (gNB2UE == NULL) {
|
||||||
|
msg("Problem generating channel model. Exiting.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **));
|
||||||
|
RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
|
||||||
|
RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
|
||||||
|
gNB = RC.gNB[0][0];
|
||||||
|
//gNB_config = &gNB->gNB_config;
|
||||||
|
|
||||||
|
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||||
|
frame_parms->nb_antennas_tx = n_tx;
|
||||||
|
frame_parms->nb_antennas_rx = n_rx;
|
||||||
|
frame_parms->N_RB_DL = N_RB_DL;
|
||||||
|
frame_parms->N_RB_UL = N_RB_UL;
|
||||||
|
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||||
|
|
||||||
|
crcTableInit();
|
||||||
|
|
||||||
|
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions);
|
||||||
|
|
||||||
|
phy_init_nr_gNB(gNB, 0, 0);
|
||||||
|
//init_eNB_afterRU();
|
||||||
|
|
||||||
|
frame_length_complex_samples = frame_parms->samples_per_subframe;
|
||||||
|
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
|
||||||
|
s_re = malloc(2 * sizeof(double *));
|
||||||
|
s_im = malloc(2 * sizeof(double *));
|
||||||
|
r_re = malloc(2 * sizeof(double *));
|
||||||
|
r_im = malloc(2 * sizeof(double *));
|
||||||
|
txdata = malloc(2 * sizeof(int * ));
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
s_re[i] = malloc(frame_length_complex_samples * sizeof(double));
|
||||||
|
bzero(s_re[i], frame_length_complex_samples * sizeof(double));
|
||||||
|
s_im[i] = malloc(frame_length_complex_samples * sizeof(double));
|
||||||
|
bzero(s_im[i], frame_length_complex_samples * sizeof(double));
|
||||||
|
r_re[i] = malloc(frame_length_complex_samples * sizeof(double));
|
||||||
|
bzero(r_re[i], frame_length_complex_samples * sizeof(double));
|
||||||
|
r_im[i] = malloc(frame_length_complex_samples * sizeof(double));
|
||||||
|
bzero(r_im[i], frame_length_complex_samples * sizeof(double));
|
||||||
|
txdata[i] = malloc(frame_length_complex_samples * sizeof(int));
|
||||||
|
bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbch_file_fd != NULL) {
|
||||||
|
load_pbch_desc(pbch_file_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for (int k=0; k<2; k++) {
|
||||||
|
// Create transport channel structures for 2 transport blocks (MIMO)
|
||||||
|
for (i=0; i<2; i++) {
|
||||||
|
gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config);
|
||||||
|
|
||||||
|
if (!gNB->dlsch[k][i]) {
|
||||||
|
printf("Can't get eNB dlsch structures\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
gNB->dlsch[k][i]->Nsoft = 10;
|
||||||
|
gNB->dlsch[k][i]->rnti = n_rnti+k;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
//configure UE
|
||||||
|
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||||
|
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||||
|
|
||||||
|
//phy_init_nr_top(frame_parms);
|
||||||
|
if (init_nr_ue_signal(UE, 1, 0) != 0) {
|
||||||
|
printf("Error at UE NR initialisation\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//nr_init_frame_parms_ue(&UE->frame_parms);
|
||||||
|
//init_nr_ue_transport(UE, 0);
|
||||||
|
for (sf = 0; sf < 2; sf++) {
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
|
||||||
|
UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0);
|
||||||
|
|
||||||
|
if (!UE->ulsch[sf][0][i]) {
|
||||||
|
printf("Can't get ue ulsch structures\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
|
||||||
|
UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
|
||||||
|
|
||||||
|
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
|
||||||
|
//time_stats_t *rm_stats, *te_stats, *i_stats;
|
||||||
|
uint8_t is_crnti = 0, llr8_flag = 0;
|
||||||
|
unsigned int TBS = 8424;
|
||||||
|
unsigned int available_bits;
|
||||||
|
uint8_t nb_re_dmrs = 6;
|
||||||
|
uint16_t length_dmrs = 1;
|
||||||
|
unsigned char mod_order;
|
||||||
|
uint8_t Nl = 1;
|
||||||
|
uint8_t rvidx = 0;
|
||||||
|
uint8_t UE_id = 1;
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0];
|
||||||
|
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
||||||
|
|
||||||
|
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0];
|
||||||
|
|
||||||
|
ulsch_ue->nb_re_dmrs = nb_re_dmrs; //[adk] A HOT FIX until cearting nfapi_nr_ul_config_ulsch_pdu_rel15_t
|
||||||
|
|
||||||
|
mod_order = nr_get_Qm(Imcs, 1);
|
||||||
|
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);
|
||||||
|
printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
|
||||||
|
|
||||||
|
/////////// setting rel15_ul parameters ///////////
|
||||||
|
rel15_ul->number_rbs = nb_rb;
|
||||||
|
rel15_ul->number_symbols = nb_symb_sch;
|
||||||
|
rel15_ul->Qm = mod_order;
|
||||||
|
rel15_ul->mcs = Imcs;
|
||||||
|
rel15_ul->rv = rvidx;
|
||||||
|
rel15_ul->n_layers = Nl;
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
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);
|
||||||
|
unsigned int errors_bit_uncoded = 0;
|
||||||
|
// unsigned char *estimated_output;
|
||||||
|
unsigned char *estimated_output_bit;
|
||||||
|
unsigned char *test_input_bit;
|
||||||
|
unsigned int errors_bit = 0;
|
||||||
|
|
||||||
|
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||||
|
// estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||||
|
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||||
|
|
||||||
|
unsigned char *test_input;
|
||||||
|
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
|
||||||
|
|
||||||
|
for (i = 0; i < TBS / 8; i++)
|
||||||
|
test_input[i] = (unsigned char) rand();
|
||||||
|
|
||||||
|
// estimated_output = ulsch_gNB->harq_processes[harq_pid]->b;
|
||||||
|
|
||||||
|
/////////////////////////[adk] preparing UL harq_process parameters/////////////////////////
|
||||||
|
///////////
|
||||||
|
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||||
|
|
||||||
|
if (harq_process_ul_ue) {
|
||||||
|
|
||||||
|
harq_process_ul_ue->mcs = Imcs;
|
||||||
|
harq_process_ul_ue->Nl = Nl;
|
||||||
|
harq_process_ul_ue->nb_rb = nb_rb;
|
||||||
|
harq_process_ul_ue->nb_symbols = nb_symb_sch;
|
||||||
|
harq_process_ul_ue->rvidx = rvidx;
|
||||||
|
harq_process_ul_ue->TBS = TBS;
|
||||||
|
harq_process_ul_ue->a = &test_input[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
///////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef DEBUG_ULSCHSIM
|
||||||
|
for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*for (int i=0; i<TBS/8; i++)
|
||||||
|
printf("test input[%d]=%d \n",i,test_input[i]);*/
|
||||||
|
|
||||||
|
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
|
||||||
|
// generate signal
|
||||||
|
|
||||||
|
/////////////////////////[adk] ULSCH coding/////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
if (input_fd == NULL) {
|
||||||
|
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||||
|
n_errors = 0;
|
||||||
|
n_false_positive = 0;
|
||||||
|
|
||||||
|
for (trial = 0; trial < n_trials; trial++) {
|
||||||
|
|
||||||
|
errors_bit_uncoded = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < available_bits; i++) {
|
||||||
|
|
||||||
|
#ifdef DEBUG_CODER
|
||||||
|
if ((i&0xf)==0)
|
||||||
|
printf("\ne %d..%d: ",i,i+15);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
if (i<16){
|
||||||
|
printf("dlsch_encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
|
||||||
|
printf("ulsch_encoder output f[%d] = %d\n",i,ulsch_ue->harq_processes[0]->f[i]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ulsch_ue->harq_processes[0]->f[i] == 0)
|
||||||
|
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
|
||||||
|
else
|
||||||
|
modulated_input[i] = -1.0; ///sqrt(2);
|
||||||
|
|
||||||
|
//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
|
||||||
|
//SNR =10;
|
||||||
|
|
||||||
|
SNR_lin = pow(10, SNR / 10.0);
|
||||||
|
sigma = 1.0 / sqrt(2 * SNR_lin);
|
||||||
|
#if 1
|
||||||
|
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);
|
||||||
|
#endif
|
||||||
|
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
|
||||||
|
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
|
||||||
|
//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
|
||||||
|
|
||||||
|
//channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
|
||||||
|
|
||||||
|
//if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]);
|
||||||
|
|
||||||
|
//Uncoded BER
|
||||||
|
if (channel_output_fixed[i] < 0)
|
||||||
|
channel_output_uncoded[i] = 1; //QPSK demod
|
||||||
|
else
|
||||||
|
channel_output_uncoded[i] = 0;
|
||||||
|
|
||||||
|
if (channel_output_uncoded[i] != ulsch_ue->harq_processes[harq_pid]->f[i])
|
||||||
|
errors_bit_uncoded = errors_bit_uncoded + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (errors_bit_uncoded>10)
|
||||||
|
printf("errors bits uncoded %u\n", errors_bit_uncoded);
|
||||||
|
|
||||||
|
#ifdef DEBUG_CODER
|
||||||
|
printf("\n");
|
||||||
|
exit(-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms,
|
||||||
|
frame, nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||||
|
|
||||||
|
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||||
|
n_errors++;
|
||||||
|
|
||||||
|
//count errors
|
||||||
|
errors_bit = 0;
|
||||||
|
|
||||||
|
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] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||||
|
|
||||||
|
if (estimated_output_bit[i] != test_input_bit[i]) {
|
||||||
|
errors_bit++;
|
||||||
|
//printf("estimated bits error occurs @%d ",i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors_bit > 0) {
|
||||||
|
n_false_positive++;
|
||||||
|
if (n_trials == 1)
|
||||||
|
printf("errors_bit %d (trial %d)\n", errors_bit, trial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("*****************************************\n");
|
||||||
|
printf("SNR %f, BLER %f (false positive %f)\n", SNR,
|
||||||
|
(float) n_errors / (float) n_trials,
|
||||||
|
(float) n_false_positive / (float) n_trials);
|
||||||
|
printf("*****************************************\n");
|
||||||
|
|
||||||
|
if ((float) n_errors / (float) n_trials < target_error_rate) {
|
||||||
|
printf("PUSCH test OK\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
|
||||||
|
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||||
|
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/
|
||||||
|
|
||||||
|
//TODO: loop over slots
|
||||||
|
/*for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||||
|
if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
|
||||||
|
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||||
|
txdata[aa],
|
||||||
|
frame_parms->ofdm_symbol_size,
|
||||||
|
12,
|
||||||
|
frame_parms->nb_prefix_samples,
|
||||||
|
CYCLIC_PREFIX);
|
||||||
|
} else {
|
||||||
|
nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
|
||||||
|
txdata[aa],
|
||||||
|
14,
|
||||||
|
frame_parms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
|
||||||
|
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||||
|
LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
|
||||||
|
|
||||||
|
|
||||||
|
for (i=0; i<frame_length_complex_samples; i++) {
|
||||||
|
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||||
|
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
|
||||||
|
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
|
||||||
|
printf("----------------------\n");
|
||||||
|
printf("freeing codeword %d\n", i);
|
||||||
|
printf("----------------------\n");
|
||||||
|
|
||||||
|
printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA
|
||||||
|
|
||||||
|
free_gNB_ulsch(gNB->ulsch[0][i]);
|
||||||
|
|
||||||
|
printf("gNB ulsch[%d][%d]\n",UE_id, i);
|
||||||
|
|
||||||
|
free_gNB_ulsch(gNB->ulsch[UE_id][i]);
|
||||||
|
|
||||||
|
for (sf = 0; sf < 2; sf++) {
|
||||||
|
|
||||||
|
printf("UE ulsch[%d][0][%d]\n", sf, i);
|
||||||
|
|
||||||
|
if (UE->ulsch[sf][0][i])
|
||||||
|
free_nr_ue_ulsch(UE->ulsch[sf][0][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
free(s_re[i]);
|
||||||
|
free(s_im[i]);
|
||||||
|
free(r_re[i]);
|
||||||
|
free(r_im[i]);
|
||||||
|
free(txdata[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(s_re);
|
||||||
|
free(s_im);
|
||||||
|
free(r_re);
|
||||||
|
free(r_im);
|
||||||
|
free(txdata);
|
||||||
|
|
||||||
|
if (output_fd)
|
||||||
|
fclose(output_fd);
|
||||||
|
|
||||||
|
if (input_fd)
|
||||||
|
fclose(input_fd);
|
||||||
|
|
||||||
|
return (n_errors);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -54,6 +54,8 @@
|
|||||||
int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
|
int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
|
||||||
{
|
{
|
||||||
int gNB_id = 0;
|
int gNB_id = 0;
|
||||||
|
int thread_number = 0;
|
||||||
|
int code_word_idx = 0;
|
||||||
int harq_pid = 0;
|
int harq_pid = 0;
|
||||||
int ndi = 1;
|
int ndi = 1;
|
||||||
uint8_t rnti_type = _C_RNTI_;
|
uint8_t rnti_type = _C_RNTI_;
|
||||||
@@ -61,7 +63,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
|
|||||||
|
|
||||||
printf("\nHARQ Uplink \n");
|
printf("\nHARQ Uplink \n");
|
||||||
|
|
||||||
config_uplink_harq_process(phy_vars_ue , gNB_id, NR_DEFAULT_DLSCH_HARQ_PROCESSES);
|
config_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx, NR_DEFAULT_DLSCH_HARQ_PROCESSES);
|
||||||
|
|
||||||
NR_UE_ULSCH_t *ulsch_harq = phy_vars_ue->ulsch[gNB_id];
|
NR_UE_ULSCH_t *ulsch_harq = phy_vars_ue->ulsch[gNB_id];
|
||||||
|
|
||||||
@@ -91,7 +93,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_uplink_harq_process(phy_vars_ue , gNB_id);
|
release_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,11 +58,7 @@ extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PHYSIM
|
|
||||||
#define NB_INST 1
|
|
||||||
#else
|
|
||||||
extern unsigned char NB_INST;
|
extern unsigned char NB_INST;
|
||||||
#endif
|
|
||||||
extern unsigned char NB_eNB_INST;
|
extern unsigned char NB_eNB_INST;
|
||||||
extern unsigned char NB_UE_INST;
|
extern unsigned char NB_UE_INST;
|
||||||
extern unsigned char NB_RN_INST;
|
extern unsigned char NB_RN_INST;
|
||||||
|
|||||||
@@ -44,17 +44,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue;
|
|||||||
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
|
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
|
||||||
|
|
||||||
|
|
||||||
#ifndef PHY_EMUL
|
|
||||||
#ifndef PHYSIM
|
|
||||||
//#define NB_INST 1
|
|
||||||
#else
|
|
||||||
extern unsigned char NB_INST;
|
extern unsigned char NB_INST;
|
||||||
#endif
|
|
||||||
extern unsigned char NB_eNB_INST;
|
extern unsigned char NB_eNB_INST;
|
||||||
extern unsigned char NB_UE_INST;
|
extern unsigned char NB_UE_INST;
|
||||||
extern unsigned short NODE_ID[1];
|
extern unsigned short NODE_ID[1];
|
||||||
extern void* bigphys_malloc(int);
|
extern void* bigphys_malloc(int);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//CONSTANTS
|
//CONSTANTS
|
||||||
|
|||||||
@@ -43,17 +43,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue;
|
|||||||
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
|
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
|
||||||
|
|
||||||
|
|
||||||
#ifndef PHY_EMUL
|
|
||||||
#ifndef PHYSIM
|
|
||||||
//#define NB_INST 1
|
|
||||||
#else
|
|
||||||
extern unsigned char NB_INST;
|
extern unsigned char NB_INST;
|
||||||
#endif
|
|
||||||
extern unsigned char NB_eNB_INST;
|
extern unsigned char NB_eNB_INST;
|
||||||
extern unsigned char NB_UE_INST;
|
extern unsigned char NB_UE_INST;
|
||||||
extern unsigned short NODE_ID[1];
|
extern unsigned short NODE_ID[1];
|
||||||
extern void* bigphys_malloc(int);
|
extern void* bigphys_malloc(int);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//CONSTANTS
|
//CONSTANTS
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
||||||
#define OPENAIRINTERFACE5G_LIMITS_H_
|
#define OPENAIRINTERFACE5G_LIMITS_H_
|
||||||
|
|
||||||
#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
|
#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/
|
||||||
# define NUMBER_OF_eNB_MAX 1
|
# define NUMBER_OF_eNB_MAX 1
|
||||||
# define NUMBER_OF_gNB_MAX 1
|
# define NUMBER_OF_gNB_MAX 1
|
||||||
# define NUMBER_OF_RU_MAX 2
|
# define NUMBER_OF_RU_MAX 2
|
||||||
# define NUMBER_OF_NR_RU_MAX 2
|
# define NUMBER_OF_NR_RU_MAX 2
|
||||||
|
# ifndef PHYSIM
|
||||||
# ifndef UE_EXPANSION
|
# ifndef UE_EXPANSION
|
||||||
# define NUMBER_OF_UE_MAX 16
|
# define NUMBER_OF_UE_MAX 16
|
||||||
# define NUMBER_OF_NR_UE_MAX 16
|
# define NUMBER_OF_NR_UE_MAX 16
|
||||||
@@ -18,6 +19,12 @@
|
|||||||
# define NUMBER_OF_CONNECTED_gNB_MAX 1
|
# define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
|
# define NUMBER_OF_UE_MAX 1
|
||||||
|
# define NUMBER_OF_NR_UE_MAX 1
|
||||||
|
# define NUMBER_OF_CONNECTED_eNB_MAX 1
|
||||||
|
# define NUMBER_OF_CONNECTED_gNB_MAX 1
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
# define NUMBER_OF_eNB_MAX 7
|
# define NUMBER_OF_eNB_MAX 7
|
||||||
# define NUMBER_OF_gNB_MAX 7
|
# define NUMBER_OF_gNB_MAX 7
|
||||||
# define NUMBER_OF_RU_MAX 32
|
# define NUMBER_OF_RU_MAX 32
|
||||||
|
|||||||
Reference in New Issue
Block a user