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:
Raymond Knopp
2019-01-04 16:46:50 +01:00
95 changed files with 18671 additions and 2773 deletions
+2 -2
View File
@@ -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]
+4
View File
@@ -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
+27 -18
View File
@@ -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)
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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
+572 -206
View File
@@ -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"
+42 -6
View File
@@ -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
+64
View File
@@ -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
+17 -42
View File
@@ -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;
}
+2 -1
View File
@@ -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;
+241
View File
@@ -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);
}
+47 -61
View File
@@ -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
+88
View File
@@ -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;
}
+11 -12
View File
@@ -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)
{
+1
View File
@@ -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};
+15 -15
View File
@@ -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
+29 -119
View File
@@ -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);
}
+110 -2
View File
@@ -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);
+28 -1
View File
@@ -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;
}
}
}
}
}
+7 -2
View File
@@ -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);
}
+5 -2
View File
@@ -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};
+1 -1
View File
@@ -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
+3 -4
View File
@@ -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);
+1 -5
View File
@@ -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;
}
+2 -1
View File
@@ -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);
+56 -36
View File
@@ -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));
}
+374
View File
@@ -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;
}
+99
View File
@@ -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);
+451
View File
@@ -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);
}
+250
View File
@@ -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();
}
+1 -7
View File
@@ -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;
}
+89
View File
@@ -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);
}
+48
View File
@@ -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);
+178
View File
@@ -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);
}
+7
View File
@@ -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.
+7 -1
View File
@@ -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
+29 -97
View File
@@ -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 */
+2 -1
View File
@@ -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
+27 -47
View File
@@ -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;
+12 -11
View File
@@ -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));
+67 -71
View File
@@ -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);
*/
}
+2 -1
View File
@@ -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__
+4
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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];
+4 -5
View File
@@ -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
+48 -1
View File
@@ -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 {
+1
View File
@@ -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;
+3 -2
View File
@@ -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;
+1
View File
@@ -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;
+2
View File
@@ -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"
+6 -3
View File
@@ -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__ */
+4 -1
View File
@@ -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"
+10 -3
View File
@@ -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;
}
+2 -1
View File
@@ -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);
+1
View File
@@ -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 );
+15 -3
View File
@@ -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);
+11 -5
View File
@@ -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);
/*@}*/
+3 -1
View File
@@ -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;
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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) {
+677
View File
@@ -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);
}
+4 -3
View File
@@ -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++;
}
+3 -1
View File
@@ -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);
+1 -1
View File
@@ -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};
+3 -1
View File
@@ -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;
+1
View File
@@ -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";
}
+6 -6
View File
@@ -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
+1 -82
View File
@@ -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);
+3 -6
View File
@@ -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
+5 -2
View File
@@ -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
View File
@@ -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,
&timestamp,
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
+18 -32
View File
@@ -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);
}
+1 -1
View File
@@ -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}, \