Merge branch 'integration_2025_w05' into 'develop'
Integration: `2025.w05` Closes #885 See merge request oai/openairinterface5g!3233 * !3102 Dockerized development environment * !3185 Add IQ file recording and IQ file viewer to ImScope * !3218 more layer1 cleaning * !3224 Ensure execution of processSlotTX in order in NR UE * !3231 Bugfix in frame and slot setting for ULSCH beam allocation * !3229 Verify the integrity protection of the RRCReestablishment message * !3230 FHI72: fix for single distributed antenna array for xran F release * !2984 NAS 5GS refactor * !3235 Parametrized JenkinsNode and JenkinsResource * !2799 Changes to support multiple TDD patterns * !3208 Downgrade gNB power limit LOG from "warning" to "debug"
This commit is contained in:
+5
-84
@@ -298,6 +298,7 @@ message(STATUS "Selected KPM Version: ${KPM_VERSION}")
|
||||
|
||||
|
||||
add_boolean_option(ENABLE_IMSCOPE OFF "Enable phy scope based on imgui" OFF)
|
||||
add_boolean_option(ENABLE_IMSCOPE_RECORD OFF "Enable recording IQ data for imscope" OFF)
|
||||
|
||||
##################################################
|
||||
# ASN.1 grammar C code generation & dependencies #
|
||||
@@ -779,9 +780,6 @@ add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c ${OPENAIR1_DIR}/PHY
|
||||
set(PHY_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sldch.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slsch.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/get_pmi.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/group_hopping.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c
|
||||
@@ -840,13 +838,9 @@ set(PHY_SRC
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pmch.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_decoding.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/uci_tools.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
|
||||
# ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/lte_init.c
|
||||
)
|
||||
@@ -917,7 +911,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
|
||||
${OPENAIR1_DIR}/PHY/nr_phy_common/src/nr_phy_common_csirs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/refsig.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
||||
)
|
||||
@@ -1114,7 +1107,6 @@ set(L2_SRC
|
||||
${PDCP_DIR}/pdcp_util.c
|
||||
${PDCP_DIR}/pdcp_security.c
|
||||
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
|
||||
# ${RRC_DIR}/rrc_UE.c
|
||||
${RRC_DIR}/rrc_eNB.c
|
||||
${RRC_DIR}/rrc_eNB_endc.c
|
||||
${RRC_DIR}/rrc_eNB_S1AP.c
|
||||
@@ -1129,7 +1121,6 @@ set(L2_SRC
|
||||
|
||||
set(L2_RRC_SRC
|
||||
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
|
||||
# ${RRC_DIR}/rrc_UE.c
|
||||
${RRC_DIR}/rrc_eNB.c
|
||||
${RRC_DIR}/rrc_eNB_endc.c
|
||||
${RRC_DIR}/rrc_eNB_S1AP.c
|
||||
@@ -1368,6 +1359,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs)
|
||||
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
|
||||
target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc)
|
||||
target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures nr_ue_ra_procedures)
|
||||
target_link_libraries(NR_L2_UE PRIVATE nr_nas)
|
||||
|
||||
add_library(MAC_NR_COMMON
|
||||
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
|
||||
@@ -1412,6 +1404,7 @@ add_library(SCTP_CLIENT ${SCTP_SRC})
|
||||
target_link_libraries(SCTP_CLIENT PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
set(NAS_SRC ${OPENAIR3_DIR}/NAS/)
|
||||
|
||||
set(libnas_api_OBJS
|
||||
${NAS_SRC}COMMON/API/NETWORK/as_message.c
|
||||
${NAS_SRC}COMMON/API/NETWORK/nas_message.c
|
||||
@@ -1451,10 +1444,6 @@ set(libnas_emm_msg_OBJS
|
||||
${NAS_SRC}COMMON/EMM/MSG/UplinkNasTransport.c
|
||||
)
|
||||
|
||||
set(libnas_fgs_msg_OBJS
|
||||
${NAS_SRC}COMMON/EMM/MSG/fgs_service_request.c
|
||||
)
|
||||
|
||||
set(libnas_esm_msg_OBJS
|
||||
${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.c
|
||||
${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.c
|
||||
@@ -1643,61 +1632,6 @@ set(libnas_ue_esm_sap_OBJS
|
||||
${NAS_SRC}UE/ESM/SAP/esm_sap.c
|
||||
)
|
||||
|
||||
set(libnrnas_emm_msg_OBJS
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c
|
||||
${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c
|
||||
${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishmentAccept.c
|
||||
${NAS_SRC}COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c
|
||||
)
|
||||
|
||||
set(libnrnas_ies_OBJS
|
||||
${NAS_SRC}COMMON/IES/ExtendedProtocolDiscriminator.c
|
||||
${NAS_SRC}COMMON/IES/FGSMobileIdentity.c
|
||||
${NAS_SRC}COMMON/IES/FGSRegistrationType.c
|
||||
${NAS_SRC}COMMON/IES/SpareHalfOctet.c
|
||||
${NAS_SRC}COMMON/IES/FGSRegistrationResult.c
|
||||
${NAS_SRC}COMMON/IES/FGMMCapability.c
|
||||
${NAS_SRC}COMMON/IES/NrUESecurityCapability.c
|
||||
${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c
|
||||
${NAS_SRC}COMMON/IES/SORTransparentContainer.c
|
||||
)
|
||||
|
||||
add_library(LIB_NAS_SIMUE
|
||||
${NAS_SRC}UE/nas_itti_messaging.c
|
||||
${NAS_SRC}UE/nas_network.c
|
||||
${NAS_SRC}UE/nas_parser.c
|
||||
${NAS_SRC}UE/nas_proc.c
|
||||
${NAS_SRC}UE/nas_user.c
|
||||
${NAS_SRC}NR_UE/nr_nas_msg.c
|
||||
${libnas_api_OBJS}
|
||||
${libnas_ue_api_OBJS}
|
||||
${libnas_emm_msg_OBJS}
|
||||
${libnas_fgs_msg_OBJS}
|
||||
${libnas_esm_msg_OBJS}
|
||||
${libnas_ies_OBJS}
|
||||
${libnas_utils_OBJS}
|
||||
${libnas_ue_emm_OBJS}
|
||||
${libnas_ue_emm_sap_OBJS}
|
||||
${libnas_ue_esm_OBJS}
|
||||
${libnas_ue_esm_sap_OBJS}
|
||||
${libnrnas_emm_msg_OBJS}
|
||||
${libnrnas_ies_OBJS}
|
||||
$<TARGET_OBJECTS:ds>
|
||||
)
|
||||
target_include_directories(LIB_NAS_SIMUE PRIVATE ${OPENAIR_DIR}/common/utils/ds/)
|
||||
target_link_libraries(LIB_NAS_SIMUE PRIVATE lte_rrc)
|
||||
|
||||
|
||||
|
||||
set(NAS_SIM_LIB LIB_NAS_SIMUE)
|
||||
target_link_libraries(LIB_NAS_SIMUE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
add_library(LIB_NAS_UE
|
||||
${NAS_SRC}UE/nas_itti_messaging.c
|
||||
${NAS_SRC}UE/nas_network.c
|
||||
@@ -1737,15 +1671,6 @@ set (NBIOT_SOURCES
|
||||
)
|
||||
add_library(NB_IoT MODULE ${NBIOT_SOURCES} )
|
||||
|
||||
add_library(LIB_5GNAS_GNB
|
||||
${NAS_SRC}/COMMON/nr_common.c
|
||||
${OPENAIR3_DIR}//UICC/usim_interface.c
|
||||
)
|
||||
|
||||
target_include_directories(LIB_5GNAS_GNB PRIVATE ${OPENAIR_DIR}/common/utils/ds/)
|
||||
target_link_libraries(LIB_5GNAS_GNB PRIVATE SECURITY)
|
||||
target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
# Simulation library
|
||||
##########################
|
||||
set (SIMUSRC
|
||||
@@ -1963,7 +1888,6 @@ add_executable(nr-uesoftmodem
|
||||
${OPENAIR_DIR}/radio/COMMON/common_lib.c
|
||||
${OPENAIR_DIR}/radio/COMMON/record_player.c
|
||||
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
|
||||
)
|
||||
|
||||
@@ -1972,11 +1896,12 @@ target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
nr_rrc SECURITY UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB
|
||||
PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_LIB NFAPI_PNF_LIB
|
||||
NFAPI_USER_LIB MISC_NFAPI_NR_LIB
|
||||
ITTI LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} SIMU shlib_loader
|
||||
ITTI SIMU shlib_loader
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt nr_ue_phy_meas)
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE ${T_LIB})
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE nr_nas lib_uicc usim_lib)
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
# force the generation of ASN.1 so that we don't need to wait during the build
|
||||
@@ -2169,10 +2094,6 @@ foreach(myExe s1ap
|
||||
)
|
||||
endforeach(myExe)
|
||||
|
||||
# to be added
|
||||
#../targets/TEST/PDCP/test_pdcp.c
|
||||
#../targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
|
||||
|
||||
#ensure that the T header files are generated before targets depending on them
|
||||
if (${T_TRACER})
|
||||
foreach(i
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
def node = "porcepix"
|
||||
def resource = "CI-NEU-CI"
|
||||
def node = "${params.JenkinsNode}"
|
||||
def resource = "${params.JenkinsResource}"
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -66,7 +66,7 @@ gNBs =
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
prach_ConfigurationIndex = 154;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
@@ -133,11 +133,21 @@ gNBs =
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
# ext: 8=ms3, 9=ms4
|
||||
dl_UL_TransmissionPeriodicity = 8;
|
||||
nrofDownlinkSlots = 3;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
# pattern2
|
||||
pattern2: {
|
||||
dl_UL_TransmissionPeriodicity2 = 4;
|
||||
nrofDownlinkSlots2 = 4;
|
||||
nrofDownlinkSymbols2 = 0;
|
||||
nrofUplinkSlots2 = 0;
|
||||
nrofUplinkSymbols2 = 0;
|
||||
};
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-SA-FR1-SC-FDMA-B200</htmlTabRef>
|
||||
<htmlTabName>40 MHz TDD SA with SC-FDMA</htmlTabName>
|
||||
<htmlTabRef>TEST-SA-FR1-SC-PATTERN2-FDMA-B200</htmlTabRef>
|
||||
<htmlTabName>40 MHz TDD (pattern2) SA with SC-FDMA</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
300000
|
||||
@@ -101,7 +101,7 @@
|
||||
</testCase>
|
||||
<testCase id="230101">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy gNB (TDD/Band78/40MHz/B200) with SC-FDMA in a container</desc>
|
||||
<desc>Deploy gNB (TDD/pattern2/Band78/40MHz/B200) with SC-FDMA in a container</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/sa_sc_b200_gnb</yaml_path>
|
||||
<eNB_instance>0</eNB_instance>
|
||||
<eNB_serverId>0</eNB_serverId>
|
||||
|
||||
@@ -46,7 +46,7 @@ BUILD_DOXYGEN=0
|
||||
DISABLE_HARDWARE_DEPENDENCY="False"
|
||||
CMAKE_BUILD_TYPE="RelWithDebInfo"
|
||||
CMAKE_CMD="$CMAKE"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_t2 ldpc_xdma websrv oai_iqplayer imscope"
|
||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_t2 ldpc_xdma websrv oai_iqplayer imscope imscope_record"
|
||||
TARGET_LIST=""
|
||||
BUILD_TOOL_OPT="-j$(nproc)"
|
||||
|
||||
|
||||
@@ -288,6 +288,12 @@ typedef struct protocol_ctxt_s {
|
||||
|
||||
#define CHECK_CTXT_ARGS(CTXT_Pp)
|
||||
|
||||
|
||||
static inline int ceil_mod(const unsigned int v, const unsigned int mod)
|
||||
{
|
||||
return ((v + mod - 1) / mod) * mod;
|
||||
}
|
||||
|
||||
#define exit_fun(msg) exit_function(__FILE__, __FUNCTION__, __LINE__, "exit_fun", OAI_EXIT_NORMAL)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -109,8 +109,6 @@ static const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2]
|
||||
/* 63 */ {{272, 1}, {16, 17}, {8, 2}, {4, 2}},
|
||||
};
|
||||
|
||||
const char *duplex_mode[]={"FDD","TDD"};
|
||||
|
||||
static const uint8_t bit_reverse_table_256[] = {
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8,
|
||||
0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
||||
@@ -126,6 +124,36 @@ static const uint8_t bit_reverse_table_256[] = {
|
||||
0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF};
|
||||
|
||||
simde__m128i byte2bit16_lut[256];
|
||||
void init_byte2bit16(void)
|
||||
{
|
||||
for (int s = 0; s < 256; s++) {
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], s & 1, 0);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 1) & 1, 1);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 2) & 1, 2);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 3) & 1, 3);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 4) & 1, 4);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 5) & 1, 5);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 6) & 1, 6);
|
||||
byte2bit16_lut[s] = simde_mm_insert_epi16(byte2bit16_lut[s], (s >> 7) & 1, 7);
|
||||
}
|
||||
}
|
||||
|
||||
simde__m128i byte2m128i[256];
|
||||
void init_byte2m128i(void) {
|
||||
|
||||
for (int s=0;s<256;s++) {
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*(s&1)),0);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>1)&1)),1);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>2)&1)),2);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>3)&1)),3);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>4)&1)),4);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>5)&1)),5);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>6)&1)),6);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>7)&1)),7);
|
||||
}
|
||||
}
|
||||
|
||||
void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out)
|
||||
{
|
||||
DevAssert(in != NULL);
|
||||
@@ -676,9 +704,12 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn)
|
||||
return frequency;
|
||||
}
|
||||
|
||||
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols)
|
||||
/**
|
||||
* @brief Get the slot index within the period
|
||||
*/
|
||||
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs)
|
||||
{
|
||||
return (nrofDownlinkSlots + (nrofDownlinkSymbols != 0 && nrofUplinkSymbols == 0));
|
||||
return slot % fs->numb_slots_period;
|
||||
}
|
||||
|
||||
int get_dmrs_port(int nl, uint16_t dmrs_ports)
|
||||
@@ -704,7 +735,7 @@ frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
|
||||
{
|
||||
int32_t delta_duplex = get_delta_duplex(current_band, scs_index);
|
||||
frame_type_t current_type = delta_duplex == 0 ? TDD : FDD;
|
||||
LOG_D(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
|
||||
LOG_D(NR_MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode_txt[current_type], delta_duplex);
|
||||
return current_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,29 @@ typedef enum frequency_range_e {
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
#define MAX_NUM_SLOTS_ALLOWED 80 // up to numerology 3 (120 KHz SCS) is supported
|
||||
enum slot_type { TDD_NR_DOWNLINK_SLOT, TDD_NR_UPLINK_SLOT, TDD_NR_MIXED_SLOT };
|
||||
|
||||
typedef struct tdd_bitmap {
|
||||
enum slot_type slot_type;
|
||||
uint8_t num_dl_symbols;
|
||||
uint8_t num_ul_symbols;
|
||||
} tdd_bitmap_t;
|
||||
|
||||
typedef struct tdd_period_config_s {
|
||||
tdd_bitmap_t tdd_slot_bitmap[MAX_NUM_SLOTS_ALLOWED];
|
||||
uint8_t num_dl_slots;
|
||||
uint8_t num_ul_slots;
|
||||
} tdd_period_config_t;
|
||||
|
||||
typedef struct frame_structure_s {
|
||||
tdd_period_config_t period_cfg;
|
||||
int8_t numb_slots_frame;
|
||||
int8_t numb_slots_period;
|
||||
int8_t numb_period_frame;
|
||||
bool is_tdd;
|
||||
} frame_structure_t;
|
||||
|
||||
typedef struct {
|
||||
/// Time shift in number of samples estimated based on DMRS-PDSCH/PUSCH
|
||||
int est_delay;
|
||||
@@ -183,6 +206,15 @@ uint32_t nr_timer_elapsed_time(const NR_timer_t *timer);
|
||||
int set_default_nta_offset(frequency_range_t freq_range, uint32_t samples_per_subframe);
|
||||
extern const nr_bandentry_t nr_bandtable[];
|
||||
|
||||
extern simde__m128i byte2bit16_lut[256];
|
||||
void init_byte2bit16(void);
|
||||
void init_byte2m128i(void);
|
||||
|
||||
static inline simde__m128i byte2bit16(uint8_t b)
|
||||
{
|
||||
return byte2bit16_lut[b];
|
||||
}
|
||||
|
||||
static inline int get_num_dmrs(uint16_t dmrs_mask )
|
||||
{
|
||||
int num_dmrs=0;
|
||||
@@ -210,7 +242,6 @@ void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out);
|
||||
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
|
||||
uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw);
|
||||
|
||||
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols);
|
||||
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
|
||||
int get_SLIV(uint8_t S, uint8_t L);
|
||||
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
|
||||
@@ -256,11 +287,12 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_
|
||||
unsigned short get_m_srs(int c_srs, int b_srs);
|
||||
unsigned short get_N_b_srs(int c_srs, int b_srs);
|
||||
|
||||
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
// Align up to a multiple of 16
|
||||
#define ALIGN_UP_16(a) ((a + 15) & ~15)
|
||||
static const char *const duplex_mode_txt[] = {"FDD", "TDD"};
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef min
|
||||
|
||||
+5
-32
@@ -1133,7 +1133,7 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/UICC/usim_interface.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/ocp-gtpu/gtp_itf.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/nr_nas_msg.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/nr_nas_msgc \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/nr_nas_msg.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/UE/nas_itti_messaging.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/UE/user_defs.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/UE/EMM/emm_proc.h \
|
||||
@@ -1274,12 +1274,10 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/emm_msg.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachReject.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/SecurityModeReject.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/UplinkNasTransport.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AuthenticationFailure.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AuthenticationResponse.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachComplete.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/GutiReallocationComplete.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/DownlinkNasTransport.h \
|
||||
@@ -1289,7 +1287,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachReject.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachAccept.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/ServiceReject.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachComplete.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachRequest.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c \
|
||||
@@ -1301,17 +1298,14 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachAccept.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/IdentityResponse.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/GutiReallocationComplete.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/ServiceRequest.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/IdentityRequest.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/DetachAccept.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AttachRequest.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/EmmStatus.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AuthenticationFailure.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/AuthenticationReject.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateAccept.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.h \
|
||||
@@ -1321,13 +1315,14 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/IdentityResponse.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/emm_cause.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/EmmInformation.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/IdentityRequest.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/GutiReallocationCommand.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/5GS/5GMM/MSG \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/5GS/5GMM/IES \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/5GS/5GSM \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/NR_UE/5GS/5GSM/MSG \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/parser.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/device.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/device.c \
|
||||
@@ -1353,7 +1348,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationParameterRand.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProtocolDiscriminator.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/CsfbResponse.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmCause.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProcedureTransactionIdentity.h \
|
||||
@@ -1367,7 +1361,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LlcServiceAccessPointIdentifier.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TransactionIdentifier.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/GutiType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SupportedCodecList.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MobileStationClassmark3.c \
|
||||
@@ -1391,12 +1384,10 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/UeSecurityCapability.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ApnAggregateMaximumBitRate.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ImeisvRequest.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SpareHalfOctet.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PdnType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ShortMac.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MobileStationClassmark3.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TrafficFlowTemplate.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SORTransparentContainer.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasPagingIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasMessageContainer.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/Cli.h \
|
||||
@@ -1406,18 +1397,15 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/DetachType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EmergencyNumberList.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmMessageContainer.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationResult.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/GprsTimer.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TmsiStatus.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/IdentityType2.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsQualityOfService.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LocationAreaIdentification.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGCNasMessageContainer.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TrackingAreaIdentityList.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MsNetworkCapability.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ShortMac.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationResult.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationFailureParameter.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TrackingAreaIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EmmCause.h \
|
||||
@@ -1432,12 +1420,10 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationParameterAutn.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PdnAddress.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmInformationTransferFlag.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SpareHalfOctet.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/KsiAndSequenceNumber.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LocationAreaIdentification.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/QualityOfService.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProcedureTransactionIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NrUESecurityCapability.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SsCode.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsQualityOfService.h \
|
||||
@@ -1447,12 +1433,10 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsMobileIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MobileIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SsCode.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TrackingAreaIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsBearerIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasMessageContainer.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/DetachType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGMMCapability.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TmsiStatus.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MobileStationClassmark2.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MessageType.c \
|
||||
@@ -1466,13 +1450,10 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AdditionalUpdateType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasRequestType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsBearerContextStatus.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSMobileIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LcsClientIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSMobileIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/ServiceType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PagingIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/UeNetworkCapability.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NrUESecurityCapability.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationParameterAutn.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PdnAddress.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsUpdateType.h \
|
||||
@@ -1480,7 +1461,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PTmsiSignature.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PacketFlowIdentifier.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGCNasMessageContainer.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/PTmsiSignature.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsMobileIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/GutiType.h \
|
||||
@@ -1496,16 +1476,13 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasKeySetIdentifier.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsAttachResult.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AccessPointName.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGMMCapability.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AdditionalUpdateResult.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsAttachType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/UeNetworkCapability.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSDeregistrationType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmMessageContainer.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SecurityHeaderType.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmCause.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NasSecurityAlgorithms.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SORTransparentContainer.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LinkedEpsBearerIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AdditionalUpdateType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/MsNetworkFeatureSupport.c \
|
||||
@@ -1518,14 +1495,12 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsBearerIdentity.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EsmInformationTransferFlag.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/TimeZoneAndTime.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/FGSRegistrationType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsUpdateResult.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/EpsUpdateType.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/NetworkName.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/LinkedEpsBearerIdentity.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/IES/SupportedCodecList.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/NR_NAS_defs.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/milenage.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/ESM/MSG/EsmStatus.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextReject.h \
|
||||
@@ -1580,7 +1555,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/ESM/MSG/EsmInformationResponse.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextAccept.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/userDef.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/nr_common.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair3/UTILS/conversions.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/X2AP/x2ap_eNB_encoder.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/X2AP/x2ap_eNB_management_procedures.c \
|
||||
@@ -2085,7 +2059,6 @@ INPUT = \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/sss_nr.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/scrambling_luts.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/dmrs_nr.c \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/refsig_defs_ue.h \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/ptrs_nr.h \
|
||||
|
||||
+3
-1
@@ -24,7 +24,9 @@
|
||||
|
||||
The following features are valid for the gNB and the 5G-NR UE.
|
||||
|
||||
* Static TDD, FDD
|
||||
* Static TDD
|
||||
- Multi TDD pattern supported refer [TDD Configuration](NR_SA_Multi_TDD_Pattern.md)
|
||||
* Static FDD
|
||||
* Normal CP
|
||||
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
|
||||
* Bandwidths: 10, 20, 40, 60, 80, 100MHz
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@@ -240,3 +240,115 @@ here, *also they pertain to the DU*, i.e., the scheduler.
|
||||
options are 2, 4, 6, 8, 10, 12, 32; **32 is a Rel-17 features**)
|
||||
* `num_ulharq` (default 16): as `num_dlharq` for UL (other valid option is 32;
|
||||
**32 is i Rel-17 feature**)
|
||||
|
||||
## ServingCellConfigCommon parameters
|
||||
|
||||
The `gNBs` configuration section has a big structure `servingCellConfigCommon`
|
||||
that has an influence on the overall behavior of MAC and L1. As the name says,
|
||||
this structure is a flat representation of the ServingCellConfigCommon
|
||||
structure, specified by 3GPP. Describing all of these parameters would be too
|
||||
exhaustive; more information about the individual fields can be found in 3GPP
|
||||
TS 38.331, section 6.3.2 "Radio resource control information elements".
|
||||
|
||||
Below is a description of some of these parameters.
|
||||
|
||||
### Frequency configuration
|
||||
|
||||
There are many parameters, such as `absoluteFrequencySSB`, etc., that have an
|
||||
impact on the frequency used by the gNB. For more information, please check the
|
||||
[corresponding document](../gNB_frequency_setup.md).
|
||||
|
||||
### TDD pattern configuration
|
||||
|
||||
The TDD configuration parameters allow to use one or two TDD patterns.
|
||||
|
||||
#### Single TDD pattern
|
||||
|
||||
Configure the TDD pattern through these options:
|
||||
- `dl_UL_TransmissionPeriodicity`: Refers to the UL/DL slots periodicity for
|
||||
the TDD pattern. See below for valid numbers.
|
||||
- `nrofDownlinkSlots`: Refers to the number of consecutive DL slots in the TDD
|
||||
pattern. The number of DL slots depends on the TDD period.
|
||||
- `nrofDownlinkSymbols`: Indicates the number of consecutive DL symbols within
|
||||
the special slot that follows the downlink slots in the TDD pattern. The
|
||||
special slot is needed only to switch from DL to UL. The maximum number of
|
||||
symbols in this slot is 14.
|
||||
- `nrofUplinkSlots`: Refers to the number of consecutive UL slots in the TDD
|
||||
pattern, depending on the desired TDD period.
|
||||
- `nrofUplinkSymbols`: Indicates the number of consecutive UL symbols within
|
||||
the special slot that follows the downlink slots in the TDD pattern. The sum
|
||||
of downlink and uplink symbols should not exceed 14.
|
||||
- `prach_ConfigurationIndex`: index for PRACH according to tables 6.3.3.2-2 to
|
||||
6.3.3.2-4 in TS 38.211.
|
||||
|
||||
As an example, the below figure shows a single TDD pattern, consisting of 3 DL
|
||||
slots, 1 mixed slots (with 10 DL, 2 guard, 2 UL symbols), and 1 UL slot.
|
||||
|
||||

|
||||
|
||||
To configure this pattern in the configuration file, use
|
||||
|
||||
```plaintext
|
||||
#dl_UL_TransmissionPeriodicity 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10, 8=ms3, 9=ms4
|
||||
|
||||
dl_UL_TransmissionPeriodicity = 5;
|
||||
nrofDownlinkSlots = 3;
|
||||
nrofDownlinkSymbols = 10;
|
||||
nrofUplinkSlots = 1;
|
||||
nrofUplinkSymbols = 2;
|
||||
```
|
||||
|
||||
The `dl_UL_TransmissionPeriodicity` is set to `5` (2.5ms). The above figure
|
||||
shows two TDD periods over 5ms. The 10 ms frame period must be strictly
|
||||
divisible by the sum of the TDD pattern periods.
|
||||
|
||||
#### Two TDD patterns
|
||||
|
||||
An optional `pattern2` structure is used to signal a TDD pattern 2.
|
||||
In this case, the TDD pattern may have two extended values of 3 ms and 4 ms.
|
||||
These values are standardized as `dl-UL-TransmissionPeriodicity-v1530`. For the
|
||||
sake of simplicity of the gNB configuration file, we have extended the set of
|
||||
`dl-UL-TransmissionPeriodicity` values to support the new TDD periods, as
|
||||
explained in the table below. However, these values will later be encoded as
|
||||
`dl-UL-TransmissionPeriodicity-v1530` to match the specifications.
|
||||
|
||||
| `dl_UL_TransmissionPeriodicity` | TDD period |
|
||||
|---------------------------------|------------|
|
||||
| 0 | 0.5 ms |
|
||||
| 1 | 0.625 ms |
|
||||
| 2 | 1 ms |
|
||||
| 3 | 1.25 ms |
|
||||
| 4 | 2 ms |
|
||||
| 5 | 2.5 ms |
|
||||
| 6 | 5 ms |
|
||||
| 7 | 10 ms |
|
||||
| 8 | 3 ms |
|
||||
| 9 | 4 ms |
|
||||
|
||||
The 10 ms frame period must be strictly divisible by the sum of the TDD pattern
|
||||
periods. For example, the 3 ms TDD pattern should be used with a second TDD
|
||||
pattern of 2 ms. Additionally, the 4 ms TDD pattern should be used with a
|
||||
second TDD pattern of 1 ms.
|
||||
|
||||
As an example, this configuration might be used, where the first TDD pattern is
|
||||
followed by a second, consisting of 4 DL slots.
|
||||
```
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
# ext: 8=ms3, 9=ms4
|
||||
dl_UL_TransmissionPeriodicity = 8;
|
||||
nrofDownlinkSlots = 3;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
# pattern2
|
||||
pattern2: {
|
||||
dl_UL_TransmissionPeriodicity2 = 4;
|
||||
nrofDownlinkSlots2 = 4;
|
||||
nrofDownlinkSymbols2 = 0;
|
||||
nrofUplinkSlots2 = 0;
|
||||
nrofUplinkSymbols2 = 0;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -135,3 +135,4 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
|
||||
|
||||
- [formatting](../tools/formatting/README.md) is a clang-format error detection tool
|
||||
- [iwyu](../tools/iwyu/README.md) is a tool to detect `#include` errors
|
||||
- [docker-dev-env](../tools/docker-dev-env/README.md) is a ubuntu22 docker development environment
|
||||
|
||||
@@ -86,6 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "time_meas.h"
|
||||
#include "utils.h"
|
||||
#include "x2ap_eNB.h"
|
||||
#include "openair1/SCHED_NR/sched_nr.h"
|
||||
|
||||
pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
@@ -116,8 +117,7 @@ double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
|
||||
double rx_gain_off = 0.0;
|
||||
|
||||
static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/;
|
||||
int chain_offset=0;
|
||||
extern void *udp_eNB_task(void *args_p);
|
||||
int chain_offset = 0;
|
||||
int emulate_rf = 0;
|
||||
int numerology = 0;
|
||||
double cpuf;
|
||||
@@ -398,9 +398,6 @@ void terminate_task(task_id_t task_id, module_id_t mod_id) {
|
||||
itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
|
||||
}
|
||||
|
||||
//extern void free_transport(PHY_VARS_gNB *);
|
||||
extern void nr_phy_free_RU(RU_t *);
|
||||
|
||||
int stop_L1(module_id_t gnb_id)
|
||||
{
|
||||
RU_t *ru = RC.ru[gnb_id];
|
||||
@@ -701,7 +698,7 @@ int main( int argc, char **argv ) {
|
||||
wait_RUs();
|
||||
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
|
||||
|
||||
if (IS_SOFTMODEM_DOSCOPE || IS_SOFTMODEM_IMSCOPE_ENABLED) {
|
||||
if (IS_SOFTMODEM_DOSCOPE || IS_SOFTMODEM_IMSCOPE_ENABLED || IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
|
||||
sleep(1);
|
||||
scopeParms_t p;
|
||||
p.argc = &argc;
|
||||
@@ -714,6 +711,11 @@ int main( int argc, char **argv ) {
|
||||
if (IS_SOFTMODEM_IMSCOPE_ENABLED) {
|
||||
load_softscope("im", &p);
|
||||
}
|
||||
AssertFatal(!(IS_SOFTMODEM_IMSCOPE_ENABLED && IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED),
|
||||
"Data recoding and ImScope cannot be enabled at the same time\n");
|
||||
if (IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
|
||||
load_module_shlib("imscope_record", NULL, 0, &p);
|
||||
}
|
||||
}
|
||||
|
||||
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF && NFAPI_MODE != NFAPI_MODE_AERIAL) {
|
||||
|
||||
+13
-1
@@ -569,6 +569,7 @@ void processSlotTX(void *arg)
|
||||
}
|
||||
}
|
||||
RU_write(rxtxD, sl_tx_action);
|
||||
dynamic_barrier_join(rxtxD->next_barrier);
|
||||
TracyCZoneEnd(ctx);
|
||||
}
|
||||
|
||||
@@ -1111,8 +1112,19 @@ void *UE_thread(void *arg)
|
||||
int slot = curMsgTx->proc.nr_slot_tx;
|
||||
int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame;
|
||||
|
||||
int wait_for_prev_slot = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
|
||||
|
||||
int next_duration_rx_to_tx =
|
||||
update_ntn_system_information
|
||||
? NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset
|
||||
: duration_rx_to_tx;
|
||||
int next_nr_slot_tx = (absolute_slot + next_duration_rx_to_tx) % nb_slot_frame;
|
||||
int next_frame_tx = ((absolute_slot + next_duration_rx_to_tx) / nb_slot_frame) % MAX_FRAME_NUMBER;
|
||||
int next_tx_slot_and_frame = next_nr_slot_tx + next_frame_tx * UE->frame_parms.slots_per_frame + 1;
|
||||
dynamic_barrier_t *next_barrier = &UE->process_slot_tx_barriers[next_tx_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS];
|
||||
curMsgTx->next_barrier = next_barrier;
|
||||
dynamic_barrier_update(&UE->process_slot_tx_barriers[slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS],
|
||||
tx_wait_for_dlsch[slot],
|
||||
tx_wait_for_dlsch[slot] + wait_for_prev_slot,
|
||||
start_process_slot_tx,
|
||||
newTx);
|
||||
stream_status = STREAM_STATUS_SYNCED;
|
||||
|
||||
@@ -91,7 +91,6 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "pdcp.h"
|
||||
#include "actor.h"
|
||||
|
||||
extern const char *duplex_mode[];
|
||||
THREAD_STRUCT thread_struct;
|
||||
nrUE_params_t nrUE_params = {0};
|
||||
|
||||
@@ -270,12 +269,13 @@ void init_openair0()
|
||||
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
|
||||
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
|
||||
|
||||
LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
|
||||
card,
|
||||
openair0_cfg[card].sample_rate,
|
||||
openair0_cfg[card].tx_num_channels,
|
||||
openair0_cfg[card].rx_num_channels,
|
||||
duplex_mode[openair0_cfg[card].duplex_mode]);
|
||||
LOG_I(PHY,
|
||||
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
|
||||
card,
|
||||
openair0_cfg[card].sample_rate,
|
||||
openair0_cfg[card].tx_num_channels,
|
||||
openair0_cfg[card].rx_num_channels,
|
||||
duplex_mode_txt[openair0_cfg[card].duplex_mode]);
|
||||
|
||||
if (is_sidelink) {
|
||||
dl_carrier = frame_parms->dl_CarrierFreq;
|
||||
@@ -532,6 +532,11 @@ int main(int argc, char **argv)
|
||||
if (IS_SOFTMODEM_IMSCOPE_ENABLED) {
|
||||
load_softscope("im", PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
AssertFatal(!(IS_SOFTMODEM_IMSCOPE_ENABLED && IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED),
|
||||
"Data recoding and ImScope cannot be enabled at the same time\n");
|
||||
if (IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED) {
|
||||
load_module_shlib("imscope_record", NULL, 0, PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
|
||||
for (int inst = 0; inst < NB_UE_INST; inst++) {
|
||||
LOG_I(PHY,"Intializing UE Threads for instance %d ...\n", inst);
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&nrUE_params.uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \
|
||||
{"reconfig-file", CONFIG_HLP_RE_CFG_FILE, 0, .strptr=&nrUE_params.reconfig_file, .defstrval="./reconfig.raw", TYPE_STRING, 0}, \
|
||||
{"rbconfig-file", CONFIG_HLP_RB_CFG_FILE, 0, .strptr=&nrUE_params.rbconfig_file, .defstrval="./rbconfig.raw", TYPE_STRING, 0}, \
|
||||
{"ue-idx-standalone", NULL, 0, .u16ptr=&ue_idx_standalone, .defuintval=0xFFFF, TYPE_UINT16, 0}, \
|
||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, .dblptr=&nrUE_params.rx_gain, .defdblval=110, TYPE_DOUBLE, 0}, \
|
||||
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, .dblptr=&nrUE_params.rx_gain_off, .defdblval=0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-txgain", CONFIG_HLP_UETXG, 0, .dblptr=&nrUE_params.tx_gain, .defdblval=0, TYPE_DOUBLE, 0}, \
|
||||
|
||||
@@ -77,6 +77,7 @@ void get_common_options(configmodule_interface_t *cfg)
|
||||
uint32_t noS1 = 0, nonbiot = 0;
|
||||
uint32_t rfsim = 0, do_forms = 0;
|
||||
uint32_t enable_imscope = 0;
|
||||
uint32_t enable_imscope_record = 0;
|
||||
int nfapi_index = 0;
|
||||
char *logmem_filename = NULL;
|
||||
|
||||
@@ -141,6 +142,10 @@ void get_common_options(configmodule_interface_t *cfg)
|
||||
IS_SOFTMODEM_IMSCOPE_ENABLED = true;
|
||||
}
|
||||
|
||||
if (enable_imscope_record) {
|
||||
IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED = true;
|
||||
}
|
||||
|
||||
if (start_websrv) {
|
||||
load_module_shlib("websrv", NULL, 0, NULL);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ extern "C"
|
||||
#define CONFIG_HLP_CHESTFREQ "Set channel estimation type in frequency domain. 0-Linear interpolation (default). 1-PRB based averaging of channel estimates in frequency. \n"
|
||||
#define CONFIG_HLP_CHESTTIME "Set channel estimation type in time domain. 0-Symbols take estimates of the last preceding DMRS symbol (default). 1-Symbol based averaging of channel estimates in time. \n"
|
||||
#define CONFIG_HLP_IMSCOPE "Enable phy scope based on imgui and implot"
|
||||
#define CONFIG_HLP_IMSCOPE_RECORD "Enable recording scope data to filesystem"
|
||||
|
||||
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
|
||||
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
|
||||
@@ -186,6 +187,7 @@ extern int usrp_tx_thread;
|
||||
{"A" , CONFIG_HLP_TADV, 0, .iptr=&softmodem_params.command_line_sample_advance,.defintval=0, TYPE_INT, 0}, \
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, .iptr=&softmodem_params.threequarter_fs, .defintval=0, TYPE_INT, 0}, \
|
||||
{"imscope" , CONFIG_HLP_IMSCOPE, PARAMFLAG_BOOL, .uptr=&enable_imscope, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"imscope-record" , CONFIG_HLP_IMSCOPE_RECORD,PARAMFLAG_BOOL, .uptr=&enable_imscope_record, .defintval=0, TYPE_UINT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -231,6 +233,7 @@ extern int usrp_tx_thread;
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -285,6 +288,7 @@ extern int usrp_tx_thread;
|
||||
#define IS_SOFTMODEM_5GUE (get_softmodem_optmask()->bit.SOFTMODEM_5GUE_BIT)
|
||||
#define IS_SOFTMODEM_NOSTATS (get_softmodem_optmask()->bit.SOFTMODEM_NOSTATS_BIT)
|
||||
#define IS_SOFTMODEM_IMSCOPE_ENABLED (get_softmodem_optmask()->bit.SOFTMODEM_IMSCOPE_BIT)
|
||||
#define IS_SOFTMODEM_IMSCOPE_RECORD_ENABLED (get_softmodem_optmask()->bit.SOFTMODEM_IMSCOPE_RECORD_BIT)
|
||||
typedef struct optmask_s {
|
||||
union {
|
||||
struct {
|
||||
@@ -304,6 +308,7 @@ typedef struct optmask_s {
|
||||
uint64_t SOFTMODEM_5GUE_BIT: 1;
|
||||
uint64_t SOFTMODEM_NOSTATS_BIT: 1;
|
||||
uint64_t SOFTMODEM_IMSCOPE_BIT: 1;
|
||||
uint64_t SOFTMODEM_IMSCOPE_RECORD_BIT : 1;
|
||||
} bit;
|
||||
uint64_t v; // allow to export entire bit set, force to 64 bit processor atomic size
|
||||
};
|
||||
@@ -361,6 +366,8 @@ void configure_rru(void *, void *arg);
|
||||
struct timespec timespec_add(struct timespec lhs, struct timespec rhs);
|
||||
struct timespec timespec_sub(struct timespec lhs, struct timespec rhs);
|
||||
extern uint8_t nfapi_mode;
|
||||
extern char *parallel_config;
|
||||
extern char *worker_config;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define NFAPI_MAX_NUM_CB 8
|
||||
#define NFAPI_MAX_NUM_PRGS 1
|
||||
#define NFAPI_MAX_NUM_BG_IF 1
|
||||
#define NFAPI_MAX_NUM_PERIODS 8
|
||||
|
||||
// Extension to the generic structures for single tlv values
|
||||
|
||||
@@ -436,7 +437,10 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nfapi_uint8_tlv_t tdd_period;//DL UL Transmission Periodicity. Value:0: ms0p5 1: ms0p625 2: ms1 3: ms1p25 4: ms2 5: ms2p5 6: ms5 7: ms10 8: ms3 9: ms4
|
||||
/**DL UL Transmission Periodicity: for multiple TDD pattern,
|
||||
* the value corresponds to the sum periodicity (3GPP TS 38.213, 11.1)
|
||||
* Values: 0:ms0p5 1:ms0p625 2:ms1 3:ms1p25 4:ms2 5:ms2p5 6:ms5 7:ms10 8:ms20 */
|
||||
nfapi_uint8_tlv_t tdd_period;
|
||||
nfapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
|
||||
|
||||
} nfapi_nr_tdd_table_t;
|
||||
|
||||
@@ -669,10 +669,6 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
|
||||
{
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
|
||||
|
||||
#if 0 // emulate set_config TLV reception (hard-code)
|
||||
int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4);
|
||||
#endif
|
||||
|
||||
if(phy)
|
||||
{
|
||||
if(phy->state != NFAPI_PNF_PHY_RUNNING)
|
||||
|
||||
-2
@@ -44,8 +44,6 @@
|
||||
// #define DEBUG_LDPC_ENCODING
|
||||
// #define DEBUG_LDPC_ENCODING_FREE 1
|
||||
|
||||
extern ldpc_interface_t ldpc_interface_segment;
|
||||
|
||||
typedef struct ldpc8blocks_args_s {
|
||||
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters;
|
||||
encoder_implemparams_t impp;
|
||||
|
||||
@@ -32,7 +32,7 @@ typedef struct ldpc_interface_s {
|
||||
} ldpc_interface_t;
|
||||
|
||||
// Global var to limit the rework of the dirty legacy code
|
||||
extern ldpc_interface_t ldpc_interface, ldpc_interface_offload;
|
||||
extern ldpc_interface_t ldpc_interface, ldpc_interface_offload, ldpc_interface_segment;
|
||||
|
||||
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
|
||||
int load_LDPClib(char *version, ldpc_interface_t *);
|
||||
|
||||
@@ -292,7 +292,7 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1
|
||||
* De-interleaving of coded bits implementation
|
||||
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
|
||||
*/
|
||||
static inline void nr_polar_rm_deinterleaving_lut(uint16_t *out, const uint E)
|
||||
static inline void nr_polar_rm_deinterleaving_lut(uint16_t *out, const int E)
|
||||
{
|
||||
int16_t in[E];
|
||||
for (uint i = 0; i < E; i++)
|
||||
|
||||
@@ -129,6 +129,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
|
||||
crcTableInit();
|
||||
init_byte2m128i();
|
||||
init_byte2bit16();
|
||||
init_pucch2_luts();
|
||||
|
||||
nr_init_fde(); // Init array for frequency equalization of transform precoding of PUSCH
|
||||
@@ -196,7 +197,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
int n_buf = Prx*max_ul_mimo_layers;
|
||||
|
||||
int nb_re_pusch = N_RB_UL * NR_NB_SC_PER_RB;
|
||||
int nb_re_pusch2 = ALIGN_UP_16(nb_re_pusch);
|
||||
int nb_re_pusch2 = ceil_mod(nb_re_pusch, 16);
|
||||
|
||||
gNB->pusch_vars = (NR_gNB_PUSCH *)malloc16_clear(gNB->max_nb_pusch * sizeof(NR_gNB_PUSCH));
|
||||
for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
|
||||
|
||||
@@ -36,10 +36,9 @@
|
||||
|
||||
#define I0_SKIP_DC 1
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) {
|
||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size])
|
||||
{
|
||||
int timing_advance = 0;
|
||||
int max_val = 0;
|
||||
|
||||
|
||||
@@ -703,11 +703,11 @@ int nr_srs_channel_estimation(
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t **srs_generated_signal,
|
||||
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int8_t *snr_per_rb,
|
||||
int8_t *snr)
|
||||
{
|
||||
@@ -738,20 +738,20 @@ int nr_srs_channel_estimation(
|
||||
c16_t noise[arr_len];
|
||||
memset(noise, 0, arr_len * sizeof(c16_t));
|
||||
|
||||
uint8_t mem_offset = ((16 - ((long)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF)
|
||||
uint8_t mem_offset = ((16 - ((intptr_t)&srs_estimated_channel_freq[0][0][subcarrier_offset + nr_srs_info->k_0_p[0][0]])) & 0xF)
|
||||
>> 2; // >> 2 <=> /sizeof(int32_t)
|
||||
|
||||
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
|
||||
// The End of OFDM symbol corresponds to the position of last 16384 in the filter
|
||||
// The c16multaddVectRealComplex applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow,
|
||||
// we added 8 in the array size
|
||||
int32_t srs_est[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset + 8] __attribute__((aligned(32)));
|
||||
c16_t srs_est[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset + 8] __attribute__((aligned(32)));
|
||||
c16_t ls_estimated = {0};
|
||||
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
memset(srs_ls_estimated_channel, 0, frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) * sizeof(c16_t));
|
||||
memset(srs_est, 0, (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset) * sizeof(int32_t));
|
||||
memset(srs_est, 0, (frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols) + mem_offset) * sizeof(c16_t));
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY, "====================== UE port %d --> gNB Rx antenna %i ======================\n", p_index, ant);
|
||||
@@ -762,7 +762,7 @@ int nr_srs_channel_estimation(
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
c16_t *srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier + mem_offset];
|
||||
c16_t *srs_estimated_channel16 = &srs_est[subcarrier + mem_offset];
|
||||
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
if (k % fd_cdm == 0) {
|
||||
@@ -773,8 +773,8 @@ int nr_srs_channel_estimation(
|
||||
int16_t generated_real = srs_generated_signal[p_index][subcarrier_cdm].r;
|
||||
int16_t generated_imag = srs_generated_signal[p_index][subcarrier_cdm].i;
|
||||
|
||||
int16_t received_real = ((c16_t *)srs_received_signal[ant])[subcarrier_cdm].r;
|
||||
int16_t received_imag = ((c16_t *)srs_received_signal[ant])[subcarrier_cdm].i;
|
||||
int16_t received_real = srs_received_signal[ant][subcarrier_cdm].r;
|
||||
int16_t received_imag = srs_received_signal[ant][subcarrier_cdm].i;
|
||||
|
||||
// We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and
|
||||
// generated_imag. So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16
|
||||
@@ -806,10 +806,10 @@ int nr_srs_channel_estimation(
|
||||
LOG_I(NR_PHY,
|
||||
"(%4i) %6i\t%6i | %6i\t%6i | %6i\t%6i\n",
|
||||
subcarrier_log,
|
||||
((c16_t *)srs_generated_signal[p_index])[subcarrier].r,
|
||||
((c16_t *)srs_generated_signal[p_index])[subcarrier].i,
|
||||
((c16_t *)srs_received_signal[ant])[subcarrier].r,
|
||||
((c16_t *)srs_received_signal[ant])[subcarrier].i,
|
||||
srs_generated_signal[p_index][subcarrier].r,
|
||||
srs_generated_signal[p_index][subcarrier].i,
|
||||
srs_received_signal[ant][subcarrier].r,
|
||||
srs_received_signal[ant][subcarrier].i,
|
||||
ls_estimated.r,
|
||||
ls_estimated.i);
|
||||
#endif
|
||||
@@ -823,7 +823,7 @@ int nr_srs_channel_estimation(
|
||||
c16multaddVectRealComplex(filt8_start, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier];
|
||||
srs_estimated_channel16 = &srs_est[subcarrier];
|
||||
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size
|
||||
@@ -837,14 +837,14 @@ int nr_srs_channel_estimation(
|
||||
} else if (k % 2 == 0) { // 2nd middle case
|
||||
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
|
||||
c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8);
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset];
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
} else {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if (subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset];
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size
|
||||
@@ -854,7 +854,7 @@ int nr_srs_channel_estimation(
|
||||
} else { // Middle case
|
||||
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
|
||||
c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16);
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset];
|
||||
srs_estimated_channel16 = &srs_est[sc_offset];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,9 +866,9 @@ int nr_srs_channel_estimation(
|
||||
|
||||
} // for (int k = 0; k < M_sc_b_SRS; k++)
|
||||
|
||||
memcpy(&srs_estimated_channel_freq[ant][p_index][0],
|
||||
memcpy(srs_estimated_channel_freq[ant][p_index],
|
||||
&srs_est[mem_offset],
|
||||
(frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)) * sizeof(int32_t));
|
||||
(frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)) * sizeof(c16_t));
|
||||
|
||||
// Compute noise
|
||||
subcarrier = subcarrier_offset + nr_srs_info->k_0_p[p_index][0];
|
||||
@@ -877,7 +877,7 @@ int nr_srs_channel_estimation(
|
||||
}
|
||||
uint16_t base_idx = ant * N_ap * M_sc_b_SRS + p_index * M_sc_b_SRS;
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
ch[base_idx + k] = ((c16_t *)srs_estimated_channel_freq[ant][p_index])[subcarrier];
|
||||
ch[base_idx + k] = srs_estimated_channel_freq[ant][p_index][subcarrier];
|
||||
noise[base_idx + k].r = abs(srs_ls_estimated_channel[subcarrier].r - ch[base_idx + k].r);
|
||||
noise[base_idx + k].i = abs(srs_ls_estimated_channel[subcarrier].i - ch[base_idx + k].i);
|
||||
subcarrier += K_TC;
|
||||
@@ -908,8 +908,8 @@ int nr_srs_channel_estimation(
|
||||
subcarrier_log,
|
||||
srs_ls_estimated_channel[subcarrier].r,
|
||||
srs_ls_estimated_channel[subcarrier].i,
|
||||
((c16_t *)srs_estimated_channel_freq[ant][p_index])[subcarrier].r,
|
||||
((c16_t *)srs_estimated_channel_freq[ant][p_index])[subcarrier].i,
|
||||
srs_estimated_channel_freq[ant][p_index][subcarrier].r,
|
||||
srs_estimated_channel_freq[ant][p_index][subcarrier].i,
|
||||
noise[base_idx + (k / K_TC)].r,
|
||||
noise[base_idx + (k / K_TC)].i);
|
||||
|
||||
@@ -926,13 +926,13 @@ int nr_srs_channel_estimation(
|
||||
(int16_t *)srs_estimated_channel_freq[ant][p_index],
|
||||
(int16_t *)srs_estimated_channel_time[ant][p_index]);
|
||||
|
||||
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][0],
|
||||
memcpy(srs_estimated_channel_time_shifted[ant][p_index],
|
||||
&srs_estimated_channel_time[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1],
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(int32_t));
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t));
|
||||
|
||||
memcpy(&srs_estimated_channel_time_shifted[ant][p_index][gNB->frame_parms.ofdm_symbol_size >> 1],
|
||||
&srs_estimated_channel_time[ant][p_index][0],
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(int32_t));
|
||||
srs_estimated_channel_time[ant][p_index],
|
||||
(gNB->frame_parms.ofdm_symbol_size >> 1) * sizeof(c16_t));
|
||||
|
||||
} // for (int p_index = 0; p_index < N_ap; p_index++)
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
|
||||
@@ -64,7 +64,7 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB,
|
||||
uint8_t nrOfLayers);
|
||||
|
||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
|
||||
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
|
||||
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -81,11 +81,11 @@ int nr_srs_channel_estimation(
|
||||
const nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
const nr_srs_info_t *nr_srs_info,
|
||||
const c16_t **srs_generated_signal,
|
||||
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
int32_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
int32_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int32_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
|
||||
c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size],
|
||||
int8_t *snr_per_rb,
|
||||
int8_t *snr);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
||||
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, int mod_order);
|
||||
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start);
|
||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
|
||||
|
||||
@@ -49,10 +49,21 @@ static const int wt2[12][2] =
|
||||
{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}};
|
||||
|
||||
// complex conjugate of mod table
|
||||
static const c16_t nr_rx_mod_table[7] =
|
||||
{{0, 0}, {23170, -23170}, {-23170, 23170}, {23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}};
|
||||
static const c16_t nr_rx_nmod_table[7] =
|
||||
{{0, 0}, {-23170, 23170}, {23170, -23170}, {-23170, 23170}, {-23170, -23170}, {23170, 23170}, {23170, -23170}};
|
||||
static const c16_t nr_rx_mod_table[4] = {{23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}};
|
||||
|
||||
static inline c16_t get_modulated(const uint32_t *gold_sequence, const int idx_gold, const bool inverse)
|
||||
{
|
||||
const uint8_t *gold = (uint8_t *)gold_sequence;
|
||||
const int swap2bits[4] = {0, 2, 1, 3};
|
||||
const uint8_t packedbyte = gold[idx_gold / 4];
|
||||
const int indexByte = (idx_gold * 2) & 7;
|
||||
const int idx = swap2bits[(packedbyte >> indexByte) & 3];
|
||||
const c16_t val = nr_rx_mod_table[idx];
|
||||
if (inverse)
|
||||
return val;
|
||||
else
|
||||
return (c16_t){-val.r, -val.i};
|
||||
}
|
||||
|
||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
@@ -64,41 +75,27 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
uint32_t re_offset,
|
||||
uint8_t dmrs_type)
|
||||
{
|
||||
int8_t w, nb_dmrs;
|
||||
unsigned char idx=0;
|
||||
int k;
|
||||
typedef int array_of_w[2];
|
||||
const array_of_w *wf = (dmrs_type == pusch_dmrs_type1) ? wf1 : wf2;
|
||||
const array_of_w *wt = (dmrs_type == pusch_dmrs_type1) ? wt1 : wt2;
|
||||
|
||||
int dmrs_offset = re_offset/((dmrs_type==pusch_dmrs_type1)?2:3);
|
||||
|
||||
const int dmrs_offset = re_offset / ((dmrs_type == pusch_dmrs_type1) ? 2 : 3);
|
||||
if (dmrs_type > 2)
|
||||
LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type+1);
|
||||
|
||||
const int nb_dmrs = dmrs_type == pusch_dmrs_type1 ? 6 : 4;
|
||||
|
||||
if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) {
|
||||
if (gNB->frame_parms.Ncp == NORMAL) {
|
||||
nb_dmrs = ((dmrs_type==pusch_dmrs_type1) ? 6:4);
|
||||
for (int i=dmrs_offset; i<dmrs_offset+(nb_pusch_rb*nb_dmrs); i++) {
|
||||
k = i-dmrs_offset;
|
||||
w = (wf[p-1000][i&1])*(wt[p-1000][lp]);
|
||||
const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
|
||||
|
||||
idx = ((((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
|
||||
output[k] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
|
||||
for (int k = 0; k < nb_pusch_rb * nb_dmrs; k++) {
|
||||
int i = k + dmrs_offset;
|
||||
int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
|
||||
output[k] = get_modulated(nr_gold_pusch, i, w == 1);
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb);
|
||||
printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]);
|
||||
printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n",
|
||||
i,
|
||||
idx,
|
||||
nr_gold_pusch[(i << 1) >> 5],
|
||||
(((nr_gold_pusch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
|
||||
(((nr_gold_pusch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
|
||||
output[k].r,
|
||||
output[k].i);
|
||||
printf("i %d idx %d pusch mod_dmrs %d %d\n", i, idx, output[k].r, output[k].i);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else {
|
||||
LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n");
|
||||
@@ -119,9 +116,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
unsigned short nb_pdsch_rb,
|
||||
uint8_t config_type)
|
||||
{
|
||||
int8_t w;
|
||||
unsigned char idx=0;
|
||||
|
||||
typedef int array_of_w[2];
|
||||
const array_of_w *wf = (config_type == NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2;
|
||||
const array_of_w *wt = (config_type == NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2;
|
||||
@@ -132,22 +126,13 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
if ((p >= 1000) && (p < ((config_type == NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) {
|
||||
if (ue->frame_parms.Ncp == NORMAL) {
|
||||
for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) {
|
||||
w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
|
||||
const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table;
|
||||
int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]);
|
||||
output[i] = get_modulated(nr_gold_pdsch, i, w == 1);
|
||||
|
||||
idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1);
|
||||
output[i] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb);
|
||||
printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]);
|
||||
printf("i %d idx %d pdsch gold %u b0-b1 %d-%d mod_dmrs %d %d\n",
|
||||
i,
|
||||
idx,
|
||||
nr_gold_pdsch[(i << 1) >> 5],
|
||||
(((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
|
||||
(((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
|
||||
output[i].r,
|
||||
output[i].i);
|
||||
printf("i %d idx %d pdsch mod_dmrs %d %d\n", i, idx, output[i].r, output[i].i);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
@@ -167,24 +152,12 @@ int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
unsigned short p,
|
||||
unsigned short nb_rb_coreset)
|
||||
{
|
||||
uint8_t idx=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) {
|
||||
for (int i=0; i<((nb_rb_coreset*6)>>1); i++) {
|
||||
idx = ((((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1);
|
||||
output[i] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
|
||||
output[i] = get_modulated(nr_gold_pdcch, i, true);
|
||||
#ifdef DEBUG_PDCCH
|
||||
if (i<8)
|
||||
printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n",
|
||||
i,
|
||||
idx,
|
||||
nr_gold_pdcch[(i << 1) >> 5],
|
||||
(((nr_gold_pdcch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1),
|
||||
(((nr_gold_pdcch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1),
|
||||
output[i].r,
|
||||
output[i].i);
|
||||
printf("i %d idx %d pdcch mod_dmrs %d %d\n", i, idx, output[i].r, output[i].i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -194,8 +167,7 @@ int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
|
||||
{
|
||||
int m,m0,m1;
|
||||
uint8_t idx=0;
|
||||
int m0, m1;
|
||||
if (sidelink) {
|
||||
AssertFatal(symbol == 0 || (symbol >= 5 && symbol <= 12), "illegal symbol %d\n", symbol);
|
||||
m0 = (symbol) ? (symbol - 4) * 33 : 0;
|
||||
@@ -216,9 +188,8 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output
|
||||
}
|
||||
// printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1);
|
||||
/// QPSK modulation
|
||||
for (m=m0; m<m1; m++) {
|
||||
idx = ((((nr_gold_pbch[(m<<1)>>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1);
|
||||
output[m - m0] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx];
|
||||
for (int m = m0; m < m1; m++) {
|
||||
output[m - m0] = get_modulated(nr_gold_pbch, m, true);
|
||||
|
||||
#ifdef DEBUG_PBCH
|
||||
if (m<16)
|
||||
@@ -235,7 +206,7 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output
|
||||
\param length is number of RE in a OFDM symbol
|
||||
\param *output pointer to all ptrs RE in a OFDM symbol
|
||||
*/
|
||||
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order)
|
||||
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, int mod_order)
|
||||
{
|
||||
uint8_t idx, b_idx;
|
||||
for (int i=0; i<length/mod_order; i++)
|
||||
@@ -248,7 +219,7 @@ void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output,
|
||||
in++;
|
||||
idx ^= (((*in)>>b_idx)&1)<<(mod_order-j-1);
|
||||
}
|
||||
output[i] = nr_rx_mod_table[offset + idx];
|
||||
output[i] = nr_rx_mod_table[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "nr_refsig.h"
|
||||
#include "nr_mod_table.h"
|
||||
short nr_qpsk_mod_table[8];
|
||||
c16_t nr_qpsk_mod_table[4];
|
||||
|
||||
int32_t nr_16qam_mod_table[16];
|
||||
simde__m128i nr_qpsk_byte_mod_table[2048];
|
||||
@@ -43,8 +43,8 @@ void nr_generate_modulation_table() {
|
||||
|
||||
// QPSK
|
||||
for (i=0; i<4; i++) {
|
||||
nr_qpsk_mod_table[i*2] = (short)(1-2*(i&1))*val*sqrt2*sqrt2;
|
||||
nr_qpsk_mod_table[i*2+1] = (short)(1-2*((i>>1)&1))*val*sqrt2*sqrt2;
|
||||
nr_qpsk_mod_table[i].r = (short)(1 - 2 * (i & 1)) * val * sqrt2 * sqrt2;
|
||||
nr_qpsk_mod_table[i].i = (short)(1 - 2 * ((i >> 1) & 1)) * val * sqrt2 * sqrt2;
|
||||
//printf("%d j%d\n",nr_qpsk_mod_table[i*2],nr_qpsk_mod_table[i*2+1]);
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ void nr_generate_modulation_table() {
|
||||
table = (short*) nr_qpsk_byte_mod_table;
|
||||
for (i=0; i<256; i++) {
|
||||
for (j=0; j<4; j++) {
|
||||
table[i*8+(j*2)] = (short)(1-2*((i>>(j*2))&1))*val*sqrt2*sqrt2;
|
||||
table[i*8+(j*2)+1] = (short)(1-2*((i>>(j*2+1))&1))*val*sqrt2*sqrt2;
|
||||
*table++ = (short)(1 - 2 * ((i >> (j * 2)) & 1)) * val * sqrt2 * sqrt2;
|
||||
*table++ = (short)(1 - 2 * ((i >> (j * 2 + 1)) & 1)) * val * sqrt2 * sqrt2;
|
||||
//printf("%d j%d\n",nr_qpsk_byte_mod_table[i*8+(j*2)],nr_qpsk_byte_mod_table[i*8+(j*2)+1]);
|
||||
}
|
||||
}
|
||||
@@ -62,16 +62,16 @@ void nr_generate_modulation_table() {
|
||||
table = (short*) nr_16qam_byte_mod_table;
|
||||
for (i=0; i<256; i++) {
|
||||
for (j=0; j<2; j++) {
|
||||
table[i*4+(j*2)] = (short)((1-2*((i>>(j*4))&1))*(2-(1-2*((i>>(j*4+2))&1))))*val*sqrt10*sqrt2;
|
||||
table[i*4+(j*2)+1] = (short)((1-2*((i>>(j*4+1))&1))*(2-(1-2*((i>>(j*4+3))&1))))*val*sqrt10*sqrt2;
|
||||
//printf("%d j%d\n",nr_16qam_byte_mod_table[i*4+(j*2)],nr_16qam_byte_mod_table[i*4+(j*2)+1]);
|
||||
*table++ = (short)((1 - 2 * ((i >> (j * 4)) & 1)) * (2 - (1 - 2 * ((i >> (j * 4 + 2)) & 1)))) * val * sqrt10 * sqrt2;
|
||||
*table++ = (short)((1 - 2 * ((i >> (j * 4 + 1)) & 1)) * (2 - (1 - 2 * ((i >> (j * 4 + 3)) & 1)))) * val * sqrt10 * sqrt2;
|
||||
// printf("%d j%d\n",nr_16qam_byte_mod_table[i*4+(j*2)],nr_16qam_byte_mod_table[i*4+(j*2)+1]);
|
||||
}
|
||||
}
|
||||
|
||||
table = (short*) nr_16qam_mod_table;
|
||||
for (i=0; i<16; i++) {
|
||||
table[i*2] = (short)((1-2*(i&1))*(2-(1-2*((i>>2)&1))))*val*sqrt10*sqrt2;
|
||||
table[i*2+1] = (short)((1-2*((i>>1)&1))*(2-(1-2*((i>>3)&1))))*val*sqrt10*sqrt2;
|
||||
*table++ = (short)((1 - 2 * (i & 1)) * (2 - (1 - 2 * ((i >> 2) & 1)))) * val * sqrt10 * sqrt2;
|
||||
*table++ = (short)((1 - 2 * ((i >> 1) & 1)) * (2 - (1 - 2 * ((i >> 3) & 1)))) * val * sqrt10 * sqrt2;
|
||||
//printf("%d j%d\n",table[i*2],table[i*2+1]);
|
||||
}
|
||||
|
||||
@@ -79,8 +79,12 @@ void nr_generate_modulation_table() {
|
||||
table = (short*) nr_64qam_mod_table;
|
||||
for (i=0; i<4096; i++) {
|
||||
for (j=0; j<2; j++) {
|
||||
table[i*4+(j*2)] = (short)((1-2*((i>>(j*6))&1))*(4-(1-2*((i>>(j*6+2))&1))*(2-(1-2*((i>>(j*6+4))&1)))))*val*sqrt42*sqrt2;
|
||||
table[i*4+(j*2)+1] = (short)((1-2*((i>>(j*6+1))&1))*(4-(1-2*((i>>(j*6+3))&1))*(2-(1-2*((i>>(j*6+5))&1)))))*val*sqrt42*sqrt2;
|
||||
*table++ = (short)((1 - 2 * ((i >> (j * 6)) & 1))
|
||||
* (4 - (1 - 2 * ((i >> (j * 6 + 2)) & 1)) * (2 - (1 - 2 * ((i >> (j * 6 + 4)) & 1)))))
|
||||
* val * sqrt42 * sqrt2;
|
||||
*table++ = (short)((1 - 2 * ((i >> (j * 6 + 1)) & 1))
|
||||
* (4 - (1 - 2 * ((i >> (j * 6 + 3)) & 1)) * (2 - (1 - 2 * ((i >> (j * 6 + 5)) & 1)))))
|
||||
* val * sqrt42 * sqrt2;
|
||||
//printf("%d j%d\n",table[i*4+(j*2)],table[i*4+(j*2)+1]);
|
||||
}
|
||||
}
|
||||
@@ -88,8 +92,12 @@ void nr_generate_modulation_table() {
|
||||
//256QAM
|
||||
table = (short*) nr_256qam_mod_table;
|
||||
for (i=0; i<256; i++) {
|
||||
table[i*2] = (short)((1-2*(i&1))*(8-(1-2*((i>>2)&1))*(4-(1-2*((i>>4)&1))*(2-(1-2*((i>>6)&1))))))*val*sqrt170*sqrt2;
|
||||
table[i*2+1] = (short)((1-2*((i>>1)&1))*(8-(1-2*((i>>3)&1))*(4-(1-2*((i>>5)&1))*(2-(1-2*((i>>7)&1))))))*val*sqrt170*sqrt2;
|
||||
*table++ = (short)((1 - 2 * (i & 1))
|
||||
* (8 - (1 - 2 * ((i >> 2) & 1)) * (4 - (1 - 2 * ((i >> 4) & 1)) * (2 - (1 - 2 * ((i >> 6) & 1))))))
|
||||
* val * sqrt170 * sqrt2;
|
||||
*table++ = (short)((1 - 2 * ((i >> 1) & 1))
|
||||
* (8 - (1 - 2 * ((i >> 3) & 1)) * (4 - (1 - 2 * ((i >> 5) & 1)) * (2 - (1 - 2 * ((i >> 7) & 1))))))
|
||||
* val * sqrt170 * sqrt2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 686
|
||||
#define NR_MOD_TABLE_BPSK_OFFSET 1
|
||||
#define NR_MOD_TABLE_QPSK_OFFSET 3
|
||||
#define NR_MOD_TABLE_QAM16_OFFSET 7
|
||||
#define NR_MOD_TABLE_QAM64_OFFSET 23
|
||||
#define NR_MOD_TABLE_QAM256_OFFSET 87
|
||||
|
||||
extern short nr_qpsk_mod_table[8];
|
||||
extern c16_t nr_qpsk_mod_table[4];
|
||||
|
||||
extern int32_t nr_16qam_mod_table[16];
|
||||
#if defined(__SSE2__)
|
||||
|
||||
@@ -44,7 +44,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
const int slot,
|
||||
const csi_mapping_parms_t *phy_csi_parms);
|
||||
void init_byte2m128i(void);
|
||||
|
||||
void nr_generate_modulation_table(void);
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
|
||||
c16_t dmrs_comp_p[(1 + sc_per_symbol / 4) * 4];
|
||||
|
||||
/* generate PTRS RE for the symbol */
|
||||
nr_gen_ref_conj_symbols(gold_seq,sc_per_symbol*2,(int16_t*)ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK
|
||||
nr_gen_ref_conj_symbols(gold_seq, sc_per_symbol * 2, (int16_t *)ptrs_p, 2); // 2 for QPSK
|
||||
uint32_t re_cnt = 0, cnt = 0;
|
||||
/* loop over all sub carriers to get compensated RE on ptrs symbols*/
|
||||
for (int re = 0; re < NR_NB_SC_PER_RB * nb_rb; re++) {
|
||||
|
||||
@@ -1,45 +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
|
||||
*/
|
||||
|
||||
/* Lookup tables for 3GPP scrambling/unscrambling */
|
||||
|
||||
/* Author R. Knopp / EURECOM / OpenAirInterface.org */
|
||||
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include <common/utils/LOG/log.h>
|
||||
|
||||
simde__m128i byte2m128i[256];
|
||||
|
||||
void init_byte2m128i(void) {
|
||||
|
||||
for (int s=0;s<256;s++) {
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*(s&1)),0);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>1)&1)),1);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>2)&1)),2);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>3)&1)),3);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>4)&1)),4);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>5)&1)),5);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>6)&1)),6);
|
||||
byte2m128i[s] = simde_mm_insert_epi16(byte2m128i[s],(1-2*((s>>7)&1)),7);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols;
|
||||
int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 6 + 15) >> 4) << 4;
|
||||
int16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
|
||||
int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15;
|
||||
c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
|
||||
|
||||
for (int d = 0; d < pdcch_pdu_rel15->numDlDci; d++) {
|
||||
/*The coreset is initialised
|
||||
@@ -114,7 +114,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
/// DMRS QPSK modulation
|
||||
for (int symb = cset_start_symb; symb < cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
|
||||
const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb);
|
||||
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
|
||||
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, (int16_t *)mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
if(dci_pdu->RNTI!=0xFFFF) {
|
||||
@@ -122,8 +122,10 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n",
|
||||
symb,
|
||||
i,
|
||||
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5],
|
||||
mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]);
|
||||
&gold_pdcch_dmrs[symb][i >> 5],
|
||||
gold_pdcch_dmrs[symb][i >> 5],
|
||||
mod_dmrs[symb][i].r,
|
||||
mod_dmrs[symb][i].i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -160,18 +162,18 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
|
||||
#endif
|
||||
/// QPSK modulation
|
||||
int16_t mod_dci[NR_MAX_DCI_SIZE>>1] __attribute__((aligned(16)));
|
||||
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated
|
||||
c16_t mod_dci[NR_MAX_DCI_SIZE >> 2] __attribute__((aligned(16)));
|
||||
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, (int16_t *)mod_dci); // Qm = 2 as DMRS is QPSK modulated
|
||||
#ifdef DEBUG_DCI
|
||||
|
||||
for (int i=0; i<encoded_length>>1; i++)
|
||||
printf("i %d mod_dci %d %d\n", i, mod_dci[i<<1], mod_dci[(i<<1)+1] );
|
||||
|
||||
printf("i %d mod_dci %d %d\n", i, mod_dci[i].r, mod_dci[i].i);
|
||||
|
||||
#endif
|
||||
|
||||
/// Resource mapping
|
||||
uint16_t amp = gNB->TX_AMP;
|
||||
int32_t *txdataF = (int32_t *)&gNB->common_vars.txdataF[beam_nb][0][txdataF_offset];
|
||||
c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0] + txdataF_offset;
|
||||
if (cset_start_sc >= frame_parms->ofdm_symbol_size)
|
||||
cset_start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
@@ -198,8 +200,7 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
|
||||
if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
|
||||
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15;
|
||||
((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[l][dmrs_idx], amp, 15);
|
||||
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
LOG_I(NR_PHY_DCI,
|
||||
@@ -207,23 +208,22 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
dmrs_idx,
|
||||
l,
|
||||
k,
|
||||
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1],
|
||||
((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1]);
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i);
|
||||
#endif
|
||||
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
|
||||
} else { // DCI payload
|
||||
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15;
|
||||
((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dci[(dci_idx << 1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dci[dci_idx], amp, 15);
|
||||
#ifdef DEBUG_DCI
|
||||
LOG_I(NR_PHY_DCI,
|
||||
"PDCCH: l %d position %d => (%d,%d)\n",
|
||||
l,
|
||||
k,
|
||||
((int16_t *)txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1],
|
||||
((int16_t *)txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1]);
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i;
|
||||
#endif
|
||||
|
||||
dci_idx++;
|
||||
|
||||
@@ -99,7 +99,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
* => size_output is a sum of parts sizes rounded up to a multiple of 64
|
||||
*/
|
||||
size_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
|
||||
size_output += (size_output_tb + 63 - ((size_output_tb + 63) % 64));
|
||||
size_output += ceil_mod(size_output_tb, 64);
|
||||
}
|
||||
|
||||
unsigned char output[size_output] __attribute__((aligned(64)));
|
||||
@@ -220,7 +220,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
* => offset_output should remain a multiple of 64 with enough offset to fit each dlsch
|
||||
*/
|
||||
uint32_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
|
||||
offset_output += (size_output_tb + 63) & ~63;
|
||||
offset_output += ceil_mod(size_output_tb, 64);
|
||||
|
||||
// Non interleaved VRB to PRB mapping
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB;
|
||||
|
||||
@@ -304,7 +304,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
* => dlsch_offset should remain a multiple of 64 with enough offset to fit each dlsch
|
||||
*/
|
||||
const size_t dlsch_size = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers;
|
||||
dlsch_offset += (dlsch_size + 63 - ((dlsch_size + 63) % 64));
|
||||
dlsch_offset += ceil_mod(dlsch_size, 64);
|
||||
}
|
||||
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include "nr_dlsch.h"
|
||||
#include "../../../nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
extern void set_taus_seed(unsigned int seed_type);
|
||||
|
||||
void nr_fill_dlsch_dl_tti_req(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu)
|
||||
{
|
||||
NR_gNB_DLSCH_t *dlsch = &msgTx->dlsch[msgTx->num_pdsch_slot][0];
|
||||
|
||||
@@ -36,13 +36,13 @@
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_mod_table.h"
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h"
|
||||
|
||||
//#define DEBUG_PBCH
|
||||
//#define DEBUG_PBCH_ENCODING
|
||||
//#define DEBUG_PBCH_DMRS
|
||||
|
||||
extern short nr_qpsk_mod_table[8];
|
||||
|
||||
const uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
|
||||
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31
|
||||
};
|
||||
@@ -56,7 +56,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
{
|
||||
int k,l;
|
||||
//int16_t a;
|
||||
int16_t mod_dmrs[NR_PBCH_DMRS_LENGTH<<1];
|
||||
c16_t mod_dmrs[NR_PBCH_DMRS_LENGTH];
|
||||
uint8_t idx=0;
|
||||
uint8_t nushift = config->cell_config.phy_cell_id.value &3;
|
||||
LOG_D(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift);
|
||||
@@ -64,11 +64,16 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
/// QPSK modulation
|
||||
for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) {
|
||||
idx = (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&3);
|
||||
mod_dmrs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||
mod_dmrs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||
mod_dmrs[m] = nr_qpsk_mod_table[idx];
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("m %d idx %d gold seq %u b0-b1 %d-%d mod_dmrs %d %d\n", m, idx, gold_pbch_dmrs[(m<<1)>>5], (((gold_pbch_dmrs[(m<<1)>>5])>>((m<<1)&0x1f))&1),
|
||||
(((gold_pbch_dmrs[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), mod_dmrs[(m<<1)], mod_dmrs[(m<<1)+1]);
|
||||
printf("m %d idx %d gold seq %u b0-b1 %d-%d mod_dmrs %d %d\n",
|
||||
m,
|
||||
idx,
|
||||
gold_pbch_dmrs[(m << 1) >> 5],
|
||||
(((gold_pbch_dmrs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 1),
|
||||
(((gold_pbch_dmrs[((m << 1) + 1) >> 5]) >> (((m << 1) + 1) & 0x1f)) & 1),
|
||||
mod_dmrs[m].r,
|
||||
mod_dmrs[m].i);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -82,13 +87,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("m %d at k %d of l %d\n", m, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("(%d,%d)\n",
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
k+=4;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
@@ -103,8 +102,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("m %d at k %d of l %d\n", m, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("(%d,%d)\n",
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
|
||||
@@ -124,13 +122,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("m %d at k %d of l %d\n", m, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[(m<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
printf("(%d,%d)\n",
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
k+=4;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
@@ -346,14 +338,13 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
int16_t mod_pbch_e[NR_POLAR_PBCH_E];
|
||||
c16_t mod_pbch_e[NR_POLAR_PBCH_E / 2];
|
||||
/// QPSK modulation
|
||||
for (int i=0; i<NR_POLAR_PBCH_E>>1; i++) {
|
||||
int idx = ((pbch_e[(i << 1) >> 5] >> ((i << 1) & 0x1f)) & 3);
|
||||
mod_pbch_e[i<<1] = nr_qpsk_mod_table[idx << 1];
|
||||
mod_pbch_e[(i<<1)+1] = nr_qpsk_mod_table[(idx << 1) + 1];
|
||||
mod_pbch_e[i] = nr_qpsk_mod_table[idx];
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[2 * i], mod_pbch_e[2 * i + 1]);
|
||||
printf("i %d idx %d mod_pbch %d %d\n", i, idx, mod_pbch_e[i].r, mod_pbch_e[i].i);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -374,8 +365,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_pbch_e[m], amp, 15);
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
@@ -397,8 +387,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_pbch_e[m], amp, 15);
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
@@ -422,8 +411,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_pbch_e[m], amp, 15);
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
@@ -445,8 +433,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
#ifdef DEBUG_PBCH
|
||||
printf("m %d ssb_sc_idx %d at k %d of l %d\n", m, ssb_sc_idx, k, l);
|
||||
#endif
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_pbch_e[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_pbch_e[(m<<1) + 1]) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_pbch_e[m], amp, 15);
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_mod_table.h"
|
||||
//#define DEBUG_PRS_MOD
|
||||
//#define DEBUG_PRS_MAP
|
||||
|
||||
extern short nr_qpsk_mod_table[8];
|
||||
|
||||
int nr_generate_prs(int slot,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
@@ -18,7 +17,7 @@ int nr_generate_prs(int slot,
|
||||
{
|
||||
|
||||
int k_prime = 0, k = 0, idx;
|
||||
int16_t mod_prs[NR_MAX_PRS_LENGTH<<1];
|
||||
c16_t mod_prs[NR_MAX_PRS_LENGTH];
|
||||
int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE;
|
||||
|
||||
// PRS resource mapping with combsize=k which means PRS symbols exist in every k-th subcarrier in frequency domain
|
||||
@@ -45,25 +44,12 @@ int nr_generate_prs(int slot,
|
||||
uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l);
|
||||
for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) {
|
||||
idx = (((gold[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
|
||||
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||
|
||||
#ifdef DEBUG_PRS_MOD
|
||||
LOG_D("m %d idx %d gold seq %d mod_prs %d %d\n", m, idx, nr_gold_prs[l][(m<<1)>>5], mod_prs[m<<1], mod_prs[(m<<1)+1]);
|
||||
#endif
|
||||
|
||||
mod_prs[m] = nr_qpsk_mod_table[idx];
|
||||
|
||||
#ifdef DEBUG_PRS_MAP
|
||||
LOG_D("m %d at k %d of l %d reIdx %d\n", m, k, l, (l*frame_parms->ofdm_symbol_size + k)<<1);
|
||||
#endif
|
||||
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_prs[m<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * mod_prs[(m<<1) + 1]) >> 15;
|
||||
|
||||
#ifdef DEBUG_PRS_MAP
|
||||
LOG_D("(%d,%d)\n",
|
||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1],
|
||||
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15);
|
||||
|
||||
k = k + prs_cfg->CombSize;
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
slot_t slot,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
nr_srs_info_t *nr_srs_info,
|
||||
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)]);
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]);
|
||||
|
||||
void init_prach_list(PHY_VARS_gNB *gNB);
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
|
||||
@@ -1026,7 +1026,7 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
int nb_layer = rel15_ul->nrOfLayers;
|
||||
int nb_rx_ant = frame_parms->nb_antennas_rx;
|
||||
int dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
|
||||
int buffer_length = ALIGN_UP_16(rel15_ul->rb_size * NR_NB_SC_PER_RB);
|
||||
int buffer_length = ceil_mod(rel15_ul->rb_size * NR_NB_SC_PER_RB, 16);
|
||||
c16_t rxFext[nb_rx_ant][buffer_length] __attribute__((aligned(32)));
|
||||
c16_t chFext[nb_layer][nb_rx_ant][buffer_length] __attribute__((aligned(32)));
|
||||
|
||||
@@ -1400,7 +1400,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
// extract the data in the OFDM frame, to the start of the array
|
||||
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
|
||||
|
||||
nb_re_pusch = ALIGN_UP_16(nb_re_pusch);
|
||||
nb_re_pusch = ceil_mod(nb_re_pusch, 16);
|
||||
int dmrs_symbol;
|
||||
if (gNB->chest_time == 0)
|
||||
dmrs_symbol = get_valid_dmrs_idx_for_channel_est(rel15_ul->ul_dmrs_symb_pos, meas_symbol);
|
||||
@@ -1524,7 +1524,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
// buffer due to reference symbol extraction and padding. The gNBscopeCopy call is broken up into steps: trylock, copy, unlock.
|
||||
metadata mt = {.slot = slot, .frame = frame};
|
||||
if (gNBTryLockScopeData(gNB, gNBPuschRxIq, sizeof(c16_t), 1, total_res, &mt)) {
|
||||
int buffer_length = ALIGN_UP_16(rel15_ul->rb_size * NR_NB_SC_PER_RB);
|
||||
int buffer_length = ceil_mod(rel15_ul->rb_size * NR_NB_SC_PER_RB, 16);
|
||||
size_t offset = 0;
|
||||
for (uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
|
||||
symbol++) {
|
||||
|
||||
@@ -74,7 +74,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
slot_t slot,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
nr_srs_info_t *nr_srs_info,
|
||||
int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
|
||||
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
|
||||
{
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
|
||||
@@ -88,12 +88,11 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
const uint8_t K_TC = 2 << srs_pdu->comb_size;
|
||||
const uint16_t M_sc_b_SRS = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index) * NR_NB_SC_PER_RB / K_TC;
|
||||
|
||||
int32_t *rx_signal;
|
||||
c16_t *rx_signal;
|
||||
bool no_srs_signal = true;
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
|
||||
memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
rx_signal = (int32_t *)&rxdataF[ant][symbol_offset];
|
||||
memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size * sizeof(c16_t));
|
||||
rx_signal = &rxdataF[ant][symbol_offset];
|
||||
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
|
||||
@@ -117,7 +116,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
|
||||
srs_received_signal[ant][l_line_offset+subcarrier] = rx_signal[l_line_offset+subcarrier];
|
||||
|
||||
if (rx_signal[l_line_offset+subcarrier] != 0) {
|
||||
if (rx_signal[l_line_offset + subcarrier].r || rx_signal[l_line_offset + subcarrier].i) {
|
||||
no_srs_signal = false;
|
||||
}
|
||||
|
||||
@@ -129,10 +128,11 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
if(subcarrier_log%12 == 0) {
|
||||
LOG_I(NR_PHY,"------------ %d ------------\n", subcarrier_log/12);
|
||||
}
|
||||
LOG_I(NR_PHY,"(%i) \t%i\t%i\n",
|
||||
LOG_I(NR_PHY,
|
||||
"(%i) \t%i\t%i\n",
|
||||
subcarrier_log,
|
||||
(int16_t)(srs_received_signal[ant][l_line_offset+subcarrier]&0xFFFF),
|
||||
(int16_t)((srs_received_signal[ant][l_line_offset+subcarrier]>>16)&0xFFFF));
|
||||
srs_received_signal[ant][l_line_offset + subcarrier].r,
|
||||
srs_received_signal[ant][l_line_offset + subcarrier].i);
|
||||
#endif
|
||||
|
||||
// Subcarrier increment
|
||||
|
||||
@@ -34,10 +34,7 @@
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
#include "instrumentation.h"
|
||||
|
||||
|
||||
extern openair0_config_t openair0_cfg[];
|
||||
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
// #define DEBUG_PDSCH
|
||||
// #define DEBUG_PDCCH
|
||||
// #define DEBUG_PBCH(a...) printf(a)
|
||||
@@ -94,7 +91,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
int slot_prs =
|
||||
(proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame;
|
||||
|
||||
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
|
||||
int16_t *rxF, *pil;
|
||||
c16_t mod_prs[NR_MAX_PRS_LENGTH];
|
||||
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
|
||||
int16_t ch[2] = {0}, noiseFig[2] = {0};
|
||||
int16_t k_prime = 0, k = 0;
|
||||
@@ -138,8 +136,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
for (int m = 0; m < num_pilots; m++)
|
||||
{
|
||||
idx = (((gold_prs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
|
||||
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||
mod_prs[m] = nr_qpsk_mod_table[idx];
|
||||
}
|
||||
|
||||
for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++)
|
||||
@@ -152,7 +149,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset;
|
||||
|
||||
// Channel estimation and interpolation
|
||||
pil = (int16_t *)&mod_prs[0];
|
||||
pil = (int16_t *)mod_prs;
|
||||
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
|
||||
|
||||
if(prs_cfg->CombSize == 2)
|
||||
@@ -520,7 +517,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
|
||||
#ifdef DEBUG_PRS_CHEST
|
||||
sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m");
|
||||
LOG_M(filename, "prs_loc", &mod_prs[0], num_pilots,1,1);
|
||||
LOG_M(filename, "prs_loc", mod_prs, num_pilots, 1, 1);
|
||||
sprintf(filename, "%s%i%s", "rxSigF_", rxAnt, ".m");
|
||||
sprintf(varname, "%s%i", "rxF_", rxAnt);
|
||||
LOG_M(filename, varname, &rxdataF[rxAnt][0], prs_cfg->NumPRSSymbols*frame_params->ofdm_symbol_size,1,1);
|
||||
|
||||
@@ -321,6 +321,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
LOG_D(PHY, "DLSCH received nok \n");
|
||||
kpiStructure.nb_nack++;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1;
|
||||
UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK");
|
||||
}
|
||||
|
||||
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
|
||||
|
||||
@@ -724,13 +724,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx };
|
||||
int total_valid_res = 0;
|
||||
for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) {
|
||||
total_valid_res = dl_valid_re[i - 1];
|
||||
total_valid_res += dl_valid_re[i];
|
||||
}
|
||||
if (UETryLockScopeData(ue, pdschRxdataF_comp, sizeof(c16_t), 1, total_valid_res, &mt)) {
|
||||
size_t offset = 0;
|
||||
for (int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) {
|
||||
size_t data_size = sizeof(c16_t) * dl_valid_re[i - i];
|
||||
UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[0][0][rx_size_symbol * i], data_size, offset, i - startSymbIdx);
|
||||
size_t data_size = sizeof(c16_t) * dl_valid_re[i];
|
||||
UEscopeCopyUnsafe(ue, pdschRxdataF_comp, &rxdataF_comp[0][0][rx_size_symbol * i], data_size, offset, i);
|
||||
offset += data_size;
|
||||
}
|
||||
UEunlockScopeData(ue, pdschRxdataF_comp)
|
||||
@@ -1515,8 +1515,8 @@ uint8_t nr_matrix_inverse(int32_t size,
|
||||
//Convert Q15 to floating point
|
||||
for (int rtx=0;rtx<size;rtx++) {//row
|
||||
for (int ctx=0;ctx<size;ctx++) {//column
|
||||
a44_cpx[ctx][rtx] = ((double)(a44[ctx][rtx])[i].r) / (1 << (shift0 - 1)) + I * ((double)(a44[ctx][rtx])[i].i) / (1 << (shift0 - 1));
|
||||
//if (i<4) printf("a44_cpx(%d,%d)= ((FP %d))%lf+(FP %d)j%lf \n",ctx,rtx,((short *)a44[ctx*size+rtx])[(i<<1)],creal(a44_cpx[ctx*size+rtx]),((short *)a44[ctx*size+rtx])[(i<<1)+1],cimag(a44_cpx[ctx*size+rtx]));
|
||||
a44_cpx[ctx][rtx] =
|
||||
((double)(a44[ctx][rtx])[i].r) / (1 << (shift0 - 1)) + I * ((double)(a44[ctx][rtx])[i].i) / (1 << (shift0 - 1));
|
||||
}
|
||||
}
|
||||
//Compute Matrix determinant (copy real value only)
|
||||
@@ -1527,13 +1527,10 @@ uint8_t nr_matrix_inverse(int32_t size,
|
||||
|
||||
//Round and convert to Q15 (Out in the same format as Fixed point).
|
||||
if (creal(determin_cpx)>0) {//determin of the symmetric matrix is real part only
|
||||
((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))+0.5);//
|
||||
//((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))+0.5);//
|
||||
((short *)ad_bc)[i << 1] = (short)((creal(determin_cpx) * (1 << (shift0))) + 0.5); //
|
||||
} else {
|
||||
((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)*(1<<(shift0)))-0.5);//
|
||||
//((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)*(1<<(shift0)))-0.5);//
|
||||
((short *)ad_bc)[i << 1] = (short)((creal(determin_cpx) * (1 << (shift0))) - 0.5); //
|
||||
}
|
||||
//if (i<4) printf("nr_det_FP= %d+j%d \n",((short*) ad_bc)[i<<1],((short*) ad_bc)[(i<<1)+1]);
|
||||
//Compute Inversion of the H^*H matrix (normalized output divide by determinant)
|
||||
for (int rtx=0;rtx<size;rtx++) {//row
|
||||
k=0;
|
||||
|
||||
@@ -64,6 +64,6 @@ if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (ENABLE_IMSCOPE)
|
||||
if (ENABLE_IMSCOPE OR ENABLE_IMSCOPE_RECORD)
|
||||
add_subdirectory(imscope)
|
||||
endif()
|
||||
|
||||
@@ -1,35 +1,47 @@
|
||||
if (ENABLE_IMSCOPE)
|
||||
CPMAddPackage("gh:ocornut/imgui#v1.91.3-docking")
|
||||
add_library(imgui
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
)
|
||||
target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR})
|
||||
|
||||
CPMAddPackage("gh:ocornut/imgui#v1.91.3-docking")
|
||||
add_library(imgui
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_tables.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
)
|
||||
target_include_directories(imgui PUBLIC ${imgui_SOURCE_DIR})
|
||||
add_library(imgui_opengl_renderer ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
|
||||
target_include_directories(imgui_opengl_renderer PUBLIC ${imgui_SOURCE_DIR}/backends/)
|
||||
target_link_libraries(imgui_opengl_renderer PUBLIC imgui)
|
||||
|
||||
add_library(imgui_opengl_renderer ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
|
||||
target_include_directories(imgui_opengl_renderer PUBLIC ${imgui_SOURCE_DIR}/backends/)
|
||||
target_link_libraries(imgui_opengl_renderer PUBLIC imgui)
|
||||
add_library(imgui_glfw_backend ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp)
|
||||
target_include_directories(imgui_glfw_backend PUBLIC ${imgui_SOURCE_DIR}/backends/)
|
||||
target_link_libraries(imgui_glfw_backend PUBLIC imgui)
|
||||
|
||||
add_library(imgui_glfw_backend ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp)
|
||||
target_include_directories(imgui_glfw_backend PUBLIC ${imgui_SOURCE_DIR}/backends/)
|
||||
target_link_libraries(imgui_glfw_backend PUBLIC imgui)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(glfw3 3.3 REQUIRED)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(glfw3 3.3 REQUIRED)
|
||||
CPMAddPackage("gh:epezent/implot#v0.16")
|
||||
add_library(implot
|
||||
${implot_SOURCE_DIR}/implot.cpp
|
||||
${implot_SOURCE_DIR}/implot_demo.cpp
|
||||
${implot_SOURCE_DIR}/implot_items.cpp
|
||||
)
|
||||
target_link_libraries(implot PUBLIC imgui)
|
||||
target_include_directories(implot PUBLIC ${implot_SOURCE_DIR})
|
||||
|
||||
CPMAddPackage("gh:epezent/implot#v0.16")
|
||||
add_library(implot
|
||||
${implot_SOURCE_DIR}/implot.cpp
|
||||
${implot_SOURCE_DIR}/implot_demo.cpp
|
||||
${implot_SOURCE_DIR}/implot_items.cpp
|
||||
)
|
||||
target_link_libraries(implot PUBLIC imgui)
|
||||
target_include_directories(implot PUBLIC ${implot_SOURCE_DIR})
|
||||
add_library(imscope MODULE imscope.cpp ../phy_scope_interface.c imscope_common.cpp imscope_init.cpp)
|
||||
target_link_libraries(imscope PUBLIC imgui_glfw_backend glfw imgui_opengl_renderer OpenGL::OpenGL implot UTIL)
|
||||
set_target_properties(imscope PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
configure_file(imgui.ini ${CMAKE_BINARY_DIR}/imscope-init.ini COPYONLY)
|
||||
|
||||
add_executable(imscope_iq_file_viewer imscope.cpp imscope_iq_file_viewer.cpp ../phy_scope_interface.c imscope_common.cpp)
|
||||
target_link_libraries(imscope_iq_file_viewer PRIVATE imgui_glfw_backend glfw imgui_opengl_renderer OpenGL::OpenGL implot UTIL minimal_lib shlib_loader)
|
||||
set_target_properties(imscope_iq_file_viewer PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
if (ENABLE_IMSCOPE_RECORD)
|
||||
add_library(imscope_record MODULE ../phy_scope_interface.c imscope_common.cpp imscope_record.cpp)
|
||||
target_link_libraries(imscope_record PRIVATE UTIL atomic)
|
||||
set_target_properties(imscope_record PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
add_library(imscope MODULE imscope.cpp ../phy_scope_interface.c)
|
||||
target_link_libraries(imscope PUBLIC imgui_glfw_backend glfw imgui_opengl_renderer OpenGL::OpenGL implot UTIL)
|
||||
set_target_properties(imscope PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
configure_file(imgui.ini ${CMAKE_BINARY_DIR}/imscope-init.ini COPYONLY)
|
||||
|
||||
@@ -42,8 +42,11 @@ extern "C" {
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include "imscope_internal.h"
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#define MAX_OFFSETS 14
|
||||
#define NR_MAX_RB 273
|
||||
#define N_SC_PER_RB NR_NB_SC_PER_RB
|
||||
|
||||
@@ -66,77 +69,9 @@ static void glfw_error_callback(int error, const char *description)
|
||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
typedef struct ImScopeData {
|
||||
std::mutex write_mutex;
|
||||
scopeGraphData_t *scope_graph_data;
|
||||
bool is_data_ready;
|
||||
metadata meta;
|
||||
uint64_t time_taken_in_ns;
|
||||
uint64_t time_taken_in_ns_per_offset[MAX_OFFSETS];
|
||||
size_t data_copied_per_offset[MAX_OFFSETS];
|
||||
} ImScopeData;
|
||||
|
||||
typedef struct MovingAverageTimer {
|
||||
uint64_t sum = 0;
|
||||
float average = 0;
|
||||
float last_update_time = 0;
|
||||
void UpdateAverage(float time)
|
||||
{
|
||||
if (time > last_update_time + 1) {
|
||||
float new_average = sum / (float)((time - last_update_time) / 1000);
|
||||
average = 0.95 * average + 0.05 * new_average;
|
||||
sum = 0;
|
||||
}
|
||||
}
|
||||
void Add(uint64_t ns)
|
||||
{
|
||||
sum += ns;
|
||||
}
|
||||
} MovingAverageTimer;
|
||||
|
||||
MovingAverageTimer iq_procedure_timer;
|
||||
|
||||
static ImScopeData scope_array[EXTRA_SCOPE_TYPES];
|
||||
|
||||
typedef struct IQData {
|
||||
std::vector<int16_t> real;
|
||||
std::vector<int16_t> imag;
|
||||
int16_t max_iq;
|
||||
std::vector<float> power;
|
||||
float max_power;
|
||||
float timestamp;
|
||||
int nonzero_count;
|
||||
int len = 0;
|
||||
metadata meta;
|
||||
|
||||
bool TryCollect(ImScopeData *imscope_data, float time, float epsilon)
|
||||
{
|
||||
if (imscope_data->is_data_ready) {
|
||||
iq_procedure_timer.Add(imscope_data->time_taken_in_ns);
|
||||
timestamp = time;
|
||||
scopeGraphData_t *iq_header = imscope_data->scope_graph_data;
|
||||
len = iq_header->lineSz;
|
||||
real.reserve(len);
|
||||
imag.reserve(len);
|
||||
power.reserve(len);
|
||||
c16_t *source = (c16_t *)(iq_header + 1);
|
||||
max_iq = 0;
|
||||
nonzero_count = 0;
|
||||
for (auto i = 0; i < len; i++) {
|
||||
real[i] = source[i].r;
|
||||
imag[i] = source[i].i;
|
||||
max_iq = std::max(max_iq, (int16_t)std::abs(source[i].r));
|
||||
max_iq = std::max(max_iq, (int16_t)std::abs(source[i].i));
|
||||
nonzero_count = std::abs(source[i].r) > epsilon || std::abs(source[i].i) > epsilon ? nonzero_count + 1 : nonzero_count;
|
||||
power[i] = std::sqrt(std::pow(source[i].r, 2) + std::pow(source[i].i, 2));
|
||||
}
|
||||
meta = imscope_data->meta;
|
||||
imscope_data->is_data_ready = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} IQData;
|
||||
ImScopeDataWrapper scope_array[EXTRA_SCOPE_TYPES];
|
||||
|
||||
class LLRPlot {
|
||||
int len = 0;
|
||||
@@ -163,19 +98,19 @@ class LLRPlot {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImScopeData &scope_data = scope_array[type];
|
||||
ImScopeDataWrapper &scope_data = scope_array[type];
|
||||
if (ImPlot::BeginPlot(label)) {
|
||||
if (!frozen || next) {
|
||||
if (scope_data.is_data_ready) {
|
||||
iq_procedure_timer.Add(scope_data.time_taken_in_ns);
|
||||
iq_procedure_timer.Add(scope_data.data.time_taken_in_ns);
|
||||
timestamp = time;
|
||||
const int16_t *tmp = (int16_t *)(scope_data.scope_graph_data + 1);
|
||||
len = scope_data.scope_graph_data->lineSz;
|
||||
const int16_t *tmp = (int16_t *)(scope_data.data.scope_graph_data + 1);
|
||||
len = scope_data.data.scope_graph_data->lineSz;
|
||||
llr.reserve(len);
|
||||
for (auto i = 0; i < len; i++) {
|
||||
llr[i] = tmp[i];
|
||||
}
|
||||
meta = scope_data.meta;
|
||||
meta = scope_data.data.meta;
|
||||
scope_data.is_data_ready = false;
|
||||
if (frozen) {
|
||||
next = false;
|
||||
@@ -323,14 +258,14 @@ class IQSlotHeatmap {
|
||||
bool next = false;
|
||||
float timestamp = 0;
|
||||
std::vector<float> power;
|
||||
ImScopeData *scope_data;
|
||||
ImScopeDataWrapper *scope_data;
|
||||
std::string label;
|
||||
int len = 0;
|
||||
float max = 0;
|
||||
float stop_at_min = 1000;
|
||||
|
||||
public:
|
||||
IQSlotHeatmap(ImScopeData *scope_data_, const char *label_)
|
||||
IQSlotHeatmap(ImScopeDataWrapper *scope_data_, const char *label_)
|
||||
{
|
||||
scope_data = scope_data_;
|
||||
label = label_;
|
||||
@@ -341,7 +276,7 @@ class IQSlotHeatmap {
|
||||
auto num_sc = num_rb * NR_NB_SC_PER_RB;
|
||||
if (!frozen || next) {
|
||||
if (scope_data->is_data_ready) {
|
||||
iq_procedure_timer.Add(scope_data->time_taken_in_ns);
|
||||
iq_procedure_timer.Add(scope_data->data.time_taken_in_ns);
|
||||
uint16_t first_sc = first_carrier_offset;
|
||||
uint16_t last_sc = first_sc + num_rb * NR_NB_SC_PER_RB;
|
||||
bool wrapped = false;
|
||||
@@ -354,7 +289,7 @@ class IQSlotHeatmap {
|
||||
wrapped_last_sc = wrapped_first_sc + num_sc_left - 1;
|
||||
}
|
||||
timestamp = time;
|
||||
scopeGraphData_t *iq_header = scope_data->scope_graph_data;
|
||||
scopeGraphData_t *iq_header = scope_data->data.scope_graph_data;
|
||||
len = iq_header->lineSz;
|
||||
c16_t *source = (c16_t *)(iq_header + 1);
|
||||
|
||||
@@ -458,8 +393,9 @@ struct ScrollingBuffer {
|
||||
}
|
||||
};
|
||||
|
||||
void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
void ShowUeScope(void *data_void_ptr, float t)
|
||||
{
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)data_void_ptr;
|
||||
ImGui::Begin("UE KPI");
|
||||
if (ImPlot::BeginPlot("##Scrolling", ImVec2(-1, 150))) {
|
||||
static float history = 10.0f;
|
||||
@@ -490,7 +426,7 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
static auto pdsch_iq_hist = new IQHist("PDSCH IQ");
|
||||
bool new_data = false;
|
||||
if (pdsch_iq_hist->ShouldReadData()) {
|
||||
new_data = iq_data->TryCollect(&scope_array[pdschRxdataF_comp], t, pdsch_iq_hist->GetEpsilon());
|
||||
new_data = iq_data->TryCollect(&scope_array[pdschRxdataF_comp], t, pdsch_iq_hist->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
pdsch_iq_hist->Draw(iq_data, t, new_data);
|
||||
}
|
||||
@@ -503,7 +439,7 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
static auto time_domain_iq = new IQHist("Time domain samples", disable_scatterplot);
|
||||
bool new_data = false;
|
||||
if (time_domain_iq->ShouldReadData()) {
|
||||
new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamples], t, time_domain_iq->GetEpsilon());
|
||||
new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamples], t, time_domain_iq->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
time_domain_iq->Draw(iq_data, t, new_data);
|
||||
}
|
||||
@@ -516,7 +452,7 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
static auto time_domain_iq = new IQHist("Time domain samples - before sync", disable_scatterplot);
|
||||
bool new_data = false;
|
||||
if (time_domain_iq->ShouldReadData()) {
|
||||
new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamplesBeforeSync], t, time_domain_iq->GetEpsilon());
|
||||
new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamplesBeforeSync], t, time_domain_iq->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
time_domain_iq->Draw(iq_data, t, new_data);
|
||||
}
|
||||
@@ -531,7 +467,7 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
if (broadcast_iq_hist->ShouldReadData()) {
|
||||
new_data = iq_data->TryCollect(&scope_array[ue->sl_mode ? psbchRxdataF_comp : pbchRxdataF_comp],
|
||||
t,
|
||||
broadcast_iq_hist->GetEpsilon());
|
||||
broadcast_iq_hist->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
broadcast_iq_hist->Draw(iq_data, t, new_data);
|
||||
ImGui::TreePop();
|
||||
@@ -543,7 +479,7 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
if (broadcast_iq_chest->ShouldReadData()) {
|
||||
new_data = chest_iq_data->TryCollect(&scope_array[ue->sl_mode ? psbchDlChEstimateTime : pbchDlChEstimateTime],
|
||||
t,
|
||||
broadcast_iq_chest->GetEpsilon());
|
||||
broadcast_iq_chest->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
broadcast_iq_chest->Draw(chest_iq_data, t, new_data);
|
||||
ImGui::TreePop();
|
||||
@@ -568,8 +504,9 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
|
||||
// ImGui::End();
|
||||
}
|
||||
|
||||
void ShowGnbScope(PHY_VARS_gNB *gNB, float t)
|
||||
void ShowGnbScope(void *data_void_ptr, float t)
|
||||
{
|
||||
(void)data_void_ptr;
|
||||
// if (ImGui::TreeNode("RX IQ")) {
|
||||
// static auto gnb_heatmap = new IQSlotHeatmap(&scope_array[gNBRxdataF], "common RX IQ");
|
||||
|
||||
@@ -585,7 +522,7 @@ void ShowGnbScope(PHY_VARS_gNB *gNB, float t)
|
||||
static auto pusch_iq_display = new IQHist("PUSCH compensated IQ");
|
||||
bool new_data = false;
|
||||
if (pusch_iq_display->ShouldReadData()) {
|
||||
new_data = pusch_iq->TryCollect(&scope_array[gNBPuschRxIq], t, pusch_iq_display->GetEpsilon());
|
||||
new_data = pusch_iq->TryCollect(&scope_array[gNBPuschRxIq], t, pusch_iq_display->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
pusch_iq_display->Draw(pusch_iq, t, new_data);
|
||||
}
|
||||
@@ -604,13 +541,33 @@ void ShowGnbScope(PHY_VARS_gNB *gNB, float t)
|
||||
static auto time_domain_iq = new IQHist("Time domain samples", disable_scatterplot);
|
||||
bool new_data = false;
|
||||
if (time_domain_iq->ShouldReadData()) {
|
||||
new_data = iq_data->TryCollect(&scope_array[gNbTimeDomainSamples], t, time_domain_iq->GetEpsilon());
|
||||
new_data = iq_data->TryCollect(&scope_array[gNbTimeDomainSamples], t, time_domain_iq->GetEpsilon(), iq_procedure_timer);
|
||||
}
|
||||
time_domain_iq->Draw(iq_data, t, new_data);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ShowIQFileViewer(void *data_void_ptr)
|
||||
{
|
||||
auto iq_data = static_cast<std::vector<IQData> *>(data_void_ptr);
|
||||
if (ImGui::Begin("Scope selection")) {
|
||||
static int selected_scope = 0;
|
||||
ImGui::Combo(
|
||||
"Select scope",
|
||||
&selected_scope,
|
||||
[](void *userdata, int idx) {
|
||||
std::vector<IQData> *iq_data = static_cast<std::vector<IQData>*>(userdata);
|
||||
return scope_id_to_string(static_cast<scopeDataType>((*iq_data)[idx].scope_id));
|
||||
},
|
||||
iq_data,
|
||||
iq_data->size());
|
||||
static auto iq_display = new IQHist("IQ File Viewer");
|
||||
iq_display->Draw(&(*iq_data)[selected_scope], 0, false);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void *imscope_thread(void *data_void_ptr)
|
||||
{
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
@@ -678,6 +635,7 @@ void *imscope_thread(void *data_void_ptr)
|
||||
static int target_fps = 24;
|
||||
|
||||
bool is_ue = IS_SOFTMODEM_5GUE;
|
||||
bool is_gnb = IS_SOFTMODEM_GNB;
|
||||
bool close_window = false;
|
||||
while (!glfwWindowShouldClose(window) && close_window == false) {
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
@@ -694,8 +652,7 @@ void *imscope_thread(void *data_void_ptr)
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
static bool reset_ini_settings = false;
|
||||
if (reset_ini_settings)
|
||||
{
|
||||
if (reset_ini_settings) {
|
||||
ImGui::LoadIniSettingsFromDisk("imscope-init.ini");
|
||||
reset_ini_settings = false;
|
||||
}
|
||||
@@ -722,7 +679,7 @@ void *imscope_thread(void *data_void_ptr)
|
||||
}
|
||||
if (ImGui::BeginMenu("Layout")) {
|
||||
if (ImGui::MenuItem("Reset")) {
|
||||
reset_ini_settings = true;
|
||||
reset_ini_settings = true;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -750,12 +707,11 @@ void *imscope_thread(void *data_void_ptr)
|
||||
iq_procedure_timer.UpdateAverage(t);
|
||||
|
||||
if (is_ue) {
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)data_void_ptr;
|
||||
ShowUeScope(ue, t);
|
||||
ShowUeScope(data_void_ptr, t);
|
||||
} else if (is_gnb) {
|
||||
ShowGnbScope(data_void_ptr, t);
|
||||
} else {
|
||||
scopeParms_t *scope_params = (scopeParms_t *)data_void_ptr;
|
||||
PHY_VARS_gNB *gNB = scope_params->gNB;
|
||||
ShowGnbScope(gNB, t);
|
||||
ShowIQFileViewer(data_void_ptr);
|
||||
}
|
||||
|
||||
// For reference
|
||||
@@ -791,147 +747,3 @@ void *imscope_thread(void *data_void_ptr)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" void imscope_autoinit(void *dataptr)
|
||||
{
|
||||
AssertFatal(IS_SOFTMODEM_5GUE || IS_SOFTMODEM_GNB, "Scope cannot find NRUE or GNB context");
|
||||
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
scope_array[i].is_data_ready = false;
|
||||
scope_array[i].scope_graph_data = nullptr;
|
||||
scope_array[i].meta = {-1, -1};
|
||||
}
|
||||
|
||||
if (IS_SOFTMODEM_GNB) {
|
||||
scopeParms_t *scope_params = (scopeParms_t *)dataptr;
|
||||
scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t));
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
scope->tryLockScopeData = tryLockScopeData;
|
||||
scope->copyDataUnsafeWithOffset = copyDataUnsafeWithOffset;
|
||||
scope->unlockScopeData = unlockScopeData;
|
||||
scope_params->gNB->scopeData = scope;
|
||||
scope_params->ru->scopeData = scope;
|
||||
} else {
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)dataptr;
|
||||
scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t));
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
ue->scopeData = scope;
|
||||
}
|
||||
pthread_t thread;
|
||||
threadCreate(&thread, imscope_thread, dataptr, (char *)"imscope", -1, sched_get_priority_min(SCHED_RR));
|
||||
}
|
||||
|
||||
void copyDataThreadSafe(void *scopeData,
|
||||
enum scopeDataType type,
|
||||
void *dataIn,
|
||||
int elementSz,
|
||||
int colSz,
|
||||
int lineSz,
|
||||
int offset,
|
||||
metadata *meta)
|
||||
{
|
||||
ImScopeData &scope_data = scope_array[type];
|
||||
|
||||
if (scope_data.is_data_ready) {
|
||||
// data is ready, wasn't consumed yet by scope
|
||||
return;
|
||||
}
|
||||
|
||||
if (scope_data.write_mutex.try_lock()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.scope_graph_data;
|
||||
int oldDataSz = data ? data->dataSize : 0;
|
||||
int newSz = elementSz * colSz * lineSz;
|
||||
if (data == NULL || oldDataSz < newSz) {
|
||||
free(data);
|
||||
scopeGraphData_t *ptr = (scopeGraphData_t *)malloc(sizeof(scopeGraphData_t) + newSz);
|
||||
if (!ptr) {
|
||||
LOG_E(PHY, "can't realloc\n");
|
||||
return;
|
||||
} else {
|
||||
data = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
data->elementSz = elementSz;
|
||||
data->colSz = colSz;
|
||||
data->lineSz = lineSz;
|
||||
data->dataSize = newSz;
|
||||
memcpy(((void *)(data + 1)), dataIn, newSz);
|
||||
scope_data.scope_graph_data = data;
|
||||
scope_data.meta = *meta;
|
||||
scope_data.time_taken_in_ns =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
scope_data.is_data_ready = true;
|
||||
scope_data.write_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool tryLockScopeData(enum scopeDataType type, int elementSz, int colSz, int lineSz, metadata *meta)
|
||||
{
|
||||
ImScopeData &scope_data = scope_array[type];
|
||||
|
||||
if (scope_data.is_data_ready) {
|
||||
// data is ready, wasn't consumed yet by scope
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scope_data.write_mutex.try_lock()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.scope_graph_data;
|
||||
int oldDataSz = data ? data->dataSize : 0;
|
||||
int newSz = elementSz * colSz * lineSz;
|
||||
if (data == NULL || oldDataSz < newSz) {
|
||||
free(data);
|
||||
scopeGraphData_t *ptr = (scopeGraphData_t *)malloc(sizeof(scopeGraphData_t) + newSz);
|
||||
if (!ptr) {
|
||||
LOG_E(PHY, "can't realloc\n");
|
||||
return false;
|
||||
} else {
|
||||
data = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
data->elementSz = elementSz;
|
||||
data->colSz = colSz;
|
||||
data->lineSz = lineSz;
|
||||
data->dataSize = newSz;
|
||||
scope_data.scope_graph_data = data;
|
||||
scope_data.meta = *meta;
|
||||
scope_data.time_taken_in_ns =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
memset(scope_data.time_taken_in_ns_per_offset, 0, sizeof(scope_data.time_taken_in_ns_per_offset));
|
||||
memset(scope_data.data_copied_per_offset, 0, sizeof(scope_data.data_copied_per_offset));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void copyDataUnsafeWithOffset(enum scopeDataType type, void *dataIn, size_t size, size_t offset, int copy_index)
|
||||
{
|
||||
AssertFatal(copy_index < MAX_OFFSETS, "Unexpected number of copies per sink. copy_index = %d\n", copy_index);
|
||||
ImScopeData &scope_data = scope_array[type];
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.scope_graph_data;
|
||||
uint8_t *outptr = (uint8_t *)(data + 1);
|
||||
memcpy(&outptr[offset], dataIn, size);
|
||||
scope_data.time_taken_in_ns_per_offset[copy_index] =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
scope_data.data_copied_per_offset[copy_index] = size;
|
||||
}
|
||||
|
||||
void unlockScopeData(enum scopeDataType type)
|
||||
{
|
||||
ImScopeData &scope_data = scope_array[type];
|
||||
size_t total_size = 0;
|
||||
for (auto i = 0; i < MAX_OFFSETS; i++) {
|
||||
scope_data.time_taken_in_ns += scope_data.time_taken_in_ns_per_offset[i];
|
||||
total_size += scope_data.data_copied_per_offset[i];
|
||||
}
|
||||
if (total_size != (uint64_t)scope_data.scope_graph_data->dataSize) {
|
||||
LOG_E(PHY,
|
||||
"Scope is missing data - not all data that was expected was copied - possibly missed copyDataUnsafeWithOffset call\n");
|
||||
}
|
||||
scope_data.is_data_ready = true;
|
||||
scope_data.write_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 "imscope_internal.h"
|
||||
#include <chrono>
|
||||
|
||||
void copyDataThreadSafe(void *scopeData,
|
||||
enum scopeDataType type,
|
||||
void *dataIn,
|
||||
int elementSz,
|
||||
int colSz,
|
||||
int lineSz,
|
||||
int offset,
|
||||
metadata *meta)
|
||||
{
|
||||
ImScopeDataWrapper &scope_data = scope_array[type];
|
||||
|
||||
if (scope_data.is_data_ready) {
|
||||
// data is ready, wasn't consumed yet by scope
|
||||
return;
|
||||
}
|
||||
|
||||
if (scope_data.write_mutex.try_lock()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.data.scope_graph_data;
|
||||
int oldDataSz = data ? data->dataSize : 0;
|
||||
int newSz = elementSz * colSz * lineSz;
|
||||
if (data == NULL || oldDataSz < newSz) {
|
||||
free(data);
|
||||
scopeGraphData_t *ptr = (scopeGraphData_t *)malloc(sizeof(scopeGraphData_t) + newSz);
|
||||
if (!ptr) {
|
||||
LOG_E(PHY, "can't realloc\n");
|
||||
return;
|
||||
} else {
|
||||
data = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
data->elementSz = elementSz;
|
||||
data->colSz = colSz;
|
||||
data->lineSz = lineSz;
|
||||
data->dataSize = newSz;
|
||||
memcpy(((void *)(data + 1)), dataIn, newSz);
|
||||
scope_data.data.scope_graph_data = data;
|
||||
scope_data.data.meta = *meta;
|
||||
scope_data.data.time_taken_in_ns =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
scope_data.data.scope_id = type;
|
||||
scope_data.is_data_ready = true;
|
||||
scope_data.write_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool tryLockScopeData(enum scopeDataType type, int elementSz, int colSz, int lineSz, metadata *meta)
|
||||
{
|
||||
ImScopeDataWrapper &scope_data = scope_array[type];
|
||||
|
||||
if (scope_data.is_data_ready) {
|
||||
// data is ready, wasn't consumed yet by scope
|
||||
return false;
|
||||
}
|
||||
|
||||
if (scope_data.write_mutex.try_lock()) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.data.scope_graph_data;
|
||||
int oldDataSz = data ? data->dataSize : 0;
|
||||
int newSz = elementSz * colSz * lineSz;
|
||||
if (data == NULL || oldDataSz < newSz) {
|
||||
free(data);
|
||||
scopeGraphData_t *ptr = (scopeGraphData_t *)malloc(sizeof(scopeGraphData_t) + newSz);
|
||||
if (!ptr) {
|
||||
LOG_E(PHY, "can't realloc\n");
|
||||
return false;
|
||||
} else {
|
||||
data = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
data->elementSz = elementSz;
|
||||
data->colSz = colSz;
|
||||
data->lineSz = lineSz;
|
||||
data->dataSize = newSz;
|
||||
scope_data.data.scope_graph_data = data;
|
||||
scope_data.data.meta = *meta;
|
||||
scope_data.data.time_taken_in_ns =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
memset(scope_data.data.time_taken_in_ns_per_offset, 0, sizeof(scope_data.data.time_taken_in_ns_per_offset));
|
||||
memset(scope_data.data.data_copied_per_offset, 0, sizeof(scope_data.data.data_copied_per_offset));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void copyDataUnsafeWithOffset(enum scopeDataType type, void *dataIn, size_t size, size_t offset, int copy_index)
|
||||
{
|
||||
AssertFatal(copy_index < MAX_OFFSETS, "Unexpected number of copies per sink. copy_index = %d\n", copy_index);
|
||||
ImScopeDataWrapper &scope_data = scope_array[type];
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
scopeGraphData_t *data = scope_data.data.scope_graph_data;
|
||||
uint8_t *outptr = (uint8_t *)(data + 1);
|
||||
memcpy(&outptr[offset], dataIn, size);
|
||||
scope_data.data.time_taken_in_ns_per_offset[copy_index] =
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start).count();
|
||||
scope_data.data.data_copied_per_offset[copy_index] = size;
|
||||
}
|
||||
|
||||
void unlockScopeData(enum scopeDataType type)
|
||||
{
|
||||
ImScopeDataWrapper &scope_data = scope_array[type];
|
||||
size_t total_size = 0;
|
||||
for (auto i = 0; i < MAX_OFFSETS; i++) {
|
||||
scope_data.data.time_taken_in_ns += scope_data.data.time_taken_in_ns_per_offset[i];
|
||||
total_size += scope_data.data.data_copied_per_offset[i];
|
||||
}
|
||||
if (total_size != (uint64_t)scope_data.data.scope_graph_data->dataSize) {
|
||||
LOG_E(PHY,
|
||||
"Scope is missing data - not all data that was expected was copied - possibly missed copyDataUnsafeWithOffset call. "
|
||||
"scope = %s, total_size = %lu, dataSize = %d\n",
|
||||
scope_id_to_string(type),
|
||||
total_size,
|
||||
scope_data.data.scope_graph_data->dataSize);
|
||||
}
|
||||
scope_data.data.scope_id = type;
|
||||
scope_data.is_data_ready = true;
|
||||
scope_data.write_mutex.unlock();
|
||||
}
|
||||
|
||||
const char *scope_id_to_string(scopeDataType type) {
|
||||
switch (type) {
|
||||
case pbchDlChEstimateTime:
|
||||
return "pbchDlChEstimateTime";
|
||||
case pbchLlr:
|
||||
return "pbchLlr";
|
||||
case pbchRxdataF_comp:
|
||||
return "pbchRxdataF_comp";
|
||||
case pdcchLlr:
|
||||
return "pdcchLlr";
|
||||
case pdcchRxdataF_comp:
|
||||
return "pdcchRxdataF_comp";
|
||||
case pdschLlr:
|
||||
return "pdschLlr";
|
||||
case pdschRxdataF_comp:
|
||||
return "pdschRxdataF_comp";
|
||||
case commonRxdataF:
|
||||
return "commonRxdataF";
|
||||
case gNBRxdataF:
|
||||
return "gNBRxdataF";
|
||||
case psbchDlChEstimateTime:
|
||||
return "psbchDlChEstimateTime";
|
||||
case psbchLlr:
|
||||
return "psbchLlr";
|
||||
case psbchRxdataF_comp:
|
||||
return "psbchRxdataF_comp";
|
||||
case gNBPuschRxIq:
|
||||
return "gNBPuschRxIq";
|
||||
case gNBPuschLlr:
|
||||
return "gNBPuschLlr";
|
||||
case ueTimeDomainSamples:
|
||||
return "ueTimeDomainSamples";
|
||||
case ueTimeDomainSamplesBeforeSync:
|
||||
return "ueTimeDomainSamplesBeforeSync";
|
||||
case gNbTimeDomainSamples:
|
||||
return "gNbTimeDomainSamples";
|
||||
default:
|
||||
return "unknown type";
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const ImScopeData &dt)
|
||||
{
|
||||
os << "dataSize: " << dt.scope_graph_data->dataSize << " elementSz: " << dt.scope_graph_data->elementSz
|
||||
<< " colSz: " << dt.scope_graph_data->colSz << " lineSz: " << dt.scope_graph_data->lineSz;
|
||||
os << " meta: " << dt.meta.frame << "." << dt.meta.slot
|
||||
<< " scope_id: " << scope_id_to_string(static_cast<scopeDataType>(dt.scope_id));
|
||||
return os;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "imscope_internal.h"
|
||||
|
||||
extern "C" void imscope_autoinit(void *dataptr)
|
||||
{
|
||||
AssertFatal(IS_SOFTMODEM_5GUE || IS_SOFTMODEM_GNB,
|
||||
"Scope cannot find NRUE or GNB context");
|
||||
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
scope_array[i].is_data_ready = false;
|
||||
scope_array[i].data.scope_graph_data = nullptr;
|
||||
scope_array[i].data.meta = {-1, -1};
|
||||
}
|
||||
|
||||
scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t));
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
scope->tryLockScopeData = tryLockScopeData;
|
||||
scope->copyDataUnsafeWithOffset = copyDataUnsafeWithOffset;
|
||||
scope->unlockScopeData = unlockScopeData;
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
if (IS_SOFTMODEM_GNB) {
|
||||
scopeParms_t *scope_params = (scopeParms_t *)dataptr;
|
||||
scope_params->gNB->scopeData = scope;
|
||||
scope_params->ru->scopeData = scope;
|
||||
} else {
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)dataptr;
|
||||
ue->scopeData = scope;
|
||||
}
|
||||
|
||||
pthread_t thread;
|
||||
threadCreate(&thread, imscope_thread, dataptr, (char *)"imscope", -1, sched_get_priority_min(SCHED_RR));
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef IMSCOPE_INTERNAL_H
|
||||
#define IMSCOPE_INTERNAL_H
|
||||
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "openair1/PHY/defs_nr_UE.h"
|
||||
extern "C" {
|
||||
#include "../phy_scope_interface.h"
|
||||
}
|
||||
|
||||
#define MAX_OFFSETS 14
|
||||
|
||||
const char *scope_id_to_string(scopeDataType type);
|
||||
|
||||
typedef struct ImScopeData {
|
||||
scopeGraphData_t *scope_graph_data;
|
||||
metadata meta;
|
||||
uint64_t time_taken_in_ns;
|
||||
uint64_t time_taken_in_ns_per_offset[MAX_OFFSETS];
|
||||
size_t data_copied_per_offset[MAX_OFFSETS];
|
||||
int scope_id;
|
||||
|
||||
void dump_to_file(std::ofstream& stream) {
|
||||
stream.write((char*)scope_graph_data, sizeof(*scope_graph_data));
|
||||
stream.write((char*)&meta, sizeof(meta));
|
||||
stream.write((char*)&scope_id, sizeof(scope_id));
|
||||
char *source = (char *)(scope_graph_data + 1);
|
||||
stream.write(source, scope_graph_data->dataSize);
|
||||
}
|
||||
|
||||
void read_from_file(std::ifstream& stream) {
|
||||
scopeGraphData_t temp;
|
||||
stream.read((char*)&temp, sizeof(temp));
|
||||
stream.read((char*)&meta, sizeof(meta));
|
||||
stream.read((char*)&scope_id, sizeof(scope_id));
|
||||
scope_graph_data = static_cast<scopeGraphData_t *>(malloc(temp.dataSize + sizeof(*scope_graph_data)));
|
||||
*scope_graph_data = temp;
|
||||
char *dest = (char *)(scope_graph_data + 1);
|
||||
stream.read(dest, temp.dataSize);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const ImScopeData& dt);
|
||||
} ImScopeData;
|
||||
|
||||
typedef struct MovingAverageTimer {
|
||||
uint64_t sum = 0;
|
||||
float average = 0;
|
||||
float last_update_time = 0;
|
||||
void UpdateAverage(float time)
|
||||
{
|
||||
if (time > last_update_time + 1) {
|
||||
float new_average = sum / (float)((time - last_update_time) / 1000);
|
||||
average = 0.95 * average + 0.05 * new_average;
|
||||
sum = 0;
|
||||
}
|
||||
}
|
||||
void Add(uint64_t ns)
|
||||
{
|
||||
sum += ns;
|
||||
}
|
||||
} MovingAverageTimer;
|
||||
|
||||
typedef struct ImScopeDataWrapper {
|
||||
std::mutex write_mutex;
|
||||
bool is_data_ready;
|
||||
ImScopeData data;
|
||||
} ImScopeDataWrapper;
|
||||
|
||||
typedef struct IQData {
|
||||
std::vector<int16_t> real;
|
||||
std::vector<int16_t> imag;
|
||||
int16_t max_iq;
|
||||
std::vector<float> power;
|
||||
float max_power;
|
||||
float timestamp;
|
||||
int nonzero_count;
|
||||
int len = 0;
|
||||
metadata meta;
|
||||
int scope_id;
|
||||
|
||||
bool TryCollect(ImScopeDataWrapper *imscope_data_wrapper, float time, float epsilon, MovingAverageTimer &iq_procedure_timer)
|
||||
{
|
||||
if (imscope_data_wrapper->is_data_ready) {
|
||||
Collect(&imscope_data_wrapper->data, time, epsilon);
|
||||
iq_procedure_timer.Add(imscope_data_wrapper->data.time_taken_in_ns);
|
||||
imscope_data_wrapper->is_data_ready = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Collect(ImScopeData *scope_data, float time, float epsilon) {
|
||||
timestamp = time;
|
||||
scopeGraphData_t *iq_header = scope_data->scope_graph_data;
|
||||
len = iq_header->lineSz;
|
||||
real.resize(len);
|
||||
imag.resize(len);
|
||||
power.resize(len);
|
||||
c16_t *source = (c16_t *)(iq_header + 1);
|
||||
max_iq = 0;
|
||||
nonzero_count = 0;
|
||||
for (auto i = 0; i < len; i++) {
|
||||
real[i] = source[i].r;
|
||||
imag[i] = source[i].i;
|
||||
max_iq = std::max(max_iq, (int16_t)std::abs(source[i].r));
|
||||
max_iq = std::max(max_iq, (int16_t)std::abs(source[i].i));
|
||||
nonzero_count = std::abs(source[i].r) > epsilon || std::abs(source[i].i) > epsilon ? nonzero_count + 1 : nonzero_count;
|
||||
power[i] = std::sqrt(std::pow(source[i].r, 2) + std::pow(source[i].i, 2));
|
||||
}
|
||||
meta = scope_data->meta;
|
||||
scope_id = scope_data->scope_id;
|
||||
}
|
||||
} IQData;
|
||||
|
||||
extern ImScopeDataWrapper scope_array[EXTRA_SCOPE_TYPES];
|
||||
|
||||
void copyDataThreadSafe(void *scopeData,
|
||||
enum scopeDataType type,
|
||||
void *dataIn,
|
||||
int elementSz,
|
||||
int colSz,
|
||||
int lineSz,
|
||||
int offset,
|
||||
metadata *meta);
|
||||
|
||||
bool tryLockScopeData(enum scopeDataType type, int elementSz, int colSz, int lineSz, metadata *meta);
|
||||
|
||||
void copyDataUnsafeWithOffset(enum scopeDataType type, void *dataIn, size_t size, size_t offset, int copy_index);
|
||||
|
||||
void unlockScopeData(enum scopeDataType type);
|
||||
|
||||
void dumpScopeData(int slot, int frame, const char *cause_string);
|
||||
|
||||
void *imscope_record_thread(void *data_void_ptr);
|
||||
void *imscope_thread(void *data_void_ptr);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 <stdint.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "imscope_internal.h"
|
||||
|
||||
static extended_kpi_ue kpiStructure;
|
||||
|
||||
extern "C" {
|
||||
static softmodem_params_t softmodem_params;
|
||||
softmodem_params_t *get_softmodem_params(void)
|
||||
{
|
||||
return &softmodem_params;
|
||||
}
|
||||
extended_kpi_ue *getKPIUE(void)
|
||||
{
|
||||
return &kpiStructure;
|
||||
}
|
||||
}
|
||||
|
||||
void *imscope_thread(void *data_void_ptr);
|
||||
|
||||
|
||||
std::vector<IQData> LoadFromFile(char *filename) {
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
std::vector<IQData> iq_data;
|
||||
if (file.is_open()) {
|
||||
while (file.peek() != EOF) {
|
||||
ImScopeData source;
|
||||
source.read_from_file(file);
|
||||
std::cout << "Loaded from IQ from file: " << source << std::endl;
|
||||
IQData iq;
|
||||
iq.Collect(&source, 0, 0);
|
||||
iq_data.push_back(iq);
|
||||
}
|
||||
}
|
||||
return iq_data;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<IQData> iq_data = LoadFromFile(argv[1]);
|
||||
if (iq_data.size() == 0) {
|
||||
printf("Error: No IQ data found in file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
imscope_thread(static_cast<void *>(&iq_data));
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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 "imscope_internal.h"
|
||||
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <atomic>
|
||||
#include <new>
|
||||
|
||||
#ifdef __cpp_lib_hardware_interference_size
|
||||
using std::hardware_constructive_interference_size;
|
||||
using std::hardware_destructive_interference_size;
|
||||
#else
|
||||
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
|
||||
constexpr std::size_t hardware_constructive_interference_size = 64;
|
||||
constexpr std::size_t hardware_destructive_interference_size = 64;
|
||||
#endif
|
||||
|
||||
#define NUM_CACHED_DATA 4
|
||||
// Set maximum number of kilobytes written per recording session to 1GB. This is a safeguard against
|
||||
// recoding thread writing too many files and exhausting disk space.
|
||||
#define MAX_KBYTES_WRITTEN_PER_SESSION (1000 * 1000)
|
||||
|
||||
ImScopeDataWrapper scope_array[EXTRA_SCOPE_TYPES];
|
||||
typedef struct alignas(hardware_destructive_interference_size) ImScopeDumpInstruction {
|
||||
int slot;
|
||||
int frame;
|
||||
const char *cause;
|
||||
} ImScopeDumpInstruction;
|
||||
|
||||
std::atomic<ImScopeDumpInstruction> dump_instruction;
|
||||
ImScopeDumpInstruction void_instruction({-1, -1, nullptr});
|
||||
|
||||
extern "C" void imscope_record_autoinit(void *dataptr)
|
||||
{
|
||||
AssertFatal(IS_SOFTMODEM_5GUE || IS_SOFTMODEM_GNB,
|
||||
"Scope cannot find NRUE or GNB context");
|
||||
LOG_A(PHY, "Imscope recording started\n");
|
||||
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
scope_array[i].is_data_ready = false;
|
||||
scope_array[i].data.scope_graph_data = nullptr;
|
||||
scope_array[i].data.meta = {-1, -1};
|
||||
}
|
||||
|
||||
dump_instruction.exchange(void_instruction);
|
||||
|
||||
scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t));
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
scope->tryLockScopeData = tryLockScopeData;
|
||||
scope->copyDataUnsafeWithOffset = copyDataUnsafeWithOffset;
|
||||
scope->unlockScopeData = unlockScopeData;
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
scope->dumpScopeData = dumpScopeData;
|
||||
if (IS_SOFTMODEM_GNB) {
|
||||
scopeParms_t *scope_params = (scopeParms_t *)dataptr;
|
||||
scope_params->gNB->scopeData = scope;
|
||||
scope_params->ru->scopeData = scope;
|
||||
} else {
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)dataptr;
|
||||
ue->scopeData = scope;
|
||||
}
|
||||
|
||||
pthread_t thread;
|
||||
threadCreate(&thread, imscope_record_thread, dataptr, (char *)"imscope_record", -1, sched_get_priority_min(SCHED_RR));
|
||||
}
|
||||
|
||||
void dumpScopeData(int slot, int frame, const char *cause_string)
|
||||
{
|
||||
ImScopeDumpInstruction to_dump = {slot, frame, cause_string};
|
||||
dump_instruction.compare_exchange_weak(void_instruction, to_dump);
|
||||
}
|
||||
|
||||
void *imscope_record_thread(void *data_void_ptr)
|
||||
{
|
||||
const char *path = "imscope-dump";
|
||||
struct stat info;
|
||||
bool has_dir = false;
|
||||
if (stat(path, &info) == 0) {
|
||||
if (info.st_mode & S_IFDIR) {
|
||||
has_dir = true;
|
||||
}
|
||||
}
|
||||
if (has_dir) {
|
||||
LOG_A(PHY, "ImScope recorder thread starts, recording data to %s\n", path);
|
||||
} else {
|
||||
LOG_A(PHY, "ImScope recorder thread starts, recording data to cwd\n");
|
||||
}
|
||||
|
||||
std::string program_name(program_invocation_name);
|
||||
size_t last_slash = program_name.find_last_of("/");
|
||||
if (last_slash != std::string::npos) {
|
||||
program_name = program_name.substr(last_slash + 1);
|
||||
}
|
||||
|
||||
ImScopeData scope_cache[EXTRA_SCOPE_TYPES][NUM_CACHED_DATA];
|
||||
memset(scope_cache, 0, sizeof(scope_cache));
|
||||
uint scope_cache_index[EXTRA_SCOPE_TYPES] = {0};
|
||||
float kbytes_written = 0.0f;
|
||||
while (kbytes_written < MAX_KBYTES_WRITTEN_PER_SESSION) {
|
||||
ImScopeDumpInstruction dump = dump_instruction.load(std::memory_order::memory_order_relaxed);
|
||||
if (dump.slot != -1) {
|
||||
std::string filename;
|
||||
if (has_dir) {
|
||||
filename += std::string(path) + "/";
|
||||
}
|
||||
filename += program_name + std::string("-") + dump.cause + std::string("-");
|
||||
filename += std::to_string(dump.frame) + std::string("-") + std::to_string(dump.slot) + std::string(".imscope");
|
||||
std::ofstream outf(filename, std::ios_base::out | std::ios_base::binary);
|
||||
if (!outf) {
|
||||
LOG_E(PHY, "Could not open file %s for writing\n", filename.c_str());
|
||||
break;
|
||||
}
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
for (auto j = 0U; j < NUM_CACHED_DATA; j++) {
|
||||
ImScopeData &scope_data = scope_cache[i][j];
|
||||
if (scope_data.meta.frame == dump.frame && scope_data.meta.slot == dump.slot) {
|
||||
scope_data.dump_to_file(outf);
|
||||
}
|
||||
}
|
||||
}
|
||||
long pos = outf.tellp();
|
||||
kbytes_written += pos / 1000.0f;
|
||||
outf.close();
|
||||
LOG_D(PHY, "ImScope done writing to %s\n", filename.c_str());
|
||||
dump_instruction.exchange(void_instruction);
|
||||
}
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
ImScopeDataWrapper &scope_data = scope_array[i];
|
||||
if (scope_data.is_data_ready) {
|
||||
uint cache_index = scope_cache_index[i]++ % NUM_CACHED_DATA;
|
||||
ImScopeData tmp = scope_cache[i][cache_index];
|
||||
scope_cache[i][cache_index] = scope_data.data;
|
||||
scope_data.data = tmp;
|
||||
scope_data.is_data_ready = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_E(PHY, "ImScope recorder thread exits!\n");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -112,6 +112,7 @@ typedef struct scopeData_s {
|
||||
bool (*tryLockScopeData)(enum scopeDataType type, int elementSz, int colSz, int lineSz, metadata *meta);
|
||||
void (*copyDataUnsafeWithOffset)(enum scopeDataType type, void *dataIn, size_t size, size_t offset, int copy_index);
|
||||
void (*unlockScopeData)(enum scopeDataType type);
|
||||
void (*dumpScopeData)(int slot, int frame, const char *cause_string);
|
||||
} scopeData_t;
|
||||
|
||||
int load_softscope(char *exectype, void *initarg);
|
||||
@@ -157,6 +158,14 @@ void copyData(void *, enum scopeDataType type, void *dataIn, int elementSz, int
|
||||
scope_data->unlockScopeData(type); \
|
||||
}
|
||||
|
||||
#define gNBdumpScopeData(gnb, slot, frame, cause_string) \
|
||||
do { \
|
||||
scopeData_t *scope_data = (scopeData_t *)gnb->scopeData; \
|
||||
if (scope_data && scope_data->dumpScopeData) { \
|
||||
scope_data->dumpScopeData((slot), (frame), (cause_string)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define UEScopeHasTryLock(ue) \
|
||||
(ue->scopeData && ((scopeData_t *)ue->scopeData)->tryLockScopeData)
|
||||
|
||||
@@ -176,6 +185,20 @@ void copyData(void *, enum scopeDataType type, void *dataIn, int elementSz, int
|
||||
scope_data->unlockScopeData(type); \
|
||||
}
|
||||
|
||||
#define UEdumpScopeData(ue, slot, frame, cause_string) \
|
||||
do { \
|
||||
scopeData_t *scope_data = (scopeData_t *)ue->scopeData; \
|
||||
if (scope_data && scope_data->dumpScopeData) { \
|
||||
scope_data->dumpScopeData((slot), (frame), (cause_string)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extended_kpi_ue* getKPIUE();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,3 +69,21 @@ Run with `--imscope` flag
|
||||
|
||||
Report bugs and feature requests on [gitlab](https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues). There is two demo windows
|
||||
enabled in the scope that showcase imgui/implot, if you find something of interest it can be implemented in the scope.
|
||||
|
||||
## Recording scope data and reviewing recorded IQ files
|
||||
|
||||
It is possible to record scope data from the modems.
|
||||
- To record IQ data, run a modem with `--imscope-record` flag.
|
||||
The recording happens whenever a modem calls `dumpScopeData`, which currently is
|
||||
done only in gNB on PUSCH DTX and PUSCH CRC NOK.
|
||||
There is a limit of ~1GB of files written by the thread in a single run to avoid
|
||||
accidentally exhausting disk space.
|
||||
If a directory `imscope-dump` is available the data will be recorded there in .imscope
|
||||
files. Otherwise files are written to the directory the modem was run. This is done so that
|
||||
the directory can be mapped in a docker container.
|
||||
|
||||
- To view recorded IQ files, use the new executable `imscope_iq_file_viewer`. This can be done by running:
|
||||
```
|
||||
./imscope_iq_file_viewer <path_to_iq_file>
|
||||
```
|
||||
Replace `<path_to_iq_file>` with the path to the IQ file you want to view.
|
||||
|
||||
@@ -627,6 +627,7 @@ typedef struct nr_rxtx_thread_data_s {
|
||||
PHY_VARS_NR_UE *UE;
|
||||
int writeBlockSize;
|
||||
nr_phy_data_t phy_data;
|
||||
dynamic_barrier_t *next_barrier;
|
||||
} nr_rxtx_thread_data_t;
|
||||
|
||||
typedef struct LDPCDecode_ue_s {
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
|
||||
#define NR_MOD_TABLE_SIZE_SHORT 686
|
||||
#define NR_MOD_TABLE_BPSK_OFFSET 1
|
||||
#define NR_MOD_TABLE_QPSK_OFFSET 3
|
||||
#define NR_MOD_TABLE_QAM16_OFFSET 7
|
||||
#define NR_MOD_TABLE_QAM64_OFFSET 23
|
||||
#define NR_MOD_TABLE_QAM256_OFFSET 87
|
||||
|
||||
@@ -39,14 +39,7 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
|
||||
|
||||
extern int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
extern int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
|
||||
extern int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
extern int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req);
|
||||
|
||||
|
||||
extern uint8_t nfapi_mode;
|
||||
#include "nfapi/oai_integration/nfapi_vnf.h"
|
||||
|
||||
void handle_nr_nfapi_ssb_pdu(processingData_L1tx_t *msgTx,int frame,int slot,
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu)
|
||||
|
||||
@@ -42,9 +42,6 @@
|
||||
#include "assertions.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
uint8_t get_nr_prach_duration(uint8_t prach_format){
|
||||
|
||||
switch(prach_format){
|
||||
|
||||
@@ -44,108 +44,112 @@
|
||||
#define NR_TST_PHY_PRINTF(...)
|
||||
#endif
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : set_tdd_configuration
|
||||
*
|
||||
* PARAMETERS : pointer to frame configuration
|
||||
*
|
||||
* OUTPUT: table of uplink symbol for each slot for 2 frames
|
||||
*
|
||||
* RETURN : nb_periods_per_frame if tdd has been properly configurated
|
||||
* -1 tdd configuration can not be done
|
||||
*
|
||||
* DESCRIPTION : generate bit map for uplink symbol for each slot for several frames
|
||||
* see TS 38.213 11.1 Slot configuration
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg,
|
||||
int mu,
|
||||
int nrofDownlinkSlots,
|
||||
int nrofDownlinkSymbols,
|
||||
int nrofUplinkSlots,
|
||||
int nrofUplinkSymbols)
|
||||
/** @brief This function processes TDD dedicated configuration for NR
|
||||
* by processing the tdd_slot_bitmap and period_cfg, and
|
||||
* allocates memory and fills max_num_of_symbol_per_slot_list
|
||||
* in the nfapi config request (cfg)
|
||||
* @ref see TS 38.213 11.1 Slot configuration
|
||||
* @param cfg NR config request structure pointer
|
||||
* @param fs TDD configuration pointer
|
||||
* @returns void
|
||||
*/
|
||||
void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs)
|
||||
{
|
||||
AssertFatal(fs != NULL, "frame_structure must be non-NULL");
|
||||
|
||||
int slot_number = 0;
|
||||
int nb_periods_per_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
|
||||
int nb_slots_to_set = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
int nb_slots_to_set = fs->numb_slots_frame;
|
||||
int slot_index = 0;
|
||||
tdd_period_config_t *pc = &fs->period_cfg;
|
||||
tdd_bitmap_t *tdd_slot_bitmap = pc->tdd_slot_bitmap;
|
||||
|
||||
int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame;
|
||||
|
||||
if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0)
|
||||
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots),
|
||||
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, "
|
||||
"nrofUplinkSlots %d, nb_slots_per_period %d \n",
|
||||
nrofDownlinkSlots,
|
||||
nrofUplinkSlots,
|
||||
nb_slots_per_period);
|
||||
else {
|
||||
AssertFatal(nrofDownlinkSymbols + nrofUplinkSymbols < 14,
|
||||
"illegal symbol configuration DL %d, UL %d\n",
|
||||
nrofDownlinkSymbols,
|
||||
nrofUplinkSymbols);
|
||||
AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots + 1),
|
||||
"set_tdd_configuration_nr: given period is inconsistent with current tdd configuration, nrofDownlinkSlots %d, "
|
||||
"nrofUplinkSlots %d, nrofMixed slots 1, nb_slots_per_period %d \n",
|
||||
nrofDownlinkSlots,
|
||||
nrofUplinkSlots,
|
||||
nb_slots_per_period);
|
||||
}
|
||||
|
||||
cfg->tdd_table.max_tdd_periodicity_list = calloc(nb_slots_to_set, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
LOG_I(NR_PHY,
|
||||
"Set TDD Period Configuration: %d periods per frame, %d slots to be configured (%d DL, %d UL)\n",
|
||||
fs->numb_period_frame,
|
||||
nb_slots_to_set,
|
||||
pc->num_dl_slots,
|
||||
pc->num_ul_slots);
|
||||
|
||||
// Allocate memory formax_num_of_symbol_per_slot_list items
|
||||
cfg->tdd_table.max_tdd_periodicity_list = calloc_or_fail(nb_slots_to_set, sizeof(nfapi_nr_max_tdd_periodicity_t));
|
||||
for (int slot = 0; slot < nb_slots_to_set; slot++) {
|
||||
nfapi_nr_max_tdd_periodicity_t *p_list = &cfg->tdd_table.max_tdd_periodicity_list[slot];
|
||||
p_list->max_num_of_symbol_per_slot_list =
|
||||
calloc(NR_NUMBER_OF_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
||||
calloc_or_fail(NR_NUMBER_OF_SYMBOLS_PER_SLOT, sizeof(*p_list->max_num_of_symbol_per_slot_list));
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
// for each symbol, assign the TLV tag for usage when packing
|
||||
p_list->max_num_of_symbol_per_slot_list[sym].slot_config.tl.tag = NFAPI_NR_CONFIG_SLOT_CONFIG_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all periods to be configured
|
||||
while (slot_number != nb_slots_to_set) {
|
||||
if (nrofDownlinkSlots != 0) {
|
||||
for (int sym = 0; sym < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number]
|
||||
.max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT]
|
||||
.slot_config.value = 0;
|
||||
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
|
||||
slot_index = get_slot_idx_in_period(slot_number, fs);
|
||||
/* Fill max_tdd_periodicity_list */
|
||||
nfapi_nr_max_tdd_periodicity_t *list = &cfg->tdd_table.max_tdd_periodicity_list[slot_number];
|
||||
// FULL DOWNLINK SLOTS
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_DOWNLINK_SLOT) {
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 0;
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||
slot_number++;
|
||||
list += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
|
||||
for (int sym = 0; sym < nrofDownlinkSymbols; sym++) {
|
||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 0;
|
||||
// FLEXIBLE SLOTS
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_MIXED_SLOT) {
|
||||
int nrofDLSymbolsInSlot = tdd_slot_bitmap[slot_index].num_dl_symbols;
|
||||
int nrofULSymbolsInSlot = tdd_slot_bitmap[slot_index].num_ul_symbols;
|
||||
AssertFatal(nrofDLSymbolsInSlot + nrofULSymbolsInSlot < NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
"illegal symbol configuration DL %d, UL %d\n",
|
||||
nrofDLSymbolsInSlot,
|
||||
nrofULSymbolsInSlot);
|
||||
// DL Symbols
|
||||
for (int sym = 0; sym < nrofDLSymbolsInSlot; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 0;
|
||||
}
|
||||
|
||||
for (int sym = nrofDownlinkSymbols; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; sym++) {
|
||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 2;
|
||||
// Flexible Symbols
|
||||
for (int sym = nrofDLSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 2;
|
||||
}
|
||||
|
||||
for (int sym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[sym].slot_config.value = 1;
|
||||
// UL Symbols
|
||||
for (int sym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofULSymbolsInSlot; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym].slot_config.value = 1;
|
||||
}
|
||||
|
||||
slot_number++;
|
||||
list += 1;
|
||||
}
|
||||
|
||||
if (nrofUplinkSlots != 0) {
|
||||
for (int sym = 0; sym < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
cfg->tdd_table.max_tdd_periodicity_list[slot_number]
|
||||
.max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT]
|
||||
.slot_config.value = 1;
|
||||
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
|
||||
// FULL UPLINK SLOTS
|
||||
if (tdd_slot_bitmap[slot_index].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||
for (int sym = 0; sym < NR_NUMBER_OF_SYMBOLS_PER_SLOT; sym++) {
|
||||
list->max_num_of_symbol_per_slot_list[sym % NR_NUMBER_OF_SYMBOLS_PER_SLOT].slot_config.value = 1;
|
||||
if ((sym + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0) {
|
||||
slot_number++;
|
||||
list += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (nb_periods_per_frame);
|
||||
// Dump 1 period on the output
|
||||
for (int s = 0; s < fs->numb_slots_period; s++) {
|
||||
if (tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT) {
|
||||
char flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT + 1];
|
||||
memset(flexi_slot, 0, sizeof(flexi_slot));
|
||||
for (int symb = 0; symb < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symb++) {
|
||||
uint8_t val = cfg->tdd_table.max_tdd_periodicity_list[s].max_num_of_symbol_per_slot_list[symb].slot_config.value;
|
||||
char *symb_type_s[] = {"D", "U", "F"};
|
||||
flexi_slot[symb] = *symb_type_s[val];
|
||||
}
|
||||
flexi_slot[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = '\0';
|
||||
LOG_I(NR_PHY, "TDD period configuration: slot %d is FLEXIBLE: %s\n", s, flexi_slot);
|
||||
} else {
|
||||
LOG_I(NR_PHY,
|
||||
"TDD period configuration: slot %d is %s\n",
|
||||
s,
|
||||
tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT ? "DOWNLINK" : "UPLINK");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -389,3 +393,48 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) {
|
||||
}
|
||||
}
|
||||
|
||||
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
|
||||
{
|
||||
frame_structure_t fs = {.is_tdd = true};
|
||||
fs.numb_slots_frame = (1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
fs.numb_period_frame = get_nb_periods_per_frame(gNB->gNB_config.tdd_table.tdd_period.value);
|
||||
fs.numb_slots_period = fs.numb_slots_frame / fs.numb_period_frame;
|
||||
tdd_period_config_t *pc = &fs.period_cfg;
|
||||
// Set DL/UL slots
|
||||
switch (mu)
|
||||
{
|
||||
case 0:
|
||||
pc->num_dl_slots = 3;
|
||||
pc->num_ul_slots = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pc->num_dl_slots = 7;
|
||||
pc->num_ul_slots = 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
pc->num_dl_slots = 27;
|
||||
pc->num_ul_slots = 12;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < pc->num_dl_slots; i++) {
|
||||
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_DOWNLINK_SLOT;
|
||||
pc->tdd_slot_bitmap[i].num_dl_symbols = 0;
|
||||
pc->tdd_slot_bitmap[i].num_ul_symbols = 0;
|
||||
}
|
||||
for (int i = pc->num_dl_slots; i < fs.numb_slots_period - pc->num_ul_slots; i++) {
|
||||
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_MIXED_SLOT;
|
||||
pc->tdd_slot_bitmap[i].num_dl_symbols = 6;
|
||||
pc->tdd_slot_bitmap[i].num_ul_symbols = 4;
|
||||
}
|
||||
for (int i = pc->num_ul_slots; i < fs.numb_slots_period; i++) {
|
||||
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_UPLINK_SLOT;
|
||||
pc->tdd_slot_bitmap[i].num_dl_symbols = 0;
|
||||
pc->tdd_slot_bitmap[i].num_ul_symbols = 0;
|
||||
}
|
||||
set_tdd_config_nr(&gNB->gNB_config, &fs);
|
||||
}
|
||||
|
||||
@@ -36,18 +36,16 @@
|
||||
|
||||
/*************** FUNCTIONS *****************************************/
|
||||
|
||||
/** \brief This function processes tdd dedicated configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
* @param dl_UL_TransmissionPeriodicity periodicity
|
||||
* @param nrofDownlinkSlots number of downlink slots
|
||||
* @param nrofDownlinkSymbols number of downlink symbols
|
||||
* @param nrofUplinkSlots number of uplink slots
|
||||
* @param nrofUplinkSymbols number of uplink symbols
|
||||
@returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */
|
||||
|
||||
int set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, int mu,
|
||||
int nrofDownlinkSlots, int nrofDownlinkSymbols,
|
||||
int nrofUplinkSlots, int nrofUplinkSymbols);
|
||||
/** @brief This function processes TDD dedicated configuration for NR
|
||||
* by processing the tdd_slot_bitmap and period_cfg, and
|
||||
* allocates memory and fills max_num_of_symbol_per_slot_list
|
||||
* in the nfapi config request (cfg)
|
||||
* @param cfg NR config request structure pointer
|
||||
* @param fs frame structure pointer
|
||||
* @returns nb_periods_per_frame if TDD has been properly configurated
|
||||
* -1 tdd configuration can not be done
|
||||
*/
|
||||
void set_tdd_config_nr(nfapi_nr_config_request_scf_t *cfg, frame_structure_t *fs);
|
||||
|
||||
/** \brief This function adds a slot configuration to current dedicated configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
@@ -92,5 +90,7 @@ void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
int get_next_downlink_slot(PHY_VARS_gNB *gNB, nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot);
|
||||
|
||||
void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu);
|
||||
|
||||
#endif /* PHY_FRAME_CONFIG_NR_H */
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "assertions.h"
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
|
||||
//#define DEBUG_RXDATA
|
||||
//#define SRS_IND_DEBUG
|
||||
@@ -438,6 +439,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo
|
||||
ulsch_harq->ulsch_pdu.rb_size,
|
||||
ulsch_harq->TBS);
|
||||
nr_fill_indication(gNB, ulsch->frame, ulsch->slot, ULSCH_id, ulsch->harq_pid, 1, 0, crc, pdu);
|
||||
gNBdumpScopeData(gNB, ulsch->slot, ulsch->frame, "ULSCH_NACK");
|
||||
ulsch->handled = 1;
|
||||
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
|
||||
ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations + 1; // Setting to max_ldpc_iterations + 1 is sufficient given that this variable is only used for checking for failure
|
||||
@@ -647,8 +649,9 @@ int fill_srs_channel_matrix(uint8_t *channel_matrix,
|
||||
const uint16_t prg_size,
|
||||
const uint16_t num_prgs,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)]) {
|
||||
|
||||
const c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports]
|
||||
[frame_parms->ofdm_symbol_size * (1 << srs_pdu->num_symbols)])
|
||||
{
|
||||
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
|
||||
const uint16_t step = prg_size*NR_NB_SC_PER_RB;
|
||||
|
||||
@@ -664,8 +667,7 @@ int fill_srs_channel_matrix(uint8_t *channel_matrix,
|
||||
}
|
||||
|
||||
for(int pI = 0; pI < num_prgs; pI++) {
|
||||
|
||||
c16_t *srs_estimated_channel16 = (c16_t *)&srs_estimated_channel_freq[gI][uI][subcarrier];
|
||||
const c16_t *srs_estimated_channel16 = srs_estimated_channel_freq[gI][uI] + subcarrier;
|
||||
uint16_t index = uI*num_gnb_antenna_elements*num_prgs + gI*num_prgs + pI;
|
||||
|
||||
if (normalized_iq_representation == 0) {
|
||||
@@ -868,6 +870,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
nfapi_nr_rx_data_pdu_t *pdu = &UL_INFO->rx_ind.pdu_list[UL_INFO->rx_ind.number_of_pdus++];
|
||||
nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid, 1, 1, crc, pdu);
|
||||
pusch_DTX++;
|
||||
gNBdumpScopeData(gNB, ulsch->slot, ulsch->frame, "ULSCH_DTX");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@@ -918,10 +921,13 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
|
||||
uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols;
|
||||
int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size * N_symb_SRS];
|
||||
int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
|
||||
int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size];
|
||||
c16_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size * N_symb_SRS];
|
||||
c16_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports]
|
||||
[frame_parms->ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
|
||||
c16_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size]
|
||||
__attribute__((aligned(32)));
|
||||
c16_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports]
|
||||
[frame_parms->ofdm_symbol_size];
|
||||
int8_t snr_per_rb[srs_pdu->bwp_size];
|
||||
|
||||
start_meas(&gNB->generate_srs_stats);
|
||||
|
||||
@@ -41,8 +41,7 @@
|
||||
#include "utils.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "SCHED_NR_UE/phy_sch_processing_time.h"
|
||||
|
||||
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
|
||||
#include "openair1/PHY/phy_extern_nr_ue.h"
|
||||
|
||||
const char *const dl_pdu_type[] = {"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM", "TA"};
|
||||
const char *const ul_pdu_type[] = {"PRACH", "PUCCH", "PUSCH", "SRS"};
|
||||
|
||||
@@ -388,8 +388,9 @@ int main(int argc, char **argv)
|
||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
crcTableInit();
|
||||
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
// TDD configuration
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
do_tdd_config_sim(gNB, mu);
|
||||
phy_init_nr_gNB(gNB);
|
||||
//init_eNB_afterRU();
|
||||
frame_length_complex_samples = frame_parms->samples_per_subframe;
|
||||
@@ -620,39 +621,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/
|
||||
|
||||
//TODO: loop over slots
|
||||
/*for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
|
||||
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||
txdata[aa],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
|
||||
txdata[aa],
|
||||
14,
|
||||
frame_parms);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);
|
||||
|
||||
|
||||
for (i=0; i<frame_length_complex_samples; i++) {
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
|
||||
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
|
||||
}
|
||||
}*/
|
||||
|
||||
free_channel_desc_scm(gNB2UE);
|
||||
|
||||
reset_DLSCH_struct(gNB, &msgDataTx);
|
||||
|
||||
@@ -189,7 +189,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
/* the following might override the table that is mandated by RRC
|
||||
* configuration */
|
||||
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], scc, slot);
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot);
|
||||
AssertFatal(sched_pdsch->time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
sched_pdsch->tda_info = get_dl_tda_info(current_BWP,
|
||||
|
||||
@@ -448,13 +448,10 @@ int main(int argc, char **argv)
|
||||
frame_parms->freq_range = mu<2 ? FR1 : FR2;
|
||||
|
||||
nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions);
|
||||
// TDD configuration
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
if (mu == 0)
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 3, 6, 1, 4);
|
||||
else if (mu == 1)
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
else if (mu == 3)
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 27, 6, 12, 4);
|
||||
do_tdd_config_sim(gNB, mu);
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
|
||||
initFloatingCoresTpool(ssb_scan_threads, &nrUE_params.Tpool, false, "UE-tpool");
|
||||
|
||||
@@ -568,7 +568,10 @@ int main(int argc, char **argv){
|
||||
|
||||
memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
|
||||
RC.nb_nr_L1_inst=1;
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
// TDD configuration
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
do_tdd_config_sim(gNB, mu);
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
nr_phy_init_RU(ru);
|
||||
|
||||
@@ -678,16 +681,16 @@ int main(int argc, char **argv){
|
||||
for (i = 0; i < frame_parms->samples_per_subframe; i++) {
|
||||
for (aa=0; aa<1; aa++) {
|
||||
if (awgn_flag == 0) {
|
||||
s_re[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
|
||||
s_im[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
|
||||
s_re[aa][i] = txdata[aa][prach_start + i].r;
|
||||
s_im[aa][i] = txdata[aa][prach_start + i].i;
|
||||
} else {
|
||||
for (aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
|
||||
if (aa==0) {
|
||||
r_re[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
|
||||
r_im[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
|
||||
r_re[aa][i] = txdata[aa][prach_start + i].r;
|
||||
r_im[aa][i] = txdata[aa][prach_start + i].i;
|
||||
} else {
|
||||
r_re[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]);
|
||||
r_im[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]);
|
||||
r_re[aa][i] += txdata[aa][prach_start + i].r;
|
||||
r_im[aa][i] += txdata[aa][prach_start + i].i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,15 +260,8 @@ static int freq_domain_loopback(PHY_VARS_NR_UE *UE_tx, PHY_VARS_NR_UE *UE_rx, in
|
||||
nr_tx_psbch(UE_tx, frame, slot, &phy_data->psbch_vars, txdataF);
|
||||
|
||||
int estimateSz = sl_ue2->sl_frame_params.samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) struct complex16 rxdataF[1][estimateSz];
|
||||
for (int i = 0; i < sl_ue1->sl_frame_params.samples_per_slot_wCP; i++) {
|
||||
struct complex16 *txdataF_ptr = (struct complex16 *)&txdataF[0][i];
|
||||
struct complex16 *rxdataF_ptr = (struct complex16 *)&rxdataF[0][i];
|
||||
rxdataF_ptr->r = txdataF_ptr->r;
|
||||
rxdataF_ptr->i = txdataF_ptr->i;
|
||||
// printf("r,i TXDATAF[%d]- %d:%d, RXDATAF[%d]- %d:%d\n",
|
||||
// i, txdataF_ptr->r, txdataF_ptr->i, i, txdataF_ptr->r, txdataF_ptr->i);
|
||||
}
|
||||
__attribute__((aligned(32))) c16_t rxdataF[1][estimateSz];
|
||||
memcpy(rxdataF[0], txdataF[0], sl_ue1->sl_frame_params.samples_per_slot_wCP * sizeof(**rxdataF));
|
||||
|
||||
uint8_t err_status = 0;
|
||||
|
||||
|
||||
@@ -433,8 +433,10 @@ int main(int argc, char **argv)
|
||||
cfg->carrier_config.num_tx_ant.value = n_tx;
|
||||
cfg->carrier_config.num_rx_ant.value = n_rx;
|
||||
nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
|
||||
// TDD configuration
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
do_tdd_config_sim(gNB, mu);
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
/* RU handles rxdataF, and gNB just has a pointer. Here, we don't have an RU,
|
||||
* so we need to allocate that memory as well. */
|
||||
|
||||
@@ -406,8 +406,10 @@ int main(int argc, char **argv)
|
||||
gNB->frame_parms.nb_antennas_rx = n_rx;
|
||||
|
||||
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
|
||||
// TDD configuration
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
|
||||
do_tdd_config_sim(gNB, mu);
|
||||
|
||||
phy_init_nr_gNB(gNB);
|
||||
|
||||
//configure UE
|
||||
|
||||
@@ -166,7 +166,7 @@ typedef struct as_stmsi_s {
|
||||
/* Dedicated NAS information */
|
||||
typedef struct as_nas_info_s {
|
||||
uint32_t length; /* Length of the NAS information data */
|
||||
Byte_t* nas_data; /* Dedicated NAS information data container */
|
||||
uint8_t* nas_data; /* Dedicated NAS information data container */
|
||||
} as_nas_info_t;
|
||||
|
||||
/* Radio Access Bearer identity */
|
||||
@@ -215,7 +215,7 @@ typedef struct broadcast_info_ind_s {
|
||||
* NAS request AS to refresh its KeNB key
|
||||
*/
|
||||
typedef struct kenb_refresh_req_s {
|
||||
Byte_t kenb[32];
|
||||
uint8_t kenb[32];
|
||||
} kenb_refresh_req_t;
|
||||
|
||||
typedef struct nsa_oai_tun_nsa_s {
|
||||
@@ -229,7 +229,7 @@ typedef struct nsa_oai_tun_nsa_s {
|
||||
*/
|
||||
typedef struct cell_info_req_s {
|
||||
plmn_t plmnID; /* Selected PLMN identity */
|
||||
Byte_t rat; /* Bitmap - set of radio access technologies */
|
||||
uint8_t rat; /* Bitmap - set of radio access technologies */
|
||||
} cell_info_req_t;
|
||||
|
||||
/*
|
||||
|
||||
+44
-33
@@ -43,7 +43,6 @@ Description Contains global common definitions
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "common/platform_constants.h"
|
||||
typedef uint8_t Byte_t; /* 8 bit unsigned integer */
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
@@ -62,30 +61,30 @@ typedef uint8_t AcT_t; /* Access Technology */
|
||||
* International Mobile Subscriber Identity
|
||||
*/
|
||||
typedef struct {
|
||||
Byte_t length;
|
||||
uint8_t length;
|
||||
union {
|
||||
struct {
|
||||
Byte_t digit2:4;
|
||||
Byte_t digit1:4;
|
||||
Byte_t digit4:4;
|
||||
Byte_t digit3:4;
|
||||
Byte_t digit6:4;
|
||||
Byte_t digit5:4;
|
||||
Byte_t digit8:4;
|
||||
Byte_t digit7:4;
|
||||
Byte_t digit10:4;
|
||||
Byte_t digit9:4;
|
||||
Byte_t digit12:4;
|
||||
Byte_t digit11:4;
|
||||
Byte_t digit14:4;
|
||||
Byte_t digit13:4;
|
||||
uint8_t digit2: 4;
|
||||
uint8_t digit1: 4;
|
||||
uint8_t digit4: 4;
|
||||
uint8_t digit3: 4;
|
||||
uint8_t digit6: 4;
|
||||
uint8_t digit5: 4;
|
||||
uint8_t digit8: 4;
|
||||
uint8_t digit7: 4;
|
||||
uint8_t digit10: 4;
|
||||
uint8_t digit9: 4;
|
||||
uint8_t digit12: 4;
|
||||
uint8_t digit11: 4;
|
||||
uint8_t digit14: 4;
|
||||
uint8_t digit13: 4;
|
||||
#define EVEN_PARITY 0
|
||||
#define ODD_PARITY 1
|
||||
Byte_t parity:4;
|
||||
Byte_t digit15:4;
|
||||
uint8_t parity: 4;
|
||||
uint8_t digit15: 4;
|
||||
} num;
|
||||
#define IMSI_SIZE 8
|
||||
Byte_t value[IMSI_SIZE];
|
||||
uint8_t value[IMSI_SIZE];
|
||||
} u;
|
||||
} imsi_t;
|
||||
|
||||
@@ -119,7 +118,7 @@ typedef struct {
|
||||
* Mobile subscriber dialing number
|
||||
*/
|
||||
typedef struct {
|
||||
Byte_t ext:1;
|
||||
uint8_t ext: 1;
|
||||
/* Type Of Number */
|
||||
#define MSISDN_TON_UNKNOWKN 0b000
|
||||
#define MSISDN_TON_INTERNATIONAL 0b001
|
||||
@@ -128,7 +127,7 @@ typedef struct {
|
||||
#define MSISDN_TON_SUBCRIBER 0b100
|
||||
#define MSISDN_TON_ABBREVIATED 0b110
|
||||
#define MSISDN_TON_RESERVED 0b111
|
||||
Byte_t ton:3;
|
||||
uint8_t ton: 3;
|
||||
/* Numbering Plan Identification */
|
||||
#define MSISDN_NPI_UNKNOWN 0b0000
|
||||
#define MSISDN_NPI_ISDN_TELEPHONY 0b0001
|
||||
@@ -140,11 +139,11 @@ typedef struct {
|
||||
#define MSISDN_NPI_ISDN_MOBILE 0b0111
|
||||
#define MSISDN_NPI_PRIVATE 0b1110
|
||||
#define MSISDN_NPI_RESERVED 0b1111
|
||||
Byte_t npi:4;
|
||||
uint8_t npi: 4;
|
||||
/* Dialing Number */
|
||||
struct {
|
||||
Byte_t lsb:4;
|
||||
Byte_t msb:4;
|
||||
uint8_t lsb: 4;
|
||||
uint8_t msb: 4;
|
||||
#define MSISDN_DIGIT_SIZE 10
|
||||
} digit[MSISDN_DIGIT_SIZE];
|
||||
} msisdn_t;
|
||||
@@ -159,12 +158,12 @@ typedef imsi_t imei_t;
|
||||
* PLMN = BCD encoding (Mobile Country Code + Mobile Network Code)
|
||||
*/
|
||||
typedef struct {
|
||||
Byte_t MCCdigit2:4;
|
||||
Byte_t MCCdigit1:4;
|
||||
Byte_t MNCdigit3:4;
|
||||
Byte_t MCCdigit3:4;
|
||||
Byte_t MNCdigit2:4;
|
||||
Byte_t MNCdigit1:4;
|
||||
uint8_t MCCdigit2: 4;
|
||||
uint8_t MCCdigit1: 4;
|
||||
uint8_t MNCdigit3: 4;
|
||||
uint8_t MCCdigit3: 4;
|
||||
uint8_t MNCdigit2: 4;
|
||||
uint8_t MNCdigit1: 4;
|
||||
} plmn_t;
|
||||
|
||||
/*
|
||||
@@ -256,17 +255,29 @@ typedef struct {
|
||||
/*
|
||||
* A list of PLMNs
|
||||
*/
|
||||
#define PLMN_LIST_T(SIZE) struct {Byte_t n_plmns; plmn_t plmn[SIZE];}
|
||||
#define PLMN_LIST_T(SIZE) \
|
||||
struct { \
|
||||
uint8_t n_plmns; \
|
||||
plmn_t plmn[SIZE]; \
|
||||
}
|
||||
|
||||
/*
|
||||
* A list of TACs
|
||||
*/
|
||||
#define TAC_LIST_T(SIZE) struct {Byte_t n_tacs; TAC_t tac[SIZE];}
|
||||
#define TAC_LIST_T(SIZE) \
|
||||
struct { \
|
||||
uint8_t n_tacs; \
|
||||
TAC_t tac[SIZE]; \
|
||||
}
|
||||
|
||||
/*
|
||||
* A list of TAIs
|
||||
*/
|
||||
#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];}
|
||||
#define TAI_LIST_T(SIZE) \
|
||||
struct { \
|
||||
uint8_t n_tais; \
|
||||
tai_t tai[SIZE]; \
|
||||
}
|
||||
|
||||
typedef enum eps_protocol_discriminator_e {
|
||||
/* Protocol discriminator identifier for EPS Mobility Management */
|
||||
|
||||
@@ -60,11 +60,11 @@ bool read_mac_sm(void* data)
|
||||
rd->dl_aggr_tbs = UE->mac_stats.dl.total_bytes;
|
||||
rd->ul_aggr_tbs = UE->mac_stats.ul.total_bytes;
|
||||
|
||||
if (is_xlsch_in_slot(RC.nrmac[mod_id]->dlsch_slot_bitmap[rd->slot / 64], rd->slot)) {
|
||||
if (is_dl_slot(rd->slot, &RC.nrmac[mod_id]->frame_structure)) {
|
||||
rd->dl_curr_tbs = UE->mac_stats.dl.current_bytes;
|
||||
rd->dl_sched_rb = UE->mac_stats.dl.current_rbs;
|
||||
}
|
||||
if (is_xlsch_in_slot(RC.nrmac[mod_id]->ulsch_slot_bitmap[rd->slot / 64], rd->slot)) {
|
||||
if (is_ul_slot(rd->slot, &RC.nrmac[mod_id]->frame_structure)) {
|
||||
rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes;
|
||||
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
|
||||
}
|
||||
|
||||
@@ -59,11 +59,6 @@
|
||||
#include "executables/thread-common.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
|
||||
extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw);
|
||||
extern char *parallel_config;
|
||||
extern char *worker_config;
|
||||
|
||||
RAN_CONTEXT_t RC;
|
||||
|
||||
void RCconfig_L1(void) {
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS "nrofDownlinkSymbols"
|
||||
#define GNB_CONFIG_STRING_NROFUPLINKSLOTS "nrofUplinkSlots"
|
||||
#define GNB_CONFIG_STRING_NROFUPLINKSYMBOLS "nrofUplinkSymbols"
|
||||
#define GNB_CONFIG_STRING_PATTERN2 "pattern2"
|
||||
#define GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2 "dl_UL_TransmissionPeriodicity2"
|
||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2 "nrofDownlinkSlots2"
|
||||
#define GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2 "nrofDownlinkSymbols2"
|
||||
@@ -247,11 +248,6 @@
|
||||
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,.defint64val=6,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSLOTS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,.defint64val=2,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols,.defint64val=4,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity,.defintval=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSymbols,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,.i64ptr=&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,.i64ptr=&scc->ss_PBCH_BlockPower,.defint64val=20,TYPE_INT64,0}, \
|
||||
{GNB_CONFIG_STRING_CELLSPECIFICKOFFSET,NULL,0,.i64ptr=scc->ext2->ntn_Config_r17->cellSpecificKoffset_r17,.defint64val=0,TYPE_INT64,0}, \
|
||||
{GNB_CONFIG_STRING_EPHEMERIS_POSITION_X,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17,.defint64val=LONG_MAX,TYPE_INT64,0}, \
|
||||
@@ -263,6 +259,15 @@
|
||||
{GNB_CONFIG_STRING_TA_COMMON,NULL,0,.i64ptr=&scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17,.defint64val=-1,TYPE_INT64,0}, \
|
||||
{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,.i64ptr=scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,.defintval=-1,TYPE_INT64,0}}
|
||||
|
||||
#define SCC_PATTERN2_STRING_CONFIG "pattern2"
|
||||
|
||||
#define SCC_PATTERN2_PARAMS_DESC(pattern2) { \
|
||||
{GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY2, NULL,0,.i64ptr=&pattern2.dl_UL_TransmissionPeriodicity,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFDOWNLINKSLOTS2, NULL,0,.i64ptr=&pattern2.nrofDownlinkSlots,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFDOWNLINKSYMBOLS2, NULL,0,.i64ptr=&pattern2.nrofDownlinkSymbols,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL, 0,.i64ptr=&pattern2.nrofUplinkSlots,.defint64val=-1,TYPE_INT64,0},\
|
||||
{GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL, 0,.i64ptr=&pattern2.nrofUplinkSymbols,.defint64val=-1,TYPE_INT64,0}}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* Serving Cell Config Dedicated configuration parameters */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -113,7 +113,10 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
|
||||
scc->ssb_periodicityServingCell = calloc_or_fail(1, sizeof(*scc->ssb_periodicityServingCell));
|
||||
scc->ssbSubcarrierSpacing = calloc_or_fail(1, sizeof(*scc->ssbSubcarrierSpacing));
|
||||
scc->tdd_UL_DL_ConfigurationCommon = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon));
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern2 = calloc_or_fail(1, sizeof(*scc->tdd_UL_DL_ConfigurationCommon->pattern2));
|
||||
struct NR_TDD_UL_DL_ConfigCommon *tdd = scc->tdd_UL_DL_ConfigurationCommon;
|
||||
tdd->pattern1.ext1 = calloc_or_fail(1, sizeof(*tdd->pattern1.ext1));
|
||||
tdd->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 =
|
||||
calloc_or_fail(1, sizeof(*tdd->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530));
|
||||
scc->downlinkConfigCommon = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon));
|
||||
scc->downlinkConfigCommon->frequencyInfoDL = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->frequencyInfoDL));
|
||||
scc->downlinkConfigCommon->initialDownlinkBWP = calloc_or_fail(1, sizeof(*scc->downlinkConfigCommon->initialDownlinkBWP));
|
||||
@@ -357,15 +360,52 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N
|
||||
p1->nrofUplinkSymbols = 4;
|
||||
|
||||
struct NR_TDD_UL_DL_Pattern *p2 = tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||
p2->dl_UL_TransmissionPeriodicity = 321;
|
||||
p2->nrofDownlinkSlots = -1;
|
||||
p2->nrofDownlinkSymbols = -1;
|
||||
p2->nrofUplinkSlots = -1;
|
||||
p2->nrofUplinkSymbols = -1;
|
||||
if (p2) {
|
||||
p2->dl_UL_TransmissionPeriodicity = 321;
|
||||
p2->nrofDownlinkSlots = -1;
|
||||
p2->nrofDownlinkSymbols = -1;
|
||||
p2->nrofUplinkSlots = -1;
|
||||
p2->nrofUplinkSymbols = -1;
|
||||
}
|
||||
|
||||
scc->ss_PBCH_BlockPower = 20;
|
||||
}
|
||||
|
||||
static void fix_tdd_pattern(NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
NR_TDD_UL_DL_Pattern_t *pattern1 = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
int pattern_ext = pattern1->dl_UL_TransmissionPeriodicity - 8;
|
||||
// Check if the pattern1 extension is configured and set the value accordingly
|
||||
if (pattern_ext >= 0) {
|
||||
pattern1->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1));
|
||||
pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 =
|
||||
calloc_or_fail(1, sizeof(*pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530));
|
||||
*pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 = pattern_ext;
|
||||
pattern1->dl_UL_TransmissionPeriodicity = 5;
|
||||
} else {
|
||||
pattern1->ext1 = NULL;
|
||||
}
|
||||
struct NR_TDD_UL_DL_Pattern *pattern2 = scc->tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||
if (pattern2 != NULL) {
|
||||
/* The pattern2 is not configured free the memory these shall not be encoded with default values in SIB1 */
|
||||
if (pattern2->dl_UL_TransmissionPeriodicity == -1) {
|
||||
free(pattern2);
|
||||
pattern2 = NULL;
|
||||
} else {
|
||||
// Check if the pattern2 extension is configured and set the value accordingly
|
||||
pattern_ext = pattern2->dl_UL_TransmissionPeriodicity - 8;
|
||||
if (pattern_ext >= 0) {
|
||||
pattern2->ext1 = calloc_or_fail(1, sizeof(*pattern2->ext1));
|
||||
pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 =
|
||||
CALLOC(1, sizeof(*pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530));
|
||||
*pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 = pattern_ext;
|
||||
pattern2->dl_UL_TransmissionPeriodicity = 5;
|
||||
} else {
|
||||
pattern2->ext1 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
|
||||
{
|
||||
@@ -436,11 +476,7 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap)
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon);
|
||||
scc->tdd_UL_DL_ConfigurationCommon = NULL;
|
||||
} else { // TDD
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity > 320 ) {
|
||||
free(scc->tdd_UL_DL_ConfigurationCommon->pattern2);
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern2 = NULL;
|
||||
}
|
||||
|
||||
fix_tdd_pattern(scc);
|
||||
}
|
||||
|
||||
if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) {
|
||||
@@ -982,6 +1018,16 @@ void RCconfig_NR_L1(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true when pattern2 is filled in
|
||||
*/
|
||||
bool is_pattern2_config(paramdef_t *param)
|
||||
{
|
||||
if (param == NULL || param->i64ptr == NULL || *(param->i64ptr) == -1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME)
|
||||
{
|
||||
NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc));
|
||||
@@ -1002,6 +1048,33 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf
|
||||
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0);
|
||||
config_get(cfg, SCCsParams, sizeofArray(SCCsParams), aprefix);
|
||||
config_get(cfg, MsgASCCsParams, sizeofArray(MsgASCCsParams), aprefix);
|
||||
// NR_TDD-UL-DL-ConfigCommon pattern2 (optional IE)
|
||||
// fetch params
|
||||
struct NR_TDD_UL_DL_Pattern p2;
|
||||
paramdef_t pattern2Params[] = SCC_PATTERN2_PARAMS_DESC(p2);
|
||||
char aprefix[MAX_OPTNAME_SIZE * 2 + 8];
|
||||
sprintf(aprefix, "%s.[%i].%s.[%i].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0, SCC_PATTERN2_STRING_CONFIG);
|
||||
config_get(config_get_if(), pattern2Params, sizeofArray(pattern2Params), aprefix);
|
||||
// check validity
|
||||
bool is_pattern2 = false;
|
||||
for (int i = 0; i < sizeofArray(pattern2Params); i++) {
|
||||
is_pattern2 |= is_pattern2_config(pattern2Params);
|
||||
}
|
||||
|
||||
if (is_pattern2) {
|
||||
LOG_I(GNB_APP, "tdd->pattern2 present\n");
|
||||
// allocate memory
|
||||
struct NR_TDD_UL_DL_ConfigCommon *tdd = scc->tdd_UL_DL_ConfigurationCommon;
|
||||
tdd->pattern2 = calloc_or_fail(1, sizeof(*tdd->pattern2));
|
||||
tdd->pattern2->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1));
|
||||
tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 = calloc_or_fail(1, sizeof(*tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530));
|
||||
// fill in scc
|
||||
*scc->tdd_UL_DL_ConfigurationCommon->pattern2 = p2;
|
||||
AssertFatal(p2.nrofUplinkSlots ^ scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
|
||||
"UL slots in pattern1 (%ld) and pattern2 (%ld) are mutually exclusive (e.g. DDDFUU DDDD, DDDD DDDFUU)\n",
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
|
||||
p2.nrofUplinkSlots);
|
||||
}
|
||||
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||
LOG_I(RRC,
|
||||
"Read in ServingCellConfigCommon (PhysCellId %d, ABSFREQSSB %d, DLBand %d, ABSFREQPOINTA %d, DLBW "
|
||||
|
||||
@@ -1235,10 +1235,12 @@ void eNB_Config_Local_DRX(instance_t module_idP, rrc_mac_drx_config_req_t *rrc_m
|
||||
|
||||
/* from here: prototypes to get rid of compilation warnings: doc to be written by function author */
|
||||
uint8_t ul_subframe2_k_phich(COMMON_channels_t *cc, sub_frame_t ul_subframe);
|
||||
#endif
|
||||
/** @}*/
|
||||
|
||||
/* MAC ITTI messaging related functions */
|
||||
/* Main loop of MAC itti message handling */
|
||||
void *mac_enb_task(void *arg);
|
||||
|
||||
uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw);
|
||||
uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw);
|
||||
#endif
|
||||
|
||||
@@ -60,8 +60,6 @@
|
||||
// #define DEBUG_MIB
|
||||
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||
// #define DEBUG_RAR
|
||||
extern uint32_t N_RB_DL;
|
||||
|
||||
/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
|
||||
static const int sequence_cyclic_shift_1_harq_ack_bit[2]
|
||||
/* HARQ-ACK Value 0 1 */
|
||||
|
||||
@@ -62,10 +62,6 @@
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
//extern int l2_init_gNB(void);
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
c16_t convert_precoder_weight(double complex c_in)
|
||||
{
|
||||
double cr = creal(c_in) * 32768 + 0.5;
|
||||
@@ -283,6 +279,257 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
|
||||
return mat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the TDD period, including bitmap, in the frame structure
|
||||
*
|
||||
* This function sets the TDD period configuration for DL, UL, and mixed slots in
|
||||
* the specified frame structure instance, according to the given pattern, and
|
||||
* updates the bitmap.
|
||||
*
|
||||
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
|
||||
* @param fs frame_structure_t pointer
|
||||
* @param curr_total_slot current position in the slot bitmap to start from
|
||||
*
|
||||
* @return Number of slots in the configured TDD period
|
||||
*/
|
||||
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
|
||||
{
|
||||
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
|
||||
int8_t n_ul_slot = pattern->nrofUplinkSlots;
|
||||
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
|
||||
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
|
||||
|
||||
// Total slots in the period: if DL/UL symbols are present, is mixed slot
|
||||
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
|
||||
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
|
||||
|
||||
/** Update TDD period configuration:
|
||||
* mixed slots with DL symbols are counted as DL slots
|
||||
* mixed slots with UL symbols are counted as UL slots */
|
||||
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
|
||||
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
|
||||
|
||||
// Populate the slot bitmap for each slot in the TDD period
|
||||
for (int i = 0; i < total_slot; i++) {
|
||||
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
|
||||
if (i < n_dl_slot)
|
||||
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
|
||||
else if ((i == n_dl_slot) && has_mixed_slot) {
|
||||
bitmap->slot_type = TDD_NR_MIXED_SLOT;
|
||||
bitmap->num_dl_symbols = n_dl_symbols;
|
||||
bitmap->num_ul_symbols = n_ul_symbols;
|
||||
} else if (n_ul_slot)
|
||||
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
|
||||
}
|
||||
|
||||
LOG_I(NR_MAC,
|
||||
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
|
||||
"UL slots, %d DL symbols, %d UL symbols)\n",
|
||||
pc->num_dl_slots,
|
||||
pc->num_ul_slots,
|
||||
total_slot,
|
||||
n_dl_slot,
|
||||
n_ul_slot,
|
||||
n_dl_symbols,
|
||||
n_ul_symbols);
|
||||
|
||||
return total_slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures TDD patterns (1 or 2) in the frame structure
|
||||
*
|
||||
* This function sets up the TDD configuration in the frame structure by applying
|
||||
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
|
||||
* It handles both TDD pattern1 and pattern2.
|
||||
*
|
||||
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
|
||||
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
|
||||
{
|
||||
int num_of_patterns = 1;
|
||||
uint8_t nb_slots_p2 = 0;
|
||||
// Reset num dl/ul slots
|
||||
tdd_period_config_t *pc = &fs->period_cfg;
|
||||
pc->num_dl_slots = 0;
|
||||
pc->num_ul_slots = 0;
|
||||
// Pattern1
|
||||
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
|
||||
// Pattern2
|
||||
if (tdd->pattern2) {
|
||||
num_of_patterns++;
|
||||
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
|
||||
}
|
||||
LOG_I(NR_MAC,
|
||||
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
|
||||
num_of_patterns,
|
||||
nb_slots_p1,
|
||||
nb_slots_p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the first UL slot index in period
|
||||
* @param fs frame structure
|
||||
* @param mixed indicates whether to include in the count also mixed slot with UL symbols or only full UL slot
|
||||
* @return slot index
|
||||
*/
|
||||
int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
if (fs->is_tdd) {
|
||||
for (int i = 0; i < fs->numb_slots_period; i++) {
|
||||
if ((mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0; // FDD
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of DL slots per period (full DL slots + mixed slots with DL symbols)
|
||||
*/
|
||||
int get_dl_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->period_cfg.num_dl_slots : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of UL slots per period (full UL slots + mixed slots with UL symbols)
|
||||
*/
|
||||
int get_ul_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->period_cfg.num_ul_slots : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of full UL slots per period
|
||||
* @param fs Pointer to the frame structure
|
||||
* @return Number of full UL slots
|
||||
*/
|
||||
int get_full_ul_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
if (!fs->is_tdd)
|
||||
return fs->numb_slots_frame;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT)
|
||||
count++;
|
||||
|
||||
LOG_D(NR_MAC, "Full UL slots in TDD period: %d\n", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of full DL slots per period
|
||||
* @param fs Pointer to the frame structure
|
||||
* @return Number of full DL slots
|
||||
*/
|
||||
int get_full_dl_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
if (!fs->is_tdd)
|
||||
return fs->numb_slots_frame;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_DOWNLINK_SLOT)
|
||||
count++;
|
||||
|
||||
LOG_D(NR_MAC, "Full DL slots in TDD period: %d\n", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of UL slots per frame
|
||||
*/
|
||||
int get_ul_slots_per_frame(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->numb_period_frame * get_ul_slots_per_period(fs) : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the nth UL slot offset for UE index idx in a TDD period using the frame structure bitmap
|
||||
* @param fs frame structure
|
||||
* @param idx UE index
|
||||
* @param count_mixed indicates whether counting mixed slot with UL symbols (e.g. for SRS) or only full UL slots
|
||||
* @return slot index offset
|
||||
*/
|
||||
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
// FDD
|
||||
if (!fs->is_tdd)
|
||||
return idx;
|
||||
|
||||
// UL slots indexes in period
|
||||
int ul_slot_idxs[fs->numb_slots_period];
|
||||
int ul_slot_count = 0;
|
||||
|
||||
/* Populate the indices of UL slots in the TDD period from the bitmap
|
||||
count also mixed slots with UL symbols if flag count_mixed is present */
|
||||
for (int i = 0; i < fs->numb_slots_period; i++) {
|
||||
if ((count_mixed && is_ul_slot(i, fs)) || fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) {
|
||||
ul_slot_idxs[ul_slot_count++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute slot index offset
|
||||
int period_idx = idx / ul_slot_count; // wrap up the count of complete TDD periods spanned by the index
|
||||
int ul_slot_idx_in_period = idx % ul_slot_count; // wrap up the UL slot index within the current TDD period
|
||||
|
||||
return ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the frame structure and the NFAPI config request
|
||||
* depending on the duplex mode. If TDD, does the TDD patterns
|
||||
* and TDD periods configuration.
|
||||
*
|
||||
* @param mu numerology
|
||||
* @param scc pointer to scc
|
||||
* @param cfg pointer to NFAPI config request
|
||||
* @param fs pointer to the frame structure to update
|
||||
*
|
||||
* @return Number of periods in frame
|
||||
*/
|
||||
static int config_frame_structure(int mu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
nfapi_nr_config_request_scf_t *cfg,
|
||||
frame_structure_t *fs)
|
||||
{
|
||||
fs->numb_slots_frame = nr_slots_per_frame[mu];
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD) {
|
||||
cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG;
|
||||
cfg->num_tlv++;
|
||||
cfg->tdd_table.tdd_period.value = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon);
|
||||
LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value);
|
||||
fs->numb_period_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
|
||||
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
|
||||
fs->is_tdd = true;
|
||||
config_tdd_patterns(scc->tdd_UL_DL_ConfigurationCommon, fs);
|
||||
set_tdd_config_nr(cfg, fs);
|
||||
} else { // FDD
|
||||
fs->is_tdd = false;
|
||||
fs->numb_period_frame = 1;
|
||||
fs->numb_slots_period = nr_slots_per_frame[mu];
|
||||
}
|
||||
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
|
||||
return fs->numb_period_frame;
|
||||
}
|
||||
|
||||
static void config_common(gNB_MAC_INST *nrmac,
|
||||
const nr_mac_config_t *config,
|
||||
NR_ServingCellConfigCommon_t *scc)
|
||||
@@ -321,10 +568,10 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
}
|
||||
}
|
||||
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
int scs = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
|
||||
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
frequency_range,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
bw_index =
|
||||
get_supported_band_index(scs, frequency_range, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
||||
cfg->num_tlv++;
|
||||
@@ -343,7 +590,7 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
cfg->num_tlv++;
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
|
||||
if (i == scs) {
|
||||
cfg->carrier_config.ul_grid_size[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
|
||||
cfg->carrier_config.ul_k0[i].value = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
|
||||
cfg->carrier_config.ul_grid_size[i].tl.tag = NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG;
|
||||
@@ -442,21 +689,15 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
prach_fd_occasion->k1.value =
|
||||
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
||||
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
||||
* i);
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||
if (IS_SA_MODE(get_softmodem_params())) {
|
||||
prach_fd_occasion->k1.value =
|
||||
NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)
|
||||
+ rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
||||
* i);
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||
} else {
|
||||
prach_fd_occasion->k1.value = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing)
|
||||
* i);
|
||||
+ (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, scs) * i);
|
||||
}
|
||||
prach_fd_occasion->k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
|
||||
cfg->num_tlv++;
|
||||
@@ -576,28 +817,9 @@ static void config_common(gNB_MAC_INST *nrmac,
|
||||
cfg->num_tlv++;
|
||||
cfg->num_tlv++;
|
||||
|
||||
// TDD Table Configuration
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD) {
|
||||
cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG;
|
||||
cfg->num_tlv++;
|
||||
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 == NULL) {
|
||||
cfg->tdd_table.tdd_period.value = scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity;
|
||||
} else {
|
||||
AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL,
|
||||
"In %s: scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n",
|
||||
__FUNCTION__);
|
||||
cfg->tdd_table.tdd_period.value = *scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530;
|
||||
}
|
||||
LOG_D(NR_MAC, "Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period.value);
|
||||
int periods_per_frame = set_tdd_config_nr(cfg,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
|
||||
|
||||
AssertFatal(periods_per_frame > 0, "TDD configuration cannot be configured\n");
|
||||
}
|
||||
// Frame structure configuration
|
||||
uint8_t mu = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
config_frame_structure(mu, scc, cfg, &nrmac->frame_structure);
|
||||
|
||||
int nb_tx = config->nb_bfw[0]; // number of tx antennas
|
||||
int nb_beams = config->nb_bfw[1]; // number of beams
|
||||
@@ -695,31 +917,6 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c
|
||||
|
||||
find_SSB_and_RO_available(nrmac);
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
|
||||
int nr_slots_period = n;
|
||||
int nr_dl_slots = n;
|
||||
int nr_ulstart_slot = 0;
|
||||
if (tdd) {
|
||||
nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
|
||||
nr_ulstart_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
|
||||
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||
} else {
|
||||
// if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
|
||||
AssertFatal(nrmac->common_channels[0].frame_type == FDD,"Dynamic TDD not handled yet\n");
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < n; ++slot) {
|
||||
nrmac->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dl_slots) << (slot % 64);
|
||||
nrmac->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"slot %d DL %d UL %d\n",
|
||||
slot,
|
||||
(nrmac->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0,
|
||||
(nrmac->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0);
|
||||
}
|
||||
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) {
|
||||
|
||||
@@ -122,8 +122,49 @@ void clear_beam_information(NR_beam_info_t *beam_info, int frame, int slot, int
|
||||
}
|
||||
}
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
return (bitmap >> (slot % 64)) & 0x01;
|
||||
/**
|
||||
* @brief Returns true for:
|
||||
* (1) FDD
|
||||
* (2) Mixed slot with UL symbols
|
||||
* (3) Full UL slot
|
||||
*/
|
||||
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs)
|
||||
{
|
||||
if (!fs->is_tdd)
|
||||
return true;
|
||||
const tdd_period_config_t *pc = &fs->period_cfg;
|
||||
slot_t s = get_slot_idx_in_period(slot, fs);
|
||||
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_ul_symbols)
|
||||
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_UPLINK_SLOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true for:
|
||||
* (1) FDD
|
||||
* (2) Mixed slot with DL symbols
|
||||
* (3) Full DL slot
|
||||
*/
|
||||
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs)
|
||||
{
|
||||
if (!fs->is_tdd)
|
||||
return true;
|
||||
const tdd_period_config_t *pc = &fs->period_cfg;
|
||||
slot_t s = get_slot_idx_in_period(slot, fs);
|
||||
return ((is_mixed_slot(s, fs) && pc->tdd_slot_bitmap[s].num_dl_symbols)
|
||||
|| (pc->tdd_slot_bitmap[s].slot_type == TDD_NR_DOWNLINK_SLOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true for:
|
||||
* (1) Mixed slot with DL and/or UL symbols
|
||||
*/
|
||||
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs)
|
||||
{
|
||||
if (!fs->is_tdd)
|
||||
return false;
|
||||
slot_t s = get_slot_idx_in_period(slot, fs);
|
||||
const tdd_period_config_t *pc = &fs->period_cfg;
|
||||
return pc->tdd_slot_bitmap[s].slot_type == TDD_NR_MIXED_SLOT;
|
||||
}
|
||||
|
||||
/* the structure nfapi_nr_ul_tti_request_t is very big, let's copy only what is necessary */
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
#include "openair2/LAYER2/RLC/rlc.h"
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
// forward declaration of functions used in this file
|
||||
static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
@@ -278,7 +276,7 @@ static void schedule_nr_MsgA_pusch(NR_UplinkConfigCommon_t *uplinkConfigCommon,
|
||||
|
||||
UL_tti_req->SFN = msgA_pusch_frame;
|
||||
UL_tti_req->Slot = msgA_pusch_slot;
|
||||
AssertFatal(is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[msgA_pusch_slot / 64], msgA_pusch_slot),
|
||||
AssertFatal(is_ul_slot(msgA_pusch_slot, &nr_mac->frame_structure),
|
||||
"Slot %d is not an Uplink slot, invalid msgA_PUSCH_TimeDomainOffset_r16 %ld\n",
|
||||
msgA_pusch_slot,
|
||||
msgA_PUSCH_Resource->msgA_PUSCH_TimeDomainOffset_r16);
|
||||
@@ -376,7 +374,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index];
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
|
||||
if (is_nr_UL_slot(scc->tdd_UL_DL_ConfigurationCommon, slotP, cc->frame_type)) {
|
||||
if (is_ul_slot(slotP, &RC.nrmac[module_idP]->frame_structure)) {
|
||||
const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &rach_ConfigCommon->rach_ConfigGeneric;
|
||||
uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
|
||||
uint8_t N_dur, N_t_slot, start_symbol = 0, N_RA_slot;
|
||||
@@ -787,7 +785,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
|
||||
if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) {
|
||||
if (is_ul_slot(sched_slot, &nr_mac->frame_structure)) {
|
||||
const int n_slots_frame = nr_slots_per_frame[mu];
|
||||
NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame);
|
||||
if (beam_ul.idx < 0)
|
||||
@@ -952,47 +950,44 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP,
|
||||
ra->ra_state = nrRA_WAIT_Msg3;
|
||||
ra->Msg3_frame = sched_frame;
|
||||
ra->Msg3_slot = sched_slot;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_feasible_msg3_tda(frame_type_t frame_type,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
static bool get_feasible_msg3_tda(const NR_ServingCellConfigCommon_t *scc,
|
||||
int mu_delta,
|
||||
uint64_t ulsch_slot_bitmap[3],
|
||||
const NR_PUSCH_TimeDomainResourceAllocationList_t *tda_list,
|
||||
int slots_per_frame,
|
||||
int frame,
|
||||
int slot,
|
||||
NR_RA_t *ra,
|
||||
NR_beam_info_t *beam_info,
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd)
|
||||
const frame_structure_t *fs)
|
||||
{
|
||||
DevAssert(tda_list != NULL);
|
||||
|
||||
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
|
||||
|
||||
int tdd_period_slot = tdd ? slots_per_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : slots_per_frame;
|
||||
int slots_per_frame = fs->numb_slots_frame;
|
||||
for (int i = 0; i < tda_list->list.count; i++) {
|
||||
// check if it is UL
|
||||
long k2 = *tda_list->list.array[i]->k2 + NTN_gNB_Koffset;
|
||||
int abs_slot = slot + k2 + mu_delta;
|
||||
int temp_frame = (frame + (abs_slot / slots_per_frame)) & 1023;
|
||||
int temp_slot = abs_slot % slots_per_frame; // msg3 slot according to 8.3 in 38.213
|
||||
if ((frame_type == TDD) && !is_xlsch_in_slot(ulsch_slot_bitmap[temp_slot / 64], temp_slot))
|
||||
if (fs->is_tdd && !is_ul_slot(temp_slot, fs))
|
||||
continue;
|
||||
|
||||
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
|
||||
int s = get_slot_idx_in_period(temp_slot, fs);
|
||||
// check if enough symbols in case of mixed slot
|
||||
bool is_mixed = false;
|
||||
if (frame_type == TDD) {
|
||||
bool has_mixed = tdd->nrofUplinkSymbols != 0 || tdd->nrofDownlinkSymbols != 0;
|
||||
is_mixed = has_mixed && ((temp_slot % tdd_period_slot) == tdd->nrofDownlinkSlots);
|
||||
}
|
||||
bool is_mixed = is_mixed_slot(s, fs);
|
||||
// if the mixed slot has not enough symbols, skip
|
||||
if (is_mixed && tdd->nrofUplinkSymbols < 3)
|
||||
if (is_mixed && tdd_slot_bitmap[s].num_ul_symbols < 3)
|
||||
continue;
|
||||
|
||||
uint16_t slot_mask = is_mixed ? SL_to_bitmap(14 - tdd->nrofUplinkSymbols, tdd->nrofUplinkSymbols) : 0x3fff;
|
||||
uint16_t slot_mask =
|
||||
is_mixed ? SL_to_bitmap(NR_NUMBER_OF_SYMBOLS_PER_SLOT - tdd_slot_bitmap[s].num_ul_symbols,
|
||||
tdd_slot_bitmap[s].num_ul_symbols)
|
||||
: 0x3fff;
|
||||
long startSymbolAndLength = tda_list->list.array[i]->startSymbolAndLength;
|
||||
int start, nr;
|
||||
SLIV2SL(startSymbolAndLength, &start, &nr);
|
||||
@@ -1387,7 +1382,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
|
||||
|
||||
// no DL -> cannot send Msg2
|
||||
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
|
||||
if (!is_dl_slot(slotP, &nr_mac->frame_structure)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1415,18 +1410,14 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
return;
|
||||
|
||||
const NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP;
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
bool ret = get_feasible_msg3_tda(cc->frame_type,
|
||||
scc,
|
||||
bool ret = get_feasible_msg3_tda(scc,
|
||||
DELTA[ul_bwp->scs],
|
||||
nr_mac->ulsch_slot_bitmap,
|
||||
ul_bwp->tdaList_Common,
|
||||
nr_slots_per_frame[ul_bwp->scs],
|
||||
frameP,
|
||||
slotP,
|
||||
ra,
|
||||
&nr_mac->beam_info,
|
||||
tdd);
|
||||
&nr_mac->frame_structure);
|
||||
if (!ret || ra->Msg3_tda_id > 15) {
|
||||
LOG_D(NR_MAC, "UE RNTI %04x %d.%d: infeasible Msg3 TDA\n", ra->rnti, frameP, slotP);
|
||||
reset_beam_status(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame, beam.new_beam);
|
||||
@@ -1455,7 +1446,7 @@ static void nr_generate_Msg2(module_id_t module_idP,
|
||||
AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n");
|
||||
const int coresetid = coreset->controlResourceSetId;
|
||||
// Calculate number of symbols
|
||||
int time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
|
||||
int time_domain_assignment = get_dl_tda(nr_mac, slotP);
|
||||
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
|
||||
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
|
||||
ss->searchSpaceType->present,
|
||||
@@ -1951,8 +1942,8 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
|
||||
NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP;
|
||||
|
||||
// if it is a DL slot, if the RA is in MSG4 state
|
||||
if (is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slotP / 64], slotP)) {
|
||||
// if it is a DL slot, if the RA is in MSG4 state
|
||||
if (is_dl_slot(slotP, &nr_mac->frame_structure)) {
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_SearchSpace_t *ss = ra->ra_ss;
|
||||
const char *ra_type_str = ra->ra_type == RA_2_STEP ? "MsgB" : "Msg4";
|
||||
@@ -2031,7 +2022,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t time_domain_assignment = get_dl_tda(nr_mac, scc, slotP);
|
||||
uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP);
|
||||
int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1;
|
||||
NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp,
|
||||
ss->searchSpaceType->present,
|
||||
|
||||
@@ -45,8 +45,6 @@
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
static void schedule_ssb(frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
@@ -52,20 +52,22 @@
|
||||
#define WORD 32
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot)
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot)
|
||||
{
|
||||
/* we assume that this function is mutex-protected from outside */
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
const frame_structure_t *fs = &nrmac->frame_structure;
|
||||
|
||||
// Use special TDA in case of CSI-RS
|
||||
if(nrmac->UE_info.sched_csirs > 0)
|
||||
if (nrmac->UE_info.sched_csirs > 0)
|
||||
return 1;
|
||||
|
||||
if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL
|
||||
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
|
||||
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
|
||||
if (fs->is_tdd) {
|
||||
int s = get_slot_idx_in_period(slot, fs);
|
||||
// if there is a mixed slot where we can transmit DL
|
||||
const tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
|
||||
if (tdd_slot_bitmap[s].num_dl_symbols > 1 && is_mixed_slot(s, fs)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0; // if FDD or not mixed slot in TDD, for now use default TDA
|
||||
}
|
||||
@@ -447,7 +449,7 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index;
|
||||
|
||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const int tda = get_dl_tda(nr_mac, scc, slot);
|
||||
const int tda = get_dl_tda(nr_mac, slot);
|
||||
AssertFatal(tda >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
/* Check first whether the old TDA can be reused
|
||||
@@ -761,7 +763,7 @@ static void pf_dl(module_id_t module_id,
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||
|
||||
/* MCS has been set above */
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot);
|
||||
sched_pdsch->time_domain_allocation = get_dl_tda(mac, slot);
|
||||
AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
const int coresetid = sched_ctrl->coreset->controlResourceSetId;
|
||||
@@ -955,7 +957,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
|
||||
"this function should be called with the scheduler mutex locked\n");
|
||||
|
||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||
if (!is_dl_slot(slot, &gNB_mac->frame_structure))
|
||||
return;
|
||||
|
||||
/* PREPROCESSOR */
|
||||
|
||||
@@ -37,10 +37,16 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
//#define UL_HARQ_PRINT
|
||||
extern RAN_CONTEXT_t RC;
|
||||
// #define UL_HARQ_PRINT
|
||||
// #define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||
|
||||
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||
/* This function checks whether the given Dl/UL slot is set
|
||||
in the input bitmap, which is a mask indicating in which
|
||||
slot to transmit (among those available in the TDD configuration) */
|
||||
static bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot)
|
||||
{
|
||||
return (bitmap >> (slot % 64)) & 0x01;
|
||||
}
|
||||
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_Nl = 1;
|
||||
@@ -66,7 +72,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
return;
|
||||
}
|
||||
|
||||
const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot);
|
||||
const int tda = get_dl_tda(RC.nrmac[module_id], slot);
|
||||
NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp,
|
||||
sched_ctrl->search_space->searchSpaceType->present,
|
||||
tda,
|
||||
@@ -244,7 +250,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
sched_ctrl->coreset->controlResourceSetId,
|
||||
sched_ctrl->search_space->searchSpaceType->present,
|
||||
TYPE_C_RNTI_);
|
||||
const int temp_tda = get_ul_tda(nr_mac, scc, frame, slot);
|
||||
const int temp_tda = get_ul_tda(nr_mac, frame, slot);
|
||||
if (temp_tda < 0)
|
||||
return false;
|
||||
AssertFatal(temp_tda < tdaList->list.count,
|
||||
@@ -254,7 +260,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
int K2 = get_K2(tdaList, temp_tda, mu, scc);
|
||||
const int sched_frame = (frame + (slot + K2) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER;
|
||||
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
|
||||
const int tda = get_ul_tda(nr_mac, scc, sched_frame, sched_slot);
|
||||
const int tda = get_ul_tda(nr_mac, sched_frame, sched_slot);
|
||||
if (tda < 0)
|
||||
return false;
|
||||
AssertFatal(tda < tdaList->list.count,
|
||||
|
||||
@@ -63,12 +63,9 @@
|
||||
|
||||
#include "common/utils/alg/find.h"
|
||||
|
||||
//#define DEBUG_DCI
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
// CQI TABLES (10 times the value in 214 to adequately compare with R)
|
||||
// Table 1 (38.214 5.2.2.1-2)
|
||||
// #define DEBUG_DCI
|
||||
// CQI TABLES (10 times the value in 214 to adequately compare with R)
|
||||
// Table 1 (38.214 5.2.2.1-2)
|
||||
static const uint16_t cqi_table1[16][2] = {{0, 0},
|
||||
{2, 780},
|
||||
{2, 1200},
|
||||
@@ -2163,6 +2160,31 @@ int get_ulbw_tbslbrm(int scc_bwpsize, const NR_ServingCellConfig_t *servingCellC
|
||||
return bw;
|
||||
}
|
||||
|
||||
static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
const NR_UE_UL_BWP_t *ul_bwp,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const frame_structure_t *fs)
|
||||
{
|
||||
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
|
||||
const int n_ul_slots_period = get_ul_slots_per_period(fs);
|
||||
|
||||
// PUCCH list size is given by the number of UL slots in the PUCCH period
|
||||
// the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead
|
||||
const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / fs->numb_slots_period + 1));
|
||||
|
||||
if (!sched_ctrl->sched_pucch) {
|
||||
sched_ctrl->sched_pucch = calloc_or_fail(list_size, sizeof(*sched_ctrl->sched_pucch));
|
||||
sched_ctrl->sched_pucch_size = list_size;
|
||||
} else if (list_size > sched_ctrl->sched_pucch_size) {
|
||||
sched_ctrl->sched_pucch = realloc(sched_ctrl->sched_pucch, list_size * sizeof(*sched_ctrl->sched_pucch));
|
||||
for (int i = sched_ctrl->sched_pucch_size; i < list_size; i++) {
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[i];
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
}
|
||||
sched_ctrl->sched_pucch_size = list_size;
|
||||
}
|
||||
}
|
||||
|
||||
// main function to configure parameters of current BWP
|
||||
void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
@@ -2408,7 +2430,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
set_max_fb_time(UL_BWP, DL_BWP);
|
||||
set_sched_pucch_list(sched_ctrl, UL_BWP, scc);
|
||||
set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure);
|
||||
}
|
||||
|
||||
if(ra) {
|
||||
@@ -2540,32 +2562,6 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
|
||||
return (UE);
|
||||
}
|
||||
|
||||
void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
const NR_UE_UL_BWP_t *ul_bwp,
|
||||
const NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
const int NTN_gNB_Koffset = get_NTN_Koffset(scc);
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
|
||||
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
|
||||
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
|
||||
// PUCCH list size is given by the number of UL slots in the PUCCH period
|
||||
// the length PUCCH period is determined by max_fb_time since we may need to prepare PUCCH for ACK/NACK max_fb_time slots ahead
|
||||
const int list_size = n_ul_slots_period << (int)ceil(log2((ul_bwp->max_fb_time + NTN_gNB_Koffset) / nr_slots_period + 1));
|
||||
if(!sched_ctrl->sched_pucch) {
|
||||
sched_ctrl->sched_pucch = calloc(list_size, sizeof(*sched_ctrl->sched_pucch));
|
||||
sched_ctrl->sched_pucch_size = list_size;
|
||||
}
|
||||
else if (list_size > sched_ctrl->sched_pucch_size) {
|
||||
sched_ctrl->sched_pucch = realloc(sched_ctrl->sched_pucch, list_size * sizeof(*sched_ctrl->sched_pucch));
|
||||
for(int i=sched_ctrl->sched_pucch_size; i<list_size; i++){
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[i];
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
}
|
||||
sched_ctrl->sched_pucch_size = list_size;
|
||||
}
|
||||
}
|
||||
|
||||
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl)
|
||||
{
|
||||
free(sched_ctrl->sched_pucch);
|
||||
|
||||
@@ -37,10 +37,7 @@
|
||||
#include <math.h>
|
||||
#include "PHY/sse_intrin.h"
|
||||
|
||||
//#define SRS_DEBUG
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
// #define SRS_DEBUG
|
||||
const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88,
|
||||
96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160,
|
||||
160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256,
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include "common/ran_context.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
@@ -136,23 +133,35 @@ static const int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
|
||||
-30 // 10 - 15
|
||||
};
|
||||
|
||||
static int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_Pattern_t *tdd, int sched_pucch_size)
|
||||
static int get_pucch_index(int frame, int slot, const frame_structure_t *fs, int sched_pucch_size)
|
||||
{
|
||||
// PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots
|
||||
// this functions return the index to the structure for slot passed to the function
|
||||
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
|
||||
const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
|
||||
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
|
||||
const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period;
|
||||
const int n_ul_slots_period = get_ul_slots_per_period(fs);
|
||||
const int n_ul_slots_frame = get_ul_slots_per_frame(fs);
|
||||
// (frame * n_ul_slots_frame) adds up the number of UL slots in the previous frames
|
||||
const int frame_start = frame * n_ul_slots_frame;
|
||||
// ((slot / nr_slots_period) * n_ul_slots_period) adds up the number of UL slots in the previous TDD periods of this frame
|
||||
const int ul_period_start = (slot / nr_slots_period) * n_ul_slots_period;
|
||||
const int ul_period_start = (slot / fs->numb_slots_period) * n_ul_slots_period;
|
||||
// ((slot % nr_slots_period) - first_ul_slot_period) gives the progressive number of the slot in this TDD period
|
||||
const int ul_period_slot = (slot % nr_slots_period) - first_ul_slot_period;
|
||||
int ul_period_slot = -1;
|
||||
for (int i = 0; i <= slot % fs->numb_slots_period; i++) {
|
||||
if (is_ul_slot(i, fs)) {
|
||||
ul_period_slot++;
|
||||
}
|
||||
}
|
||||
LOG_D(NR_MAC,
|
||||
"PUCCH frame/slot: request %4d.%2d:frame_start %d,ul_period_start %d, ul_period_slot %d pucch_index %d pucch_size %d "
|
||||
"scheduling PUCCH\n",
|
||||
frame,
|
||||
slot,
|
||||
frame_start,
|
||||
ul_period_start,
|
||||
ul_period_slot,
|
||||
((frame_start + ul_period_start + ul_period_slot) % sched_pucch_size),
|
||||
sched_pucch_size);
|
||||
// the sum gives the index of current UL slot in the frame which is normalized wrt sched_pucch_size
|
||||
return (frame_start + ul_period_start + ul_period_slot) % sched_pucch_size;
|
||||
|
||||
}
|
||||
|
||||
void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP)
|
||||
@@ -160,17 +169,12 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP)
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
|
||||
if (!is_ul_slot(slotP, &nrmac->frame_structure))
|
||||
return;
|
||||
|
||||
UE_iterator(nrmac->UE_info.list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
|
||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[0].ServingCellConfigCommon;
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
const int pucch_index = get_pucch_index(frameP, slotP, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
|
||||
const int pucch_index = get_pucch_index(frameP, slotP, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[pucch_index];
|
||||
if (!curr_pucch->active)
|
||||
continue;
|
||||
@@ -239,7 +243,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
|
||||
if ((sched_frame * n_slots_frame + sched_slot - offset) % period != 0)
|
||||
continue;
|
||||
|
||||
AssertFatal(is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[sched_slot / 64], sched_slot), "CSI reporting slot %d is not set for an uplink slot\n", sched_slot);
|
||||
AssertFatal(is_ul_slot(sched_slot, &nrmac->frame_structure), "CSI reporting slot %d is not set for an uplink slot\n", sched_slot);
|
||||
LOG_D(NR_MAC, "CSI reporting in frame %d slot %d CSI report ID %ld\n", sched_frame, sched_slot, csirep->reportConfigId);
|
||||
|
||||
const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1
|
||||
@@ -251,9 +255,7 @@ void nr_csi_meas_reporting(int Mod_idP,frame_t frame, sub_frame_t slot)
|
||||
AssertFatal(res_index < n,
|
||||
"CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource);
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || nrmac->common_channels[0].frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
const int pucch_index = get_pucch_index(sched_frame, sched_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
|
||||
const int pucch_index = get_pucch_index(sched_frame, sched_slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
||||
AssertFatal(curr_pucch->active == false, "CSI structure is scheduled in advance. It should be free!\n");
|
||||
curr_pucch->r_pucch = -1;
|
||||
@@ -1001,10 +1003,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
|
||||
const int minfbtime = mac->radio_config.minRXTXTIME + NTN_gNB_Koffset;
|
||||
const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP;
|
||||
const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs];
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || mac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
|
||||
const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
|
||||
const frame_structure_t *fs = &mac->frame_structure;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
|
||||
@@ -1025,11 +1024,14 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
|
||||
continue;
|
||||
const int pucch_slot = (slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) % n_slots_frame;
|
||||
// check if the slot is UL
|
||||
if(pucch_slot%nr_slots_period < first_ul_slot_period)
|
||||
continue;
|
||||
if (fs->is_tdd) {
|
||||
int mod_slot = pucch_slot % fs->numb_slots_period;
|
||||
if (!is_ul_slot(mod_slot, fs))
|
||||
continue;
|
||||
}
|
||||
const int pucch_frame = (frame + ((slot + pdsch_to_harq_feedback[f] + NTN_gNB_Koffset) / n_slots_frame)) % MAX_FRAME_NUMBER;
|
||||
// we store PUCCH resources according to slot, TDD configuration and size of the vector containing PUCCH structures
|
||||
const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
|
||||
const int pucch_index = get_pucch_index(pucch_frame, pucch_slot, &mac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
||||
if (curr_pucch->active &&
|
||||
curr_pucch->frame == pucch_frame &&
|
||||
@@ -1128,7 +1130,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
|
||||
if (!is_ul_slot(slot, &nrmac->frame_structure))
|
||||
return;
|
||||
const int CC_id = 0;
|
||||
UE_iterator(nrmac->UE_info.list, UE) {
|
||||
@@ -1167,10 +1169,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
|
||||
}
|
||||
AssertFatal(idx > -1, "SR resource not found among PUCCH resources");
|
||||
|
||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || nrmac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
const int pucch_index = get_pucch_index(SFN, slot, n_slots_frame, tdd, sched_ctrl->sched_pucch_size);
|
||||
const int pucch_index = get_pucch_index(SFN, slot, &nrmac->frame_structure, sched_ctrl->sched_pucch_size);
|
||||
NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[pucch_index];
|
||||
|
||||
if (curr_pucch->active && curr_pucch->frame == SFN && curr_pucch->ul_slot == slot && curr_pucch->resource_indicator == idx)
|
||||
|
||||
@@ -40,19 +40,21 @@
|
||||
|
||||
//#define SRS_IND_DEBUG
|
||||
|
||||
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot)
|
||||
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot)
|
||||
{
|
||||
/* we assume that this function is mutex-protected from outside */
|
||||
NR_SCHED_ENSURE_LOCKED(&nrmac->sched_lock);
|
||||
|
||||
/* there is a mixed slot only when in TDD */
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
AssertFatal(tdd || nrmac->common_channels->frame_type == FDD, "Dynamic TDD not handled yet\n");
|
||||
frame_structure_t *fs = &nrmac->frame_structure;
|
||||
|
||||
if (tdd && tdd->nrofUplinkSymbols > 1) { // if there is uplink symbols in mixed slot
|
||||
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
|
||||
if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
|
||||
if (fs->is_tdd) {
|
||||
// if there is uplink symbols in mixed slot
|
||||
int s = get_slot_idx_in_period(slot, fs);
|
||||
tdd_bitmap_t *tdd_slot_bitmap = fs->period_cfg.tdd_slot_bitmap;
|
||||
if ((tdd_slot_bitmap[s].num_ul_symbols > 1) && is_mixed_slot(s, fs)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid slots with the SRS
|
||||
@@ -453,9 +455,9 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
if (phr->PH < 55) {
|
||||
PH = phr->PH - 32;
|
||||
} else if (phr->PH < 63) {
|
||||
PH = 28 + (phr->PH - 55) * 2;
|
||||
PH = 24 + (phr->PH - 55) * 2;
|
||||
} else {
|
||||
PH = 42;
|
||||
PH = 38;
|
||||
}
|
||||
// in sched_ctrl we set normalized PH wrt MCS and PRBs
|
||||
long *deltaMCS = ul_bwp->pusch_Config ? ul_bwp->pusch_Config->pusch_PowerControl->deltaMCS : NULL;
|
||||
@@ -1519,25 +1521,21 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
|
||||
return 3 + NTN_gNB_Koffset;
|
||||
}
|
||||
|
||||
static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
|
||||
static bool nr_UE_is_to_be_scheduled(const frame_structure_t *fs,
|
||||
NR_UE_info_t *UE,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint32_t ulsch_max_frame_inactivity)
|
||||
{
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int n = fs->numb_slots_frame;
|
||||
const int now = frame * n + slot;
|
||||
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
int num_slots_per_period;
|
||||
int last_ul_slot;
|
||||
if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
|
||||
num_slots_per_period = n / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||
last_ul_slot = 1 + tdd->nrofDownlinkSlots;
|
||||
} else {
|
||||
num_slots_per_period = n;
|
||||
last_ul_slot = sched_ctrl->last_ul_slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the default transmission in a full slot as early
|
||||
* as possible in the UL portion of TDD period (last_ul_slot) */
|
||||
int num_slots_per_period = fs->numb_slots_period;
|
||||
int last_ul_slot = fs->is_tdd ? get_first_ul_slot(fs, false) : sched_ctrl->last_ul_slot;
|
||||
const int last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
|
||||
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
|
||||
/* UE is to be scheduled if
|
||||
@@ -1641,7 +1639,7 @@ static void nr_ue_max_mcs_min_rb(int mu,
|
||||
}
|
||||
|
||||
if (ph_limit < tx_power)
|
||||
LOG_W(NR_MAC, "Normalized power %d based on current resources (RBs %d, MCS %d) exceed reported PHR %d (normalized value)\n",
|
||||
LOG_D(NR_MAC, "Normalized power %d based on current resources (RBs %d, MCS %d) exceed reported PHR %d (normalized value)\n",
|
||||
tx_power, *Rb, *mcs, ph_limit);
|
||||
}
|
||||
|
||||
@@ -1842,7 +1840,7 @@ static void pf_ul(module_id_t module_id,
|
||||
}
|
||||
|
||||
int n = nr_slots_per_frame[current_BWP->scs];
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n);
|
||||
if (beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
@@ -1856,7 +1854,7 @@ static void pf_ul(module_id_t module_id,
|
||||
LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n", UE->rnti, sched_pusch->ul_harq_pid);
|
||||
if (sched_pusch->ul_harq_pid >= 0) {
|
||||
/* Allocate retransmission*/
|
||||
const int tda = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
|
||||
const int tda = get_ul_tda(nrmac, sched_frame, sched_slot);
|
||||
bool r = allocate_ul_retransmission(nrmac,
|
||||
frame,
|
||||
slot,
|
||||
@@ -1869,7 +1867,7 @@ static void pf_ul(module_id_t module_id,
|
||||
tda);
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UL retransmission could not be allocated\n", UE->rnti, frame, slot);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
@@ -1885,7 +1883,7 @@ static void pf_ul(module_id_t module_id,
|
||||
* if the UE disconnected in L2sim, in which case the gNB is not notified
|
||||
* (this can be considered a design flaw) */
|
||||
if (sched_ctrl->available_ul_harq.head < 0) {
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] has no free UL HARQ process, skipping\n", UE->rnti, frame, slot);
|
||||
continue;
|
||||
@@ -1893,11 +1891,15 @@ static void pf_ul(module_id_t module_id,
|
||||
|
||||
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||
/* preprocessor computed sched_frame/sched_slot */
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_frame, sched_slot, nrmac->ulsch_max_frame_inactivity);
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(&nrmac->frame_structure,
|
||||
UE,
|
||||
sched_frame,
|
||||
sched_slot,
|
||||
nrmac->ulsch_max_frame_inactivity);
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n", UE->rnti, do_sched ? "yes" : "no");
|
||||
if ((B == 0 && !do_sched) || nr_timer_is_active(&sched_ctrl->transm_interrupt)) {
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
@@ -1927,13 +1929,13 @@ static void pf_ul(module_id_t module_id,
|
||||
false);
|
||||
if (CCEIndex < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI (BSR 0)\n", UE->rnti, frame, slot);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
|
||||
sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1;
|
||||
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
|
||||
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, sched_frame, sched_slot);
|
||||
sched_pusch->tda_info = get_ul_tda_info(current_BWP,
|
||||
sched_ctrl->coreset->controlResourceSetId,
|
||||
sched_ctrl->search_space->searchSpaceType->present,
|
||||
@@ -1962,7 +1964,7 @@ static void pf_ul(module_id_t module_id,
|
||||
rbStart,
|
||||
min_rb,
|
||||
bwpSize);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
continue;
|
||||
}
|
||||
@@ -2042,11 +2044,7 @@ static void pf_ul(module_id_t module_id,
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
|
||||
int n = nr_slots_per_frame[current_BWP->scs];
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot,
|
||||
iterator->UE->UE_beam_index,
|
||||
n);
|
||||
NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n);
|
||||
if (beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
|
||||
iterator++;
|
||||
@@ -2054,7 +2052,7 @@ static void pf_ul(module_id_t module_id,
|
||||
}
|
||||
|
||||
if (remainUEs[beam.idx] == 0 || n_rb_sched[beam.idx] < min_rb) {
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
@@ -2063,7 +2061,7 @@ static void pf_ul(module_id_t module_id,
|
||||
NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl);
|
||||
if (dci_beam.idx < 0) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
iterator++;
|
||||
continue;
|
||||
}
|
||||
@@ -2079,7 +2077,7 @@ static void pf_ul(module_id_t module_id,
|
||||
|
||||
if (CCEIndex < 0) {
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] no free CCE for UL DCI\n", iterator->UE->rnti, frame, slot);
|
||||
iterator++;
|
||||
continue;
|
||||
@@ -2090,7 +2088,7 @@ static void pf_ul(module_id_t module_id,
|
||||
|
||||
|
||||
sched_pusch->nrOfLayers = sched_ctrl->srs_feedback.ul_ri + 1;
|
||||
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, scc, sched_frame, sched_slot);
|
||||
sched_pusch->time_domain_allocation = get_ul_tda(nrmac, sched_frame, sched_slot);
|
||||
sched_pusch->tda_info = get_ul_tda_info(current_BWP,
|
||||
sched_ctrl->coreset->controlResourceSetId,
|
||||
sched_ctrl->search_space->searchSpaceType->present,
|
||||
@@ -2115,7 +2113,7 @@ static void pf_ul(module_id_t module_id,
|
||||
|
||||
if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) {
|
||||
reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, n_dl, dci_beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_pusch->frame, sched_pusch->slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, n, beam.new_beam);
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
|
||||
iterator->UE->rnti,
|
||||
frame,
|
||||
@@ -2219,7 +2217,7 @@ static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_fram
|
||||
const int K2 = nr_mac->radio_config.minRXTXTIME + get_NTN_Koffset(scc);
|
||||
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
|
||||
const int sched_slot = (slot + K2) % slots_frame;
|
||||
if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot))
|
||||
if (!is_ul_slot(sched_slot, &nr_mac->frame_structure))
|
||||
return false;
|
||||
|
||||
int num_beams = nr_mac->beam_info.beam_allocation ? nr_mac->beam_info.beams_per_period : 1;
|
||||
@@ -2278,7 +2276,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n
|
||||
|
||||
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
|
||||
* because we have to schedule the DCI0 first before schedule uplink data */
|
||||
if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) {
|
||||
if (!is_dl_slot(slot, &nr_mac->frame_structure)) {
|
||||
LOG_D(NR_MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,14 @@ void set_cset_offset(uint16_t);
|
||||
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
|
||||
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
|
||||
int get_ul_slots_per_period(const frame_structure_t *fs);
|
||||
int get_ul_slots_per_frame(const frame_structure_t *fs);
|
||||
int get_dl_slots_per_period(const frame_structure_t *fs);
|
||||
int get_full_ul_slots_per_period(const frame_structure_t *fs);
|
||||
int get_full_dl_slots_per_period(const frame_structure_t *fs);
|
||||
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed);
|
||||
|
||||
void mac_top_init_gNB(ngran_node_t node_type,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_ServingCellConfig_t *scd,
|
||||
@@ -344,7 +352,9 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
|
||||
int binomial(int n, int k);
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
|
||||
bool is_ul_slot(const slot_t slot, const frame_structure_t *fs);
|
||||
bool is_dl_slot(const slot_t slot, const frame_structure_t *fs);
|
||||
bool is_mixed_slot(const slot_t slot, const frame_structure_t *fs);
|
||||
|
||||
/* \brief Function to indicate a received SDU on ULSCH.
|
||||
@param Mod_id Instance ID of gNB
|
||||
@@ -406,13 +416,10 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx);
|
||||
|
||||
uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format);
|
||||
|
||||
void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
const NR_UE_UL_BWP_t *ul_bwp,
|
||||
const NR_ServingCellConfigCommon_t *scc);
|
||||
void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot);
|
||||
int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int frame, int slot);
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot);
|
||||
int get_ul_tda(gNB_MAC_INST *nrmac, int frame, int slot);
|
||||
|
||||
int get_cce_index(const gNB_MAC_INST *nrmac,
|
||||
const int CC_id,
|
||||
|
||||
@@ -72,9 +72,6 @@
|
||||
#include "time_meas.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
|
||||
#define MACSTATSSTRLEN 36256
|
||||
|
||||
void *nrmac_stats_thread(void *arg) {
|
||||
|
||||
@@ -905,13 +905,10 @@ typedef struct gNB_MAC_INST_s {
|
||||
|
||||
NR_beam_info_t beam_info;
|
||||
|
||||
/// bitmap of DLSCH slots, can hold up to 160 slots
|
||||
uint64_t dlsch_slot_bitmap[3];
|
||||
/// bitmap of ULSCH slots, can hold up to 160 slots
|
||||
uint64_t ulsch_slot_bitmap[3];
|
||||
|
||||
/// maximum number of slots before a UE will be scheduled ULSCH automatically
|
||||
uint32_t ulsch_max_frame_inactivity;
|
||||
/// instance of the frame structure configuration
|
||||
frame_structure_t frame_structure;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
#include "openair2/F1AP/f1ap_du_rrc_message_transfer.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
@@ -45,22 +45,11 @@
|
||||
#include "openair2/NR_PHY_INTERFACE/nr_sched_response.h"
|
||||
#include "openair2/PHY_INTERFACE/queue_t.h"
|
||||
#include "utils.h"
|
||||
#include "nfapi/oai_integration/nfapi_pnf.h"
|
||||
|
||||
#define MAX_IF_MODULES 100
|
||||
|
||||
static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
|
||||
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
|
||||
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
|
||||
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
|
||||
extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
|
||||
extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
|
||||
extern int oai_nfapi_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
|
||||
extern int oai_nfapi_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
|
||||
extern int oai_nfapi_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
|
||||
extern int oai_nfapi_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
|
||||
extern int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
|
||||
extern int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
static void handle_nr_rach(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,6 @@ void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot,
|
||||
return;
|
||||
}
|
||||
|
||||
extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
|
||||
float get_bler_val(uint8_t mcs, int sinr)
|
||||
{
|
||||
// 4th col = dropped packets, 5th col = total packets
|
||||
|
||||
@@ -461,7 +461,7 @@ typedef struct UE_RRC_INST_NB_IoT_s {
|
||||
Rrc_State_NB_IoT_t RrcState;
|
||||
Rrc_Sub_State_NB_IoT_t RrcSubState;
|
||||
plmn_t plmnID;
|
||||
Byte_t rat;
|
||||
uint8_t rat;
|
||||
as_nas_info_t initialNasMsg;
|
||||
OAI_UECapability_NB_IoT_t *UECap;
|
||||
uint8_t *UECapability;
|
||||
|
||||
@@ -801,7 +801,7 @@ typedef struct UE_RRC_INST_s {
|
||||
Rrc_State_t RrcState;
|
||||
Rrc_Sub_State_t RrcSubState;
|
||||
plmn_t plmnID;
|
||||
Byte_t rat;
|
||||
uint8_t rat;
|
||||
uint8_t selected_plmn_identity;
|
||||
as_nas_info_t initialNasMsg;
|
||||
OAI_UECapability_t *UECap;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "uper_encoder.h"
|
||||
#include "uper_decoder.h"
|
||||
#include "rrc_defs.h"
|
||||
#include "rrc_proto.h"
|
||||
#include "rrc_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "common/ran_context.h"
|
||||
@@ -104,23 +105,8 @@
|
||||
#define NUMBEROF_DRBS_TOBE_ADDED 1
|
||||
static int encode_CG_ConfigInfo(char *buffer,int buffer_size,rrc_eNB_ue_context_t *const ue_context_pP,int *enc_size);
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
extern eNB_MAC_INST *eNB_mac_inst;
|
||||
extern UE_MAC_INST *UE_mac_inst;
|
||||
|
||||
|
||||
mui_t rrc_eNB_mui = 0;
|
||||
|
||||
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
|
||||
extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP);
|
||||
extern void process_eNB_security_key(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_pP,
|
||||
uint8_t *security_key_pP);
|
||||
extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config,
|
||||
OCTET_STRING_t *scg_RB_config);
|
||||
extern struct rrc_eNB_ue_context_s *get_first_ue_context(eNB_RRC_INST *rrc_instance_pP);
|
||||
|
||||
pthread_mutex_t rrc_release_freelist;
|
||||
RRC_release_list_t rrc_release_info;
|
||||
pthread_mutex_t lock_ue_freelist;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
#include "rrc_defs.h"
|
||||
#include "rrc_proto.h"
|
||||
#include "rrc_extern.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
#include "RRC/LTE/MESSAGES/asn1_msg.h"
|
||||
@@ -396,7 +397,9 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte
|
||||
return INTEGRITY_ALGORITHM_NONE;
|
||||
}
|
||||
|
||||
/*! \fn int rrc_eNB_process_security (uint8_t mod_id, uint8_t ue_index, security_capabilities_t *security_capabilities)
|
||||
/*! \fn int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP,
|
||||
rrc_eNB_ue_context_t *const ue_context_pP,
|
||||
security_capabilities_t *security_capabilities_pP)
|
||||
*\brief save and analyze available security algorithms bit mask and select relevant ones.
|
||||
*\param mod_id Instance ID of eNB.
|
||||
*\param ue_index Instance ID of UE in the eNB.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user