Merge remote-tracking branch 'origin/nr_pdsch' into nr-polar-encoder-optimizations
Conflicts: cmake_targets/CMakeLists.txt openair1/PHY/CODING/TESTBENCH/ldpctest.c openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c openair1/PHY/CODING/nr_compute_tbs.c openair1/PHY/CODING/nr_segmentation.c openair1/PHY/MODULATION/slot_fep_nr.c openair1/PHY/NR_REFSIG/nr_dmrs_rx.c openair1/PHY/NR_TRANSPORT/nr_dci_tools.c openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c openair1/PHY/NR_UE_TRANSPORT/dci_nr.c openair1/SCHED_NR/fapi_nr_l1.c openair1/SCHED_NR/nr_ru_procedures.c openair1/SCHED_NR/phy_procedures_nr_common.c openair1/SCHED_NR/phy_procedures_nr_gNB.c openair1/SCHED_NR_UE/defs.h openair1/SCHED_NR_UE/fapi_nr_ue_l1.c openair1/SCHED_NR_UE/phy_procedures_nr_ue.c openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c targets/RT/USER/nr-gnb.c targets/RT/USER/nr-ru.c targets/RT/USER/nr-ue.c
This commit is contained in:
@@ -252,7 +252,7 @@ case $key in
|
||||
VM_NAME=ci-phy-sim
|
||||
ARCHIVES_LOC=phy_sim
|
||||
LOG_PATTERN=.Rel15.txt
|
||||
NB_PATTERN_FILES=6
|
||||
NB_PATTERN_FILES=7
|
||||
BUILD_OPTIONS="--phy_simulators"
|
||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||
NBARGS=$[$NBARGS+256]
|
||||
@@ -330,7 +330,7 @@ case $key in
|
||||
VM_NAME=ci-phy-sim
|
||||
ARCHIVES_LOC=phy_sim
|
||||
LOG_PATTERN=.Rel15.txt
|
||||
NB_PATTERN_FILES=6
|
||||
NB_PATTERN_FILES=7
|
||||
BUILD_OPTIONS="--phy_simulators"
|
||||
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
|
||||
NBARGS=$[$NBARGS+256]
|
||||
|
||||
@@ -411,6 +411,10 @@ function report_build {
|
||||
then
|
||||
summary_table_row "PBCH Test - Release 15" ./archives/phy_sim/nr_pbchsim.Rel15.txt "Built target nr_pbchsim" ./phy_sim_row6.html
|
||||
fi
|
||||
if [ -f ./archives/phy_sim/nr_dlschsim.Rel15.txt ]
|
||||
then
|
||||
summary_table_row "DLSCH Test - Release 15" ./archives/phy_sim/nr_dlschsim.Rel15.txt "Built target nr_dlschsim" ./phy_sim_row7.html
|
||||
fi
|
||||
summary_table_footer
|
||||
|
||||
|
||||
|
||||
@@ -290,6 +290,8 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
|
||||
|
||||
add_list2_option(RRC_ASN1_VERSION "Rel15" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA")
|
||||
|
||||
Message("RRC_ASN1_VERSION is ${RRC_ASN1_VERSION}")
|
||||
|
||||
if (${RRC_ASN1_VERSION} STREQUAL "Rel8")
|
||||
make_version(RRC_VERSION 8 6 0)
|
||||
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn)
|
||||
@@ -366,9 +368,9 @@ execute_process(COMMAND mkdir -p ${NR_RRC_FULL_DIR}
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET)
|
||||
|
||||
if (NOT ${ret} STREQUAL 0)
|
||||
message(FATAL_ERROR "${ret}: error")
|
||||
endif (NOT ${ret} STREQUAL 0)
|
||||
#if (NOT ${ret} STREQUAL 0)
|
||||
# message(FATAL_ERROR "${ret}: error")
|
||||
#endif (NOT ${ret} STREQUAL 0)
|
||||
|
||||
file(GLOB nr_rrc_source ${NR_RRC_FULL_DIR}/*.c)
|
||||
file(GLOB nr_rrc_h ${NR_RRC_FULL_DIR}/*.h)
|
||||
@@ -1184,6 +1186,7 @@ set(PHY_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/nr_compute_tbs.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/nr_rate_matching.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
|
||||
@@ -1304,6 +1307,11 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pbch.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dci_tools.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_coding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
@@ -1333,6 +1341,10 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dmrs_nr.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_dlsch_demodulation.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_TRANSPORT/nr_tbs_tools.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_prach.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
||||
@@ -1343,6 +1355,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
@@ -1523,14 +1536,6 @@ set(NR_L2_SRC_UE
|
||||
${NR_UE_RRC_DIR}/L2_interface_ue.c
|
||||
${NR_UE_RRC_DIR}/main_ue.c
|
||||
${NR_UE_RRC_DIR}/rrc_UE.c
|
||||
# ${NR_UE_RRC_DIR}/mac_vars.c
|
||||
#${RRC_DIR}/rrc_UE.c
|
||||
)
|
||||
|
||||
set(L2_NR_SRC_UE
|
||||
${NR_UE_RRC_DIR}/L2_interface_ue.c
|
||||
${NR_UE_RRC_DIR}/main_ue.c
|
||||
${NR_UE_RRC_DIR}/rrc_UE.c
|
||||
)
|
||||
|
||||
set (MAC_SRC
|
||||
@@ -1636,26 +1641,27 @@ set ( NR_LTE_UE_REUSE_SRC
|
||||
${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
|
||||
#${OPENAIR1_DIR}/SCHED_UE/phy_procedures_lte_ue.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch_common.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch_common.c
|
||||
|
||||
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach_common.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
|
||||
#${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach_common.c
|
||||
# ${OPENAIR1_DIR}/PHY/INIT/lte_init_ue.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/crc_byte.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/viterbi.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c
|
||||
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c
|
||||
# ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
|
||||
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_est_freq_offset.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
|
||||
#${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c
|
||||
)
|
||||
|
||||
@@ -2555,6 +2561,9 @@ target_link_libraries(polartest SIMU PHY PHY_NR PHY_COMMON m ${ATLAS_LIBRARIES})
|
||||
add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c)
|
||||
target_link_libraries(ldpctest SIMU PHY PHY_NR m ${ATLAS_LIBRARIES})
|
||||
|
||||
add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c ${T_SOURCE})
|
||||
target_link_libraries(nr_dlschsim -Wl,--start-group UTIL SIMU PHY PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
|
||||
|
||||
add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ${T_SOURCE})
|
||||
target_link_libraries(nr_pbchsim -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)
|
||||
|
||||
|
||||
@@ -692,7 +692,7 @@ function main() {
|
||||
echo_info "Compiling unitary tests simulators"
|
||||
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
||||
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
||||
simlist="dlsim ulsim polartest ldpctest nr_pbchsim"
|
||||
simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim"
|
||||
for f in $simlist ; do
|
||||
compilations \
|
||||
phy_simulators $f \
|
||||
|
||||
@@ -191,6 +191,27 @@ typedef struct {
|
||||
#define NFAPI_NR_SCH_CONFIG_SS_PBCH_BLOCK_POWER 0x5023
|
||||
#define NFAPI_NR_SCH_CONFIG_N_SSB_CRB 0x5024
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t data_scrambling_id;
|
||||
nfapi_uint16_tlv_t dmrs_typeA_position;
|
||||
nfapi_uint16_tlv_t dmrs_additional_position;
|
||||
nfapi_uint16_tlv_t dmrs_type;
|
||||
nfapi_uint16_tlv_t dmrs_max_length;
|
||||
nfapi_uint16_tlv_t mapping_type;
|
||||
nfapi_uint16_tlv_t resource_allocation;
|
||||
nfapi_uint16_tlv_t time_allocation_list;
|
||||
nfapi_uint16_tlv_t mcs_table;
|
||||
nfapi_uint16_tlv_t aggregation_factor;
|
||||
nfapi_uint16_tlv_t prb_bundling_type;
|
||||
nfapi_uint16_tlv_t rbg_size;
|
||||
nfapi_uint16_tlv_t vrb_to_prb_interleaver;
|
||||
nfapi_uint16_tlv_t code_block_groug_transmission;
|
||||
nfapi_uint16_tlv_t x_overhead;
|
||||
nfapi_uint16_tlv_t max_dci_codewords;
|
||||
|
||||
} nfapi_nr_pdsch_config_t;
|
||||
#define NFAPI_NR_PDSCH_CONFIG_TAG
|
||||
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t prach_RootSequenceIndex; ///// L1 parameter 'PRACHRootSequenceIndex'
|
||||
@@ -205,12 +226,6 @@ typedef struct {
|
||||
nfapi_uint16_tlv_t preambleReceivedTargetPower;
|
||||
} nfapi_nr_rach_config_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t dmrs_TypeA_Position; ///// Position of (first) DL DM-RS
|
||||
nfapi_uint16_tlv_t TimeDomainResourceAllocation_k0; ///// L1 parameter 'K0'
|
||||
nfapi_uint16_tlv_t TimeDomainResourceAllocation_mappingType; ///// L1 parameter 'Mapping-type'
|
||||
} nfapi_nr_pdsch_config_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint16_tlv_t groupHoppingEnabledTransformPrecoding; ///// L1 parameter 'Group-hopping-enabled-Transform-precoding'
|
||||
nfapi_uint16_tlv_t msg3_DeltaPreamble; ///// L1 parameter 'Delta-preamble-msg3'
|
||||
@@ -269,8 +284,8 @@ typedef struct {
|
||||
nfapi_nr_subframe_config_t subframe_config;
|
||||
nfapi_nr_rf_config_t rf_config;
|
||||
nfapi_nr_sch_config_t sch_config;
|
||||
nfapi_nr_rach_config_t rach_config;
|
||||
nfapi_nr_pdsch_config_t pdsch_config;
|
||||
nfapi_nr_rach_config_t rach_config;
|
||||
nfapi_nr_pusch_config_t pusch_config;
|
||||
nfapi_nr_pucch_config_t pucch_config;
|
||||
nfapi_nr_pdcch_config_t pdcch_config;
|
||||
@@ -321,6 +336,13 @@ typedef enum {
|
||||
NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
|
||||
} nfapi_nr_search_space_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0=0,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0A,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_2
|
||||
} nfapi_nr_common_search_space_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=0,
|
||||
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2,
|
||||
@@ -342,6 +364,44 @@ typedef enum {
|
||||
NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS
|
||||
} nfapi_nr_coreset_precoder_granularity_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A=0,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C,
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST
|
||||
} nfapi_nr_pdsch_time_domain_alloc_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_MAPPING_TYPE_A=0,
|
||||
NFAPI_NR_PDSCH_MAPPING_TYPE_B
|
||||
} nfapi_nr_pdsch_mapping_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PDSCH_RBG_CONFIG_TYPE1=0,
|
||||
NFAPI_NR_PDSCH_RBG_CONFIG_TYPE2
|
||||
} nfapi_nr_pdsch_rbg_config_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PRG_GRANULARITY_2=2,
|
||||
NFAPI_NR_PRG_GRANULARITY_4=4,
|
||||
NFAPI_NR_PRG_GRANULARITY_WIDEBAND
|
||||
} nfapi_nr_prg_granularity_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_PRB_BUNDLING_TYPE_STATIC=0,
|
||||
NFAPI_NR_PRB_BUNDLING_TYPE_DYNAMIC
|
||||
} nfapi_nr_prb_bundling_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_MCS_TABLE_QAM64_LOW_SE=0,
|
||||
NFAPI_NR_MCS_TABLE_QAM256
|
||||
} nfapi_nr_pdsch_mcs_table_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_DMRS_TYPE1=0,
|
||||
NFAPI_NR_DMRS_TYPE2
|
||||
} nfapi_nr_dmrs_type_e;
|
||||
|
||||
// P7 Sub Structures
|
||||
|
||||
typedef struct {
|
||||
@@ -445,13 +505,14 @@ typedef struct{
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
uint8_t rnti;
|
||||
uint16_t rnti;
|
||||
uint8_t rnti_type;
|
||||
uint8_t dci_format;
|
||||
/// Number of CRB in BWP that this DCI configures
|
||||
uint16_t n_RB_BWP;
|
||||
uint8_t config_type;
|
||||
uint8_t search_space_type;
|
||||
uint8_t search_space_type;
|
||||
uint8_t common_search_space_type;
|
||||
uint8_t aggregation_level;
|
||||
uint8_t n_rb;
|
||||
uint8_t n_symb;
|
||||
@@ -484,14 +545,50 @@ typedef struct {
|
||||
} nfapi_nr_dl_config_bch_pdu;
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
nfapi_nr_search_space_t sib1searchSpace;
|
||||
nfapi_nr_coreset_t sib1ControlResourceSets;
|
||||
nfapi_nr_search_space_t sibssearchSpace;
|
||||
nfapi_nr_coreset_t sibsControlResourceSets;
|
||||
nfapi_nr_search_space_t ra_SearchSpace;
|
||||
nfapi_nr_coreset_t ra_ControlResourceSets;
|
||||
nfapi_tl_t tl;
|
||||
uint16_t length;
|
||||
uint8_t pdu_index;
|
||||
uint16_t rnti;
|
||||
uint16_t nb_mod_symbols;
|
||||
uint8_t time_allocation_type;
|
||||
uint8_t freq_allocation_type;
|
||||
uint8_t start_prb;
|
||||
uint8_t n_prb;
|
||||
uint8_t start_symbol;
|
||||
uint8_t nb_symbols;
|
||||
uint8_t mcs_idx;
|
||||
uint8_t ndi;
|
||||
uint8_t nb_codewords;
|
||||
uint8_t nb_layers;
|
||||
uint16_t coding_rate;
|
||||
uint8_t modulation;
|
||||
uint8_t modulation_order;
|
||||
uint16_t transport_block_size;
|
||||
uint8_t nb_re_dmrs;
|
||||
uint8_t time_alloc_list_flag;
|
||||
uint8_t time_alloc_list;
|
||||
uint8_t rbg_list;
|
||||
uint8_t virtual_resource_block_assignment_flag;
|
||||
uint32_t resource_block_coding;
|
||||
uint8_t redundancy_version;
|
||||
uint8_t transport_blocks;
|
||||
uint8_t transmission_scheme;
|
||||
uint8_t number_of_subbands;
|
||||
uint8_t codebook_index[NFAPI_MAX_NUM_SUBBANDS];
|
||||
uint8_t ue_category_capacity;
|
||||
uint8_t pa;
|
||||
uint8_t delta_power_offset_index;
|
||||
uint8_t ngap;
|
||||
uint8_t transmission_mode;
|
||||
uint8_t num_bf_prb_per_subband;
|
||||
uint8_t num_bf_vector;
|
||||
nfapi_bf_vector_t bf_vector[NFAPI_MAX_BF_VECTORS];
|
||||
}nfapi_nr_dl_config_dlsch_pdu_rel15_t;
|
||||
#define NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG
|
||||
|
||||
typedef struct {
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_pdu_rel15;
|
||||
} nfapi_nr_dl_config_dlsch_pdu;
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
@@ -501,15 +598,15 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
|
||||
} nfapi_nr_dl_config_nbch_pdu;
|
||||
} nfapi_nr_dl_config_nbch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} nfapi_nr_dl_config_npdcch_pdu;
|
||||
} nfapi_nr_dl_config_npdcch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} nfapi_nr_dl_config_ndlsch_pdu;
|
||||
} nfapi_nr_dl_config_ndlsch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15;
|
||||
@@ -524,11 +621,11 @@ typedef struct {
|
||||
union {
|
||||
nfapi_nr_dl_config_dci_dl_pdu dci_dl_pdu;
|
||||
nfapi_nr_dl_config_bch_pdu_rel15_t bch_pdu_rel15;
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_pdu_rel15;
|
||||
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
|
||||
nfapi_nr_dl_config_pch_pdu_rel15_t pch_pdu_rel15;
|
||||
//nfapi_nr_dl_config_nbch_pdu_rel15_t nbch_pdu_rel15;
|
||||
//nfapi_nr_dl_config_npdcch_pdu_rel15_t npdcch_pdu_rel15;
|
||||
//nfapi_nr_dl_config_ndlsch_pdu_rel15_t ndlsch_pdu_rel15;
|
||||
nfapi_nr_dl_config_nbch_pdu_rel15_t nbch_pdu_rel15;
|
||||
nfapi_nr_dl_config_npdcch_pdu_rel15_t npdcch_pdu_rel15;
|
||||
nfapi_nr_dl_config_ndlsch_pdu_rel15_t ndlsch_pdu_rel15;
|
||||
};
|
||||
} nfapi_nr_dl_config_request_pdu_t;
|
||||
|
||||
|
||||
@@ -18,6 +18,6 @@ alias oailte='cd $OPENAIR_TARGETS/RT/USER'
|
||||
alias oais='cd $OPENAIR_TARGETS/SIMU/USER'
|
||||
alias oaiex='cd $OPENAIR_TARGETS/SIMU/EXAMPLES'
|
||||
|
||||
#export IIOD_REMOTE=192.168.121.32
|
||||
export IIOD_REMOTE=192.168.1.11
|
||||
export IIOD_REMOTE=192.168.121.32
|
||||
#export IIOD_REMOTE=192.168.1.11
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
#include "PHY/CODING/nrLDPC_encoder/defs.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||
@@ -38,6 +39,10 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define NR_LDPC_PROFILER_DETAIL
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
|
||||
|
||||
// 4-bit quantizer
|
||||
char quantize4bit(double D,double x)
|
||||
{
|
||||
@@ -53,13 +58,33 @@ char quantize4bit(double D,double x)
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
char quantize8bit(double D,double x)
|
||||
{
|
||||
double qxd;
|
||||
//char maxlev;
|
||||
qxd = floor(x/D);
|
||||
|
||||
//maxlev = 1<<(B-1);
|
||||
|
||||
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||
|
||||
if (qxd <= -128)
|
||||
qxd = -128;
|
||||
else if (qxd >= 128)
|
||||
qxd = 127;
|
||||
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
char quantize(double D,double x,unsigned char B)
|
||||
{
|
||||
double qxd;
|
||||
char maxlev;
|
||||
short maxlev;
|
||||
qxd = floor(x/D);
|
||||
// printf("x=%f,qxd=%f\n",x,qxd);
|
||||
maxlev = 1<<(B-1);
|
||||
|
||||
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;
|
||||
@@ -69,45 +94,78 @@ char quantize(double D,double x,unsigned char B)
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
double n_iter_mean;
|
||||
double n_iter_std;
|
||||
int n_iter_max;
|
||||
} n_iter_stats_t;
|
||||
|
||||
#define MAX_BLOCK_LENGTH 8448
|
||||
|
||||
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
|
||||
|
||||
int test_ldpc(short No_iteration,
|
||||
//int nom_rate,
|
||||
//int denom_rate,
|
||||
int nom_rate,
|
||||
int denom_rate,
|
||||
double SNR,
|
||||
unsigned char qbits,
|
||||
unsigned short block_length,
|
||||
short block_length,
|
||||
unsigned int ntrials,
|
||||
int n_segments,
|
||||
unsigned int *errors,
|
||||
unsigned int *crc_misses)
|
||||
unsigned int *errors_bit,
|
||||
double *errors_bit_uncoded,
|
||||
unsigned int *crc_misses,
|
||||
time_stats_t *time_optim,
|
||||
time_stats_t *time_decoder,
|
||||
n_iter_stats_t * dec_iter)
|
||||
{
|
||||
//clock initiate
|
||||
time_stats_t time,time_optim,tinput,tprep,tparity,toutput;
|
||||
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
|
||||
time_stats_t time, tinput,tprep,tparity,toutput;
|
||||
double n_iter_mean = 0;
|
||||
double n_iter_std = 0;
|
||||
int n_iter_max = 0;
|
||||
unsigned int segment_bler = 0;
|
||||
|
||||
double sigma;
|
||||
sigma = 1.0/sqrt(2*SNR);
|
||||
|
||||
opp_enabled=1;
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
//short test_input[block_length];
|
||||
unsigned char *test_input[MAX_NUM_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
|
||||
//short *c; //padded codeword
|
||||
unsigned char *estimated_output;
|
||||
unsigned char *estimated_output[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *estimated_output_bit[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *test_input_bit;
|
||||
unsigned char *channel_input[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *channel_output_uncoded[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *channel_input_optim[MAX_NUM_DLSCH_SEGMENTS];
|
||||
double *channel_output;
|
||||
double *modulated_input;
|
||||
char *channel_output_fixed;
|
||||
double *modulated_input[MAX_NUM_DLSCH_SEGMENTS];
|
||||
char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned int i,j,trial=0;
|
||||
short BG,Zc,Kb;
|
||||
//short nrows,ncols;
|
||||
//int no_punctured_columns,removed_bit;
|
||||
short BG,Zc,Kb,nrows;//,ncols;
|
||||
int no_punctured_columns,removed_bit;
|
||||
int i1;
|
||||
int R_ind = 0;
|
||||
//Table of possible lifting sizes
|
||||
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
|
||||
int n_segments=8;
|
||||
int N; //length encoded block
|
||||
//short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
|
||||
//int n_segments=1;
|
||||
int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
|
||||
//double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
|
||||
|
||||
t_nrLDPC_dec_params decParams;
|
||||
int n_iter;
|
||||
|
||||
t_nrLDPC_time_stats decoder_profiler;
|
||||
t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
|
||||
|
||||
int32_t n_iter = 0;
|
||||
|
||||
*errors=0;
|
||||
*errors_bit=0;
|
||||
*errors_bit_uncoded=0;
|
||||
*crc_misses=0;
|
||||
|
||||
// generate input block
|
||||
@@ -115,37 +173,454 @@ int test_ldpc(short No_iteration,
|
||||
test_input[j]=(unsigned char *)malloc16(sizeof(unsigned char) * block_length/8);
|
||||
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
channel_input_optim[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
channel_output_uncoded[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
estimated_output[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
estimated_output_bit[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
modulated_input[j] = (double *)malloc16(sizeof(double) * 68*384);
|
||||
channel_output_fixed[j] = (char *)malloc16(sizeof( char) * 68*384);
|
||||
}
|
||||
modulated_input = (double *)malloc(sizeof(double) * 68*384);
|
||||
channel_output = (double *)malloc(sizeof(double) * 68*384);
|
||||
channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
|
||||
estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
|
||||
memset(channel_output_fixed,0,sizeof(char) * 68*384);
|
||||
//modulated_input = (double *)malloc(sizeof(double) * 68*384);
|
||||
//channel_output = (double *)malloc(sizeof(double) * 68*384);
|
||||
//channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
|
||||
//modulated_input = (double *)calloc(68*384, sizeof(double));
|
||||
channel_output = (double *)calloc(68*384, sizeof(double));
|
||||
//channel_output_fixed = (double *)calloc(68*384, sizeof(double));
|
||||
//channel_output_fixed = (unsigned char*)calloc(68*384, sizeof(unsigned char*));
|
||||
//estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);///8);
|
||||
//estimated_output_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
test_input_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
|
||||
reset_meas(&time);
|
||||
reset_meas(&time_optim);
|
||||
reset_meas(time_optim);
|
||||
reset_meas(time_decoder);
|
||||
reset_meas(&tinput);
|
||||
reset_meas(&tprep);
|
||||
reset_meas(&tparity);
|
||||
reset_meas(&toutput);
|
||||
//Reset Decoder profiles
|
||||
reset_meas(&decoder_profiler.llr2llrProcBuf);
|
||||
reset_meas(&decoder_profiler.llr2CnProcBuf);
|
||||
reset_meas(&decoder_profiler.cnProc);
|
||||
reset_meas(&decoder_profiler.cnProcPc);
|
||||
reset_meas(&decoder_profiler.bnProc);
|
||||
reset_meas(&decoder_profiler.bnProcPc);
|
||||
reset_meas(&decoder_profiler.cn2bnProcBuf);
|
||||
reset_meas(&decoder_profiler.bn2cnProcBuf);
|
||||
reset_meas(&decoder_profiler.llrRes2llrOut);
|
||||
reset_meas(&decoder_profiler.llr2bit);
|
||||
//reset_meas(&decoder_profiler.total);
|
||||
|
||||
for (j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
for (i=0; i<block_length/8; i++) {
|
||||
test_input[j][i]=(unsigned char) rand();
|
||||
//test_input[j][i]=j%256;
|
||||
//test_input[j][i]=252;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//determine number of bits in codeword
|
||||
if ((block_length>3840) && (block_length <= MAX_BLOCK_LENGTH))
|
||||
if (block_length>3840)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
//ncols=22; //info bits
|
||||
}
|
||||
else if (block_length<=3840)
|
||||
{
|
||||
BG=2;
|
||||
nrows=42; //parity check bits
|
||||
//ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
|
||||
if (nom_rate == 1)
|
||||
if (denom_rate == 5)
|
||||
if (BG == 2)
|
||||
R_ind = 0;
|
||||
else
|
||||
printf("Not supported");
|
||||
else if (denom_rate == 3)
|
||||
R_ind = 1;
|
||||
else if (denom_rate == 2)
|
||||
//R_ind = 3;
|
||||
printf("Not supported");
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
else if (nom_rate == 2)
|
||||
if (denom_rate == 5)
|
||||
//R_ind = 2;
|
||||
printf("Not supported");
|
||||
else if (denom_rate == 3)
|
||||
R_ind = 4;
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
else if ((nom_rate == 22) && (denom_rate == 30))
|
||||
//R_ind = 5;
|
||||
printf("Not supported");
|
||||
else if ((nom_rate == 22) && (denom_rate == 27))
|
||||
//R_ind = 6;
|
||||
printf("Not supported");
|
||||
else if ((nom_rate == 22) && (denom_rate == 25))
|
||||
if (BG == 1)
|
||||
R_ind = 7;
|
||||
else
|
||||
printf("Not supported");
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
{
|
||||
Zc = lift_size[i1];
|
||||
//printf("%d\n",Zc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length,BG, Zc, Kb);
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
|
||||
// printf("puncture:%d\n",no_punctured_columns);
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
|
||||
if (ntrials==0)
|
||||
ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
|
||||
|
||||
for (trial=0; trial < ntrials; trial++)
|
||||
{
|
||||
segment_bler = 0;
|
||||
//// encoder
|
||||
start_meas(&time);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_orig(test_input[j], channel_input[j],block_length,BG,0);
|
||||
}
|
||||
stop_meas(&time);
|
||||
|
||||
/* start_meas(time_optim);
|
||||
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
|
||||
}
|
||||
stop_meas(time_optim);*/
|
||||
|
||||
for(j=0;j<(n_segments%8+1);j++) {
|
||||
start_meas(time_optim);
|
||||
ldpc_encoder_optim_8seg_multi(test_input,channel_input_optim,block_length, BG, n_segments,j,&tinput,&tprep,&tparity,&toutput);
|
||||
stop_meas(time_optim);
|
||||
}
|
||||
|
||||
if (ntrials==1)
|
||||
for (j=0;j<n_segments;j++)
|
||||
for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
|
||||
if (channel_input[j][i]!=channel_input_optim[j][i]) {
|
||||
printf("differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
return (-1);
|
||||
}
|
||||
//else{
|
||||
// printf("NOT differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
// }
|
||||
if (trial== 0) {
|
||||
printf("nrows: %d\n", nrows);
|
||||
printf("no_punctured_columns: %d\n", no_punctured_columns);
|
||||
printf("removed_bit: %d\n", removed_bit);
|
||||
printf("To: %d\n", (Kb+nrows-no_punctured_columns) * Zc-removed_bit);
|
||||
printf("number of undecoded bits: %d\n", (Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
|
||||
|
||||
}
|
||||
|
||||
//print_meas_now(&time, "", stdout);
|
||||
|
||||
// for (i=0;i<6400;i++)
|
||||
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//printf("%d ",channel_input[i]);
|
||||
|
||||
//if ((BG==2) && (Zc==128||Zc==256))
|
||||
if (1) { // Transmitting one segment
|
||||
for(j=0;j<n_segments;j++) {
|
||||
for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) {
|
||||
#ifdef DEBUG_CODER
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
|
||||
if (channel_input[j][i-2*Zc]==0)
|
||||
modulated_input[j][i]=1.0;///sqrt(2); //QPSK
|
||||
else
|
||||
modulated_input[j][i]=-1.0;///sqrt(2);
|
||||
|
||||
///channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
|
||||
//channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
|
||||
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
|
||||
|
||||
//channel_output_fixed[i] = (char)quantize(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
|
||||
channel_output_fixed[j][i] = (char)quantize(sigma/4.0/4.0,modulated_input[j][i] + sigma*gaussdouble(0.0,1.0),qbits);
|
||||
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
|
||||
//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);
|
||||
|
||||
//Uncoded BER
|
||||
if (channel_output_fixed[j][i]<0)
|
||||
channel_output_uncoded[j][i]=1; //QPSK demod
|
||||
else
|
||||
channel_output_uncoded[j][i]=0;
|
||||
|
||||
if (channel_output_uncoded[j][i] != channel_input[j][i-2*Zc])
|
||||
*errors_bit_uncoded = (*errors_bit_uncoded) + 1;
|
||||
|
||||
}
|
||||
} // End segments
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
//{
|
||||
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//printf("%lf %d\n",channel_output[i], channel_output_fixed[i]);
|
||||
//printf("v[%d]=%lf\n",i,modulated_input[i]);}
|
||||
#ifdef DEBUG_CODER
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
decParams.BG=BG;
|
||||
decParams.Z=Zc;
|
||||
decParams.R=code_rate_vec[R_ind];//13;
|
||||
decParams.numMaxIter=No_iteration;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
//decParams.outMode =nrLDPC_outMode_LLRINT8;
|
||||
|
||||
|
||||
for(j=0;j<n_segments;j++) {
|
||||
start_meas(time_decoder);
|
||||
// decode the sequence
|
||||
// decoder supports BG2, Z=128 & 256
|
||||
//esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
|
||||
///nrLDPC_decoder(&decParams, channel_output_fixed, estimated_output, NULL);
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_decoder_profiler);
|
||||
|
||||
stop_meas(time_decoder);
|
||||
}
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
|
||||
|
||||
//count errors
|
||||
for(j=0;j<n_segments;j++) {
|
||||
for (i=0; i<block_length>>3; i++)
|
||||
{
|
||||
//printf("block_length>>3: %d \n",block_length>>3);
|
||||
/// printf("i: %d \n",i);
|
||||
///printf("estimated_output[%d]: %d \n",i,estimated_output[i]);
|
||||
///printf("test_input[0][%d]: %d \n",i,test_input[0][i]);
|
||||
if (estimated_output[j][i] != test_input[j][i])
|
||||
{
|
||||
//////printf("error pos %d (%d, %d)\n\n",i,estimated_output[i],test_input[0][i]);
|
||||
segment_bler = segment_bler + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<block_length; i++)
|
||||
{
|
||||
estimated_output_bit[j][i] = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
test_input_bit[i] = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
|
||||
if (estimated_output_bit[j][i] != test_input_bit[i])
|
||||
{
|
||||
*errors_bit = (*errors_bit) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//if (*errors == 1000)
|
||||
//break;
|
||||
|
||||
n_iter_mean = n_iter_mean + n_iter;
|
||||
n_iter_std = n_iter_std + pow(n_iter-1,2);
|
||||
|
||||
if ( n_iter > n_iter_max )
|
||||
n_iter_max = n_iter;
|
||||
|
||||
} // end segments
|
||||
|
||||
if (segment_bler != 0)
|
||||
*errors = (*errors) + 1;
|
||||
|
||||
}
|
||||
/*else if (trial==0)
|
||||
printf("decoder is not supported\n");*/
|
||||
}
|
||||
|
||||
|
||||
dec_iter->n_iter_mean = n_iter_mean/(double)ntrials/(double)n_segments - 1;
|
||||
dec_iter->n_iter_std = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2));
|
||||
dec_iter->n_iter_max = n_iter_max -1;
|
||||
|
||||
*errors_bit_uncoded = *errors_bit_uncoded / (double)((Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
|
||||
|
||||
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
free(test_input[j]);
|
||||
free(channel_input[j]);
|
||||
free(channel_output_uncoded[j]);
|
||||
free(channel_input_optim[j]);
|
||||
free(modulated_input[j]);
|
||||
free(channel_output_fixed[j]);
|
||||
free(estimated_output[j]);
|
||||
free(estimated_output_bit[j]);
|
||||
}
|
||||
//free(modulated_input);
|
||||
free(channel_output);
|
||||
//free(channel_output_fixed);
|
||||
//free(estimated_output);
|
||||
|
||||
print_meas(&time,"ldpc_encoder",NULL,NULL);
|
||||
print_meas(time_optim,"ldpc_encoder_optim",NULL,NULL);
|
||||
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
|
||||
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
|
||||
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
|
||||
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
|
||||
printf("\n");
|
||||
print_meas(time_decoder,"ldpc_decoder",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2llrProcBuf,"llr2llrProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2CnProcBuf,"llr2CnProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProc,"cnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProcPc,"cnProcPc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProc,"bnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProcPc,"bnProcPc(per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cn2bnProcBuf,"cn2bnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bn2cnProcBuf,"bn2cnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llrRes2llrOut,"llrRes2llrOut",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2bit,"llr2bit",NULL,NULL);
|
||||
printf("\n");
|
||||
|
||||
return *errors;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int errors, errors_bit, crc_misses;
|
||||
double errors_bit_uncoded;
|
||||
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
|
||||
short No_iteration=5;
|
||||
int n_segments=1;
|
||||
//double rate=0.333;
|
||||
int nom_rate=1;
|
||||
int denom_rate=3;
|
||||
double SNR0=-2.0,SNR,SNR_lin;
|
||||
unsigned char qbits=8;
|
||||
unsigned int decoded_errors[10000]; // initiate the size of matrix equivalent to size of SNR
|
||||
int c,i=0, i1 = 0;
|
||||
|
||||
int n_trials = 1;
|
||||
double SNR_step = 0.1;
|
||||
|
||||
randominit(0);
|
||||
int test_uncoded= 0;
|
||||
|
||||
time_stats_t time_optim[10], time_decoder[10];
|
||||
n_iter_stats_t dec_iter[3];
|
||||
|
||||
short BG,Zc,Kb;
|
||||
|
||||
while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h")) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
qbits = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
nom_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
denom_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
block_length = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_trials = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
SNR0 = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
n_segments = atof(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
SNR_step = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
No_iteration = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
test_uncoded = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
printf("CURRENTLY SUPPORTED CODE RATES: \n");
|
||||
printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
|
||||
printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
|
||||
printf("-h This message\n");
|
||||
printf("-q Quantization bits, Default: 8\n");
|
||||
printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
|
||||
printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
|
||||
printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
|
||||
printf("-n Number of simulation trials, Default: 1\n");
|
||||
//printf("-M MCS2 for TB 2\n");
|
||||
printf("-s SNR per information bit (EbNo) in dB, Default: -2\n");
|
||||
printf("-S Number of segments (Maximum: 8), Default: 1\n");
|
||||
printf("-t SNR simulation step, Default: 0.1\n");
|
||||
printf("-i Max decoder iterations, Default: 5\n");
|
||||
printf("-u Set SNR per coded bit, Default: 0\n");
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
|
||||
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
|
||||
printf("block length %d: \n", block_length);
|
||||
printf("n_trials %d: \n", n_trials);
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
|
||||
|
||||
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (block_length>3840)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
//nrows=46; //parity check bits
|
||||
//ncols=22; //info bits
|
||||
}
|
||||
else if (block_length<=3840)
|
||||
else if (block_length<=3840)
|
||||
{
|
||||
BG=2;
|
||||
//nrows=42; //parity check bits
|
||||
@@ -159,14 +634,11 @@ int test_ldpc(short No_iteration,
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
else {
|
||||
printf("block_length %d not supported\n",block_length);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
@@ -177,193 +649,87 @@ int test_ldpc(short No_iteration,
|
||||
}
|
||||
}
|
||||
|
||||
if (BG==1)
|
||||
N=66*Zc;
|
||||
else if (BG==2)
|
||||
N=50*Zc;
|
||||
char fname[200];
|
||||
sprintf(fname,"ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, No_iteration);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
|
||||
|
||||
printf("ldpc_test: block_length %d, BG %d, Zc %d, Kb %d, N %d\n",block_length,BG, Zc, Kb, N);
|
||||
//no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
|
||||
// printf("puncture:%d\n",no_punctured_columns);
|
||||
//removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
|
||||
if (ntrials==0)
|
||||
ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
|
||||
|
||||
for (trial=0; trial < ntrials; trial++)
|
||||
fprintf(fd,"SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX\n");
|
||||
|
||||
for (SNR=SNR0;SNR<SNR0+20.0;SNR+=SNR_step)
|
||||
{
|
||||
|
||||
//// encoder
|
||||
start_meas(&time);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_orig(test_input[j], channel_input[j],block_length,BG,0);
|
||||
}
|
||||
stop_meas(&time);
|
||||
|
||||
start_meas(&time_optim);
|
||||
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
|
||||
/*for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
|
||||
}*/
|
||||
stop_meas(&time_optim);
|
||||
|
||||
if (ntrials==1)
|
||||
for (j=0;j<n_segments;j++)
|
||||
for (i = 0; i < 3*block_length; i++)
|
||||
if (channel_input[j][i]!=channel_input_optim[j][i]) {
|
||||
printf("differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
//print_meas_now(&time, "", stdout);
|
||||
|
||||
// for (i=0;i<6400;i++)
|
||||
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//printf("%d ",channel_input[i]);
|
||||
|
||||
for (i = 2*Zc; i < 3*block_length; i++)
|
||||
{
|
||||
#ifdef DEBUG_CODER
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
|
||||
if (channel_input[0][i-2*Zc]==0)
|
||||
modulated_input[i]=1/sqrt(2); //BPSK
|
||||
else
|
||||
modulated_input[i]=-1/sqrt(2);
|
||||
|
||||
channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
|
||||
if (channel_output[i]>1.0)
|
||||
channel_output_fixed[i]=127;
|
||||
else if (channel_output[i]<-1.0)
|
||||
channel_output_fixed[i]=-128;
|
||||
else
|
||||
channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
|
||||
//printf("llr[%d]=%d (%f)\n",i,channel_output_fixed[i],channel_output[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
the LDPC decoder supports several rates and the input has to be adapted accordingly (by padding with zeros to the next lower supported rate). Moreover, the first 2*Z LLRs are zero (since they are punctured and not transmitted) then you have the LLRs corresponding to the systematic bits. After that come the filler bits, the encoder uses 0 for the filler bits hence for the decoder you need to put 127 (max LLR for bit 0) at their place. Then come the LLRs corresponding to the punctured bits followed by zeros to pad for the supported decoder rate.
|
||||
*/
|
||||
for (i=0;i<2*Zc;i++)
|
||||
channel_output_fixed[i] = 0;
|
||||
|
||||
decParams.BG=BG;
|
||||
decParams.Z=Zc;
|
||||
decParams.R=13;
|
||||
decParams.numMaxIter=6;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
|
||||
// decode the sequence
|
||||
// decoder supports BG2, Z=128 & 256
|
||||
//estimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
|
||||
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*) channel_output_fixed, (int8_t*) estimated_output, NULL);
|
||||
printf("nrLDPC_decoder n_iter=%d\n",n_iter);
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
|
||||
|
||||
//count errors
|
||||
for (i=0; i<block_length>>3; i++)
|
||||
{
|
||||
if (estimated_output[i] != test_input[0][i])
|
||||
{
|
||||
printf("error pos %d (%d, %d)\n",i,estimated_output[i],test_input[0][i]);
|
||||
*errors = (*errors) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
free(test_input[j]);
|
||||
free(channel_input[j]);
|
||||
free(channel_input_optim[j]);
|
||||
}
|
||||
free(modulated_input);
|
||||
free(channel_output);
|
||||
free(channel_output_fixed);
|
||||
free(estimated_output);
|
||||
|
||||
print_meas(&time,"ldpc_encoder",NULL,NULL);
|
||||
print_meas(&time_optim,"ldpc_encoder_optim",NULL,NULL);
|
||||
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
|
||||
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
|
||||
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
|
||||
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
|
||||
return *errors;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int errors,crc_misses;
|
||||
short block_length=576; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
short No_iteration=25;
|
||||
//double rate=0.333;
|
||||
//int nom_rate=1;
|
||||
//int denom_rate=3;
|
||||
double SNR0=-2.0,SNR,SNR_lin;
|
||||
unsigned char qbits=4;
|
||||
unsigned int decoded_errors[100]; // initiate the size of matrix equivalent to size of SNR
|
||||
int c,i=0;
|
||||
|
||||
int n_trials = 1;
|
||||
|
||||
randominit(0);
|
||||
|
||||
while ((c = getopt (argc, argv, "q:s:l:n:h")) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
qbits = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
block_length = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_trials = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
SNR0 = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("usage ldpctest -h -l blocklength -n n_trials -s SNR\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
|
||||
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
|
||||
//printf("rate: %d/%d\n",nom_rate,denom_rate);
|
||||
printf("block length %d: \n", block_length);
|
||||
printf("n_trials %d: \n", n_trials);
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
for (SNR=SNR0;SNR<SNR0+1.0;SNR+=1.0)
|
||||
{
|
||||
SNR_lin = pow(10,SNR/10);
|
||||
//reset_meas(&time_optim);
|
||||
//reset_meas(&time_decoder);
|
||||
//n_iter_stats_t dec_iter = {0, 0, 0};
|
||||
if (test_uncoded == 1)
|
||||
SNR_lin = pow(10,SNR/10.0);
|
||||
else
|
||||
SNR_lin = pow(10,SNR/10.0)*nom_rate/denom_rate;
|
||||
printf("Linear SNR: %f\n", SNR_lin);
|
||||
decoded_errors[i]=test_ldpc(No_iteration,
|
||||
//nom_rate,
|
||||
//denom_rate,
|
||||
nom_rate,
|
||||
denom_rate,
|
||||
SNR_lin, // noise standard deviation
|
||||
qbits,
|
||||
block_length, // block length bytes
|
||||
n_trials,
|
||||
n_segments,
|
||||
&errors,
|
||||
&crc_misses);
|
||||
&errors_bit,
|
||||
&errors_bit_uncoded,
|
||||
&crc_misses,
|
||||
time_optim,
|
||||
time_decoder,
|
||||
dec_iter);
|
||||
|
||||
printf("SNR %f, BLER %f (%d/%d)\n",SNR,(float)decoded_errors[i]/(float)n_trials,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, BER %f (%d/%d)\n",SNR,(float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments ,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, Uncoded BER %f (%d/%d)\n",SNR,errors_bit_uncoded/(float)n_trials/(double)n_segments ,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, Mean iterations: %f\n",SNR, dec_iter->n_iter_mean);
|
||||
printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
|
||||
printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
|
||||
printf("\n");
|
||||
printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz);
|
||||
printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)));
|
||||
printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz);
|
||||
printf("\n");
|
||||
printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz);
|
||||
printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)));
|
||||
printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz);
|
||||
|
||||
fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
|
||||
SNR,
|
||||
(double)decoded_errors[i]/(double)n_trials ,
|
||||
(double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments ,
|
||||
errors_bit_uncoded/(double)n_trials/(double)n_segments ,
|
||||
(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,
|
||||
sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)),
|
||||
(double)time_optim->max/1000.0/cpu_freq_GHz,
|
||||
(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,
|
||||
sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)),
|
||||
(double)time_decoder->max/1000.0/cpu_freq_GHz,
|
||||
dec_iter->n_iter_mean,
|
||||
dec_iter->n_iter_std,
|
||||
dec_iter->n_iter_max
|
||||
);
|
||||
|
||||
if (decoded_errors[i] == 0)
|
||||
break;
|
||||
i=i+1;
|
||||
|
||||
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
#define MAX_TURBO_ITERATIONS_MBSFN 8
|
||||
#define MAX_TURBO_ITERATIONS max_turbo_iterations
|
||||
|
||||
#define MAX_LDPC_ITERATIONS 4
|
||||
#define MAX_LDPC_ITERATIONS_MBSFN 4
|
||||
|
||||
#define LTE_NULL 2
|
||||
#define NR_NULL 2
|
||||
typedef struct {
|
||||
unsigned short nb_bits;
|
||||
unsigned short f1;
|
||||
@@ -443,16 +448,11 @@ unsigned int crcbit (unsigned char * inputptr, int octetlen, unsigned int poly);
|
||||
int16_t reverseBits(int32_t ,int32_t);
|
||||
void phy_viterbi_dot11(int8_t *,uint8_t *,uint16_t);
|
||||
|
||||
decoder_if_t phy_threegpplte_turbo_decoder;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder8;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder16;
|
||||
|
||||
int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
unsigned char **output_buffers,
|
||||
unsigned int B,
|
||||
unsigned int *C,
|
||||
unsigned int *Kplus,
|
||||
unsigned int *Kminus,
|
||||
unsigned int *K,
|
||||
unsigned int *Zout,
|
||||
unsigned int *F);
|
||||
|
||||
@@ -463,4 +463,40 @@ uint32_t nr_compute_tbs(uint8_t mcs,
|
||||
uint16_t length_dmrs,
|
||||
uint8_t Nl);
|
||||
|
||||
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
|
||||
|
||||
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f);
|
||||
|
||||
uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
|
||||
uint32_t Tbslbrm,
|
||||
uint8_t BG,
|
||||
uint16_t Z,
|
||||
uint32_t G,
|
||||
uint8_t *w,
|
||||
uint8_t *e,
|
||||
uint8_t C,
|
||||
uint8_t rvidx,
|
||||
uint8_t Qm,
|
||||
uint8_t Nl,
|
||||
uint8_t r);
|
||||
|
||||
int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
|
||||
uint32_t Tbslbrm,
|
||||
uint8_t BG,
|
||||
uint16_t Z,
|
||||
uint32_t G,
|
||||
int16_t *w,
|
||||
int16_t *soft_input,
|
||||
uint8_t C,
|
||||
uint8_t rvidx,
|
||||
uint8_t clear,
|
||||
uint8_t Qm,
|
||||
uint8_t Nl,
|
||||
uint8_t r,
|
||||
uint32_t *E_out);
|
||||
|
||||
decoder_if_t phy_threegpplte_turbo_decoder;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder8;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder16;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,12 +35,14 @@
|
||||
|
||||
/*ref 36-212 v8.6.0 , pp 8-9 */
|
||||
/* the highest degree is set by default */
|
||||
|
||||
unsigned int poly24a = 0x864cfb00; // 1000 0110 0100 1100 1111 1011
|
||||
// D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1
|
||||
unsigned int poly24b = 0x80006300; // 1000 0000 0000 0000 0110 0011
|
||||
// D^24 + D^23 + D^6 + D^5 + D + 1
|
||||
unsigned int poly24c = 0xb2b11700; // 1011 0010 1011 0001 0001 0111
|
||||
// D^24+D^23+D^21+D^20+D^17+D^15+D^13+D^12+D^8+D^4+D^2+D+1
|
||||
|
||||
unsigned int poly16 = 0x10210000; // 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1
|
||||
unsigned int poly12 = 0x80F00000; // 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1
|
||||
unsigned int poly8 = 0x9B000000; // 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1
|
||||
@@ -253,6 +255,68 @@ unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table
|
||||
return crc;
|
||||
}
|
||||
|
||||
int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
|
||||
{
|
||||
uint32_t crc=0,oldcrc=0;
|
||||
uint8_t crc_len,temp;
|
||||
|
||||
switch (crc_type) {
|
||||
case CRC24_A:
|
||||
case CRC24_B:
|
||||
crc_len=3;
|
||||
break;
|
||||
|
||||
case CRC16:
|
||||
crc_len=2;
|
||||
break;
|
||||
|
||||
case CRC8:
|
||||
crc_len=1;
|
||||
break;
|
||||
|
||||
default:
|
||||
crc_len=3;
|
||||
}
|
||||
|
||||
for (int i=0; i<crc_len; i++)
|
||||
oldcrc |= (decoded_bytes[(n>>3)-crc_len+i])<<((crc_len-1-i)<<3);
|
||||
|
||||
switch (crc_type) {
|
||||
|
||||
case CRC24_A:
|
||||
oldcrc&=0x00ffffff;
|
||||
crc = crc24a(decoded_bytes,
|
||||
n-24)>>8;
|
||||
|
||||
break;
|
||||
|
||||
case CRC24_B:
|
||||
oldcrc&=0x00ffffff;
|
||||
crc = crc24b(decoded_bytes,
|
||||
n-24)>>8;
|
||||
|
||||
break;
|
||||
|
||||
case CRC16:
|
||||
oldcrc&=0x0000ffff;
|
||||
crc = crc16(decoded_bytes,
|
||||
n-16)>>16;
|
||||
|
||||
break;
|
||||
|
||||
case CRC8:
|
||||
oldcrc&=0x000000ff;
|
||||
crc = crc8(decoded_bytes,
|
||||
n-8)>>24;
|
||||
break;
|
||||
}
|
||||
|
||||
if (crc == oldcrc)
|
||||
return(1);
|
||||
else
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_CRC
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#include "nrLDPC_cnProc.h"
|
||||
#include "nrLDPC_bnProc.h"
|
||||
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
//#define NR_LDPC_PROFILER_DETAIL
|
||||
|
||||
#ifdef NR_LDPC_DEBUG_MODE
|
||||
#include "nrLDPC_tools/nrLDPC_debug.h"
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
|
||||
void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb);
|
||||
int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
|
||||
int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
|
||||
int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
|
||||
|
||||
/*ldpc_generate_coefficient.c*/
|
||||
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,unsigned char gen_code);
|
||||
|
||||
@@ -68,7 +68,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
|
||||
printf("problem with BG\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
|
||||
|
||||
@@ -201,13 +201,7 @@ void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,sho
|
||||
int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short Zc;
|
||||
|
||||
//initialize for BG == 1
|
||||
short Kb = 22;
|
||||
short nrows = 46;//parity check bits
|
||||
short ncols = 22;//info bits
|
||||
|
||||
short Zc,Kb,nrows,ncols;
|
||||
int i,i1;
|
||||
int no_punctured_columns,removed_bit;
|
||||
|
||||
@@ -217,20 +211,30 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
|
||||
int simd_size;
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==2)
|
||||
{
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
@@ -316,13 +320,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
|
||||
int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short Zc;
|
||||
|
||||
//initialize for BG == 1
|
||||
short Kb = 22;
|
||||
short nrows = 46;//parity check bits
|
||||
short ncols = 22;//info bits
|
||||
|
||||
short Zc,Kb,nrows,ncols;
|
||||
int i,i1,j;
|
||||
int no_punctured_columns,removed_bit;
|
||||
//Table of possible lifting sizes
|
||||
@@ -349,8 +347,18 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==2)
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
@@ -362,7 +370,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
@@ -481,12 +489,12 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
// if (((block_length-(2*Zc))&31)>0) l1++;
|
||||
|
||||
for (i=0;i<l1;i++)
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
|
||||
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
|
||||
|
||||
for (i1=0;i1<l2;i1++,i++)
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_LDPC
|
||||
@@ -494,10 +502,10 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
#endif
|
||||
// do non-SIMD version
|
||||
for (i=0;i<(block_length-2*Zc);i++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
channel_input[j][i] = (c[2*Zc+i]>>j)&1;
|
||||
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
channel_input[j][block_length-2*Zc+i] = (d[i]>>j)&1;
|
||||
}
|
||||
|
||||
@@ -508,3 +516,217 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
stop_meas(toutput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short Zc,Kb,nrows,ncols;
|
||||
int i,i1,j;
|
||||
int no_punctured_columns,removed_bit;
|
||||
//Table of possible lifting sizes
|
||||
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
|
||||
char temp;
|
||||
int simd_size;
|
||||
int macro_segment, macro_segment_end;
|
||||
|
||||
|
||||
macro_segment = 8*macro_num;
|
||||
macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
|
||||
///printf("macro_segment: %d\n", macro_segment);
|
||||
///printf("macro_segment_end: %d\n", macro_segment_end );
|
||||
|
||||
#ifdef __AVX2__
|
||||
__m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
|
||||
__m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats.
|
||||
__m256i zero256 = _mm256_setzero_si256();
|
||||
__m256i masks[8];
|
||||
register __m256i c256;
|
||||
masks[0] = _mm256_set1_epi8(0x1);
|
||||
masks[1] = _mm256_set1_epi8(0x2);
|
||||
masks[2] = _mm256_set1_epi8(0x4);
|
||||
masks[3] = _mm256_set1_epi8(0x8);
|
||||
masks[4] = _mm256_set1_epi8(0x10);
|
||||
masks[5] = _mm256_set1_epi8(0x20);
|
||||
masks[6] = _mm256_set1_epi8(0x40);
|
||||
masks[7] = _mm256_set1_epi8(0x80);
|
||||
#endif
|
||||
|
||||
///AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==1)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
else if (BG==2)
|
||||
{
|
||||
BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
{
|
||||
Zc = lift_size[i1];
|
||||
//printf("%d\n",Zc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LDPC
|
||||
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
|
||||
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
|
||||
#endif
|
||||
|
||||
AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
|
||||
|
||||
if ((Zc&31) > 0) simd_size = 16;
|
||||
else simd_size = 32;
|
||||
|
||||
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
|
||||
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
|
||||
|
||||
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
|
||||
|
||||
// calculate number of punctured bits
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3);
|
||||
// printf("%d\n",no_punctured_columns);
|
||||
// printf("%d\n",removed_bit);
|
||||
// unpack input
|
||||
memset(c,0,sizeof(unsigned char) * ncols * Zc);
|
||||
memset(d,0,sizeof(unsigned char) * nrows * Zc);
|
||||
|
||||
start_meas(tinput);
|
||||
#if 0
|
||||
for (i=0; i<block_length; i++) {
|
||||
//for (j=0; j<n_segments; j++) {
|
||||
for (j=macro_segment; j < macro_segment_end; j++) {
|
||||
|
||||
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
//printf("c(%d,%d)=%d\n",j,i,temp);
|
||||
c[i] |= (temp << (j-macro_segment));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef __AVX2__
|
||||
for (i=0; i<block_length>>5; i++) {
|
||||
c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
|
||||
//for (j=1; j<n_segments; j++) {
|
||||
for (j=macro_segment+1; j < macro_segment_end; j++) {
|
||||
c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j-macro_segment]),c256);
|
||||
}
|
||||
((__m256i *)c)[i] = c256;
|
||||
}
|
||||
|
||||
for (i=(block_length>>5)<<5;i<block_length;i++) {
|
||||
//for (j=0; j<n_segments; j++) {
|
||||
for (j=macro_segment; j < macro_segment_end; j++) {
|
||||
|
||||
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
//printf("c(%d,%d)=%d\n",j,i,temp);
|
||||
c[i] |= (temp << (j-macro_segment));
|
||||
}
|
||||
}
|
||||
#else
|
||||
AssertFatal(1==0,"Need AVX2 for this\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stop_meas(tinput);
|
||||
|
||||
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
|
||||
// extend matrix
|
||||
start_meas(tprep);
|
||||
for (i1=0; i1 < ncols; i1++)
|
||||
{
|
||||
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
|
||||
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
|
||||
}
|
||||
for (i1=1;i1<simd_size;i1++) {
|
||||
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
|
||||
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
|
||||
/*
|
||||
printf("shift %d: ",i1);
|
||||
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
|
||||
printf("\n");
|
||||
*/
|
||||
}
|
||||
stop_meas(tprep);
|
||||
//parity check part
|
||||
start_meas(tparity);
|
||||
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
|
||||
stop_meas(tparity);
|
||||
}
|
||||
else {
|
||||
if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
|
||||
printf("Problem with encoder\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
start_meas(toutput);
|
||||
// information part and puncture columns
|
||||
/*
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
|
||||
*/
|
||||
#ifdef __AVX2__
|
||||
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
|
||||
//AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
|
||||
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
|
||||
uint32_t l1 = (block_length-(2*Zc))>>5;
|
||||
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
|
||||
__m256i *c256p = (__m256i *)&c[2*Zc];
|
||||
__m256i *d256p = (__m256i *)&d[0];
|
||||
// if (((block_length-(2*Zc))&31)>0) l1++;
|
||||
|
||||
for (i=0;i<l1;i++)
|
||||
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
|
||||
|
||||
|
||||
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
|
||||
|
||||
for (i1=0;i1<l2;i1++,i++)
|
||||
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_LDPC
|
||||
LOG_W(PHY,"using non-optimized version\n");
|
||||
#endif
|
||||
// do non-SIMD version
|
||||
for (i=0;i<(block_length-2*Zc);i++)
|
||||
//for (j=0; j<n_segments; j++)
|
||||
for (j=macro_segment; j < macro_segment_end; j++)
|
||||
channel_input[j][i] = (c[2*Zc+i]>>(j-macro_segment))&1;
|
||||
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
|
||||
//for (j=0; j<n_segments; j++)
|
||||
for (j=macro_segment; j < macro_segment_end; j++)
|
||||
channel_input[j][block_length-2*Zc+i] = (d[i]>>(j-macro_segment))&1;
|
||||
}
|
||||
|
||||
#else
|
||||
AssertFatal(1==0,"Need AVX2 for now\n");
|
||||
#endif
|
||||
|
||||
stop_meas(toutput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ short *choose_generator_matrix(short BG,short Zc)
|
||||
return Gen_shift_values;
|
||||
}
|
||||
|
||||
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,unsigned char gen_code)
|
||||
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code)
|
||||
{
|
||||
unsigned char c[22*384]; //padded input, unpacked, max size
|
||||
unsigned char d[68*384]; //coded output, unpacked, max size
|
||||
@@ -384,20 +384,30 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
int indlist2[1000];
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==2)
|
||||
{
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
@@ -415,8 +425,6 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
return(-1);
|
||||
}
|
||||
|
||||
//int K = ncols*Zc; //unused variable
|
||||
|
||||
Gen_shift_values=choose_generator_matrix(BG,Zc);
|
||||
if (Gen_shift_values==NULL) {
|
||||
printf("ldpc_encoder_orig: could not find generator matrix\n");
|
||||
@@ -438,15 +446,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
}
|
||||
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
//nrows - no_punctured_columns = 2 +2*block_length/Zc
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3);
|
||||
// ((nrows-no_punctured_columns) * Zc-removed_bit) =
|
||||
// 2Zc + 2*block_length
|
||||
//printf("%d\n",no_punctured_columns);
|
||||
//printf("%d\n",removed_bit);
|
||||
//printf("%d\n",nrows-no_punctured_columns);
|
||||
//printf("%d\n",((nrows-no_punctured_columns) * Zc-removed_bit));
|
||||
|
||||
// unpack input
|
||||
memset(c,0,sizeof(unsigned char) * ncols * Zc);
|
||||
memset(d,0,sizeof(unsigned char) * nrows * Zc);
|
||||
@@ -614,8 +616,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
}
|
||||
|
||||
// information part and puncture columns
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); //systematic bits
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); //systematic bits 2Zc + 2*block_length
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
|
||||
//memcpy(channel_input,c,Kb*Zc*sizeof(unsigned char));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,5 +35,27 @@
|
||||
|
||||
#define NR_POLAR_UCI_MESSAGE_TYPE -1 //int8_t
|
||||
#define NR_POLAR_UCI_CRC_ERROR_CORRECTION_BITS 3
|
||||
#define NR_POLAR_PUCCH_PAYLOAD_BITS 32
|
||||
#define NR_POLAR_PUCCH_E 32
|
||||
|
||||
//Ref. 38-212, Section 6.3.1.2.1
|
||||
#define NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT 6
|
||||
#define NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG 11
|
||||
|
||||
#define NR_POLAR_PUCCH_I_SEG_LONG 1
|
||||
#define NR_POLAR_PUCCH_I_SEG_SHORT 0
|
||||
|
||||
//Ref. 38-212, Section 6.3.1.3.1
|
||||
#define NR_POLAR_PUCCH_N_MAX 10
|
||||
#define NR_POLAR_PUCCH_I_IL 0
|
||||
#define NR_POLAR_PUCCH_N_PC_SHORT 3
|
||||
#define NR_POLAR_PUCCH_N_PC_LONG 0
|
||||
#define NR_POLAR_PUCCH_N_PC_WM_LONG 0
|
||||
#define NR_POLAR_PUCCH_N_PC_WM_SHORT 1
|
||||
|
||||
//Ref. 38-212, Section 6.3.1.4.1
|
||||
#define NR_POLAR_PUCCH_I_BIL 1
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,35 +28,8 @@
|
||||
|
||||
#define INDEX_MAX_TBS_TABLE (93)
|
||||
//Table 5.1.3.1-1
|
||||
uint16_t Mcsindextable1[29][3] = {{2,120,0.2344},
|
||||
{2,157,0.3066},
|
||||
{2,193,0.3770},
|
||||
{2,251,0.4902},
|
||||
{2,308,0.6016},
|
||||
{2,379,0.7402},
|
||||
{2,449,0.8770},
|
||||
{2,526,1.0273},
|
||||
{2,602,1.1758},
|
||||
{2,679,1.3262},
|
||||
{4,340,1.3281},
|
||||
{4,378,1.4766},
|
||||
{4,434,1.6953},
|
||||
{4,490,1.9141},
|
||||
{4,553,2.1602},
|
||||
{4,616,2.4063},
|
||||
{4,658,2.5703},
|
||||
{6,438,2.5664},
|
||||
{6,466,2.7305},
|
||||
{6,517,3.0293},
|
||||
{6,567,3.3223},
|
||||
{6,616,3.6094},
|
||||
{6,666,3.9023},
|
||||
{6,719,4.2129},
|
||||
{6,772,4.5234},
|
||||
{6,822,4.8164},
|
||||
{6,873,5.1152},
|
||||
{6,910,5.3320},
|
||||
{6,948,5.5547}};
|
||||
uint16_t Mcsindextable1[29][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616},
|
||||
{4,658},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}};
|
||||
//Table 5.1.2.2-2
|
||||
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824};
|
||||
|
||||
@@ -67,9 +40,9 @@ uint32_t nr_compute_tbs(uint8_t mcs,
|
||||
uint16_t length_dmrs,
|
||||
uint8_t Nl)
|
||||
{
|
||||
uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh, Ninfo,Np_info,n,Qm,R,C;
|
||||
|
||||
uint32_t nr_tbs = 0;//Initialization to remove [-Wmaybe-uninitialized]
|
||||
uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh,Qm,R;
|
||||
uint32_t nr_tbs=0;
|
||||
double Ninfo,Np_info,n,C;
|
||||
|
||||
nb_rb_oh = 0; //set to 0 if not configured by higher layer
|
||||
Qm = Mcsindextable1[mcs][0];
|
||||
@@ -81,17 +54,17 @@ uint32_t nr_compute_tbs(uint8_t mcs,
|
||||
nb_re = min(156, nbp_re) * nb_rb;
|
||||
|
||||
// Intermediate number of information bits
|
||||
Ninfo = (nb_re * R * Qm * Nl)/1024;
|
||||
Ninfo = (double)((nb_re * R * Qm * Nl)/1024);
|
||||
|
||||
//printf("Ninfo %d nbp_re %d nb_re %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re, Qm, R);
|
||||
//printf("Ninfo %lf nbp_re %d nb_re %d mcs %d Qm %d, R %d\n", Ninfo, nbp_re, nb_re,mcs, Qm, R);
|
||||
|
||||
if (Ninfo <=3824) {
|
||||
|
||||
n = max(3, floor(log2(Ninfo)) - 6);
|
||||
Np_info = max(24, pow(n,2) * floor(Ninfo/pow(n,2)));
|
||||
Np_info = max(24, pow(2,n) * floor(Ninfo/pow(2,n)));
|
||||
|
||||
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
|
||||
if (Tbstable_nr[i] >= Np_info){
|
||||
if ((double)Tbstable_nr[i] >= Np_info){
|
||||
nr_tbs = Tbstable_nr[i];
|
||||
break;
|
||||
}
|
||||
@@ -99,19 +72,21 @@ uint32_t nr_compute_tbs(uint8_t mcs,
|
||||
}
|
||||
else {
|
||||
n = floor(log2(Ninfo-24)) - 5;
|
||||
Np_info = max(3840, pow(n,2) * round((Ninfo - 24)/pow(n,2)));
|
||||
Np_info = max(3840, pow(2,n) * round((Ninfo - 24)/pow(2,n)));
|
||||
|
||||
if (R <= 1024/4) {
|
||||
if (R <= 256) { //1/4
|
||||
C = ceil( (Np_info + 24)/3816 );
|
||||
nr_tbs = 8 * C * ceil( (Np_info + 24)/(8*C) ) - 24;
|
||||
nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
|
||||
}
|
||||
else {
|
||||
if (Np_info > 8424){
|
||||
C = ceil( (Np_info + 24)/8424 );
|
||||
nr_tbs = 8 * C * ceil( (Np_info + 24)/(8*C) ) - 24;
|
||||
nr_tbs = (uint32_t)(8 * C * ceil( (Np_info + 24)/(8*C) ) - 24);
|
||||
}
|
||||
else {
|
||||
nr_tbs = (uint32_t)(8 * ceil( (Np_info + 24)/8 ) - 24);
|
||||
//printf("n %lf Np_info %f pow %f ceil %f \n",n, Np_info,pow(2,6),ceil( (Np_info + 24)/8 ));
|
||||
}
|
||||
else
|
||||
nr_tbs = 8 * ceil( (Np_info + 24)/8 ) - 24;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
|
||||
|
||||
//Parse the list. If the node is already created, return without initialization.
|
||||
while (currentPtr != NULL) {
|
||||
// printf("currentPtr->idx %d, (%d,%d,%d)\n",currentPtr->idx,messageType,messageLength,aggregation_prime);
|
||||
printf("currentPtr->idx %d, (%d,%d)\n",currentPtr->idx,currentPtr->payloadBits,currentPtr->encoderLength);
|
||||
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
|
||||
else currentPtr = currentPtr->nextPtr;
|
||||
}
|
||||
@@ -64,6 +64,7 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
|
||||
|
||||
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
|
||||
newPolarInitNode->nextPtr = NULL;
|
||||
printf("newPolarInitNode->idx %d, (%d,%d,%d:%d)\n",newPolarInitNode->idx,messageType,messageLength,aggregation_prime,aggregation_level);
|
||||
|
||||
if (messageType == 0) { //PBCH
|
||||
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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: nr_rate_matching.c
|
||||
purpose: Procedures for rate matching/interleaving for NR LDPC
|
||||
author: hongzhi.wang@tcl.com
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
//#define RM_DEBUG 1
|
||||
|
||||
uint8_t index_k0[2][4] = {{0,17,33,56},{0,13,25,43}};
|
||||
|
||||
|
||||
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
|
||||
{
|
||||
uint32_t EQm;
|
||||
|
||||
EQm = E/Qm;
|
||||
memset(f,0,E*sizeof(uint8_t));
|
||||
|
||||
for (int j = 0; j< EQm; j++){
|
||||
for (int i = 0; i< Qm; i++){
|
||||
f[(i+j*Qm)] = e[(i*EQm + j)];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
|
||||
{
|
||||
|
||||
uint32_t EQm;
|
||||
|
||||
EQm = E/Qm;
|
||||
|
||||
for (int j = 0; j< EQm; j++){
|
||||
for (int i = 0; i< Qm; i++){
|
||||
e[(i*EQm + j)] = f[(i+j*Qm)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
|
||||
uint32_t Tbslbrm,
|
||||
uint8_t BG,
|
||||
uint16_t Z,
|
||||
uint32_t G,
|
||||
uint8_t *w,
|
||||
uint8_t *e,
|
||||
uint8_t C,
|
||||
uint8_t rvidx,
|
||||
uint8_t Qm,
|
||||
uint8_t Nl,
|
||||
uint8_t r)
|
||||
{
|
||||
uint8_t Cprime;
|
||||
uint32_t Ncb,E,ind,k,Nref,N;
|
||||
uint8_t *e2;
|
||||
|
||||
AssertFatal(Nl>0,"Nl is 0\n");
|
||||
AssertFatal(Qm>0,"Qm is 0\n");
|
||||
|
||||
//Bit selection
|
||||
N = (BG==1)?(66*Z):(50*Z);
|
||||
|
||||
if (Ilbrm == 0)
|
||||
Ncb = N;
|
||||
else {
|
||||
Nref = 3*Tbslbrm/(2*C); //R_LBRM = 2/3
|
||||
Ncb = min(N, Nref);
|
||||
}
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
printf("nr_rate_matching: Ncb %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",Ncb,rvidx, G, Qm,Nl,r);
|
||||
#endif
|
||||
|
||||
Cprime = C; //assume CBGTI not present
|
||||
|
||||
if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
|
||||
E = Nl*Qm*(G/(Nl*Qm*Cprime));
|
||||
else
|
||||
E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
|
||||
|
||||
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
printf("nr_rate_matching: E %d, k0 %d Cprime %d modcprime %d\n",E,ind, Cprime,((G/(Nl*Qm))%Cprime));
|
||||
#endif
|
||||
|
||||
e2 = e;
|
||||
|
||||
k=0;
|
||||
|
||||
for (; (ind<Ncb)&&(k<E); ind++) {
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
|
||||
#endif
|
||||
|
||||
if (w[ind] != NR_NULL) e2[k++]=w[ind];
|
||||
}
|
||||
|
||||
while(k<E) {
|
||||
for (ind=0; (ind<Ncb)&&(k<E); ind++) {
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
|
||||
#endif
|
||||
|
||||
if (w[ind] != NR_NULL) e2[k++]=w[ind];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
|
||||
uint32_t Tbslbrm,
|
||||
uint8_t BG,
|
||||
uint16_t Z,
|
||||
uint32_t G,
|
||||
int16_t *w,
|
||||
int16_t *soft_input,
|
||||
uint8_t C,
|
||||
uint8_t rvidx,
|
||||
uint8_t clear,
|
||||
uint8_t Qm,
|
||||
uint8_t Nl,
|
||||
uint8_t r,
|
||||
uint32_t *E_out)
|
||||
{
|
||||
uint8_t Cprime;
|
||||
uint32_t Ncb,E,ind,k,Nref,N;
|
||||
|
||||
int16_t *soft_input2;
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
int nulled=0;
|
||||
#endif
|
||||
|
||||
if (C==0 || Qm==0 || Nl==0) {
|
||||
printf("nr_rate_matching: invalid parameters (C %d, Qm %d, Nl %d\n",C,Qm,Nl);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
AssertFatal(Nl>0,"Nl is 0\n");
|
||||
AssertFatal(Qm>0,"Qm is 0\n");
|
||||
|
||||
//Bit selection
|
||||
N = (BG==1)?(66*Z):(50*Z);
|
||||
|
||||
if (Ilbrm == 0)
|
||||
Ncb = N;
|
||||
else {
|
||||
Nref = (3*Tbslbrm/(2*C)); //R_LBRM = 2/3
|
||||
Ncb = min(N, Nref);
|
||||
}
|
||||
|
||||
Cprime = C; //assume CBGTI not present
|
||||
|
||||
if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
|
||||
E = Nl*Qm*(G/(Nl*Qm*Cprime));
|
||||
else
|
||||
E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
|
||||
|
||||
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, Ncb %d,rvidx %d, G %d, Qm %d, Nl%d, r %d\n",clear,E,Ncb,rvidx, G, Qm,Nl,r);
|
||||
#endif
|
||||
|
||||
if (clear==1)
|
||||
memset(w,0,Ncb*sizeof(int16_t));
|
||||
|
||||
soft_input2 = soft_input;
|
||||
k=0;
|
||||
|
||||
for (; (ind<Ncb)&&(k<E); ind++) {
|
||||
if (soft_input2[ind] != NR_NULL) {
|
||||
w[ind] += soft_input2[k++];
|
||||
#ifdef RM_DEBUG
|
||||
printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
else {
|
||||
printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
|
||||
nulled++;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
while(k<E) {
|
||||
for (ind=0; (ind<Ncb)&&(k<E); ind++) {
|
||||
if (soft_input2[ind] != NR_NULL) {
|
||||
w[ind] += soft_input2[k++];
|
||||
#ifdef RM_DEBUG
|
||||
printf("RM_RX k%d Ind: %d (%d)(soft in %d)\n",k-1,ind,w[ind],soft_input2[k-1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RM_DEBUG
|
||||
else {
|
||||
printf("RM_RX Ind: %d NULL %d\n",ind,nulled);
|
||||
nulled++;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
*E_out = E;
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -33,14 +33,12 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
unsigned char **output_buffers,
|
||||
unsigned int B,
|
||||
unsigned int *C,
|
||||
unsigned int *Kplus,
|
||||
unsigned int *Kminus,
|
||||
unsigned int *K,
|
||||
unsigned int *Zout,
|
||||
unsigned int *F)
|
||||
{
|
||||
|
||||
|
||||
unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,Kprime;//crc
|
||||
unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime;
|
||||
|
||||
if (B<=8448) {
|
||||
L=0;
|
||||
@@ -60,13 +58,13 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
}
|
||||
|
||||
if ((*C)>MAX_NUM_DLSCH_SEGMENTS) {
|
||||
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
|
||||
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// Find K+
|
||||
Bprime_by_C = Bprime/(*C);
|
||||
/*if (Bprime <=192) {
|
||||
if (Bprime <=192) {
|
||||
Kb = 6;
|
||||
} else if (Bprime <=560) {
|
||||
Kb = 8;
|
||||
@@ -74,9 +72,9 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
Kb = 9;
|
||||
} else if (Bprime <=3840) {
|
||||
Kb = 10;;
|
||||
} else {*/
|
||||
} else {
|
||||
Kb = 22;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
if ((Bprime_by_C%Kb) > 0)
|
||||
@@ -89,97 +87,85 @@ else
|
||||
#endif
|
||||
|
||||
if (Z <= 2) {
|
||||
*Kplus = 2;
|
||||
*Kminus = 0;
|
||||
*K = 2;
|
||||
} else if (Z<=16) { // increase by 1 byte til here
|
||||
*Kplus = Z;
|
||||
*Kminus = Z-1;
|
||||
*K = Z;
|
||||
} else if (Z <=32) { // increase by 2 bytes til here
|
||||
*Kplus = (Z>>1)<<1;
|
||||
*K = (Z>>1)<<1;
|
||||
|
||||
if (*Kplus < Z)
|
||||
*Kplus = *Kplus + 2;
|
||||
if (*K < Z)
|
||||
*K = *K + 2;
|
||||
|
||||
*Kminus = (*Kplus - 2);
|
||||
} else if (Z <= 64) { // increase by 4 bytes til here
|
||||
*Kplus = (Z>>2)<<2;
|
||||
*K = (Z>>2)<<2;
|
||||
|
||||
if (*Kplus < Z)
|
||||
*Kplus = *Kplus + 4;
|
||||
if (*K < Z)
|
||||
*K = *K + 4;
|
||||
|
||||
*Kminus = (*Kplus - 4);
|
||||
} else if (Z <=128 ) { // increase by 8 bytes til here
|
||||
|
||||
*Kplus = (Z>>3)<<3;
|
||||
*K = (Z>>3)<<3;
|
||||
|
||||
if (*Kplus < Z)
|
||||
*Kplus = *Kplus + 8;
|
||||
if (*K < Z)
|
||||
*K = *K + 8;
|
||||
|
||||
#ifdef DEBUG_SEGMENTATION
|
||||
printf("Z_by_C %d , Kplus2 %d\n",Z,*Kplus);
|
||||
printf("Z_by_C %d , K2 %d\n",Z,*K);
|
||||
#endif
|
||||
*Kminus = (*Kplus - 8);
|
||||
} else if (Z <= 256) { // increase by 4 bytes til here
|
||||
*Kplus = (Z>>4)<<4;
|
||||
*K = (Z>>4)<<4;
|
||||
|
||||
if (*Kplus < Z)
|
||||
*Kplus = *Kplus + 16;
|
||||
if (*K < Z)
|
||||
*K = *K + 16;
|
||||
|
||||
*Kminus = (*Kplus - 16);
|
||||
} else if (Z <= 384) { // increase by 4 bytes til here
|
||||
*Kplus = (Z>>5)<<5;
|
||||
*K = (Z>>5)<<5;
|
||||
|
||||
if (*Kplus < Z)
|
||||
*Kplus = *Kplus + 32;
|
||||
if (*K < Z)
|
||||
*K = *K + 32;
|
||||
|
||||
*Kminus = (*Kplus - 32);
|
||||
} else {
|
||||
//msg("nr_segmentation.c: Illegal codeword size !!!\n");
|
||||
return(-1);
|
||||
}
|
||||
*Zout = *Kplus;
|
||||
*Kplus = *Kplus*Kb;
|
||||
*Kminus = *Kminus*Kb;
|
||||
*Zout = *K;
|
||||
*K = *K*Kb;
|
||||
|
||||
|
||||
|
||||
*F = ((*C)*(*Kplus) - (Bprime));
|
||||
*F = ((*K) - Bprime_by_C);
|
||||
|
||||
#ifdef DEBUG_SEGMENTATION
|
||||
printf("final nr seg output Z %d Kplus %d F %d \n", *Zout, *Kplus, *F);
|
||||
printf("C %d, Kplus %d, Kminus %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*Kplus,*Kminus,Bprime>>3,Bprime,*F);
|
||||
printf("final nr seg output Z %d K %d F %d \n", *Zout, *K, *F);
|
||||
printf("C %d, K %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*K,Bprime>>3,Bprime,*F);
|
||||
#endif
|
||||
|
||||
if ((input_buffer) && (output_buffers)) {
|
||||
|
||||
for (k=0; k<*F>>3; k++) {
|
||||
output_buffers[0][k] = 0;
|
||||
}
|
||||
|
||||
s=0;
|
||||
|
||||
for (r=0; r<*C; r++) {
|
||||
|
||||
//if (r<(B%(*C)))
|
||||
Kprime = *Kplus;
|
||||
//else
|
||||
// Kprime = *Kminus;
|
||||
Kprime = Bprime_by_C;
|
||||
|
||||
while (k<((Kprime - L)>>3)) {
|
||||
output_buffers[r][k] = input_buffer[s];
|
||||
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
|
||||
//printf("encoding segment %d : byte %d (%d) => %d\n",r,k,(Kprime-L)>>3,input_buffer[s]);
|
||||
k++;
|
||||
s++;
|
||||
}
|
||||
|
||||
/*
|
||||
if (*C > 1) { // add CRC
|
||||
crc = crc24b(output_buffers[r],Kprime-24)>>8;
|
||||
output_buffers[r][(Kprime-24)>>3] = ((uint8_t*)&crc)[2];
|
||||
output_buffers[r][1+((Kprime-24)>>3)] = ((uint8_t*)&crc)[1];
|
||||
output_buffers[r][2+((Kprime-24)>>3)] = ((uint8_t*)&crc)[0];
|
||||
if (*F>0)
|
||||
for (k=Kprime>>3; k<(*K)>>3; k++) {
|
||||
output_buffers[r][k] = NR_NULL;
|
||||
//printf("r %d filler bits [%d] = %d Kprime %d \n", r,k, output_buffers[r][k], Kprime);
|
||||
}
|
||||
*/
|
||||
|
||||
if (*C > 1) { // add CRC
|
||||
crc = crc24b(output_buffers[r],Kprime-L)>>8;
|
||||
output_buffers[r][(Kprime-L)>>3] = ((uint8_t*)&crc)[2];
|
||||
output_buffers[r][1+((Kprime-L)>>3)] = ((uint8_t*)&crc)[1];
|
||||
output_buffers[r][2+((Kprime-L)>>3)] = ((uint8_t*)&crc)[0];
|
||||
}
|
||||
|
||||
k=0;
|
||||
}
|
||||
}
|
||||
@@ -193,12 +179,12 @@ else
|
||||
main()
|
||||
{
|
||||
|
||||
unsigned int Kplus,Kminus,C,F,Bbytes;
|
||||
unsigned int K,C,F,Bbytes, Zout;
|
||||
|
||||
for (Bbytes=5; Bbytes<8; Bbytes++) {
|
||||
nr_segmentation(0,0,Bbytes<<3,&C,&Kplus,&Kminus, &F);
|
||||
printf("Bbytes %d : C %d, Kplus %d, Kminus %d, F %d\n",
|
||||
Bbytes, C, Kplus, Kminus, F);
|
||||
nr_segmentation(0,0,Bbytes<<3,&C,&K,&Zout, &F);
|
||||
printf("Bbytes %d : C %d, K %d, F %d\n",
|
||||
Bbytes, C, K, F);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "RadioResourceConfigCommonSIB.h"
|
||||
#include "RadioResourceConfigDedicated.h"
|
||||
#include "TDD-Config.h"
|
||||
@@ -146,6 +147,27 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
||||
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
||||
|
||||
|
||||
//PDSCH DMRS init
|
||||
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t***));
|
||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t**));
|
||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++){
|
||||
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t*));
|
||||
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++) {
|
||||
pdsch_dmrs[slot][symb][q] = (uint32_t*)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
||||
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
||||
/// Transport init necessary for NR synchro
|
||||
init_nr_transport(gNB);
|
||||
|
||||
/*
|
||||
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
|
||||
generate_pcfich_reg_mapping(fp);
|
||||
@@ -451,3 +473,69 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config)
|
||||
|
||||
|
||||
}
|
||||
|
||||
void init_nr_transport(PHY_VARS_gNB *gNB) {
|
||||
|
||||
int i;
|
||||
int j;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||
|
||||
LOG_I(PHY, "Initialise nr transport\n");
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
||||
for (j=0; j<2; j++) {
|
||||
gNB->dlsch[i][j] = new_gNB_dlsch(1,16,NSOFT,0,fp,cfg);
|
||||
if (!gNB->dlsch[i][j]) {
|
||||
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
||||
exit(-1);
|
||||
}/* else {
|
||||
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_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||
//gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
|
||||
|
||||
/*if (!gNB->ulsch[1+i]) {
|
||||
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
||||
exit(-1);
|
||||
}*/
|
||||
|
||||
// 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
|
||||
//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);
|
||||
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);
|
||||
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
|
||||
gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
|
||||
LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH);
|
||||
|
||||
|
||||
gNB->rx_total_gain_dB=130;
|
||||
|
||||
for(i=0; i<NUMBER_OF_UE_MAX; i++)
|
||||
gNB->mu_mimo_mode[i].dl_pow_off = 2;
|
||||
|
||||
gNB->check_for_total_transmissions = 0;
|
||||
|
||||
gNB->check_for_MUMIMO_transmissions = 0;
|
||||
|
||||
gNB->FULL_MUMIMO_transmissions = 0;
|
||||
|
||||
gNB->check_for_SUMIMO_transmissions = 0;
|
||||
|
||||
//fp->pucch_config_common.deltaPUCCH_Shift = 1;
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <math.h>
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
//#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
#include "PHY/NR_REFSIG/pss_nr.h"
|
||||
@@ -816,10 +816,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
|
||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->llr = (int16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->llr16 = (int16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->wbar = (int16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int16_t*)malloc16_clear( 4*2*100*12 );
|
||||
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||
(*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
|
||||
@@ -912,7 +912,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
|
||||
|
||||
int i,j,k;
|
||||
@@ -920,25 +919,25 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
|
||||
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
|
||||
for (j=0; j<2; j++) {
|
||||
for (k=0; k<2; k++) {
|
||||
AssertFatal((ue->dlsch[k][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_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[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[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
|
||||
|
||||
ue->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
|
||||
ue->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_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->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_eNB==1 ? 1 : 2;
|
||||
}
|
||||
|
||||
//ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
|
||||
|
||||
ue->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0);
|
||||
ue->dlsch_MCH[0] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0);
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
void phy_init_nr_top(PHY_VARS_NR_UE *ue)
|
||||
{
|
||||
|
||||
@@ -385,6 +385,7 @@ void nr_phy_config_request(NR_PHY_Config_t *gNB);
|
||||
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu);
|
||||
void phy_free_nr_gNB(PHY_VARS_gNB *gNB);
|
||||
int l1_north_init_gNB(void);
|
||||
void init_nr_transport(PHY_VARS_gNB *gNB);
|
||||
|
||||
void init_dfts(void);
|
||||
|
||||
|
||||
@@ -58,9 +58,6 @@ char lte_cqi_snr_dB[15] = { -2,
|
||||
|
||||
unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1,1,1,0,0,0};
|
||||
|
||||
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||
|
||||
int qam64_table[8],qam16_table[4],qpsk_table[2];
|
||||
|
||||
unsigned char cs_ri_normal[4] = {1,4,7,10};
|
||||
|
||||
@@ -49,7 +49,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
unsigned char symbol = l;//+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
|
||||
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
unsigned int subframe_offset;//,subframe_offset_F;
|
||||
//unsigned int subframe_offset;//,subframe_offset_F;
|
||||
unsigned int slot_offset;
|
||||
//int i;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||
@@ -57,13 +57,10 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns>>1]][0];
|
||||
uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB;
|
||||
uint16_t nb_rb_coreset = 24;
|
||||
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;
|
||||
uint16_t nb_rb_pdsch = 100;
|
||||
|
||||
/*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
|
||||
unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
|
||||
LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
|
||||
int uespec_pilot[9][1200];*/
|
||||
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset+516;
|
||||
uint16_t nb_rb_pdsch = 50;
|
||||
uint8_t p=0;
|
||||
uint8_t l0 = 2;
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||
@@ -107,11 +104,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
if (no_prefix) {
|
||||
subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot*frame_parms->slots_per_subframe) * (Ns>>1);
|
||||
} else {
|
||||
subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
|
||||
slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
|
||||
slot_offset = (frame_parms->samples_per_subframe) * (Ns>>1);
|
||||
}
|
||||
|
||||
/*if (l<0 || l>=7-frame_parms->Ncp) {
|
||||
@@ -129,7 +124,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
|
||||
rx_offset = sample_offset + slot_offset + nb_prefix_samples0 - SOFFSET;
|
||||
// Align with 256 bit
|
||||
// rx_offset = rx_offset&0xfffffff8;
|
||||
|
||||
@@ -167,7 +162,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
|
||||
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
|
||||
|
||||
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
|
||||
(void *)&common_vars->rxdata[aa][0],
|
||||
@@ -196,7 +190,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset);
|
||||
printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns)&1].frame_rx, symbol,rx_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -272,12 +266,18 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
|
||||
ue->frame_parms.nushift = (p>>1)&1;;
|
||||
|
||||
if (symbol ==l0)
|
||||
nr_pdsch_channel_estimation(ue,eNB_id,0,
|
||||
Ns,
|
||||
p,
|
||||
l,
|
||||
symbol,
|
||||
bwp_start_subcarrier,
|
||||
nb_rb_pdsch);
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
|
||||
@@ -30,25 +30,12 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
//#define DEBUG_DL_DMRS
|
||||
//#define DEBUG_PDCCH
|
||||
//#define NR_PBCH_DMRS_LENGTH_DWORD 5
|
||||
//#define NR_PBCH_DMRS_LENGTH 144
|
||||
|
||||
#ifdef USER_MODE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "refsig_defs_ue.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "nr_mod_table.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#ifdef LOG_I
|
||||
#undef LOG_I
|
||||
#define LOG_I(A,B...) printf(B)
|
||||
#endif
|
||||
/*Table 7.4.1.1.2-1/2 from 38.211 */
|
||||
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
|
||||
int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
|
||||
@@ -56,102 +43,28 @@ int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1
|
||||
int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}};
|
||||
|
||||
|
||||
short nr_rx_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170};
|
||||
short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170};
|
||||
short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170};
|
||||
|
||||
/*int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned int Ns,
|
||||
unsigned int nr_gold_pdcch[7][20][3][10],
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
int length_dmrs,
|
||||
unsigned short nb_rb_coreset)
|
||||
{
|
||||
int32_t qpsk[4],n;
|
||||
int w,ind,l,ind_dword,ind_qpsk_symb,kp,k;
|
||||
short pamp;
|
||||
pamp = ONE_OVER_SQRT2_Q15;
|
||||
|
||||
// This includes complex conjugate for channel estimation
|
||||
((short *)&qpsk[0])[0] = pamp;
|
||||
((short *)&qpsk[0])[1] = -pamp;
|
||||
((short *)&qpsk[1])[0] = -pamp;
|
||||
((short *)&qpsk[1])[1] = -pamp;
|
||||
((short *)&qpsk[2])[0] = pamp;
|
||||
((short *)&qpsk[2])[1] = pamp;
|
||||
((short *)&qpsk[3])[0] = -pamp;
|
||||
((short *)&qpsk[3])[1] = pamp;
|
||||
|
||||
if (p==2000) {
|
||||
for (n=0; n<nb_rb_coreset*3; n++) {
|
||||
for (l =0; l<length_dmrs; l++){
|
||||
for (kp=0; kp<3; kp++){
|
||||
|
||||
ind = 3*n+kp;
|
||||
ind_dword = ind>>4;
|
||||
ind_qpsk_symb = ind&0xf;
|
||||
|
||||
output[k] = qpsk[(nr_gold_pdcch[eNB_offset][Ns][l][ind_dword]>>(2*ind_qpsk_symb))&3];
|
||||
|
||||
#ifdef DEBUG_DL_DMRS
|
||||
LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n",
|
||||
Ns,p,idx_dword,idx_qpsk_symb);
|
||||
LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lprime][ind_dword]>>(2*ind_qpsk_symb))&3);
|
||||
#endif
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"Illegal PDCCH DMRS port %d\n",p);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}*/
|
||||
|
||||
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned int Ns,
|
||||
unsigned int nr_gold_pdsch[2][20][2][21],
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
int length_dmrs,
|
||||
unsigned short nb_rb_pdsch)
|
||||
unsigned int Ns,
|
||||
unsigned int *nr_gold_pdsch,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pdsch_rb)
|
||||
{
|
||||
int32_t qpsk[4],nqpsk[4],*qpsk_p, n;
|
||||
//int w,mprime,ind,l,ind_dword,ind_qpsk_symb,kp,lp, config_type, k;
|
||||
int w,ind,ind_dword,ind_qpsk_symb,kp,lp, config_type, k=0;
|
||||
short pamp;
|
||||
int8_t w,config_type;
|
||||
short *mod_table;
|
||||
unsigned char idx=0;
|
||||
|
||||
typedef int array_of_w[2];
|
||||
array_of_w *wf;
|
||||
array_of_w *wt;
|
||||
|
||||
config_type = 1;
|
||||
printf("dmrs config type %d port %d\n", config_type, p);
|
||||
|
||||
// Compute the correct pilot amplitude, sqrt_rho_b = Q3.13
|
||||
pamp = ONE_OVER_SQRT2_Q15;
|
||||
|
||||
// This includes complex conjugate for channel estimation
|
||||
((short *)&qpsk[0])[0] = pamp;
|
||||
((short *)&qpsk[0])[1] = -pamp;
|
||||
((short *)&qpsk[1])[0] = -pamp;
|
||||
((short *)&qpsk[1])[1] = -pamp;
|
||||
((short *)&qpsk[2])[0] = pamp;
|
||||
((short *)&qpsk[2])[1] = pamp;
|
||||
((short *)&qpsk[3])[0] = -pamp;
|
||||
((short *)&qpsk[3])[1] = pamp;
|
||||
|
||||
((short *)&nqpsk[0])[0] = -pamp;
|
||||
((short *)&nqpsk[0])[1] = pamp;
|
||||
((short *)&nqpsk[1])[0] = pamp;
|
||||
((short *)&nqpsk[1])[1] = pamp;
|
||||
((short *)&nqpsk[2])[0] = -pamp;
|
||||
((short *)&nqpsk[2])[1] = -pamp;
|
||||
((short *)&nqpsk[3])[0] = pamp;
|
||||
((short *)&nqpsk[3])[1] = -pamp;
|
||||
config_type = 0; //to be updated by higher layer
|
||||
|
||||
wf = (config_type==0) ? wf1 : wf2;
|
||||
wt = (config_type==0) ? wt1 : wt2;
|
||||
@@ -160,31 +73,26 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type);
|
||||
|
||||
if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) {
|
||||
if (ue->frame_parms.Ncp == NORMAL) {
|
||||
|
||||
// r_n from 38.211 7.4.1.1
|
||||
for (n=0; n<nb_rb_pdsch*((config_type==0) ? 3:2); n++) {
|
||||
for (lp =0; lp<length_dmrs; lp++){
|
||||
for (kp=0; kp<2; kp++){
|
||||
w = (wf[p-1000][kp])*(wt[p-1000][lp]);
|
||||
qpsk_p = (w==1) ? qpsk : nqpsk;
|
||||
for (int i=0; i<nb_pdsch_rb*((config_type==0) ? 6:4); i++) {
|
||||
|
||||
ind = 2*n+kp;
|
||||
ind_dword = ind>>4;
|
||||
ind_qpsk_symb = ind&0xf;
|
||||
w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
|
||||
mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table;
|
||||
|
||||
output[k] = qpsk_p[(nr_gold_pdsch[0][Ns][lp][ind_dword]>>(2*ind_qpsk_symb))&3];
|
||||
|
||||
|
||||
#ifdef DEBUG_DL_DMRS
|
||||
LOG_I(PHY,"Ns %d, p %d, ind_dword %d, ind_qpsk_symbol %d\n",
|
||||
Ns,p,ind_dword,ind_qpsk_symb);
|
||||
LOG_I(PHY,"index = %d\n",(nr_gold_pdsch[0][Ns][lp][ind_dword]>>(2*ind_qpsk_symb))&3);
|
||||
idx = ((((nr_gold_pdsch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdsch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
|
||||
((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
|
||||
((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb);
|
||||
printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
|
||||
printf("i %d idx %d pdsch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pdsch[(i<<1)>>5], (((nr_gold_pdsch[(i<<1)>>5])>>((i<<1)&0x1f))&1),
|
||||
(((nr_gold_pdsch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]);
|
||||
#endif
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"extended cp not supported for PDSCH DMRS yet\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"Illegal p %d PDSCH DMRS port\n",p);
|
||||
}
|
||||
@@ -256,3 +164,5 @@ int nr_pbch_dmrs_rx(int symbol,unsigned int *nr_gold_pbch,int32_t *output )
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,38 @@
|
||||
% 0 .. "0"
|
||||
% 1,2 .. BPSK(0),BPSK(1)
|
||||
|
||||
K = 1/sqrt(2);
|
||||
|
||||
% Amplitude for BPSK (\f$ 2^15 \times 1/\sqrt{2}\f$)
|
||||
BPSK = 23170;
|
||||
|
||||
% Amplitude for QPSK (\f$ 2^15 \times 1/\sqrt{2}\f$)
|
||||
QPSK = 23170;
|
||||
|
||||
|
||||
% First Amplitude for QAM16 (\f$ 2^15 \times 2/\sqrt{10}\f$)
|
||||
QAM16_n1 = 20724;
|
||||
% Second Amplitude for QAM16 (\f$ 2^15 \times 1/\sqrt{10}\f$)
|
||||
QAM16_n2 = 10362;
|
||||
|
||||
% First Amplitude for QAM64 (\f$ 2^15 \times 4/\sqrt{42}\f$)
|
||||
QAM64_n1 = 20225;
|
||||
% Second Amplitude for QAM64 (\f$ 2^15 \times 2/\sqrt{42}\f$)
|
||||
QAM64_n2 = 10112;
|
||||
% Third Amplitude for QAM64 (\f$ 2^15 \times 1/\sqrt{42}\f$)
|
||||
QAM64_n3 = 5056;
|
||||
|
||||
|
||||
% First Amplitude for QAM256 (\f$ 2^15 \times 8/\sqrt{170}\f$)
|
||||
QAM256_n1 = 20105;
|
||||
% Second Amplitude for QAM256 (\f$ 2^15 \times 4/\sqrt{170}\f$)
|
||||
QAM256_n2 = 10052;
|
||||
% Third Amplitude for QAM256 (\f$ 2^15 \times 2/\sqrt{170}\f$)
|
||||
QAM256_n3 = 5026;
|
||||
% Third Amplitude for QAM256 (\f$ 2^15 \times 1/\sqrt{170}\f$)
|
||||
QAM256_n4 = 2513;
|
||||
|
||||
|
||||
% BPSK
|
||||
for b = 0:1
|
||||
bpsk_table(b+1) = (1 - 2*b)*BPSK + 1j*(1-2*b)*BPSK;
|
||||
@@ -17,12 +43,91 @@ end
|
||||
%% QPSK
|
||||
for r=0:1 %0 -- 1 LS
|
||||
for j=0:1 %0 -- 1 MS
|
||||
%% Formula is dispalayed
|
||||
|
||||
qpsk_table(2*r+j+1) = ((1-r*2)*QPSK + 1j*(1-2*j)*QPSK);
|
||||
end
|
||||
end
|
||||
|
||||
table = [ 0; bpsk_table(:); qpsk_table(:) ];
|
||||
%% QAM16
|
||||
for a=-1:2:1
|
||||
for b=-1:2:1
|
||||
index = (1+a) + (1+b)/2;
|
||||
qam16_table(index+1) = -a*(QAM16_n1 + (b*QAM16_n2));
|
||||
end
|
||||
end
|
||||
|
||||
for b0=0:1
|
||||
for b1=0:1
|
||||
for b2=0:1
|
||||
for b3=0:1
|
||||
qam16_table2(b0*8+b1*4+b2*2+b3*1+1) = qam16_table(b0*2+b2*1+1) + 1j*qam16_table(b1*2+b3*1+1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%% QAM64
|
||||
for a=-1:2:1
|
||||
for b=-1:2:1
|
||||
for c=-1:2:1
|
||||
index = (1+a)*2 + (1+b) + (1+c)/2;
|
||||
qam64_table(index+1) = -a*(QAM64_n1 + b*(QAM64_n2 + (c*QAM64_n3)));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for b0=0:1
|
||||
for b1=0:1
|
||||
for b2=0:1
|
||||
for b3=0:1
|
||||
for b4=0:1
|
||||
for b5=0:1
|
||||
qam64_table2(b0*32+b1*16+b2*8+b3*4+b4*2+b5*1+1) = qam64_table(b0*4+b2*2+b4*1+1) + 1j*qam64_table(b1*4+b3*2+b5*1+1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
%%256QAM
|
||||
%% QAM256 *******************************************************************************************
|
||||
for a=-1:2:1
|
||||
for b=-1:2:1
|
||||
for c=-1:2:1
|
||||
for d = -1:2:1
|
||||
|
||||
index = (1+a)*4 + (1+b)*2 + (1+c)+(1+d)/2;
|
||||
qam256_table(index+1) = -a*(QAM256_n1 + b*(QAM256_n2 + (c*(QAM256_n3+d*QAM256_n4))));
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for b0=0:1
|
||||
for b1=0:1
|
||||
for b2=0:1
|
||||
for b3=0:1
|
||||
for b4=0:1
|
||||
for b5=0:1
|
||||
for b6=0:1
|
||||
for b7=0:1
|
||||
|
||||
%%qam64_table2(b0*32+b1*16+b2*8+b3*4+b4*2+b5*1+1) = qam64_table(b0*4+b2*2+b4*1+1) + 1j*qam64_table(b1*4+b3*2+b5*1+1);
|
||||
qam256_table2(b0*128+b1*64+b2*32+b3*16+b4*8+b5*4+b6*2+b7*1+1) = qam256_table(b0*8+b2*4+b4*2+b6*1+1) + 1j*qam256_table(b1*8+b3*4+b5*2+b7*1+1);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
table = round(K * [ 0; bpsk_table(:); qpsk_table(:);qam16_table2(:); qam64_table2(:);qam256_table2(:) ]);
|
||||
%scatter (real(qam256_table2), imag(qam256_table2), 'x');
|
||||
save mod_table.mat table
|
||||
|
||||
table2 = zeros(1,length(table)*2);
|
||||
@@ -33,7 +138,10 @@ fd = fopen("nr_mod_table.h","w");
|
||||
fprintf(fd,"#define NR_MOD_TABLE_SIZE_SHORT %d\n", length(table)*2);
|
||||
fprintf(fd,"#define NR_MOD_TABLE_BPSK_OFFSET %d\n", 1);
|
||||
fprintf(fd,"#define NR_MOD_TABLE_QPSK_OFFSET %d\n", 3);
|
||||
fprintf(fd,"short nr_mod_table[MOD_TABLE_SIZE_SHORT] = {");
|
||||
fprintf(fd,"#define NR_MOD_TABLE_QAM16_OFFSET %d\n", 7);
|
||||
fprintf(fd,"#define NR_MOD_TABLE_QAM64_OFFSET %d\n", 23);
|
||||
fprintf(fd,"#define NR_MOD_TABLE_QAM256_OFFSET %d\n", 87);
|
||||
fprintf(fd,"short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {");
|
||||
fprintf(fd,"%d,",table2(1:end-1));
|
||||
fprintf(fd,"%d};\n",table2(end));
|
||||
fclose(fd);
|
||||
|
||||
@@ -65,7 +65,7 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
|
||||
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
|
||||
reset = 1;
|
||||
x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1))&(((uint32_t)1<<31)-1);
|
||||
x2 = ((1<<17) * (14*slot+symb+1) * ((Nid<<1)+1) + (Nid<<1));
|
||||
|
||||
for (uint32_t n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
|
||||
pdcch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
@@ -75,3 +75,30 @@ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
|
||||
{
|
||||
|
||||
uint32_t x1, x2;
|
||||
uint8_t reset;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
||||
|
||||
uint16_t N_n_scid[NR_MAX_NB_CODEWORDS]={Nid, Nid}; // Not correct, appropriate scrambling IDs have to be updated to support DCI 1_1
|
||||
uint8_t n_scid=0; // again works only for 1_0
|
||||
for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
for (uint8_t q=0; q<NR_MAX_NB_CODEWORDS; q++) {
|
||||
|
||||
reset = 1;
|
||||
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
|
||||
for (uint32_t n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
|
||||
pdsch_dmrs[slot][symb][q][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
||||
{
|
||||
|
||||
unsigned int n, x1, x2;
|
||||
unsigned char Nid, i_ssb, i_ssb2;
|
||||
unsigned int Nid, i_ssb, i_ssb2;
|
||||
unsigned char Lmax, l, n_hf, N_hf;
|
||||
|
||||
Nid = ue->frame_parms.Nid_cell;
|
||||
@@ -123,6 +123,8 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned short *n_idDM
|
||||
nid = n_idDMRS[nscid];
|
||||
else
|
||||
nid = ue->frame_parms.Nid_cell;
|
||||
|
||||
//printf("gold pdsch nid %d lbar %d\n",nid,lbar);
|
||||
|
||||
for (ns=0; ns<20; ns++) {
|
||||
|
||||
@@ -130,6 +132,8 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned short *n_idDM
|
||||
|
||||
x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit
|
||||
|
||||
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
|
||||
|
||||
x1 = 1+ (1<<31);
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
@@ -143,12 +147,13 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned short *n_idDM
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
}
|
||||
|
||||
for (n=0; n<14; n++) {
|
||||
for (n=0; n<52; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
ue->nr_gold_pdsch[nscid][ns][l][n] = x1^x2;
|
||||
// if ((ns==2)&&(l==0))
|
||||
//printf("n=%d : c %x\n",n,x1^x2);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 14
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 686
|
||||
#define NR_MOD_TABLE_BPSK_OFFSET 1
|
||||
#define NR_MOD_TABLE_QPSK_OFFSET 3
|
||||
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,23170,23170,-23170,-23170,23170,23170,23170,-23170,-23170,23170,-23170,-23170};
|
||||
#define NR_MOD_TABLE_QAM16_OFFSET 7
|
||||
#define NR_MOD_TABLE_QAM64_OFFSET 23
|
||||
#define NR_MOD_TABLE_QAM256_OFFSET 87
|
||||
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
|
||||
|
||||
@@ -37,6 +37,6 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
|
||||
@param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID
|
||||
*/
|
||||
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||
|
||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,13 +43,12 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
unsigned short nb_rb_corset);
|
||||
|
||||
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_offset,
|
||||
unsigned int Ns,
|
||||
unsigned int nr_gold_pdsch[2][20][2][21],
|
||||
unsigned int *nr_gold_pdsch,
|
||||
int32_t *output,
|
||||
unsigned short p,
|
||||
int length_dmrs,
|
||||
unsigned short nb_rb_pdsch);
|
||||
unsigned char lp,
|
||||
unsigned short nb_pdsch_rb);
|
||||
|
||||
void nr_gold_pbch(PHY_VARS_NR_UE* ue);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_dci.c
|
||||
* \brief Implements DCI encoding/decoding and PDCCH TX/RX procedures (38.212/38.213/38.214). V15.2.0 2018-06.
|
||||
* \brief Implements DCI encoding and PDCCH TX procedures (38.212/38.213/38.214). V15.2.0 2018-06.
|
||||
* \author Guy De Souza
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
@@ -336,9 +336,5 @@ printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%0
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DCI
|
||||
write_output("txdataF_dci.m", "txdataF_dci", txdataF[0], frame_parms.samples_per_frame_wCP>>1, 1, 1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
int subframe,
|
||||
gNB_L1_rxtx_proc_t *proc,
|
||||
NR_gNB_DCI_ALLOC_t *dci_alloc,
|
||||
nfapi_nr_dl_config_request_pdu_t *pdu);
|
||||
nfapi_nr_dl_config_dci_dl_pdu *pdu,
|
||||
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu);
|
||||
|
||||
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m);
|
||||
|
||||
|
||||
@@ -31,8 +31,12 @@
|
||||
*/
|
||||
|
||||
#include "nr_dci.h"
|
||||
|
||||
//#define DEBUG_FILL_DCI
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
|
||||
|
||||
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) {
|
||||
|
||||
nr_cce_t* cce;
|
||||
@@ -61,7 +65,7 @@ void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m
|
||||
AssertFatal(cond==0, "CCE to REG interleaving: Invalid configuration leading to non integer C\n");
|
||||
C = N_reg/(bsize*R);
|
||||
|
||||
tmp = L * (( Y + (uint16_t)(floor((m*N_cce)/(L*M_s_max))) + n_CI ) % ((uint16_t)floor(N_cce/L)));
|
||||
tmp = L * (( Y + (m*N_cce)/(L*M_s_max) + n_CI ) % (N_cce/L));
|
||||
|
||||
LOG_I(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d tmp %d\n", m, bsize, R, tmp);
|
||||
for (uint8_t cce_idx=0; cce_idx<L; cce_idx++) {
|
||||
@@ -110,23 +114,27 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
int subframe,
|
||||
gNB_L1_rxtx_proc_t *proc,
|
||||
NR_gNB_DCI_ALLOC_t *dci_alloc,
|
||||
nfapi_nr_dl_config_request_pdu_t *pdu)
|
||||
nfapi_nr_dl_config_dci_dl_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu)
|
||||
{
|
||||
|
||||
uint8_t n_shift;
|
||||
|
||||
|
||||
uint64_t *dci_pdu = (uint64_t*)dci_alloc->dci_pdu;
|
||||
memset((void*)dci_pdu,0,2*sizeof(uint64_t));
|
||||
nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &pdu->dci_dl_pdu.dci_dl_pdu_rel15;
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &pdu->dci_dl_pdu.pdcch_params_rel15;
|
||||
nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &pdcch_pdu->dci_dl_pdu_rel15;
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &pdcch_pdu->pdcch_params_rel15;
|
||||
|
||||
|
||||
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||
|
||||
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
|
||||
NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes;
|
||||
|
||||
uint16_t N_RB = params_rel15->n_RB_BWP;
|
||||
uint8_t fsize=0, pos=0, cand_idx=0;
|
||||
|
||||
|
||||
dci_alloc->L = 8;
|
||||
memcpy((void*)&dci_alloc->pdcch_params, (void*)params_rel15, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t));
|
||||
dci_alloc->size = nr_get_dci_size(dci_alloc->pdcch_params.dci_format,
|
||||
@@ -142,6 +150,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
/// Payload generation
|
||||
switch(params_rel15->dci_format) {
|
||||
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_1_0:
|
||||
switch(params_rel15->rnti_type) {
|
||||
case NFAPI_NR_RNTI_RA:
|
||||
@@ -182,70 +191,76 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
|
||||
case NFAPI_NR_RNTI_C:
|
||||
// indicating a DL DCI format 1bit
|
||||
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos++);
|
||||
pos++;
|
||||
*dci_pdu |= (pdu_rel15->format_indicator&1)<<(dci_alloc->size-pos);
|
||||
// Freq domain assignment (275rb >> fsize = 16)
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
for (int i=0; i<fsize; i++)
|
||||
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=fsize;
|
||||
*dci_pdu |= ((pdu_rel15->frequency_domain_assignment&((1<<fsize)-1)) << (dci_alloc->size-pos));
|
||||
|
||||
if (((pdu_rel15->frequency_domain_assignment+1)&1) ==0) //fsize are all 1 38.212 p86
|
||||
{
|
||||
// ra_preamble_index 6 bits
|
||||
for (int i=0; i<6; i++)
|
||||
*dci_pdu |= ((pdu_rel15->ra_preamble_index>>(5-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=6;
|
||||
*dci_pdu |= ((pdu_rel15->ra_preamble_index&0x3f)<<(dci_alloc->size-pos));
|
||||
|
||||
// UL/SUL indicator 1 bit
|
||||
*dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos++);
|
||||
pos++;
|
||||
*dci_pdu |= (pdu_rel15->ul_sul_indicator&1)<<(dci_alloc->size-pos);
|
||||
|
||||
// SS/PBCH index 6 bits
|
||||
for (int i=0; i<6; i++)
|
||||
*dci_pdu |= ((pdu_rel15->ss_pbch_index>>(5-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=6;
|
||||
*dci_pdu |= ((pdu_rel15->ss_pbch_index&0x3f)<<(dci_alloc->size-pos));
|
||||
|
||||
// prach_mask_index 4 bits
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= ((pdu_rel15->prach_mask_index>>(3-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=4;
|
||||
*dci_pdu |= ((pdu_rel15->prach_mask_index&0xf)<<(dci_alloc->size-pos));
|
||||
|
||||
} //end if
|
||||
|
||||
else {
|
||||
|
||||
// Time domain assignment 4bit
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_alloc->size-pos++);
|
||||
|
||||
pos+=4;
|
||||
*dci_pdu |= ((pdu_rel15->time_domain_assignment&0xf) << (dci_alloc->size-pos));
|
||||
|
||||
|
||||
// VRB to PRB mapping 1bit
|
||||
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos++);
|
||||
pos++;
|
||||
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<(dci_alloc->size-pos);
|
||||
|
||||
// MCS 5bit //bit over 32, so dci_pdu ++
|
||||
for (int i=0; i<5; i++)
|
||||
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=5;
|
||||
*dci_pdu |= (pdu_rel15->mcs&0x1f)<<(dci_alloc->size-pos);
|
||||
|
||||
// New data indicator 1bit
|
||||
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos++);
|
||||
pos++;
|
||||
*dci_pdu |= (pdu_rel15->ndi&1)<<(dci_alloc->size-pos);
|
||||
|
||||
// Redundancy version 2bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= ((pdu_rel15->rv>>(1-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=2;
|
||||
*dci_pdu |= (pdu_rel15->rv&0x3)<<(dci_alloc->size-pos);
|
||||
|
||||
// HARQ process number 4bit
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= ((pdu_rel15->harq_pid>>(3-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=4;
|
||||
*dci_pdu |= ((pdu_rel15->harq_pid&0xf)<<(dci_alloc->size-pos));
|
||||
|
||||
// Downlink assignment index 2bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= ((pdu_rel15->dai>>(1-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=2;
|
||||
*dci_pdu |= ((pdu_rel15->dai&3)<<(dci_alloc->size-pos));
|
||||
|
||||
// TPC command for scheduled PUCCH 2bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= ((pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=2;
|
||||
*dci_pdu |= ((pdu_rel15->tpc&3)<<(dci_alloc->size-pos));
|
||||
|
||||
// PUCCH resource indicator 3bit
|
||||
for (int i=0; i<3; i++)
|
||||
*dci_pdu |= ((pdu_rel15->pucch_resource_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=3;
|
||||
*dci_pdu |= ((pdu_rel15->pucch_resource_indicator&0x7)<<(dci_alloc->size-pos));
|
||||
|
||||
// PDSCH-to-HARQ_feedback timing indicator 3bit
|
||||
for (int i=0; i<3; i++)
|
||||
*dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
|
||||
pos+=3;
|
||||
*dci_pdu |= ((pdu_rel15->pdsch_to_harq_feedback_timing_indicator&0x7)<<(dci_alloc->size-pos));
|
||||
|
||||
} //end else
|
||||
break;
|
||||
@@ -275,6 +290,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= ((pdu_rel15->tb_scaling>>(1-i))&1)<<(dci_alloc->size-pos++);
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case NFAPI_NR_RNTI_SI:
|
||||
@@ -328,9 +344,10 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= ((pdu_rel15->tpc>>(1-i))&1)<<(dci_alloc->size-pos++);
|
||||
|
||||
// PUCCH resource indicator – 3 bits
|
||||
for (int i=0; i<3; i++)
|
||||
*dci_pdu |= ((pdu_rel15->pucch_resource_indicator>>(2-i))&1)<<(dci_alloc->size-pos++);
|
||||
|
||||
// LOG_I(PHY, "DCI PDU: [0]->0x%08llx \t [1]->0x%08llx \t [2]->0x%08llx \t [3]->0x%08llx\n",
|
||||
// dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
|
||||
|
||||
|
||||
// PDSCH-to-HARQ_feedback timing indicator – 3 bits
|
||||
for (int i=0; i<3; i++)
|
||||
@@ -425,4 +442,7 @@ void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
|
||||
LOG_I(PHY, "DCI PDU: [0]->0x%16llxx \t [1]->0x%16llx \n",(long long unsigned int)dci_pdu[0], (long long unsigned int)dci_pdu[1]);
|
||||
LOG_I(PHY, "DCI type %d payload (size %d) generated on candidate %d\n", dci_alloc->pdcch_params.dci_format, dci_alloc->size, cand_idx);
|
||||
|
||||
/// DLSCH struct
|
||||
memcpy((void*)&harq[dci_alloc->harq_pid]->dlsch_pdu, (void*)dlsch_pdu, sizeof(nfapi_nr_dl_config_dlsch_pdu));
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* 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_TRANSPORT/dlsch_decoding.c
|
||||
* \brief Top-level routines for transmission of the PDSCH 38211 v 15.2.0
|
||||
* \author Guy De Souza
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: desouza@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
#include "nr_dci.h"
|
||||
#include "nr_sch_dmrs.h"
|
||||
|
||||
//#define DEBUG_DLSCH
|
||||
//#define DEBUG_DLSCH_MAPPING
|
||||
|
||||
uint8_t mod_order[5] = {1, 2, 4, 6, 8};
|
||||
uint16_t mod_offset[5] = {1,3,7,23,87};
|
||||
|
||||
void nr_pdsch_codeword_scrambling(uint8_t *in,
|
||||
uint16_t size,
|
||||
uint8_t q,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI,
|
||||
uint32_t* out) {
|
||||
|
||||
uint8_t reset, b_idx;
|
||||
uint32_t x1, x2, s=0;
|
||||
|
||||
reset = 1;
|
||||
x2 = (n_RNTI<<15) + (q<<14) + Nid;
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
b_idx = i&0x1f;
|
||||
if (b_idx==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
if (i)
|
||||
out++;
|
||||
}
|
||||
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
|
||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void nr_modulation(uint32_t *in,
|
||||
uint16_t length,
|
||||
nr_mod_t modulation_type,
|
||||
int16_t *out) {
|
||||
|
||||
uint16_t offset;
|
||||
uint16_t order;
|
||||
order = mod_order[modulation_type];
|
||||
offset = mod_offset[modulation_type];
|
||||
|
||||
for (int i=0; i<length/order; i++) {
|
||||
uint8_t idx = 0, b_idx;
|
||||
|
||||
for (int j=0; j<order; j++) {
|
||||
b_idx = (i*order+j)&0x1f;
|
||||
if (i && (!b_idx))
|
||||
in++;
|
||||
idx ^= (((*in)>>b_idx)&1)<<(order-j-1);
|
||||
}
|
||||
|
||||
out[i<<1] = nr_mod_table[(offset+idx)<<1];
|
||||
out[(i<<1)+1] = nr_mod_table[((offset+idx)<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
void nr_pdsch_codeword_modulation(uint32_t *in,
|
||||
uint8_t Qm,
|
||||
uint32_t length,
|
||||
int16_t *out) {
|
||||
|
||||
uint16_t offset = (Qm==2)? NR_MOD_TABLE_QPSK_OFFSET : (Qm==4)? NR_MOD_TABLE_QAM16_OFFSET : \
|
||||
(Qm==6)? NR_MOD_TABLE_QAM64_OFFSET: (Qm==8)? NR_MOD_TABLE_QAM256_OFFSET : 0;
|
||||
AssertFatal(offset, "Invalid modulation order %d\n", Qm);
|
||||
|
||||
for (int i=0; i<length/Qm; i++) {
|
||||
uint8_t idx = 0, b_idx;
|
||||
|
||||
for (int j=0; j<Qm; j++) {
|
||||
b_idx = (i*Qm+j)&0x1f;
|
||||
if (i && (!b_idx))
|
||||
in++;
|
||||
idx ^= (((*in)>>b_idx)&1)<<(Qm-j-1);
|
||||
}
|
||||
|
||||
out[i<<1] = nr_mod_table[(offset+idx)<<1];
|
||||
out[(i<<1)+1] = nr_mod_table[((offset+idx)<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
void nr_pdsch_layer_mapping(int16_t **mod_symbs,
|
||||
uint8_t n_layers,
|
||||
uint16_t n_symbs,
|
||||
int16_t **tx_layers) {
|
||||
|
||||
switch (n_layers) {
|
||||
|
||||
case 1:
|
||||
memcpy((void*)tx_layers[0], (void*)mod_symbs[0], (n_symbs<<1)*sizeof(int16_t));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
for (int i=0; i<n_symbs/n_layers; i++)
|
||||
for (int l=0; l<n_layers; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][(n_layers*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][((n_layers*i+l)<<1)+1];
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
for (int i=0; i<n_symbs>>1; i++)
|
||||
for (int l=0; l<2; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][((i<<1)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<1)+l)<<1)+1];
|
||||
}
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=2; l<5; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
for (int q=0; q<2; q++)
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1];
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
|
||||
}
|
||||
for (int i=0; i<n_symbs/4; i++)
|
||||
for (int l=3; l<7; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][((i<<2)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<2)+l)<<1)+1];
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
for (int q=0; q<2; q++)
|
||||
for (int i=0; i<n_symbs>>2; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[q][((i<<2)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[q][(((i<<2)+l)<<1)+1];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint16_t get_pdsch_dmrs_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) {
|
||||
uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta);
|
||||
return dmrs_idx;
|
||||
}
|
||||
|
||||
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch,
|
||||
NR_gNB_DCI_ALLOC_t dci_alloc,
|
||||
uint32_t ***pdsch_dmrs,
|
||||
int32_t** txdataF,
|
||||
int16_t amp,
|
||||
uint8_t slot,
|
||||
NR_DL_FRAME_PARMS frame_parms,
|
||||
nfapi_nr_config_request_t config) {
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = dlsch.harq_processes[dci_alloc.harq_pid];
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &harq->dlsch_pdu.dlsch_pdu_rel15;
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
int16_t **mod_symbs = (int16_t**)dlsch.mod_symbs;
|
||||
int16_t **tx_layers = (int16_t**)dlsch.txdataF;
|
||||
int8_t Wf[2], Wt[2], l0, l_prime[2], delta;
|
||||
uint16_t nb_symbols = rel15->nb_mod_symbols;
|
||||
uint8_t Qm = rel15->modulation_order;
|
||||
uint16_t encoded_length = nb_symbols*Qm;
|
||||
|
||||
/// CRC, coding, interleaving and rate matching
|
||||
nr_dlsch_encoding(harq->pdu, slot, &dlsch, &frame_parms);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH encoding:\nPayload:\n");
|
||||
for (int i=0; i<TBS>>7; i++) {
|
||||
for (int j=0; j<16; j++)
|
||||
printf("0x%02x\t", harq->pdu[(i<<4)+j]);
|
||||
printf("\n");
|
||||
}
|
||||
printf("\nEncoded payload:\n");
|
||||
for (int i=0; i<encoded_length>>3; i++) {
|
||||
for (int j=0; j<8; j++)
|
||||
printf("%d", harq->f[(i<<3)+j]);
|
||||
printf("\t");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/// scrambling
|
||||
for (int q=0; q<rel15->nb_codewords; q++)
|
||||
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
|
||||
uint16_t n_RNTI = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
|
||||
((pdcch_params.scrambling_id)?pdcch_params.rnti:0) : 0;
|
||||
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? \
|
||||
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
|
||||
for (int q=0; q<rel15->nb_codewords; q++)
|
||||
nr_pdsch_codeword_scrambling(harq->f,
|
||||
encoded_length,
|
||||
q,
|
||||
Nid,
|
||||
n_RNTI,
|
||||
scrambled_output[q]);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH scrambling:\n");
|
||||
for (int i=0; i<encoded_length>>8; i++) {
|
||||
for (int j=0; j<8; j++)
|
||||
printf("0x%08x\t", scrambled_output[0][(i<<3)+j]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Modulation
|
||||
for (int q=0; q<rel15->nb_codewords; q++)
|
||||
nr_pdsch_codeword_modulation(scrambled_output[q],
|
||||
Qm,
|
||||
encoded_length,
|
||||
mod_symbs[q]);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_symbols);
|
||||
for (int i=0; i<nb_symbols>>3; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Layer mapping
|
||||
nr_pdsch_layer_mapping(mod_symbs,
|
||||
rel15->nb_layers,
|
||||
nb_symbols,
|
||||
tx_layers);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("Layer mapping (%d layers):\n", rel15->nb_layers);
|
||||
for (int l=0; l<rel15->nb_layers; l++)
|
||||
for (int i=0; i<(nb_symbols/rel15->nb_layers)>>3; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Antenna port mapping
|
||||
//to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
uint16_t n_dmrs = (rel15->n_prb*rel15->nb_re_dmrs)<<1;
|
||||
int16_t mod_dmrs[n_dmrs<<1];
|
||||
uint8_t dmrs_type = config.pdsch_config.dmrs_type.value;
|
||||
l0 = get_l0(dmrs_type, 2);//config.pdsch_config.dmrs_typeA_position.value);
|
||||
nr_modulation(pdsch_dmrs[l0][0], n_dmrs, MOD_QPSK, mod_dmrs); // currently only codeword 0 is modulated
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_type);
|
||||
for (int i=0; i<n_dmrs>>4; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Resource mapping
|
||||
|
||||
|
||||
// Non interleaved VRB to PRB mapping
|
||||
uint16_t start_sc = frame_parms.first_carrier_offset + frame_parms.ssb_start_subcarrier;
|
||||
if (start_sc >= frame_parms.ofdm_symbol_size)
|
||||
start_sc -= frame_parms.ofdm_symbol_size;
|
||||
/*rel15->start_prb*NR_NB_SC_PER_RB +
|
||||
((pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON) && (pdcch_params.dci_format == NFAPI_NR_DL_DCI_FORMAT_1_0))?\
|
||||
((frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + pdcch_params.rb_offset)*NR_NB_SC_PER_RB) : 0;*/
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n",
|
||||
start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols);
|
||||
#endif
|
||||
|
||||
for (int ap=0; ap<rel15->nb_layers; ap++) {
|
||||
|
||||
// DMRS params for this ap
|
||||
get_Wt(Wt, ap, dmrs_type);
|
||||
get_Wf(Wf, ap, dmrs_type);
|
||||
delta = get_delta(ap, dmrs_type);
|
||||
l_prime[0] = 0; // single symbol ap 0
|
||||
uint8_t dmrs_symbol = l0+l_prime[0];
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
|
||||
ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
|
||||
#endif
|
||||
uint8_t k_prime=0;
|
||||
uint16_t m=0, n=0, dmrs_idx=0, k=0;
|
||||
|
||||
for (int l=rel15->start_symbol; l<rel15->start_symbol+rel15->nb_symbols; l++) {
|
||||
k = start_sc;
|
||||
for (int i=0; i<rel15->n_prb*NR_NB_SC_PER_RB; i++) {
|
||||
// Note the dmrs index modulo 2048 only works for that symbol size -- to be fixed soon
|
||||
// Also the different amplitudes are for debug purposes and temporary
|
||||
if ((l == dmrs_symbol) && (k == ((start_sc+get_pdsch_dmrs_idx(n, k_prime, delta, dmrs_type))&((1<<11)-1)))) {
|
||||
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*(amp>>1)*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*(amp>>1)*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
|
||||
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1],
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1]);
|
||||
#endif
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1] = ((amp<<1) * tx_layers[ap][m<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = ((amp<<1) * tx_layers[ap][(m<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms.ofdm_symbol_size + k)<<1],
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1]);
|
||||
#endif
|
||||
m++;
|
||||
}
|
||||
if (++k >= frame_parms.ofdm_symbol_size)
|
||||
k -= frame_parms.ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/LTE_TRANSPORT/defs.h
|
||||
* \brief data structures for PDSCH/DLSCH/PUSCH/ULSCH physical and transport channel descriptors (TX/RX)
|
||||
* \author R. Knopp
|
||||
* \date 2011
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
|
||||
|
||||
void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
|
||||
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
|
||||
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu);
|
||||
|
||||
void nr_check_time_alloc(uint8_t S, uint8_t L, nfapi_nr_config_request_t config);
|
||||
|
||||
uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB);
|
||||
|
||||
uint16_t get_SLIV(uint8_t S, uint8_t L);
|
||||
|
||||
uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_typeA_position);
|
||||
|
||||
void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type);
|
||||
|
||||
void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list);
|
||||
|
||||
void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type);
|
||||
|
||||
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
|
||||
|
||||
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
|
||||
|
||||
void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
|
||||
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
|
||||
nfapi_nr_config_request_t config);
|
||||
|
||||
void nr_pdsch_codeword_scrambling(uint8_t *in,
|
||||
uint16_t size,
|
||||
uint8_t q,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI,
|
||||
uint32_t* out);
|
||||
|
||||
void nr_pdsch_codeword_modulation(uint32_t *in,
|
||||
uint8_t Qm,
|
||||
uint32_t length,
|
||||
int16_t *out);
|
||||
|
||||
void nr_pdsch_layer_mapping(int16_t **mod_symbs,
|
||||
uint8_t n_layers,
|
||||
uint16_t n_symbs,
|
||||
int16_t **tx_layers);
|
||||
|
||||
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch,
|
||||
NR_gNB_DCI_ALLOC_t dci_alloc,
|
||||
uint32_t ***pdsch_dmrs,
|
||||
int32_t** txdataF,
|
||||
int16_t amp,
|
||||
uint8_t subframe,
|
||||
NR_DL_FRAME_PARMS frame_parms,
|
||||
nfapi_nr_config_request_t config);
|
||||
|
||||
/** \brief Computes available bits G.
|
||||
@param nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs */
|
||||
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm, uint8_t Nl);
|
||||
|
||||
int nr_dlsch_encoding(unsigned char *a,
|
||||
uint8_t subframe,
|
||||
NR_gNB_DLSCH_t *dlsch,
|
||||
NR_DL_FRAME_PARMS* frame_parms);
|
||||
|
||||
void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
|
||||
|
||||
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* 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/LTE_TRANSPORT/dlsch_coding.c
|
||||
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
|
||||
* \author H.Wang
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#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_encoder/defs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.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_DLSCH_CODING
|
||||
//#define DEBUG_DLSCH_FREE 1
|
||||
|
||||
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
|
||||
if (dlsch) {
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch %p\n",dlsch);
|
||||
#endif
|
||||
|
||||
for (i=0; i<dlsch->Mdlharq; i++) {
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch process %d\n",i);
|
||||
#endif
|
||||
|
||||
if (dlsch->harq_processes[i]) {
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]);
|
||||
#endif
|
||||
|
||||
if (dlsch->harq_processes[i]->b) {
|
||||
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
|
||||
dlsch->harq_processes[i]->b = NULL;
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch process %d c (%p)\n",i,dlsch->harq_processes[i]->c);
|
||||
#endif
|
||||
|
||||
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
|
||||
|
||||
#ifdef DEBUG_DLSCH_FREE
|
||||
printf("Freeing dlsch process %d c[%d] (%p)\n",i,r,dlsch->harq_processes[i]->c[r]);
|
||||
#endif
|
||||
|
||||
if (dlsch->harq_processes[i]->c[r]) {
|
||||
free16(dlsch->harq_processes[i]->c[r],1056);
|
||||
dlsch->harq_processes[i]->c[r] = NULL;
|
||||
}
|
||||
if (dlsch->harq_processes[i]->d[r]) {
|
||||
free16(dlsch->harq_processes[i]->d[r],3*8448);
|
||||
dlsch->harq_processes[i]->d[r] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
free16(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t));
|
||||
dlsch->harq_processes[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free16(dlsch,sizeof(NR_gNB_DLSCH_t));
|
||||
dlsch = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
|
||||
unsigned char Mdlharq,
|
||||
uint32_t Nsoft,
|
||||
uint8_t abstraction_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_config_request_t *config)
|
||||
{
|
||||
|
||||
NR_gNB_DLSCH_t *dlsch;
|
||||
unsigned char exit_flag = 0,i,r,aa,layer;
|
||||
int re;
|
||||
unsigned char bw_scaling =1;
|
||||
uint16_t N_RB = config->rf_config.dl_carrier_bandwidth.value;
|
||||
|
||||
switch (N_RB) {
|
||||
|
||||
case 106:
|
||||
bw_scaling =2;
|
||||
break;
|
||||
|
||||
default:
|
||||
bw_scaling =1;
|
||||
break;
|
||||
}
|
||||
|
||||
dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t));
|
||||
|
||||
if (dlsch) {
|
||||
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
|
||||
dlsch->Kmimo = Kmimo;
|
||||
dlsch->Mdlharq = Mdlharq;
|
||||
dlsch->Mlimit = 4;
|
||||
dlsch->Nsoft = Nsoft;
|
||||
|
||||
for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
|
||||
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
|
||||
|
||||
for (aa=0; aa<64; aa++) {
|
||||
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
|
||||
for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
|
||||
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
|
||||
}
|
||||
}
|
||||
|
||||
dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH>>1)*sizeof(int32_t*));
|
||||
}
|
||||
|
||||
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
|
||||
dlsch->mod_symbs[q] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH>>1)*sizeof(int32_t*));
|
||||
|
||||
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
|
||||
for (aa=0; aa<64; aa++) {
|
||||
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
|
||||
|
||||
}
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
dlsch->harq_ids[i] = 0;
|
||||
|
||||
|
||||
for (i=0; i<Mdlharq; i++) {
|
||||
dlsch->harq_processes[i] = (NR_DL_gNB_HARQ_t *)malloc16(sizeof(NR_DL_gNB_HARQ_t));
|
||||
LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n",
|
||||
MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling,bw_scaling, i,dlsch->harq_processes[i]);
|
||||
|
||||
if (dlsch->harq_processes[i]) {
|
||||
bzero(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t));
|
||||
// dlsch->harq_processes[i]->first_tx=1;
|
||||
dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
if (dlsch->harq_processes[i]->pdu) {
|
||||
bzero(dlsch->harq_processes[i]->pdu,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
nr_emulate_dlsch_payload(dlsch->harq_processes[i]->pdu, (MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling)>>3);
|
||||
} else {
|
||||
printf("Can't allocate PDU\n");
|
||||
exit_flag=1;
|
||||
}
|
||||
|
||||
if (dlsch->harq_processes[i]->b) {
|
||||
bzero(dlsch->harq_processes[i]->b,MAX_NR_DLSCH_PAYLOAD_BYTES/bw_scaling);
|
||||
} else {
|
||||
printf("Can't get b\n");
|
||||
exit_flag=1;
|
||||
}
|
||||
|
||||
if (abstraction_flag==0) {
|
||||
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
|
||||
// account for filler in first segment and CRCs for multiple segment case
|
||||
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
|
||||
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384);
|
||||
if (dlsch->harq_processes[i]->c[r]) {
|
||||
bzero(dlsch->harq_processes[i]->c[r],8448);
|
||||
} else {
|
||||
printf("Can't get c\n");
|
||||
exit_flag=2;
|
||||
}
|
||||
if (dlsch->harq_processes[i]->d[r]) {
|
||||
bzero(dlsch->harq_processes[i]->d[r],(3*8448));
|
||||
} else {
|
||||
printf("Can't get d\n");
|
||||
exit_flag=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("Can't get harq_p %d\n",i);
|
||||
exit_flag=3;
|
||||
}
|
||||
}
|
||||
|
||||
if (exit_flag==0) {
|
||||
for (i=0; i<Mdlharq; i++) {
|
||||
dlsch->harq_processes[i]->round=0;
|
||||
}
|
||||
|
||||
return(dlsch);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n",
|
||||
exit_flag, sizeof(NR_gNB_DLSCH_t));
|
||||
free_gNB_dlsch(dlsch);
|
||||
return(NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
|
||||
{
|
||||
|
||||
unsigned char Mdlharq;
|
||||
unsigned char i,j,r;
|
||||
|
||||
if (dlsch) {
|
||||
Mdlharq = dlsch->Mdlharq;
|
||||
dlsch->rnti = 0;
|
||||
dlsch->active = 0;
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
dlsch->harq_ids[i] = Mdlharq;
|
||||
|
||||
for (i=0; i<Mdlharq; i++) {
|
||||
if (dlsch->harq_processes[i]) {
|
||||
// dlsch->harq_processes[i]->Ndi = 0;
|
||||
//dlsch->harq_processes[i]->status = 0;
|
||||
dlsch->harq_processes[i]->round = 0;
|
||||
|
||||
for (j=0; j<96; j++)
|
||||
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
|
||||
if (dlsch->harq_processes[i]->d[r])
|
||||
dlsch->harq_processes[i]->d[r][j] = NR_NULL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nr_dlsch_encoding(unsigned char *a,
|
||||
uint8_t slot,
|
||||
NR_gNB_DLSCH_t *dlsch,
|
||||
NR_DL_FRAME_PARMS* frame_parms)
|
||||
{
|
||||
|
||||
unsigned int G;
|
||||
unsigned int crc=1;
|
||||
|
||||
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;
|
||||
uint16_t nb_rb = rel15.n_prb;
|
||||
uint8_t nb_symb_sch = rel15.nb_symbols;
|
||||
uint32_t A, Z;
|
||||
uint32_t *pz = &Z;
|
||||
uint8_t mod_order = rel15.modulation_order;
|
||||
uint16_t Kr=0,r,r_offset=0;//Kr_bytes
|
||||
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
|
||||
uint8_t kb,BG=1;
|
||||
uint32_t E;
|
||||
uint8_t Ilbrm = 0;
|
||||
uint32_t Tbslbrm = 950984; //max tbs
|
||||
uint8_t nb_re_dmrs = rel15.nb_re_dmrs;
|
||||
uint16_t length_dmrs = 1;
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
A = rel15.transport_block_size;
|
||||
|
||||
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
|
||||
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
|
||||
|
||||
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
|
||||
|
||||
// if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet
|
||||
if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
/*
|
||||
int i;
|
||||
printf("dlsch (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(a,A)>>8;
|
||||
a[A>>3] = ((uint8_t*)&crc)[2];
|
||||
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
|
||||
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
|
||||
dlsch->harq_processes[harq_pid]->B = A+24;
|
||||
// dlsch->harq_processes[harq_pid]->b = a;
|
||||
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
|
||||
|
||||
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
|
||||
dlsch->harq_processes[harq_pid]->c,
|
||||
dlsch->harq_processes[harq_pid]->B,
|
||||
&dlsch->harq_processes[harq_pid]->C,
|
||||
&dlsch->harq_processes[harq_pid]->K,
|
||||
pz,
|
||||
&dlsch->harq_processes[harq_pid]->F);
|
||||
|
||||
kb = dlsch->harq_processes[harq_pid]->K/(*pz);
|
||||
if ( kb==22){
|
||||
BG = 1;
|
||||
}
|
||||
else{
|
||||
BG = 2;
|
||||
}
|
||||
|
||||
Kr = dlsch->harq_processes[harq_pid]->K;
|
||||
//Kr_bytes = Kr>>3;
|
||||
|
||||
//printf("segment Z %d kb %d k %d Kr %d BG %d\n", *pz,kb,dlsch->harq_processes[harq_pid]->K,Kr,BG);
|
||||
|
||||
//start_meas(te_stats);
|
||||
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
||||
d_tmp[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
||||
//channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0];
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
printf("Encoder: B %d F %d \n",dlsch->harq_processes[harq_pid]->B, dlsch->harq_processes[harq_pid]->F);
|
||||
printf("start ldpc encoder segment %d/%d\n",r,dlsch->harq_processes[harq_pid]->C);
|
||||
printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
|
||||
for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
|
||||
printf("%d ", dlsch->harq_processes[harq_pid]->c[r][cnt]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
#endif
|
||||
//ldpc_encoder_orig((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->d[r],Kr,BG,0);
|
||||
//ldpc_encoder_optim((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][0],Kr,BG,NULL,NULL,NULL,NULL);
|
||||
}
|
||||
|
||||
//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", dlsch->harq_processes[harq_pid]->d[0][0], dlsch->harq_processes[harq_pid]->d[0][1], dlsch->harq_processes[harq_pid]->d[r][2],dlsch->harq_processes[harq_pid]->d[0][3], dlsch->harq_processes[harq_pid]->d[0][4]);
|
||||
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
|
||||
printf("%d \n", dlsch->harq_processes[harq_pid]->d[0][cnt]);
|
||||
}
|
||||
printf("\n");*/
|
||||
|
||||
ldpc_encoder_optim_8seg(dlsch->harq_processes[harq_pid]->c,d_tmp,Kr,BG,dlsch->harq_processes[harq_pid]->C,NULL,NULL,NULL,NULL);
|
||||
|
||||
//stop_meas(te_stats);
|
||||
//printf("end ldpc encoder -- output\n");
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
|
||||
write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) {
|
||||
#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", dlsch->harq_processes[harq_pid]->rvidx);
|
||||
#endif
|
||||
|
||||
E = nr_rate_matching_ldpc(Ilbrm,
|
||||
Tbslbrm,
|
||||
BG,
|
||||
*pz,
|
||||
G,
|
||||
dlsch->harq_processes[harq_pid]->d[r],
|
||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
||||
dlsch->harq_processes[harq_pid]->C,
|
||||
rel15.redundancy_version,
|
||||
mod_order,
|
||||
rel15.nb_layers,
|
||||
r);
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i], r_offset);
|
||||
#endif
|
||||
//stop_meas(rm_stats);
|
||||
|
||||
//start_meas(i_stats);
|
||||
nr_interleaving_ldpc(E,
|
||||
mod_order,
|
||||
dlsch->harq_processes[harq_pid]->e+r_offset,
|
||||
dlsch->harq_processes[harq_pid]->f+r_offset);
|
||||
//stop_meas(i_stats);
|
||||
|
||||
r_offset += E;
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
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*r_offset], r_offset);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
|
||||
if (r==dlsch->harq_processes[harq_pid]->C-1)
|
||||
write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,r_offset,1,4);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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_TRANSPORT/nr_dlsch_tools.c
|
||||
* \brief Top-level routines for decoding DLSCH transport channel from 38-214, V15.2.0 2018-06
|
||||
* \author Guy De Souza
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: desouza@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
|
||||
extern void set_taus_seed(unsigned int seed_type);
|
||||
|
||||
uint8_t nr_pdsch_default_time_alloc_A_S_nCP[23] = {2,3,2,3,2,3,2,3,2,3,9,10,4,6,5,5,9,12,1,1,2,4,8};
|
||||
uint8_t nr_pdsch_default_time_alloc_A_L_nCP[23] = {12,11,10,9,9,8,7,6,5,4,4,4,4,4,7,2,2,2,13,6,4,7,4};
|
||||
uint8_t nr_pdsch_default_time_alloc_A_S_eCP[23] = {2,3,2,3,2,3,2,3,2,3,6,8,4,6,5,5,9,10,1,1,2,4,8};
|
||||
uint8_t nr_pdsch_default_time_alloc_A_L_eCP[23] = {6,5,10,9,9,8,7,6,5,4,4,2,4,4,6,2,2,2,11,6,4,6,4};
|
||||
uint8_t nr_pdsch_default_time_alloc_B_S[16] = {2,4,6,8,10,2,4,2,4,6,8,10,2,2,3,2};
|
||||
uint8_t nr_pdsch_default_time_alloc_B_L[16] = {2,2,2,2,2,2,2,4,4,4,4,4,7,12,11,4};
|
||||
uint8_t nr_pdsch_default_time_alloc_C_S[15] = {2,4,6,8,10,2,4,6,8,10,2,2,3,0,2};
|
||||
uint8_t nr_pdsch_default_time_alloc_C_L[15] = {2,2,2,2,2,4,4,4,4,4,7,12,11,6,6};
|
||||
|
||||
|
||||
/// Time domain allocation routines
|
||||
|
||||
void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
|
||||
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
|
||||
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu) {
|
||||
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
|
||||
uint8_t *alloc_type = &dlsch_pdu->dlsch_pdu_rel15.time_allocation_type;
|
||||
uint8_t mux_pattern = params_rel15.mux_pattern;
|
||||
uint8_t alloc_list_flag = dlsch_pdu->dlsch_pdu_rel15.time_alloc_list_flag;
|
||||
|
||||
switch(params_rel15.rnti_type) {
|
||||
|
||||
case NFAPI_NR_RNTI_SI:
|
||||
AssertFatal(params_rel15.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0,
|
||||
"Invalid common search space type %d for SI RNTI, expected %d\n",
|
||||
params_rel15.common_search_space_type, NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_0);
|
||||
|
||||
if (mux_pattern == NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1)
|
||||
AssertFatal(config.subframe_config.dl_cyclic_prefix_type.value == NFAPI_CP_NORMAL,
|
||||
"Invalid configuration CP extended for SI RNTI type 0 search space\n");
|
||||
|
||||
*alloc_type = (mux_pattern == NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1)?NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A :
|
||||
(mux_pattern == NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2)?NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B :
|
||||
NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C;
|
||||
break;
|
||||
|
||||
case NFAPI_NR_RNTI_RA:
|
||||
case NFAPI_NR_RNTI_TC:
|
||||
/*AssertFatal(dci_alloc.pdcch_params.common_search_space_type == NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1,
|
||||
"Invalid common search space type %d for RNTI %d, expected %d\n",dci_alloc.pdcch_params.common_search_space_type,
|
||||
NFAPI_NR_COMMON_SEARCH_SPACE_TYPE_1, dci_alloc.rnti_type);*/
|
||||
*alloc_type = (alloc_list_flag) ? NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST : NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A;
|
||||
break;
|
||||
|
||||
case NFAPI_NR_RNTI_P:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_RNTI_C:
|
||||
case NFAPI_NR_RNTI_CS:
|
||||
if (params_rel15.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON)
|
||||
*alloc_type = (alloc_list_flag)? NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST : NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A;
|
||||
else
|
||||
*alloc_type = NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_ALLOC_LIST;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t get_SLIV(uint8_t S, uint8_t L) {
|
||||
return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) );
|
||||
}
|
||||
|
||||
static inline uint8_t get_K0(uint8_t row_idx, uint8_t time_alloc_type) {
|
||||
return ( (time_alloc_type == NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A)||
|
||||
(time_alloc_type == NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C)? 0 :
|
||||
((row_idx==6)||(row_idx==7)||(row_idx==15))? 1 : 0);
|
||||
}
|
||||
|
||||
/*ideally combine the calculation of L in the same function once the right struct is defined*/
|
||||
uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_typeA_position) {
|
||||
|
||||
uint8_t idx;
|
||||
//uint8_t S;
|
||||
|
||||
switch(time_alloc_type) {
|
||||
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A:
|
||||
idx = (row_idx>7)? (row_idx+6) : (((row_idx-1)<<1)-1+((dmrs_typeA_position==2)?0:1));
|
||||
return ((CP==NFAPI_CP_NORMAL)?nr_pdsch_default_time_alloc_A_S_nCP[idx] : nr_pdsch_default_time_alloc_A_S_eCP[idx]);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_B:
|
||||
idx = (row_idx<14)? (row_idx-1) : (row_idx == 14)? row_idx-1+((dmrs_typeA_position==2)?0:1) : 15;
|
||||
return (nr_pdsch_default_time_alloc_B_S[idx]);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C:
|
||||
AssertFatal((row_idx!=6)&&(row_idx!=7)&&(row_idx<17), "Invalid row index %d in %s %s\n", row_idx, __FUNCTION__, __FILE__);
|
||||
idx = (row_idx<6)? (row_idx-1) : (row_idx<14)? (row_idx-3) : (row_idx == 14)? row_idx-3+((dmrs_typeA_position==2)?0:1) : (row_idx-2);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Invalid Time domain allocation type %d in %s %s\n", time_alloc_type, __FUNCTION__, __FILE__);
|
||||
}
|
||||
return 0; // temp warning fix
|
||||
}
|
||||
|
||||
void nr_check_time_alloc(uint8_t S, uint8_t L, nfapi_nr_config_request_t config) {
|
||||
|
||||
switch (config.subframe_config.dl_cyclic_prefix_type.value) {
|
||||
case NFAPI_CP_NORMAL:
|
||||
if (config.pdsch_config.mapping_type.value == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
|
||||
AssertFatal(S<4, "Invalid value of S(%d) for mapping type A and normal CP\n", S);
|
||||
|
||||
if (S==3)
|
||||
AssertFatal(config.pdsch_config.mapping_type.value == 3, "Invalid S %d for dmrs_typeA_position %d\n",
|
||||
S, config.pdsch_config.dmrs_typeA_position.value);
|
||||
|
||||
AssertFatal((L>2)&&(L<15), "Invalid L %d for mapping type A and normal CP\n", L);
|
||||
|
||||
AssertFatal(((S+L)>2)&&((S+L)<15), "Invalid S+L %d for mapping type A and normal CP\n", S+L);
|
||||
}
|
||||
else {
|
||||
AssertFatal(S<13, "Invalid value of S(%d) for mapping type B and normal CP\n", S);
|
||||
|
||||
AssertFatal((L>1)&&(L<8), "Invalid L %d for mapping type B and normal CP\n", L);
|
||||
|
||||
AssertFatal(((S+L)>1)&&((S+L)<15), "Invalid S+L %d for mapping type B and normal CP\n", S+L);
|
||||
}
|
||||
break;
|
||||
|
||||
case NFAPI_CP_EXTENDED:
|
||||
if (config.pdsch_config.mapping_type.value == NFAPI_NR_PDSCH_MAPPING_TYPE_A) {
|
||||
AssertFatal(S<4, "Invalid value of S(%d) for mapping type A and extended CP\n", S);
|
||||
|
||||
if (S==3)
|
||||
AssertFatal(config.pdsch_config.dmrs_typeA_position.value == 3, "Invalid S %d for dmrs_typeA_position %d\n",
|
||||
S, config.pdsch_config.dmrs_typeA_position.value);
|
||||
|
||||
AssertFatal((L>2)&&(L<13), "Invalid L %d for mapping type A and extended CP\n", L);
|
||||
|
||||
AssertFatal(((S+L)>2)&&((S+L)<13), "Invalid S+L %d for mapping type A and extended CP\n", S+L);
|
||||
}
|
||||
else {
|
||||
AssertFatal(S<11, "Invalid value of S(%d) for mapping type B and extended CP\n", S);
|
||||
|
||||
AssertFatal((L>1)&&(L<7), "Invalid L %d for mapping type B and extended CP\n", L);
|
||||
|
||||
AssertFatal(((S+L)>1)&&((S+L)<13), "Invalid S+L %d for mapping type B and extended CP\n", S+L);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Frequency domain allocation routines
|
||||
|
||||
// DL alloc type 0
|
||||
static inline uint8_t get_RBG_size_P(uint16_t n_RB, uint8_t RBG_config) {
|
||||
if (RBG_config == NFAPI_NR_PDSCH_RBG_CONFIG_TYPE1)
|
||||
return ((n_RB<37)?2:(n_RB<73)?4:(n_RB<145)?8:16);
|
||||
else if (RBG_config == NFAPI_NR_PDSCH_RBG_CONFIG_TYPE2)
|
||||
return ((n_RB<37)?4:(n_RB<73)?8:(n_RB<145)?16:16);
|
||||
else
|
||||
AssertFatal(0, "Invalid RBG config type (%d)\n", RBG_config);
|
||||
}
|
||||
|
||||
void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type) {
|
||||
nr_rbg_parms_t* rbg_parms = &bwp->rbg_parms;
|
||||
|
||||
rbg_parms->P = get_RBG_size_P(bwp->N_RB, config_type);
|
||||
rbg_parms->start_size = rbg_parms->P - bwp->location%rbg_parms->P;
|
||||
rbg_parms->end_size = ((bwp->location + bwp->N_RB)%rbg_parms->P)? ((bwp->location + bwp->N_RB)%rbg_parms->P) : rbg_parms->P;
|
||||
rbg_parms->N_RBG = (uint8_t)ceil( (bwp->N_RB + (bwp->location%rbg_parms->P))/(float)rbg_parms->P);
|
||||
LOG_I(PHY, "RBG parameters for BWP %d location %d N_RB %d:\n", bwp->bwp_id, bwp->location, bwp->N_RB);
|
||||
LOG_I(PHY, "P %d\t start size %d\t endsize %d\t N_RBG %d\n", rbg_parms->P, rbg_parms->start_size, rbg_parms->end_size, rbg_parms->N_RBG);
|
||||
}
|
||||
|
||||
void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list) {
|
||||
uint8_t idx=0;
|
||||
for (int i=0; i<n_rbg; i++)
|
||||
if ((bitmap>>(n_rbg-i-1))&1)
|
||||
rbg_list[idx++]=i;
|
||||
}
|
||||
|
||||
// DL alloc type 1
|
||||
|
||||
uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB) {
|
||||
if ((L-1)<=(N_RB>>1))
|
||||
return (N_RB*(L-1)+rb_start);
|
||||
else
|
||||
return (N_RB*(N_RB-L+1) + (N_RB-1-rb_start));
|
||||
}
|
||||
|
||||
/// PRB bundling routines
|
||||
|
||||
// Precoding granularity
|
||||
static inline uint8_t nr_get_P_prime(uint8_t rnti_type, uint8_t dci_format, uint8_t prb_bundling_type) {
|
||||
if (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_0)
|
||||
return (NFAPI_NR_PRG_GRANULARITY_2);
|
||||
else // NFAPI_NR_DL_DCI_FORMAT_1_1
|
||||
return ((prb_bundling_type)?0:2);// incomplete for 1_1
|
||||
}
|
||||
|
||||
void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type) {
|
||||
nr_prg_parms_t* prg_parms = &bwp->prg_parms;
|
||||
|
||||
prg_parms->P_prime = nr_get_P_prime(dci_alloc.pdcch_params.rnti_type, dci_alloc.pdcch_params.dci_format, prb_bundling_type);
|
||||
prg_parms->start_size = prg_parms->P_prime - bwp->location%prg_parms->P_prime;
|
||||
prg_parms->end_size = (bwp->location + bwp->N_RB)%prg_parms->P_prime;
|
||||
if (!prg_parms->end_size)
|
||||
prg_parms->end_size = prg_parms->P_prime;
|
||||
prg_parms->N_PRG = ceil((float)bwp->N_RB/prg_parms->P_prime);
|
||||
LOG_I(PHY, "PRG parameters for BWP %d location %d N_RB %d:\n", bwp->bwp_id, bwp->location, bwp->N_RB);
|
||||
LOG_I(PHY, "P_prime %d\t start size %d\t endsize %d\t N_PRG %d\n", prg_parms->P_prime, prg_parms->start_size, prg_parms->end_size, prg_parms->N_PRG);
|
||||
}
|
||||
|
||||
/// Payload emulation
|
||||
void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) {
|
||||
set_taus_seed(0);
|
||||
for (int i=0; i<size; i++)
|
||||
*(pdu+i) = (uint8_t)rand();
|
||||
}
|
||||
@@ -40,7 +40,7 @@
|
||||
//#define DEBUG_PBCH_ENCODING
|
||||
//#define DEBUG_PBCH_DMRS
|
||||
|
||||
#include "PHY/NR_REFSIG/nr_mod_table.h"
|
||||
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
|
||||
|
||||
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
|
||||
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
|
||||
@@ -438,11 +438,5 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_PBCH
|
||||
write_output("txdataF_pbch.m", "txdataF_pbch", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1);
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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_TRANSPORT/nr_sch_dmrs.c
|
||||
* \brief
|
||||
* \author
|
||||
* \date
|
||||
* \version
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "nr_sch_dmrs.h"
|
||||
|
||||
|
||||
/*Table 7.4.1.1.2-1 and 7.4.1.1.2-2 38211 Columns: ap - CDM group - Delta - Wf(0) - Wf(1) - Wt(0) - Wt(1)*/
|
||||
int8_t pdsch_dmrs_1[8][7] = {{0,0,0,1,1,1,1},
|
||||
{1,0,0,1,-1,1,1},
|
||||
{2,1,1,1,1,1,1},
|
||||
{3,1,1,1,-1,1,1},
|
||||
{4,0,0,1,1,1,-1},
|
||||
{5,0,0,1,-1,1,-1},
|
||||
{6,1,1,1,1,1,-1},
|
||||
{7,1,1,1,-1,1,-1}};
|
||||
|
||||
int8_t pdsch_dmrs_2[12][7] = {{0,0,0,1,1,1,1},
|
||||
{1,0,0,1,-1,1,1},
|
||||
{2,1,2,1,1,1,1},
|
||||
{3,1,2,1,-1,1,1},
|
||||
{4,2,4,1,1,1,1},
|
||||
{5,2,4,1,-1,1,1},
|
||||
{6,0,0,1,1,1,-1},
|
||||
{7,0,0,1,-1,1,-1},
|
||||
{8,1,2,1,1,1,-1},
|
||||
{9,1,2,1,-1,1,-1},
|
||||
{10,2,4,1,1,1,-1},
|
||||
{11,2,4,1,-1,1,-1}};
|
||||
|
||||
void get_l_prime(uint8_t *l_prime, uint8_t n_symbs) {
|
||||
for (int i=0; i<n_symbs; i++)
|
||||
*(l_prime+i) = i;
|
||||
}
|
||||
|
||||
void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config) {
|
||||
if (config == NFAPI_NR_DMRS_TYPE1)
|
||||
for (int i=0; i<(4+((n_symbs-1)<<2)); i++)
|
||||
*(ap+i) = i;
|
||||
else
|
||||
for (int i=0; i<(7+((n_symbs-1)<<2)); i++)
|
||||
*(ap+i) = i;
|
||||
}
|
||||
|
||||
void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config) {
|
||||
for (int i=0; i<2; i++)
|
||||
*(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]);
|
||||
}
|
||||
|
||||
void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config) {
|
||||
for (int i=0; i<2; i++)
|
||||
*(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]);
|
||||
}
|
||||
|
||||
uint8_t get_delta(uint8_t ap, uint8_t config) {
|
||||
return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2]));
|
||||
}
|
||||
|
||||
uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position) {
|
||||
return ((config==NFAPI_NR_DMRS_TYPE1)?dmrs_typeA_position:0);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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_TRANSPORT/nr_sch_dmrs.c
|
||||
* \brief
|
||||
* \author
|
||||
* \date
|
||||
* \version
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
#define NR_PDSCH_DMRS_ANTENNA_PORT0 1000
|
||||
#define NR_PDSCH_DMRS_NB_ANTENNA_PORTS 12
|
||||
|
||||
void get_l_prime(uint8_t *l_prime, uint8_t n_symbs);
|
||||
|
||||
void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config);
|
||||
|
||||
void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config);
|
||||
|
||||
void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config);
|
||||
|
||||
uint8_t get_delta(uint8_t ap, uint8_t config);
|
||||
|
||||
uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position);
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* 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/LTE_TRANSPORT/dlsch_coding.c
|
||||
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
|
||||
* \author H.Wang
|
||||
* \date 2018
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "nr_dlsch.h"
|
||||
|
||||
/// Target code rate tables indexed by Imcs
|
||||
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
|
||||
616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
|
||||
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
|
||||
uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
|
||||
616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
|
||||
uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
|
||||
378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
|
||||
uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
|
||||
336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
|
||||
1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
|
||||
3104, 3240, 3368, 3496, 3624, 3752, 3824};
|
||||
|
||||
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 1:
|
||||
return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 1:
|
||||
return (nr_target_code_rate_table1[Imcs]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return (nr_target_code_rate_table2[Imcs]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return (nr_target_code_rate_table3[Imcs]);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t is_codeword_disabled(uint8_t format, uint8_t Imcs, uint8_t rv) {
|
||||
return ((format==NFAPI_NR_DL_DCI_FORMAT_1_1)&&(Imcs==26)&&(rv==1));
|
||||
}
|
||||
|
||||
static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8_t rnti_type, uint8_t ss_type) {
|
||||
if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1) && ((rnti_type==NFAPI_NR_RNTI_C)||(rnti_type==NFAPI_NR_RNTI_CS)))
|
||||
return 2;
|
||||
else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type!=NFAPI_NR_RNTI_new) && (rnti_type==NFAPI_NR_RNTI_C) && (ss_type==NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC))
|
||||
return 3;
|
||||
else if (rnti_type==NFAPI_NR_RNTI_new)
|
||||
return 3;
|
||||
else if ((mcs_table == NFAPI_NR_MCS_TABLE_QAM256) && (rnti_type==NFAPI_NR_RNTI_CS) && (dci_format == NFAPI_NR_DL_DCI_FORMAT_1_1))
|
||||
return 2; // Condition mcs_table not configured in sps_config necessary here but not yet implemented
|
||||
/*else if((mcs_table == NFAPI_NR_MCS_TABLE_QAM64_LOW_SE) && (rnti_type==NFAPI_NR_RNTI_CS))
|
||||
* table_idx = 3;
|
||||
* Note: the commented block refers to the case where the mcs_table is from sps_config*/
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
|
||||
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
|
||||
nfapi_nr_config_request_t config) {
|
||||
|
||||
LOG_I(MAC, "TBS calculation\n");
|
||||
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t params_rel15 = dci_pdu.pdcch_params_rel15;
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_rel15 = &dlsch_pdu->dlsch_pdu_rel15;
|
||||
uint8_t rnti_type = params_rel15.rnti_type;
|
||||
uint8_t dci_format = params_rel15.dci_format;
|
||||
uint8_t ss_type = params_rel15.search_space_type;
|
||||
uint8_t N_PRB_oh = ((rnti_type==NFAPI_NR_RNTI_SI)||(rnti_type==NFAPI_NR_RNTI_RA)||(rnti_type==NFAPI_NR_RNTI_P))? 0 : \
|
||||
(config.pdsch_config.x_overhead.value);
|
||||
uint8_t N_PRB_DMRS = (config.pdsch_config.dmrs_type.value == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000
|
||||
uint8_t mcs_table = config.pdsch_config.mcs_table.value;
|
||||
uint8_t N_sh_symb = dlsch_rel15->nb_symbols;
|
||||
uint8_t Imcs = dlsch_rel15->mcs_idx;
|
||||
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
||||
LOG_I(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
|
||||
|
||||
uint16_t N_RE, Ninfo, Ninfo_prime, C, TBS=0, R;
|
||||
uint8_t table_idx, Qm, n, scale;
|
||||
|
||||
table_idx = get_table_idx(mcs_table, dci_format, rnti_type, ss_type);
|
||||
scale = ((table_idx==2)&&((Imcs==20)||(Imcs==26)))?11:10;
|
||||
|
||||
N_RE = min(156, N_RE_prime)*dlsch_rel15->n_prb;
|
||||
R = nr_get_code_rate(Imcs, table_idx);
|
||||
Qm = nr_get_Qm(Imcs, table_idx);
|
||||
Ninfo = (N_RE*R*Qm*dlsch_rel15->nb_layers)>>scale;
|
||||
|
||||
if (Ninfo <= 3824) {
|
||||
n = max(3, (log2(Ninfo)-6));
|
||||
Ninfo_prime = max(24, (Ninfo>>n)<<n);
|
||||
for (int i=0; i<93; i++)
|
||||
if (nr_tbs_table[i] >= Ninfo_prime) {
|
||||
TBS = nr_tbs_table[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = log2(Ninfo-24)-5;
|
||||
Ninfo_prime = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
|
||||
|
||||
if (R<256) {
|
||||
C = CEILIDIV((Ninfo_prime+24),3816);
|
||||
TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
|
||||
}
|
||||
else {
|
||||
if (Ninfo_prime>8424) {
|
||||
C = CEILIDIV((Ninfo_prime+24),8424);
|
||||
TBS = (C<<3)*CEILIDIV((Ninfo_prime+24),(C<<3)) - 24;
|
||||
}
|
||||
else
|
||||
TBS = ((CEILIDIV((Ninfo_prime+24),8))<<3) - 24;
|
||||
}
|
||||
}
|
||||
|
||||
dlsch_rel15->coding_rate = R;
|
||||
dlsch_rel15->modulation_order = Qm;
|
||||
dlsch_rel15->transport_block_size = TBS;
|
||||
dlsch_rel15->nb_re_dmrs = N_PRB_DMRS;
|
||||
dlsch_rel15->nb_mod_symbols = N_RE_prime*dlsch_rel15->n_prb*dlsch_rel15->nb_codewords;
|
||||
|
||||
LOG_I(MAC, "TBS %d : N_RE %d N_PRB_DMRS %d N_sh_symb %d N_PRB_oh %d Ninfo %d Ninfo_prime %d R %d Qm %d table %d scale %d nb_symbols %d\n",
|
||||
TBS, N_RE, N_PRB_DMRS, N_sh_symb, N_PRB_oh, Ninfo, Ninfo_prime, R, Qm, table_idx, scale, dlsch_rel15->nb_mod_symbols);
|
||||
}
|
||||
|
||||
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) {
|
||||
uint32_t G;
|
||||
G = ((NR_NB_SC_PER_RB*nb_symb_sch)-(nb_re_dmrs*length_dmrs))*nb_rb*Qm*Nl;
|
||||
return(G);
|
||||
}
|
||||
@@ -106,4 +106,11 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
||||
*/
|
||||
void nr_init_pbch_interleaver(uint8_t *interleaver);
|
||||
|
||||
NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
|
||||
unsigned char Mdlharq,
|
||||
uint32_t Nsoft,
|
||||
uint8_t abstraction_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_config_request_t *config);
|
||||
|
||||
#endif /*__NR_TRANSPORT__H__*/
|
||||
|
||||
@@ -33,6 +33,15 @@
|
||||
#ifndef __NR_TRANSPORT_COMMON_PROTO__H__
|
||||
#define __NR_TRANSPORT_COMMON_PROTO__H__
|
||||
|
||||
#define MAX_NUM_NR_DLSCH_SEGMENTS 32
|
||||
#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_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
|
||||
|
||||
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
|
||||
#define MAX_NUM_NR_RE (14*273*12)
|
||||
|
||||
// Functions below implement minor procedures from 38-214
|
||||
|
||||
/** \brief Computes Q based on I_MCS PDSCH and when 'MCS-Table-PDSCH' is set to "256QAM". Implements Table 5.1.3.1-2 from 38.214.
|
||||
|
||||
@@ -90,7 +90,7 @@ short filt8_l0[8] = {
|
||||
16384,8192,0,0,0,0,0,0};
|
||||
|
||||
short filt8_mr0[8] = {
|
||||
0,8192,16384,8192,0,-8192,0,0};
|
||||
0,0,0,8192,16384,8192,0,-8192};
|
||||
|
||||
short filt8_r0[8] = {
|
||||
0,8192,16384,24576,0,0,0,0};
|
||||
@@ -98,6 +98,9 @@ short filt8_r0[8] = {
|
||||
short filt8_m0[8] = {
|
||||
0,8192,16384,8192,0,0,0,0};
|
||||
|
||||
short filt8_mm0[8]= {
|
||||
0,0,0,8192,16384,8192,0,0};
|
||||
|
||||
short filt8_l1[8] = {
|
||||
24576,16384,0,0,0,0,0,0};
|
||||
|
||||
@@ -109,3 +112,6 @@ short filt8_r1[8] = {
|
||||
|
||||
short filt8_m1[8] = {
|
||||
0,0,8192,16384,8192,0,0,0};
|
||||
|
||||
short filt8_mm1[8]= {
|
||||
0,0,0,0,8192,16384,8192,0};
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 "PHY/types.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
//#include "openair2/LAYER2/MAC/mac_proto.h"
|
||||
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#define DEBUG_PHY
|
||||
|
||||
// Adjust location synchronization point to account for drift
|
||||
// The adjustment is performed once per frame based on the
|
||||
// last channel estimate of the receiver
|
||||
|
||||
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t eNB_id,
|
||||
uint8_t subframe,
|
||||
unsigned char clear,
|
||||
short coef)
|
||||
{
|
||||
|
||||
static int max_pos_fil = 0;
|
||||
static int count_max_pos_ok = 0;
|
||||
static int first_time = 1;
|
||||
int temp = 0, i, aa, max_val = 0, max_pos = 0;
|
||||
int diff;
|
||||
short Re,Im,ncoef;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
|
||||
|
||||
ncoef = 32767 - coef;
|
||||
|
||||
//#ifdef DEBUG_PHY
|
||||
LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset);
|
||||
//#endif //DEBUG_PHY
|
||||
|
||||
|
||||
// we only use channel estimates from tx antenna 0 here
|
||||
for (i = 0; i < frame_parms->nb_prefix_samples; i++) {
|
||||
temp = 0;
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)];
|
||||
Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)];
|
||||
temp += (Re*Re/2) + (Im*Im/2);
|
||||
}
|
||||
|
||||
if (temp > max_val) {
|
||||
max_pos = i;
|
||||
max_val = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// filter position to reduce jitter
|
||||
if (clear == 1)
|
||||
max_pos_fil = max_pos;
|
||||
else
|
||||
max_pos_fil = ((max_pos_fil * coef) + (max_pos * ncoef)) >> 15;
|
||||
|
||||
// do not filter to have proactive timing adjustment
|
||||
//max_pos_fil = max_pos;
|
||||
|
||||
if(subframe == 1)
|
||||
{
|
||||
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
|
||||
|
||||
if ( abs(diff) < SYNCH_HYST )
|
||||
ue->rx_offset = 0;
|
||||
else
|
||||
ue->rx_offset = diff;
|
||||
|
||||
if(abs(diff)<5)
|
||||
count_max_pos_ok ++;
|
||||
else
|
||||
count_max_pos_ok = 0;
|
||||
|
||||
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
|
||||
|
||||
if(count_max_pos_ok > 10 && first_time == 1)
|
||||
{
|
||||
first_time = 0;
|
||||
ue->time_sync_cell = 1;
|
||||
if (ue->mac_enabled==1) {
|
||||
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
|
||||
//mac_resynch();
|
||||
//dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
|
||||
ue->UE_mode[0] = PRACH;
|
||||
}
|
||||
else {
|
||||
ue->UE_mode[0] = PUSCH;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ue->rx_offset < 0 )
|
||||
ue->rx_offset += frame_parms->samples_per_frame;
|
||||
|
||||
if ( ue->rx_offset >= frame_parms->samples_per_frame )
|
||||
ue->rx_offset -= frame_parms->samples_per_frame;
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_PHY
|
||||
LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
|
||||
ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
|
||||
subframe,
|
||||
ue->current_thread_id[subframe],
|
||||
diff,
|
||||
ue->rx_offset,
|
||||
clear,
|
||||
max_pos,
|
||||
max_pos_fil,
|
||||
temp,max_val,
|
||||
(frame_parms->nb_prefix_samples>>3));
|
||||
#endif //DEBUG_PHY
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
#include "filt16a_32.h"
|
||||
#include "T.h"
|
||||
//#define DEBUG_CH
|
||||
//#define DEBUG_PDSCH
|
||||
|
||||
|
||||
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
@@ -48,7 +48,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
|
||||
|
||||
uint8_t nushift,ssb_index=0, n_hf=0;
|
||||
uint8_t nushift, ssb_index=0, n_hf=0;
|
||||
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
|
||||
|
||||
@@ -262,7 +262,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned short nb_rb_coreset)
|
||||
{
|
||||
int pilot[200] __attribute__((aligned(16)));
|
||||
unsigned char aarx;
|
||||
unsigned char aarx,p;
|
||||
unsigned short k;
|
||||
unsigned int pilot_cnt;
|
||||
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
|
||||
@@ -286,7 +286,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
k = coreset_start_subcarrier;
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
|
||||
ue->frame_parms.Ncp,l,Ns,k, symbol);
|
||||
#endif
|
||||
@@ -295,9 +295,11 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
fm = filt16a_m1;
|
||||
fr = filt16a_r1;
|
||||
|
||||
|
||||
// generate pilot
|
||||
nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
|
||||
|
||||
|
||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
pil = (int16_t *)&pilot[0];
|
||||
@@ -309,18 +311,18 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
|
||||
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
|
||||
1,ue->frame_parms.ofdm_symbol_size);
|
||||
//#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
|
||||
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
|
||||
printf("rxF addr %p\n", rxF);
|
||||
printf("dl_ch addr %p\n",dl_ch);
|
||||
//#endif
|
||||
// if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
|
||||
printf("dl_ch addr %p\n",dl_ch);
|
||||
#endif
|
||||
// if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
@@ -335,7 +337,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
@@ -348,7 +350,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
@@ -357,7 +359,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
dl_ch,
|
||||
16);
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
for (int m =0; m<12; m++)
|
||||
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
|
||||
#endif
|
||||
@@ -376,7 +378,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fl,
|
||||
@@ -392,7 +394,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
@@ -405,7 +407,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
|
||||
@@ -424,33 +426,81 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
void (*idft)(int16_t *,int16_t *, int);
|
||||
|
||||
switch (ue->frame_parms.ofdm_symbol_size) {
|
||||
case 128:
|
||||
idft = idft128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
idft = idft256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
idft = idft512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
idft = idft1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
idft = idft1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
idft = idft2048;
|
||||
break;
|
||||
|
||||
default:
|
||||
idft = idft512;
|
||||
break;
|
||||
}
|
||||
|
||||
if( (Ns== 2) && (l == 0))
|
||||
{
|
||||
// do ifft of channel estimate
|
||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
|
||||
for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
|
||||
if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
|
||||
{
|
||||
LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
|
||||
idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0],
|
||||
(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_id,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned char l,
|
||||
unsigned char symbol,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch)
|
||||
uint8_t eNB_id,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char l,
|
||||
unsigned char symbol,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch)
|
||||
{
|
||||
int pilot[200] __attribute__((aligned(16)));
|
||||
int pilot[1320] __attribute__((aligned(16)));
|
||||
unsigned char aarx;
|
||||
unsigned short k;
|
||||
unsigned int pilot_cnt;
|
||||
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr;
|
||||
int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm;
|
||||
int ch_offset,symbol_offset;
|
||||
|
||||
|
||||
//uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
|
||||
|
||||
uint8_t nushift=0;
|
||||
uint8_t nushift;
|
||||
int **dl_ch_estimates =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
|
||||
|
||||
nushift = (p>>1)&1;
|
||||
ue->frame_parms.nushift = nushift;
|
||||
|
||||
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
|
||||
ch_offset = ue->frame_parms.ofdm_symbol_size ;
|
||||
@@ -460,38 +510,41 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
||||
|
||||
k = bwp_start_subcarrier;
|
||||
int re_offset = k;
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
|
||||
printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
|
||||
ue->frame_parms.Ncp,l,Ns,k, symbol);
|
||||
#endif
|
||||
|
||||
switch (nushift) {
|
||||
case 0:
|
||||
fl = filt8_l0;
|
||||
fm = filt8_m0;
|
||||
fr = filt8_r0;
|
||||
fml = filt8_m0;
|
||||
fmr = filt8_mr0;
|
||||
break;
|
||||
case 0:
|
||||
fl = filt8_l0;
|
||||
fm = filt8_m0;
|
||||
fr = filt8_r0;
|
||||
fmm = filt8_mm0;
|
||||
fml = filt8_m0;
|
||||
fmr = filt8_mr0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fl = filt8_l1;
|
||||
fm = filt8_m1;
|
||||
fr = filt8_r1;
|
||||
fml = filt8_ml1;
|
||||
fmr = filt8_m1;
|
||||
break;
|
||||
case 1:
|
||||
fl = filt8_l1;
|
||||
fm = filt8_m1;
|
||||
fr = filt8_r1;
|
||||
fmm = filt8_mm1;
|
||||
fml = filt8_ml1;
|
||||
fmr = filt8_m1;
|
||||
break;
|
||||
|
||||
default:
|
||||
msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// generate pilot
|
||||
nr_pdsch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdsch, &pilot[0],1000,1,nb_rb_pdsch);
|
||||
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch);
|
||||
|
||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
@@ -504,33 +557,35 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
|
||||
ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
|
||||
1,ue->frame_parms.ofdm_symbol_size);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
|
||||
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
|
||||
printf("rxF addr %p\n", rxF);
|
||||
printf("dl_ch addr %p\n",dl_ch);
|
||||
printf("rxF addr %p p %d\n", rxF,p);
|
||||
printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
|
||||
#endif
|
||||
if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
//if ((ue->frame_parms.N_RB_DL&1)==0) {
|
||||
|
||||
// Treat first 2 pilots specially (left edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
printf("data 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fl,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
//for (int i= 0; i<8; i++)
|
||||
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fml,
|
||||
@@ -538,21 +593,36 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
dl_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
dl_ch+=4;
|
||||
k+=4;
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
//printf("dl_ch addr %p\n",dl_ch);
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fmm,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
|
||||
//for (int i= 0; i<16; i++)
|
||||
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
dl_ch+=8;
|
||||
|
||||
for (pilot_cnt=2; pilot_cnt<(6*(nb_rb_pdsch-1)+4); pilot_cnt+=2) {
|
||||
if ((pilot_cnt%6)==0)
|
||||
dl_ch+=4;
|
||||
|
||||
if (k >= ue->frame_parms.ofdm_symbol_size){
|
||||
k-=ue->frame_parms.ofdm_symbol_size;
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
|
||||
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pdsch-3); pilot_cnt+=2) {
|
||||
//if ((pilot_cnt%6)==0)
|
||||
//dl_ch+=4;
|
||||
//printf("re_offset %d\n",re_offset);
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
@@ -561,56 +631,69 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
8);
|
||||
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
dl_ch+=4;
|
||||
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
multadd_real_vector_complex_scalar(fmm,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
dl_ch+=4;
|
||||
k+=4;
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
dl_ch+=8;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Treat first 2 pilots specially (right edge)
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fm,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
|
||||
//for (int i= 0; i<8; i++)
|
||||
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
|
||||
|
||||
pil+=2;
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
printf("pilot %d: rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fmr,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
//for (int i= 0; i<8; i++)
|
||||
//printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
|
||||
|
||||
re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
|
||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
|
||||
dl_ch+=8;
|
||||
|
||||
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
#ifdef DEBUG_CH
|
||||
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("pilot %d: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
|
||||
#endif
|
||||
multadd_real_vector_complex_scalar(fr,
|
||||
ch,
|
||||
dl_ch,
|
||||
8);
|
||||
pil+=2;
|
||||
rxF+=4;
|
||||
dl_ch+=4;
|
||||
k+=4;
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -62,8 +62,17 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_id,
|
||||
uint8_t eNB_offset,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char l,
|
||||
unsigned char symbol,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch);
|
||||
|
||||
void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
module_id_t eNB_id,
|
||||
uint8_t subframe,
|
||||
unsigned char clear,
|
||||
short coef);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
|
||||
#ifdef NR_PDCCH_DCI_RUN
|
||||
|
||||
static const uint16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
|
||||
//static const int16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
|
||||
|
||||
void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
@@ -130,6 +131,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
bundle_j = (c*coreset_interleaver_size_R)+r;
|
||||
f_bundle_j = ((r*coreset_C)+c+n_shift)%((coreset_nbr_rb*coreset_time_dur)/reg_bundle_size_L);
|
||||
if (coreset_interleaved==0) f_bundle_j=bundle_j;
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j);
|
||||
#endif
|
||||
@@ -141,6 +143,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb)));
|
||||
for (int i=0; i<9; i++){
|
||||
z[index_z + i] = llr[index_llr + i];
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n",
|
||||
reg,bundle_j,(index_z + i),*(int16_t*) &z[index_z + i],*(1 + (int16_t*) &z[index_z + i]),
|
||||
@@ -163,6 +166,7 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp,
|
||||
|
||||
pdcch_llrp = &pdcch_llr[2 * symbol * coreset_nbr_rb * 9];
|
||||
|
||||
|
||||
if (!pdcch_llrp) {
|
||||
printf("pdcch_qpsk_llr: llr is null, symbol %d\n", symbol);
|
||||
return (-1);
|
||||
@@ -299,89 +303,6 @@ __m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
|
||||
#endif
|
||||
|
||||
|
||||
void pdcch_detection_mrc_i(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int32_t **rxdataF_comp_i,
|
||||
int32_t **rho,
|
||||
int32_t **rho_i,
|
||||
uint8_t symbol)
|
||||
{
|
||||
|
||||
uint8_t aatx;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
|
||||
#elif defined(__arm__)
|
||||
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
|
||||
#endif
|
||||
int32_t i;
|
||||
|
||||
if (frame_parms->nb_antennas_rx>1) {
|
||||
for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
|
||||
//if (frame_parms->mode1_flag && (aatx>0)) break;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
|
||||
#elif defined(__arm__)
|
||||
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
|
||||
#endif
|
||||
// MRC on each re of rb on MF output
|
||||
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
|
||||
#elif defined(__arm__)
|
||||
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
|
||||
#elif defined(__arm__)
|
||||
rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12];
|
||||
#endif
|
||||
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
|
||||
#elif defined(__arm__)
|
||||
rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
|
||||
#elif defined(__arm__)
|
||||
rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
|
||||
rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
|
||||
|
||||
#endif
|
||||
// MRC on each re of rb on MF and rho
|
||||
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
|
||||
rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
|
||||
#elif defined(__arm__)
|
||||
rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]);
|
||||
rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef NR_PDCCH_DCI_RUN
|
||||
@@ -504,6 +425,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
|
||||
//if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -526,6 +448,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)){
|
||||
//if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -544,6 +467,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
// if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC)
|
||||
// we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table)
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -614,6 +538,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
for (i = 0; i < 12; i++) {
|
||||
if ((i != 1) && (i != 5) && (i != 9)) {
|
||||
rxF_ext[j] = rxF[i];
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n",
|
||||
c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short*) &rxF_ext[j]), i,
|
||||
@@ -759,6 +684,7 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
|
||||
rxdataF128+=3;
|
||||
rxdataF_comp128+=3;
|
||||
|
||||
|
||||
#elif defined(__arm__)
|
||||
// to be filled in
|
||||
#endif
|
||||
@@ -855,7 +781,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
int do_common;
|
||||
if (searchSpaceType == common) do_common=1;
|
||||
if (searchSpaceType == ue_specific) do_common=0;
|
||||
uint8_t log2_maxh, aatx, aarx;
|
||||
uint8_t log2_maxh, aarx;
|
||||
int32_t avgs;
|
||||
int32_t avgP[4];
|
||||
|
||||
@@ -940,6 +866,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
for (int s = start_symbol; s < (start_symbol + coreset_time_dur); s++) {
|
||||
|
||||
|
||||
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n",
|
||||
is_secondary_ue);
|
||||
@@ -985,7 +912,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
nr_pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
|
||||
pdcch_vars[eNB_id]->dl_ch_estimates_ext,
|
||||
pdcch_vars[eNB_id]->rxdataF_comp,
|
||||
(aatx > 1) ? pdcch_vars[eNB_id]->rho : NULL,
|
||||
NULL,
|
||||
frame_parms,
|
||||
s,
|
||||
log2_maxh,
|
||||
@@ -1013,7 +940,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
nr_pdcch_llr(frame_parms,
|
||||
pdcch_vars[eNB_id]->rxdataF_comp,
|
||||
(char *) pdcch_vars[eNB_id]->llr,
|
||||
pdcch_vars[eNB_id]->llr,
|
||||
s,
|
||||
coreset_nbr_rb);
|
||||
|
||||
@@ -1048,7 +975,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
nr_pdcch_unscrambling(pdcch_vars[eNB_id]->crnti,
|
||||
frame_parms,
|
||||
nr_tti_rx,
|
||||
(uint16_t*) pdcch_vars[eNB_id]->e_rx,
|
||||
pdcch_vars[eNB_id]->e_rx,
|
||||
coreset_time_dur*coreset_nbr_rb*9*2,
|
||||
// get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
|
||||
pdcch_DMRS_scrambling_id,
|
||||
@@ -1130,6 +1057,7 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
if (i%2 == 0) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ",
|
||||
@@ -1157,6 +1085,7 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8
|
||||
printf("unscrambled_z=%d\n",z[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1194,7 +1123,7 @@ void nr_dci_decoding_procedure0(int s,
|
||||
uint8_t L2 = (1 << L);
|
||||
unsigned int Yk, nb_candidates = 0, i, m;
|
||||
unsigned int CCEmap_cand;
|
||||
double *polar_input = malloc (sizeof(double) * 108*L2);
|
||||
|
||||
int8_t decoderState=0;
|
||||
|
||||
// A[p], p is the current active CORESET
|
||||
@@ -1353,12 +1282,8 @@ void nr_dci_decoding_procedure0(int s,
|
||||
CCEmap = CCEmap1;
|
||||
else if (CCEind < 96)
|
||||
CCEmap = CCEmap2;
|
||||
else {
|
||||
LOG_E(PHY, "Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind, Yk, m, nCCE, L2);
|
||||
//mac_xface->macphy_exit("Illegal CCEind\n");
|
||||
return; // not reached
|
||||
}
|
||||
|
||||
else AssertFatal(1==0,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind, Yk, m, nCCE[p], L2);
|
||||
|
||||
switch (L2) {
|
||||
case 1:
|
||||
CCEmap_mask = (1 << (CCEind & 0x1f));
|
||||
@@ -1387,6 +1312,7 @@ void nr_dci_decoding_procedure0(int s,
|
||||
#endif
|
||||
|
||||
if (CCEmap_cand == 0) {
|
||||
|
||||
#ifdef DEBUG_DCI_DECODING
|
||||
if (do_common == 1)
|
||||
LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
|
||||
@@ -1406,6 +1332,7 @@ void nr_dci_decoding_procedure0(int s,
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n",
|
||||
coreset_time_dur,coreset_nbr_rb,p,CCEind);
|
||||
#endif
|
||||
/*
|
||||
int reg_p=0,reg_e=0;
|
||||
for (int m=0; m < (L2*6); m++){
|
||||
reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2;
|
||||
@@ -1431,14 +1358,16 @@ void nr_dci_decoding_procedure0(int s,
|
||||
}
|
||||
for (j=0;j<27;j++) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding input)-> polar_hex[%d]=%x\n",j,polar_hex[j]);
|
||||
#endif
|
||||
|
||||
*/
|
||||
|
||||
uint32_t dci_estimation[4]={0};
|
||||
|
||||
|
||||
nr_polar_init(&nrPolar_params, 1, sizeof_bits, L2);
|
||||
|
||||
|
||||
t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, sizeof_bits, L2);
|
||||
decoderState = polar_decoder_int16((int16_t*)&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2],
|
||||
decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2],
|
||||
(uint64_t*)dci_estimation,
|
||||
currentPtrDCI);
|
||||
crc = decoderState;
|
||||
@@ -1455,6 +1384,7 @@ void nr_dci_decoding_procedure0(int s,
|
||||
printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled);
|
||||
#endif
|
||||
|
||||
|
||||
if (crc == crc_scrambled_values[_C_RNTI_]) {
|
||||
*crc_scrambled =_c_rnti;
|
||||
*format_found=1;
|
||||
@@ -2598,6 +2528,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// }
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n");
|
||||
@@ -2609,6 +2540,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue,
|
||||
printf(" }\n");
|
||||
#endif
|
||||
|
||||
|
||||
return dci_size[format];
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -175,7 +175,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
||||
* sync_pos SS/PBCH block
|
||||
*/
|
||||
|
||||
|
||||
cnt++;
|
||||
if (1){ // (cnt>100)
|
||||
cnt =0;
|
||||
@@ -183,17 +182,20 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
|
||||
/* process pss search on received buffer */
|
||||
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
|
||||
|
||||
sync_pos_slot = (fp->samples_per_subframe/fp->slots_per_subframe) - 10*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
|
||||
|
||||
if (sync_pos >= fp->nb_prefix_samples)
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;
|
||||
else
|
||||
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;
|
||||
if (sync_pos >= fp->nb_prefix_samples){
|
||||
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;}
|
||||
else{
|
||||
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;}
|
||||
|
||||
ue->rx_offset = ue->ssb_offset - sync_pos_slot;
|
||||
|
||||
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos,ue->common_vars.eNb_id);
|
||||
LOG_I(PHY,"sync_pos %d ssb_offset %d\n",sync_pos,ue->ssb_offset);
|
||||
LOG_I(PHY,"sync_pos %d ssb_offset %d sync_pos_slot %d \n",sync_pos,ue->ssb_offset,sync_pos_slot);
|
||||
#endif
|
||||
|
||||
/* check that SSS/PBCH block is continuous inside the received buffer */
|
||||
|
||||
@@ -283,6 +283,7 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
|
||||
|
||||
uint16_t nb_re=180;
|
||||
uint8_t aarx;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
|
||||
#elif defined(__arm__)
|
||||
@@ -569,7 +570,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
|
||||
for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
|
||||
|
||||
|
||||
nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF,
|
||||
nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[eNB_id],
|
||||
nr_ue_pbch_vars->rxdataF_ext,
|
||||
@@ -681,6 +681,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
|
||||
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1);
|
||||
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask);
|
||||
//printf("nushift %d sfn 3rd %d 2nd %d", nushift,((nr_ue_pbch_vars->pbch_a_prime>>6)&1), ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) );
|
||||
|
||||
//payload deinterleaving
|
||||
//uint32_t in=0;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#ifndef __NR_TRANSPORT_PROTO_UE__H__
|
||||
#define __NR_TRANSPORT_PROTO_UE__H__
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
//#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
|
||||
#include <math.h>
|
||||
#include "nfapi_interface.h"
|
||||
@@ -46,7 +47,7 @@
|
||||
\brief This function frees memory allocated for a particular DLSCH at UE
|
||||
@param dlsch Pointer to DLSCH to be removed
|
||||
*/
|
||||
void free_ue_dlsch(NR_UE_DLSCH_t *dlsch);
|
||||
void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
|
||||
|
||||
/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
|
||||
\brief This function allocates structures for a particular DLSCH at UE
|
||||
@@ -57,7 +58,7 @@ void free_ue_dlsch(NR_UE_DLSCH_t *dlsch);
|
||||
@params N_RB_DL total number of resource blocks (determine the operating BW)
|
||||
@param abstraction_flag Flag to indicate abstracted interface
|
||||
*/
|
||||
NR_UE_DLSCH_t *new_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);
|
||||
@@ -106,7 +107,7 @@ void qpsk_qpsk(int16_t *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr128p pointer to pointer to symbol in dlsch_llr*/
|
||||
int32_t dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int32_t **rxdataF_comp_i,
|
||||
int32_t **rho_i,
|
||||
@@ -142,7 +143,7 @@ void qpsk_qam16(int16_t *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr128p pointer to pointer to symbol in dlsch_llr*/
|
||||
int32_t dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t nr_dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int32_t **rxdataF_comp_i,
|
||||
int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
|
||||
@@ -154,6 +155,7 @@ int32_t dlsch_qpsk_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t pbch_pss_sss_adj,
|
||||
int16_t **llr128p);
|
||||
|
||||
|
||||
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/64QAM reception.
|
||||
@param stream0_in Input from channel compensated (MR combined) stream 0
|
||||
@param stream1_in Input from channel compensated (MR combined) stream 1
|
||||
@@ -179,7 +181,7 @@ void qpsk_qam64(int16_t *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr128p pointer to pointer to symbol in dlsch_llr*/
|
||||
int32_t dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t nr_dlsch_qpsk_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int32_t **rxdataF_comp_i,
|
||||
int **dl_ch_mag_i, //|h_1|^2*(2/sqrt{10})
|
||||
@@ -217,7 +219,7 @@ void qam16_qpsk(short *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_16qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
|
||||
@@ -258,7 +260,7 @@ void qam16_qam16(short *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_16qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
|
||||
@@ -300,7 +302,7 @@ void qam16_qam64(short *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_16qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag, //|h_0|^2*(2/sqrt{10})
|
||||
@@ -339,7 +341,7 @@ void qam64_qpsk(short *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_64qam_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag,
|
||||
@@ -396,7 +398,7 @@ void qam64_qam16_avx2(short *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_64qam_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag,
|
||||
@@ -454,7 +456,7 @@ void qam64_qam64_avx2(int32_t *stream0_in,
|
||||
@param nb_rb number of RBs for this allocation
|
||||
@param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS
|
||||
@param llr16p pointer to pointer to symbol in dlsch_llr*/
|
||||
int dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int **rxdataF_comp_i,
|
||||
int **dl_ch_mag,
|
||||
@@ -480,15 +482,13 @@ int dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param llr128p pointer to pointer to symbol in dlsch_llr
|
||||
@param beamforming_mode beamforming mode
|
||||
*/
|
||||
int32_t dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int16_t *dlsch_llr,
|
||||
uint8_t symbol,
|
||||
uint8_t first_symbol_flag,
|
||||
uint16_t nb_rb,
|
||||
uint16_t pbch_pss_sss_adj,
|
||||
//int16_t **llr128p,
|
||||
uint8_t beamforming_mode);
|
||||
int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int16_t *dlsch_llr,
|
||||
uint8_t symbol,
|
||||
uint8_t first_symbol_flag,
|
||||
uint16_t nb_rb,
|
||||
uint8_t beamforming_mode);
|
||||
|
||||
/**
|
||||
\brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
|
||||
@@ -504,7 +504,7 @@ int32_t dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param beamforming_mode beamforming mode
|
||||
*/
|
||||
|
||||
int32_t dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int **rxdataF_comp,
|
||||
int32_t **sic_buffer,
|
||||
int **rho_i,
|
||||
@@ -515,15 +515,14 @@ int32_t dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t mod_order_0,
|
||||
uint32_t rb_alloc);
|
||||
|
||||
void dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int16_t *dlsch_llr,
|
||||
int32_t **dl_ch_mag,
|
||||
uint8_t symbol,
|
||||
uint8_t first_symbol_flag,
|
||||
uint16_t nb_rb,
|
||||
uint16_t pbch_pss_sss_adjust,
|
||||
int16_t **llr128p,
|
||||
int16_t **llr32p,
|
||||
uint8_t beamforming_mode);
|
||||
/**
|
||||
\brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms
|
||||
@@ -538,7 +537,7 @@ void dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs)
|
||||
@param beamforming_mode beamforming mode
|
||||
*/
|
||||
void dlsch_16qam_llr_SIC (NR_DL_FRAME_PARMS *frame_parms,
|
||||
void nr_dlsch_16qam_llr_SIC (NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int32_t **sic_buffer, //Q15
|
||||
int32_t **rho_i,
|
||||
@@ -563,8 +562,7 @@ void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t mod_order_0,
|
||||
uint32_t rb_alloc);
|
||||
|
||||
|
||||
void dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp,
|
||||
int16_t *dlsch_llr,
|
||||
int32_t **dl_ch_mag,
|
||||
@@ -572,8 +570,6 @@ void dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t symbol,
|
||||
uint8_t first_symbol_flag,
|
||||
uint16_t nb_rb,
|
||||
uint16_t pbch_pss_sss_adjust,
|
||||
//int16_t **llr_save,
|
||||
uint32_t llr_offset,
|
||||
uint8_t beamforming_mode);
|
||||
|
||||
@@ -708,7 +704,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param high_speed_flag
|
||||
@param frame_parms Pointer to frame descriptor
|
||||
*/
|
||||
uint16_t dlsch_extract_rbs_single(int32_t **rxdataF,
|
||||
/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
int32_t **rxdataF_ext,
|
||||
int32_t **dl_ch_estimates_ext,
|
||||
@@ -718,7 +714,21 @@ uint16_t dlsch_extract_rbs_single(int32_t **rxdataF,
|
||||
uint8_t symbol,
|
||||
uint8_t subframe,
|
||||
uint32_t high_speed_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
NR_DL_FRAME_PARMS *frame_parms);*/
|
||||
|
||||
unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
int **dl_ch_estimates,
|
||||
int **rxdataF_ext,
|
||||
int **dl_ch_estimates_ext,
|
||||
unsigned short pmi,
|
||||
unsigned char *pmi_ext,
|
||||
unsigned int *rb_alloc,
|
||||
unsigned char symbol,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_pdsch_rb,
|
||||
unsigned char nr_tti_rx,
|
||||
uint32_t high_speed_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
@@ -802,7 +812,7 @@ uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
|
||||
@param output_shift Rescaling for compensated output (should be energy-normalizing)
|
||||
@param phy_measurements Pointer to UE PHY measurements
|
||||
*/
|
||||
void dlsch_channel_compensation(int32_t **rxdataF_ext,
|
||||
void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
|
||||
int32_t **dl_ch_estimates_ext,
|
||||
int32_t **dl_ch_mag,
|
||||
int32_t **dl_ch_magb,
|
||||
@@ -816,6 +826,12 @@ void dlsch_channel_compensation(int32_t **rxdataF_ext,
|
||||
uint8_t output_shift,
|
||||
PHY_NR_MEASUREMENTS *phy_measurements);
|
||||
|
||||
void nr_dlsch_deinterleaving(uint8_t symbol,
|
||||
uint16_t L,
|
||||
uint16_t *llr,
|
||||
uint16_t *llr_deint,
|
||||
uint16_t nb_rb_pdsch);
|
||||
|
||||
void dlsch_dual_stream_correlation(NR_DL_FRAME_PARMS *frame_parms,
|
||||
unsigned char symbol,
|
||||
unsigned short nb_rb,
|
||||
@@ -923,7 +939,7 @@ void dlsch_channel_compensation_TM34(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param pilots_flag Flag to indicate pilots in symbol
|
||||
@param nb_rb Number of allocated RBs
|
||||
*/
|
||||
void dlsch_channel_level(int32_t **dl_ch_estimates_ext,
|
||||
void nr_dlsch_channel_level(int32_t **dl_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *avg,
|
||||
uint8_t pilots_flag,
|
||||
@@ -953,7 +969,7 @@ void dlsch_channel_level_TM7(int32_t **dl_bf_ch_estimates_ext,
|
||||
uint8_t pilots_flag,
|
||||
uint16_t nb_rb);
|
||||
|
||||
void dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
|
||||
void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_UE_DLSCH_t **dlsch_ue,
|
||||
uint8_t symbol_mod,
|
||||
@@ -977,17 +993,42 @@ void dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
|
||||
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
|
||||
@returns 0 on success, 1 on unsuccessful decoding
|
||||
*/
|
||||
uint32_t dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
int16_t *dlsch_llr,
|
||||
NR_DL_FRAME_PARMS *lte_frame_parms,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_DL_UE_HARQ_t *harq_process,
|
||||
uint32_t frame,
|
||||
uint8_t subframe,
|
||||
uint8_t harq_pid,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag);
|
||||
|
||||
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
short *dlsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_DL_UE_HARQ_t *harq_process,
|
||||
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 nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int eNB_id,
|
||||
short *dlsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_DL_UE_HARQ_t *harq_process,
|
||||
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);
|
||||
|
||||
void *nr_dlsch_decoding_2thread0(void *arg);
|
||||
|
||||
void *nr_dlsch_decoding_2thread1(void *arg);
|
||||
|
||||
void nr_dlsch_unscrambling(int16_t* llr,
|
||||
uint32_t size,
|
||||
uint8_t q,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI);
|
||||
|
||||
uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
uint8_t subframe,
|
||||
@@ -1011,7 +1052,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
@param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
|
||||
@param i_mod Modulation order of the interfering stream
|
||||
*/
|
||||
int32_t rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
PDSCH_t type,
|
||||
uint8_t eNB_id,
|
||||
uint8_t eNB_id_i,
|
||||
@@ -1023,12 +1064,16 @@ int32_t rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
uint8_t i_mod,
|
||||
uint8_t harq_pid);
|
||||
|
||||
int32_t rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
uint32_t frame,
|
||||
uint8_t subframe,
|
||||
uint8_t eNB_id,
|
||||
MIMO_mode_t mimo_mode,
|
||||
uint32_t high_speed_flag);
|
||||
int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t eNB_id,
|
||||
MIMO_mode_t mimo_mode,
|
||||
uint32_t high_speed_flag,
|
||||
uint8_t is_secondary_ue,
|
||||
int nb_coreset_active,
|
||||
uint16_t symbol_mon,
|
||||
NR_SEARCHSPACE_TYPE_t searchSpaceType);
|
||||
|
||||
/*! \brief Extract PSS and SSS resource elements
|
||||
@param phy_vars_ue Pointer to UE variables
|
||||
@@ -1386,37 +1431,6 @@ uint32_t ulsch_encoding(uint8_t *a,
|
||||
uint8_t control_only_flag,
|
||||
uint8_t Nbundled);
|
||||
|
||||
|
||||
|
||||
|
||||
/* \brief This routine demodulates the PHICH and updates PUSCH/ULSCH parameters.
|
||||
@param phy_vars_ue Pointer to UE variables
|
||||
@param proc Pointer to RXN_TXNp4 proc
|
||||
@param subframe Subframe of received PDCCH/PHICH
|
||||
@param eNB_id Index of eNB
|
||||
*/
|
||||
|
||||
void rx_phich(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t subframe,
|
||||
uint8_t eNB_id);
|
||||
|
||||
|
||||
/** \brief This routine provides the relationship between a PHICH TXOp and its corresponding PUSCH subframe (Table 8.3.-1 from 36.213).
|
||||
@param frame_parms Pointer to DL frame configuration parameters
|
||||
@param subframe Subframe of received/transmitted PHICH
|
||||
@returns subframe of PUSCH transmission
|
||||
*/
|
||||
uint8_t phich_subframe2_pusch_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
|
||||
|
||||
/** \brief This routine provides the relationship between a PHICH TXOp and its corresponding PUSCH frame (Table 8.3.-1 from 36.213).
|
||||
@param frame_parms Pointer to DL frame configuration parameters
|
||||
@param frame Frame of received/transmitted PHICH
|
||||
@param subframe Subframe of received/transmitted PHICH
|
||||
@returns frame of PUSCH transmission
|
||||
*/
|
||||
int phich_frame2_pusch_frame(NR_DL_FRAME_PARMS *frame_parms, int frame, int subframe);
|
||||
|
||||
void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL);
|
||||
|
||||
void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_NR_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff);
|
||||
@@ -1643,5 +1657,66 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8
|
||||
|
||||
uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
|
||||
|
||||
uint8_t nr_dci_decoding_procedure(int s,
|
||||
int p,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
NR_DCI_ALLOC_t *dci_alloc,
|
||||
NR_SEARCHSPACE_TYPE_t searchSpacetype,
|
||||
int16_t eNB_id,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
||||
uint16_t n_RB_ULBWP,
|
||||
uint16_t n_RB_DLBWP,
|
||||
crc_scrambled_t *crc_scrambled,
|
||||
format_found_t *format_found,
|
||||
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]);
|
||||
|
||||
int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
|
||||
uint8_t eNB_id,
|
||||
int frame,
|
||||
uint8_t nr_tti_rx,
|
||||
uint32_t dci_pdu[4],
|
||||
uint16_t rnti,
|
||||
uint8_t dci_length,
|
||||
NR_DCI_format_t dci_format,
|
||||
NR_UE_PDCCH *pdcch_vars,
|
||||
NR_UE_PDSCH *pdsch_vars,
|
||||
NR_UE_DLSCH_t **dlsch,
|
||||
NR_UE_ULSCH_t *ulsch,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
uint8_t beamforming_mode,
|
||||
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
|
||||
uint16_t n_RB_ULBWP,
|
||||
uint16_t n_RB_DLBWP,
|
||||
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES],
|
||||
NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted);
|
||||
|
||||
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
PDSCH_t type,
|
||||
unsigned char eNB_id,
|
||||
unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
unsigned char symbol,
|
||||
unsigned char first_symbol_flag,
|
||||
RX_type_t rx_type,
|
||||
unsigned char i_mod,
|
||||
unsigned char harq_pid);
|
||||
|
||||
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
|
||||
|
||||
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
short *dlsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
NR_DL_UE_HARQ_t *harq_process,
|
||||
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);
|
||||
|
||||
/**@}*/
|
||||
#endif
|
||||
|
||||
@@ -37,10 +37,7 @@
|
||||
|
||||
|
||||
//#include "PHY/defs_nr_UE.h"
|
||||
//#include "../LTE_TRANSPORT/dci.h"
|
||||
//#include "../LTE_TRANSPORT/mdci.h"
|
||||
//#include "../LTE_TRANSPORT/uci_common.h"
|
||||
//#include "../LTE_TRANSPORT/transport_common.h"
|
||||
#include "../NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#ifndef STANDALONE_COMPILE
|
||||
#include "UTIL/LISTS/list.h"
|
||||
#endif
|
||||
@@ -117,39 +114,31 @@ typedef struct {
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
|
||||
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
||||
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
||||
/// Index of current HARQ round for this ULSCH
|
||||
uint8_t round;
|
||||
/// MCS format of this ULSCH
|
||||
uint8_t mcs;
|
||||
/// Redundancy-version of the current sub-frame
|
||||
uint8_t rvidx;
|
||||
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))];
|
||||
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144];
|
||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||
/// LDPC-code outputs
|
||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
||||
/// Interleaver outputs
|
||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448];
|
||||
/// Number of code segments
|
||||
uint32_t C;
|
||||
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cminus;
|
||||
/// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cplus;
|
||||
/// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kminus;
|
||||
/// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kplus;
|
||||
/// Number of bits in code segments
|
||||
uint32_t K;
|
||||
/// Total number of bits across all segments
|
||||
uint32_t sumKr;
|
||||
/// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
/// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27)
|
||||
/// Msc_initial, Initial number of subcarriers for ULSCH
|
||||
uint16_t Msc_initial;
|
||||
/// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27)
|
||||
/// Nsymb_initial, Initial number of symbols for ULSCH
|
||||
uint8_t Nsymb_initial;
|
||||
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
|
||||
/// n_DMRS for cyclic shift of DMRS
|
||||
uint8_t n_DMRS;
|
||||
/// n_DMRS2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
|
||||
/// n_DMRS2 for cyclic shift of DMRS
|
||||
uint8_t n_DMRS2;
|
||||
/// Flag to indicate that this is a control only ULSCH (i.e. no MAC SDU)
|
||||
uint8_t control_only;
|
||||
@@ -261,9 +250,7 @@ typedef struct {
|
||||
/// Pointer to the payload
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t *c[MAX_NUM_DLSCH_SEGMENTS];
|
||||
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
||||
uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS];
|
||||
uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS];
|
||||
/// Index of current HARQ round for this DLSCH
|
||||
uint8_t round;
|
||||
/// MCS format for this DLSCH
|
||||
@@ -275,24 +262,20 @@ typedef struct {
|
||||
/// MIMO mode for this DLSCH
|
||||
MIMO_mode_t mimo_mode;
|
||||
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
int16_t w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
|
||||
int16_t w[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||
/// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
double w_abs[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
|
||||
double w_abs[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
int16_t *d[MAX_NUM_DLSCH_SEGMENTS];
|
||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||
int16_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
|
||||
/// Number of code segments
|
||||
uint32_t C;
|
||||
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cminus;
|
||||
/// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cplus;
|
||||
/// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kminus;
|
||||
/// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kplus;
|
||||
/// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
/// Number of bits in code segments
|
||||
uint32_t K;
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
/// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17)
|
||||
/// LDPC lifting factor
|
||||
uint32_t Z;
|
||||
/// Number of MIMO layers (streams)
|
||||
uint8_t Nl;
|
||||
/// current delta_pucch
|
||||
int8_t delta_PUCCH;
|
||||
@@ -353,25 +336,22 @@ typedef struct {
|
||||
uint32_t cqi_alloc2;
|
||||
/// saved subband PMI allocation from last PUSCH/PUCCH report
|
||||
uint16_t pmi_alloc;
|
||||
//#if defined(UPGRADE_RAT_NR)
|
||||
#if 1
|
||||
/// Pointers to up to HARQ processes
|
||||
NR_DL_UE_HARQ_t harq_processes[NR_MAX_DLSCH_HARQ_PROCESSES];
|
||||
NR_DL_UE_HARQ_t *harq_processes[NR_MAX_DLSCH_HARQ_PROCESSES];
|
||||
// DL number of harq processes
|
||||
uint8_t number_harq_processes_for_pdsch;
|
||||
/* higher layer parameter for reception of two transport blocks TS 38.213 9.1.3.1 Type-2 HARQ-ACK codebook dtermination */
|
||||
uint8_t Number_MCS_HARQ_DL_DCI;
|
||||
/* spatial bundling of PUCCH */
|
||||
uint8_t HARQ_ACK_spatial_bundling_PUCCH;
|
||||
#endif
|
||||
/// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17
|
||||
uint8_t Mdlharq;
|
||||
/// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
|
||||
uint8_t Kmimo;
|
||||
/// Nsoft parameter related to UE Category
|
||||
uint32_t Nsoft;
|
||||
/// Maximum number of Turbo iterations
|
||||
uint8_t max_turbo_iterations;
|
||||
/// Maximum number of LDPC iterations
|
||||
uint8_t max_ldpc_iterations;
|
||||
/// number of iterations used in last turbo decoding
|
||||
uint8_t last_iteration_cnt;
|
||||
|
||||
|
||||
@@ -383,8 +383,8 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
bzero( primary_synchro_nr[i], sizePss);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
p = malloc(LENGTH_PSS_NR*2);
|
||||
if (p != NULL) {
|
||||
@@ -397,7 +397,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
bzero( primary_synchro_time_nr[i], size);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -408,7 +408,7 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
bzero( pss_corr_ue[i], size);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ void free_context_pss_nr(void)
|
||||
primary_synchro_time_nr[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ void free_context_pss_nr(void)
|
||||
primary_synchro_nr[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ void free_context_pss_nr(void)
|
||||
pss_corr_ue[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
@@ -480,13 +480,13 @@ void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
/* initialise global buffers for synchronisation */
|
||||
synchroF_tmp = malloc16(SYNCF_TMP_SIZE);
|
||||
if (synchroF_tmp == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
synchro_tmp = malloc16(SYNC_TMP_SIZE);
|
||||
if (synchro_tmp == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ void free_context_synchro_nr(void)
|
||||
synchroF_tmp = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -527,7 +527,7 @@ void free_context_synchro_nr(void)
|
||||
synchro_tmp = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
LOG_E(PHY,"Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -838,6 +838,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||
/* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */
|
||||
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
|
||||
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
|
||||
|
||||
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
|
||||
avg[pss_index]=0;
|
||||
memset(pss_corr_ue[pss_index],0,length*sizeof(int64_t));
|
||||
|
||||
@@ -419,7 +419,7 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
|
||||
fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
|
||||
fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
|
||||
fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
|
||||
fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
|
||||
//fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
|
||||
|
||||
// I/Q PBCH comp
|
||||
fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
|
||||
@@ -501,21 +501,29 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
/*
|
||||
int16_t **chest_t;
|
||||
int16_t **chest_f;
|
||||
*/
|
||||
int16_t *pdsch_llr;
|
||||
int16_t *pdsch_comp;
|
||||
int16_t *pdsch_mag;
|
||||
//int16_t *pdsch_mag;
|
||||
int8_t *pdcch_llr;
|
||||
int16_t *pdcch_comp;
|
||||
int8_t *pbch_llr;
|
||||
int16_t *pbch_llr;
|
||||
int16_t *pbch_comp;
|
||||
float Re,Im,ymax=1;
|
||||
int num_pdcch_symbols=3;
|
||||
float *llr, *bit, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
|
||||
float llr_pbch[1920], bit_pbch[1920];
|
||||
float *llr, *bit;
|
||||
float *llr_pdcch, *bit_pdcch;
|
||||
float *I, *Q;
|
||||
float **chest_t_abs;
|
||||
int num_pdcch_symbols=2;
|
||||
int num_re = 4500;
|
||||
int Qm = 2;
|
||||
int coded_bits_per_codeword = num_re*Qm;
|
||||
int symbol, first_symbol,nb_re;
|
||||
int nb_rb_pdsch =50;
|
||||
/*
|
||||
float Re,Im,ymax=1;
|
||||
float **chest_t_abs, *chest_f_abs;
|
||||
float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
|
||||
int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
|
||||
int coded_bits_per_codeword = 0;
|
||||
int mcs = 0;
|
||||
unsigned char harq_pid = 0;
|
||||
*/
|
||||
@@ -554,9 +562,10 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
} else {
|
||||
coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
|
||||
}
|
||||
|
||||
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float));
|
||||
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float));
|
||||
*/
|
||||
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
|
||||
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
|
||||
/*
|
||||
chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
|
||||
|
||||
for (arx=0; arx<nb_antennas_rx; arx++) {
|
||||
@@ -564,11 +573,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
}
|
||||
|
||||
chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
|
||||
*/
|
||||
|
||||
llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
|
||||
bit = malloc(coded_bits_per_codeword*sizeof(float));
|
||||
|
||||
llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
|
||||
bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
|
||||
*/
|
||||
|
||||
rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
|
||||
rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float*));
|
||||
@@ -577,19 +588,20 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
}
|
||||
time = calloc(samples_per_frame,sizeof(float));
|
||||
corr = calloc(samples_per_frame,sizeof(float));
|
||||
|
||||
|
||||
/*
|
||||
chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
|
||||
chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
|
||||
pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
|
||||
*/
|
||||
pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
|
||||
pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
|
||||
|
||||
pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
|
||||
pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
|
||||
pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
|
||||
pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
|
||||
// pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
|
||||
pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
|
||||
pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
|
||||
*/
|
||||
//pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
|
||||
|
||||
// Received signal in time domain of receive antenna 0
|
||||
if (rxsig_t != NULL) {
|
||||
@@ -615,6 +627,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
*/
|
||||
}
|
||||
|
||||
if (phy_vars_ue->is_synchronized==0) {
|
||||
for (ind=0;ind<3;ind++) {
|
||||
if (pss_corr_ue[ind]) {
|
||||
for (i=0; i<samples_per_frame; i++) {
|
||||
@@ -628,7 +641,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Channel Impulse Response (still repeated format)
|
||||
@@ -710,59 +723,55 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// PBCH LLRs
|
||||
if (pbch_llr != NULL) {
|
||||
for (i=0; i<1920; i++) {
|
||||
for (i=0; i<864; i++) {
|
||||
llr_pbch[i] = (float) pbch_llr[i];
|
||||
bit_pbch[i] = (float) i;
|
||||
}
|
||||
|
||||
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
|
||||
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
|
||||
}
|
||||
|
||||
if (phy_vars_ue->is_synchronized==1)
|
||||
first_symbol=5;
|
||||
else
|
||||
first_symbol=1;
|
||||
|
||||
// PBCH I/Q of MF Output
|
||||
if (pbch_comp!=NULL) {
|
||||
for (i=0; i<72*2; i++) {
|
||||
I[i] = pbch_comp[2*i];
|
||||
Q[i] = pbch_comp[2*i+1];
|
||||
for (symbol=first_symbol; symbol<(first_symbol+3); symbol++) {
|
||||
if (symbol == 2 || symbol == 6)
|
||||
nb_re = 72;
|
||||
else
|
||||
nb_re = 180;
|
||||
for (i=0; i<nb_re; i++) {
|
||||
I[i] = pbch_comp[2*symbol*20*12+2*i];
|
||||
Q[i] = pbch_comp[2*symbol*20*12+2*i+1];
|
||||
}
|
||||
}
|
||||
|
||||
fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
|
||||
fl_set_xyplot_data(form->pbch_comp,I,Q,432,"","","");
|
||||
}
|
||||
|
||||
// PDCCH LLRs
|
||||
if (pdcch_llr != NULL) {
|
||||
for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols; i++) {
|
||||
llr_pdcch[i] = (float) pdcch_llr[i];
|
||||
for (i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
|
||||
llr_pdcch[i] = (float) pdcch_llr[2*24*9 +i];
|
||||
bit_pdcch[i] = (float) i;
|
||||
}
|
||||
|
||||
fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
|
||||
if (frame_parms->N_RB_DL != 100)
|
||||
{
|
||||
fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n");
|
||||
}
|
||||
fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
|
||||
}
|
||||
|
||||
// PDCCH I/Q of MF Output
|
||||
if (pdcch_comp!=NULL) {
|
||||
for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
|
||||
I[i] = pdcch_comp[2*i];
|
||||
Q[i] = pdcch_comp[2*i+1];
|
||||
}
|
||||
if (frame_parms->N_RB_DL != 100)
|
||||
{
|
||||
fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n");
|
||||
for (i=0; i<100; i++) {
|
||||
I[i] = pdcch_comp[2*50*12+2*i];
|
||||
Q[i] = pdcch_comp[2*50*12+2*i+1];
|
||||
}
|
||||
fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
|
||||
}
|
||||
|
||||
// PDSCH LLRs
|
||||
@@ -772,32 +781,20 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
bit[i] = (float) i;
|
||||
}
|
||||
|
||||
fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
|
||||
if (frame_parms->N_RB_DL != 100)
|
||||
{
|
||||
fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","","");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n");
|
||||
}
|
||||
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
|
||||
fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","","");
|
||||
}
|
||||
|
||||
// PDSCH I/Q of MF Output
|
||||
if (pdsch_comp!=NULL) {
|
||||
ind=0;
|
||||
|
||||
for (k=0; k<frame_parms->symbols_per_tti; k++) {
|
||||
for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
|
||||
int j = (2*frame_parms->N_RB_DL*12*k)+4*i;
|
||||
I[ind] = (pdsch_mag[j ]!=0? 1.0/pdsch_mag[j ]: 0.0) * pdsch_comp[j ]*1.0;
|
||||
Q[ind] = (pdsch_mag[j+1]!=0? 1.0/pdsch_mag[j+1]: 0.0) * pdsch_comp[j+1]*1.0;
|
||||
ind++;
|
||||
}
|
||||
for (i=0; i<nb_rb_pdsch*12; i++) {
|
||||
I[i] = pdsch_comp[2*2*nb_rb_pdsch*12+2*i ];
|
||||
Q[i] = pdsch_comp[2*2*nb_rb_pdsch*12+2*i+1];
|
||||
}
|
||||
|
||||
fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
|
||||
|
||||
fl_set_xyplot_data(form->pdsch_comp,I,Q,nb_rb_pdsch*12,"","","");
|
||||
}
|
||||
/*
|
||||
|
||||
// PDSCH Throughput
|
||||
memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
@@ -824,19 +821,18 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
}
|
||||
free(rxsig_t_dB);
|
||||
|
||||
/*
|
||||
free(I);
|
||||
free(Q);
|
||||
free(chest_f_abs);
|
||||
free(llr);
|
||||
free(bit);
|
||||
free(bit_pdcch);
|
||||
free(llr_pdcch);
|
||||
|
||||
/*
|
||||
free(chest_f_abs);
|
||||
for (arx=0; arx<nb_antennas_rx; arx++) {
|
||||
free(chest_t_abs[arx]);
|
||||
}
|
||||
|
||||
free(chest_t_abs);
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
|
||||
struct complex {
|
||||
double x;
|
||||
double y;
|
||||
@@ -416,4 +415,6 @@ void idft8192(int16_t *x,int16_t *y,int scale);
|
||||
|
||||
double interp(double x, double *xs, double *ys, int count);
|
||||
|
||||
int write_output(const char *fname,const char *vname,void *data,int length,int dec,char format);
|
||||
|
||||
#endif //__PHY_TOOLS_DEFS__H__
|
||||
|
||||
@@ -67,7 +67,10 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "TOOLS/tools_defs.h"
|
||||
|
||||
#include "targets/COMMON/openairinterface5g_limits.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "nfapi_interface.h"
|
||||
@@ -102,6 +105,7 @@
|
||||
#ifdef OCP_FRAMEWORK
|
||||
#include "enums.h"
|
||||
#else
|
||||
|
||||
typedef enum {TDD=1,FDD=0} lte_frame_type_t;
|
||||
|
||||
typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t;
|
||||
|
||||
@@ -710,4 +710,5 @@ typedef struct PHY_VARS_eNB_s {
|
||||
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
|
||||
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
|
||||
} PHY_VARS_eNB;
|
||||
|
||||
#endif // __PHY_DEFS_eNB_H__
|
||||
|
||||
+93
-4
@@ -37,6 +37,7 @@
|
||||
#include "defs_nr_common.h"
|
||||
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
|
||||
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
||||
|
||||
@@ -61,6 +62,8 @@ typedef struct {
|
||||
uint16_t size;
|
||||
/// Aggregation level
|
||||
uint8_t L;
|
||||
/// HARQ PID
|
||||
uint8_t harq_pid;
|
||||
/// PDCCH parameters
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params;
|
||||
/// CCE list
|
||||
@@ -71,9 +74,92 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_dci;
|
||||
uint8_t num_pdsch_rnti;
|
||||
NR_gNB_DCI_ALLOC_t dci_alloc[256];
|
||||
} NR_gNB_PDCCH;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Nfapi DLSCH PDU
|
||||
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
|
||||
/// pointer to pdu from MAC interface (this is "a" in 36.212)
|
||||
uint8_t *pdu;
|
||||
/// The payload + CRC size in bits, "B" from 36-212
|
||||
uint32_t B;
|
||||
/// Pointer to the payload
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t *c[MAX_NUM_NR_DLSCH_SEGMENTS];
|
||||
/// 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;
|
||||
/// MIMO mode for this DLSCH
|
||||
MIMO_mode_t mimo_mode;
|
||||
/// Concatenated sequences
|
||||
uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||
/// LDPC-code outputs
|
||||
uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
|
||||
/// Interleaver outputs
|
||||
uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
|
||||
/// Number of code segments
|
||||
uint32_t C;
|
||||
/// Number of bits in "small" code segments
|
||||
uint32_t K;
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
} NR_DL_gNB_HARQ_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
/// Pointers to 16 HARQ processes for the DLSCH
|
||||
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)
|
||||
int32_t *txdataF[NR_MAX_NB_LAYERS];
|
||||
/// Modulated symbols buffer
|
||||
int32_t *mod_symbs[NR_MAX_NB_CODEWORDS];
|
||||
/// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
|
||||
int32_t **ue_spec_bf_weights[NR_MAX_NB_LAYERS];
|
||||
/// dl channel estimates (estimated from ul channel estimates)
|
||||
int32_t **calib_dl_ch_estimates;
|
||||
/// Allocated RNTI (0 means DLSCH_t is not currently used)
|
||||
uint16_t rnti;
|
||||
/// Active flag for baseband transmitter processing
|
||||
uint8_t active;
|
||||
/// HARQ process mask, indicates which processes are currently active
|
||||
uint16_t harq_mask;
|
||||
/// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK.
|
||||
uint8_t subframe_tx[10];
|
||||
/// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK.
|
||||
uint8_t nCCE[10];
|
||||
/// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids
|
||||
uint8_t harq_ids[10];
|
||||
/// Window size (in outgoing transport blocks) for fine-grain rate adaptation
|
||||
uint8_t ra_window_size;
|
||||
/// First-round error threshold for fine-grain rate adaptation
|
||||
uint8_t error_threshold;
|
||||
/// Number of soft channel bits
|
||||
uint32_t G;
|
||||
/// Codebook index for this dlsch (0,1,2,3)
|
||||
uint8_t codebook_index;
|
||||
/// Maximum number of HARQ processes
|
||||
uint8_t Mdlharq;
|
||||
/// Maximum number of HARQ rounds
|
||||
uint8_t Mlimit;
|
||||
/// MIMO transmission mode indicator for this sub-frame
|
||||
uint8_t Kmimo;
|
||||
/// Nsoft parameter related to UE Category
|
||||
uint32_t Nsoft;
|
||||
/// amplitude of PDSCH (compared to RS) in symbols without pilots
|
||||
int16_t sqrt_rho_a;
|
||||
/// amplitude of PDSCH (compared to RS) in symbols containing pilots
|
||||
int16_t sqrt_rho_b;
|
||||
} NR_gNB_DLSCH_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// \brief Pointers (dynamic) to the received data in the time domain.
|
||||
/// - first index: rx antenna [0..nb_antennas_rx[
|
||||
@@ -313,11 +399,11 @@ typedef struct PHY_VARS_gNB_s {
|
||||
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_PRACH prach_vars;
|
||||
LTE_eNB_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
|
||||
LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
|
||||
LTE_eNB_DLSCH_t *dlsch_MCH;
|
||||
LTE_eNB_DLSCH_t *dlsch_PCH;
|
||||
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
|
||||
NR_gNB_DLSCH_t *dlsch_MCH;
|
||||
NR_gNB_DLSCH_t *dlsch_PCH;
|
||||
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
|
||||
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
|
||||
|
||||
@@ -338,6 +424,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// PDCCH DMRS sequence
|
||||
uint32_t ***nr_gold_pdcch_dmrs;
|
||||
|
||||
/// PDSCH DMRS sequence
|
||||
uint32_t ****nr_gold_pdsch_dmrs;
|
||||
|
||||
/// Indicator set to 0 after first SR
|
||||
uint8_t first_sr[NUMBER_OF_UE_MAX];
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
# include "COMMON/ral_messages_types.h"
|
||||
# include "UTIL/queue.h"
|
||||
# endif
|
||||
# include "common/utils/LOG/log.h"
|
||||
# define msg(aRGS...) LOG_D(PHY, ##aRGS)
|
||||
# else
|
||||
# define msg printf
|
||||
@@ -864,16 +863,16 @@ typedef struct {
|
||||
int32_t **rho;
|
||||
/// \brief Pointer to llrs, 4-bit resolution.
|
||||
/// - first index: ? [0..48*N_RB_DL[
|
||||
uint16_t *llr;
|
||||
int16_t *llr;
|
||||
/// \brief Pointer to llrs, 16-bit resolution.
|
||||
/// - first index: ? [0..96*N_RB_DL[
|
||||
uint16_t *llr16;
|
||||
int16_t *llr16;
|
||||
/// \brief \f$\overline{w}\f$ from 36-211.
|
||||
/// - first index: ? [0..48*N_RB_DL[
|
||||
uint16_t *wbar;
|
||||
int16_t *wbar;
|
||||
/// \brief PDCCH/DCI e-sequence (input to rate matching).
|
||||
/// - first index: ? [0..96*N_RB_DL[
|
||||
int8_t *e_rx;
|
||||
int16_t *e_rx;
|
||||
/// number of PDCCH symbols in current subframe
|
||||
uint8_t num_pdcch_symbols;
|
||||
/// Allocated CRNTI for UE
|
||||
|
||||
@@ -54,9 +54,12 @@
|
||||
#define ONE_OVER_SQRT2_Q15 23170
|
||||
#define ONE_OVER_TWO_Q15 16384
|
||||
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 14
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 686
|
||||
#define NR_MOD_TABLE_BPSK_OFFSET 1
|
||||
#define NR_MOD_TABLE_QPSK_OFFSET 3
|
||||
#define NR_MOD_TABLE_QAM16_OFFSET 7
|
||||
#define NR_MOD_TABLE_QAM64_OFFSET 23
|
||||
#define NR_MOD_TABLE_QAM256_OFFSET 87
|
||||
|
||||
#define NR_PSS_LENGTH 127
|
||||
#define NR_SSS_LENGTH 127
|
||||
@@ -71,6 +74,9 @@
|
||||
/*used for the resource mapping*/
|
||||
#define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
|
||||
|
||||
#define NR_MAX_PDSCH_DMRS_LENGTH 3300 //275*6(k)*2(QPSK)
|
||||
#define NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD 104 // ceil(NR_MAX_PDSCH_DMRS_LENGTH/32)
|
||||
|
||||
#define NR_MAX_DCI_PAYLOAD_SIZE 64
|
||||
#define NR_MAX_DCI_SIZE 1728 //16(L)*2(QPSK)*9(12 RE per REG - 3(DMRS))*6(REG per CCE)
|
||||
#define NR_MAX_DCI_SIZE_DWORD 54 // ceil(NR_MAX_DCI_SIZE/32)
|
||||
@@ -80,6 +86,13 @@
|
||||
#define NR_MAX_PDCCH_AGG_LEVEL 16
|
||||
#define NR_MAX_CSET_DURATION 3
|
||||
|
||||
#define NR_MAX_NB_RBG 18
|
||||
#define NR_MAX_NB_LAYERS 8
|
||||
#define NR_MAX_NB_CODEWORDS 2
|
||||
#define NR_MAX_NB_HARQ_PROCESSES 16
|
||||
#define NR_MAX_PDSCH_ENCODED_LENGTH 950984
|
||||
#define NR_MAX_PDSCH_TBS 3824
|
||||
|
||||
typedef enum {
|
||||
NR_MU_0=0,
|
||||
NR_MU_1,
|
||||
@@ -109,6 +122,36 @@ typedef enum {
|
||||
nr_FR2
|
||||
} nr_frequency_range_e;
|
||||
|
||||
typedef enum {
|
||||
MOD_BPSK=0,
|
||||
MOD_QPSK,
|
||||
MOD_QAM16,
|
||||
MOD_QAM64,
|
||||
MOD_QAM256
|
||||
}nr_mod_t;
|
||||
|
||||
typedef struct {
|
||||
/// Size of first RBG
|
||||
uint8_t start_size;
|
||||
/// Nominal size
|
||||
uint8_t P;
|
||||
/// Size of last RBG
|
||||
uint8_t end_size;
|
||||
/// Number of RBG
|
||||
uint8_t N_RBG;
|
||||
}nr_rbg_parms_t;
|
||||
|
||||
typedef struct {
|
||||
/// Size of first PRG
|
||||
uint8_t start_size;
|
||||
/// Nominal size
|
||||
uint8_t P_prime;
|
||||
/// Size of last PRG
|
||||
uint8_t end_size;
|
||||
/// Number of PRG
|
||||
uint8_t N_PRG;
|
||||
} nr_prg_parms_t;
|
||||
|
||||
typedef struct NR_BWP_PARMS {
|
||||
/// BWP ID
|
||||
uint8_t bwp_id;
|
||||
@@ -122,6 +165,10 @@ typedef struct NR_BWP_PARMS {
|
||||
uint16_t ofdm_symbol_size;
|
||||
/// Cyclic prefix
|
||||
uint8_t cyclic_prefix;
|
||||
/// RBG params
|
||||
nr_rbg_parms_t rbg_parms;
|
||||
/// PRG params
|
||||
nr_prg_parms_t prg_parms;
|
||||
} NR_BWP_PARMS;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -38,6 +38,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
|
||||
extern unsigned int DAQ_MBOX;
|
||||
extern int number_of_cards;
|
||||
|
||||
extern short conjugate[8],conjugate2[8];
|
||||
|
||||
#ifndef OCP_FRAMEWORK
|
||||
//extern PHY_VARS_eNB ***PHY_vars_eNB_g;
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __PHY_EXTERN_UE__H__
|
||||
#define __PHY_EXTERN_UE__H__
|
||||
#ifndef __PHY_EXTERN_NR_UE__H__
|
||||
#define __PHY_EXTERN_NR_UE__H__
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "common/ran_context.h"
|
||||
@@ -34,6 +34,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
|
||||
|
||||
//#include "PHY/LTE_TRANSPORT/transport_extern.h"
|
||||
|
||||
extern short conjugate[8],conjugate2[8];
|
||||
extern int number_of_cards;
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
|
||||
|
||||
extern int number_of_cards;
|
||||
|
||||
extern short conjugate[8],conjugate2[8];
|
||||
|
||||
#ifndef OCP_FRAMEWORK
|
||||
extern PHY_VARS_UE ***PHY_vars_UE_g;
|
||||
|
||||
@@ -59,6 +59,8 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
|
||||
unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
|
||||
|
||||
|
||||
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||
|
||||
|
||||
#include "SIMULATION/ETH_TRANSPORT/vars.h"
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __PHY_VARS_NR_H__
|
||||
#define __PHY_VARS_NR_H__
|
||||
#ifndef __PHY_VARS_NR_UE_H__
|
||||
#define __PHY_VARS_NR_UE_H__
|
||||
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
@@ -55,6 +55,9 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
|
||||
unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
|
||||
|
||||
|
||||
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||
|
||||
|
||||
#include "SIMULATION/ETH_TRANSPORT/vars.h"
|
||||
|
||||
@@ -143,5 +146,5 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
|
||||
/// lookup table for scrambling in TX
|
||||
uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
|
||||
|
||||
uint8_t max_turbo_iterations=4;
|
||||
uint8_t max_ldpc_iterations=4;
|
||||
#endif /*__PHY_VARS_H__ */
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "PHY/phy_vars_ue.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
|
||||
@@ -54,6 +53,10 @@ unsigned short rev[2048],rev_times4[8192],rev_half[1024];
|
||||
unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
|
||||
|
||||
|
||||
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
|
||||
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||
|
||||
|
||||
#include "SIMULATION/ETH_TRANSPORT/vars.h"
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB,
|
||||
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
|
||||
int frame, int slot,
|
||||
gNB_L1_rxtx_proc_t *proc,
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu)
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu,
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu)
|
||||
{
|
||||
int idx = slot&1;
|
||||
NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars;
|
||||
@@ -65,7 +66,7 @@ void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
|
||||
LOG_I(PHY,"Frame %d, Slot %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,slot, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci);
|
||||
|
||||
// copy dci configuration into gNB structure
|
||||
nr_fill_dci_and_dlsch(gNB,frame,slot,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dl_config_pdu);
|
||||
nr_fill_dci_and_dlsch(gNB,frame,slot,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],&dl_config_pdu->dci_dl_pdu,&dl_config_dlsch_pdu->dlsch_pdu);
|
||||
|
||||
LOG_I(PHY,"Frame %d, Slot %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:slot_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->slot_tx, pdcch_vars->num_dci, proc->slot_tx, idx, pdcch_vars->num_dci);
|
||||
}
|
||||
@@ -92,6 +93,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu;
|
||||
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu;
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu;
|
||||
|
||||
int i;
|
||||
|
||||
@@ -102,6 +104,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
|
||||
int do_oai =0;
|
||||
int dont_send =0;
|
||||
gNB->pdcch_vars.num_dci = 0;
|
||||
gNB->pdcch_vars.num_pdsch_rnti = 0;
|
||||
|
||||
gNB->pdcch_vars.num_dci=0;
|
||||
|
||||
@@ -125,11 +129,14 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE:
|
||||
dl_config_dlsch_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[++i];
|
||||
handle_nfapi_nr_dci_dl_pdu(gNB,
|
||||
frame, slot,
|
||||
proc,
|
||||
dl_config_pdu);
|
||||
dl_config_pdu,
|
||||
dl_config_dlsch_pdu);
|
||||
gNB->pdcch_vars.num_dci++;
|
||||
gNB->pdcch_vars.num_pdsch_rnti++;
|
||||
do_oai=1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -42,4 +42,5 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
|
||||
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
|
||||
int frame, int subframe,
|
||||
gNB_L1_rxtx_proc_t *proc,
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu);
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu,
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu);
|
||||
|
||||
@@ -130,6 +130,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru) {
|
||||
// this copy should be done in the precoding thread (currently inactive)
|
||||
for (int aa=0;aa<ru->nb_tx;aa++)
|
||||
memcpy((void*)ru->common.txdataF_BF[aa],
|
||||
|
||||
(void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "sched_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
#include "SCHED/sched_eNB.h"
|
||||
#include "SCHED/sched_common_extern.h"
|
||||
#include "nfapi_interface.h"
|
||||
@@ -165,8 +166,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
int aa;
|
||||
int frame=proc->frame_tx;
|
||||
|
||||
int slot=proc->slot_tx;
|
||||
uint8_t num_dci=0;
|
||||
uint8_t num_dci=0,num_pdsch_rnti;
|
||||
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||
@@ -190,17 +192,27 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
num_dci = gNB->pdcch_vars.num_dci;
|
||||
|
||||
num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
|
||||
if (num_dci) {
|
||||
LOG_I(PHY, "[gNB %d] Frame %d slot %d \
|
||||
Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci);
|
||||
|
||||
|
||||
if (nfapi_mode == 0 || nfapi_mode == 1)
|
||||
if (nfapi_mode == 0 || nfapi_mode == 1){
|
||||
nr_generate_dci_top(gNB->pdcch_vars,
|
||||
&gNB->nrPolar_params,
|
||||
gNB->nr_gold_pdcch_dmrs[slot],
|
||||
gNB->common_vars.txdataF[0],
|
||||
AMP, *fp, *cfg);
|
||||
if (num_pdsch_rnti) {
|
||||
LOG_I(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti);
|
||||
nr_generate_pdsch(*gNB->dlsch[0][0],
|
||||
gNB->pdcch_vars.dci_alloc[0],
|
||||
gNB->nr_gold_pdsch_dmrs[slot],
|
||||
gNB->common_vars.txdataF,
|
||||
AMP, slot, *fp, *cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
|
||||
@param mode calib/normal mode
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
*/
|
||||
void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
|
||||
/*! \brief Scheduling for UE RX procedures in normal subframes.
|
||||
@param last_slot Index of last slot (0-19)
|
||||
@param phy_vars_ue Pointer to UE variables on which to act
|
||||
@@ -124,7 +124,8 @@ void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB
|
||||
@param phy_vars_rn pointer to RN variables
|
||||
*/
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode);
|
||||
int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
|
||||
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
|
||||
|
||||
|
||||
#ifdef UE_SLOT_PARALLELISATION
|
||||
void *UE_thread_slot1_dl_processing(void *arg);
|
||||
@@ -136,7 +137,7 @@ void *UE_thread_slot1_dl_processing(void *arg);
|
||||
@param abstraction_flag Indicator of PHY abstraction
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
*/
|
||||
void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type);
|
||||
//void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type);
|
||||
|
||||
/*! \brief Scheduling for UE RX procedures in TDD S-subframes.
|
||||
@param phy_vars_ue Pointer to UE variables on which to act
|
||||
@@ -144,7 +145,7 @@ void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstractio
|
||||
@param abstraction_flag Indicator of PHY abstraction
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
*/
|
||||
void phy_procedures_UE_S_RX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag, relaying_type_t r_type);
|
||||
//void phy_procedures_UE_S_RX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag, relaying_type_t r_type);
|
||||
|
||||
|
||||
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
|
||||
@@ -154,7 +155,7 @@ void phy_procedures_UE_S_RX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstractio
|
||||
*/
|
||||
|
||||
|
||||
nr_subframe_t nr_subframe_select(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
|
||||
//nr_subframe_t nr_subframe_select(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
|
||||
|
||||
|
||||
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index. Same as nr_subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler.
|
||||
@@ -368,6 +369,11 @@ int nr_is_srs_occasion_common(NR_DL_FRAME_PARMS *frame_parms,int frame_tx,int su
|
||||
|
||||
void nr_compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
|
||||
|
||||
void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx);
|
||||
int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx);
|
||||
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
|
||||
|
||||
int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
|
||||
/// module id
|
||||
module_id_t module_id = scheduled_response->module_id;
|
||||
/// component carrier id
|
||||
@@ -106,7 +107,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
//dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
|
||||
|
||||
NR_DL_UE_HARQ_t dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
|
||||
NR_DL_UE_HARQ_t dlsch0_harq = *(dlsch0->harq_processes[current_harq_pid]);
|
||||
|
||||
|
||||
//dlsch0->harq_processes[current_harq_pid]->nb_rb = dlsch_config_pdu->number_rbs;
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
|
||||
|
||||
dlsch[0]->current_harq_pid = nr_dci_info_extracted->harq_process_number;
|
||||
|
||||
NR_DL_UE_HARQ_t *dl_harq = &dlsch[0]->harq_processes[dlsch[0]->current_harq_pid];
|
||||
NR_DL_UE_HARQ_t *dl_harq = dlsch[0]->harq_processes[dlsch[0]->current_harq_pid];
|
||||
|
||||
dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1;
|
||||
dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind;
|
||||
@@ -401,9 +401,9 @@ void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int
|
||||
|
||||
memset(&dlsch->harq_processes[harq_pid],0,sizeof(NR_DL_UE_HARQ_t));
|
||||
|
||||
NR_DL_UE_HARQ_t dl_harq = dlsch->harq_processes[harq_pid];
|
||||
NR_DL_UE_HARQ_t *dl_harq = dlsch->harq_processes[harq_pid];
|
||||
|
||||
init_downlink_harq_status(&dl_harq);
|
||||
init_downlink_harq_status(dl_harq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -193,7 +193,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
|
||||
|
||||
if (dl_harq_pid < ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->number_harq_processes_for_pdsch) {
|
||||
/* pucch indicator can be reseted in function get_downlink_ack so it should be get now */
|
||||
pucch_resource_indicator = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid].harq_ack.pucch_resource_indicator;
|
||||
pucch_resource_indicator = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator;
|
||||
}
|
||||
|
||||
/* Part - I
|
||||
@@ -292,7 +292,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
|
||||
int occ_length = 0;
|
||||
int occ_Index = 0;
|
||||
|
||||
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid].harq_ack;
|
||||
NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack;
|
||||
|
||||
if (select_pucch_resource(ue, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set,
|
||||
&pucch_resource_id, harq_status) == TRUE) {
|
||||
@@ -691,7 +691,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
|
||||
|
||||
for (int dl_harq_pid = 0; dl_harq_pid < number_pid_dl; dl_harq_pid++) {
|
||||
|
||||
harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid].harq_ack;
|
||||
harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack;
|
||||
|
||||
/* check if current tx slot should transmit downlink acknowlegment */
|
||||
if (harq_status->slot_for_feedback_ack == proc->nr_tti_tx) {
|
||||
|
||||
@@ -0,0 +1,677 @@
|
||||
/*
|
||||
* 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/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/INIT/phy_init.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.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"
|
||||
|
||||
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_earfcn(int eutra_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; //,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;
|
||||
uint8_t N_RB_DL=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;
|
||||
uint32_t Nsoft;
|
||||
double sigma;
|
||||
unsigned char qbits=8;
|
||||
int ret;
|
||||
int run_initial_sync=0;
|
||||
int loglvl=OAILOG_WARNING;
|
||||
float target_error_rate = 0.01;
|
||||
|
||||
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: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 'N':
|
||||
Nid_cell = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
N_RB_DL = atoi(optarg);
|
||||
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;
|
||||
|
||||
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("-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;
|
||||
crcTableInit();
|
||||
nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu);
|
||||
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));
|
||||
}
|
||||
|
||||
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 (int sf = 0; sf < 2; sf++) {
|
||||
for (i=0; i<2; i++) {
|
||||
UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo,8,Nsoft,5,N_RB_DL,0);
|
||||
|
||||
if (!UE->dlsch[sf][0][i]) {
|
||||
printf("Can't get ue dlsch structures\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
UE->dlsch[sf][0][i]->rnti = n_rnti;
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
|
||||
time_stats_t *rm_stats;
|
||||
time_stats_t *te_stats;
|
||||
time_stats_t *i_stats;
|
||||
uint8_t is_crnti;
|
||||
uint8_t llr8_flag;
|
||||
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;
|
||||
dlsch->rnti =1;
|
||||
/*dlsch->harq_processes[0]->mcs = Imcs;
|
||||
dlsch->harq_processes[0]->rvidx = rvidx;*/
|
||||
//printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
|
||||
// dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
|
||||
mod_order = nr_get_Qm(Imcs,1);
|
||||
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);
|
||||
//dlsch->harq_ids[subframe]= 0;
|
||||
rel15->n_prb = nb_rb;
|
||||
rel15->nb_symbols = nb_symb_sch;
|
||||
rel15->modulation_order = mod_order;
|
||||
rel15->nb_layers = Nl;
|
||||
rel15->nb_re_dmrs = nb_re_dmrs;
|
||||
rel15->transport_block_size = TBS;
|
||||
double *modulated_input = malloc16(sizeof(double) * 16*68*384);
|
||||
short *channel_output_fixed = malloc16(sizeof( short) *16* 68*384);
|
||||
short *channel_output_uncoded = malloc16(sizeof(unsigned short) *16* 68*384);
|
||||
double 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);
|
||||
NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[UE->current_thread_id[subframe]][0][0];
|
||||
NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
|
||||
harq_process->mcs = Imcs;
|
||||
harq_process->Nl = Nl;
|
||||
harq_process->nb_rb = nb_rb;
|
||||
harq_process->Qm = mod_order;
|
||||
harq_process->rvidx = rvidx;
|
||||
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm,nb_symb_sch);
|
||||
unsigned char *test_input;
|
||||
test_input=(unsigned char *)malloc16(sizeof(unsigned char) * TBS/8);
|
||||
|
||||
for (i=0; i<TBS/8; i++)
|
||||
test_input[i]=(unsigned char) rand();
|
||||
|
||||
estimated_output = harq_process->b;
|
||||
|
||||
/*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
|
||||
if (input_fd==NULL) {
|
||||
nr_dlsch_encoding(test_input,
|
||||
subframe,
|
||||
dlsch,
|
||||
frame_parms);
|
||||
}
|
||||
|
||||
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("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
|
||||
if (dlsch->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);
|
||||
channel_output_fixed[i] = (short)quantize(sigma/4.0/4.0,modulated_input[i] + sigma*gaussdouble(0.0,1.0),qbits);
|
||||
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
|
||||
//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] != dlsch->harq_processes[harq_pid]->f[i])
|
||||
errors_bit_uncoded = errors_bit_uncoded + 1;
|
||||
}
|
||||
|
||||
//if (errors_bit_uncoded>10)
|
||||
//printf("errors bits uncoded %f\n", errors_bit_uncoded);
|
||||
#ifdef DEBUG_CODER
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
#endif
|
||||
ret = nr_dlsch_decoding(UE,
|
||||
channel_output_fixed,
|
||||
&UE->frame_parms,
|
||||
dlsch0_ue,
|
||||
dlsch0_ue->harq_processes[0],
|
||||
frame,
|
||||
nb_symb_sch,
|
||||
subframe,
|
||||
harq_pid,
|
||||
is_crnti,
|
||||
llr8_flag);
|
||||
|
||||
if (ret>dlsch0_ue->max_ldpc_iterations)
|
||||
n_errors++;
|
||||
|
||||
//count errors
|
||||
errors_bit = 0;
|
||||
|
||||
for (i=0; i<TBS; i++) {
|
||||
estimated_output_bit[i] = (estimated_output[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("\n errors_bit %d (trial %d)\n", errors_bit,trial);
|
||||
}
|
||||
}
|
||||
|
||||
printf("SNR %f, BLER %f (false positive %f)\n",SNR,(float)n_errors/(float)n_trials,(float)n_false_positive/(float)n_trials);
|
||||
|
||||
if ((float)n_errors/(float)n_trials < target_error_rate)
|
||||
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("gNB %d\n",i);
|
||||
free_gNB_dlsch(gNB->dlsch[0][i]);
|
||||
printf("UE %d\n",i);
|
||||
free_nr_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/defs_gNB.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/INIT/phy_init.h"
|
||||
@@ -494,6 +495,7 @@ int main(int argc, char **argv)
|
||||
gNB_mac = RC.nrmac[0];
|
||||
|
||||
config_common(0,0,78,(uint64_t)3640000000L,N_RB_DL);
|
||||
config_nr_mib(0,0,1,kHz30,0,0,0,0);
|
||||
|
||||
nr_l2_init_ue();
|
||||
UE_mac = get_mac_inst(0);
|
||||
@@ -682,10 +684,9 @@ int main(int argc, char **argv)
|
||||
phy_procedures_nrUE_RX(UE,
|
||||
&UE_proc,
|
||||
0,
|
||||
0,
|
||||
do_pdcch_flag,
|
||||
normal_txrx,
|
||||
no_relay);
|
||||
normal_txrx);
|
||||
|
||||
|
||||
if (UE->dci_ind.number_of_dcis==0) n_errors++;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/defs_gNB.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/INIT/phy_init.h"
|
||||
@@ -426,7 +427,7 @@ int main(int argc, char **argv)
|
||||
//configure UE
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
phy_init_nr_top(UE);
|
||||
//phy_init_nr_top(UE); //called from init_nr_ue_signal
|
||||
if (run_initial_sync==1) UE->is_synchronized = 0;
|
||||
else UE->is_synchronized = 1;
|
||||
|
||||
@@ -524,6 +525,7 @@ int main(int argc, char **argv)
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_subframe,1,1);
|
||||
}
|
||||
|
||||
if (UE->is_synchronized == 0) {
|
||||
ret = nr_initial_sync(UE, normal_txrx);
|
||||
printf("nr_initial_sync1 returns %d\n",ret);
|
||||
|
||||
@@ -629,7 +629,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
|
||||
////////// Physical parameters
|
||||
//checkedparam_t config_check_CCparams[] = NRCCPARAMS_CHECK;
|
||||
checkedparam_t config_check_CCparams[] = NRCCPARAMS_CHECK;
|
||||
paramdef_t CCsParams[] = NRCCPARAMS_DESC;
|
||||
paramlist_def_t CCsParamList = {GNB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
|
||||
|
||||
|
||||
@@ -423,7 +423,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
}
|
||||
|
||||
// Phytest scheduling/ option not activated because of pending bug
|
||||
nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);
|
||||
|
||||
if (slotP==2)
|
||||
nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,11 +31,13 @@
|
||||
#include "nr_mac_gNB.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "mac_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
/*Scheduling of DLSCH with associated DCI in common search space
|
||||
* current version has only a DCI for type 1 PDCCH for RA-RNTI*/
|
||||
* current version has only a DCI for type 1 PDCCH for C_RNTI*/
|
||||
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP)
|
||||
@@ -45,9 +47,12 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
//NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
nfapi_nr_dl_config_request_body_t *dl_req;
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu;
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_dci_pdu;
|
||||
nfapi_nr_dl_config_request_pdu_t *dl_config_dlsch_pdu;
|
||||
nfapi_tx_request_pdu_t *TX_req;
|
||||
|
||||
nfapi_nr_config_request_t *cfg = &nr_mac->config[0];
|
||||
uint16_t rnti = 0x1234;
|
||||
|
||||
uint16_t sfn_sf = frameP << 7 | slotP;
|
||||
int dl_carrier_bandwidth = cfg->rf_config.dl_carrier_bandwidth.value;
|
||||
@@ -60,13 +65,30 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
|
||||
dl_req = &nr_mac->DL_req[CC_id].dl_config_request_body;
|
||||
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
|
||||
memset((void*)dl_config_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
|
||||
dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
|
||||
dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu));
|
||||
dl_config_dci_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
|
||||
memset((void*)dl_config_dci_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
|
||||
dl_config_dci_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
|
||||
dl_config_dci_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dci_dl_pdu));
|
||||
|
||||
nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel15;
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_pdu->dci_dl_pdu.pdcch_params_rel15;
|
||||
dl_config_dlsch_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu+1];
|
||||
memset((void*)dl_config_dlsch_pdu,0,sizeof(nfapi_nr_dl_config_request_pdu_t));
|
||||
dl_config_dlsch_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DLSCH_PDU_TYPE;
|
||||
dl_config_dlsch_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_nr_dl_config_dlsch_pdu));
|
||||
|
||||
nfapi_nr_dl_config_dci_dl_pdu_rel15_t *pdu_rel15 = &dl_config_dci_pdu->dci_dl_pdu.dci_dl_pdu_rel15;
|
||||
nfapi_nr_dl_config_pdcch_parameters_rel15_t *params_rel15 = &dl_config_dci_pdu->dci_dl_pdu.pdcch_params_rel15;
|
||||
nfapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu_rel15 = &dl_config_dlsch_pdu->dlsch_pdu.dlsch_pdu_rel15;
|
||||
|
||||
dlsch_pdu_rel15->start_prb = 0;
|
||||
dlsch_pdu_rel15->n_prb = 50;
|
||||
dlsch_pdu_rel15->start_symbol = 2;
|
||||
dlsch_pdu_rel15->nb_symbols = 8;
|
||||
dlsch_pdu_rel15->rnti = rnti;
|
||||
dlsch_pdu_rel15->nb_layers =1;
|
||||
dlsch_pdu_rel15->nb_codewords = 1;
|
||||
dlsch_pdu_rel15->mcs_idx = 9;
|
||||
dlsch_pdu_rel15->ndi = 1;
|
||||
dlsch_pdu_rel15->redundancy_version = 0;
|
||||
|
||||
|
||||
nr_configure_css_dci_initial(params_rel15,
|
||||
@@ -76,20 +98,33 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
|
||||
params_rel15->first_slot = 0;
|
||||
|
||||
pdu_rel15->frequency_domain_assignment = 5;
|
||||
pdu_rel15->time_domain_assignment = 2;
|
||||
pdu_rel15->vrb_to_prb_mapping = 0;
|
||||
pdu_rel15->mcs = 12;
|
||||
pdu_rel15->frequency_domain_assignment = get_RIV(dlsch_pdu_rel15->start_prb, dlsch_pdu_rel15->n_prb, cfg->rf_config.dl_carrier_bandwidth.value);
|
||||
pdu_rel15->time_domain_assignment = get_SLIV(dlsch_pdu_rel15->start_symbol, dlsch_pdu_rel15->nb_symbols);
|
||||
pdu_rel15->vrb_to_prb_mapping = 1;
|
||||
pdu_rel15->mcs = 9;
|
||||
pdu_rel15->tb_scaling = 1;
|
||||
LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d\n",
|
||||
|
||||
pdu_rel15->ra_preamble_index = 25;
|
||||
pdu_rel15->format_indicator = 1;
|
||||
pdu_rel15->ndi = 1;
|
||||
pdu_rel15->rv = 0;
|
||||
pdu_rel15->harq_pid = 0;
|
||||
pdu_rel15->dai = 2;
|
||||
pdu_rel15->tpc = 2;
|
||||
pdu_rel15->pucch_resource_indicator = 7;
|
||||
pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7;
|
||||
|
||||
LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
|
||||
pdu_rel15->frequency_domain_assignment,
|
||||
pdu_rel15->time_domain_assignment,
|
||||
pdu_rel15->vrb_to_prb_mapping,
|
||||
pdu_rel15->mcs,
|
||||
pdu_rel15->tb_scaling);
|
||||
pdu_rel15->tb_scaling,
|
||||
pdu_rel15->ndi,
|
||||
pdu_rel15->rv);
|
||||
|
||||
params_rel15->rnti = 0x03;
|
||||
params_rel15->rnti_type = NFAPI_NR_RNTI_RA;
|
||||
params_rel15->rnti = rnti;
|
||||
params_rel15->rnti_type = NFAPI_NR_RNTI_C;
|
||||
params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0;
|
||||
//params_rel15->aggregation_level = 1;
|
||||
LOG_D(MAC, "DCI type 1 params: rmsi_pdcch_config %d, rnti %d, rnti_type %d, dci_format %d\n \
|
||||
@@ -108,15 +143,35 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
params_rel15->nb_slots,
|
||||
params_rel15->sfn_mod2,
|
||||
params_rel15->first_slot);
|
||||
nr_get_tbs(&dl_config_dlsch_pdu->dlsch_pdu, dl_config_dci_pdu->dci_dl_pdu, *cfg);
|
||||
LOG_I(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n",
|
||||
dlsch_pdu_rel15->start_prb,
|
||||
dlsch_pdu_rel15->n_prb,
|
||||
dlsch_pdu_rel15->start_symbol,
|
||||
dlsch_pdu_rel15->nb_symbols,
|
||||
dlsch_pdu_rel15->nb_layers,
|
||||
dlsch_pdu_rel15->nb_codewords,
|
||||
dlsch_pdu_rel15->mcs_idx);
|
||||
|
||||
dl_req->number_dci++;
|
||||
dl_req->number_pdu++;
|
||||
dl_req->number_pdsch_rnti++;
|
||||
dl_req->number_pdu+=2;
|
||||
|
||||
TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus];
|
||||
TX_req->pdu_length = 6;
|
||||
TX_req->pdu_index = nr_mac->pdu_index[CC_id]++;
|
||||
TX_req->num_segments = 1;
|
||||
TX_req->segments[0].segment_length = 8;
|
||||
//TX_req->segments[0].segment_data = (uint8_t*)pdu_rel15;
|
||||
nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
|
||||
nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;
|
||||
nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
|
||||
nr_mac->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
|
||||
|
||||
TX_req = &nr_mac->TX_req[CC_id].tx_request_body.tx_pdu_list[nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus+1];
|
||||
TX_req->pdu_length = dlsch_pdu_rel15->transport_block_size;
|
||||
TX_req->pdu_index = nr_mac->pdu_index[CC_id]++;
|
||||
TX_req->num_segments = 1;
|
||||
TX_req->segments[0].segment_length = 8;
|
||||
nr_mac->TX_req[CC_id].tx_request_body.number_of_pdus++;
|
||||
nr_mac->TX_req[CC_id].sfn_sf = sfn_sf;
|
||||
nr_mac->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
|
||||
|
||||
@@ -204,6 +204,7 @@ typedef struct {
|
||||
//! clock source
|
||||
clock_source_t clock_source;
|
||||
//! Manual SDR IP address
|
||||
//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
char *sdr_addrs;
|
||||
//! Auto calibration flag
|
||||
int autocal[4];
|
||||
|
||||
@@ -262,7 +262,7 @@ RUs = (
|
||||
THREAD_STRUCT = (
|
||||
{
|
||||
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
|
||||
parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
worker_config = "WORKER_DISABLE";
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ variables.trx_tst[63:0]
|
||||
functions.eNB_thread_rxtx0
|
||||
@24
|
||||
variables.frame_number_RX0_RU[63:0]
|
||||
variables.subframe_number_RX0_RU[63:0]
|
||||
variables.tti_number_RX0_RU[63:0]
|
||||
variables.frame_number_TX0_RU[63:0]
|
||||
variables.subframe_number_TX0_RU[63:0]
|
||||
variables.tti_number_TX0_RU[63:0]
|
||||
@28
|
||||
functions.mac_schedule_dlsch
|
||||
functions.macxface_eNB_dlsch_ulsch_scheduler
|
||||
@@ -34,16 +34,16 @@ functions.macxface_ue_scheduler
|
||||
functions.phy_eNB_ofdm_mod_l
|
||||
@24
|
||||
variables.frame_number_RX0_gNB[63:0]
|
||||
variables.subframe_number_RX0_gNB[63:0]
|
||||
variables.slot_number_RX0_gNB[63:0]
|
||||
variables.frame_number_TX0_gNB[63:0]
|
||||
variables.subframe_number_TX0_gNB[63:0]
|
||||
variables.slot_number_TX0_gNB[63:0]
|
||||
@28
|
||||
functions.gNB_thread_rxtx0
|
||||
@24
|
||||
variables.frame_number_RX1_gNB[63:0]
|
||||
variables.subframe_number_RX1_gNB[63:0]
|
||||
variables.slot_number_RX1_gNB[63:0]
|
||||
variables.frame_number_TX1_gNB[63:0]
|
||||
variables.subframe_number_TX1_gNB[63:0]
|
||||
variables.slot_number_TX1_gNB[63:0]
|
||||
@28
|
||||
functions.gNB_thread_rxtx1
|
||||
functions.phy_procedures_ru_feprx0
|
||||
|
||||
@@ -904,87 +904,7 @@ void print_opp_meas(void) {
|
||||
print_meas(&softmodem_stats_rx_sf,"[gNB][total_phy_proc_rx]",NULL,NULL);
|
||||
}
|
||||
}
|
||||
/*
|
||||
void free_transport(PHY_VARS_gNB *gNB)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
LOG_I(PHY, "Freeing Transport Channel Buffers for DLSCH, UE %d\n",i);
|
||||
for (j=0; j<2; j++) free_gNB_dlsch(gNB->dlsch[i][j]);
|
||||
|
||||
LOG_I(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||
free_gNB_ulsch(gNB->ulsch[1+i]);
|
||||
}
|
||||
free_gNB_ulsch(gNB->ulsch[0]);
|
||||
}*/
|
||||
|
||||
/*
|
||||
void init_transport(PHY_VARS_gNB *gNB) {
|
||||
|
||||
int i;
|
||||
int j;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
|
||||
LOG_I(PHY, "Initialise transport\n");
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
|
||||
for (j=0; j<2; j++) {
|
||||
gNB->dlsch[i][j] = new_gNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp);
|
||||
if (!gNB->dlsch[i][j]) {
|
||||
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
|
||||
exit(-1);
|
||||
} else {
|
||||
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_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||
gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
|
||||
|
||||
if (!gNB->ulsch[1+i]) {
|
||||
LOG_E(PHY,"Can't get gNB ulsch structures\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// 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
|
||||
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,fp->N_RB_DL, 0, fp);
|
||||
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,fp->N_RB_DL, 0, fp);
|
||||
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
|
||||
gNB->dlsch_MCH = new_gNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
|
||||
LOG_D(PHY,"gNB %d.%d : MCH %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_MCH);
|
||||
|
||||
|
||||
gNB->rx_total_gain_dB=130;
|
||||
|
||||
for(i=0; i<NUMBER_OF_UE_MAX; i++)
|
||||
gNB->mu_mimo_mode[i].dl_pow_off = 2;
|
||||
|
||||
gNB->check_for_total_transmissions = 0;
|
||||
|
||||
gNB->check_for_MUMIMO_transmissions = 0;
|
||||
|
||||
gNB->FULL_MUMIMO_transmissions = 0;
|
||||
|
||||
gNB->check_for_SUMIMO_transmissions = 0;
|
||||
|
||||
fp->pucch_config_common.deltaPUCCH_Shift = 1;
|
||||
|
||||
} */
|
||||
|
||||
/// eNB kept in function name for nffapi calls, TO FIX
|
||||
void init_eNB_afterRU(void) {
|
||||
@@ -1035,8 +955,7 @@ void init_eNB_afterRU(void) {
|
||||
* In monolithic mode, we come here with nb_antennas_rx == 0
|
||||
* (not tested in other modes).
|
||||
*/
|
||||
/// Transport init necessary for NR synchro
|
||||
//init_transport(gNB);
|
||||
|
||||
//init_precoding_weights(RC.gNB[inst][CC_id]);
|
||||
}
|
||||
init_gNB_proc(inst);
|
||||
|
||||
@@ -764,6 +764,7 @@ void tx_rf(RU_t *ru) {
|
||||
(SF_type == SF_S)) {
|
||||
|
||||
int siglen=fp->samples_per_slot,flags=1;
|
||||
|
||||
/*
|
||||
if (SF_type == SF_S) {
|
||||
siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
|
||||
@@ -788,13 +789,9 @@ void tx_rf(RU_t *ru) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, proc->tti_tx );
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++)
|
||||
|
||||
txp[i] = (void*)&ru->common.txdata[i][(proc->tti_tx*fp->samples_per_slot)-sf_extension];
|
||||
/*
|
||||
if (proc->tti_tx == 0){
|
||||
write_output("txdataF_frame.m","txdataF_frame",&ru->common.txdataF_BF[i],fp->samples_per_subframe_wCP, 1, 1);
|
||||
write_output("txdata_frame.m","txdata_frame",&ru->common.txdata[i],fp->samples_per_subframe, 1, 1);
|
||||
}
|
||||
*/
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
|
||||
// prepare tx buffer pointers
|
||||
|
||||
@@ -103,6 +103,9 @@ static pthread_t forms_thread; //xforms
|
||||
|
||||
#endif //XFORMS
|
||||
|
||||
short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655};
|
||||
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
@@ -384,11 +387,11 @@ void reset_stats(FL_OBJECT *button, long arg)
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
for (k=0; k<8; k++) { //harq_processes
|
||||
for (j=0; j<phy_vars_gNB->dlsch[i][0]->Mlimit; j++) {
|
||||
/* for (j=0; j<phy_vars_gNB->dlsch[i][0]->Mlimit; j++) {
|
||||
phy_vars_gNB->UE_stats[i].dlsch_NAK[k][j]=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_ACK[k][j]=0;
|
||||
phy_vars_gNB->UE_stats[i].dlsch_trials[k][j]=0;
|
||||
}
|
||||
}*/
|
||||
|
||||
phy_vars_gNB->UE_stats[i].dlsch_l2_errors[k]=0;
|
||||
phy_vars_gNB->UE_stats[i].ulsch_errors[k]=0;
|
||||
|
||||
+24
-20
@@ -226,7 +226,7 @@ PHY_VARS_NR_UE* init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms,
|
||||
// initialize all signal buffers
|
||||
init_nr_ue_signal(ue,1,abstraction_flag);
|
||||
// intialize transport
|
||||
//init_nr_ue_transport(ue,abstraction_flag);
|
||||
init_nr_ue_transport(ue,abstraction_flag);
|
||||
|
||||
return(ue);
|
||||
}
|
||||
@@ -442,6 +442,8 @@ static void *UE_thread_synch(void *arg) {
|
||||
#endif
|
||||
if (nr_initial_sync( UE, UE->mode ) == 0) {
|
||||
|
||||
//write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_subframe), 1, 1);
|
||||
|
||||
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe;
|
||||
printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
|
||||
hw_slot_offset,
|
||||
@@ -594,7 +596,7 @@ static void *UE_thread_synch(void *arg) {
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef XFORMS
|
||||
#if 0 //defined XFORMS
|
||||
if (do_forms) {
|
||||
extern FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
|
||||
|
||||
@@ -603,7 +605,7 @@ static void *UE_thread_synch(void *arg) {
|
||||
0,0,7);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
|
||||
// indicate readiness
|
||||
UE->proc.instance_cnt_synch--;
|
||||
@@ -688,10 +690,10 @@ static void *UE_thread_rxn_txnp4(void *arg) {
|
||||
UE->if_inst->dcireq(&UE->dcireq);
|
||||
|
||||
#ifdef UE_SLOT_PARALLELISATION
|
||||
phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
|
||||
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
|
||||
#else
|
||||
phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode);
|
||||
printf(">>> nr_ue_pdcch_procedures ended\n");
|
||||
// printf(">>> nr_ue_pdcch_procedures ended\n");
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -699,7 +701,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&UE->generic_stat);
|
||||
#endif
|
||||
printf(">>> mac init\n");
|
||||
//printf(">>> mac init\n");
|
||||
|
||||
if (UE->mac_enabled==1) {
|
||||
|
||||
@@ -770,7 +772,7 @@ printf(">>> mac init\n");
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&UE->generic_stat);
|
||||
#endif
|
||||
printf(">>> mac ended\n");
|
||||
//printf(">>> mac ended\n");
|
||||
|
||||
// Prepare the future Tx data
|
||||
#if 0
|
||||
@@ -874,13 +876,14 @@ void *UE_thread(void *arg) {
|
||||
usleep(500*1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (instance_cnt_synch < 0) { // we can invoke the synch
|
||||
// grab 10 ms of signal and wakeup synch thread
|
||||
for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
rxp[i] = (void*)&UE->common_vars.rxdata[i][0];
|
||||
|
||||
if (UE->mode != loop_through_memory)
|
||||
AssertFatal( UE->frame_parms.samples_per_subframe*10 ==
|
||||
AssertFatal( UE->frame_parms.samples_per_subframe*10==
|
||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||
×tamp,
|
||||
rxp,
|
||||
@@ -933,10 +936,10 @@ void *UE_thread(void *arg) {
|
||||
}
|
||||
UE->rx_offset=0;
|
||||
UE->time_sync_cell=0;
|
||||
//UE->proc.proc_rxtx[0].frame_rx++;
|
||||
UE->proc.proc_rxtx[0].frame_rx++;
|
||||
//UE->proc.proc_rxtx[1].frame_rx++;
|
||||
for (th_id=0; th_id < RX_NB_TH; th_id++) {
|
||||
UE->proc.proc_rxtx[th_id].frame_rx++;
|
||||
for (th_id=1; th_id < RX_NB_TH; th_id++) {
|
||||
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
|
||||
}
|
||||
|
||||
//printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx);
|
||||
@@ -955,6 +958,10 @@ void *UE_thread(void *arg) {
|
||||
rt_sleep_ns(1000*1000);
|
||||
|
||||
} else {
|
||||
thread_idx++;
|
||||
if(thread_idx>=RX_NB_TH)
|
||||
thread_idx = 0;
|
||||
|
||||
subframe_nr++;
|
||||
subframe_nr %= NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
UE_nr_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
|
||||
@@ -975,9 +982,6 @@ void *UE_thread(void *arg) {
|
||||
|
||||
LOG_D(PHY,"Process subframe %d thread Idx %d \n", subframe_nr, UE->current_thread_id[subframe_nr]);
|
||||
|
||||
thread_idx++;
|
||||
if(thread_idx>=RX_NB_TH)
|
||||
thread_idx = 0;
|
||||
|
||||
if (UE->mode != loop_through_memory) {
|
||||
for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
|
||||
@@ -1046,10 +1050,10 @@ void *UE_thread(void *arg) {
|
||||
// operate on thread sf mod 2
|
||||
AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
|
||||
if(subframe_nr == 0) {
|
||||
//UE->proc.proc_rxtx[0].frame_rx++;
|
||||
UE->proc.proc_rxtx[0].frame_rx++;
|
||||
//UE->proc.proc_rxtx[1].frame_rx++;
|
||||
for (th_id=0; th_id < RX_NB_TH; th_id++) {
|
||||
UE->proc.proc_rxtx[th_id].frame_rx++;
|
||||
for (th_id=1; th_id < RX_NB_TH; th_id++) {
|
||||
UE->proc.proc_rxtx[th_id].frame_rx = UE->proc.proc_rxtx[0].frame_rx;
|
||||
}
|
||||
#ifdef SAIF_ENABLED
|
||||
if (!(proc->frame_rx%4000))
|
||||
@@ -1069,7 +1073,7 @@ void *UE_thread(void *arg) {
|
||||
|
||||
proc->nr_tti_rx=subframe_nr;
|
||||
proc->subframe_rx=subframe_nr;
|
||||
|
||||
|
||||
proc->frame_tx = proc->frame_rx;
|
||||
proc->nr_tti_tx= subframe_nr + DURATION_RX_TO_TX;
|
||||
if (proc->nr_tti_tx > NR_NUMBER_OF_SUBFRAMES_PER_FRAME) {
|
||||
@@ -1194,11 +1198,11 @@ void init_UE_threads(PHY_VARS_NR_UE *UE) {
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td,NULL);
|
||||
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td,NULL);
|
||||
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td,NULL,dlsch_decoding_2thread0, rtd);
|
||||
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td,NULL,nr_dlsch_decoding_2thread0, rtd);
|
||||
//thread 2
|
||||
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_dlsch_td1,NULL);
|
||||
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_dlsch_td1,NULL);
|
||||
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td1,NULL,dlsch_decoding_2thread1, rtd);
|
||||
pthread_create(&UE->proc.proc_rxtx[i].pthread_dlsch_td1,NULL,nr_dlsch_decoding_2thread1, rtd);
|
||||
#endif
|
||||
|
||||
#ifdef UE_SLOT_PARALLELISATION
|
||||
|
||||
@@ -85,10 +85,10 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
|
||||
// at eNB 0, an UL scope for every UE
|
||||
FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX];
|
||||
FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
|
||||
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
|
||||
char title[255];
|
||||
unsigned char scope_enb_num_ue = 2;
|
||||
//unsigned char scope_enb_num_ue = 2;
|
||||
static pthread_t forms_thread; //xforms
|
||||
#endif //XFORMS
|
||||
#include "nr-uesoftmodem.h"
|
||||
@@ -119,6 +119,8 @@ int threequarter_fs=0;
|
||||
uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
extern int16_t nr_dlsch_demod_shift;
|
||||
|
||||
|
||||
//static char *conf_config_file_name = NULL;
|
||||
|
||||
@@ -435,21 +437,21 @@ static void *scope_thread(void *arg) {
|
||||
|
||||
#endif
|
||||
|
||||
while (!oai_exit) {
|
||||
while (!oai_exit) {
|
||||
//len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
|
||||
//fl_set_object_label(form_stats->stats_text, stats_buffer);
|
||||
fl_clear_browser(form_stats->stats_text);
|
||||
fl_add_browser_line(form_stats->stats_text, stats_buffer);
|
||||
//fl_clear_browser(form_stats->stats_text);
|
||||
//fl_add_browser_line(form_stats->stats_text, stats_buffer);
|
||||
|
||||
if (PHY_vars_UE_g[0][0]->is_synchronized == 1)
|
||||
//if (PHY_vars_UE_g[0][0]->is_synchronized == 1)
|
||||
phy_scope_UE(form_ue[0],
|
||||
PHY_vars_UE_g[0][0],
|
||||
0,0,7);
|
||||
0,0,1);
|
||||
//else it is done in the synch thread
|
||||
|
||||
//printf("doing forms\n");
|
||||
//usleep(100000); // 100 ms
|
||||
sleep(1);
|
||||
sleep(0.1);
|
||||
}
|
||||
|
||||
// printf("%s",stats_buffer);
|
||||
@@ -547,7 +549,7 @@ static void get_options(void) {
|
||||
set_glog_onlinelog(online_log_messages);
|
||||
}
|
||||
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
|
||||
set_glog(glog_level);
|
||||
set_glog(glog_level);
|
||||
}
|
||||
|
||||
if (start_telnetsrv) {
|
||||
@@ -872,23 +874,6 @@ int main( int argc, char **argv ) {
|
||||
T_Config_Init();
|
||||
#endif
|
||||
|
||||
// initialize the log (see log.h for details)
|
||||
set_glog(OAILOG_DEBUG);
|
||||
|
||||
set_log(HW, OAILOG_DEBUG);
|
||||
set_log(PHY, OAILOG_DEBUG);
|
||||
set_log(MAC, OAILOG_INFO);
|
||||
set_log(RLC, OAILOG_INFO);
|
||||
set_log(PDCP, OAILOG_INFO);
|
||||
set_log(OTG, OAILOG_INFO);
|
||||
set_log(RRC, OAILOG_INFO);
|
||||
#if defined(ENABLE_ITTI)
|
||||
set_log(SIM, OAILOG_INFO);
|
||||
# if defined(ENABLE_USE_MME)
|
||||
set_log(NAS, OAILOG_INFO);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//randominit (0);
|
||||
set_taus_seed (0);
|
||||
|
||||
@@ -1131,6 +1116,8 @@ int main( int argc, char **argv ) {
|
||||
pthread_cond_init(&sync_cond,NULL);
|
||||
pthread_mutex_init(&sync_mutex, NULL);
|
||||
|
||||
init_UE(1);
|
||||
|
||||
#ifdef XFORMS
|
||||
int UE_id;
|
||||
int fl_argc=1;
|
||||
@@ -1140,8 +1127,8 @@ int main( int argc, char **argv ) {
|
||||
fl_initialize (&fl_argc, argv, NULL, 0, 0);
|
||||
// restore the original command line args
|
||||
// argv = fl_get_cmdline_args( &argc );
|
||||
form_stats = create_form_stats_form();
|
||||
fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
|
||||
//form_stats = create_form_stats_form();
|
||||
//fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
|
||||
UE_id = 0;
|
||||
form_ue[UE_id] = create_lte_phy_scope_ue();
|
||||
sprintf (title, "NR DL SCOPE UE");
|
||||
@@ -1171,7 +1158,6 @@ int main( int argc, char **argv ) {
|
||||
|
||||
rt_sleep_ns(10*100000000ULL);
|
||||
|
||||
init_UE(1);
|
||||
number_of_cards = 1;
|
||||
|
||||
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
@@ -1232,8 +1218,8 @@ int main( int argc, char **argv ) {
|
||||
|
||||
if (do_forms==1) {
|
||||
pthread_join(forms_thread,&status);
|
||||
fl_hide_form(form_stats->stats_form);
|
||||
fl_free_form(form_stats->stats_form);
|
||||
//fl_hide_form(form_stats->stats_form);
|
||||
//fl_free_form(form_stats->stats_form);
|
||||
fl_hide_form(form_ue[0]->lte_phy_scope_ue);
|
||||
fl_free_form(form_ue[0]->lte_phy_scope_ue);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \
|
||||
{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \
|
||||
{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \
|
||||
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
{"nr_dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
|
||||
{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \
|
||||
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
|
||||
|
||||
Reference in New Issue
Block a user