Merge remote-tracking branch 'origin/polar-decoder-optimizations' into nr_pbchsim

Conflicts:
	openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
	openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
	openair1/PHY/defs_NR.h
This commit is contained in:
Raymond Knopp
2018-10-14 13:04:18 +02:00
82 changed files with 7715 additions and 16293 deletions
+29 -21
View File
@@ -1119,24 +1119,19 @@ set(PHY_TURBOSRC
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder.c
)
set(PHY_POLARSRC
${OPENAIR1_DIR}/PHY/CODING/nrPolar_init.c
${OPENAIR1_DIR}/PHY/CODING/nr_polar_init.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_bitwise_operations.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/decoder_K56_N512_E864.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kernal_operation.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_output_length.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_procedures.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_sequence_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_encoder.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoder.c
)
set(PHY_TURBOIF
${OPENAIR1_DIR}/PHY/CODING/coding_load.c
@@ -1179,6 +1174,8 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${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/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
@@ -1294,6 +1291,8 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pss.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sss.c
${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_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
@@ -1458,7 +1457,7 @@ set(L2_SRC
${RRC_DIR}/L2_interface_ue.c
)
set(NR_L2_SRC
set(L2_NR_SRC
${NR_RRC_DIR}/rrc_gNB.c
${NR_RRC_DIR}/nr_rrc_common.c
${NR_RRC_DIR}/L2_nr_interface.c
@@ -1514,6 +1513,12 @@ set(NR_L2_SRC_UE
#${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
#${PHY_INTERFACE_DIR}/phy_stub_UE.c
${PHY_INTERFACE_DIR}/IF_Module.c
@@ -1536,15 +1541,16 @@ set (MAC_SRC
${MAC_DIR}/pre_processor.c
${MAC_DIR}/config.c
${MAC_DIR}/config_ue.c
)
)
set (NR_MAC_SRC
set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_MAC_DIR}/main.c
${NR_MAC_DIR}/config.c
${NR_MAC_DIR}/gNB_scheduler.c
${NR_MAC_DIR}/gNB_scheduler_bch.c
${NR_MAC_DIR}/gNB_scheduler_primitives.c
${NR_MAC_DIR}/gNB_scheduler_phytest.c
)
@@ -1582,11 +1588,12 @@ add_library(L2
${L2_SRC}
${MAC_SRC}
${ENB_APP_SRC}
)
)
# ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c)
add_library(NR_L2
${NR_L2_SRC}
${NR_MAC_SRC}
add_library(L2_NR
${L2_NR_SRC}
${MAC_NR_SRC}
${GNB_APP_SRC}
)
@@ -2204,7 +2211,7 @@ add_executable(lte-softmodem
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -2358,8 +2365,8 @@ add_executable(nr-softmodem
target_link_libraries (nr-softmodem
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ATLAS_LIBRARIES}
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 NR_L2
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB}
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
@@ -2380,6 +2387,7 @@ add_executable(nr-softmodem-nos1
${OPENAIR_TARGETS}/RT/USER/nr-ru.c
${OPENAIR_TARGETS}/RT/USER/nr-softmodem.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_nr_tasks.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
@@ -2399,7 +2407,7 @@ target_link_libraries (nr-softmodem-nos1
-Wl,--start-group
UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${MIH_LIB}
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 NR_L2
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
-1
View File
@@ -1134,7 +1134,6 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req)
int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req);
dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1;
dl_config_req->dl_config_request_body.number_dci = 0;
dl_config_req->dl_config_request_body.number_pdu = 0;
dl_config_req->dl_config_request_body.number_pdsch_rnti = 0;
@@ -40,6 +40,7 @@
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
#define CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
#define CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
@@ -55,4 +56,4 @@
#define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04
#endif
#endif
@@ -37,8 +37,8 @@ typedef struct {
uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1:
uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
uint8_t tpc_cmd_number ; // 5 TPC_CMD_NUMBER: The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits
uint8_t block_number ; // 6 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND:
uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND:
uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND:
uint8_t short_messages ; // 9 SHORT_MESSAGES:
@@ -81,7 +81,7 @@ typedef struct {
uint8_t antenna_ports ; // 38 ANTENNA_PORTS:
uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
uint8_t srs_request ; // 40 SRS_REQUEST:
uint8_t tpc_cmd_number_format2_3 ; // 41 TPC_CMD_NUMBER_FORMAT2_3:
uint8_t tpc_cmd ; // 41 TPC_CMD:
uint8_t csi_request ; // 42 CSI_REQUEST:
uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
@@ -237,15 +237,34 @@ typedef struct {
typedef struct {
} fapi_nr_ul_config_pucch_pdu;
typedef enum {pusch_freq_hopping_disabled = 0 , pusch_freq_hopping_enabled = 1}pusch_freq_hopping_t;
typedef struct{
uint8_t aperiodicSRS_ResourceTrigger;
} fapi_nr_ul_srs_config_t;
typedef struct {
uint8_t bandwidth_part_ind;
uint16_t number_rbs;
uint16_t start_rb;
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
pusch_freq_hopping_t pusch_freq_hopping;
uint8_t mcs;
uint8_t tpc_command;
uint8_t ndi;
uint8_t rv;
uint8_t harq_process_nbr;
int8_t accumulated_delta_PUSCH;
int8_t absolute_delta_PUSCH;
uint8_t n_layers;
uint8_t tpmi;
uint8_t n_dmrs_cdm_groups;
uint8_t dmrs_ports[4];
uint8_t n_front_load_symb;
fapi_nr_ul_srs_config_t srs_config;
uint8_t csi_reportTriggerSize;
uint8_t maxCodeBlockGroupsPerTransportBlock;
uint8_t ptrs_dmrs_association_port;
uint8_t beta_offset_ind;
} fapi_nr_ul_config_pusch_pdu_rel15_t;
typedef struct {
@@ -290,17 +309,43 @@ typedef struct {
typedef struct {
fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15;
} fapi_nr_dl_config_dci_pdu;
typedef struct{
uint8_t aperiodicSRS_ResourceTrigger;
} fapi_nr_dl_srs_config_t;
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
//typedef fapi_nr_dci_pdu_rel15_t fapi_nr_dl_config_dlsch_pdu_rel15_t;
typedef struct {
uint8_t bandwidth_part_ind;
uint16_t number_rbs;
uint16_t start_rb;
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
uint8_t prb_bundling_size_ind;
uint8_t rate_matching_ind;
uint8_t zp_csi_rs_trigger;
uint8_t mcs;
uint8_t rv;
uint8_t harq_pid;
uint8_t ndi;
// TODO: check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
uint8_t rv;
uint8_t tb2_mcs;
uint8_t tb2_ndi;
uint8_t tb2_rv;
uint8_t harq_process_nbr;
vrb_to_prb_mapping_t vrb_to_prb_mapping;
uint8_t dai;
double scaling_factor_S;
int8_t accumulated_delta_PUCCH;
uint8_t pucch_resource_id;
uint8_t pdsch_to_harq_feedback_time_ind;
uint8_t n_dmrs_cdm_groups;
uint8_t dmrs_ports[10];
uint8_t n_front_load_symb;
uint8_t tci_state;
fapi_nr_dl_srs_config_t srs_config;
uint8_t cbgti;
uint8_t codeBlockGroupFlushIndicator;
// to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
typedef struct {
@@ -598,7 +643,7 @@ typedef struct {
typedef struct {
uint8_t dmrs_type;
uint8_t dmrs_addition_position;
uint8_t ptrs_uplink_config; // to indicate if PTRS Uplink is configured of not
uint8_t ptrs_type; //cp-OFDM, dft-S-OFDM
uint16_t ptrs_frequency_density[2];
uint8_t ptrs_time_density[3];
@@ -624,9 +669,15 @@ typedef struct {
uint8_t delta_mcs;
} fapi_nr_pusch_power_control_t;
typedef enum {tx_config_codebook = 1, tx_config_nonCodebook = 2} tx_config_t;
typedef enum {transform_precoder_disabled = 0, transform_precoder_enabled = 1} transform_precoder_t;
typedef enum {
codebook_subset_fullyAndPartialAndNonCoherent = 1,
codebook_subset_partialAndNonCoherent = 2,
codebook_subset_nonCoherent = 3} codebook_subset_t;
typedef struct {
uint16_t data_scrambling_identity;
uint8_t tx_config;
tx_config_t tx_config;
fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_a;
fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_b;
fapi_nr_pusch_power_control_t pusch_power_control;
@@ -637,8 +688,8 @@ typedef struct {
uint8_t pusch_aggregation_factor;
uint8_t mcs_table;
uint8_t mcs_table_transform_precoder;
uint8_t transform_precoder;
uint8_t codebook_subset;
transform_precoder_t transform_precoder;
codebook_subset_t codebook_subset;
uint8_t max_rank;
uint8_t rbg_size;
@@ -11,6 +11,30 @@
#include "nfapi_interface.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
// Extension to the generic structures for single tlv values
typedef struct {
nfapi_tl_t tl;
int32_t value;
} nfapi_int32_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint32_t value;
} nfapi_uint32_tlv_t;
/*typedef struct {
nfapi_tl_t tl;
int64_t value;
} nfapi_int64_tlv_t;
typedef struct {
nfapi_tl_t tl;
uint64_t value;
} nfapi_uint64_tlv_t;*/
// nFAPI enums
typedef enum {
NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE = 0,
@@ -159,6 +183,7 @@ typedef struct {
nfapi_uint16_tlv_t ssb_periodicity;
nfapi_uint16_tlv_t ss_pbch_block_power;
nfapi_uint16_tlv_t n_ssb_crb;
nfapi_uint16_tlv_t rmsi_pdcch_config;
} nfapi_nr_sch_config_t;
#define NFAPI_NR_SCH_CONFIG_PHYSICAL_CELL_ID_TAG 0x501E
@@ -268,13 +293,10 @@ typedef enum {
NFAPI_NR_DL_DCI_FORMAT_2_0,
NFAPI_NR_DL_DCI_FORMAT_2_1,
NFAPI_NR_DL_DCI_FORMAT_2_2,
NFAPI_NR_DL_DCI_FORMAT_2_3
} nfapi_nr_dl_dci_format_e;
typedef enum {
NFAPI_NR_UL_DCI_FORMAT_0_0 = 0,
NFAPI_NR_UL_DCI_FORMAT_1_0,
} nfapi_nr_ul_dci_format_e;
NFAPI_NR_DL_DCI_FORMAT_2_3,
NFAPI_NR_UL_DCI_FORMAT_0_0,
NFAPI_NR_UL_DCI_FORMAT_0_1
} nfapi_nr_dci_format_e;
typedef enum {
NFAPI_NR_RNTI_new = 0,
@@ -290,73 +312,62 @@ typedef enum {
NFAPI_NR_RNTI_TPC_PUSCH,
NFAPI_NR_RNTI_TPC_PUCCH,
NFAPI_NR_RNTI_TPC_SRS
} nfapi_nr_rnti_type_e ;
} nfapi_nr_rnti_type_e;
typedef enum {
NFAPI_NR_USS_FORMAT_0_0_AND_1_0,
NFAPI_NR_USS_FORMAT_0_1_AND_1_1,
} nfapi_nr_uss_dci_formats_e;
typedef enum {
NFAPI_NR_SEARCH_SPACE_TYPE_COMMON=0,
NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
} nfapi_nr_search_space_type_e;
typedef enum {
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=0,
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2,
NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3
} nfapi_nr_ssb_and_cset_mux_pattern_type_e;
typedef enum {
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=0,
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
} nfapi_nr_cce_reg_mapping_type_e;
typedef enum {
NFAPI_NR_CSET_CONFIG_MIB_SIB1=0,
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG
} nfapi_nr_coreset_config_type_e;
typedef enum {
NFAPI_NR_CSET_SAME_AS_REG_BUNDLE=0,
NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS
} nfapi_nr_coreset_precoder_granularity_type_e;
// P7 Sub Structures
//formats 0_0 and 0_1
typedef struct {
nfapi_tl_t tl;
uint8_t cce_idx;
uint8_t aggregation_level;
uint16_t rnti;
uint8_t dci_format; //1 bit
uint16_t frequency_domain_resource_assignment; //up to 9 bits
uint8_t time_domain_resource_assignment; //0, 1, 2, 3 or 4 bits
uint8_t format_indicator; //1 bit
uint16_t frequency_domain_assignment; //up to 16 bits
uint8_t time_domain_assignment; // 4 bits
uint8_t frequency_hopping_flag; //1 bit
uint8_t mcs; //5 bits
uint8_t new_data_indicator; //1 bit
uint8_t redundancy_version; //2 bits
uint8_t harq_process; //4 bits
uint8_t tpc; //2 bits
uint16_t padding;
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t carrier_indicator; //0 or 3 bits
uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t downlink_assignment_index1; //1 or 2 bits
uint8_t downlink_assignment_index2; //0 or 2 bits
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t antenna_ports;
uint8_t srs_request;
uint8_t csi_request;
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
uint8_t dmrs_sequence_initialization; //0 or 1 bit
uint8_t ul_sch_indicator; //1 bit
} nfapi_nr_ul_config_dci_ul_pdu_rel15_t;
//#define NFAPI_NR_UL_CONFIG_REQUEST_DCI_UL_PDU_REL15_TAG 0x????
//formats 1_0, 1_1, 2_0, 2_1, 2_2 and 2_3
typedef struct {
nfapi_tl_t tl;
uint8_t cce_idx;
uint8_t aggregation_level;
uint16_t rnti;
uint8_t dci_format; //1 bit
uint16_t frequency_domain_resource_assignment; //up to 9 bits
uint8_t ra_preamble_index; //6 bits
uint8_t ul_sul_indicator; //1 bit
uint8_t ss_pbch_index; //6 bits
uint8_t prach_mask_index; //4 bits
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint8_t time_domain_resource_assignment; //0, 1, 2, 3 or 4 bits
uint8_t vrb_to_prb_mapping; //0 or 1 bit
uint8_t mcs; //5 bits
uint8_t new_data_indicator; //1 bit
uint8_t redundancy_version; //2 bits
uint8_t harq_process; //4 bits
uint8_t downlink_assignment_index; //0, 2 or 4 bits
uint8_t ndi; //1 bit
uint8_t rv; //2 bits
uint8_t harq_pid; //4 bits
uint8_t dai; //0, 2 or 4 bits
uint8_t dai1; //1 or 2 bits
uint8_t dai2; //0 or 2 bits
uint8_t tpc; //2 bits
uint8_t pucch_resource_indicator; //3 bits
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
@@ -370,13 +381,18 @@ uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t prb_bundling_size_indicator; //0 or 1 bits
uint8_t rate_matching_indicator; //0, 1 or 2 bits
uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
uint8_t antenna_ports; //4, 5 or 6 bits
uint8_t transmission_configuration_indication; //0 or 3 bits
uint8_t srs_request; //2 bits
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
uint8_t dmrs_sequence_initialization; //0 or 1 bit
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t csi_request;
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
uint8_t slot_format_indicator_count;
uint8_t *slot_format_indicators;
@@ -386,17 +402,75 @@ uint16_t *pre_emption_indications; //14 bit
uint8_t block_number_count;
uint8_t *block_numbers;
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t antenna_ports;
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint16_t padding;
} nfapi_nr_dl_config_dci_dl_pdu_rel15_t;
//#define NFAPI_NR_DL_CONFIG_REQUEST_DCI_DL_PDU_REL15_TAG 0x????
typedef struct {
nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15;
} nfapi_nr_dl_config_dci_dl_pdu;
typedef struct{
nfapi_tl_t tl;
uint8_t coreset_id;
uint64_t frequency_domain_resources;
uint8_t duration;
uint8_t cce_reg_mapping_type;
uint8_t reg_bundle_size;
uint8_t interleaver_size;
uint8_t shift_index;
uint8_t precoder_granularity;
uint8_t tci_state_id;
uint8_t tci_present_in_dci;
uint32_t dmrs_scrambling_id;
} nfapi_nr_coreset_t;
typedef struct{
nfapi_tl_t tl;
uint8_t search_space_id;
uint8_t coreset_id;
uint8_t search_space_type;
uint8_t duration;
uint8_t css_formats_0_0_and_1_0;
uint8_t css_format_2_0;
uint8_t css_format_2_1;
uint8_t css_format_2_2;
uint8_t css_format_2_3;
uint8_t uss_dci_formats;
uint8_t srs_monitoring_periodicity;
uint8_t slot_monitoring_periodicity;
uint8_t slot_monitoring_offset;
uint16_t monitoring_symbols_in_slot;
uint16_t number_of_candidates[NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS];
} nfapi_nr_search_space_t;
typedef struct {
nfapi_nr_ul_config_dci_ul_pdu_rel15_t dci_ul_pdu_rel15;
} nfapi_nr_ul_config_dci_ul_pdu;
nfapi_tl_t tl;
uint8_t rnti;
uint8_t rnti_type;
uint8_t dci_format;
uint8_t config_type;
uint8_t search_space_type;
uint8_t aggregation_level;
uint8_t n_rb;
uint8_t n_symb;
uint8_t rb_offset;
uint8_t cr_mapping_type;
uint8_t reg_bundle_size;
uint8_t interleaver_size;
uint8_t shift_index;
uint8_t mux_pattern;
uint8_t precoder_granularity;
uint8_t first_slot;
uint8_t first_symbol;
uint8_t nb_ss_sets_per_slot;
uint8_t nb_slots;
uint8_t sfn_mod2;
uint16_t scrambling_id;
nfapi_bf_vector_t bf_vector;
} nfapi_nr_dl_config_pdcch_parameters_rel15_t;
typedef struct {
nfapi_tl_t tl;
@@ -411,13 +485,20 @@ typedef struct {
} nfapi_nr_dl_config_bch_pdu;
typedef struct {
} nfapi_nr_dl_config_dlsch_pdu;
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_nr_dl_config_dlsch_pdu_rel15_t;
typedef struct {
nfapi_tl_t tl;
nfapi_nr_SearchSpace_t pagingSearchSpace;
} nfapi_nr_dl_config_pch_pdu;
nfapi_nr_search_space_t pagingSearchSpace;
nfapi_nr_coreset_t pagingControlResourceSets;
}nfapi_nr_dl_config_pch_pdu_rel15_t;
typedef struct {
@@ -431,26 +512,31 @@ typedef struct {
} nfapi_nr_dl_config_ndlsch_pdu;
typedef struct {
nfapi_nr_dl_config_dci_dl_pdu_rel15_t dci_dl_pdu_rel15;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params_rel15;
} nfapi_nr_dl_config_dci_dl_pdu;
typedef struct {
uint8_t pdu_type;
uint8_t pdu_size;
union {
nfapi_nr_dl_config_dci_dl_pdu dci_dl_pdu;
nfapi_nr_ul_config_dci_ul_pdu dci_ul_pdu;
nfapi_nr_dl_config_bch_pdu bch_pdu;
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
nfapi_nr_dl_config_pch_pdu pch_pdu;
nfapi_nr_dl_config_nbch_pdu nbch_pdu;
nfapi_nr_dl_config_npdcch_pdu npdcch_pdu;
nfapi_nr_dl_config_ndlsch_pdu ndlsch_pdu;
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_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_request_pdu_t;
typedef struct {
nfapi_tl_t tl;
uint8_t number_pdcch_ofdm_symbols;
uint8_t number_dci;
uint16_t number_pdu;
uint8_t number_pdu;
uint8_t number_pdsch_rnti;
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu_list;
} nfapi_nr_dl_config_request_body_t;
+292 -124
View File
@@ -7,10 +7,13 @@
#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"
//#define DEBUG_DCI_POLAR_PARAMS
//#define DEBUG_POLAR_TIMING
//#define DEBUG_CRC
int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
@@ -18,39 +21,30 @@ int main(int argc, char *argv[]) {
time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
time_stats_t path_metric,sorting,update_LLR;
opp_enabled=1;
int decoder_int8=0;
int decoder_int16=0;
int generate_optim_code=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
reset_meas(&polar_decoder_init);
reset_meas(&polar_rate_matching);
reset_meas(&decoding);
reset_meas(&bit_extraction);
reset_meas(&deinterleaving);
reset_meas(&sorting);
reset_meas(&path_metric);
reset_meas(&update_LLR);
randominit(0);
crcTableInit();
randominit(1234);
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 1; //0=DCI, 1=PBCH, 2=UCI
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
double SNR, SNR_lin;
int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
int8_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
uint16_t testLength, coderLength, blockErrorCumulative=0, bitErrorCumulative=0;
uint16_t testLength = 0, coderLength = 0, blockErrorCumulative=0, bitErrorCumulative=0;
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
int generate_optim_code=0;
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 0;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:qg")) != -1)
switch (arguments)
{
case 's':
SNRstart = atof(optarg);
printf("SNRstart = %f\n", SNRstart);
break;
case 'd':
@@ -78,7 +72,7 @@ int main(int argc, char *argv[]) {
break;
case 'q':
decoder_int8=1;
decoder_int16=1;
break;
case 'g':
@@ -86,10 +80,10 @@ int main(int argc, char *argv[]) {
iterations=1;
SNRstart=-6.0;
SNRstop =-6.0;
decoder_int8=1;
decoder_int16=1;
break;
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
exit(-1);
default:
@@ -97,22 +91,17 @@ int main(int argc, char *argv[]) {
exit(-1);
}
if (polarMessageType == 0) { //DCI
//testLength = ;
//coderLength = ;
printf("polartest for DCI not supported yet\n");
exit(-1);
} else if (polarMessageType == 1) { //PBCH
testLength = NR_POLAR_PBCH_PAYLOAD_BITS;
coderLength = NR_POLAR_PBCH_E;
printf("running polartest for PBCH\n");
} else if (polarMessageType == 2) { //UCI
testLength = NR_POLAR_PUCCH_PAYLOAD_BITS;
coderLength = NR_POLAR_PUCCH_E;
printf("running polartest for UCI");
} else {
printf("unsupported polarMessageType %d (0=DCI, 1=PBCH, 2=UCI)\n",polarMessageType);
exit(-1);
if (polarMessageType == 0) { //PBCH
testLength = NR_POLAR_PBCH_PAYLOAD_BITS;
coderLength = NR_POLAR_PBCH_E;
aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
} else if (polarMessageType == 1) { //DCI
//testLength = nr_get_dci_size(params_rel15->dci_format, params_rel15->rnti_type, &fp->initial_bwp_dl, cfg);
testLength = 20;
coderLength = 108; //to be changed by aggregate level function.
} else if (polarMessageType == -1) { //UCI
//testLength = ;
//coderLength = ;
}
@@ -123,7 +112,12 @@ int main(int argc, char *argv[]) {
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
#ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#else
sprintf(fileName,"%s/_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
#endif
strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime));
strcat(fileName,currentTimeInfo);
@@ -132,104 +126,283 @@ int main(int argc, char *argv[]) {
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
FILE* logFile;
logFile = fopen(fileName, "w");
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
logFile = fopen(fileName, "w");
if (logFile==NULL) {
fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
exit(-1);
}
uint8_t *testInput = malloc(sizeof(uint8_t) * testLength); //generate randomly
uint8_t *encoderOutput = malloc(sizeof(uint8_t) * coderLength);
#ifdef DEBUG_POLAR_TIMING
fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
#else
fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
#endif
uint8_t testArrayLength = ceil(testLength / 32.0);
uint8_t coderArrayLength = ceil(coderLength / 32.0);
uint32_t *testInput = malloc(sizeof(uint32_t) * testArrayLength); //generate randomly
uint32_t *encoderOutput = malloc(sizeof(uint32_t) * coderArrayLength);
uint32_t *estimatedOutput = malloc(sizeof(uint32_t) * testArrayLength); //decoder output
memset(testInput,0,sizeof(uint32_t) * testArrayLength);
memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength);
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
int16_t *channelOutput_int8 = malloc (sizeof(int16_t) * coderLength); //add noise
uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output
int16_t *channelOutput_int16;
if (decoder_int16 == 1) channelOutput_int16 = (int16_t*)malloc (sizeof(int16_t) * coderLength);
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level);
t_nrPolar_params nrPolar_params;
nr_polar_init(&nrPolar_params, polarMessageType);
nr_polar_llrtableinit();
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
memset(dci_pdu,0,sizeof(uint32_t)*4);
dci_pdu[0]=0x01189400;
printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
uint32_t encoder_output[54];
memset(encoder_output,0,sizeof(uint32_t)*54);
uint16_t size=41;
uint16_t rnti=3;
aggregation_level=8;
nr_polar_init(&nrPolar_params, 1, size, aggregation_level);
t_nrPolar_paramsPtr currentPtrDCI=nr_polar_params(nrPolar_params, 1, size, aggregation_level);
if (generate_optim_code==1) nrPolar_params.decoder_kernel = NULL;
polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
for (int i=0;i<54;i++)
printf("encoder_output: [%2d]->0x%08x \n",i, encoder_output[i]);
uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
uint32_t dci_estimation[4];
memset(dci_estimation,0,sizeof(uint32_t)*4);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
nr_bit2byte_uint32_8_t(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
printf("[polartest] encoder_outputByte: ");
for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]);
printf("\n");
for(int i=0; i<currentPtrDCI->encoderLength; i++) {
if (encoder_outputByte[i] == 0) {
channel_output[i]=1/sqrt(2);
}
else {
channel_output[i]=(-1)/sqrt(2);
}
}
decoderState = polar_decoder_dci(channel_output,
dci_estimation,
currentPtrDCI,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
rnti);
printf("dci_estimation: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_estimation[0], dci_estimation[1], dci_estimation[2], dci_estimation[3]);
return 0;
#endif
#ifdef DEBUG_CRC
uint32_t crc;
unsigned int poly24c = 0xb2b11700;
uint32_t testInputCRC[4];
testInputCRC[0]=0x00291880;
//testInputCRC[0]=0x01189400;
testInputCRC[1]=0x00000000;
testInputCRC[2]=0x00000000;
testInputCRC[3]=0x00000000;
uint32_t testInputcrc=0x01189400;
uint32_t testInputcrc2=0x00291880;
uint8_t testInputCRC2[8];
nr_crc_bit2bit_uint32_8_t(testInputCRC, 32, testInputCRC2);
printf("testInputCRC2: [0]->%x \t [1]->%x \t [2]->%x \t [3]->%x\n"
" [4]->%x \t [5]->%x \t [6]->%x \t [7]->%x\n",
testInputCRC2[0], testInputCRC2[1], testInputCRC2[2], testInputCRC2[3],
testInputCRC2[4], testInputCRC2[5], testInputCRC2[6], testInputCRC2[7]);
unsigned int crc41 = crc24c(testInputCRC, 32);
unsigned int crc65 = crc24c(testInputCRC, 56);
printf("crc41: [0]->0x%08x\tcrc65: [0]->0x%08x\n",crc41, crc65);
for (int i=0;i<32;i++) printf("crc41[%d]=%d\tcrc65[%d]=%d\n",i,(crc41>>i)&1,i,(crc65>>i)&1);
crc = crc24c(testInputCRC, testLength)>>8;
for (int i=0;i<24;i++) printf("[i]=%d\n",(crc>>i)&1);
printf("crc: [0]->0x%08x\n",crc);
//crcbit(testInputCRC, sizeof(test) - 1, poly24c));
testInputCRC[testLength>>3] = ((uint8_t*)&crc)[2];
testInputCRC[1+(testLength>>3)] = ((uint8_t*)&crc)[1];
testInputCRC[2+(testLength>>3)] = ((uint8_t*)&crc)[0];
printf("testInputCRC: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
testInputCRC[0], testInputCRC[1], testInputCRC[2], testInputCRC[3]);
//uint32_t trial32 = 0xffffffff;
uint32_t trial32 = 0xf10fffff;
uint8_t a[4];
//memcpy(a, &trial32, sizeof(trial32));
*(uint32_t *)a = trial32;
unsigned char trial[4];
trial[0]=0xff; trial[1]=0xff; trial[2]=0x0f; trial[3]=0xf1;
uint32_t trialcrc = crc24c(trial, 32);
uint32_t trialcrc32 = crc24c((uint8_t *)&trial32, 32);
//uint32_t trialcrc32 = crc24c(a, 32);
printf("crcbit(trial = %x\n", crcbit(trial, 4, poly24c));
printf("trialcrc = %x\n", trialcrc);
printf("trialcrc32 = %x\n", trialcrc32);
for (int i=0;i<32;i++) printf("trialcrc[%2d]=%d\ttrialcrc32[%2d]=%d\n",i,(trialcrc>>i)&1,i,(trialcrc32>>i)&1);
//uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
uint8_t nr_polar_A[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,1};
uint8_t nr_polar_crc[24];
uint8_t **crc_generator_matrix = crc24c_generator_matrix(32);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(nr_polar_A,
crc_generator_matrix,
nr_polar_crc,
32,
24);
for (uint8_t i = 0; i < 24; i++){
nr_polar_crc[i] = (nr_polar_crc[i] % 2);
printf("nr_polar_crc[%d]=%d\n",i,nr_polar_crc[i]);
}
return 0;
#endif
#ifdef DEBUG_POLAR_TIMING
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
SNR_lin = pow(10, SNR / 10);
for (itr = 1; itr <= iterations; itr++) {
for (int j=0; j<ceil(testLength / 32.0); j++) {
for(int i=0; i<32; i++) {
testInput[j] |= ( ((uint32_t) (rand()%2)) &1);
testInput[j]<<=1;
}
}
printf("testInput: [0]->0x%08x \n", testInput[0]);
polar_encoder_timing(testInput, encoderOutput, currentPtr, cpu_freq_GHz, logFile);
}
}
fclose(logFile);
free(testInput);
free(encoderOutput);
free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
#endif
// We assume no a priori knowledge available about the payload.
double aPrioriArray[nrPolar_params.payloadBits];
for (int i=0; i<=nrPolar_params.payloadBits; i++) aPrioriArray[i] = NAN;
printf("SNRstart %f, SNRstop %f,, SNRinc %f\n",SNRstart,SNRstop,SNRinc);
double aPrioriArray[currentPtr->payloadBits];
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) {
for(int i=0; i<testLength; i++)
testInput[i]=(uint8_t) (rand() % 2);
start_meas(&timeEncoder);
polar_encoder(testInput, encoderOutput, &nrPolar_params);
stop_meas(&timeEncoder);
//BPSK modulation
for(int i=0; i<coderLength; i++) {
if (encoderOutput[i] == 0)
modulatedInput[i]=1/sqrt(2);
else
modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int8==1) {
if (channelOutput[i] > 15) channelOutput_int8[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int8[i] = -128;
else channelOutput_int8[i] = (int16_t) (8*channelOutput[i]);
for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
testInput[i]<<=1;
}
testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
}
}
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
for (int i=0; i<32; i++)
printf("%d\n",(testInput[0]>>i)&1);*/
start_meas(&timeEncoder);
polar_encoder(testInput, encoderOutput, currentPtr);
stop_meas(&timeEncoder);
/*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/
//Bit-to-byte:
nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte);
//BPSK modulation
for(int i=0; i<coderLength; i++) {
if (encoderOutputByte[i] == 0)
modulatedInput[i]=1/sqrt(2);
else
modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
start_meas(&timeDecoder);
if (decoder_int8==0)
decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params,
decoderListSize, aPrioriArray, pathMetricAppr,
&polar_decoder_init,&polar_rate_matching,&decoding,
&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR);
else
decoderState = polar_decoder_int8_new(channelOutput_int8, estimatedOutput, &nrPolar_params,
decoderListSize, &polar_decoder_init,&polar_rate_matching,
&decoding,&bit_extraction,&deinterleaving,
&sorting,&path_metric,&update_LLR,
generate_optim_code);
stop_meas(&timeDecoder);
//calculate errors
if (decoderState==-1) {
blockErrorState=-1;
nBitError=-1;
} else {
for(int i=0; i<testLength; i++){
if (estimatedOutput[i]!=testInput[i]) nBitError++;
}
if (nBitError>0) blockErrorState=1;
}
//Iteration times are in microseconds.
timeEncoderCumulative+=(timeEncoder.diff_now/(cpu_freq_GHz*1000.0));
timeDecoderCumulative+=(timeDecoder.diff_now/(cpu_freq_GHz*1000.0));
fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState,
(timeEncoder.diff_now/(cpu_freq_GHz*1000.0)), (timeDecoder.diff_now/(cpu_freq_GHz*1000.0)));
start_meas(&timeDecoder);
/*decoderState = polar_decoder(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
aPrioriArray,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
if (decoder_int16==0)
decoderState = polar_decoder_aPriori(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray);
else
decoderState = polar_decoder_int16(channelOutput_int16,
estimatedOutput,
currentPtr);
if (nBitError<0) {
blockErrorCumulative++;
bitErrorCumulative+=testLength;
} else {
blockErrorCumulative+=blockErrorState;
bitErrorCumulative+=nBitError;
}
stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
decoderState=0;
nBitError=0;
blockErrorState=0;
//calculate errors
if (decoderState==-1) {
blockErrorState=-1;
nBitError=-1;
} else {
for (int i = 0; i < testArrayLength; i++) {
for (int j = 0; j < (sizeof(testInput[0])*8); j++) {
if (((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1)) nBitError++;
}
}
if (nBitError>0) blockErrorState=1;
}
//Iteration times are in microseconds.
timeEncoderCumulative+=(timeEncoder.diff_now/(cpu_freq_GHz*1000.0));
timeDecoderCumulative+=(timeDecoder.diff_now/(cpu_freq_GHz*1000.0));
fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState,
(timeEncoder.diff_now/(cpu_freq_GHz*1000.0)), (timeDecoder.diff_now/(cpu_freq_GHz*1000.0)));
if (nBitError<0) {
blockErrorCumulative++;
bitErrorCumulative+=testLength;
} else {
blockErrorCumulative+=blockErrorState;
bitErrorCumulative+=nBitError;
}
decoderState=0;
nBitError=0;
blockErrorState=0;
}
//Calculate error statistics for the SNR.
@@ -237,15 +410,7 @@ int main(int argc, char *argv[]) {
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
printf("decoding init %9.3fus\n",polar_decoder_init.diff/(cpu_freq_GHz*1000.0*polar_decoder_init.trials));
printf("decoding polar_rate_matching %9.3fus\n",polar_rate_matching.diff/(cpu_freq_GHz*1000.0*polar_rate_matching.trials));
printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials));
printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials));
blockErrorCumulative = 0; bitErrorCumulative = 0;
timeEncoderCumulative = 0; timeDecoderCumulative = 0;
}
@@ -254,11 +419,14 @@ int main(int argc, char *argv[]) {
print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
fclose(logFile);
//Bit
free(testInput);
free(encoderOutput);
free(estimatedOutput);
//Byte
free(encoderOutputByte);
free(modulatedInput);
free(channelOutput);
free(estimatedOutput);
return (0);
}
+26 -2
View File
@@ -355,8 +355,16 @@ based on 3GPP UMTS/LTE specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits
*/
unsigned int crc24b (unsigned char * inptr, int bitlen);
uint32_t crc24b (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc24c(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 24-bit crc ('c' variant for transport-block segments)
based on 3GPP Rel 15 specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits
*/
uint32_t crc24c (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 16-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@@ -440,4 +448,20 @@ 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 *Zout,
unsigned int *F);
uint32_t nr_compute_tbs(uint8_t mcs,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint8_t nb_re_dmrs,
uint16_t length_dmrs,
uint8_t Nl);
#endif
+42 -15
View File
@@ -35,9 +35,12 @@
/*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
uint32_t poly24c = 0xB2B11700; //101100101011000100010111
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
@@ -52,10 +55,11 @@ For initialization && verification purposes,
The first bit is in the MSB of each byte
*********************************************************/
unsigned int
crcbit (unsigned char * inputptr, int octetlen, unsigned int poly)
unsigned int crcbit (unsigned char * inputptr,
int octetlen,
unsigned int poly)
{
unsigned int i, crc = 0, c;
unsigned int i, crc = 0, c;
while (octetlen-- > 0) {
c = (*inputptr++) << 24;
@@ -78,19 +82,21 @@ crcbit (unsigned char * inputptr, int octetlen, unsigned int poly)
crc table initialization
*********************************************************/
static unsigned int crc24aTable[256];
static unsigned int crc24bTable[256];
static unsigned int crc24aTable[256];
static unsigned int crc24bTable[256];
static unsigned int crc24cTable[256];
static unsigned short crc16Table[256];
static unsigned short crc12Table[256];
static unsigned char crc8Table[256];
void crcTableInit (void)
{
unsigned char c = 0;
unsigned char c = 0;
do {
crc24aTable[c] = crcbit (&c, 1, poly24a);
crc24bTable[c] = crcbit (&c, 1, poly24b);
crc24cTable[c] = crcbit (&c, 1, poly24c);
crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
crc12Table[c] = (unsigned short) (crcbit (&c, 1, poly12) >> 16);
crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
@@ -114,8 +120,8 @@ Byte by byte implementations,
assuming initial byte is 0 padded (in MSB) if necessary
*********************************************************/
unsigned int
crc24a (unsigned char * inptr, int bitlen)
unsigned int crc24a (unsigned char * inptr,
int bitlen)
{
int octetlen, resbit;
@@ -134,11 +140,11 @@ crc24a (unsigned char * inptr, int bitlen)
return crc;
}
unsigned int crc24b (unsigned char * inptr, int bitlen)
unsigned int crc24b (unsigned char * inptr,
int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
@@ -153,6 +159,27 @@ unsigned int crc24b (unsigned char * inptr, int bitlen)
return crc;
}
unsigned int crc24c (unsigned char * inptr,
int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
/*#ifdef DEBUG_CRC24C
printf("crc24c: in %x => crc %x (%x)\n",crc,*inptr,crc24cTable[(*inptr) ^ (crc >> 24)]);
#endif*/
crc = (crc << 8) ^ crc24cTable[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
crc = (crc << resbit) ^ crc24cTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
unsigned int
crc16 (unsigned char * inptr, int bitlen)
{
@@ -21,17 +21,38 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_byte2bit(uint8_t *array, uint8_t arraySize, uint8_t *bitArray){//First 2 parameters are in bytes.
for (int i=0; i<arraySize; i++){
bitArray[(7+(i*8))] = ( array[i]>>0 & 0x01);
bitArray[(6+(i*8))] = ( array[i]>>1 & 0x01);
bitArray[(5+(i*8))] = ( array[i]>>2 & 0x01);
bitArray[(4+(i*8))] = ( array[i]>>3 & 0x01);
bitArray[(3+(i*8))] = ( array[i]>>4 & 0x01);
bitArray[(2+(i*8))] = ( array[i]>>5 & 0x01);
bitArray[(1+(i*8))] = ( array[i]>>6 & 0x01);
bitArray[ (i*8) ] = ( array[i]>>7 & 0x01);
void nr_bit2byte_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
uint8_t arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < (arrayInd-1); i++) {
for (int j = 0; j < 32; j++) {
out[j+(i*32)] = (in[i] >> j) & 1;
}
}
for (int j = 0; j < arraySize - ((arrayInd-1) * 32); j++) out[j + ((arrayInd-1) * 32)] = (in[(arrayInd-1)] >> j) & 1;
}
void nr_byte2bit_uint8_32_t(uint8_t *in, uint16_t arraySize, uint32_t *out) {
uint8_t arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < arrayInd; i++) {
out[i]=0;
for (int j = 31; j > 0; j--) {
out[i]|=in[(i*32)+j];
out[i]<<=1;
}
out[i]|=in[(i*32)];
}
}
void nr_crc_bit2bit_uint32_8_t(uint32_t *in, uint16_t arraySize, uint8_t *out) {
out[0]=0xff;
out[1]=0xff;
out[2]=0xff;
uint8_t arrayInd = ceil(arraySize / 32.0);
for (int i = 0; i < arrayInd; i++) {
out[3+i*4] = ((in[i] & (0x0000000f))<<4) | ((in[i] & (0x000000f0))>>4);
out[4+i*4] = (((in[i] & (0x00000f00))<<4) | ((in[i] & (0x0000f000))>>4))>>8;
out[5+i*4] = (((in[i] & (0x000f0000))<<4) | ((in[i] & (0x00f00000))>>4))>>16;
out[6+i*4] = (((in[i] & (0x0f000000))<<4) | ((in[i] & (0xf0000000))>>4))>>24;
}
}
@@ -1,63 +0,0 @@
/*
* 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/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_channel_interleaver_pattern(uint16_t *cip, uint8_t I_BIL, uint16_t E){
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
}
}
@@ -33,10 +33,14 @@
#ifndef __NR_POLAR_DCI_DEFS__H__
#define __NR_POLAR_DCI_DEFS__H__
#define NR_POLAR_DCI_MESSAGE_TYPE 1 //int8_t
#define NR_POLAR_DCI_CRC_PARITY_BITS 24
#define NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS 3
//Sec. 7.3.3: Channel Coding
#define NR_POLAR_DCI_N_MAX 9 //uint8_t
#define NR_POLAR_DCI_I_IL 1 //uint8_t
//#define NR_POLAR_DCI_I_SEG 0 //uint8_t
#define NR_POLAR_DCI_I_SEG 0 //uint8_t
#define NR_POLAR_DCI_N_PC 0 //uint8_t
#define NR_POLAR_DCI_N_PC_WM 0 //uint8_t
File diff suppressed because it is too large Load Diff
@@ -19,275 +19,179 @@
* contact@openairinterface.org
*/
#include "PHY/impl_defs_top.h"
/*!\file PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) __attribute__((always_inline));
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) {
//#define DEBUG_NEW_IMPL
double a;
double b;
double absA,absB;
a = llr[col + 1][row];
b = llr[col+1][row + offset];
if (approximation) { //eq. (9)
absA = fabs(a);
absB = fabs(b);
llr[col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
} else { //eq. (8a)
llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
void updateLLR(double ***llr,
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
uint8_t approximation)
{
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
} else {
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
computeLLR(llr, row, col, i, offset, approximation);
}
}
llrU[row][col]=1;
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
int16_t llrtab[256][256];
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen)
{
void nr_polar_llrtableinit() {
int16_t absA,absB;
int16_t minabs;
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (int a=-128;a<128;a++) {
for (int b=-128;b<128;b++) {
absA=abs(a);
absB=abs(b);
minabs = absA<absB ? absA:absB;
if ((a<0 && b<0) || (a>=0 && b>=0)) llrtab[a+128][b+128] = minabs;
else llrtab[a+128][b+128] = -minabs;
}
}
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
bit[row][col][i] = bit[row][col-1][i];
} else {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen);
bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2);
}
}
bitU[row][col]=1;
}
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation)
{
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,llr[row][0][i]) )) pathMetric[i] += fabs(llr[row][0][i]);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ;
}
}
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) {
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t appr)
{
double *tempPM = malloc(sizeof(double) * listSize);
for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i];
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
for (uint8_t i=0; i<listSize; i++) {
dlist[i]->llr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row];
}
} else {
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
}
llrU[row][col]=1;
}
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen,
int generate_optim_code,FILE *fd) {
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen,generate_optim_code,fd);
if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen,generate_optim_code,fd);
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd);
uint8_t bitValue = 0;
if (appr) { //eq. (12)
for (uint8_t i = 0; i < listSize; i++) {
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][i]))) pathMetric[i] += fabs(llr[row][0][i]);
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = 0; i < listSize; i++) pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i]));
}
if (generate_optim_code==1) fprintf(fd,"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset);
bitValue = 1;
if (appr) { //eq. (12)
for (uint8_t i = listSize; i < 2*listSize; i++) {
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][(i-listSize)]))) pathMetric[i] = tempPM[(i-listSize)] + fabs(llr[row][0][(i-listSize)]);
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = listSize; i < 2*listSize; i++) pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)]));
}
updateLLR_int8_A(dlist,listSize,col,row,offset);
} else {
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd);
if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen,generate_optim_code,fd);
if (generate_optim_code==1) fprintf(fd,"computeLLR_int8(sorted_dlist,%d,%d,%d,%d);\n",listSize,row,col,offset);
computeLLR_int8(dlist,listSize, row, col, offset);
}
llrU[row][col]=1;
}
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
} else {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
}
}
bitU[row][col]=1;
}
free(tempPM);
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU,
uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen,
int generate_optim_code,FILE *fd) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
if (generate_optim_code==1) fprintf(fd,"updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",listSize,col,row);
updateBit_int8_A(dlist,listSize,col,row);
} else {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd);
if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen,generate_optim_code,fd);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset];
// printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
if (generate_optim_code==1) fprintf(fd,"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset);
updateBit_int8_B(dlist,listSize,col,row,offset);
}
bitU[row][col]=1;
}
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation) {
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) {
dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
}
}
}
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) {
int16_t mask,absllr;
updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr);
if (generate_optim_code == 1) fprintf(fd,"updatePathMetric0_int8_A(sorted_dlist,%d,%d,mask,absllr);\n",listSize,row);
/*
mask = dlist[i]->llr[0][row]>>15;
if (mask != 0) {
int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask;
dlist[i]->pathMetric += absllr;
}*/
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation)
{
double a = llr[row][col + 1][i];
double absA = fabs(a);
double b = llr[row + offset][col + 1][i];
double absB = fabs(b);
if (approximation || isinf(absA) || isinf(absB)) { //eq. (9)
llr[row][col][i] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
} else { //eq. (8a)
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
}
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
int i;
for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
decoder_list_t **dlist2 = &dlist[listSize];
if (appr) { //eq. (12)
for (i = 0; i < listSize; i++) {
// bitValue=0
if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
// bitValue=1
else dlist2[i]->pathMetric += dlist[i]->llr[0][row];
}
} else { //eq. (11b)
for (i = 0; i < listSize; i++) {
// bitValue=0
dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
// bitValue=1
dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row]));
}
}
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
}
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updatePathMetric2_int8_A(sorted_dlist,%d,%d);\n",
listSize,row);
updatePathMetric2_int8_A(dlist,listSize,row);
// dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
//if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
//else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len)
{
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",listSize,i2,len);
updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum2_int8_A(sorted_dlist,%d,polarParams->extended_crc_generator_matrix,%d,%d);\n",listSize,i2,len);
updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
decoder_node_t *new_decoder_node(int first_leaf_index,int level) {
@@ -342,6 +246,7 @@ if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp);
return(new_node);
}
void build_decoder_tree(t_nrPolar_params *pp) {
pp->tree.num_nodes=0;
@@ -349,6 +254,18 @@ void build_decoder_tree(t_nrPolar_params *pp) {
}
#if defined(__arm__) || defined(__aarch64__)
// translate 1-1 SIMD functions from SSE to NEON
#define __m128i int16x8_t
#define __m64 int8x8_t
#define _mm_abs_epi16(a) vabsq_s16(a)
#define _mm_min_epi16(a,b) vminq_s16(a,b)
#define _mm_subs_epi16(a,b) vsubq_s16(a,b)
#define _mm_abs_pi16(a) vabs_s16(a)
#define _mm_min_pi16(a,b) vmin_s16(a,b)
#define _mm_subs_pi16(a,b) vsub_s16(a,b)
#endif
void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
int16_t *alpha_v=node->alpha;
int16_t *alpha_l=node->left->alpha;
@@ -362,23 +279,23 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
for (int i=0;i<node->Nv;i++) printf("i%d (frozen %d): alpha_v[i] = %d\n",i,1-pp->information_bit_pattern[node->first_leaf_index+i],alpha_v[i]);
#endif
if (node->left->all_frozen == 0) {
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&15;
if (avx2mod == 0) {
__m256i a256,b256,absa256,absb256,minabs256;
int avx2len = node->Nv/2/16;
// printf("avx2len %d\n",avx2len);
for (int i=0;i<avx2len;i++) {
a256 =((__m256i*)alpha_v)[i];
b256 =((__m256i*)alpha_v)[i+avx2len];
absa256 =_mm256_abs_epi16(a256);
absb256 =_mm256_abs_epi16(b256);
minabs256 =_mm256_min_epi16(absa256,absb256);
((__m256i*)alpha_l)[i] =_mm256_sign_epi16(minabs256,_mm256_xor_si256(a256,b256));
((__m256i*)alpha_l)[i] =_mm256_sign_epi16(minabs256,_mm256_sign_epi16(a256,b256));
}
}
else if (avx2mod == 8) {
@@ -388,7 +305,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
absa128 =_mm_abs_epi16(a128);
absb128 =_mm_abs_epi16(b128);
minabs128 =_mm_min_epi16(absa128,absb128);
*((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_xor_si128(a128,b128));
*((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_sign_epi16(a128,b128));
}
else if (avx2mod == 4) {
__m64 a64,b64,absa64,absb64,minabs64;
@@ -397,11 +314,56 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
absa64 =_mm_abs_pi16(a64);
absb64 =_mm_abs_pi16(b64);
minabs64 =_mm_min_pi16(absa64,absb64);
*((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_xor_si64(a64,b64));
*((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_sign_pi16(a64,b64));
}
else
#else
int sse4mod = (node->Nv/2)&7;
int sse4len = node->Nv/2/8;
#if defined(__arm__) || defined(__aarch64__)
int16x8_t signatimesb,comp1,comp2,negminabs128;
int16x8_t zero=vdupq_n_s16(0);
#endif
{
if (sse4mod == 0) {
for (int i=0;i<sse4len;i++) {
__m128i a128,b128,absa128,absb128,minabs128;
int sse4len = node->Nv/2/8;
a128 =*((__m128i*)alpha_v);
b128 =((__m128i*)alpha_v)[1];
absa128 =_mm_abs_epi16(a128);
absb128 =_mm_abs_epi16(b128);
minabs128 =_mm_min_epi16(absa128,absb128);
#if defined(__arm__) || defined(__aarch64__)
// unfortunately no direct equivalent to _mm_sign_epi16
signatimesb=vxorrq_s16(a128,b128);
comp1=vcltq_s16(signatimesb,zero);
comp2=vcgeq_s16(signatimesb,zero);
negminabs128=vnegq_s16(minabs128);
*((__m128i*)alpha_l) =vorrq_s16(vandq_s16(minabs128,comp0),vandq_s16(negminabs128,comp1));
#else
*((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_sign_epi16(a128,b128));
#endif
}
}
else if (sse4mod == 4) {
__m64 a64,b64,absa64,absb64,minabs64;
a64 =*((__m64*)alpha_v);
b64 =((__m64*)alpha_v)[1];
absa64 =_mm_abs_pi16(a64);
absb64 =_mm_abs_pi16(b64);
minabs64 =_mm_min_pi16(absa64,absb64);
#if defined(__arm__) || defined(__aarch64__)
AssertFatal(1==0,"Need to do this still for ARM\n");
#else
*((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_sign_epi16(a64,b64));
#endif
}
else
#endif
{ // equvalent scalar code to above, activated only on non x86/ARM architectures
for (int i=0;i<node->Nv/2;i++) {
a=alpha_v[i];
b=alpha_v[i+(node->Nv/2)];
@@ -411,6 +373,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
absb=(b+maskb)^maskb;
minabs = absa<absb ? absa : absb;
alpha_l[i] = (maska^maskb)==0 ? minabs : -minabs;
// printf("alphal[%d] %d (%d,%d)\n",i,alpha_l[i],a,b);
}
}
if (node->Nv == 2) { // apply hard decision on left node
@@ -418,7 +381,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
#ifdef DEBUG_NEW_IMPL
printf("betal[0] %d (%p)\n",betal[0],&betal[0]);
#endif
pp->nr_polar_u[node->first_leaf_index] = (1+betal[0])>>1;
pp->nr_polar_U[node->first_leaf_index] = (1+betal[0])>>1;
#ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]);
#endif
@@ -453,27 +416,53 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
else if (avx2mod == 8) {
((__m128i *)alpha_r)[0] = _mm_subs_epi16(((__m128i *)alpha_v)[1],_mm_sign_epi16(((__m128i *)alpha_v)[0],((__m128i *)betal)[0]));
}
else if (avx2mod == 4) {
((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__m64 *)alpha_v)[0],((__m64 *)betal)[0]));
}
else
#else
int sse4mod = (node->Nv/2)&7;
if (sse4mod == 0) {
int sse4len = node->Nv/2/8;
for (int i=0;i<sse4len;i++) {
#if defined(__arm__) || defined(__aarch64__)
((int16x8_t *)alpha_r)[0] = vsubq_s16(((int16x8_t *)alpha_v)[1],vmulq_epi16(((int16x8_t *)alpha_v)[0],((int16x8_t *)betal)[0]));
#else
((__m128i *)alpha_r)[0] = _mm_subs_epi16(((__m128i *)alpha_v)[1],_mm_sign_epi16(((__m128i *)alpha_v)[0],((__m128i *)betal)[0]));
#endif
}
}
else if (sse4mod == 4) {
#if defined(__arm__) || defined(__aarch64__)
((int16x4_t *)alpha_r)[0] = vsub_s16(((int16x4_t *)alpha_v)[1],vmul_epi16(((int16x4_t *)alpha_v)[0],((int16x4_t *)betal)[0]));
#else
((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__64 *)alpha_v)[0],((__m64 *)betal)[0]));
#endif
}
else
#endif
{
{// equvalent scalar code to above, activated only on non x86/ARM architectures
for (int i=0;i<node->Nv/2;i++) {
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
}
}
if (node->Nv == 2) { // apply hard decision on right node
betar[0] = (alpha_r[0]>0) ? -1 : 1;
pp->nr_polar_u[node->first_leaf_index+1] = (1+betar[0])>>1;
pp->nr_polar_U[node->first_leaf_index+1] = (1+betar[0])>>1;
#ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask);
printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]);
#endif
}
}
}
int16_t minus1[16] = {-1,-1,-1,-1,
-1,-1,-1,-1,
-1,-1,-1,-1,
-1,-1,-1,-1};
int16_t all1[16] = {1,1,1,1,
1,1,1,1,
1,1,1,1,
1,1,1,1};
void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
@@ -486,27 +475,37 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&15;
register __m256i allones=*((__m256i*)all1);
if (avx2mod == 0) {
int avx2len = node->Nv/2/16;
for (int i=0;i<avx2len;i++) {
((__m256i*)betav)[i] = _mm256_sign_epi16(((__m256i*)betar)[i],
((__m256i*)betal)[i]);
((__m256i*)betav)[i] = _mm256_sign_epi16(((__m256i*)betav)[i],
((__m256i*)minus1)[0]);
((__m256i*)betav)[i] = _mm256_or_si256(_mm256_cmpeq_epi16(((__m256i*)betar)[i],
((__m256i*)betal)[i]),allones);
}
}
else if (avx2mod == 8) {
((__m128i*)betav)[0] = _mm_sign_epi16(((__m128i*)betar)[0],
((__m128i*)betal)[0]);
((__m128i*)betav)[0] = _mm_sign_epi16(((__m128i*)betav)[0],
((__m128i*)minus1)[0]);
((__m128i*)betav)[0] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[0],
((__m128i*)betal)[0]),*((__m128i*)all1));
}
else if (avx2mod == 4) {
((__m64*)betav)[0] = _mm_sign_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]);
((__m64*)betav)[0] = _mm_sign_pi16(((__m64*)betav)[0],
((__m64*)minus1)[0]);
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]),*((__m64*)all1));
}
else
#else
int avx2mod = (node->Nv/2)&15;
if (ssr4mod == 0) {
int ssr4len = node->Nv/2/8;
register __m128i allones=*((__m128i*)all1);
for (int i=0;i<sse4len;i++) {
((__m256i*)betav)[i] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[i],
((__m128i*)betal)[i]),allones));
}
}
else if (sse4mod == 4) {
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]),*((__m64*)all1));
}
else
#endif
+257 -303
View File
@@ -19,7 +19,16 @@
* contact@openairinterface.org
*/
#define NR_POLAR_CRC_ERROR_CORRECTION_BITS 3
/*!\file PHY/CODING/nrPolar_tools/nr_polar_defs.h
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#ifndef __NR_POLAR_DEFS__H__
#define __NR_POLAR_DEFS__H__
@@ -30,7 +39,20 @@
#include <stdlib.h>
#include <string.h>
#include "PHY/TOOLS/time_meas.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/CODING/coding_defs.h"
//#include "SIMULATION/TOOLS/sim.h"
#define NR_POLAR_DECODER_LISTSIZE 8 //uint8_t
#define NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
#define NR_POLAR_AGGREGATION_LEVEL_1_PRIME 149 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_2_PRIME 151 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_4_PRIME 157 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_8_PRIME 163 //uint16_t
#define NR_POLAR_AGGREGATION_LEVEL_16_PRIME 167 //uint16_t
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 };
@@ -38,26 +60,6 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3
#define Nmax 1024
#define nmax 10
typedef struct decoder_list_s {
uint8_t bit[1+nmax][Nmax];
double llr[1+nmax][Nmax];
uint8_t crcChecksum[24];
double pathMetric;
} decoder_list_t;
typedef struct decoder_list_int8_s {
uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32)));
int16_t llr[1+nmax][Nmax]__attribute__((aligned(32)));
uint8_t crcChecksum[24];
int32_t pathMetric;
} decoder_list_int8_t;
typedef struct decoder_node_t_s {
struct decoder_node_t_s *left;
struct decoder_node_t_s *right;
@@ -76,342 +78,294 @@ typedef struct decoder_tree_t_s {
} decoder_tree_t;
struct nrPolar_params {
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
uint8_t n_pc;
uint8_t n_pc_wm;
uint8_t i_bil;
uint16_t payloadBits;
uint16_t encoderLength;
uint8_t crcParityBits;
uint8_t crcCorrectionBits;
uint16_t K;
uint16_t N;
uint8_t n;
uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern;
const uint16_t *Q_0_Nminus1;
int16_t *Q_I_N;
int16_t *Q_F_N;
int16_t *Q_PC_N;
uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint32_t* crc256Table;
uint8_t **extended_crc_generator_matrix;
//messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime);
struct nrPolar_params *nextPtr;
//polar_encoder vectors:
uint8_t *nr_polar_crc;
uint8_t *nr_polar_b;
uint8_t *nr_polar_cPrime;
uint8_t *nr_polar_u;
uint8_t *nr_polar_d;
void (*decoder_kernel)(struct nrPolar_params *,decoder_list_int8_t **);
decoder_tree_t tree;
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
uint8_t n_pc;
uint8_t n_pc_wm;
uint8_t i_bil;
uint16_t payloadBits;
uint16_t encoderLength;
uint8_t crcParityBits;
uint8_t crcCorrectionBits;
uint16_t K;
uint16_t N;
uint8_t n;
uint32_t crcBit;
uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern;
const uint16_t *Q_0_Nminus1;
int16_t *Q_I_N;
int16_t *Q_F_N;
int16_t *Q_PC_N;
uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint32_t* crc256Table;
uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors
uint8_t *nr_polar_crc;
uint8_t *nr_polar_aPrime;
uint8_t *nr_polar_APrime;
uint8_t *nr_polar_D;
uint8_t *nr_polar_E;
//Polar Coding vectors
uint8_t *nr_polar_A;
uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_B;
uint8_t *nr_polar_U;
decoder_tree_t tree;
} __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
void polar_encoder(uint32_t *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams);
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI);
void polar_encoder_timing(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
double cpuFreqGHz,
FILE* logFile);
int8_t polar_decoder(double *input,
uint8_t *output,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr);
void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParams);
int8_t polar_decoder_aPriori(double *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload);
void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N);
int8_t polar_decoder_aPriori_timing(double *input,
uint32_t *output,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
double *aPrioriPayload,
double cpuFreqGHz,
FILE* logFile);
int8_t polar_decoder_dci(double *input,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint8_t listSize,
uint8_t pathMetricAppr,
uint16_t n_RNTI);
void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *);
int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams,
uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR);
void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
int8_t polar_decoder_int8(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code);
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams);
int8_t polar_decoder_int8_new(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code);
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level);
void nr_polar_llrtableinit(void);
void nr_polar_init(t_nrPolar_params* polarParams, int messageType);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
uint8_t** nr_polar_kronecker_power_matrices(uint8_t n);
const uint16_t* nr_polar_sequence_pattern(uint8_t n);
uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max);
/*!@fn uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max)
* @brief Computes...
* @param K Number of bits to encode (=payloadBits+crcParityBits)
* @param E
* @param n_max */
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max);
void nr_polar_channel_interleaver_pattern(uint16_t *cip, uint8_t I_BIL,
uint16_t E);
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E);
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_,
uint16_t K, uint16_t N, uint16_t E);
void nr_polar_rate_matching_pattern(uint16_t *rmp,
uint16_t *J,
const uint8_t *P_i_,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp,
uint16_t K, uint16_t N, uint16_t E);
void nr_polar_rate_matching(double *input,
double *output,
uint16_t *rmp,
uint16_t K,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp,
uint16_t K, uint16_t N, uint16_t E);
void nr_polar_rate_matching_int16(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_);
void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL,
uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N,
uint16_t *J, const uint16_t *Q_0_Nminus1, uint16_t K, uint16_t N, uint16_t E,
uint8_t n_PC);
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC);
void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output,
uint8_t *pattern, uint16_t size);
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size);
void nr_byte2bit(uint8_t *array, uint8_t arraySize, uint8_t *bitArray);
void nr_bit2byte_uint32_8_t(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N,
uint16_t K, int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC);
void nr_byte2bit_uint8_32_t(uint8_t *in,
uint16_t arraySize,
uint32_t *out);
void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **matrix2,
uint8_t *output, uint16_t row, uint16_t col);
void nr_crc_bit2bit_uint32_8_t(uint32_t *in,
uint16_t arraySize,
uint8_t *out);
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen,
uint16_t zlen);
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen);
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen);
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC);
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen);
void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen);
void nr_free_double_2D_array(double **input, uint16_t xlen);
void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1,
uint8_t **matrix2,
uint8_t *output,
uint16_t row,
uint16_t col);
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation);
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd);
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen,
uint16_t ylen);
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen,
uint16_t ylen,
uint16_t zlen);
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd);
void nr_free_uint8_t_3D_array(uint8_t ***input,
uint16_t xlen,
uint16_t ylen);
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation);
void nr_free_uint8_t_2D_array(uint8_t **input,
uint16_t xlen);
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd);
void nr_free_double_3D_array(double ***input,
uint16_t xlen,
uint16_t ylen);
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr);
void updateLLR(double ***llr,
uint8_t **llrU,
uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen,
uint8_t approximation);
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd);
void updateBit(uint8_t ***bit,
uint8_t **bitU,
uint8_t listSize,
uint16_t row,
uint16_t col,
uint16_t xlen,
uint8_t ylen);
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updatePathMetric(double *pathMetric,
double ***llr,
uint8_t listSize,
uint8_t bitValue,
uint16_t row,
uint8_t approximation);
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd);
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
uint16_t row,
uint8_t approximation);
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void computeLLR(double ***llr,
uint16_t row,
uint16_t col,
uint8_t i,
uint16_t offset,
uint8_t approximation);
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd);
void updateCrcChecksum(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum,
uint8_t **crcGen,
uint8_t listSize,
uint32_t i2,
uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len);
void nr_sort_asc_double_1D_array_ind(double *matrix,
uint8_t *ind,
uint8_t len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits);
void crcTable256Init (uint32_t poly, uint32_t* crc256Table);
void nr_crc_computation(uint8_t* input, uint8_t* output, uint16_t payloadBits, uint16_t crcParityBits, uint32_t* crc256Table);
unsigned int crcbit (unsigned char* inputptr, int octetlen, uint32_t poly);
unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table);
static inline void nr_polar_rate_matcher(uint8_t *input, unsigned char *output, uint16_t *pattern, uint16_t size) {
//Also nr_polar_rate_matcher
static inline void nr_polar_interleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
for (int i=0; i<size; i++) output[i]=input[pattern[i]];
}
static inline void nr_polar_interleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size) {
for (int i=0; i<size; i++) output[i]=input[pattern[i]];
}
static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint16_t *pattern, uint16_t size) {
static inline void nr_polar_deinterleaver(uint8_t *input,
uint8_t *output,
uint16_t *pattern,
uint16_t size)
{
for (int i=0; i<size; i++) output[pattern[i]]=input[i];
}
void polar_decoder_K56_N512_E864(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_list);
void build_decoder_tree(t_nrPolar_params *pp);
#define updateLLR_int8_A(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];if(dlist[(i)]->llr[col][row]>127 || dlist[i]->llr[col][row]<-128) printf("dlist[%d]->llr[%d][%d] = %d> 8bit\n",i,col,row,dlist[i]->llr[col][row]);}}
#define updateBit_int8_A(dlist,listSize,col,row) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)];}}
#define updateBit_int8_B(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)];}}
#define updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr) {for (int i=0;i<listSize;i++) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}}
#define updatePathMetric2_int8_A(dlist,listSize,row) {for (int i=0;i<listSize;i++) {{dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}}}
#define updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}}
#define updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}}
extern int16_t llrtab[256][256];
inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col,
uint16_t offset) __attribute__((always_inline));
inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col,
uint16_t offset) {
int16_t a;
int16_t b;
int16_t absA,absB;
int16_t maska,maskb;
int16_t minabs;
// int16_t **llr=dlist[i]->llr;
for (int i=0;i<listSize;i++) {
a = dlist[i]->llr[col + 1][row];
b = dlist[i]->llr[col+1][row + offset];
// printf("LLR: a %d, b %d\n",a,b);
maska = a>>15;
maskb = b>>15;
absA = (a+maska)^maska;
absB = (b+maskb)^maskb;
// printf("LLR: absA %d, absB %d\n",absA,absB);
minabs = absA<absB ? absA : absB;
if ((maska^maskb) == 0)
dlist[i]->llr[col][row] = minabs;
else
dlist[i]->llr[col][row] = -minabs;
// printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
//dlist[i]->llr[col][row] = llrtab[a+128][b+128];
// printf("newLLR [%d,%d]: %d\n",col,row,dlist[i]->llr[col][row]);
}
}
#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \
for (int k = 0; k < (polarParams->n+1); k++) { \
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\
(void*)&sorted_dlist[i]->bit[k][0],\
sizeof(uint8_t)*polarParams->N);\
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\
(void*)&sorted_dlist[i]->llr[k][0],\
sizeof(int16_t)*polarParams->N);}}}
#define decoder_int8_B(sorted_dlist,currentBit,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}}
void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[],
t_nrPolar_params *polarParams,
int currentBit,
int currentListSize,
int listSize) {
int32_t pathMetric[2*listSize];
decoder_list_int8_t *temp_dlist[2*listSize];
int listIndex[2*listSize];
int listIndex2[2*listSize];
for (int i = 0; i < currentListSize; i++) {
listIndex[i]=i;
pathMetric[i] = sorted_dlist[i]->pathMetric;
}
nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i=0;i<currentListSize;i++) {
listIndex2[listIndex[i]] = i;
}
// copy the llr/bit arrays that are needed
for (int i = 0; i < listSize; i++) {
// printf("listIndex[%d] %d\n",i,listIndex[i]);
if ((listIndex2[i+listSize]<listSize) && (listIndex2[i]<listSize)) { // both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
}
else if (listIndex2[i+listSize]<listSize) { // only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
for (int i = 0; i < 2*listSize; i++) {
temp_dlist[i] = sorted_dlist[i];
}
for (int i = 0; i < 2*listSize; i++) {
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist[i] = temp_dlist[listIndex[i]];
}
}
#endif
@@ -19,57 +19,298 @@
* contact@openairinterface.org
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
/*!\file PHY/CODING/nrPolar_tools/nr_polar_encoder.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
void polar_encoder(
uint8_t *input,
uint8_t *output,
t_nrPolar_params *polarParams)
//#define DEBUG_POLAR_ENCODER
//#define DEBUG_POLAR_ENCODER_DCI
//#define DEBUG_POLAR_ENCODER_TIMING
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
//input [a_31 a_30 ... a_0]
//output [f_31 f_30 ... f_0] [f_63 f_62 ... f_32] ...
void polar_encoder(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams)
{
if (polarParams->idx == 0){//PBCH
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
/*
* Bytewise operations
*/
//Calculate CRC.
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->payloadBits,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++)
polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
} else { //UCI
}
//Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
//Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
#ifdef DEBUG_POLAR_ENCODER
for (int i=0; i< polarParams->encoderLength;i++) printf("f[%d]=%d\n", i, polarParams->nr_polar_E[i]);
#endif
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
}
void polar_encoder_dci(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
uint16_t n_RNTI)
{
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
#endif
/*
* Bytewise operations
*/
//(a to a')
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
for (int i=0; i<polarParams->crcParityBits; i++) polarParams->nr_polar_APrime[i]=1;
for (int i=0; i<polarParams->payloadBits; i++) polarParams->nr_polar_APrime[i+(polarParams->crcParityBits)]=polarParams->nr_polar_A[i];
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] A: ");
for (int i=0; i<polarParams->payloadBits; i++) printf("%d-", polarParams->nr_polar_A[i]);
printf("\n");
printf("[polar_encoder_dci] APrime: ");
for (int i=0; i<polarParams->K; i++) printf("%d-", polarParams->nr_polar_APrime[i]);
printf("\n");
printf("[polar_encoder_dci] GP: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->crc_generator_matrix[0][i]);
printf("\n");
#endif
//Calculate CRC.
// --- OLD ---
//nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(input, polarParams->crc_generator_matrix,
// polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits);
//for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
// --- NEW ---
nr_crc_computation(input, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits, polarParams->crc256Table);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_APrime,
polarParams->crc_generator_matrix,
polarParams->nr_polar_crc,
polarParams->K,
polarParams->crcParityBits);
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] CRC: ");
for (int i=0; i<polarParams->crcParityBits; i++) printf("%d-", polarParams->nr_polar_crc[i]);
printf("\n");
#endif
//Attach CRC to the Transport Block. (a to b)
for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_b[i] = input[i];
for (uint16_t i = 0; i < polarParams->payloadBits; i++)
polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i];
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++)
polarParams->nr_polar_b[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( polarParams->nr_polar_B[polarParams->payloadBits+8+i] + ((n_RNTI>>(15-i))&1) ) % 2;
}
/* //(a to a')
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime);
//Parity bits computation (p)
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits));
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] crc: 0x%08x\n", polarParams->crcBit);
for (int i=0; i<32; i++)
{
printf("%d\n",((polarParams->crcBit)>>i)&1);
}
#endif
//(a to b)
//
// Bytewise operations
//
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0);
for (int i=0; i<arrayInd-1; i++){
for (int j=0; j<8; j++) {
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
}
}
for (int i=0; i<((polarParams->payloadBits)%8); i++) {
polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
}
for (int i=0; i<8; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
}
//Scrambling (b to c)
for (int i=0; i<16; i++) {
polarParams->nr_polar_B[polarParams->payloadBits+8+i] =
( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2;
}*/
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] B: ");
for (int i = 0; i < polarParams->K; i++) printf("%d-", polarParams->nr_polar_B[i]);
printf("\n");
#endif
//Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_b, polarParams->nr_polar_cPrime, polarParams->interleaving_pattern, polarParams->K);
nr_polar_interleaver(polarParams->nr_polar_B,
polarParams->nr_polar_CPrime,
polarParams->interleaving_pattern,
polarParams->K);
//Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_cPrime, polarParams->nr_polar_u, polarParams->N, polarParams->K,
polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc);
nr_polar_bit_insertion(polarParams->nr_polar_CPrime,
polarParams->nr_polar_U,
polarParams->N,
polarParams->K,
polarParams->Q_I_N,
polarParams->Q_PC_N,
polarParams->n_pc);
//Encoding (u to d)
// --- OLD ---
//nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_u, polarParams->G_N, polarParams->nr_polar_d, polarParams->N, polarParams->N);
//for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_d[i] = (polarParams->nr_polar_d[i] % 2);
//printf("\nd old: ");
//for (uint16_t i = 0; i < polarParams->N; i++)
//printf("%i ", polarParams->nr_polar_d[i]);
// --- NEW ---
nr_polar_kernal_operation(polarParams->nr_polar_u, polarParams->nr_polar_d, polarParams->N);
//printf("\nd new: ");
//for (uint16_t i = 0; i < polarParams->N; i++)
// printf("%i ", polarParams->nr_polar_d[i]);
//for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_d[i] = (polarParams->nr_polar_d[i] % 2);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U,
polarParams->G_N,
polarParams->nr_polar_D,
polarParams->N,
polarParams->N);
for (uint16_t i = 0; i < polarParams->N; i++)
polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
//Rate matching
//Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_rate_matcher(polarParams->nr_polar_d, output, polarParams->rate_matching_pattern, polarParams->encoderLength);
nr_polar_interleaver(polarParams->nr_polar_D,
polarParams->nr_polar_E,
polarParams->rate_matching_pattern,
polarParams->encoderLength);
/*
* Return bits.
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] E: ");
for (int i = 0; i < polarParams->encoderLength; i++) printf("%d-", polarParams->nr_polar_E[i]);
uint8_t outputInd = ceil(polarParams->encoderLength / 32.0);
printf("\n[polar_encoder_dci] out: ");
for (int i = 0; i < outputInd; i++) {
printf("[%d]->0x%08x\t", i, out[i]);
}
#endif
}
void polar_encoder_timing(uint32_t *in,
uint32_t *out,
t_nrPolar_paramsPtr polarParams,
double cpuFreqGHz,
FILE* logFile)
{
//Initiate timing.
time_stats_t timeEncoderCRCByte, timeEncoderCRCBit, timeEncoderInterleaver, timeEncoderBitInsertion, timeEncoder1, timeEncoder2, timeEncoderRateMatching, timeEncoderByte2Bit;
reset_meas(&timeEncoderCRCByte); reset_meas(&timeEncoderCRCBit); reset_meas(&timeEncoderInterleaver); reset_meas(&timeEncoderBitInsertion); reset_meas(&timeEncoder1); reset_meas(&timeEncoder2); reset_meas(&timeEncoderRateMatching); reset_meas(&timeEncoderByte2Bit);
uint16_t n_RNTI=0x0000;
start_meas(&timeEncoderCRCByte);
nr_crc_bit2bit_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_aPrime); //(a to a')
polarParams->crcBit = crc24c(polarParams->nr_polar_aPrime, (polarParams->payloadBits+polarParams->crcParityBits)); //Parity bits computation (p)
uint8_t arrayInd = ceil(polarParams->payloadBits / 8.0); //(a to b)
for (int i=0; i<arrayInd-1; i++)
for (int j=0; j<8; j++)
polarParams->nr_polar_B[j+(i*8)] = ((polarParams->nr_polar_aPrime[3+i]>>(7-j)) & 1);
for (int i=0; i<((polarParams->payloadBits)%8); i++) polarParams->nr_polar_B[i+(arrayInd-1)*8] = ((polarParams->nr_polar_aPrime[3+(arrayInd-1)]>>(7-i)) & 1);
for (int i=0; i<8; i++) polarParams->nr_polar_B[polarParams->payloadBits+i] = ((polarParams->crcBit)>>(31-i))&1;
for (int i=0; i<16; i++) polarParams->nr_polar_B[polarParams->payloadBits+8+i] = ( (((polarParams->crcBit)>>(23-i))&1) + ((n_RNTI>>(15-i))&1) ) % 2; //Scrambling (b to c)
stop_meas(&timeEncoderCRCByte);
start_meas(&timeEncoderCRCBit);
nr_bit2byte_uint32_8_t(in, polarParams->payloadBits, polarParams->nr_polar_A);
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_A, polarParams->crc_generator_matrix, polarParams->nr_polar_crc, polarParams->payloadBits, polarParams->crcParityBits); //Calculate CRC.
for (uint8_t i = 0; i < polarParams->crcParityBits; i++) polarParams->nr_polar_crc[i] = (polarParams->nr_polar_crc[i] % 2);
for (uint16_t i = 0; i < polarParams->payloadBits; i++) polarParams->nr_polar_B[i] = polarParams->nr_polar_A[i]; //Attach CRC to the Transport Block. (a to b)
for (uint16_t i = polarParams->payloadBits; i < polarParams->K; i++) polarParams->nr_polar_B[i]= polarParams->nr_polar_crc[i-(polarParams->payloadBits)];
stop_meas(&timeEncoderCRCBit);
start_meas(&timeEncoderInterleaver); //Interleaving (c to c')
nr_polar_interleaver(polarParams->nr_polar_B, polarParams->nr_polar_CPrime, polarParams->interleaving_pattern, polarParams->K);
stop_meas(&timeEncoderInterleaver);
start_meas(&timeEncoderBitInsertion); //Bit insertion (c' to u)
nr_polar_bit_insertion(polarParams->nr_polar_CPrime, polarParams->nr_polar_U, polarParams->N, polarParams->K, polarParams->Q_I_N, polarParams->Q_PC_N, polarParams->n_pc);
stop_meas(&timeEncoderBitInsertion);
start_meas(&timeEncoder1); //Encoding (u to d)
nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(polarParams->nr_polar_U, polarParams->G_N, polarParams->nr_polar_D, polarParams->N, polarParams->N);
stop_meas(&timeEncoder1);
start_meas(&timeEncoder2);
for (uint16_t i = 0; i < polarParams->N; i++) polarParams->nr_polar_D[i] = (polarParams->nr_polar_D[i] % 2);
stop_meas(&timeEncoder2);
start_meas(&timeEncoderRateMatching);//Rate matching //Sub-block interleaving (d to y) and Bit selection (y to e)
nr_polar_interleaver(polarParams->nr_polar_D, polarParams->nr_polar_E, polarParams->rate_matching_pattern, polarParams->encoderLength);
stop_meas(&timeEncoderRateMatching);
start_meas(&timeEncoderByte2Bit); //Return bits.
nr_byte2bit_uint8_32_t(polarParams->nr_polar_E, polarParams->encoderLength, out);
stop_meas(&timeEncoderByte2Bit);
fprintf(logFile,",%f,%f,%f,%f,%f,%f,%f,%f\n",
(timeEncoderCRCByte.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoderCRCBit.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoderInterleaver.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoderBitInsertion.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoder1.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoder2.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoderRateMatching.diff_now/(cpuFreqGHz*1000.0)),
(timeEncoderByte2Bit.diff_now/(cpuFreqGHz*1000.0)));
}
@@ -1,131 +0,0 @@
/*
* 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/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N,
uint16_t *J, const uint16_t *Q_0_Nminus1, uint16_t K, uint16_t N, uint16_t E,
uint8_t n_PC) {
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
for (int i = 0; i <= N; i++) {
Q_Ftmp_N[i] = -1; // Empty array.
Q_Itmp_N[i] = -1;
}
uint8_t flag;
uint16_t limit, ind;
if (E < N) {
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
for (int n = 0; n <= N - E - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double) N) >= (3.0 / 4)) {
limit = ceil((double) (3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
} else {
limit = ceil((double) (9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else { //shortening
for (int n = E; n <= N - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
Q_Itmp_N[N]++;
}
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for (int n = 0; n <= (K + n_PC) - 1; n++) {
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
Q_I_N[n] = Q_Itmp_N[ind];
}
//Q_F_N = Q_0_N-1 \ Q_I_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (Q_0_Nminus1[n] == Q_I_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
Q_F_N[N]++;
}
}
//Information Bit Pattern
for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) {
ibp[n] = 1;
break;
}
}
}
free(Q_Ftmp_N);
free(Q_Itmp_N);
}
void nr_polar_info_bit_extraction(uint8_t *input, uint8_t *output, uint8_t *pattern, uint16_t size) {
uint16_t j = 0;
for (int i = 0; i < size; i++) {
if (pattern[i] > 0) {
output[j] = input[i];
j++;
}
}
}
@@ -19,6 +19,17 @@
* contact@openairinterface.org
*/
/*!\file PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){
@@ -19,6 +19,17 @@
* contact@openairinterface.org
*/
/*!\file PHY/CODING/nrPolar_tools/nr_polar_kronecker_power_matrices.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
uint8_t (*const(G_N_1[])) = {
@@ -19,6 +19,17 @@
* contact@openairinterface.org
*/
/*!\file PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **matrix2,
@@ -66,6 +77,40 @@ uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen
return output;
}
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) {
double ***output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 2D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = NULL;
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 3D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
return output;
}
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) {
double **output;
int i, j;
@@ -117,6 +162,18 @@ uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
return output;
}
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
}
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
@@ -144,7 +201,7 @@ void nr_free_double_2D_array(double **input, uint16_t xlen) {
}
// Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) {
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) {
int swaps;
double temp;
int tempInd;
@@ -1,46 +0,0 @@
/*
* 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 <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
uint32_t nr_polar_output_length(uint16_t K, uint16_t E, uint8_t n_max){
uint8_t n_1, n_2, n_min=5, n;
uint32_t polar_code_output_length;
double R_min=1.0/8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
polar_code_output_length = (uint32_t) pow(2.0,n);
return polar_code_output_length;
}
@@ -19,21 +19,23 @@
* contact@openairinterface.org
*/
/*! \file PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h
* \brief Defines the constant variables for polar coding of the PBCH from 38-212, V15.1.1 2018-04.
* \author
* \date 2018
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
/*!\file PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h
* \brief Defines the constant variables for polar coding of the PBCH from 38-212, V15.1.1 2018-04.
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#ifndef __NR_POLAR_PBCH_DEFS__H__
#define __NR_POLAR_PBCH_DEFS__H__
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t
#define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3
//Assumed 3 by 3GPP when NR_POLAR_PBCH_L>8 to meet false alarm rate requirements.
@@ -49,9 +51,7 @@
//Sec. 7.1.5: Rate Matching
#define NR_POLAR_PBCH_I_BIL 0 //uint8_t
#define NR_POLAR_PBCH_E 864 //uint16_t
//#define NR_POLAR_PBCH_L 5 //uint8_t
#define NR_POLAR_PBCH_PATH_METRIC_APPROXIMATION 0 //uint8_t; 0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
#define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32
/*
* TEST CODE
@@ -0,0 +1,337 @@
/*
* 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/CODING/nrPolar_tools/nr_polar_procedures.h
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
uint16_t K,
int16_t *Q_I_N,
int16_t *Q_PC_N,
uint8_t n_PC)
{
uint16_t k=0;
uint8_t flag;
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
}
}
uint32_t nr_polar_output_length(uint16_t K,
uint16_t E,
uint8_t n_max)
{
uint8_t n_1, n_2, n_min=5, n;
double R_min=1.0/8;
if ( (E <= (9.0/8)*pow(2,ceil(log2(E))-1)) && (K/E < 9.0/16) ) {
n_1 = ceil(log2(E))-1;
} else {
n_1 = ceil(log2(E));
}
n_2 = ceil(log2(K/R_min));
n=n_max;
if (n>n_1) n=n_1;
if (n>n_2) n=n_2;
if (n<n_min) n=n_min;
return ((uint32_t) pow(2.0,n)); //=polar_code_output_length
}
void nr_polar_channel_interleaver_pattern(uint16_t *cip,
uint8_t I_BIL,
uint16_t E)
{
if (I_BIL == 1) {
uint16_t T=0, k;
while( ((T/2)*(T+1)) < E ) T++;
int16_t **v = malloc(T * sizeof(*v));
for (int i = 0; i <= T-1; i++) v[i] = malloc((T-i) * sizeof(*(v[i])));
k=0;
for (int i = 0; i <= T-1; i++) {
for (int j = 0; j <= (T-1)-i; j++) {
if (k<E) {
v[i][j] = k;
} else {
v[i][j] = (-1);
}
k++;
}
}
k=0;
for (int j = 0; j <= T-1; j++) {
for (int i = 0; i <= (T-1)-j; i++) {
if ( v[i][j] != (-1) ) {
cip[k]=v[i][j];
k++;
}
}
}
for (int i = 0; i <= T-1; i++) free(v[i]);
free(v);
} else {
for (int i=0; i<=E-1; i++) cip[i]=i;
}
}
void nr_polar_info_bit_pattern(uint8_t *ibp,
int16_t *Q_I_N,
int16_t *Q_F_N,
uint16_t *J,
const uint16_t *Q_0_Nminus1,
uint16_t K,
uint16_t N,
uint16_t E,
uint8_t n_PC)
{
int16_t *Q_Ftmp_N = malloc(sizeof(int16_t) * (N + 1)); // Last element shows the final
int16_t *Q_Itmp_N = malloc(sizeof(int16_t) * (N + 1)); // array index assigned a value.
for (int i = 0; i <= N; i++) {
Q_Ftmp_N[i] = -1; // Empty array.
Q_Itmp_N[i] = -1;
}
uint8_t flag;
uint16_t limit, ind;
if (E < N) {
if ((K / (double) E) <= (7.0 / 16)) { //puncturing
for (int n = 0; n <= N - E - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
if ((E / (double) N) >= (3.0 / 4)) {
limit = ceil((double) (3 * N - 2 * E) / 4);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
} else {
limit = ceil((double) (9 * N - 4 * E) / 16);
for (int n = 0; n <= limit - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = n;
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
} else { //shortening
for (int n = E; n <= N - 1; n++) {
ind = Q_Ftmp_N[N] + 1;
Q_Ftmp_N[ind] = J[n];
Q_Ftmp_N[N] = Q_Ftmp_N[N] + 1;
}
}
}
//Q_I,tmp_N = Q_0_N-1 \ Q_F,tmp_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= Q_Ftmp_N[N]; m++) {
if (Q_0_Nminus1[n] == Q_Ftmp_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_Itmp_N[Q_Itmp_N[N] + 1] = Q_0_Nminus1[n];
Q_Itmp_N[N]++;
}
}
//Q_I_N comprises (K+n_PC) most reliable bit indices in Q_I,tmp_N
for (int n = 0; n <= (K + n_PC) - 1; n++) {
ind = Q_Itmp_N[N] + n - ((K + n_PC) - 1);
Q_I_N[n] = Q_Itmp_N[ind];
}
//Q_F_N = Q_0_N-1 \ Q_I_N
for (int n = 0; n <= N - 1; n++) {
flag = 1;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (Q_0_Nminus1[n] == Q_I_N[m]) {
flag = 0;
break;
}
}
if (flag) {
Q_F_N[Q_F_N[N] + 1] = Q_0_Nminus1[n];
Q_F_N[N]++;
}
}
//Information Bit Pattern
for (int n = 0; n <= N - 1; n++) {
ibp[n] = 0;
for (int m = 0; m <= (K + n_PC) - 1; m++) {
if (n == Q_I_N[m]) {
ibp[n] = 1;
break;
}
}
}
free(Q_Ftmp_N);
free(Q_Itmp_N);
}
void nr_polar_info_bit_extraction(uint8_t *input,
uint8_t *output,
uint8_t *pattern,
uint16_t size)
{
uint16_t j = 0;
for (int i = 0; i < size; i++) {
if (pattern[i] > 0) {
output[j] = input[i];
j++;
}
}
}
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
free(d);
free(y);
}
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
void nr_polar_rate_matching_int16(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
@@ -33,27 +33,7 @@
#ifndef __NR_POLAR_UCI_DEFS__H__
#define __NR_POLAR_UCI_DEFS__H__
#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
#define NR_POLAR_UCI_MESSAGE_TYPE -1 //int8_t
#define NR_POLAR_UCI_CRC_ERROR_CORRECTION_BITS 3
#endif
+120
View File
@@ -0,0 +1,120 @@
/*
* 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_compute_tbs.c
purpose: Compute NR TBS
author: Hongzhi WANG (TCL)
*/
#include "PHY/defs_nr_UE.h"
//#include "SCHED/extern.h"
#define INDEX_MAX_TBS_TABLE (93)
//Table 5.1.3.1-1
uint16_t Mcsindextable1[29][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}};
//Table 5.1.2.2-2
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824};
uint32_t nr_compute_tbs(uint8_t mcs,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint8_t nb_re_dmrs,
uint16_t length_dmrs,
uint8_t Nl)
{
uint16_t nbp_re, nb_re, nb_dmrs_prb, nb_rb_oh, Ninfo,Np_info,n,Qm,R,C;
uint32_t nr_tbs;
nb_rb_oh = 0; //set to 0 if not configured by higher layer
Qm = Mcsindextable1[mcs][0];
R = Mcsindextable1[mcs][1];
nb_dmrs_prb = nb_re_dmrs*length_dmrs;
nbp_re = 12 * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
nb_re = min(156, nbp_re) * nb_rb;
// Intermediate number of information bits
Ninfo = (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);
if (Ninfo <=3824) {
n = max(3, floor(log2(Ninfo)) - 6);
Np_info = max(24, pow(n,2) * floor(Ninfo/pow(n,2)));
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
if (Tbstable_nr[i] >= Np_info){
nr_tbs = Tbstable_nr[i];
break;
}
}
}
else {
n = floor(log2(Ninfo-24)) - 5;
Np_info = max(3840, pow(n,2) * round((Ninfo - 24)/pow(n,2)));
if (R <= 1024/4) {
C = ceil( (Np_info + 24)/3816 );
nr_tbs = 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;
}
else
nr_tbs = 8 * ceil( (Np_info + 24)/8 ) - 24;
}
}
return nr_tbs;
}
+214
View File
@@ -0,0 +1,214 @@
/*
* 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/CODING/nr_polar_init.h
* \brief
* \author Turker Yilmaz
* \date 2018
* \version 0.1
* \company EURECOM
* \email turker.yilmaz@eurecom.fr
* \note
* \warning
*/
#include "nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = *polarParams;
uint16_t aggregation_prime = nr_polar_aggregation_prime(aggregation_level);
//Parse the list. If the node is already created, return without initialization.
while (currentPtr != NULL) {
if (currentPtr->idx == (messageType * messageLength * aggregation_prime)) return;
else currentPtr = currentPtr->nextPtr;
}
//Else, initialize and add node to the end of the linked list.
t_nrPolar_paramsPtr newPolarInitNode = malloc(sizeof(t_nrPolar_params));
if (newPolarInitNode != NULL) {
newPolarInitNode->idx = (messageType * messageLength * aggregation_prime);
newPolarInitNode->nextPtr = NULL;
if (messageType == 0) { //PBCH
newPolarInitNode->n_max = NR_POLAR_PBCH_N_MAX;
newPolarInitNode->i_il = NR_POLAR_PBCH_I_IL;
newPolarInitNode->i_seg = NR_POLAR_PBCH_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_PBCH_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_PBCH_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = NR_POLAR_PBCH_E;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
} else if (messageType == 1) { //DCI
newPolarInitNode->n_max = NR_POLAR_DCI_N_MAX;
newPolarInitNode->i_il = NR_POLAR_DCI_I_IL;
newPolarInitNode->i_seg = NR_POLAR_DCI_I_SEG;
newPolarInitNode->n_pc = NR_POLAR_DCI_N_PC;
newPolarInitNode->n_pc_wm = NR_POLAR_DCI_N_PC_WM;
newPolarInitNode->i_bil = NR_POLAR_DCI_I_BIL;
newPolarInitNode->crcParityBits = NR_POLAR_DCI_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->encoderLength = aggregation_level*108;
newPolarInitNode->crcCorrectionBits = NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix=crc24c_generator_matrix(newPolarInitNode->payloadBits+newPolarInitNode->crcParityBits);//G_P
} else if (messageType == -1) { //UCI
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
newPolarInitNode->K = newPolarInitNode->payloadBits + newPolarInitNode->crcParityBits; // Number of bits to encode.
newPolarInitNode->N = nr_polar_output_length(newPolarInitNode->K, newPolarInitNode->encoderLength, newPolarInitNode->n_max);
newPolarInitNode->n = log2(newPolarInitNode->N);
newPolarInitNode->G_N = nr_polar_kronecker_power_matrices(newPolarInitNode->n);
//polar_encoder vectors:
newPolarInitNode->nr_polar_crc = malloc(sizeof(uint8_t) * newPolarInitNode->crcParityBits);
newPolarInitNode->nr_polar_aPrime = malloc(sizeof(uint8_t) * ((ceil((newPolarInitNode->payloadBits)/32.0)*4)+3));
newPolarInitNode->nr_polar_APrime = malloc(sizeof(uint8_t) * newPolarInitNode->K);
newPolarInitNode->nr_polar_D = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->nr_polar_E = malloc(sizeof(uint8_t) * newPolarInitNode->encoderLength);
//Polar Coding vectors
newPolarInitNode->nr_polar_U = malloc(sizeof(uint8_t) * newPolarInitNode->N); //Decoder: nr_polar_uHat
newPolarInitNode->nr_polar_CPrime = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_cHat
newPolarInitNode->nr_polar_B = malloc(sizeof(uint8_t) * newPolarInitNode->K); //Decoder: nr_polar_bHat
newPolarInitNode->nr_polar_A = malloc(sizeof(uint8_t) * newPolarInitNode->payloadBits); //Decoder: nr_polar_aHat
newPolarInitNode->Q_0_Nminus1 = nr_polar_sequence_pattern(newPolarInitNode->n);
newPolarInitNode->interleaving_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->K);
nr_polar_interleaving_pattern(newPolarInitNode->K,
newPolarInitNode->i_il,
newPolarInitNode->interleaving_pattern);
newPolarInitNode->rate_matching_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
uint16_t *J = malloc(sizeof(uint16_t) * newPolarInitNode->N);
nr_polar_rate_matching_pattern(newPolarInitNode->rate_matching_pattern,
J,
nr_polar_subblock_interleaver_pattern,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength);
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
newPolarInitNode->Q_F_N = malloc( sizeof(int16_t) * (newPolarInitNode->N + 1)); // Last element shows the final array index assigned a value.
newPolarInitNode->Q_PC_N = malloc( sizeof(int16_t) * (newPolarInitNode->n_pc));
for (int i = 0; i <= newPolarInitNode->N; i++)
newPolarInitNode->Q_F_N[i] = -1; // Empty array.
nr_polar_info_bit_pattern(newPolarInitNode->information_bit_pattern,
newPolarInitNode->Q_I_N,
newPolarInitNode->Q_F_N,
J,
newPolarInitNode->Q_0_Nminus1,
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength,
newPolarInitNode->n_pc);
newPolarInitNode->channel_interleaver_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_channel_interleaver_pattern(newPolarInitNode->channel_interleaver_pattern,
newPolarInitNode->i_bil,
newPolarInitNode->encoderLength);
free(J);
build_decoder_tree(newPolarInitNode);
printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created");
}
currentPtr = *polarParams;
//If polarParams is empty:
if (currentPtr == NULL)
{
*polarParams = newPolarInitNode;
return;
}
//Else, add node to the end of the linked list.
while (currentPtr->nextPtr != NULL) {
currentPtr = currentPtr->nextPtr;
}
currentPtr->nextPtr= newPolarInitNode;
return;
}
void nr_polar_print_polarParams(t_nrPolar_paramsPtr polarParams)
{
uint8_t i = 0;
if (polarParams == NULL) {
printf("polarParams is empty.\n");
} else {
while (polarParams != NULL){
printf("polarParams[%d] = %d\n", i, polarParams->idx);
polarParams = polarParams->nextPtr;
i++;
}
}
return;
}
t_nrPolar_paramsPtr nr_polar_params (t_nrPolar_paramsPtr polarParams,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_paramsPtr currentPtr = NULL;
while (polarParams != NULL) {
if (polarParams->idx ==
(messageType * messageLength * (nr_polar_aggregation_prime(aggregation_level)) )) {
currentPtr = polarParams;
break;
} else {
polarParams = polarParams->nextPtr;
}
}
return currentPtr;
}
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level)
{
if (aggregation_level == 0) return 0;
else if (aggregation_level == 1) return NR_POLAR_AGGREGATION_LEVEL_1_PRIME;
else if (aggregation_level == 2) return NR_POLAR_AGGREGATION_LEVEL_2_PRIME;
else if (aggregation_level == 4) return NR_POLAR_AGGREGATION_LEVEL_4_PRIME;
else if (aggregation_level == 8) return NR_POLAR_AGGREGATION_LEVEL_8_PRIME;
else return NR_POLAR_AGGREGATION_LEVEL_16_PRIME; //aggregation_level == 16
}
+2 -2
View File
@@ -24,8 +24,8 @@
author: Hongzhi WANG (TCL)
date: 12.09.2017
*/
#include "PHY/defs.h"
#include "SCHED/extern.h"
#include "PHY/defs_nr_UE.h"
//#include "SCHED/extern.h"
//#define DEBUG_SEGMENTATION
+25 -3
View File
@@ -20,8 +20,8 @@
*/
#include "PHY/defs_gNB.h"
#include "SCHED/sched_eNB.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "RadioResourceConfigCommonSIB.h"
@@ -32,7 +32,7 @@
#include "assertions.h"
#include <math.h>
#include "PHY/NR_REFSIG/defs.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
@@ -120,7 +120,25 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
// Polar encoder init for PBCH
nr_polar_init(&fp->pbch_polar_params, 1);
nr_polar_init(&gNB->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
//PDCCH DMRS init
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t**));
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
for (int slot=0; slot<fp->slots_per_frame; slot++) {
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t*));
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
for (int symb=0; symb<fp->symbols_per_slot; symb++){
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
}
}
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
/*
lte_gold(fp,gNB->lte_gold_table,fp->Nid_cell);
@@ -278,6 +296,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
LTE_eNB_PUSCH** const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS* const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH* const prach_vars = &gNB->prach_vars;
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
int i, UE_id;
@@ -290,6 +309,9 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(common_vars->txdataF);
free_and_zero(common_vars->rxdataF);
// PDCCH DMRS sequences
free_and_zero(pdcch_dmrs);
// Channel estimates for SRS
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
for (i=0; i<64; i++) {
+23 -9
View File
@@ -34,6 +34,9 @@
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.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"
#include "openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h"
//uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
@@ -324,6 +327,7 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
}
}
void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id)
{
@@ -341,6 +345,7 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n
memcpy((void*)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int));
}
*/
#if defined(Rel10) || defined(Rel14)
void phy_config_dedicated_scell_ue(uint8_t Mod_id,
@@ -352,17 +357,17 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
}
#endif
void phy_config_harq_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
uint16_t max_harq_tx )
{
PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
}
extern uint16_t beta_cqi[16];
/*
void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
struct PhysicalConfigDedicated *physicalConfigDedicated )
{
@@ -660,8 +665,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
//LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
//phy_init_nr_top(&ue->frame_parms);
//nr_init_frame_parms_ue(&ue->frame_parms);
nr_init_frame_parms_ue(&ue->frame_parms);
phy_init_nr_top(ue);
// many memory allocation sizes are hard coded
AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" );
@@ -907,8 +912,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
return 0;
}
/*
void nr_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) {
void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
int i,j,k;
@@ -929,14 +935,17 @@ void nr_lte_ue_transport(PHY_VARS_UE *ue,int 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->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);
}*/
void phy_init_nr_top(NR_DL_FRAME_PARMS *frame_parms)
void phy_init_nr_top(PHY_VARS_NR_UE *ue)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_DLSCH_t *dlsch0 = ue->dlsch[0][0][0];
dlsch0 =(NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
crcTableInit();
@@ -962,7 +971,12 @@ void phy_init_nr_top(NR_DL_FRAME_PARMS *frame_parms)
generate_ul_reference_signal_sequences(SHRT_MAX);
// Polar encoder init for PBCH
nr_polar_init(&frame_parms->pbch_polar_params, 1);
//nr_polar_init(&frame_parms->pbch_polar_params, 1);
/*t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&ue->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
//lte_sync_time_init(frame_parms);
+17 -2
View File
@@ -40,7 +40,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB, Ncp);
#endif
if (Ncp == EXTENDED)
if (Ncp == NFAPI_CP_EXTENDED)
AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);
switch(mu) {
@@ -139,7 +139,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
AssertFatal(1==0,"Invalid numerology index %d", mu);
}
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe;
frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe;
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP;
@@ -148,6 +148,14 @@ int nr_init_frame_parms(nfapi_nr_config_request_t* config,
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
frame_parms->freq_range = (frame_parms->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
// Initial bandwidth part configuration -- full carrier bandwidth
frame_parms->initial_bwp_dl.bwp_id = 0;
frame_parms->initial_bwp_dl.scs = frame_parms->subcarrier_spacing;
frame_parms->initial_bwp_dl.location = 0;
frame_parms->initial_bwp_dl.N_RB = N_RB;
frame_parms->initial_bwp_dl.cyclic_prefix = Ncp;
frame_parms->initial_bwp_dl.ofdm_symbol_size = frame_parms->ofdm_symbol_size;
return 0;
}
@@ -276,6 +284,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms)
frame_parms->samples_per_subframe = 30720 * frame_parms->ttis_per_subframe;
//frame_parms->first_carrier_offset = 2048-600;
frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe;
frame_parms->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe;
frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP;
@@ -298,4 +307,10 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms)
LOG_I(PHY,"frame_parms->samples_per_frame_wCP=%d\n",frame_parms->samples_per_frame_wCP);
LOG_I(PHY,"frame_parms->samples_per_subframe=%d\n",frame_parms->samples_per_subframe);
LOG_I(PHY,"frame_parms->samples_per_frame=%d\n",frame_parms->samples_per_frame);
LOG_I(PHY,"frame_parms->initial_bwp_dl.bwp_id=%d\n",frame_parms->initial_bwp_dl.bwp_id);
LOG_I(PHY,"frame_parms->initial_bwp_dl.scs=%d\n",frame_parms->initial_bwp_dl.scs);
LOG_I(PHY,"frame_parms->initial_bwp_dl.N_RB=%d\n",frame_parms->initial_bwp_dl.N_RB);
LOG_I(PHY,"frame_parms->initial_bwp_dl.cyclic_prefix=%d\n",frame_parms->initial_bwp_dl.cyclic_prefix);
LOG_I(PHY,"frame_parms->initial_bwp_dl.location=%d\n",frame_parms->initial_bwp_dl.location);
LOG_I(PHY,"frame_parms->initial_bwp_dl.ofdm_symbol_size=%d\n",frame_parms->initial_bwp_dl.ofdm_symbol_size);
}
+2
View File
@@ -56,6 +56,8 @@ int l1_north_init_eNB(void);
*/
int phy_init_top(LTE_DL_FRAME_PARMS *frame_parms);
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
/*!
\brief Allocate and Initialize the PHY variables relevant to the LTE ue signal buffers.
+6 -1
View File
@@ -224,7 +224,12 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a
proc->frame_tx, proc->subframe_tx, rel8->rnti);
}
void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu)
void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
int frame,
int subframe,
eNB_rxtx_proc_t *proc,
DCI_ALLOC_t *dci_alloc,
nfapi_dl_config_dci_dl_pdu *pdu)
{
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
+3 -2
View File
@@ -115,7 +115,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned short nb_rb_pdsch)
{
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,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;
typedef int array_of_w[2];
@@ -196,7 +197,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
{
uint8_t idx=0;
uint8_t pdcch_rb_offset =0;
//uint8_t pdcch_rb_offset =0;
//nr_gold_pdcch += ((int)floor(ue->frame_parms.ssb_start_subcarrier/12)+pdcch_rb_offset)*3/32;
if (p==2000) {
+30 -20
View File
@@ -19,16 +19,16 @@
* contact@openairinterface.org
*/
#include "defs.h"
#include "nr_refsig.h"
void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
{
unsigned int n, x1, x2;
unsigned int x1, x2;
unsigned char Nid, i_ssb, i_ssb2;
unsigned char Lmax, l, n_hf, N_hf;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
uint8_t reset;
Nid = cfg->sch_config.physical_cell_id.value;
@@ -36,32 +36,42 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
N_hf = (Lmax == 4)? 2:1;
for (n_hf = 0; n_hf < N_hf; n_hf++) {
for (l = 0; l < Lmax ; l++) {
i_ssb = l & (Lmax-1);
i_ssb2 = (i_ssb<<2) + n_hf;
x1 = 1 + (1<<31);
reset = 1;
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
x2 = x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
// skip first 50 double words (1600 bits)
for (n = 1; n < 50; n++) {
x1 = (x1>>1) ^ (x1>>4);
x1 = x1 ^ (x1<<31) ^ (x1<<28);
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
}
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; 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);
gNB->nr_gold_pbch_dmrs[n_hf][l][n] = x1 ^ x2;
for (uint8_t n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
gNB->nr_gold_pbch_dmrs[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
}
}
}
void nr_init_pdcch_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 ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
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);
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);
reset = 0;
}
}
}
}
@@ -21,15 +21,22 @@
/* Definitions for LTE Reference signals */
/* Author R. Knopp / EURECOM / OpenAirInterface.org */
#ifndef __NR_REFSIG_DEFS__H__
#define __NR_REFSIG_DEFS__H__
#ifndef __NR_REFSIG__H__
#define __NR_REFSIG__H__
#include "PHY/defs_gNB.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/
void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
@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);
#endif
+213 -25
View File
@@ -20,7 +20,7 @@
*/
/*! \file PHY/NR_TRANSPORT/nr_dci.c
* \brief Implements DCI encoding/decoding (38.212/38.213/38.214). Current NR compliance V15.1 2018-06.
* \brief Implements DCI encoding/decoding and PDCCH TX/RX procedures (38.212/38.213/38.214). V15.2.0 2018-06.
* \author Guy De Souza
* \date 2018
* \version 0.1
@@ -32,25 +32,32 @@
#include "nr_dci.h"
uint8_t nr_get_dci_size(nr_dci_format_e format,
nr_rnti_type_e rnti,
//#define DEBUG_PDCCH_DMRS
//#define DEBUG_DCI
//#define DEBUG_CHANNEL_CODING
#define PDCCH_TEST_POLAR_TEMP_FIX
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
NR_BWP_PARMS* bwp,
nfapi_nr_config_request_t* config)
{
uint8_t size = 0;
uint16_t size = 0;
uint16_t N_RB = bwp->N_RB;
switch(format) {
case nr_dci_format_0_0:
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 --16
size += 16;
size += ceil( log2( (N_RB*(N_RB+1))>>2 ) ); // Freq domain assignment -- hopping scenario to be updated
// Time domain assignment
// UL/SUL indicator
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
case NFAPI_NR_UL_DCI_FORMAT_0_0:
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
size += 20;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, bwp, config) - size; // Padding to match 1_0 size
// UL/SUL indicator assumed to be 0
break;
case nr_dci_format_0_1:
case NFAPI_NR_UL_DCI_FORMAT_0_1:
/// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, SRS request 2 --17
size += 17;
// Carrier indicator
@@ -72,14 +79,14 @@ uint8_t nr_get_dci_size(nr_dci_format_e format,
// DMRS sequence init
break;
case nr_dci_format_1_0:
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 --24
size += 24;
size += ceil( log2( (N_RB*(N_RB+1))>>2 ) ); // Freq domain assignment
// Time domain assignment
case NFAPI_NR_DL_DCI_FORMAT_1_0:
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
size += 28;
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
break;
case nr_dci_format_1_1:
case NFAPI_NR_DL_DCI_FORMAT_1_1:
// Carrier indicator
size += 1; // Format identifier
// BWP Indicator
@@ -106,16 +113,16 @@ uint8_t nr_get_dci_size(nr_dci_format_e format,
break;
case nr_dci_format_2_0:
case NFAPI_NR_DL_DCI_FORMAT_2_0:
break;
case nr_dci_format_2_1:
case NFAPI_NR_DL_DCI_FORMAT_2_1:
break;
case nr_dci_format_2_2:
case NFAPI_NR_DL_DCI_FORMAT_2_2:
break;
case nr_dci_format_2_3:
case NFAPI_NR_DL_DCI_FORMAT_2_3:
break;
default:
@@ -125,12 +132,193 @@ uint8_t nr_get_dci_size(nr_dci_format_e format,
return size;
}
void nr_pdcch_scrambling(uint32_t *in,
uint8_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out) {
uint8_t nr_generate_dci_top(NR_DCI_ALLOC_t dci_alloc,
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
x2 = (n_RNTI<<16) + Nid;
for (int i=0; i<size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
*out ^= (((*in)>>i)&1) ^ ((s>>i)&1);
}
}
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t** txdataF,
int16_t amp,
NR_DL_FRAME_PARMS* frame_parms,
nfapi_nr_config_request_t* config)
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config)
{
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1]; // 3 for the max coreset duration
uint8_t idx=0;
uint16_t a;
int k,l,k_prime,dci_idx, dmrs_idx;
nr_cce_t cce;
nr_reg_t reg;
nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
/*First iteration: single DCI*/
NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0];
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
uint16_t dmrs_length = dci_alloc.L*36; //2(QPSK)*3(per RB)*6(REG per CCE)
uint16_t encoded_length = dci_alloc.L*108; //2(QPSK)*9(per RB)*6(REG per CCE)
/*The coreset is initialised
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset
* in time: by its first slot and its first symbol*/
uint16_t cset_start_sc = frame_parms.first_carrier_offset + ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*NR_NB_SC_PER_RB;
uint8_t cset_start_symb = pdcch_params.first_slot*frame_parms.symbols_per_slot + pdcch_params.first_symbol;
uint8_t cset_nsymb = pdcch_params.n_symb;
dci_idx = 0;
/// DMRS QPSK modulation
/*There is a need to shift from which index the pregenerated DMRS sequence is used
* see 38211 r15.2.0 section 7.4.1.3.2: assumption is the reference point for k refers to the DMRS sequence*/
if (pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
gold_pdcch_dmrs += ((int)floor(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_params.rb_offset)*3/32;
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_params.n_symb; symb++) {
for (int i=0; i<dmrs_length>>1; i++) {
idx = ((((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
mod_dmrs[symb][i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dmrs[symb][(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_PDCCH_DMRS
printf("symb %d i %d idx %d gold seq %u b0-b1 %d-%d mod_dmrs %d %d\n", symb, i, idx, gold_pdcch_dmrs[symb][(i<<1)>>5],
(((gold_pdcch_dmrs[symb][(i<<1)>>5])>>((i<<1)&0x1f))&1), (((gold_pdcch_dmrs[symb][((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1),
mod_dmrs[symb][(i<<1)], mod_dmrs[symb][(i<<1)+1]);
#endif
}
}
/// DCI payload processing
// CRC attachment + Scrambling + Channel coding + Rate matching
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
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;
#ifdef PDCCH_TEST_POLAR_TEMP_FIX
t_nrPolar_paramsPtr currentPtr = NULL;//, polarParams = NULL;
nr_polar_init(&currentPtr, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
// t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
#else
nr_polar_init(nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
t_nrPolar_paramsPtr currentPtr = nr_polar_params(*nrPolar_params, NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
#endif
polar_encoder_dci(dci_alloc.dci_pdu, encoder_output, currentPtr, pdcch_params.rnti);
#ifdef DEBUG_CHANNEL_CODING
printf("DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_alloc.dci_pdu[0], dci_alloc.dci_pdu[1], dci_alloc.dci_pdu[2], dci_alloc.dci_pdu[3]);
printf("Encoded Payload: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
encoder_output[0], encoder_output[1], encoder_output[2], encoder_output[3]);
#endif
/// Scrambling
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD];
nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output);
// QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
for (int i=0; i<encoded_length>>1; i++) {
idx = ((((scrambled_output[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((scrambled_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
mod_dci[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_dci[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1];
#ifdef DEBUG_DCI
printf("i %d idx %d b0-b1 %d-%d mod_dci %d %d\n", i, idx, (((encoder_output[(i<<1)>>5])>>((i<<1)&0x1f))&1),
(((encoder_output[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), mod_dci[(i<<1)], mod_dci[(i<<1)+1]);
#endif
}
/// Resource mapping
a = (config.rf_config.tx_antenna_ports.value == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15;
for (int aa = 0; aa < config.rf_config.tx_antenna_ports.value; aa++)
{
if (cset_start_sc >= frame_parms.ofdm_symbol_size)
cset_start_sc -= frame_parms.ofdm_symbol_size;
/*Reorder REG list for a freq first mapping*/
uint8_t symb_idx[NR_MAX_CSET_DURATION] = {0,0,0};
uint8_t nb_regs = dci_alloc.L*NR_NB_REG_PER_CCE;
uint8_t regs_per_symb = nb_regs/cset_nsymb;
for (int cce_idx=0; cce_idx<dci_alloc.L; cce_idx++){
cce = dci_alloc.cce_list[cce_idx];
for (int reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = cce.reg_list[reg_idx];
reg_mapping_list[reg.symb_idx*regs_per_symb + symb_idx[reg.symb_idx]++] = reg;
}
}
#ifdef DEBUG_DCI
printf("\n Ordered REG list:\n");
for (int i=0; i<nb_regs; i++)
printf("%d\t",reg_mapping_list[i].reg_idx );
printf("\n");
#endif
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_ALL_CONTIGUOUS_RBS) {
/*in this case the DMRS are mapped on all the coreset*/
for (l=cset_start_symb; l<cset_start_symb+ cset_nsymb; l++) {
dmrs_idx = 0;
k = cset_start_sc + 1;
while (dmrs_idx<3*pdcch_params.n_rb) {
((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
k+=4;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
dmrs_idx++;
}
}
}
/*Now mapping the encoded DCI based on newly constructed REG list
* and the DMRS for the precoder granularity same as REG bundle*/
for (int reg_idx=0; reg_idx<nb_regs; reg_idx++) {
reg = reg_mapping_list[reg_idx];
k = cset_start_sc + reg.start_sc_idx;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
l = cset_start_symb + reg.symb_idx;
dmrs_idx = (reg.reg_idx/cset_nsymb)*3;
k_prime = 0;
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped
if (pdcch_params.precoder_granularity == NFAPI_NR_CSET_SAME_AS_REG_BUNDLE) {
((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dmrs[l][dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
k_prime++;
dmrs_idx++;
}
}
else { // DCI payload
((int16_t*)txdataF[aa])[(l*frame_parms.ofdm_symbol_size + k)<<1] = (a * mod_dci[dci_idx<<1]) >> 15;
((int16_t*)txdataF[aa])[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (a * mod_dci[(dci_idx<<1) + 1]) >> 15;
dci_idx++;
}
k++;
if (k >= frame_parms.ofdm_symbol_size)
k -= frame_parms.ofdm_symbol_size;
}
}
}
#ifdef DEBUG_DCI
write_output("txdataF_dci.m", "txdataF_dci", txdataF[0], frame_parms.samples_per_frame_wCP>>1, 1, 1);
#endif
return 0;
}
+26 -7
View File
@@ -22,19 +22,38 @@
#ifndef __PHY_NR_TRANSPORT_DCI__H
#define __PHY_NR_TRANSPORT_DCI__H
#include "defs_gNB.h"
#include "PHY/defs_gNB.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
typedef unsigned __int128 uint128_t;
uint8_t nr_get_dci_size(nr_dci_format_e format,
nr_rnti_type_e rnti,
NR_BWP_PARMS bwp,
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
NR_BWP_PARMS* bwp,
nfapi_nr_config_request_t* config);
uint8_t nr_generate_dci_top(NR_DCI_ALLOC_t dci_alloc,
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
t_nrPolar_paramsPtr *nrPolar_params,
uint32_t **gold_pdcch_dmrs,
int32_t** txdataF,
int16_t amp,
NR_DL_FRAME_PARMS* frame_parms,
nfapi_nr_config_request_t* config)
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config);
void nr_pdcch_scrambling(uint32_t *in,
uint8_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame,
int subframe,
gNB_rxtx_proc_t *proc,
NR_gNB_DCI_ALLOC_t *dci_alloc,
nfapi_nr_dl_config_request_pdu_t *pdu);
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m);
#endif //__PHY_NR_TRANSPORT_DCI__H
+170
View File
@@ -0,0 +1,170 @@
/*
* 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_dci_tools.c
* \brief
* \author
* \date 2018
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
#include "nr_dci.h"
void nr_fill_cce_list(NR_gNB_DCI_ALLOC_t* dci_alloc, uint16_t n_shift, uint8_t m) {
nr_cce_t* cce;
nr_reg_t* reg;
nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params = &dci_alloc->pdcch_params;
uint8_t L = dci_alloc->L;
uint8_t bsize = pdcch_params->reg_bundle_size;
uint8_t R = pdcch_params->interleaver_size;
uint16_t N_reg = pdcch_params->n_rb * pdcch_params->n_symb;
uint16_t Y, N_cce, M_s_max, n_CI=0, tmp, C;
if (pdcch_params->config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)
AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L);
N_cce = N_reg / NR_NB_REG_PER_CCE;
/*Max number of candidates per aggregation level -- SIB1 configured search space only*/
M_s_max = (L==4)?4:(L==8)?2:1;
if (pdcch_params->search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_COMMON)
Y = 0;
else { //NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC
}
uint8_t cond = N_reg%(bsize*R);
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)));
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++) {
cce = &dci_alloc->cce_list[cce_idx];
cce->cce_idx = tmp + cce_idx;
LOG_D(PHY, "cce_idx %d\n", cce->cce_idx);
if (pdcch_params->cr_mapping_type == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) {
LOG_D(PHY, "Interleaved CCE to REG mapping\n");
uint8_t j = cce->cce_idx, j_prime;
uint8_t r,c,idx;
for (uint8_t bundle_idx=0; bundle_idx<NR_NB_REG_PER_CCE/bsize; bundle_idx++) {
j_prime = 6*j/bsize + bundle_idx;
r = j_prime%R;
c = (j_prime-r)/R;
idx = (r*C + c + n_shift)%(N_reg/bsize);
LOG_D(PHY, "bundle idx = %d \n j = %d \t j_prime = %d \t r = %d \t c = %d\n", idx, j , j_prime, r, c);
for (uint8_t reg_idx=0; reg_idx<bsize; reg_idx++) {
reg = &cce->reg_list[reg_idx];
reg->reg_idx = bsize*idx + reg_idx;
reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB;
reg->symb_idx = reg->reg_idx % pdcch_params->n_symb;
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
}
}
}
else { // NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
LOG_D(PHY, "Non interleaved CCE to REG mapping\n");
for (uint8_t reg_idx=0; reg_idx<NR_NB_REG_PER_CCE; reg_idx++) {
reg = &cce->reg_list[reg_idx];
reg->reg_idx = cce->cce_idx*NR_NB_REG_PER_CCE + reg_idx;
reg->start_sc_idx = (reg->reg_idx/pdcch_params->n_symb) * NR_NB_SC_PER_RB;
reg->symb_idx = reg->reg_idx % pdcch_params->n_symb;
LOG_D(PHY, "reg %d symbol %d start subcarrier %d\n", reg->reg_idx, reg->symb_idx, reg->start_sc_idx);
}
}
}
}
void nr_fill_dci_and_dlsch(PHY_VARS_gNB *gNB,
int frame,
int subframe,
gNB_rxtx_proc_t *proc,
NR_gNB_DCI_ALLOC_t *dci_alloc,
nfapi_nr_dl_config_request_pdu_t *pdu)
{
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
uint8_t n_shift;
uint32_t *dci_pdu = dci_alloc->dci_pdu;
memset((void*)dci_pdu,0,4*sizeof(uint32_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_config_request_t *cfg = &gNB->gNB_config;
uint16_t N_RB = fp->initial_bwp_dl.N_RB;
uint8_t fsize=0, pos=0, cand_idx=0;
/// 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:
// Freq domain assignment
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)<<pos++;
// Time domain assignment
for (int i=0; i<4; i++)
*dci_pdu |= ((pdu_rel15->time_domain_assignment>>(3-i))&1)<<pos++;
// VRB to PRB mapping
*dci_pdu |= (pdu_rel15->vrb_to_prb_mapping&1)<<pos++;
// MCS
for (int i=0; i<5; i++)
*dci_pdu |= ((pdu_rel15->mcs>>(4-i))&1)<<pos++;
// TB scaling
for (int i=0; i<2; i++)
*dci_pdu |= ((pdu_rel15->tb_scaling>>(1-i))&1)<<pos++;
break;
}
break;
case NFAPI_NR_UL_DCI_FORMAT_0_0:
break;
}
LOG_I(PHY, "DCI PDU: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n",
dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
/// rest of DCI alloc
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,
dci_alloc->pdcch_params.rnti_type,
&fp->initial_bwp_dl,
cfg);
n_shift = (dci_alloc->pdcch_params.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)?
cfg->sch_config.physical_cell_id.value : dci_alloc->pdcch_params.shift_index;
nr_fill_cce_list(dci_alloc, n_shift, cand_idx);
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);
}
+24 -36
View File
@@ -137,28 +137,24 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t bitwise)
uint8_t encoded)
{
uint8_t reset, offset;
uint32_t x1, x2, s=0;
uint8_t *pbch_e = pbch->pbch_e;
uint32_t *pbch_a_prime = (uint32_t*)pbch->pbch_a_prime;
uint32_t *pbch_a_interleaved = (uint32_t*)pbch->pbch_a_interleaved;
uint32_t *pbch_e = pbch->pbch_e;
uint32_t unscrambling_mask = 0x100006D;
reset = 1;
// x1 is set in lte_gold_generic
x2 = Nid;
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
for (int i=0; i<(uint16_t)ceil((nushift*M)/32); i++) {
s = lte_gold_generic(&x1, &x2, reset);
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
// Scrambling is now done with offset (nushift*M)%32
offset = (nushift*M)&0x1f;
#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling params: nushift %d M %d length %d bitwise %d offset %d\n", nushift, M, length, bitwise, offset);
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
#endif
for (int i=0; i<length; i++) {
@@ -169,12 +165,11 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
#ifdef DEBUG_PBCH_ENCODING
printf("s: %04x\t", s);
#endif
if (bitwise) {
(*pbch_a_prime) ^= ((unscrambling_mask>>i)&1)? (((*pbch_a_interleaved)>>i)&1)<<i : ((((*pbch_a_interleaved)>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
}
if (!encoded)
pbch->pbch_a_prime ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_interleaved>>i)&1)<<i : (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
else
pbch_e[i] = (pbch_e[i]&1) ^ ((s>>((i+offset)&0x1f))&1);
pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f));
}
}
@@ -200,6 +195,7 @@ uint8_t nr_pbch_payload_interleaver(uint8_t i) {
// 29,31,16,23,18,17,8,30,10,6,24,7,0,5,3,2};
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
int32_t **txdataF,
int16_t amp,
@@ -224,6 +220,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
LOG_I(PHY, "PBCH generation started\n");
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
///Payload generation
// Fix byte endian
if (!(sfn&7))
@@ -258,59 +255,50 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
in |= (uint32_t)(pbch->pbch_a[i]<<((3-i)<<3));
for (int i=0; i<32; i++) {
out |= ((in>>i)&1)<<(nr_pbch_payload_interleaver(i));//nr_pbch_payload_interleaving_pattern[i]
pbch->pbch_a_interleaved |= ((in>>i)&1)<<(nr_pbch_payload_interleaver(i));//nr_pbch_payload_interleaving_pattern[i]
#ifdef DEBUG_PBCH_ENCODING
printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) %d\n", i, in, out, nr_pbch_payload_interleaver(i), (in>>i)&1);
printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) %d\n", i, in, pbch->pbch_a_interleaved, nr_pbch_payload_interleaver(i), (in>>i)&1);
#endif
}
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
pbch->pbch_a_interleaved[i] = (uint8_t)((out>>(i<<3))&0xff);
#ifdef DEBUG_PBCH_ENCODING
printf("Interleaving:\n");
for (int i=0; i<4; i++)
printf("pbch_a_interleaved[%d]: 0x%02x\n", i, pbch->pbch_a_interleaved[i]);
printf("pbch_a_interleaved: 0x%08x\n", pbch->pbch_a_interleaved);
#endif
// Scrambling
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 1);
pbch->pbch_a_prime = 0;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0);
#ifdef DEBUG_PBCH_ENCODING
printf("Payload scrambling:\n");
for (int i=0; i<4; i++)
printf("pbch_a_prime[%d]: 0x%02x\n", i, pbch->pbch_a_prime[i]);
printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1);
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
#endif
//for (int m=0;m<32;m++){
//pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01);
//printf("pbch_a_b[%d] %d\n", m, pbch_a_b[m] );
//}
/// CRC, coding and rate matching
polar_encoder (pbch->pbch_a_prime, pbch->pbch_e, &frame_parms->pbch_polar_params);
polar_encoder (&pbch->pbch_a_prime, pbch->pbch_e, polar_params);
#ifdef DEBUG_PBCH_ENCODING
printf("Channel coding:\n");
for (int i=0; i<NR_POLAR_PBCH_E>>3; i++)
printf("pbch_e[%d]: 0x%02x\t", i, pbch->pbch_e[i]);
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// Scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 0);
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1);
#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PBCH_E>>3; i++)
printf("pbch_e[%d]: 0x%02x\t", i, pbch->pbch_e[i]);
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
printf("pbch_e[%d]: 0x%08x\t", i, pbch->pbch_e[i]);
printf("\n");
#endif
/// QPSK modulation
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++){
idx = ((pbch->pbch_e[i<<1]&1)<<1) ^ (pbch->pbch_e[(i<<1)+1]&1);
idx = (((pbch->pbch_e[(i<<1)>>5]>>((i<<1)&0x1f))&1)<<1) ^ ((pbch->pbch_e[((i<<1)+1)>>5]>>(((i<<1)+1)&0x1f))&1);
mod_pbch_e[i<<1] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1];
mod_pbch_e[(i<<1)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1];
-35
View File
@@ -1,35 +0,0 @@
/*
* 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_pdcch.c
* \brief Implements PDCCH physical channel TX/RX procedures (38.211). Current NR compliance V15.1 2018-06.
* \author Guy De Souza
* \date 2018
* \version 0.1
* \company Eurecom
* \email: desouza@eurecom.fr
* \note
* \warning
*/
#include "nr_dci.h"
+2 -1
View File
@@ -75,7 +75,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t bitwise);
uint8_t encoded);
/*!
\fn int nr_generate_pbch
@@ -84,6 +84,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
@returns 0 on success
*/
int nr_generate_pbch(NR_gNB_PBCH *pbch,
t_nrPolar_paramsPtr polar_params,
uint8_t *pbch_pdu,
int32_t **txdataF,
int16_t amp,
@@ -326,10 +326,17 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
ch,
dl_ch,
16);
#ifdef DEBUG_CH
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
pil+=2;
rxF+=8;
dl_ch+=24;
k+=12;
for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -49,8 +49,8 @@ struct NR_DCI_INFO_EXTRACTED {
uint8_t sul_ind_0_1 ; // 2 SUL_IND_0_1:
uint8_t slot_format_ind ; // 3 SLOT_FORMAT_IND: size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213]
uint8_t pre_emption_ind ; // 4 PRE_EMPTION_IND: size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits
uint8_t tpc_cmd_number ; // 5 TPC_CMD_NUMBER: The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits
uint8_t block_number ; // 6 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
uint8_t block_number ; // 5 BLOCK_NUMBER: starting position of a block is determined by the parameter startingBitOfFormat2_3
uint8_t close_loop_ind ; // 6 CLOSE_LOOP_IND:
uint8_t bandwidth_part_ind ; // 7 BANDWIDTH_PART_IND:
uint8_t short_message_ind ; // 8 SHORT_MESSAGE_IND:
uint8_t short_messages ; // 9 SHORT_MESSAGES:
@@ -93,7 +93,7 @@ struct NR_DCI_INFO_EXTRACTED {
uint8_t antenna_ports ; // 38 ANTENNA_PORTS:
uint8_t tci ; // 39 TCI: 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits
uint8_t srs_request ; // 40 SRS_REQUEST:
uint8_t tpc_cmd_number_format2_3 ; // 41 TPC_CMD_NUMBER_FORMAT2_3:
uint8_t tpc_cmd ; // 41 TPC_CMD:
uint8_t csi_request ; // 42 CSI_REQUEST:
uint8_t cbgti ; // 43 CBGTI: 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH
uint8_t cbgfi ; // 44 CBGFI: 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator
File diff suppressed because it is too large Load Diff
+19 -29
View File
@@ -32,11 +32,11 @@
#include "PHY/types.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "nr_transport_proto_ue.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
//#include "defs.h"
//#include "extern.h"
#include "common_lib.h"
@@ -45,20 +45,16 @@
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
extern openair0_config_t openair0_cfg[];
static nfapi_nr_config_request_t config_t;
static nfapi_nr_config_request_t* config =&config_t;
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
int cnt=0;
/* forward declarations */
void set_default_frame_parms_single(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms);
//#define DEBUG_INITIAL_SYNCH
int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
{
printf("nr pbch detec RB_DL %d\n", ue->frame_parms.N_RB_DL);
uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
char phich_resource[6];
int ret =-1;
#ifdef DEBUG_INITIAL_SYNCH
@@ -98,23 +94,15 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
pbch_decoded = 0;
printf("pbch_detection nid_cell %d\n",frame_parms->Nid_cell);
//for (frame_mod4=0; frame_mod4<4; frame_mod4++) {
ret = nr_rx_pbch(ue,
&ue->proc.proc_rxtx[0],
ue->pbch_vars[0],
frame_parms,
0,
SISO,
ue->high_speed_flag,
frame_mod4);
pbch_decoded = 0; //to be updated
// break;
//}
ue->high_speed_flag);
if (ret==0) {
@@ -156,18 +144,18 @@ char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
{
int32_t sync_pos, sync_pos2, k_ssb, N_ssb_crb, sync_pos_slot;
int32_t sync_pos, sync_pos2, sync_pos_slot; // k_ssb, N_ssb_crb,
int32_t metric_fdd_ncp=0;
uint8_t phase_fdd_ncp;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int ret=-1;
int aarx,rx_power=0;
int rx_power=0; //aarx,
//nfapi_nr_config_request_t* config;
/*offset parameters to be updated from higher layer */
k_ssb =0;
N_ssb_crb = 0;
//k_ssb =0;
//N_ssb_crb = 0;
/*#ifdef OAI_USRP
__m128i *rxdata128;
@@ -176,7 +164,6 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
// First try FDD normal prefix
frame_parms->Ncp=NORMAL;
frame_parms->frame_type=TDD;
set_default_frame_parms_single(config,frame_parms);
nr_init_frame_parms_ue(frame_parms);
LOG_D(PHY,"nr_initial sync ue RB_DL %d\n", ue->frame_parms.N_RB_DL);
/*
@@ -197,8 +184,9 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
* sync_pos SS/PBCH block
*/
cnt++;
if (1){
if (1){ // (cnt>100)
cnt =0;
/* process pss search on received buffer */
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
@@ -235,16 +223,18 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
rx_sss_nr(ue,&metric_fdd_ncp,&phase_fdd_ncp);
//set_default_frame_parms_single(config,&ue->frame_parms);
nr_init_frame_parms_ue(config,&ue->frame_parms);
nr_init_frame_parms_ue(&ue->frame_parms);
nr_gold_pbch(ue);
ret = nr_pbch_detection(ue,mode);
nr_gold_pdcch(ue,0, 2);
nr_slot_fep(ue,0, 0, ue->rx_offset, 1, 1, NR_PDCCH_EST);
nr_slot_fep(ue,1, 0, ue->rx_offset, 1, 1, NR_PDCCH_EST);
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = 0;
nr_slot_fep(ue,0, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST);
nr_slot_fep(ue,1, 0, ue->rx_offset, 0, 1, NR_PDCCH_EST);
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
ue->Mod_id,
+41 -68
View File
@@ -33,7 +33,7 @@
#include "PHY/CODING/coding_extern.h"
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/sse_intrin.h"
//#include "SIMULATION/TOOLS/sim.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#define DEBUG_PBCH 1
//#define DEBUG_PBCH_ENCODING
@@ -396,12 +396,12 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
uint16_t length,
uint8_t bitwise)
{
int i;
uint8_t reset, offset;
uint32_t x1, x2, s=0;
int16_t *demod_pbch_e = pbch->llr;
uint32_t *pbch_a_prime = (uint32_t*)pbch->pbch_a_prime;
uint32_t *pbch_a_interleaved = (uint32_t*)pbch->pbch_a_interleaved;
uint32_t unscrambling_mask = 0x100006D;
printf("unscramb nid_cell %d\n",Nid);
@@ -411,7 +411,7 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
x2 = Nid; //this is c_init
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
for (int i=0; i<(uint16_t)ceil((nushift*M)/32); i++) {
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
@@ -426,9 +426,11 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
#ifdef DEBUG_PBCH_ENCODING
if (i<8)
printf("s: %04x\t", s);
printf("pbch_a_interleaved 0x%08x\n", pbch->pbch_a_interleaved);
#endif
if (bitwise) {
(*pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? (((*pbch_a_prime)>>i)&1)<<i : ((((*pbch_a_prime)>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
}
else {
@@ -512,8 +514,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag,
uint8_t frame_mod4)
uint32_t high_speed_flag)
{
NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
@@ -524,8 +525,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
int symbol,i;
//uint8_t pbch_a[64];
uint8_t *pbch_a = malloc(sizeof(uint8_t) * 32);
uint8_t *pbch_a_prime;
uint8_t *pbch_a_b = malloc(sizeof(uint8_t) *NR_POLAR_PBCH_PAYLOAD_BITS);
uint32_t pbch_a_prime;
int8_t *pbch_e_rx;
uint8_t *decoded_output = nr_ue_pbch_vars->decoded_output;
uint8_t nushift;
@@ -533,9 +533,6 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
uint8_t Lmax=8; //to update
uint8_t ssb_index=0;
//uint16_t crc;
//short nr_demod_table[8] = {0,0,0,1,1,0,1,1};
//double nr_demod_table[8] = {0.707,0.707,-0.707,0.707,0.707,-0.707,-0.707,-0.707};
//int16_t *demod_pbch_e; // = malloc (sizeof(int16_t) * 864);
unsigned short idx_demod =0;
int8_t decoderState=0;
uint8_t decoderListSize = 8, pathMetricAppr = 0;
@@ -546,17 +543,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
//printf("nr_pbch_ue nid_cell %d\n",frame_parms->Nid_cell);
reset_meas(&polar_decoder_init);
reset_meas(&polar_rate_matching);
reset_meas(&decoding);
reset_meas(&bit_extraction);
reset_meas(&deinterleaving);
reset_meas(&sorting);
reset_meas(&path_metric);
reset_meas(&update_LLR);
//for (int i=0; i<frame_parms->pbch_polar_params.payloadBits; i++) aPrioriArray[i] = NAN;
int subframe_rx = proc->subframe_rx;
printf("ue->current_thread_id[subframe_rx] %d subframe_rx %d\n",ue->current_thread_id[subframe_rx], subframe_rx);
pbch_e_rx = &nr_ue_pbch_vars->llr[0];
@@ -635,73 +627,59 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
pbch_e_rx = nr_ue_pbch_vars->llr;
//demod_pbch_e = nr_ue_pbch_vars->demod_pbch_e;
pbch_a = nr_ue_pbch_vars->pbch_a;
pbch_a_prime = nr_ue_pbch_vars->pbch_a_prime;
//#ifdef DEBUG_PBCH
#ifdef DEBUG_PBCH
//pbch_e_rx = &nr_ue_pbch_vars->llr[0];
short *p = (short *)&(nr_ue_pbch_vars->rxdataF_comp[0][5*20*12]);
for (int cnt = 0; cnt < 8 ; cnt++)
for (int cnt = 0; cnt < 32 ; cnt++)
printf("pbch rx llr %d rxdata_comp %d addr %p\n",*(pbch_e_rx+cnt), p[cnt], &p[0]);
//#endif
/*
for (i=0; i<NR_POLAR_PBCH_E/2; i++){
idx_demod = (sign(pbch_e_rx[i<<1])&1) ^ ((sign(pbch_e_rx[(i<<1)+1])&1)<<1);
demod_pbch_e[i<<1] = nr_demod_table[(idx_demod)<<1];
demod_pbch_e[(i<<1)+1] = nr_demod_table[((idx_demod)<<1)+1];
#ifdef DEBUG_PBCH
if (i<16){
printf("idx[%d]= %d\n", i , idx_demod);
printf("sign[%d]= %d sign[%d]= %d\n", i<<1 , sign(pbch_e_rx[i<<1]), (i<<1)+1 , sign(pbch_e_rx[(i<<1)+1]));
printf("demod_pbch_e[%d] r = %2.3f i = %2.3f\n", i<<1 , demod_pbch_e[i<<1], demod_pbch_e[(i<<1)+1]);}
#endif
}
*/
//un-scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0);
/*
//#ifdef DEBUG_PBCH
for (i=0; i<16; i++){
printf("unscrambling demod_pbch_e[%d] r = %2.3f i = %2.3f\n", i<<1 , demod_pbch_e[i<<1], demod_pbch_e[(i<<1)+1]);}
//#endif
*/
//polar decoding de-rate matching
decoderState = polar_decoder_int8_new(pbch_e_rx, pbch_a_b, &frame_parms->pbch_polar_params, decoderListSize, &polar_decoder_init,&polar_rate_matching, &decoding,&bit_extraction,&deinterleaving, &sorting,&path_metric,&update_LLR,0);
// uint32_t pbch_out;
//polar decoding de-rate matching
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);
currentPtr = nr_polar_params(nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);
decoderState = polar_decoder_int16(pbch_e_rx,&nr_ue_pbch_vars->pbch_a_prime,currentPtr);
printf("polar decoder state %d\n", decoderState);
if(decoderState == -1)
return(decoderState);
memset(&pbch_a_prime[0], 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS>>3);
for (i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
{
pbch_a_prime[i/8] ^= (pbch_a_b[i]&1)<<(i&7);
//printf("pbch_a_b[%d] = %u pbch_a_prime[i/8] 0x%02x \n", i,pbch_a_b[i],pbch_a_prime[i/8]);
}
//#ifdef DEBUG_PBCH
for (i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
printf("pbch_a_prime[%d] = 0x%02x\n", i,pbch_a_prime[i]);
//#endif
//printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
//payload un-scrambling
memset(nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS>>3);
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = ((pbch_a_prime[0]>>6)&1) ^ (((pbch_a_prime[3])&1)<<1);
//printf("payload unscrambling nushift %d sfn3 %d sfn2 %d M %d\n",nushift, ((pbch_a_prime[0]>>6)&1),((pbch_a_prime[3])&1),M);
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>6)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>24)&1)<<1);
printf("payload unscrambling nushift %d sfn3 %d sfn2 %d M %d\n",nushift, ((nr_ue_pbch_vars->pbch_a_prime>>6)&1),((nr_ue_pbch_vars->pbch_a_prime>>24)&1),M);
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1);
//payload deinterleaving
uint32_t in=0, out=0;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
in |= (uint32_t)(nr_ue_pbch_vars->pbch_a_interleaved[i]<<(i<<3));
//uint32_t in=0;
uint32_t out=0;
for (int i=0; i<32; i++) {
out |= ((in>>i)&1)<<(pbch_deinterleaving_pattern[i]);
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
#ifdef DEBUG_PBCH
printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) 0x%08x\n", i, in, out, pbch_deinterleaving_pattern[i], (in>>i)&1);
// printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) 0x%08x\n", i, nr_ue_pbch_vars->pbch_a_interleaved, out, pbch_deinterleaving_pattern[i], (in>>i)&1);
#endif
}
@@ -711,7 +689,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
// Fix byte endian
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++)
decoded_output[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_a[i];
//#ifdef DEBUG_PBCH
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
//printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
@@ -735,8 +713,3 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
return 0;
}
@@ -1072,13 +1072,13 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
/*! \brief receiver for the PBCH
\returns number of tx antennas or -1 if error
*/
uint16_t rx_pbch(NR_UE_COMMON *lte_ue_common_vars,
NR_UE_PBCH *lte_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag,
uint8_t frame_mod4);
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
NR_UE_PBCH *nr_ue_pbch_vars,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
MIMO_mode_t mimo_mode,
uint32_t high_speed_flag);
uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t eNB_id,
+10 -3
View File
@@ -155,6 +155,11 @@ typedef struct {
// int calibration_flag;
/// Number of soft channel bits
uint32_t G;
// number of symbols
uint8_t nb_symbols;
// first symbol in the slot
uint8_t start_symbol;
// decode phich
uint8_t decode_phich;
} NR_UL_UE_HARQ_t;
@@ -326,6 +331,8 @@ typedef struct {
uint8_t rnti_type;
/// Active flag for DLSCH demodulation
uint8_t active;
/// accumulated tx power adjustment for PUCCH
int8_t g_pucch;
/// Transmission mode
uint8_t mode1_flag;
/// amplitude of PDSCH (compared to RS) in symbols without pilots
@@ -347,7 +354,7 @@ typedef struct {
//#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 */
@@ -365,8 +372,8 @@ typedef struct {
uint8_t max_turbo_iterations;
/// number of iterations used in last turbo decoding
uint8_t last_iteration_cnt;
/// accumulated tx power adjustment for PUCCH
int8_t g_pucch;
} NR_UE_DLSCH_t;
typedef enum {format0_0,
+1 -2
View File
@@ -4568,7 +4568,6 @@ void dft2048(int16_t *x,int16_t *y,int scale)
int i;
simd256_q15_t ONE_OVER_SQRT2_Q15_128 = set1_int16_simd256(ONE_OVER_SQRT2_Q15);
write_output("dftin.m","dftin",x,2048,1,1);
xtmpp = xtmp;
@@ -4648,7 +4647,7 @@ void dft2048(int16_t *x,int16_t *y,int scale)
_mm_empty();
_m_empty();
write_output("dftout.m","dftout",y,2048,1,1);
}
void idft2048(int16_t *x,int16_t *y,int scale)
+2 -4
View File
@@ -576,7 +576,7 @@ typedef struct PHY_VARS_eNB_s {
unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX];
unsigned char first_run_I0_measurements;
unsigned char is_secondary_eNB; // primary by default
unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system.
unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created.
@@ -710,6 +710,4 @@ 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__ */
#endif // __PHY_DEFS_eNB_H__
+33 -10
View File
@@ -29,6 +29,7 @@
\note
\warning
*/
#ifndef __PHY_DEFS_GNB__H__
#define __PHY_DEFS_GNB__H__
@@ -37,13 +38,32 @@
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
typedef struct {
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint8_t pbch_a_interleaved[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint8_t pbch_a_prime[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint8_t pbch_e[NR_POLAR_PBCH_E];
uint32_t pbch_a_interleaved;
uint32_t pbch_a_prime;
uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD];
} NR_gNB_PBCH;
typedef struct {
/// Length of DCI payload in bits
uint16_t size;
/// Aggregation level
uint8_t L;
/// PDCCH parameters
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params;
/// CCE list
nr_cce_t cce_list[NR_MAX_PDCCH_AGG_LEVEL];
/// DCI pdu
uint32_t dci_pdu[4];
} NR_gNB_DCI_ALLOC_t;
typedef struct {
uint8_t num_dci;
NR_gNB_DCI_ALLOC_t dci_alloc[256];
} NR_gNB_PDCCH;
typedef struct {
/// \brief Pointers (dynamic) to the received data in the time domain.
/// - first index: rx antenna [0..nb_antennas_rx[
@@ -263,14 +283,16 @@ typedef struct PHY_VARS_gNB_s {
/// NFAPI PRACH information
nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES];
Sched_Rsp_t Sched_INFO;
LTE_eNB_PDCCH pdcch_vars[2];
LTE_eNB_PHICH phich_vars[2];
Sched_Rsp_t Sched_INFO;
NR_gNB_PDCCH pdcch_vars;
NR_gNB_PBCH pbch;
t_nrPolar_paramsPtr nrPolar_params;
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_type0_params;
LTE_eNB_PHICH phich_vars[2];
NR_gNB_COMMON common_vars;
LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
NR_gNB_PBCH pbch;
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
@@ -292,6 +314,9 @@ typedef struct PHY_VARS_gNB_s {
/// PBCH DMRS sequence
uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
/// PDCCH DMRS sequence
uint32_t ***nr_gold_pdcch_dmrs;
/// Indicator set to 0 after first SR
uint8_t first_sr[NUMBER_OF_UE_MAX];
@@ -307,7 +332,7 @@ typedef struct PHY_VARS_gNB_s {
unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX];
unsigned char first_run_I0_measurements;
unsigned char is_secondary_gNB; // primary by default
unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system.
unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created.
@@ -440,6 +465,4 @@ typedef struct PHY_VARS_gNB_s {
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
} PHY_VARS_gNB;
#endif
+16 -7
View File
@@ -603,8 +603,8 @@ typedef struct {
#define SUL_IND_0_1 2
#define SLOT_FORMAT_IND 3
#define PRE_EMPTION_IND 4
#define TPC_CMD_NUMBER 5
#define BLOCK_NUMBER 6
#define BLOCK_NUMBER 5
#define CLOSE_LOOP_IND 6
#define BANDWIDTH_PART_IND 7
#define SHORT_MESSAGE_IND 8
#define SHORT_MESSAGES 9
@@ -639,7 +639,7 @@ typedef struct {
#define ANTENNA_PORTS 38
#define TCI 39
#define SRS_REQUEST 40
#define TPC_CMD_NUMBER_FORMAT2_3 41
#define TPC_CMD 41
#define CSI_REQUEST 42
#define CBGTI 43
#define CBGFI 44
@@ -708,7 +708,7 @@ typedef struct {
} NR_UE_CORESET_CCE_REG_MAPPING_t;
typedef enum {allContiguousRBs=0,sameAsREGbundle=1} NR_UE_CORESET_precoder_granularity_t;
typedef enum {tciPresentInDCI_enabled = 1} tciPresentInDCI_t;
typedef struct {
/*
* define CORESET structure according to 38.331
@@ -747,7 +747,7 @@ typedef struct {
NR_UE_CORESET_CCE_REG_MAPPING_t cce_reg_mappingType;
NR_UE_CORESET_precoder_granularity_t precoderGranularity;
int tciStatesPDCCH;
int tciPresentInDCI;
tciPresentInDCI_t tciPresentInDCI;
uint16_t pdcchDMRSScramblingID;
uint16_t rb_offset;
} NR_UE_PDCCH_CORESET;
@@ -921,8 +921,8 @@ typedef struct {
/// - second index: ? [0..287] (hard coded)
int32_t **dl_ch_estimates_ext;
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint8_t pbch_a_interleaved[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint8_t pbch_a_prime[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
uint32_t pbch_a_interleaved;
uint32_t pbch_a_prime;
uint8_t pbch_e[NR_POLAR_PBCH_E];
int16_t demod_pbch_e[NR_POLAR_PBCH_E];
/// \brief Pointer to PBCH llrs.
@@ -1061,6 +1061,7 @@ typedef struct {
uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE];
#endif
t_nrPolar_paramsPtr nrPolar_params;
/// PBCH DMRS sequence
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
@@ -1189,6 +1190,14 @@ typedef struct {
PUCCH_Config_t pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_eNB_MAX];
PUSCH_Config_t pusch_config;
SRS_NR srs;
crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig;
supplementaryUplink_t supplementaryUplink;
dmrs_UplinkConfig_t dmrs_UplinkConfig;
dmrs_DownlinkConfig_t dmrs_DownlinkConfig;
csi_MeasConfig_t csi_MeasConfig;
PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig;
#endif
+49 -7
View File
@@ -43,6 +43,11 @@
#define MAX_NUM_SUBCARRIER_SPACING 5
#define NR_MAX_NB_RB 275
#define NR_NB_SC_PER_RB 12
#define NR_NB_REG_PER_CCE 6
#define NR_SYMBOLS_PER_SLOT 14
#define ONE_OVER_SQRT2_Q15 23170
@@ -56,10 +61,24 @@
#define NR_SSS_LENGTH 127
#define NR_PBCH_DMRS_LENGTH 144 // in mod symbols
#define NR_PBCH_DMRS_LENGTH_DWORD 10 // roundup(2(QPSK)*NR_PBCH_DMRS_LENGTH/32)
#define NR_PBCH_DMRS_LENGTH_DWORD 10 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32)
/*These max values are for the gold sequences which are generated at init for the
* full carrier bandwidth*/
#define NR_MAX_PDCCH_DMRS_INIT_LENGTH ((NR_MAX_NB_RB<<1)*3) // 3 symbols *2(QPSK)
#define NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD 52 // ceil(NR_MAX_PDCCH_DMRS_LENGTH/32)
/*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_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)
#define NR_MAX_NUM_BWP 4
#define NR_MAX_PDCCH_AGG_LEVEL 16
#define NR_MAX_CSET_DURATION 3
typedef enum {
NR_MU_0=0,
NR_MU_1,
@@ -68,6 +87,13 @@ typedef enum {
NR_MU_4,
} nr_numerology_index_e;
typedef enum {
kHz15=0,
kHz30,
kHz60,
kHz120,
kHz240
} nr_scs_e;
typedef enum{
nr_ssb_type_A = 0,
@@ -83,16 +109,31 @@ typedef enum {
} nr_frequency_range_e;
typedef struct NR_BWP_PARMS {
/// Associated numerology index
uint8_t numerology_index;
/// Freq domain location
/// BWP ID
uint8_t bwp_id;
/// Subcarrier spacing
nr_scs_e scs;
/// Freq domain location -- 1st CRB index
uint8_t location;
/// Bandwidth in PRB
uint16_t N_RB;
/// Size of FFT/IFFT
uint16_t ofdm_symbol_size;
/// Cyclic prefix
uint8_t cyclic_prefix;
} NR_BWP_PARMS;
typedef struct {
uint8_t reg_idx;
uint16_t start_sc_idx;
uint8_t symb_idx;
} nr_reg_t;
typedef struct {
uint8_t cce_idx;
nr_reg_t reg_list[NR_NB_REG_PER_CCE];
} nr_cce_t;
typedef struct NR_DL_FRAME_PARMS {
/// frequency range
nr_frequency_range_e freq_range;
@@ -137,6 +178,8 @@ typedef struct NR_DL_FRAME_PARMS {
uint16_t symbols_per_slot;
/// Number of slots per subframe
uint16_t slots_per_subframe;
/// Number of slots per frame
uint16_t slots_per_frame;
/// Number of samples in a subframe
uint32_t samples_per_subframe;
/// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
@@ -155,7 +198,6 @@ typedef struct NR_DL_FRAME_PARMS {
uint8_t ttis_per_subframe;
/// NR number of slots per tti . Assumption only 2 Slot per TTI is supported (Slot Config 1 in 38.211)
uint8_t slots_per_tti;
//#endif
/// Number of Physical transmit antennas in node
uint8_t nb_antennas_tx;
/// Number of Receive antennas in node
@@ -188,8 +230,8 @@ typedef struct NR_DL_FRAME_PARMS {
t_nrPolar_params pbch_polar_params;
//BWP params
NR_BWP_PARMS initial_bwp_params_dl;
NR_BWP_PARMS initial_bwp_params_ul;
NR_BWP_PARMS initial_bwp_dl;
NR_BWP_PARMS initial_bwp_ul;
} NR_DL_FRAME_PARMS;
+267 -7
View File
@@ -370,12 +370,104 @@ typedef struct {
/* FFS TODO_NR partial structure that should be complete */
typedef enum {
semiStatic = 0,
dynamic = 1
} pdsch_HARQ_ACK_Codebook_t;
////////////////////////////////////////////////////////////////////////////////################################
#define MAX_NR_RATE_MATCH_PATTERNS 4
#define MAX_NR_ZP_CSI_RS_RESOURCES 32
typedef enum{
dl_resourceAllocationType0 = 1,
dl_resourceAllocationType1 = 2,
dl_dynamicSwitch = 3
} dl_resourceAllocation_t;
typedef enum{
dl_rgb_config1 = 1,
dl_rgb_config2 = 2
} dl_rgb_Size_t;
typedef enum {
st_n4 = 1,
st_wideband = 2
} static_bundleSize_t;
typedef enum {
dy_1_n4 = 1,
dy_1_wideband = 2,
dy_1_n2_wideband = 3,
dy_1_n4_wideband = 4
} bundleSizeSet1_t;
typedef enum {
dy_2_n4 = 1,
dy_2_wideband = 2,
} bundleSizeSet2_t;
typedef struct{
bundleSizeSet1_t bundleSizeSet1;
bundleSizeSet2_t bundleSizeSet2;
} dynamic_bundleSize_t;
typedef struct {
static_bundleSize_t staticBundling;
dynamic_bundleSize_t dynamicBundlig;
} prb_bundleType_t;
typedef enum {
nb_code_n1 = 1,
nb_code_n2 = 2
} maxNrofCodeWordsScheduledByDCI_t;
typedef struct{
// to be defined FIXME!!!
}rateMatchPattern_t;
typedef struct{
// to be defined FIXME!!!
}zp_CSI_RS_Resource_t;
typedef struct {
/*
* resourceAllocation
*/
dl_resourceAllocation_t dl_resourceAllocation;
/*
* corresponds to I, where I the number of entries in the higher layer parameter pdsch-AllocationList
*/
uint8_t n_pdsh_alloc_list;
/*
* rateMatchPatternToAddModList
*/
rateMatchPattern_t rateMatchPatternToAddModList[MAX_NR_RATE_MATCH_PATTERNS];
/*
* rateMatchPatternToReleaseList
*/
uint8_t rateMatchPatternToReleaseList[MAX_NR_RATE_MATCH_PATTERNS];
/*
* n_rateMatchPatterns indicates the number of rateMatchPatterns defined currently
*/
uint8_t n_rateMatchPatterns;
/*
* zp-CSI-RS-ResourceToAddModList
*/
zp_CSI_RS_Resource_t zp_CSI_RS_Resource[MAX_NR_ZP_CSI_RS_RESOURCES];
/*
* zp-CSI-RS-ResourceToReleaseList
*/
uint8_t zp_CSI_RS_ResourceId[MAX_NR_ZP_CSI_RS_RESOURCES];
/*
* n_zp-CSI-RS-Resource
*/
uint8_t n_zp_CSI_RS_ResourceId;
/*
* rgb_Size
*/
dl_rgb_Size_t dl_rgbSize;
/*
* prb-BundlingType
*/
prb_bundleType_t prbBundleType;
/*
* pdsch-HARQ-ACK-Codebook: this is part of the IE PhysicalCellGroupConfig which is used to configure cell-group specific L1 parameters (TS 38.331)
*/
pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook;
////////////////////////////////////////////////////////////////////////////////################################
/*
Maximum number of code words that a single DCI may schedule. This changes the number of MCS/RV/NDI bits in the DCI message from 1 to 2.
*/
@@ -413,8 +505,168 @@ typedef struct {
mappingType_t mappingType;
uint8_t startSymbolAndLength;
} PUSCH_TimeDomainResourceAllocation_t;
////////////////////////////////////////////////////////////////////////////////################################
typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS)
} ptrs_UplinkConfig_t;
typedef enum{
maxCodeBlockGroupsPerTransportBlock_n2 = 2,
maxCodeBlockGroupsPerTransportBlock_n4 = 4,
maxCodeBlockGroupsPerTransportBlock_n6 = 6,
maxCodeBlockGroupsPerTransportBlock_n8 = 8
} maxCodeBlockGroupsPerTransportBlock_t;
typedef struct{ // The IE PUSCH-ServingCellConfig is used to configure UE specific PUSCH parameters that are common across the UE's BWPs of one serving cell
maxCodeBlockGroupsPerTransportBlock_t maxCodeBlockGroupsPerTransportBlock;
} PUSCH_ServingCellConfig_t;
typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference signals)
uint8_t reportTriggerSize;
} csi_MeasConfig_t;
typedef enum {
pdsch_dmrs_type1 = 1,
pdsch_dmrs_type2 = 2
} pdsch_dmrs_type_t;
typedef enum {
pusch_dmrs_type1 = 1,
pusch_dmrs_type2 = 2
} pusch_dmrs_type_t;
typedef enum {
pdsch_dmrs_pos0 = 0,
pdsch_dmrs_pos1 = 1,
pdsch_dmrs_pos3 = 3,
} pdsch_dmrs_AdditionalPosition_t;
typedef enum {
pusch_dmrs_pos0 = 0,
pusch_dmrs_pos1 = 1,
pusch_dmrs_pos3 = 3,
} pusch_dmrs_AdditionalPosition_t;
typedef enum {
pdsch_len1 = 1,
pdsch_len2 = 2
} pdsch_maxLength_t;
typedef enum {
pusch_len1 = 1,
pusch_len2 = 2
} pusch_maxLength_t;
typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH
pdsch_dmrs_type_t pdsch_dmrs_type;
pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition;
pdsch_maxLength_t pdsch_maxLength;
uint16_t scramblingID0;
uint16_t scramblingID1;
} dmrs_DownlinkConfig_t;
typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodulation reference signals for PUSCH
pusch_dmrs_type_t pusch_dmrs_type;
pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition;
pusch_maxLength_t pusch_maxLength;
uint16_t scramblingID0;
uint16_t scramblingID1;
} dmrs_UplinkConfig_t;
typedef struct {
/*
* Serving cell ID of a PSCell. The PCell of the Master Cell Group uses ID = 0
*/
uint8_t servCellIndex;
}servCellIndex_t;
typedef struct{
uint8_t cif_presence;
}own_t;
typedef struct{
servCellIndex_t scheduling_cell_id;
uint8_t cif_InSchedulingCell;
}other_t;
typedef struct{
own_t own;
other_t other;
}schedulingCellInfo_t;
typedef struct{
schedulingCellInfo_t schedulingCellInfo;
} crossCarrierSchedulingConfig_t;
typedef struct{
// this variable will be filled with '1' if SUL is supported and '0' if SUL is not supported
uint8_t supplementaryUplink;
}supplementaryUplink_t;
typedef enum {
txConfig_codebook = 1,
txConfig_nonCodebook = 2
} txConfig_t;
typedef enum {
f_hop_mode1 = 1,
f_hop_mode2 = 2
} frequencyHopping_t;
typedef enum{
ul_resourceAllocationType0 = 1,
ul_resourceAllocationType1 = 2,
ul_dynamicSwitch = 3
} ul_resourceAllocation_t;
typedef enum{
ul_rgb_config1 = 1,
ul_rgb_config2 = 2
} ul_rgb_Size_t;
typedef enum {
transformPrecoder_enabled = 1,
transformPrecoder_disabled = 2
} transformPrecoder_t;
typedef enum {
codebookSubset_fullyAndPartialAndNonCoherent = 1,
codebookSubset_partialAndNonCoherent = 2,
codebookSubset_nonCoherent = 3
} codebookSubset_t;
typedef enum{
betaOffset_dynamic = 1,
betaOffset_semiStatic = 2
}betaOffset_type_t;
typedef struct{
} betaOffset_t;
typedef struct {
betaOffset_type_t betaOffset_type;
betaOffset_t betaOffset;
} uci_onPusch_t;
typedef struct {
/*
* txConfig
*/
txConfig_t txConfig;
/*
* frequencyHopping
*/
frequencyHopping_t frequencyHopping;
/*
* frequencyHoppingOffsetLists
*/
uint16_t frequencyHoppingOffsetLists[4];
// n_frequencyHoppingOffsetLists contains the number of offsets listed. We can list up to 4 offsets
uint8_t n_frequencyHoppingOffsetLists;
/*
* resourceAllocation
*/
ul_resourceAllocation_t ul_resourceAllocation;
/*
* rgb_Size
*/
ul_rgb_Size_t ul_rgbSize;
/*
* corresponds to I, where I the number of entries in the higher layer parameter pusch-AllocationList
*/
uint8_t n_push_alloc_list;
/*
* transformPrecoder
*/
transformPrecoder_t transformPrecoder;
/*
* codebookSubset
*/
codebookSubset_t codebookSubset;
/*
* maxRank
*/
uint8_t maxRank;
/*
* uci_onPusch
*/
uci_onPusch_t uci_onPusch;
////////////////////////////////////////////////////////////////////////////////################################
PUSCH_PowerControl_t pusch_PowerControl;
PUSCH_TimeDomainResourceAllocation_t *pusch_TimeDomainResourceAllocation[MAX_NR_OF_UL_ALLOCATIONS];
} PUSCH_Config_t;
@@ -647,11 +899,6 @@ typedef struct {
typedef uint16_t RNTI_value_t;
typedef enum {
semiStatic = 0,
dynamic = 1
} pdsch_HARQ_ACK_Codebook_t;
typedef struct {
/*
-- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUCCH
@@ -748,6 +995,12 @@ typedef enum {
n12_dl_harq = 12,
n16_dl_harq = 16
} nrofHARQ_ProcessesForPDSCH_t;
typedef enum{
maxCodeBlockGroupsPerTransportBlock_dl_n2 = 2,
maxCodeBlockGroupsPerTransportBlock_dl_n4 = 4,
maxCodeBlockGroupsPerTransportBlock_dl_n6 = 6,
maxCodeBlockGroupsPerTransportBlock_dl_n8 = 8
} maxCodeBlockGroupsPerTransportBlock_dl_t;
typedef struct {
/*
@@ -770,7 +1023,14 @@ typedef struct {
-- If the field is absent, the UE sends the HARQ feedback on the PUCCH of the SpCell of this cell group.
*/
uint8_t pucch_Cell;
/*
* maxCodeBlockGroupsPerTransportBlock_dl_t
*/
maxCodeBlockGroupsPerTransportBlock_dl_t maxCodeBlockGroupsPerTransportBlock_dl;
/*
* codeBlockGroupFlushIndicator (boolean)
*/
uint8_t codeBlockGroupFlushIndicator;
} PDSCH_ServingCellConfig_t;
/***********************************************************************
+32 -5
View File
@@ -42,8 +42,8 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB,
uint8_t *sdu)
{
AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel15.length == 3, "BCH PDU has length %d != 3\n",
dl_config_pdu->bch_pdu.bch_pdu_rel15.length);
AssertFatal(dl_config_pdu->bch_pdu_rel15.length == 3, "BCH PDU has length %d != 3\n",
dl_config_pdu->bch_pdu_rel15.length);
LOG_I(PHY,"pbch_pdu[0]: %x,pbch_pdu[1]: %x,gNB->pbch_pdu[2]: %x\n",sdu[0],sdu[1],sdu[2]);
gNB->pbch_pdu[0] = sdu[2];
@@ -53,6 +53,24 @@ void handle_nr_nfapi_bch_pdu(PHY_VARS_gNB *gNB,
// adjust transmit amplitude here based on NFAPI info
}
void handle_nfapi_nr_dci_dl_pdu(PHY_VARS_gNB *gNB,
int frame, int subframe,
gNB_rxtx_proc_t *proc,
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu)
{
int idx = subframe&1;
NR_gNB_PDCCH *pdcch_vars = &gNB->pdcch_vars;
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci);
// copy dci configuration into gNB structure
nr_fill_dci_and_dlsch(gNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],dl_config_pdu);
LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci);
}
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
PHY_VARS_gNB *gNB;
gNB_rxtx_proc_t *proc;
@@ -90,9 +108,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
//LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type);
switch (dl_config_pdu->pdu_type) {
case NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE:
AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel15.pdu_index < TX_req->tx_request_body.number_of_pdus,
AssertFatal(dl_config_pdu->bch_pdu_rel15.pdu_index < TX_req->tx_request_body.number_of_pdus,
"bch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n",
dl_config_pdu->bch_pdu.bch_pdu_rel15.pdu_index,
dl_config_pdu->bch_pdu_rel15.pdu_index,
TX_req->tx_request_body.number_of_pdus);
gNB->pbch_configured=1;
do_oai=1;
@@ -100,7 +118,16 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
handle_nr_nfapi_bch_pdu(gNB,
proc,
dl_config_pdu,
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel15.pdu_index].segments[0].segment_data);
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu_rel15.pdu_index].segments[0].segment_data);
break;
case NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE:
handle_nfapi_nr_dci_dl_pdu(gNB,
frame, subframe,
proc,
dl_config_pdu);
gNB->pdcch_vars.num_dci++;
do_oai=1;
break;
}
}
+5 -1
View File
@@ -38,4 +38,8 @@
#include "SCHED_NR/sched_nr.h"
#include "nfapi_nr_interface.h"
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
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_rxtx_proc_t *proc,
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu);
+141 -4
View File
@@ -29,15 +29,152 @@
* \note
* \warning
*/
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "sched_nr.h"
/// LUT for the number of symbols in the coreset indexed by coreset index (4 MSB rmsi_pdcch_config)
uint8_t nr_coreset_nsymb_pdcch_type_0_b40Mhz[16] = {2,2,2,2,2,3,3,3,3,3,1,1,1,2,2,2}; // below 40Mhz bw
uint8_t nr_coreset_nsymb_pdcch_type_0_a40Mhz[10] = {2,2,3,3,1,1,2,2,3,3}; // above 40Mhz bw
/// LUT for the number of RBs in the coreset indexed by coreset index
uint8_t nr_coreset_rb_offset_pdcch_type_0_b40Mhz[16] = {0,1,2,3,4,0,1,2,3,4,12,14,16,12,14,16};
uint8_t nr_coreset_rb_offset_pdcch_type_0_a40Mhz[10] = {0,4,0,4,0,28,0,28,0,28};
/// LUT for monitoring occasions param O indexed by ss index (4 LSB rmsi_pdcch_config)
uint8_t nr_ss_param_O_type_0_mux1_FR1[16] = {0,0,2,2,5,5,7,7,0,5,0,0,2,2,5,5};
uint8_t nr_ss_param_O_type_0_mux1_FR2[14] = {0,0,2.5,2.5,5,5,0,2.5,5,7.5,7.5,7.5,0,5};
/// LUT for number of SS sets per slot indexed by ss index
uint8_t nr_ss_sets_per_slot_type_0_FR1[16] = {1,2,1,2,1,2,1,2,1,1,1,1,1,1,1,1};
uint8_t nr_ss_sets_per_slot_type_0_FR2[14] = {1,2,1,2,1,2,2,2,2,1,2,2,1,1};
/// LUT for monitoring occasions param M indexed by ss index
uint8_t nr_ss_param_M_type_0_mux1_FR1[16] = {1,0.5,1,0.5,1,0.5,1,0.5,2,2,1,1,1,1,1,1};
uint8_t nr_ss_param_M_type_0_mux1_FR2[14] = {1,0.5,1,0.5,1,0.5,0.5,0.5,0.5,1,0.5,0.5,2,2};
/// LUT for SS first symbol index indexed by ss index
uint8_t nr_ss_first_symb_idx_type_0_mux1_FR1[8] = {0,0,1,2,1,2,1,2};
nr_subframe_t nr_subframe_select(nfapi_nr_config_request_t *cfg,unsigned char subframe)
{
if (cfg->subframe_config.duplex_mode.value == FDD)
return(SF_DL);
else
return SF_DL;
}
void nr_configure_css_dci_from_mib(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params,
nr_scs_e scs_common,
nr_scs_e pdcch_scs,
nr_frequency_range_e freq_range,
uint8_t rmsi_pdcch_config,
uint8_t ssb_idx,
uint16_t nb_slots_per_frame,
uint16_t N_RB)
{
uint8_t O, M;
uint8_t ss_idx = rmsi_pdcch_config&0xf;
uint8_t cset_idx = (rmsi_pdcch_config>>4)&0xf;
uint8_t mu;
/// Coreset params
switch(scs_common) {
case kHz15:
mu = 0;
break;
case kHz30:
mu = 1;
if (N_RB < 106) { // Minimum 40Mhz bandwidth not satisfied
switch(pdcch_scs) {
case kHz15:
break;
case kHz30:
pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1;
pdcch_params->n_rb = (cset_idx < 10)? 24 : 48;
pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_b40Mhz[cset_idx];
pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_b40Mhz[cset_idx];
break;
default:
AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs);
}
}
else {
AssertFatal(ss_idx<10 ,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs);
switch(pdcch_scs) {
case kHz15:
break;
case kHz30:
pdcch_params->mux_pattern = NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1;
pdcch_params->n_rb = (cset_idx < 4)? 24 : 48;
pdcch_params->n_symb = nr_coreset_nsymb_pdcch_type_0_b40Mhz[cset_idx];
pdcch_params->rb_offset = nr_coreset_rb_offset_pdcch_type_0_b40Mhz[cset_idx];
break;
default:
AssertFatal(1==0,"Invalid scs_common/pdcch_scs combination %d/%d \n", scs_common, pdcch_scs);
}
}
case kHz60:
mu = 2;
break;
case kHz120:
mu = 3;
break;
default:
AssertFatal(1==0,"Invalid common subcarrier spacing %d\n", scs_common);
}
/// Search space params
switch(pdcch_params->mux_pattern) {
case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE1:
if (freq_range == nr_FR1) {
O = nr_ss_param_O_type_0_mux1_FR1[ss_idx];
pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR1[ss_idx];
M = nr_ss_param_M_type_0_mux1_FR1[ss_idx];
pdcch_params->first_symbol = (ss_idx < 8)? ( (ss_idx&1)? pdcch_params->n_symb : 0 ) : nr_ss_first_symb_idx_type_0_mux1_FR1[ss_idx - 8];
}
else {
AssertFatal(ss_idx<14 ,"Invalid search space index for multiplexing type 1 and FR2 %d\n", ss_idx);
O = nr_ss_param_O_type_0_mux1_FR2[ss_idx];
pdcch_params->nb_ss_sets_per_slot = nr_ss_sets_per_slot_type_0_FR2[ss_idx];
M = nr_ss_param_M_type_0_mux1_FR2[ss_idx];
pdcch_params->first_symbol = (ss_idx < 12)? ( (ss_idx&1)? 7 : 0 ) : 0;
}
pdcch_params->nb_slots = 2;
pdcch_params->sfn_mod2 = ((uint8_t)(floor( (O*pow(2, mu) + floor(ssb_idx*M)) / nb_slots_per_frame )) & 1)? 1 : 0;
pdcch_params->first_slot = (uint8_t)(O*pow(2, mu) + floor(ssb_idx*M)) % nb_slots_per_frame;
break;
case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE2:
break;
case NFAPI_NR_SSB_AND_CSET_MUX_PATTERN_TYPE3:
break;
default:
AssertFatal(1==0, "Invalid SSB and coreset multiplexing pattern %d\n", pdcch_params->mux_pattern);
}
pdcch_params->config_type = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
pdcch_params->cr_mapping_type = NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED;
pdcch_params->precoder_granularity = NFAPI_NR_CSET_SAME_AS_REG_BUNDLE;
pdcch_params->reg_bundle_size = 6;
pdcch_params->interleaver_size = 2;
}
void nr_configure_css_dci_from_pdcch_config(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params,
nfapi_nr_coreset_t* coreset,
nfapi_nr_search_space_t* search_space) {
}
+23 -6
View File
@@ -46,7 +46,7 @@ extern uint8_t nfapi_mode;
int return_ssb_type(nfapi_config_request_t *cfg)
{
int mu = cfg->subframe_config.numerology_index_mu.value;
nr_numerology_index_e ssb_type;
nr_ssb_type_e ssb_type;
switch(mu) {
@@ -140,23 +140,24 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp);
/*if ((frame_mod8) == 0){
if (!(frame&7)){
if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0;
}*/
}
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp);
nr_generate_pbch(&gNB->pbch, pbch_pdu, txdataF, AMP_OVER_2, ssb_start_symbol, n_hf, Lmax, ssb_index, frame, cfg, fp);
nr_generate_pbch(&gNB->pbch, gNB->nrPolar_params, pbch_pdu, txdataF, AMP_OVER_2, ssb_start_symbol, n_hf, Lmax, ssb_index, frame, cfg, fp);
}
}
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
gNB_rxtx_proc_t *proc,
int do_meas)
gNB_rxtx_proc_t *proc,
int do_meas)
{
int aa;
int frame=proc->frame_tx;
int subframe=proc->subframe_tx;
uint8_t num_dci=0;
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
@@ -178,4 +179,20 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
//if (frame == 9)
//write_output("txdataF.m","txdataF",gNB->common_vars.txdataF[aa],fp->samples_per_frame_wCP, 1, 1);
}
num_dci = gNB->pdcch_vars.num_dci;
if (num_dci) {
LOG_I(PHY, "[gNB %d] Frame %d subframe %d \
Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, subframe, num_dci);
uint8_t slot_idx = gNB->pdcch_vars.dci_alloc[0].pdcch_params.first_slot;
if (nfapi_mode == 0 || nfapi_mode == 1)
nr_generate_dci_top(gNB->pdcch_vars,
gNB->nrPolar_params,
gNB->nr_gold_pdcch_dmrs[slot_idx],
gNB->common_vars.txdataF,
AMP, *fp, *cfg);
}
}
+10
View File
@@ -31,6 +31,7 @@
#include "PHY/defs_gNB.h"
#include "PHY_INTERFACE/phy_interface.h"
#include "SCHED/sched_eNB.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
lte_subframe_t nr_subframe_select (nfapi_nr_config_request_t *cfg, unsigned char subframe);
@@ -42,4 +43,13 @@ void nr_feptx_ofdm(RU_t *ru);
void nr_feptx_ofdm_2thread(RU_t *ru);
void nr_feptx0(RU_t *ru,int slot);
void nr_configure_css_dci_from_mib(nfapi_nr_dl_config_pdcch_parameters_rel15_t* pdcch_params,
nr_scs_e scs_common,
nr_scs_e pdcch_scs,
nr_frequency_range_e freq_range,
uint8_t rmsi_pdcch_config,
uint8_t ssb_idx,
uint16_t nb_slots_per_frame,
uint16_t N_RB);
#endif
+49 -18
View File
@@ -48,8 +48,9 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
uint32_t i;
if(scheduled_response != NULL){
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id];
NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[0][0];
NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[0][0];
NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0];
if(scheduled_response->dl_config != NULL){
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
@@ -87,32 +88,62 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
//pdcch_vars2->coreset[i].tciStatesPDCCH;
//pdcch_vars2->coreset[i].tciPresentInDCI;
pdcch_vars2->coreset[i].pdcchDMRSScramblingID = dci_config->coreset.pdcch_dmrs_scrambling_id;
}else{ //FAPI_NR_DL_CONFIG_TYPE_DLSCH
// dlsch config pdu
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[0]][0]; //nr_tti_rx
NR_UE_DLSCH_t *dlsch0 = dlsch[0];
NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[dlsch_pdu->harq_pid];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
dlsch0->current_harq_pid = current_harq_pid;
dlsch0->active = 1;
//dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
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;
dlsch0_harq.nb_rb = dlsch_config_pdu->number_rbs;
dlsch0_harq.start_rb = dlsch_config_pdu->start_rb;
dlsch0_harq.nb_symbols = dlsch_config_pdu->number_symbols;
dlsch0_harq.start_symbol = dlsch_config_pdu->start_symbol;
dlsch0_harq.mcs = dlsch_config_pdu->mcs;
dlsch0_harq.DCINdi = dlsch_config_pdu->ndi;
dlsch0_harq.rvidx = dlsch_config_pdu->rv;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
dlsch0_harq.harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
dlsch0_harq.harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind;
printf(">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq.mcs);
//for (int j = 0 ; j<1000; j++) printf("\nk = %d",j);
dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
dlsch0_harq->start_rb = dlsch_pdu->start_rb;
dlsch0_harq->nb_rb = dlsch_pdu->number_rbs;
dlsch0_harq->nb_symbols = dlsch_pdu->number_symbols;
dlsch0_harq->nb_symbols = dlsch_pdu->number_symbols;
dlsch0_harq->start_symbol = dlsch_pdu->start_symbol;
dlsch0->current_harq_pid = dlsch_pdu->harq_pid;
dlsch0->active = 1;
dlsch0_harq->mcs = dlsch_pdu->mcs;
dlsch0_harq->DCINdi = dlsch_pdu->ndi;
}
#if 0
dlsch0->harq_processes[current_harq_pid]->mcs = dlsch_config_pdu->mcs;
dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH;
//pdlsch0->rnti = rnti;
#endif
}
}
}else{
pdcch_vars2->nb_search_space = 0;
}
if(scheduled_response->ul_config != NULL){
fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
for(i=0; i<ul_config->number_pdus; ++i){
if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){
// pusch config pdu
fapi_nr_ul_config_pusch_pdu_rel15_t *pusch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15;
uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr;
ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs;
ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb;
ulsch0->harq_processes[current_harq_pid]->nb_symbols = pusch_config_pdu->number_symbols;
ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol;
ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs;
ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi;
ulsch0->harq_processes[current_harq_pid]->rvidx = pusch_config_pdu->rv;
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
}
}
}else{
}
+10 -10
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;
@@ -373,7 +373,7 @@ void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int
{
NR_UE_DLSCH_t *dlsch;
dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
//dlsch = (NR_UE_DLSCH_t *)malloc16(sizeof(NR_UE_DLSCH_t));
if (dlsch != NULL) {
@@ -392,18 +392,18 @@ void config_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, int
/* allocation of HARQ process context */
for (int harq_pid = 0; harq_pid < number_harq_processes_for_pdsch; harq_pid++) {
dlsch->harq_processes[harq_pid] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
//dlsch->harq_processes[harq_pid] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
if (dlsch->harq_processes[harq_pid] == NULL) {
/*if (dlsch->harq_processes[harq_pid] == NULL) {
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
assert(0);
}
}*/
memset(dlsch->harq_processes[harq_pid],0,sizeof(NR_DL_UE_HARQ_t));
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);
}
}
@@ -425,12 +425,12 @@ void release_downlink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int TB_id, in
{
NR_UE_DLSCH_t *dlsch = ue->dlsch[execution_thread_number][gNB_id][TB_id];
for (int process_id = 0; process_id < dlsch->Mdlharq; process_id++) {
/*for (int process_id = 0; process_id < dlsch->Mdlharq; process_id++) {
free16(dlsch->harq_processes[process_id],sizeof(NR_DL_UE_HARQ_t));
dlsch->harq_processes[process_id] = NULL;
}
}*/
free16(dlsch,sizeof(NR_UE_DLSCH_t));
+161 -86
View File
@@ -54,7 +54,7 @@
#define DEBUG_PHY_PROC
#define NR_PDCCH_SCHED
//#define NR_PDCCH_SCHED_DEBUG
#define NR_PDCCH_SCHED_DEBUG
//#define NR_PUCCH_SCHED
//#define NR_PUCCH_SCHED_DEBUG
@@ -89,7 +89,51 @@ fifo_dump_emos_UE emos_dump_UE;
extern double cpuf;
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);
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);
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
@@ -3138,31 +3182,45 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
// table dci_fields_sizes_cnt[dci_cnt-1][i][j] will then be used in function nr_extract_dci_info
uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = {0};
uint16_t tc_rnti = 1; // FIXME
uint16_t int_rnti = 1; // FIXME
uint16_t sfi_rnti = 1; // FIXME
uint16_t tpc_pusch_rnti =1; // FIXME
uint16_t tpc_pucch_rnti = 1; // FIXME
uint16_t tpc_srs_rnti = 1; // FIXME
int nb_searchspace_active=0;
NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]];
NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id];
uint16_t c_rnti=pdcch_vars[eNB_id]->crnti;
uint16_t cs_rnti=1,new_rnti=1,tc_rnti=1;
uint16_t p_rnti=P_RNTI;
uint16_t si_rnti=SI_RNTI;
uint16_t ra_rnti=3;
uint16_t sp_csi_rnti=1,sfi_rnti=1,int_rnti=1,tpc_pusch_rnti=1,tpc_pucch_rnti=1,tpc_srs_rnti=1; //FIXME
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES] =
{c_rnti,cs_rnti,new_rnti,tc_rnti,p_rnti,si_rnti,ra_rnti,sp_csi_rnti,sfi_rnti,int_rnti,tpc_pusch_rnti,tpc_pucch_rnti,tpc_srs_rnti};
// s in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 10 different search spaces
// Higher layers have updated the number of searchSpaces with are active in the current slot and this value is stored in variable nb_searchspace_total
int nb_searchspace_total = pdcch_vars2->nb_search_space;
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total=%d\n",nb_searchspace_total);
#endif
if (nb_searchspace_total>1) nb_searchspace_total=1; // to be removed when fixing bug in FAPI
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total so we set it to 1...\n");
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> the number of searchSpaces active in the current slot(%d) is %d) \n",
nr_tti_rx,nb_searchspace_total);
#endif
// p in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 3 different CORESETs (including coresetId 0 for common search space)
int nb_coreset_total = NR_NBR_CORESET_ACT_BWP;
unsigned int dci_cnt=0;
//int nb_coreset_total = NR_NBR_CORESET_ACT_BWP;
uint8_t dci_cnt=0;
// this table contains 56 (NBR_NR_DCI_FIELDS) elements for each dci field and format described in TS 38.212. Each element represents the size in bits for each dci field
uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = {0};
//uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS] = {0};
// this is the UL bandwidth part. FIXME! To be defined where this value comes from
uint16_t n_RB_ULBWP = 106;
// this is the DL bandwidth part. FIXME! To be defined where this value comes from
uint16_t n_RB_DLBWP = 106;
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> n_RB_ULBWP=%d n_RB_DLBWP=%d\n",
n_RB_ULBWP,
n_RB_DLBWP);
#endif
// First we have to identify each searchSpace active at a time and do PDCCH monitoring corresponding to current searchSpace
// Up to 10 searchSpaces can be configured to UE (s<=10)
@@ -3186,7 +3244,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
* To be implemented LATER !!!
*/
//int _offset,_index,_M;
int searchSpace_id = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceId;
//int searchSpace_id = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceId;
/*
* The following code has been removed as it is handled by higher layers (fapi)
if (searchSpace_id == 0){ // Implementing TS 38.213 subclause 13, UE procedure for monitoring Type0-PDCCH common search space
@@ -3216,16 +3274,16 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
// the searchSpace indicates that we need to monitor PDCCH in current nr_tti_rx
// get the parameters describing the current SEARCHSPACE
// the CORESET id applicable to the current SearchSpace
int searchSpace_coreset_id = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId;
//int searchSpace_coreset_id = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId;
// FIXME this variable is a bit string (14 bits) identifying every OFDM symbol in a slot.
// at the moment we will not take into consideration this variable and we will consider that the OFDM symbol offset is always the first OFDM in a symbol
uint16_t symbol_within_slot_mon = pdcch_vars2->searchSpace[nb_searchspace_active].monitoringSymbolWithinSlot;
// get the remaining parameters describing the current SEARCHSPACE: // FIXME! To be defined where we get this information from
NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1;
NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2;
NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4;
NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8;
NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16;
//NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L1 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel1;
//NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L2 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel2;
//NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L4 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel4;
//NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L8 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel8;
//NR_UE_SEARCHSPACE_nbrCAND_t num_cand_L16 = pdcch_vars2->searchSpace[nb_searchspace_active].nrofCandidates_aggrlevel16;
// FIXME! A table of five enum elements
// searchSpaceType indicates whether this is a common search space or a UE-specific search space
//int searchSpaceType = pdcch_vars2->searchSpace[nb_searchspace_active].searchSpaceType.type;
@@ -3295,8 +3353,8 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
ue->high_speed_flag,
ue->is_secondary_ue);*/ //removed for nr_ue_pdcch_procedures
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_rx_pdcch(nb_coreset_active=%d, (symbol_within_slot_mon&0x3FFF)=%d, searchSpaceType=%d)\n",
nb_coreset_active,(symbol_within_slot_mon&0x3FFF),
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_rx_pdcch with eNB_id=%d (nb_coreset_active=%d, (symbol_within_slot_mon&0x3FFF)=%d, searchSpaceType=%d)\n",
eNB_id,nb_coreset_active,(symbol_within_slot_mon&0x3FFF),
searchSpaceType);
#endif
nr_rx_pdcch(ue,
@@ -3346,57 +3404,41 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
*/ //removed for nr_ue_pdcch_procedures
crc_scrambled_t crc_scrambled;
format_found_t format_found=255;
#ifdef NR_PDCCH_SCHED_DEBUG
if (searchSpaceType == common) { // search all possible dci's for COMMON SEARCH SPACES according to the current SEARCHSPACE configuration
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure(searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
searchSpaceType,
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure with eNB_id=%d (n_RB_ULBWP=%d, n_RB_DLBWP=%d, searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
eNB_id,n_RB_ULBWP,n_RB_DLBWP,searchSpaceType,
nb_searchspace_active,
nb_coreset_active,
dci_cnt);
#endif
dci_cnt += nr_dci_decoding_procedure(nb_searchspace_active,
nb_coreset_active,
ue,
dci_alloc_rx[dci_cnt],
searchSpaceType, // if we're in PUSCH don't listen to common search space,
// later when we need paging or RA during connection, update this ...
eNB_id,
nr_tti_rx,
dci_fields_sizes,dci_fields_sizes_cnt,
n_RB_ULBWP,
n_RB_DLBWP,
&crc_scrambled,
&format_found);
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt);
#endif
}
if (searchSpaceType == ue_specific){// search all possible dci's for UE-SPECIFIC SEARCH SPACES according to the current SEARCHSPACE configuration
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure(searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
searchSpaceType,
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_dci_decoding_procedure with eNB_id=%d (n_RB_ULBWP=%d, n_RB_DLBWP=%d, searchSpaceType=%d, nb_searchspace_active=%d, nb_coreset_active=%d) -> dci_cnt=%d\n",
eNB_id,n_RB_ULBWP,n_RB_DLBWP,searchSpaceType,
nb_searchspace_active,
nb_coreset_active,
dci_cnt);
#endif
dci_cnt += nr_dci_decoding_procedure(nb_searchspace_active,
nb_coreset_active,
ue,
dci_alloc_rx[dci_cnt],
searchSpaceType, // if we're in PUSCH don't listen to common search space,
// later when we need paging or RA during connection, update this ...
eNB_id,
nr_tti_rx,
dci_fields_sizes,dci_fields_sizes_cnt,
n_RB_ULBWP,
n_RB_DLBWP,
&crc_scrambled,
&format_found);
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt);
#endif
}
#endif
dci_cnt += nr_dci_decoding_procedure(nb_searchspace_active,
nb_coreset_active,
ue,
&dci_alloc_rx[dci_cnt],
searchSpaceType,
eNB_id,
nr_tti_rx,
dci_fields_sizes_cnt,
n_RB_ULBWP,
n_RB_DLBWP,
&crc_scrambled,
&format_found,
crc_scrambled_values);
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%d\n",dci_cnt);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
//LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_tti_rx);
@@ -3483,14 +3525,6 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
/*
* This is the NR part
*/
uint16_t c_rnti=pdcch_vars[eNB_id]->crnti;
uint16_t cs_rnti,new_rnti,tc_rnti;
uint16_t p_rnti=P_RNTI;
uint16_t si_rnti=SI_RNTI;
uint16_t ra_rnti=99;
uint16_t sp_csi_rnti,sfi_rnti,int_rnti,tpc_pusch_rnti,tpc_pucch_rnti,tpc_srs_rnti; //FIXME
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES] =
{c_rnti,cs_rnti,new_rnti,tc_rnti,p_rnti,si_rnti,ra_rnti,sp_csi_rnti,sfi_rnti,int_rnti,tpc_pusch_rnti,tpc_pucch_rnti,tpc_srs_rnti};
if ((dci_alloc_rx[i].format == format0_0))
if ((dci_alloc_rx[i].format == format1_0) &&
@@ -3513,7 +3547,16 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
if ((dci_alloc_rx[i].format == format1_1)){ // This format not implemented at a first time. FIXME
}
NR_DCI_INFO_EXTRACTED_t nr_dci_info_extracted;
nr_generate_ue_ul_dlsch_params_from_dci(ue,
NR_DCI_INFO_EXTRACTED_t *ptr_nr_dci_info_extracted = &nr_dci_info_extracted;
#ifdef NR_PDCCH_SCHED_DEBUG
printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Entering function nr_generate_ue_ul_dlsch_params_from_dci with eNB_id=%d dci_cnt=%d format=%d, rnti=%d\n",
eNB_id,
dci_cnt,
dci_alloc_rx[i].format,
dci_alloc_rx[i].rnti);
#endif
nr_generate_ue_ul_dlsch_params_from_dci(ue,
eNB_id,
frame_rx,
nr_tti_rx,
@@ -3532,15 +3575,17 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
n_RB_ULBWP,
n_RB_DLBWP,
crc_scrambled_values,
&nr_dci_info_extracted);
ptr_nr_dci_info_extracted);//&nr_dci_info_extracted);
ue->dci_ind.dci_list[i].rnti = dci_alloc_rx[i].rnti;
ue->dci_ind.dci_list[i].dci_format = dci_alloc_rx[i].format;
memcpy(&ue->dci_ind.dci_list[i].dci, &nr_dci_info_extracted, sizeof(fapi_nr_dci_pdu_rel15_t) );
//printf(">>> example mcs=%d\n",nr_dci_info_extracted.mcs);
//printf(">>> calling MAC with dl_indication DCI_IND\n");
// TODO: check where should we send up this message.
//ue->if_inst->dl_indication(&ue->dl_indication);
ue->dl_indication.dci_ind=&ue->dci_ind;
ue->if_inst->dl_indication(&ue->dl_indication);
/*
* This is the LTE part to be removed
@@ -3769,7 +3814,7 @@ int nr_ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_tti_rx %d: Found cba rnti %x, format 0, dci_cnt %d\n",
ue->Mod_id,frame_rx,nr_tti_rx,dci_alloc_rx[i].rnti,i);
/*
if (((frame_rx%100) == 0) || (frame_rx < 20))
dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
@@ -4027,6 +4072,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t
memcpy(harq_ack_dest, current_harq_ack, sizeof(nr_harq_status_t));
}*/
#if 0
void ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) {
int nr_tti_rx = proc->nr_tti_rx;
@@ -4046,11 +4092,11 @@ void ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id
if ((pdsch==PDSCH) &&
(ue->transmission_mode[eNB_id] == 5) &&
(dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
(dlsch0->harq_processes[harq_pid].dl_power_off==0) &&
(ue->use_ia_receiver ==1)) {
dual_stream_UE = 1;
eNB_id_i = ue->n_connected_eNB;
i_mod = dlsch0->harq_processes[harq_pid]->Qm;
i_mod = dlsch0->harq_processes[harq_pid].Qm;
}
else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3))
@@ -4115,6 +4161,8 @@ void ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id
} // CRNTI active
}
}
#endif
#if 0
void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
@@ -5446,17 +5494,18 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
relaying_type_t r_type) {
int l,l2;
int pilot1;
int pmch_flag=0;
//int l,l2;
//int pilot1;
//int pmch_flag=0;
int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx;
proc->decoder_switch = 0;
//int counter_decoder = 0;
uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
//uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
//uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
#if 0
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
#if T_TRACER
@@ -5468,9 +5517,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
#endif
// start timers
#ifdef UE_DEBUG_TRACE
//#ifdef UE_DEBUG_TRACE
LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx);
#endif
//#endif
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
@@ -5478,6 +5527,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
#endif
pmch_flag = is_pmch_subframe(frame_rx,nr_tti_rx,&ue->frame_parms) ? 1 : 0;
if (do_pdcch_flag) {
// deactivate reception until we scan pdcch
@@ -5500,6 +5553,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
ue->Mod_id,frame_rx, nr_tti_rx);
#endif
if (ue->frame_parms.Ncp == 0) { // normal prefix
pilot1 = 4;
} else { // extended prefix
@@ -5530,6 +5584,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
#endif
//nr_gold_pdcch(ue,0, 2);
/*
@@ -5555,26 +5610,46 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
}*/
//ue_measurement_procedures(l-1,ue,proc,eNB_id,(nr_tti_rx<<1),abstraction_flag,mode);
if (do_pdcch_flag) {
//if (do_pdcch_flag) {
// if ((l==pilot1) || ((pmch_flag==1)&(l==l2))) {
// LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]]);
//printf(">>> at phy_procedures_nrUE_RX, nr_ue_pdcch_procedures init, dlsch->active=%d\n",
// ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active);
if (nr_ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,nr_tti_rx);
return(-1);
}
//for (int m=0;m<1000;m++) printf("%d",m);
//printf("\n>>> at phy_procedures_nrUE_RX, nr_ue_pdcch_procedures end, dlsch->active=%d\n",
// ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active);
// preparing for PDSCH procedures
// if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
// ue_pdsch_procedures(ue,
// proc,
// eNB_id,
// PDSCH,
// ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0],
// NULL,
// ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
// ue->frame_parms.symbols_per_tti>>1,
// abstraction_flag);
// }
#if 0
//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]]);
//printf("nr_tti_rx %d n_pdcch_sym %d pdcch procedures %5.3f \n",
// nr_tti_rx, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols,
// (ue->rx_pdcch_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols);
// }
}
//}
// } // for l=1..l2
#if 0
ue_measurement_procedures(l-1,ue,proc,eNB_id,(nr_tti_rx<<1),abstraction_flag,mode);
LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
+58 -4
View File
@@ -48,6 +48,60 @@
#endif
int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
/*
void nr_generate_pucch0(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
int16_t amp,
int nr_tti_tx,
uint8_t mcs,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB);
void nr_generate_pucch1(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t timeDomainOCC,
uint8_t nr_bit);
void nr_generate_pucch2(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit);
void nr_generate_pucch3_4(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
pucch_format_nr_t fmt,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit,
uint8_t occ_length_format4,
uint8_t occ_index_format4);
*/
/**************** variables **************************************/
@@ -139,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
@@ -238,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) {
@@ -633,7 +687,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) {
@@ -671,7 +725,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
}
}
if (do_reset == TRUE) {
init_downlink_harq_status(ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid]);
init_downlink_harq_status(&ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid]);
}
}
}
+7 -11
View File
@@ -609,14 +609,15 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
int32_t RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 0;
int32_t RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0;
char* RateMatchPatternLTE_CRS_subframeAllocation_choice = NULL;
/*
int32_t srb1_timer_poll_retransmit = 0;
/*int32_t srb1_timer_poll_retransmit = 0;
int32_t srb1_timer_reordering = 0;
int32_t srb1_timer_status_prohibit = 0;
int32_t srb1_poll_pdu = 0;
int32_t srb1_poll_byte = 0;
int32_t srb1_max_retx_threshold = 0;
*/
int32_t srb1_max_retx_threshold = 0;*/
//int32_t my_int;
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
@@ -624,16 +625,11 @@ 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};
//paramdef_t SRB1Params[] = SRB1PARAMS_DESC;
/* map parameter checking array instances to parameter definition array instances */
for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
//paramdef_t SRB1Params[] = SRB1PARAMS_DESC;
/* get global parameters, defined outside any section in the config file */
File diff suppressed because it is too large Load Diff
+4 -30
View File
@@ -82,7 +82,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF
DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1;
DL_req[CC_idP].dl_config_request_body.number_dci = 0;
DL_req[CC_idP].dl_config_request_body.number_pdu = 0;
DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0;
@@ -418,36 +417,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
if((subframeP == 0) && (frameP & 7) == 0){
schedule_nr_mib(module_idP, frameP, subframeP);
}
/*
if (phy_test == 0){
// This schedules SI for legacy LTE and eMTC starting in subframeP
schedule_SI(module_idP, frameP, subframeP);
// This schedules Paging in subframeP
schedule_PCH(module_idP,frameP,subframeP);
// This schedules Random-Access for legacy LTE and eMTC starting in subframeP
schedule_RA(module_idP, frameP, subframeP);
// copy previously scheduled UL resources (ULSCH + HARQ)
copy_nr_ulreq(module_idP, frameP, subframeP);
// This schedules SRS in subframeP
schedule_nr_SRS(module_idP, frameP, subframeP);
// This schedules ULSCH in subframeP (dci0)
schedule_ulsch(module_idP, frameP, subframeP);
// This schedules UCI_SR in subframeP
schedule_nr_SR(module_idP, frameP, subframeP);
// This schedules UCI_CSI in subframeP
schedule_nr_CSI(module_idP, frameP, subframeP);
// This schedules DLSCH in subframeP
schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status);
}
else{
schedule_ulsch_phy_test(module_idP,frameP,subframeP);
schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status);
}
*/
if (RC.flexran[module_idP]->enabled)
flexran_agent_send_update_stats(module_idP);
// Phytest scheduling/ option not activated because of pending bug
nr_schedule_css_dlsch_phytest(module_idP, frameP, subframeP);
/*
// Allocate CCEs for good after scheduling is done
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
@@ -19,34 +19,44 @@
* contact@openairinterface.org
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
/*! \file gNB_scheduler_RA.c
* \brief primitives used for random access
* \author
* \date
* \email:
* \version
*/
void nr_polar_bit_insertion(uint8_t *input, uint8_t *output, uint16_t N, uint16_t K,
int16_t *Q_I_N, int16_t *Q_PC_N, uint8_t n_PC){
#include nr_mac_gNB.h
uint16_t k=0;
uint8_t flag;
void
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
if (n_PC>0) {
/*
*
*/
} else {
for (int n=0; n<=N-1; n++) {
flag=0;
for (int m=0; m<=(K+n_PC)-1; m++) {
if ( n == Q_I_N[m]) {
flag=1;
break;
}
}
if (flag) { // n ϵ Q_I_N
output[n]=input[k];
k++;
} else {
output[n] = 0;
}
}
}
eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = mac->common_channels;
RA_t *ra;
uint8_t i;
start_meas(&mac->schedule_ra);
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (i = 0; i < NB_RA_PROC_MAX; i++) {
ra = (RA_t *) & cc[CC_id].ra[i];
//LOG_D(MAC,"RA[state:%d]\n",ra->state);
if (ra->state == MSG2)
generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == MSG4)
generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == WAITMSG4ACK)
check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra);
} // for i=0 .. N_RA_PROC-1
} // CC_id
stop_meas(&mac->schedule_ra);
}
@@ -31,7 +31,7 @@
*/
#include "assertions.h"
#include "LAYER2/NR_MAC_gNB/mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/MAC/mac_extern.h"
#include "common/utils/LOG/log.h"
@@ -97,10 +97,10 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_BCH_PDU_TYPE;
dl_config_pdu->pdu_size =2 + sizeof(nfapi_nr_dl_config_bch_pdu_rel15_t);
dl_config_pdu->bch_pdu.bch_pdu_rel15.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG;
dl_config_pdu->bch_pdu.bch_pdu_rel15.length = mib_sdu_length;
dl_config_pdu->bch_pdu.bch_pdu_rel15.pdu_index = gNB->pdu_index[CC_id];
dl_config_pdu->bch_pdu.bch_pdu_rel15.transmission_power = 6000;
dl_config_pdu->bch_pdu_rel15.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_BCH_PDU_REL15_TAG;
dl_config_pdu->bch_pdu_rel15.length = mib_sdu_length;
dl_config_pdu->bch_pdu_rel15.pdu_index = gNB->pdu_index[CC_id];
dl_config_pdu->bch_pdu_rel15.transmission_power = 6000;
dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
dl_req->number_pdu++;
dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST;
@@ -0,0 +1,120 @@
/*
* 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 gNB_scheduler_phytest.c
* \brief gNB scheduling procedures in phy_test mode
* \author Guy De Souza
* \date 07/2018
* \email: desouza@eurecom.fr
* \version 1.0
* @ingroup _mac
*/
#include "nr_mac_gNB.h"
#include "SCHED_NR/sched_nr.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*/
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP)
{
uint8_t CC_id;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
//NR_COMMON_channels_t *cc = nr_mac->common_channels;
nfapi_nr_dl_config_request_body_t *dl_req;
nfapi_nr_dl_config_request_pdu_t *dl_config_pdu;
nfapi_tx_request_pdu_t *TX_req;
uint16_t sfn_sf = frameP << 4 | subframeP;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
LOG_I(MAC, "Scheduling common search space DCI type 1 for CC_id %d\n",CC_id);
PHY_VARS_gNB *gNB = RC.gNB[module_idP][CC_id];
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
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));
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;
nr_configure_css_dci_from_mib(&gNB->pdcch_type0_params,
kHz30, kHz30, nr_FR1, 0, 0,
fp->slots_per_frame,
cfg->rf_config.dl_carrier_bandwidth.value);
memcpy((void*)params_rel15, (void*)&gNB->pdcch_type0_params, sizeof(nfapi_nr_dl_config_pdcch_parameters_rel15_t));
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->tb_scaling = 1;
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\n",
pdu_rel15->frequency_domain_assignment,
pdu_rel15->time_domain_assignment,
pdu_rel15->vrb_to_prb_mapping,
pdu_rel15->mcs,
pdu_rel15->tb_scaling);
params_rel15->rnti = 0x03;
params_rel15->rnti_type = NFAPI_NR_RNTI_RA;
params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0;
//params_rel15->aggregation_level = 1;
LOG_I(MAC, "DCI type 1 params: rmsi_pdcch_config %d, rnti %d, rnti_type %d, dci_format %d\n \
coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \
ss params : nb_ss_sets_per_slot %d, first symb %d, nb_slots %d, sfn_mod2 %d, first slot %d\n",
0,
params_rel15->rnti,
params_rel15->rnti_type,
params_rel15->dci_format,
params_rel15->mux_pattern,
params_rel15->n_rb,
params_rel15->n_symb,
params_rel15->rb_offset,
params_rel15->nb_ss_sets_per_slot,
params_rel15->first_symbol,
params_rel15->nb_slots,
params_rel15->sfn_mod2,
params_rel15->first_slot);
dl_req->number_dci++;
dl_req->number_pdu++;
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;
}
}
@@ -33,7 +33,7 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_gNB/mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+3 -3
View File
@@ -31,8 +31,8 @@
#ifndef __LAYER2_NR_MAC_PROTO_H__
#define __LAYER2_NR_MAC_PROTO_H__
#include "mac.h"
#include "PHY/defs_nr_common.h"
#include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h"
void mac_top_init_gNB(void);
@@ -59,4 +59,4 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
@@ -35,8 +35,8 @@
/*@}*/
#ifndef __LAYER2_NR_MAC_DEFS_H__
#define __LAYER2_NR_MAC_DEFS_H__
#ifndef __LAYER2_NR_MAC_GNB_H__
#define __LAYER2_NR_MAC_GNB_H__
#include <stdio.h>
#include <stdlib.h>
@@ -53,13 +53,16 @@
#include "PHY/TOOLS/time_meas.h"
#include "PHY/defs_common.h" // for PRACH_RESOURCES_t
#include "PHY/defs_gNB.h"
#include "targets/ARCH/COMMON/common_lib.h"
#include "LAYER2/MAC/mac.h" // temporary
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/MAC/mac_extern.h"
#include "common/ran_context.h"
/*! \brief eNB common channels */
/*! \brief gNB common channels */
typedef struct {
int physCellId;
int p_gNB;
@@ -164,4 +167,4 @@ typedef struct gNB_MAC_INST_s {
time_stats_t schedule_pch;
} gNB_MAC_INST;
#endif /*__LAYER2_NR_MAC_DEFS_H__ */
#endif /*__LAYER2_NR_MAC_GNB_H__ */
+2 -2
View File
@@ -148,7 +148,8 @@ int8_t nr_ue_dl_indication(nr_downlink_indication_t *dl_info){
if(dl_info->dci_ind != NULL){
printf("[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
for(i=0; dl_info->dci_ind->number_of_dcis; ++i){
for(i=0; i<dl_info->dci_ind->number_of_dcis; ++i){
//printf(">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
fapi_nr_dci_pdu_rel15_t *dci = &dl_info->dci_ind->dci_list[i].dci;
ret_mask |= (handle_dci(
@@ -199,7 +200,6 @@ int8_t nr_ue_dl_indication(nr_downlink_indication_t *dl_info){
break;
}*/
//(dl_info->dci_list+i)->rnti
+1 -1
View File
@@ -18,7 +18,7 @@
* contact@openairinterface.org
*/
/*! \file nr_rrc_defs.h
/*! \file RRC/NR/nr_rrc_defs.h
* \brief NR RRC struct definitions and function prototypes
* \author Navid Nikaein, Raymond Knopp, WEI-TAI CHEN
* \date 2010 - 2014, 2018
+1 -1
View File
@@ -1039,7 +1039,7 @@ extern "C" {
if(device_adds.size() == 0) {
double usrp_master_clock = 184.32e6;
std::string args = "type=x300";
std::string args = "type=x300, addr=192.168.30.2";
// workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
@@ -52,10 +52,11 @@ gNBs =
DL_FreqBandIndicatorNR = 15;
DL_absoluteFrequencyPointA = 15;
DL_offsetToCarrier = 15;
DL_SCS_SubcarrierSpacing = "kHz15";
DL_SCS_SubcarrierSpacing = "kHz30";
DL_SCS_SpecificCarrier_k0 = 0;
DL_carrierBandwidth = 15;
DL_locationAndBandwidth = 15;
DL_BWP_SubcarrierSpacing = "kHz15";
DL_BWP_SubcarrierSpacing = "kHz30";
DL_BWP_prefix_type = "NORMAL";
UL_FreqBandIndicatorNR = 15;
UL_absoluteFrequencyPointA = 13;
@@ -63,10 +64,11 @@ gNBs =
UL_p_Max = -1;
UL_frequencyShift7p5khz = "TRUE";
UL_offsetToCarrier = 10;
UL_SCS_SubcarrierSpacing = "kHz15";
UL_SCS_SubcarrierSpacing = "kHz30";
UL_SCS_SpecificCarrier_k0 = 0;
UL_carrierBandwidth = 15;
UL_locationAndBandwidth = 15;
UL_BWP_SubcarrierSpacing = "kHz15";
UL_BWP_SubcarrierSpacing = "kHz30";
UL_BWP_prefix_type = "NORMAL";
UL_timeAlignmentTimerCommon = "infinity";
ServingCellConfigCommon_n_TimingAdvanceOffset = "n0"
@@ -101,7 +103,7 @@ gNBs =
prach_RootSequenceIndex_choice = "l839";
prach_RootSequenceIndex_l839 = 0;
prach_RootSequenceIndex_l139 = 0;
prach_msg1_SubcarrierSpacing = "kHz15";
prach_msg1_SubcarrierSpacing = "kHz30";
restrictedSetConfig = "unrestrictedSet";
msg3_transformPrecoding = "ENABLE";
prach_ConfigurationIndex = 10;
@@ -130,7 +132,7 @@ gNBs =
symbolsInResourceBlock = "oneSlot";
periodicityAndPattern = 2;
RateMatchPattern_controlResourceSet = 5;
RateMatchPattern_subcarrierSpacing = "kHz15";
RateMatchPattern_subcarrierSpacing = "kHz30";
RateMatchPattern_mode = "dynamic";
controlResourceSetZero = 0;
searchSpaceZero = 0;
+6 -7
View File
@@ -181,21 +181,17 @@ static inline int rxtx(PHY_VARS_gNB *gNB,gNB_rxtx_proc_t *proc, char *thread_nam
gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
gNB->UL_INFO.cqi_ind.number_of_cqis
) {
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n",
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
gNB->UL_INFO.cqi_ind.number_of_cqis,
proc->frame_rx, proc->subframe_rx,
proc->frame_tx, proc->subframe_tx, gNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols);
proc->frame_tx, proc->subframe_tx);
}
}
if (nfapi_mode == 1 && gNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) {
LOG_E(PHY, "gNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0");
return 0;
}
/// NR disabling
// ****************************************
@@ -920,7 +916,10 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB = RC.gNB[inst][CC_id];
gNB->abstraction_flag = 0;
gNB->single_thread_flag = single_thread_flag;
/*nr_polar_init(&gNB->nrPolar_params,
NR_POLAR_PBCH_MESSAGE_TYPE,
NR_POLAR_PBCH_PAYLOAD_BITS,
NR_POLAR_PBCH_AGGREGATION_LEVEL);*/
LOG_I(PHY,"Initializing gNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
#ifndef OCP_FRAMEWORK
+100 -40
View File
@@ -134,6 +134,9 @@ int connect_rau(RU_t *ru);
extern uint16_t sf_ahead;
extern int emulate_rf;
extern int numerology;
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -587,7 +590,7 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
RU_proc_t *proc = &ru->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full;
uint32_t symbol_number,symbol_mask,symbol_mask_full=0;
int subframe_tx,frame_tx;
LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru);
@@ -669,6 +672,34 @@ void fh_if4p5_north_out(RU_t *ru) {
}
static void* emulatedRF_thread(void* param) {
RU_proc_t *proc = (RU_proc_t *) param;
int microsec = 500; // length of time to sleep, in miliseconds
struct timespec req = {0};
req.tv_sec = 0;
req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2;
cpu_set_t cpuset;
CPU_SET(1,&cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
int policy;
struct sched_param sparam;
memset(&sparam, 0, sizeof(sparam));
sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
policy = SCHED_FIFO ;
pthread_setschedparam(pthread_self(), policy, &sparam);
wait_sync("emulatedRF_thread");
while(!oai_exit){
nanosleep(&req, (struct timespec *)NULL);
pthread_mutex_lock(&proc->mutex_emulateRF);
++proc->instance_cnt_emulateRF;
pthread_mutex_unlock(&proc->mutex_emulateRF);
pthread_cond_signal(&proc->cond_emulateRF);
}
return 0;
}
void rx_rf(RU_t *ru,int *frame,int *subframe) {
RU_proc_t *proc = &ru->proc;
@@ -685,11 +716,18 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
old_ts = proc->timestamp_rx;
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
if(emulate_rf){
wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread");
rxs = fp->samples_per_tti;
}
else{
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
&ts,
rxp,
fp->samples_per_subframe,
ru->nb_rx);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
@@ -1360,26 +1398,37 @@ static void* ru_thread( void* param ) {
LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
// Start IF device if any
if (ru->start_if) {
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n");
if (ru->if_south == LOCAL_RF) ret = connect_rau(ru);
else ret = attach_rru(ru);
AssertFatal(ret==0,"Cannot connect to radio\n");
}
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
if(emulate_rf){
fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
}
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
else{
// Start IF device if any
if (ru->start_if) {
LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx);
AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n");
if (ru->if_south == LOCAL_RF) ret = connect_rau(ru);
else ret = attach_rru(ru);
AssertFatal(ret==0,"Cannot connect to radio\n");
}
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
}
if (setup_RU_buffers(ru)!=0) {
printf("Exiting, cannot initialize RU Buffers\n");
exit(-1);
}
}
LOG_I(PHY, "Signaling main thread that RU %d is ready\n",ru->idx);
@@ -1390,28 +1439,30 @@ static void* ru_thread( void* param ) {
wait_sync("ru_thread");
// Start RF device if any
if (ru->start_rf) {
if (ru->start_rf(ru) != 0)
LOG_E(HW,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
}
else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
if(!emulate_rf){
// Start RF device if any
if (ru->start_rf) {
if (ru->start_rf(ru) != 0)
LOG_E(HW,"Could not start the RF device\n");
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
}
else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
// if an asnych_rxtx thread exists
// wakeup the thread because the devices are ready at this point
// if an asnych_rxtx thread exists
// wakeup the thread because the devices are ready at this point
if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
}
else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
pthread_mutex_lock(&proc->mutex_asynch_rxtx);
proc->instance_cnt_asynch_rxtx=0;
pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
pthread_cond_signal(&proc->cond_asynch_rxtx);
}
else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
// if this is a slave RRU, try to synchronize on the DL frequency
if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
}
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
@@ -1470,9 +1521,12 @@ static void* ru_thread( void* param ) {
// do OFDM if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
if (!emulate_rf)
{
// do outgoing fronthaul (south) if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
}
if (ru->fh_north_out) ru->fh_north_out(ru);
}
@@ -1593,7 +1647,7 @@ void init_RU_proc(RU_t *ru) {
int i=0;
RU_proc_t *proc;
pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL;// *attr_synch=NULL;
pthread_attr_t *attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL, *attr_emulateRF=NULL;// *attr_synch=NULL;
//pthread_attr_t *attr_fep=NULL;
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
//pthread_attr_t *attr_prach_br=NULL;
@@ -1611,6 +1665,7 @@ void init_RU_proc(RU_t *ru) {
proc->instance_cnt_synch = -1; ;
proc->instance_cnt_FH = -1;
proc->instance_cnt_asynch_rxtx = -1;
proc->instance_cnt_emulateRF = -1;
proc->first_rx = 1;
proc->first_tx = 1;
proc->frame_offset = 0;
@@ -1623,15 +1678,18 @@ void init_RU_proc(RU_t *ru) {
pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
pthread_mutex_init( &proc->mutex_synch,NULL);
pthread_mutex_init( &proc->mutex_FH,NULL);
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
pthread_mutex_init( &proc->mutex_gNBs, NULL);
pthread_cond_init( &proc->cond_prach, NULL);
pthread_cond_init( &proc->cond_FH, NULL);
pthread_cond_init( &proc->cond_emulateRF, NULL);
pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
pthread_cond_init( &proc->cond_synch,NULL);
pthread_cond_init( &proc->cond_gNBs, NULL);
pthread_attr_init( &proc->attr_FH);
pthread_attr_init( &proc->attr_emulateRF);
pthread_attr_init( &proc->attr_prach);
pthread_attr_init( &proc->attr_synch);
pthread_attr_init( &proc->attr_asynch_rxtx);
@@ -1640,13 +1698,15 @@ void init_RU_proc(RU_t *ru) {
#ifndef DEADLINE_SCHEDULER
attr_FH = &proc->attr_FH;
attr_emulateRF = &proc->attr_emulateRF;
attr_prach = &proc->attr_prach;
//attr_synch = &proc->attr_synch;
attr_asynch = &proc->attr_asynch_rxtx;
#endif
pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
if(emulate_rf)
pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
if (ru->function == NGFI_RRU_IF4p5) {
pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
///tmp deactivation of synch thread
+5 -4
View File
@@ -35,9 +35,9 @@
#include "msc.h"
#include "PHY/types.h"
#include "common/ran_context.h"
#include "PHY/defs_gNB.h"
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/load_module_shlib.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -206,7 +206,7 @@ extern void init_eNB_afterRU(void);
int transmission_mode=1;
int emulate_rf = 0;
//int numerology = 0;
int numerology = 0;
int codingw = 0;
//int fepw = 0;
@@ -394,8 +394,8 @@ static void *scope_thread(void *arg) {
for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
if ((ue_cnt<scope_enb_num_ue)) {
phy_scope_eNB(form_enb[CC_id][ue_cnt],
RC.gNB[0][CC_id],
UE_id);
RC.gNB[0][CC_id],
UE_id);
ue_cnt++;
}
}
@@ -884,6 +884,7 @@ static void wait_nfapi_init(char *thread_name) {
int main( int argc, char **argv )
{
crcTableInit();
int i;
#if defined (XFORMS)
//void *status;
+3
View File
@@ -86,6 +86,8 @@
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -166,6 +168,7 @@
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
}
+18 -7
View File
@@ -60,8 +60,8 @@
#include "T.h"
extern double cpuf;
static nfapi_nr_config_request_t config_t;
static nfapi_nr_config_request_t* config =&config_t;
//static nfapi_nr_config_request_t config_t;
//static nfapi_nr_config_request_t* config =&config_t;
/*
* NR SLOT PROCESSING SEQUENCE
@@ -279,9 +279,10 @@ void init_UE(int nb_inst)
NR_UE_MAC_INST_t *mac_inst;
for (inst=0; inst < nb_inst; inst++) {
// UE->rfdevice.type = NONE_DEV;
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
//PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]);
PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0);
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0];
AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n");
nr_l3_init_ue();
@@ -291,6 +292,11 @@ void init_UE(int nb_inst)
mac_inst->if_module = UE->if_inst;
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
//init_UE_threads(inst);
//UE = PHY_vars_UE_g[inst][0];
AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
&UE->proc.attr_ue,
@@ -655,12 +661,16 @@ static void *UE_thread_rxn_txnp4(void *arg) {
phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
phy_procedures_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
printf(">>> nr_ue_pdcch_procedures ended\n");
#endif
}
#if UE_TIMING_TRACE
start_meas(&UE->generic_stat);
#endif
printf(">>> mac init\n");
if (UE->mac_enabled==1) {
// trigger L2 to run ue_scheduler thru IF module
@@ -673,8 +683,8 @@ static void *UE_thread_rxn_txnp4(void *arg) {
UE->ul_indication.slot = 0; // to be fill
UE->ul_indication.frame = 0; // to be fill
// [TODO] mapping right after NR initial sync
//UE->ul_indication.frame = ;
//UE->ul_indication.slot = ;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
@@ -730,6 +740,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
#if UE_TIMING_TRACE
stop_meas(&UE->generic_stat);
#endif
printf(">>> mac ended\n");
// Prepare the future Tx data
#if 0
@@ -784,7 +795,7 @@ void *UE_thread(void *arg) {
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
// int tx_enabled = 0;
int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
openair0_timestamp timestamp,timestamp1;
openair0_timestamp timestamp;
void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
int start_rx_stream = 0;
int i;
@@ -991,7 +1002,7 @@ void *UE_thread(void *arg) {
if ( first_symbols > 0 )
AssertFatal(first_symbols ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
&timestamp1,
&timestamp,
(void**)UE->common_vars.rxdata,
first_symbols,
UE->frame_parms.nb_antennas_rx),"");
+150 -98
View File
@@ -121,6 +121,8 @@ uint32_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
//static char *conf_config_file_name = NULL;
#if defined(ENABLE_ITTI)
static char *itti_dump_file = NULL;
#endif
@@ -168,6 +170,9 @@ int codingw = 0;
int fepw = 0;
int rx_input_level_dBm;
//static int online_log_messages=0;
#ifdef XFORMS
extern int otg_enabled;
static char do_forms=0;
@@ -354,7 +359,7 @@ void exit_fun(const char* s) {
void reset_stats(FL_OBJECT *button, long arg) {
int i,j,k;
//int i,j,k;
/*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
@@ -388,10 +393,10 @@ static void *scope_thread(void *arg) {
# ifdef ENABLE_XFORMS_WRITE_STATS
FILE *UE_stats, *eNB_stats;
# endif
int len = 0;
//int len = 0;
struct sched_param sched_param;
int UE_id, CC_id;
int ue_cnt=0;
//int UE_id, CC_id;
//int ue_cnt=0;
sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
sched_setscheduler(0, SCHED_FIFO,&sched_param);
@@ -488,82 +493,128 @@ void *l2l1_task(void *arg) {
extern int16_t dlsch_demod_shift;
static void get_options (int argc, char **argv) {
int CC_id;
int tddflag, nonbiotflag;
char *loopfile=NULL;
int dumpframe;
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv;
nfapi_nr_config_request_t *config[MAX_NUM_CCs];
static void get_options(void) {
int CC_id;
int tddflag, nonbiotflag;
char *loopfile=NULL;
int dumpframe;
uint32_t online_log_messages;
uint32_t glog_level, glog_verbosity;
uint32_t start_telnetsrv;
paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] = CMDLINE_LOGPARAMS_DESC ;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
//set_default_frame_parms(config,frame_parms);
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
set_default_frame_parms(frame_parms);
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
if (strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
printf("Enabling OPT for PCAP with the following file %s \n",in_path);
}
if (strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
printf("Enabling OPT for wireshark for local interface");
}
if (strlen(in_path) > 0) {
opt_type = OPT_PCAP;
opt_enabled=1;
printf("Enabling OPT for PCAP with the following file %s \n",in_path);
}
if (strlen(in_ip) > 0) {
opt_enabled=1;
opt_type = OPT_WIRESHARK;
printf("Enabling OPT for wireshark for local interface");
}
config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
set_glog_onlinelog(online_log_messages);
}
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0);
}
config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
set_glog_onlinelog(online_log_messages);
}
if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0);
}
paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
if (loopfile != NULL) {
printf("Input file for hardware emulation: %s",loopfile);
mode=loop_through_memory;
input_fd = fopen(loopfile,"r");
AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
}
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect;
if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
if (dumpframe > 0) mode = rx_dump_frame;
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
}
UE_scan=0;
if (tddflag > 0) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
frame_parms[CC_id]->frame_type = TDD;
}
/*if (frame_parms[0]->N_RB_DL !=0) {
if ( frame_parms[0]->N_RB_DL < 6 ) {
frame_parms[0]->N_RB_DL = 6;
printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 100 ) {
frame_parms[0]->N_RB_DL = 100;
printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
frame_parms[0]->N_RB_DL = 50;
printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
}
if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
frame_parms[0]->N_RB_DL = 25;
printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
}
UE_scan = 0;
frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
}
}*/
for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) {
tx_max_power[CC_id]=tx_max_power[0];
rx_gain[0][CC_id] = rx_gain[0][0];
tx_gain[0][CC_id] = tx_gain[0][0];
}
#if T_TRACER
paramdef_t cmdline_ttraceparams[] = CMDLINE_TTRACEPARAMS_DESC ;
config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);
paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);
#endif
paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC;
paramdef_t cmdline_ueparams[] = CMDLINE_UEPARAMS_DESC;
if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
// Here the configuration file is the XER encoded UE capabilities
// Read it in and store in asn1c data structures
sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME"));
printf("%s\n",uecap_xer);
uecap_xer_in=1;
} /* UE with config file */
#if defined(OAI_USRP) || defined(CPRIGW) || defined(OAI_ADRV9371_ZC706)
int clock_src;
#endif
config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
if (loopfile != NULL) {
printf("Input file for hardware emulation: %s",loopfile);
mode=loop_through_memory;
input_fd = fopen(loopfile,"r");
AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
}
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect;
if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
// Here the configuration file is the XER encoded UE capabilities
// Read it in and store in asn1c data structures
sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME"));
printf("%s\n",uecap_xer);
uecap_xer_in=1;
} /* UE with config file */
}
#if T_TRACER
@@ -593,8 +644,8 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
frame_parms[CC_id]->frame_type = FDD;
frame_parms[CC_id]->tdd_config = 3;
//frame_parms[CC_id]->tdd_config_S = 0;
frame_parms[CC_id]->N_RB_DL = 100;
frame_parms[CC_id]->N_RB_UL = 100;
frame_parms[CC_id]->N_RB_DL = 106;
frame_parms[CC_id]->N_RB_UL = 106;
frame_parms[CC_id]->Ncp = NORMAL;
//frame_parms[CC_id]->Ncp_UL = NORMAL;
frame_parms[CC_id]->Nid_cell = 0;
@@ -645,7 +696,7 @@ void init_openair0() {
openair0_cfg[card].mmapped_dma=mmapped_dma;
openair0_cfg[card].configFilename = NULL;
if(frame_parms[0]->N_RB_DL == 100) {
if(frame_parms[0]->N_RB_DL == 106) {
if (numerology==0) {
if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=23.04e6;
@@ -737,14 +788,14 @@ void init_openair0() {
}
int main( int argc, char **argv ) {
int i,j,k,aa,re;
int i;//j,k,aa,re;
#if defined (XFORMS)
void *status;
#endif
int CC_id;
uint8_t abstraction_flag=0;
uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
//uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
#if defined (XFORMS)
int ret;
@@ -772,12 +823,13 @@ int main( int argc, char **argv ) {
set_latency_target();
// set default parameters
set_default_frame_parms(frame_parms);
// initialize logging
logInit();
// get options and fill parameters from configuration file
get_options (); //Command-line options, enb_properties
#if T_TRACER
T_Config_Init();
#endif
@@ -822,7 +874,7 @@ int main( int argc, char **argv ) {
#endif
// get options and fill parameters from configuration file
get_options (argc, argv); //Command-line options, enb_properties
get_options (); //Command-line options, enb_properties
if (opt_type != OPT_NONE) {
radio_type_t radio_type;
@@ -858,7 +910,6 @@ int main( int argc, char **argv ) {
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
// set_default_frame_parms(frame_parms);//
// init the parameters
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -868,14 +919,9 @@ int main( int argc, char **argv ) {
frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx);
//set_default_frame_parms(config[CC_id],frame_parms[CC_id]);
//init_ul_hopping(frame_parms[CC_id]);
nr_init_frame_parms_ue(frame_parms[CC_id]);
printf("after init frame_parms %d\n",frame_parms[CC_id]->ofdm_symbol_size);
// phy_init_top(frame_parms[CC_id]);
phy_init_nr_top(frame_parms[CC_id]);
//phy_init_nr_top(frame_parms[CC_id]);
}
@@ -941,13 +987,13 @@ int main( int argc, char **argv ) {
if (UE[CC_id]->mac_enabled == 1)
{
//UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234;
//UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234;
UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234;
UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234;
}
else
{
//UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235;
//UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235;
UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235;
UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235;
}
rx_gain[CC_id][0] = 81;
@@ -1019,6 +1065,9 @@ int main( int argc, char **argv ) {
LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
#endif
//openair0_cfg[0].log_level = glog_level;
/*int eMBMS_active=0;
if (node_function[0] <= NGFI_RAU_IF4p5) { // don't initialize L2 for RRU
LOG_I(PHY,"Intializing L2\n");
@@ -1053,6 +1102,9 @@ int main( int argc, char **argv ) {
mac_xface->mrbch_phy_sync_failure (0, 0, 0);
}*/
// init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
mlockall(MCL_CURRENT | MCL_FUTURE);
@@ -1065,13 +1117,13 @@ int main( int argc, char **argv ) {
if (do_forms==1) {
fl_initialize (&argc, argv, NULL, 0, 0);
//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, "LTE DL SCOPE UE");
fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
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");
fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
/*
if (openair_daq_vars.use_ia_receiver) {