Merge branch 'integration_2024_w41' into 'develop'
Integration: `2024.w41` See merge request oai/openairinterface5g!3032 * !3006 Fix some sizeof and switch-case issues * !3028 Add CMakePresets.json * !3011 Aerial: cleanup unused code, avoid superfluous memcpy(), avoid L1 structures * !3022 NR CSI-RS L1 refactoring → check CI * !2935 Improvements in handling the beamforming procedure via FAPI * !3026 NR ULSCH scheduler fix when using transform precoding * !3031 CI: Increase test bitrates for 100 MHz scenario in SA-2x2 pipeline * !3017 Fix SRS * !2731 Implementation of 2-Step RA * !3027 Add dockerized include what you use tool
This commit is contained in:
@@ -25,3 +25,4 @@ tags
|
||||
nfapi_nr_interface_scf
|
||||
*.log
|
||||
*.out
|
||||
CMakeUserPresets.json
|
||||
|
||||
+2
-4
@@ -1001,7 +1001,7 @@ set(PHY_SRC_UE
|
||||
|
||||
set(PHY_NR_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.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
|
||||
@@ -1033,12 +1033,12 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_freq_equalization.c
|
||||
${OPENAIR1_DIR}/PHY/NR_ESTIMATION/nr_measurements_gNB.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
#${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
|
||||
@@ -1093,7 +1093,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
# ${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c
|
||||
@@ -1104,7 +1103,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
|
||||
# ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
|
||||
${PHY_POLARSRC}
|
||||
${PHY_SMALLBLOCKSRC}
|
||||
${PHY_NR_CODINGIF}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default Config",
|
||||
"description": "Default build using Ninja generator",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/cmake_targets/ran_build/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tests",
|
||||
"displayName": "Default unit test config",
|
||||
"inherits": "default",
|
||||
"binaryDir": "${sourceDir}/cmake_targets/ran_build/build_test",
|
||||
"cacheVariables": {
|
||||
"ENABLE_TESTS": "ON",
|
||||
"SANITIZE_ADDRESS": "ON",
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "5gdefault",
|
||||
"configurePreset": "default",
|
||||
"targets": [
|
||||
"nr-uesoftmodem",
|
||||
"nr-softmodem",
|
||||
"rfsimulator",
|
||||
"dfts",
|
||||
"ldpc",
|
||||
"params_libconfig",
|
||||
"params_yaml"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "default",
|
||||
"inherits": "5gdefault"
|
||||
},
|
||||
{
|
||||
"name": "4gdefault",
|
||||
"configurePreset": "default",
|
||||
"targets": [
|
||||
"lte-softmodem",
|
||||
"lte-uesoftmodem",
|
||||
"dfts",
|
||||
"coding",
|
||||
"rfsimulator",
|
||||
"params_libconfig"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tests",
|
||||
"configurePreset": "tests",
|
||||
"targets": [
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -76,7 +76,8 @@ openairinterface5g
|
||||
├── openair3 : Layer 3 (3GPP LTE Rel-10 S1AP/GTP, NR Rel-15 NGAP/GTP)
|
||||
├── openshift : OpenShift helm charts for some deployment options of OAI
|
||||
├── radio : Drivers for various radios such as USRP, AW2S, RFsim, 7.2 FHI, ...
|
||||
└── targets : Some configuration files; only historical relevance, and might be deleted in the future
|
||||
├── targets : Some configuration files; only historical relevance, and might be deleted in the future
|
||||
└── tools : Tools for use by the developers/ci machines: code analysis and formatting
|
||||
```
|
||||
|
||||
# How to get support from the OAI Community #
|
||||
|
||||
@@ -198,8 +198,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -195,8 +195,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 108;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -198,8 +198,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -200,8 +200,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -187,15 +187,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
|
||||
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
|
||||
clock_src = "external";
|
||||
# if_freq = 3700000000L;
|
||||
|
||||
@@ -198,15 +198,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 50;
|
||||
eNB_instances = [0];
|
||||
## beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
## beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
#bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
|
||||
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -198,15 +198,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 50;
|
||||
eNB_instances = [0];
|
||||
## beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
## beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
#bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
|
||||
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -191,7 +191,6 @@ RUs = ({
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 50;
|
||||
eNB_instances = [0];
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
|
||||
});
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ RUs = ({
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 50;
|
||||
eNB_instances = [0];
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
|
||||
});
|
||||
|
||||
|
||||
@@ -211,7 +211,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
bf_weights = [0x00007fff, 0x00007fff];
|
||||
#clock_src = "external";
|
||||
sf_extension = 0
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
|
||||
@@ -23,7 +23,8 @@ gNBs =
|
||||
|
||||
sib1_tda = 15;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
beam_weights = [0]; // single SSB -> one analog beam
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
@@ -177,6 +178,9 @@ MACRLCs = ({
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
set_analog_beamforming = 1;
|
||||
beam_duration = 1;
|
||||
beams_per_period = 1;
|
||||
});
|
||||
|
||||
L1s = (
|
||||
|
||||
@@ -203,8 +203,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -216,14 +216,6 @@ RUs = (
|
||||
max_rxgain = 114;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sdr_addrs = "type=x300";
|
||||
clock_src = "internal";
|
||||
# if_freq = 3700000000L;
|
||||
|
||||
@@ -203,14 +203,6 @@ RUs = (
|
||||
max_rxgain = 114;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sdr_addrs = "type=x300";
|
||||
clock_src = "internal";
|
||||
# if_freq = 3700000000L;
|
||||
|
||||
@@ -212,8 +212,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
#clock_src = "internal";
|
||||
sdr_addrs = "addr=192.168.80.53, clock_source=internal,time_source=internal"
|
||||
|
||||
|
||||
@@ -220,8 +220,6 @@ RUs = (
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 5;
|
||||
sl_ahead = 5;
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000,0x00007fff, 0x0000];
|
||||
clock_src = "internal";
|
||||
tr_preference = "raw_if4p5"; # important: activate FHI7.2
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
|
||||
@@ -23,7 +23,6 @@ gNBs = (
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
ul_prbblacklist = "135,136,137,138"
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
@@ -177,8 +176,8 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
pusch_TargetSNRx10 = 270;
|
||||
pucch_TargetSNRx10 = 270;
|
||||
pusch_FailureThres = 1000;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
ul_max_mcs = 25;
|
||||
@@ -200,14 +199,12 @@ RUs = (
|
||||
local_rf = "yes"
|
||||
nb_tx = 2;
|
||||
nb_rx = 2;
|
||||
att_tx = 12;
|
||||
att_tx = 15;
|
||||
att_rx = 0;
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 72;
|
||||
max_rxgain = 71;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
#clock_src = "internal";
|
||||
sdr_addrs = "addr=192.168.80.53,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -211,8 +211,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 65;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "addr=192.168.80.52,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -205,14 +205,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "serial=XXXXXXX"
|
||||
}
|
||||
|
||||
@@ -266,8 +266,6 @@ RUs = ({
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
});
|
||||
|
||||
|
||||
@@ -166,14 +166,6 @@ RUs:
|
||||
max_pdschReferenceSignalPower: -27
|
||||
max_rxgain: 75
|
||||
eNB_instances: [0]
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights: [0x00007fff, 0x0000]
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension: 0
|
||||
sdr_addrs: serial=XXXXXXX
|
||||
|
||||
|
||||
@@ -204,14 +204,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 68;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ MACRLCs = (
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ul_prbblack_SNR_threshold = 10;
|
||||
ul_max_mcs = 9;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -200,8 +199,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -217,14 +217,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 68;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
sl_ahead = 5;
|
||||
|
||||
@@ -218,14 +218,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -203,8 +203,6 @@ RUs = (
|
||||
max_rxgain = 114;
|
||||
sf_extension = 0;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -227,8 +227,6 @@ RUs = (
|
||||
eNB_instances = [0];
|
||||
ru_thread_core = 5;
|
||||
sl_ahead = 10;
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000,0x00007fff, 0x0000];
|
||||
tr_preference = "raw_if4p5"; # important: activate FHI7.2
|
||||
do_precoding = 0; # needs to match O-RU configuration
|
||||
}
|
||||
|
||||
@@ -199,8 +199,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
#clock_src = "internal";
|
||||
sdr_addrs = "mgmt_addr=192.168.10.2,addr=192.168.10.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -219,14 +219,6 @@ RUs = (
|
||||
eNB_instances = [0];
|
||||
bands = [78];
|
||||
sl_ahead = 5;
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -219,14 +219,6 @@ RUs = (
|
||||
eNB_instances = [0];
|
||||
bands = [78];
|
||||
sl_ahead = 5;
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -199,8 +199,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -217,15 +217,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
);
|
||||
|
||||
@@ -213,15 +213,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
);
|
||||
|
||||
@@ -221,14 +221,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
##beamforming 1x2 matrix: 1 layer x 2 antennas
|
||||
bf_weights = [0x00007fff, 0x0000];
|
||||
##beamforming 1x4 matrix: 1 layer x 4 antennas
|
||||
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
|
||||
## beamforming 2x2 matrix:
|
||||
# bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
|
||||
## beamforming 4x4 matrix:
|
||||
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
|
||||
sf_extension = 0
|
||||
sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal"
|
||||
}
|
||||
|
||||
@@ -203,8 +203,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 75;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -201,8 +201,6 @@ RUs = (
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
#beamforming 1x4 matrix:
|
||||
bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
|
||||
clock_src = "internal";
|
||||
}
|
||||
);
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
|
||||
<testCase id="071100">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/600Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 600M -t 30 -R -O 10 -l 9000</iperf_args>
|
||||
<desc>iperf (DL/650Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 650M -t 30 -R -O 10 -l 9000</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -124,12 +124,12 @@
|
||||
|
||||
<testCase id="071101">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/40Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 40M -t 30 -O 10</iperf_args>
|
||||
<desc>iperf (UL/130Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 130M -t 30 -O 10</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>70</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="071002">
|
||||
|
||||
@@ -150,8 +150,8 @@
|
||||
|
||||
<testCase id="270001">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/6Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 6M -t 30</iperf_args>
|
||||
<desc>iperf (UL/18Mbps/UDP)(30 sec)</desc>
|
||||
<iperf_args>-u -b 18M -t 30</iperf_args>
|
||||
<id>idefix</id>
|
||||
<svr_id>sabox-nepes</svr_id>
|
||||
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
|
||||
|
||||
@@ -387,7 +387,8 @@
|
||||
(Test10: PUSCH Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
|
||||
(Test11: 25 PRBs, 15 kHz SCS),
|
||||
(Test12: MCS 0, low SNR performance)
|
||||
(Test13: MCS 28, 106 PRBs, Time shift 8)</desc>
|
||||
(Test13: MCS 28, 106 PRBs, Time shift 8)
|
||||
(Test14: SRS, SNR 40 dB)</desc>
|
||||
<main_exec>nr_ulsim</main_exec>
|
||||
<main_exec_args>-n100 -m9 -r106 -s5
|
||||
-n100 -m16 -s10
|
||||
@@ -401,8 +402,9 @@
|
||||
-n100 -s5 -a4 -b8 -T 1,2 -U 1,3,1,1
|
||||
-n100 -u0 -m0 -R25 -r25 -i 1,0
|
||||
-n100 -m0 -S -0.6 -i 1,0
|
||||
-n100 -m 28 -R106 -r106 -t90 -s24 -S24 -d 8</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13</tags>
|
||||
-n100 -m 28 -R106 -r106 -t90 -s24 -S24 -d 8
|
||||
-n100 -s40 -E 1</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14</tags>
|
||||
<search_expr_true>PUSCH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "PHY/defs_common.h"
|
||||
|
||||
#define NR_MAX_PDSCH_TBS 3824
|
||||
#define MAX_NUM_BEAM_PERIODS 4
|
||||
#define MAX_BWP_SIZE 275
|
||||
#define NR_MAX_NUM_BWP 4
|
||||
#define NR_MAX_HARQ_PROCESSES 32
|
||||
@@ -53,6 +54,7 @@
|
||||
R(TYPE_P_RNTI_) /* Paging RNTI */ \
|
||||
R(TYPE_SI_RNTI_) /* System information RNTI */ \
|
||||
R(TYPE_RA_RNTI_) /* Random Access RNTI */ \
|
||||
R(TYPE_MSGB_RNTI_) /* Random Access MsgB RNTI */ \
|
||||
R(TYPE_SP_CSI_RNTI_) /* Semipersistent CSI reporting on PUSCH */ \
|
||||
R(TYPE_SFI_RNTI_) /* Slot Format Indication on the given cell */ \
|
||||
R(TYPE_INT_RNTI_) /* Indication pre-emption in DL */ \
|
||||
|
||||
+3
-10
@@ -154,17 +154,10 @@ static inline uint16_t BIT_STRING_to_uint16(const BIT_STRING_t *asn) {
|
||||
|
||||
DevCheck ((asn->size > 0) && (asn->size <= 2), asn->size, 0, 0);
|
||||
|
||||
switch (asn->size) {
|
||||
case 2:
|
||||
result |= asn->buf[index++] << (8 - asn->bits_unused);
|
||||
|
||||
case 1:
|
||||
result |= asn->buf[index] >> asn->bits_unused;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (asn->size == 2) {
|
||||
result |= asn->buf[index++] << (8 - asn->bits_unused);
|
||||
}
|
||||
result |= asn->buf[index] >> asn->bits_unused;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -217,6 +217,30 @@ cmake-gui ../../..
|
||||
```
|
||||
You can of course use all standard cmake/ninja/make commands in this directory.
|
||||
|
||||
## cmake presets
|
||||
|
||||
CMake presets are common project configure options. See https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||
|
||||
Configure presets:
|
||||
|
||||
- `default`: Configure compilation with default options
|
||||
- `tests`: Same as above but ENABLE_TESTS and SANITIZE_ADDRESS is ON
|
||||
|
||||
Build presets:
|
||||
|
||||
- `5gdefault`: Build the software for NR rfsimulator test
|
||||
- `default`: same as 5gdefault
|
||||
- `4gdefault`: Build the software for LTE rfsimulator test
|
||||
- `tests`: build all unit tests
|
||||
|
||||
To configure using configuration preset:
|
||||
|
||||
cmake --preset <preset_name>
|
||||
|
||||
To build using a build preset:
|
||||
|
||||
cmake --build --preset <preset_name>
|
||||
|
||||
# Cross Compile
|
||||
|
||||
If you want to use cross-compiler on x86 platform for aarch64 version, please refer the [cross-compile.md](./cross-compile.md) for more information.
|
||||
|
||||
+21
-7
@@ -105,10 +105,18 @@ These modes of operation are supported:
|
||||
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
|
||||
- Scheduler procedures for SIB1
|
||||
- Scheduler procedures for RA
|
||||
- Contention Free RA procedure
|
||||
- Contention Based RA procedure
|
||||
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
|
||||
- CBRA can be performed using MAC CE or C-RNTI
|
||||
- 4-Step RA
|
||||
- Contention Free RA procedure
|
||||
- Contention Based RA procedure
|
||||
- Msg3 can transfer uplink CCCH, DTCH or DCCH messages
|
||||
- CBRA can be performed using MAC CE for C-RNTI
|
||||
- Is not possible to use 2-Step RA and 4-Step RA at the same time
|
||||
- 2-Step RA
|
||||
- Contention Based RA procedure
|
||||
- MsgA can transfer uplink CCCH, DTCH or DCCH messages
|
||||
- CBRA can be performed using MAC CE for C-RNTI
|
||||
- Is not possible to use 2-Step RA and 4-Step RA at the same time
|
||||
- Fallback not supported
|
||||
- Scheduler procedures for CSI-RS
|
||||
- MAC downlink scheduler
|
||||
- phy-test scheduler (fixed allocation and usable also without UE)
|
||||
@@ -310,9 +318,15 @@ These modes of operation are supported:
|
||||
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
|
||||
- Mapping SSBs to multiple ROs
|
||||
- Scheduling of PRACH
|
||||
- Processing of RAR
|
||||
- Transmission and re-transmission of Msg3
|
||||
- Msg4 and contention resolution
|
||||
- 4-Step RA
|
||||
- Processing of RAR
|
||||
- Transmission and re-transmission of Msg3
|
||||
- Msg4 and contention resolution
|
||||
- 2-Step RA
|
||||
- Transmission of MsgA-PUSCH
|
||||
- Reception of MsgB
|
||||
- Processing of SuccessRAR
|
||||
- Fallback not supported
|
||||
* DCI processing
|
||||
- format 10 (RA-RNTI, C-RNTI, SI-RNTI, TC-RNTI)
|
||||
- format 00 (C-RNTI, TC-RNTI)
|
||||
|
||||
@@ -115,3 +115,8 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
|
||||
|
||||
- [UnitTests.md](./UnitTests.md) explains the unit testing setup
|
||||
- [TESTBenches.md](./TESTBenches.md) lists the CI setup and links to pipelines
|
||||
|
||||
# Developer tools
|
||||
|
||||
- [formatting](../tools/formatting/README.md) is a clang-format error detection tool
|
||||
- [iwyu](../tools/iwyu/README.md) is a tool to detect `#include` errors
|
||||
|
||||
@@ -54,7 +54,8 @@ RUN /bin/sh oaienv && \
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai -w AERIAL --gNB --ninja
|
||||
./build_oai -c -w AERIAL --gNB --ninja \
|
||||
--cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror"
|
||||
|
||||
|
||||
#start from scratch for target executable
|
||||
|
||||
+17
-18
@@ -128,7 +128,7 @@ static void tx_func(processingData_L1tx_t *info)
|
||||
|
||||
// At this point, MAC scheduler just ran, including scheduling
|
||||
// PRACH/PUCCH/PUSCH, so trigger RX chain processing
|
||||
LOG_D(NR_PHY, "%s() trigger RX for %d.%d\n", __func__, frame_rx, slot_rx);
|
||||
LOG_D(NR_PHY, "Trigger RX for %d.%d\n", frame_rx, slot_rx);
|
||||
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->resp_L1, NULL);
|
||||
processingData_L1_t *syncMsg = NotifiedFifoData(res);
|
||||
syncMsg->gNB = gNB;
|
||||
@@ -229,15 +229,17 @@ static void rx_func(processingData_L1_t *info)
|
||||
if (gNB->phase_comp) {
|
||||
//apply the rx signal rotation here
|
||||
int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
|
||||
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
|
||||
apply_nr_rotation_RX(&gNB->frame_parms,
|
||||
gNB->common_vars.rxdataF[aa],
|
||||
gNB->frame_parms.symbol_rotation[1],
|
||||
slot_rx,
|
||||
gNB->frame_parms.N_RB_UL,
|
||||
soffset,
|
||||
0,
|
||||
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14);
|
||||
for (int bb = 0; bb < gNB->common_vars.num_beams_period; bb++) {
|
||||
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
|
||||
apply_nr_rotation_RX(&gNB->frame_parms,
|
||||
gNB->common_vars.rxdataF[bb][aa],
|
||||
gNB->frame_parms.symbol_rotation[1],
|
||||
slot_rx,
|
||||
gNB->frame_parms.N_RB_UL,
|
||||
soffset,
|
||||
0,
|
||||
gNB->frame_parms.Ncp == EXTENDED ? 12 : 14);
|
||||
}
|
||||
}
|
||||
}
|
||||
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
|
||||
@@ -417,17 +419,14 @@ void init_eNB_afterRU(void) {
|
||||
LOG_I(PHY,"gNB->num_RU:%d\n", gNB->num_RU);
|
||||
|
||||
for (ru_id=0,aa=0; ru_id<gNB->num_RU; ru_id++) {
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF!=NULL,
|
||||
"RU %d : common.rxdataF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF!=NULL,
|
||||
"RU %d : prach_rxsigF is NULL\n",
|
||||
gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->common.rxdataF != NULL, "RU %d : common.rxdataF is NULL\n", gNB->RU_list[ru_id]->idx);
|
||||
AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF != NULL, "RU %d : prach_rxsigF is NULL\n", gNB->RU_list[ru_id]->idx);
|
||||
|
||||
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
|
||||
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
|
||||
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i];
|
||||
gNB->common_vars.rxdataF[aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i];
|
||||
// TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
gNB->common_vars.rxdataF[0][aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+46
-96
@@ -58,8 +58,6 @@ static int DEFBANDS[] = {7};
|
||||
static int DEFENBS[] = {0};
|
||||
static int DEFBFW[] = {0x00007fff};
|
||||
static int DEFRUTPCORES[] = {-1,-1,-1,-1};
|
||||
//static int DEFNRBANDS[] = {7};
|
||||
//static int DEFGNBS[] = {0};
|
||||
|
||||
#include "ENB_APP/enb_paramdef.h"
|
||||
#include "GNB_APP/gnb_paramdef.h"
|
||||
@@ -540,9 +538,11 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx );
|
||||
}
|
||||
|
||||
if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx);
|
||||
if (ru->feptx_ofdm)
|
||||
ru->feptx_ofdm(ru, frame_tx, slot_tx);
|
||||
|
||||
if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx);
|
||||
if (ru->fh_south_out)
|
||||
ru->fh_south_out(ru, frame_tx, slot_tx, proc->timestamp_tx);
|
||||
}
|
||||
|
||||
void fh_if5_north_out(RU_t *ru) {
|
||||
@@ -717,7 +717,7 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot)
|
||||
|
||||
if (ru->common.beam_id) {
|
||||
int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame;
|
||||
const uint8_t *beam_ids = ru->common.beam_id[0];
|
||||
const int *beam_ids = ru->common.beam_id[0];
|
||||
int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot];
|
||||
int beam = beam_ids[slot * fp->symbols_per_slot];
|
||||
if (prev_beam != beam) {
|
||||
@@ -748,12 +748,12 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot)
|
||||
return flags_gpio;
|
||||
}
|
||||
|
||||
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
|
||||
void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
{
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->config;
|
||||
void *txp[ru->nb_tx];
|
||||
unsigned int txs;
|
||||
int i;
|
||||
T(T_ENB_PHY_OUTPUT_SIGNAL,
|
||||
T_INT(0),
|
||||
@@ -809,7 +809,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
|
||||
flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE;
|
||||
}
|
||||
|
||||
if (fp->freq_range == FR2)
|
||||
if (ru->openair0_cfg.gpio_controller != RU_GPIO_CONTROL_NONE)
|
||||
flags_gpio = get_gpio_flags(ru, slot);
|
||||
|
||||
const int flags = flags_burst | (flags_gpio << 4);
|
||||
@@ -827,8 +827,11 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp + ru->ts_offset) & 0xffffffff);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1);
|
||||
// prepare tx buffer pointers
|
||||
txs = ru->rfdevice
|
||||
.trx_write_func(&ru->rfdevice, timestamp + ru->ts_offset - sf_extension, txp, siglen + sf_extension, ru->nb_tx, flags);
|
||||
uint32_t txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
timestamp + ru->ts_offset - sf_extension,
|
||||
txp,
|
||||
siglen + sf_extension,
|
||||
ru->nb_tx, flags);
|
||||
LOG_D(PHY,
|
||||
"[TXPATH] RU %d aa %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, "
|
||||
"returned %d, E %f\n",
|
||||
@@ -1031,7 +1034,8 @@ void *ru_stats_thread(void *param) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void ru_tx_func(void *param) {
|
||||
void ru_tx_func(void *param)
|
||||
{
|
||||
processingData_RU_t *info = (processingData_RU_t *) param;
|
||||
RU_t *ru = info->ru;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
@@ -1039,7 +1043,7 @@ void ru_tx_func(void *param) {
|
||||
int slot_tx = info->slot_tx;
|
||||
int print_frame = 8;
|
||||
char filename[40];
|
||||
|
||||
|
||||
int cumul_samples = fp->get_samples_per_slot(0, fp);
|
||||
int i = 1;
|
||||
for (; i < fp->slots_per_subframe / 2; i++)
|
||||
@@ -1050,10 +1054,12 @@ void ru_tx_func(void *param) {
|
||||
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]);
|
||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||
if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx);
|
||||
if (ru->feptx_prec)
|
||||
ru->feptx_prec(ru,frame_tx,slot_tx);
|
||||
|
||||
// do OFDM with/without TX front-end processing if needed
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx);
|
||||
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm))
|
||||
ru->feptx_ofdm(ru, frame_tx, slot_tx);
|
||||
|
||||
if(!emulate_rf) {
|
||||
// do outgoing fronthaul (south) if needed
|
||||
@@ -1100,7 +1106,8 @@ void ru_tx_func(void *param) {
|
||||
LOG_D(PHY,"rt_prof_idx %d : RU_TX time %d\n",rt_prof_idx,(int)(1e9 * (t1->tv_sec - t0->tv_sec) + (t1->tv_nsec-t0->tv_nsec)));
|
||||
}
|
||||
|
||||
void *ru_thread( void *param ) {
|
||||
void *ru_thread(void *param)
|
||||
{
|
||||
static int ru_thread_status;
|
||||
RU_t *ru = (RU_t *)param;
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
@@ -1333,11 +1340,11 @@ void *ru_thread( void *param ) {
|
||||
|
||||
// Do PRACH RU processing
|
||||
int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST);
|
||||
if (prach_id>=0) {
|
||||
if (prach_id >= 0) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
|
||||
|
||||
T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0),
|
||||
T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
|
||||
T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
|
||||
int N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
|
||||
|
||||
for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
|
||||
@@ -1348,11 +1355,12 @@ void *ru_thread( void *param ) {
|
||||
ru->prach_list[prach_id].numRA,
|
||||
prachStartSymbol,
|
||||
prach_oc,
|
||||
proc->frame_rx,proc->tti_rx);
|
||||
proc->frame_rx,
|
||||
proc->tti_rx);
|
||||
}
|
||||
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx]);
|
||||
free_nr_ru_prach_entry(ru,prach_id);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0);
|
||||
} // end if (prach_id > 0)
|
||||
} // end if (ru->feprx)
|
||||
else {
|
||||
@@ -1602,38 +1610,8 @@ void configure_rru(void *ruu, void *arg)
|
||||
nr_phy_init_RU(ru);
|
||||
}
|
||||
|
||||
/*
|
||||
void init_precoding_weights(PHY_VARS_gNB *gNB) {
|
||||
|
||||
int layer,ru_id,aa,re,ue,tb;
|
||||
LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
RU_t *ru;
|
||||
LTE_gNB_DLSCH_t *dlsch;
|
||||
|
||||
// init precoding weigths
|
||||
for (ue=0;ue<NUMBER_OF_UE_MAX;ue++) {
|
||||
for (tb=0;tb<2;tb++) {
|
||||
dlsch = gNB->dlsch[ue][tb];
|
||||
for (layer=0; layer<4; layer++) {
|
||||
int nb_tx=0;
|
||||
for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
|
||||
ru = RC.ru[ru_id];
|
||||
nb_tx+=ru->nb_tx;
|
||||
}
|
||||
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(nb_tx*sizeof(int32_t*));
|
||||
|
||||
for (aa=0; aa<nb_tx; aa++) {
|
||||
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
for (re=0;re<fp->ofdm_symbol_size; re++) {
|
||||
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void set_function_spec_param(RU_t *ru) {
|
||||
void set_function_spec_param(RU_t *ru)
|
||||
{
|
||||
switch (ru->if_south) {
|
||||
case LOCAL_RF: // this is an RU with integrated RF (RRU, gNB)
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
@@ -1782,20 +1760,19 @@ void init_NR_RU(configmodule_interface_t *cfg, char *rf_config_file)
|
||||
}
|
||||
}
|
||||
|
||||
gNB_RC = RC.gNB[0];
|
||||
gNB0 = ru->gNB_list[0];
|
||||
fp = ru->nr_frame_parms;
|
||||
gNB_RC = RC.gNB[0];
|
||||
gNB0 = ru->gNB_list[0];
|
||||
fp = ru->nr_frame_parms;
|
||||
LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
|
||||
|
||||
if (gNB0) {
|
||||
if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
|
||||
AssertFatal(gNB0!=NULL,"gNB0 is null!\n");
|
||||
AssertFatal(gNB0, "gNB0 is null!\n");
|
||||
|
||||
if (gNB0 && gNB_RC) {
|
||||
LOG_I(PHY,"Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n",gNB0->Mod_id,ru->idx);
|
||||
memset((void *)fp, 0, sizeof(NR_DL_FRAME_PARMS));
|
||||
memcpy((void *)fp,&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
memcpy((void *)&gNB0->frame_parms,(void *)&gNB_RC->frame_parms,sizeof(NR_DL_FRAME_PARMS));
|
||||
LOG_I(PHY,"Copying frame parms from gNB in RC to gNB %d in ru %d and frame_parms in ru\n", gNB0->Mod_id, ru->idx);
|
||||
memcpy((void *)fp, &gNB_RC->frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
memcpy((void *)&gNB0->frame_parms, (void *)&gNB_RC->frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
// attach all RU to all gNBs in its list/
|
||||
LOG_D(PHY,"ru->num_gNB:%d gNB0->num_RU:%d\n", ru->num_gNB, gNB0->num_RU);
|
||||
|
||||
@@ -1851,39 +1828,26 @@ void stop_RU(int nb_ru) {
|
||||
static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
{
|
||||
paramdef_t RUParams[] = RUPARAMS_DESC;
|
||||
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
|
||||
paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST, NULL, 0};
|
||||
config_getlist(cfg, &RUParamList, RUParams, sizeofArray(RUParams), NULL);
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0};
|
||||
config_get(cfg, GNBSParams, sizeofArray(GNBSParams), NULL);
|
||||
int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
AssertFatal(num_gnbs > 0, "Failed to parse config file no gnbs %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS);
|
||||
config_getlist(cfg, &GNBParamList, GNBParams, sizeofArray(GNBParams), NULL);
|
||||
int N1 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr;
|
||||
int N2 = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr;
|
||||
int XP = *GNBParamList.paramarray[0][GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr;
|
||||
int num_logical_antennas = N1 * N2 * XP;
|
||||
|
||||
if (RUParamList.numelt > 0) {
|
||||
RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *));
|
||||
RC.ru_mask = (1 << NB_RU) - 1;
|
||||
printf("Set RU mask to %lx\n",RC.ru_mask);
|
||||
|
||||
for (int j = 0; j < RC.nb_RU; j++) {
|
||||
RC.ru[j] = (RU_t *)malloc(sizeof(RU_t));
|
||||
memset((void *)RC.ru[j],0,sizeof(RU_t));
|
||||
RC.ru[j]->idx = j;
|
||||
RC.ru[j]->nr_frame_parms = (NR_DL_FRAME_PARMS *)malloc(sizeof(NR_DL_FRAME_PARMS));
|
||||
RC.ru[j]->frame_parms = (LTE_DL_FRAME_PARMS *)malloc(sizeof(LTE_DL_FRAME_PARMS));
|
||||
RC.ru[j] = calloc(1, sizeof(*RC.ru[j]));
|
||||
RC.ru[j]->idx = j;
|
||||
RC.ru[j]->nr_frame_parms = calloc(1, sizeof(*RC.ru[j]->nr_frame_parms));
|
||||
RC.ru[j]->frame_parms = calloc(1, sizeof(*RC.ru[j]->frame_parms));
|
||||
printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]);
|
||||
RC.ru[j]->if_timing = synch_to_ext_device;
|
||||
RC.ru[j]->if_timing = synch_to_ext_device;
|
||||
|
||||
if (RC.nb_nr_L1_inst > 0)
|
||||
RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
|
||||
RC.ru[j]->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
|
||||
else
|
||||
RC.ru[j]->num_gNB = 0;
|
||||
RC.ru[j]->num_gNB = 0;
|
||||
|
||||
for (int i = 0; i < RC.ru[j]->num_gNB; i++)
|
||||
RC.ru[j]->gNB_list[i] = RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]];
|
||||
@@ -1904,10 +1868,8 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
"bad GPIO controller in configuration file: '%s'\n",
|
||||
*(RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr));
|
||||
}
|
||||
} else {
|
||||
RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC;
|
||||
LOG_I(PHY, "RU GPIO control set as 'generic'\n");
|
||||
}
|
||||
} else
|
||||
RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_NONE;
|
||||
|
||||
if (config_isparamset(RUParamList.paramarray[j], RU_TX_SUBDEV)) {
|
||||
RC.ru[j]->openair0_cfg.tx_subdev = strdup(*(RUParamList.paramarray[j][RU_TX_SUBDEV].strptr));
|
||||
@@ -2032,14 +1994,11 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
} /* strcmp(local_rf, "yes") != 0 */
|
||||
|
||||
RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
|
||||
AssertFatal(RC.ru[j]->nb_tx >= num_logical_antennas,
|
||||
"Number of logical antenna ports (set in config file with pdsch_AntennaPorts) cannot be larger than physical antennas (nb_tx)\n");
|
||||
RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
|
||||
RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr);
|
||||
RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr);
|
||||
RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr);
|
||||
RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr);
|
||||
RC.ru[j]->do_precoding = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr);
|
||||
RC.ru[j]->sl_ahead = *(RUParamList.paramarray[j][RU_SL_AHEAD].iptr);
|
||||
RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
|
||||
for (int i = 0; i < RC.ru[j]->num_bands; i++)
|
||||
@@ -2057,15 +2016,6 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg)
|
||||
AssertFatal(RC.ru[j]->num_tpcores <= RUParamList.paramarray[j][RU_TP_CORES].numelt, "Number of TP cores should be <=16\n");
|
||||
for (int i = 0; i < RC.ru[j]->num_tpcores; i++)
|
||||
RC.ru[j]->tpcores[i] = RUParamList.paramarray[j][RU_TP_CORES].iptr[i];
|
||||
if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) {
|
||||
RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt;
|
||||
|
||||
for (int i = 0; i < RC.ru[j]->num_gNB; i++) {
|
||||
RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t));
|
||||
for (int b = 0; b < RC.ru[j]->nb_bfw; b++)
|
||||
RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b];
|
||||
}
|
||||
}
|
||||
}// j=0..num_rus
|
||||
} else {
|
||||
RC.nb_RU = 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ if (OAI_AERIAL)
|
||||
else ()
|
||||
message(STATUS " nvlog library found in ${NVLOG_LIB}")
|
||||
endif ()
|
||||
target_compile_definitions(aerial_lib PUBLIC ENABLE_L2_SLT_RSP ENABLE_AERIAL)
|
||||
target_compile_definitions(aerial_lib PUBLIC ENABLE_L2_SLT_RSP)
|
||||
target_link_libraries(aerial_lib PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(aerial_lib PRIVATE nr_fapi_p5)
|
||||
target_link_libraries(aerial_lib PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}")
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
@@ -79,39 +79,8 @@ static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *p_cpu_data = NULL;
|
||||
if (msg->data_buf != NULL) {
|
||||
int gpu;
|
||||
if (msg->data_pool == NV_IPC_MEMPOOL_CUDA_DATA) {
|
||||
gpu = 1;
|
||||
} else {
|
||||
gpu = 0;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
// Test CUDA: call CUDA functions to change all string to lower case
|
||||
test_cuda_to_lower_case(test_cuda_device_id, msg->data_buf, TEST_DATA_BUF_LEN, gpu);
|
||||
#endif
|
||||
|
||||
if (gpu) {
|
||||
p_cpu_data = cpu_buf_recv;
|
||||
memset(cpu_buf_recv, 0, RECV_BUF_LEN);
|
||||
ipc->cuda_memcpy_to_host(ipc, p_cpu_data, msg->data_buf, RECV_BUF_LEN);
|
||||
} else {
|
||||
p_cpu_data = msg->data_buf;
|
||||
}
|
||||
}
|
||||
|
||||
int messageBufLen = msg->msg_len;
|
||||
int dataBufLen = msg->data_len;
|
||||
uint8_t msgbuf[messageBufLen];
|
||||
uint8_t databuf[dataBufLen];
|
||||
memcpy(msgbuf, msg->msg_buf, messageBufLen);
|
||||
memcpy(databuf, msg->data_buf, dataBufLen);
|
||||
uint8_t *pReadPackedMessage = msgbuf;
|
||||
uint8_t *pReadData = databuf;
|
||||
uint8_t *end = msgbuf + messageBufLen;
|
||||
uint8_t *data_end = databuf + dataBufLen;
|
||||
uint8_t *pReadPackedMessage = msg->msg_buf;
|
||||
uint8_t *end = msg->msg_buf + msg->msg_len;
|
||||
|
||||
// unpack FAPI messages and handle them
|
||||
if (vnf_config != 0) {
|
||||
@@ -209,6 +178,9 @@ static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
|
||||
}
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
|
||||
uint8_t *pReadData = msg->data_buf;
|
||||
int dataBufLen = msg->data_len;
|
||||
uint8_t *data_end = msg->data_buf + dataBufLen;
|
||||
nfapi_nr_rx_data_indication_t ind;
|
||||
ind.header.message_id = fapi_msg.message_id;
|
||||
ind.header.message_length = fapi_msg.message_length;
|
||||
@@ -652,11 +624,7 @@ int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_trans
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef NVIPC_CUDA_ENABLE
|
||||
int test_cuda_device_id = get_cuda_device_id();
|
||||
#else
|
||||
int test_cuda_device_id = -1;
|
||||
#endif
|
||||
LOG_D(NFAPI_VNF,"CUDA device ID configured : %d \n", test_cuda_device_id);
|
||||
config->transport_config.shm.cuda_device_id = test_cuda_device_id;
|
||||
if (test_cuda_device_id >= 0) {
|
||||
@@ -686,4 +654,3 @@ int nvIPC_Init(nvipc_params_t nvipc_params_s)
|
||||
aerial_pnf_nr_connection_indication_cb(vnf_config, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#define OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
|
||||
@@ -37,9 +36,10 @@
|
||||
#include "nv_ipc_utils.h"
|
||||
#include "nvlog.h"
|
||||
#include "nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h"
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_msg;
|
||||
uint8_t opaque_handle;
|
||||
@@ -55,7 +55,6 @@ int aerial_send_P7_msg_with_data(void *packedBuf,
|
||||
uint32_t dataLength,
|
||||
nfapi_p7_message_header_t *header);
|
||||
void set_config(nfapi_vnf_config_t *conf);
|
||||
int nvIPC_Init(nvipc_params_t);
|
||||
int nvIPC_Init(nvipc_params_t nvipc_params_s);
|
||||
|
||||
#endif // OPENAIRINTERFACE_FAPI_NVIPC_H
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
|
||||
#include "fapi_vnf_p5.h"
|
||||
#include "fapi_vnf_p7.h"
|
||||
#include "nfapi/open-nFAPI/vnf/inc/vnf_p7.h"
|
||||
@@ -53,19 +53,19 @@ void *aerial_vnf_nr_p7_config_init(void *ptr)
|
||||
init_queue(&gnb_slot_ind_queue);
|
||||
|
||||
p7_vnf->config->port = p7_vnf->local_port;
|
||||
p7_vnf->config->sync_indication = &aerial_phy_sync_indication;
|
||||
p7_vnf->config->slot_indication = &aerial_phy_slot_indication;
|
||||
p7_vnf->config->harq_indication = &aerial_phy_harq_indication;
|
||||
p7_vnf->config->sync_indication = NULL;
|
||||
p7_vnf->config->slot_indication = NULL;
|
||||
p7_vnf->config->harq_indication = NULL;
|
||||
p7_vnf->config->nr_crc_indication = &aerial_phy_nr_crc_indication;
|
||||
p7_vnf->config->nr_rx_data_indication = &aerial_phy_nr_rx_data_indication;
|
||||
p7_vnf->config->nr_rach_indication = &aerial_phy_nr_rach_indication;
|
||||
p7_vnf->config->nr_uci_indication = &aerial_phy_nr_uci_indication;
|
||||
p7_vnf->config->srs_indication = &aerial_phy_srs_indication;
|
||||
p7_vnf->config->sr_indication = &aerial_phy_sr_indication;
|
||||
p7_vnf->config->cqi_indication = &aerial_phy_cqi_indication;
|
||||
p7_vnf->config->lbt_dl_indication = &aerial_phy_lbt_dl_indication;
|
||||
p7_vnf->config->nb_harq_indication = &aerial_phy_nb_harq_indication;
|
||||
p7_vnf->config->nrach_indication = &aerial_phy_nrach_indication;
|
||||
p7_vnf->config->srs_indication = NULL;
|
||||
p7_vnf->config->sr_indication = NULL;
|
||||
p7_vnf->config->cqi_indication = NULL;
|
||||
p7_vnf->config->lbt_dl_indication = NULL;
|
||||
p7_vnf->config->nb_harq_indication = NULL;
|
||||
p7_vnf->config->nrach_indication = NULL;
|
||||
p7_vnf->config->nr_slot_indication = &aerial_phy_nr_slot_indication;
|
||||
p7_vnf->config->nr_srs_indication = &aerial_phy_nr_srs_indication;
|
||||
p7_vnf->config->malloc = &aerial_vnf_allocate;
|
||||
@@ -283,7 +283,7 @@ int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
|
||||
pnf_info *pnf = vnf->pnfs;
|
||||
phy_info *phy = pnf->phys;
|
||||
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; //&RC.gNB[0]->gNB_config; // check
|
||||
nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0];
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO,
|
||||
"[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n",
|
||||
@@ -617,4 +617,3 @@ int oai_fapi_send_end_request(int cell, uint32_t frame, uint32_t slot){
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#define _GNU_SOURCE
|
||||
@@ -70,4 +70,3 @@ int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req);
|
||||
int oai_fapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req);
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
#endif //OPENAIRINTERFACE_FAPI_VNF_P5_H
|
||||
#endif
|
||||
|
||||
@@ -29,414 +29,148 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifdef ENABLE_AERIAL
|
||||
|
||||
#include "fapi_vnf_p7.h"
|
||||
#include "nr_nfapi_p7.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern UL_RCC_IND_t UL_RCC_INFO;
|
||||
extern uint16_t sf_ahead;
|
||||
|
||||
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot)
|
||||
{
|
||||
struct timespec curr_t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &curr_t);
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME
|
||||
// %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec);
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
gNB_L1_rxtx_proc_t *L1_proc = (slot & 1) ? &proc->L1_proc : &proc->L1_proc_tx;
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
|
||||
// int i;
|
||||
struct timespec wait;
|
||||
clock_gettime(CLOCK_REALTIME, &wait);
|
||||
wait.tv_sec = 0;
|
||||
wait.tv_nsec += 5000L;
|
||||
// wait.tv_nsec = 0;
|
||||
// wake up TX for subframe n+sf_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
if (pthread_mutex_timedlock(&L1_proc->mutex, &wait) != 0) {
|
||||
LOG_E(PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx & 1, L1_proc->instance_cnt);
|
||||
exit_fun("error locking mutex_rxtx");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
{
|
||||
static uint16_t old_slot = 0;
|
||||
static uint16_t old_sfn = 0;
|
||||
proc->slot_rx = old_slot;
|
||||
proc->frame_rx = old_sfn;
|
||||
// Try to be 1 frame back
|
||||
old_slot = slot;
|
||||
old_sfn = sfn;
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx);
|
||||
if (old_slot == 0 && old_sfn % 100 == 0)
|
||||
LOG_W(PHY,
|
||||
"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n",
|
||||
sfn,
|
||||
slot,
|
||||
old_sfn,
|
||||
old_slot,
|
||||
proc->frame_rx,
|
||||
proc->slot_rx);
|
||||
}
|
||||
|
||||
++L1_proc->instance_cnt;
|
||||
// LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf,
|
||||
// proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
|
||||
// We have just received and processed the common part of a subframe, say n.
|
||||
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
||||
// transmitted timestamp of the next TX slot (first).
|
||||
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
||||
// we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
|
||||
// and proc->subframe_tx = proc->subframe_rx+sf_ahead
|
||||
L1_proc->timestamp_tx = proc->timestamp_rx + (gNB->if_inst->sl_ahead * fp->samples_per_subframe);
|
||||
L1_proc->frame_rx = proc->frame_rx;
|
||||
L1_proc->slot_rx = proc->slot_rx;
|
||||
L1_proc->frame_tx = (L1_proc->slot_rx > (19 - gNB->if_inst->sl_ahead)) ? (L1_proc->frame_rx + 1) & 1023 : L1_proc->frame_rx;
|
||||
L1_proc->slot_tx = (L1_proc->slot_rx + gNB->if_inst->sl_ahead) % 20;
|
||||
|
||||
// LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx,
|
||||
// L1_proc->frame_rx, L1_proc->slot_rx); NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot
|
||||
// %d\n",L1_proc->frame_rx,L1_proc->slot_rx);
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond) != 0) {
|
||||
LOG_E(PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n");
|
||||
exit_fun("ERROR pthread_clond_signal");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
// LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int aerialwake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf)
|
||||
{
|
||||
L1_proc_t *proc = &eNB->proc;
|
||||
L1_rxtx_proc_t *L1_proc = (sf & 1) ? &proc->L1_proc : &proc->L1_proc_tx;
|
||||
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf);
|
||||
// int i;
|
||||
struct timespec wait;
|
||||
wait.tv_sec = 0;
|
||||
wait.tv_nsec = 5000000L;
|
||||
|
||||
// wake up TX for subframe n+sf_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
// if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
|
||||
// LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt );
|
||||
// exit_fun( "error locking mutex_rxtx" );
|
||||
// return(-1);
|
||||
//}
|
||||
|
||||
{
|
||||
static uint16_t old_sf = 0;
|
||||
static uint16_t old_sfn = 0;
|
||||
proc->subframe_rx = old_sf;
|
||||
proc->frame_rx = old_sfn;
|
||||
// Try to be 1 frame back
|
||||
old_sf = sf;
|
||||
old_sfn = sfn;
|
||||
|
||||
if (old_sf == 0 && old_sfn % 100 == 0)
|
||||
LOG_D(PHY, "[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx);
|
||||
}
|
||||
// wake up TX for subframe n+sf_ahead
|
||||
// lock the TX mutex and make sure the thread is ready
|
||||
if (pthread_mutex_timedlock(&L1_proc->mutex, &wait) != 0) {
|
||||
LOG_E(PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx & 1, L1_proc->instance_cnt);
|
||||
// exit_fun( "error locking mutex_rxtx" );
|
||||
return (-1);
|
||||
}
|
||||
static int busy_log_cnt = 0;
|
||||
if (L1_proc->instance_cnt < 0) {
|
||||
++L1_proc->instance_cnt;
|
||||
if (busy_log_cnt != 0) {
|
||||
LOG_E(MAC,
|
||||
"RCC singal to rxtx frame %d subframe %d busy end %d (frame %d subframe %d)\n",
|
||||
L1_proc->frame_rx,
|
||||
L1_proc->subframe_rx,
|
||||
busy_log_cnt,
|
||||
proc->frame_rx,
|
||||
proc->subframe_rx);
|
||||
}
|
||||
busy_log_cnt = 0;
|
||||
} else {
|
||||
if (busy_log_cnt == 0) {
|
||||
LOG_E(MAC,
|
||||
"RCC singal to rxtx frame %d subframe %d busy %d (frame %d subframe %d)\n",
|
||||
L1_proc->frame_rx,
|
||||
L1_proc->subframe_rx,
|
||||
L1_proc->instance_cnt,
|
||||
proc->frame_rx,
|
||||
proc->subframe_rx);
|
||||
}
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
busy_log_cnt++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&L1_proc->mutex);
|
||||
|
||||
// LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf,
|
||||
// proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
|
||||
// We have just received and processed the common part of a subframe, say n.
|
||||
// TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
|
||||
// transmitted timestamp of the next TX slot (first).
|
||||
// The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
|
||||
// we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
|
||||
// and proc->subframe_tx = proc->subframe_rx+sf_ahead
|
||||
L1_proc->timestamp_tx = proc->timestamp_rx + (sf_ahead * fp->samples_per_tti);
|
||||
L1_proc->frame_rx = proc->frame_rx;
|
||||
L1_proc->subframe_rx = proc->subframe_rx;
|
||||
L1_proc->frame_tx = (L1_proc->subframe_rx > (9 - sf_ahead)) ? (L1_proc->frame_rx + 1) & 1023 : L1_proc->frame_rx;
|
||||
L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead) % 10;
|
||||
|
||||
// LOG_D(PHY, "sfn/sf:%d%d proc[rx:%d%d] L1_proc[instance_cnt_rxtx:%d rx:%d%d] About to wake rxtx thread\n\n", sfn, sf,
|
||||
// proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx, L1_proc->frame_rx, L1_proc->subframe_rx);
|
||||
|
||||
// the thread can now be woken up
|
||||
if (pthread_cond_signal(&L1_proc->cond) != 0) {
|
||||
LOG_E(PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
|
||||
exit_fun("ERROR pthread_cond_signal");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" // for handle_nr_srs_measurements()
|
||||
|
||||
extern pthread_cond_t nfapi_sync_cond;
|
||||
extern pthread_mutex_t nfapi_sync_mutex;
|
||||
extern int nfapi_sync_var;
|
||||
|
||||
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync)
|
||||
{
|
||||
// NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
|
||||
|
||||
if (sync == 1 && nfapi_sync_var != 0) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Signal to OAI main code that it can go\n");
|
||||
pthread_mutex_lock(&nfapi_sync_mutex);
|
||||
nfapi_sync_var = 0;
|
||||
pthread_cond_broadcast(&nfapi_sync_cond);
|
||||
pthread_mutex_unlock(&nfapi_sync_mutex);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
|
||||
{
|
||||
static uint8_t first_time = 1;
|
||||
|
||||
if (first_time) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot));
|
||||
first_time = 0;
|
||||
}
|
||||
|
||||
if (RC.gNB && RC.gNB[0]->configured) {
|
||||
// uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
|
||||
// uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
|
||||
LOG_D(PHY, "[VNF] slot indication sfn:%d slot:%d\n", sfn, slot);
|
||||
aerial_wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent
|
||||
} else {
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB);
|
||||
|
||||
if (RC.gNB)
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind)
|
||||
{
|
||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||
LOG_D(MAC,
|
||||
"%s() NFAPI SFN/SF:%d number_of_harqs:%u\n",
|
||||
__FUNCTION__,
|
||||
NFAPI_SFNSF2DEC(ind->sfn_sf),
|
||||
ind->harq_indication_body.number_of_harqs);
|
||||
AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed");
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf);
|
||||
|
||||
UL_RCC_INFO.harq_ind[index] = *ind;
|
||||
|
||||
assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
|
||||
if (ind->harq_indication_body.number_of_harqs > 0) {
|
||||
UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list =
|
||||
malloc(sizeof(nfapi_harq_indication_pdu_t) * NFAPI_HARQ_IND_MAX_PDU);
|
||||
}
|
||||
for (int i = 0; i < ind->harq_indication_body.number_of_harqs; i++) {
|
||||
memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i],
|
||||
&ind->harq_indication_body.harq_pdu_list[i],
|
||||
sizeof(nfapi_harq_indication_pdu_t));
|
||||
}
|
||||
} else {
|
||||
eNB->UL_INFO.harq_ind = *ind;
|
||||
eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
|
||||
|
||||
assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU);
|
||||
for (int i = 0; i < ind->harq_indication_body.number_of_harqs; i++) {
|
||||
memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i],
|
||||
&ind->harq_indication_body.harq_pdu_list[i],
|
||||
sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i]));
|
||||
}
|
||||
}
|
||||
AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed");
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_harq_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind)
|
||||
{
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind));
|
||||
crc_ind->header.message_id = ind->header.message_id;
|
||||
crc_ind->number_crcs = ind->number_crcs;
|
||||
crc_ind->sfn = ind->sfn;
|
||||
crc_ind->slot = ind->slot;
|
||||
if (ind->number_crcs > 0) {
|
||||
crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t));
|
||||
AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication.");
|
||||
nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind));
|
||||
crc_ind->header.message_id = ind->header.message_id;
|
||||
crc_ind->number_crcs = ind->number_crcs;
|
||||
crc_ind->sfn = ind->sfn;
|
||||
crc_ind->slot = ind->slot;
|
||||
if (ind->number_crcs > 0) {
|
||||
crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t));
|
||||
AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication.");
|
||||
}
|
||||
for (int j = 0; j < ind->number_crcs; j++) {
|
||||
crc_ind->crc_list[j].handle = ind->crc_list[j].handle;
|
||||
crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti;
|
||||
crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id;
|
||||
crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status;
|
||||
crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb;
|
||||
crc_ind->crc_list[j].cb_crc_status = ind->crc_list[j].cb_crc_status;
|
||||
crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi;
|
||||
crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance;
|
||||
crc_ind->crc_list[j].rssi = ind->crc_list[j].rssi;
|
||||
if (crc_ind->crc_list[j].tb_crc_status != 0) {
|
||||
LOG_D(NR_MAC,
|
||||
"Received crc_ind.harq_id %d status %d for index %d SFN SLot %u %u with rnti %04x\n",
|
||||
crc_ind->crc_list[j].harq_id,
|
||||
crc_ind->crc_list[j].tb_crc_status,
|
||||
j,
|
||||
crc_ind->sfn,
|
||||
crc_ind->slot,
|
||||
crc_ind->crc_list[j].rnti);
|
||||
}
|
||||
for (int j = 0; j < ind->number_crcs; j++) {
|
||||
crc_ind->crc_list[j].handle = ind->crc_list[j].handle;
|
||||
crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti;
|
||||
crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id;
|
||||
crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status;
|
||||
crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb;
|
||||
crc_ind->crc_list[j].cb_crc_status = ind->crc_list[j].cb_crc_status;
|
||||
crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi;
|
||||
crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance;
|
||||
crc_ind->crc_list[j].rssi = ind->crc_list[j].rssi;
|
||||
if (crc_ind->crc_list[j].tb_crc_status != 0) {
|
||||
LOG_D(NR_MAC,
|
||||
"Received crc_ind.harq_id %d status %d for index %d SFN SLot %u %u with rnti %04x\n",
|
||||
crc_ind->crc_list[j].harq_id,
|
||||
crc_ind->crc_list[j].tb_crc_status,
|
||||
j,
|
||||
crc_ind->sfn,
|
||||
crc_ind->slot,
|
||||
crc_ind->crc_list[j].rnti);
|
||||
}
|
||||
}
|
||||
if (!put_queue(&gnb_crc_ind_queue, crc_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for crc_ind\n");
|
||||
free(crc_ind->crc_list);
|
||||
free(crc_ind);
|
||||
}
|
||||
} else {
|
||||
LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode());
|
||||
}
|
||||
if (!put_queue(&gnb_crc_ind_queue, crc_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for crc_ind\n");
|
||||
free(crc_ind->crc_list);
|
||||
free(crc_ind);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind)
|
||||
{
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind));
|
||||
rx_ind->header.message_id = ind->header.message_id;
|
||||
rx_ind->sfn = ind->sfn;
|
||||
rx_ind->slot = ind->slot;
|
||||
rx_ind->number_of_pdus = ind->number_of_pdus;
|
||||
nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind));
|
||||
rx_ind->header.message_id = ind->header.message_id;
|
||||
rx_ind->sfn = ind->sfn;
|
||||
rx_ind->slot = ind->slot;
|
||||
rx_ind->number_of_pdus = ind->number_of_pdus;
|
||||
|
||||
if (ind->number_of_pdus > 0) {
|
||||
rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t));
|
||||
AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication.");
|
||||
}
|
||||
for (int j = 0; j < ind->number_of_pdus; j++) {
|
||||
rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle;
|
||||
rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti;
|
||||
rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id;
|
||||
rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length;
|
||||
rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi;
|
||||
rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance;
|
||||
rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi;
|
||||
if (ind->number_of_pdus > 0) {
|
||||
rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t));
|
||||
AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication.");
|
||||
}
|
||||
for (int j = 0; j < ind->number_of_pdus; j++) {
|
||||
rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle;
|
||||
rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti;
|
||||
rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id;
|
||||
rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length;
|
||||
rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi;
|
||||
rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance;
|
||||
rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi;
|
||||
// Only copy PDU data if there's any to copy
|
||||
if (rx_ind->pdu_list[j].pdu_length > 0) {
|
||||
rx_ind->pdu_list[j].pdu = calloc(rx_ind->pdu_list[j].pdu_length, sizeof(uint8_t));
|
||||
memcpy(rx_ind->pdu_list[j].pdu,ind->pdu_list[j].pdu,ind->pdu_list[j].pdu_length);
|
||||
LOG_D(NR_MAC,
|
||||
"(%d.%d) Handle %d for index %d, RNTI, %04x, HARQID %d\n",
|
||||
ind->sfn,
|
||||
ind->slot,
|
||||
ind->pdu_list[j].handle,
|
||||
j,
|
||||
ind->pdu_list[j].rnti,
|
||||
ind->pdu_list[j].harq_id);
|
||||
memcpy(rx_ind->pdu_list[j].pdu, ind->pdu_list[j].pdu, ind->pdu_list[j].pdu_length);
|
||||
}
|
||||
if (!put_queue(&gnb_rx_ind_queue, rx_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for rx_ind\n");
|
||||
free(rx_ind->pdu_list);
|
||||
free(rx_ind);
|
||||
}
|
||||
} else {
|
||||
LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode());
|
||||
LOG_D(NR_MAC,
|
||||
"(%d.%d) Handle %d for index %d, RNTI, %04x, HARQID %d\n",
|
||||
ind->sfn,
|
||||
ind->slot,
|
||||
ind->pdu_list[j].handle,
|
||||
j,
|
||||
ind->pdu_list[j].rnti,
|
||||
ind->pdu_list[j].harq_id);
|
||||
}
|
||||
if (!put_queue(&gnb_rx_ind_queue, rx_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for rx_ind\n");
|
||||
free(rx_ind->pdu_list);
|
||||
free(rx_ind);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind)
|
||||
{
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
|
||||
rach_ind->header.message_id = ind->header.message_id;
|
||||
rach_ind->sfn = ind->sfn;
|
||||
rach_ind->slot = ind->slot;
|
||||
rach_ind->number_of_pdus = ind->number_of_pdus;
|
||||
rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list));
|
||||
AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication.");
|
||||
for (int i = 0; i < ind->number_of_pdus; i++) {
|
||||
rach_ind->pdu_list[i].phy_cell_id = ind->pdu_list[i].phy_cell_id;
|
||||
rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index;
|
||||
rach_ind->pdu_list[i].slot_index = ind->pdu_list[i].slot_index;
|
||||
rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index;
|
||||
rach_ind->pdu_list[i].avg_rssi = ind->pdu_list[i].avg_rssi;
|
||||
rach_ind->pdu_list[i].avg_snr = ind->pdu_list[i].avg_snr;
|
||||
rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble;
|
||||
for (int j = 0; j < ind->pdu_list[i].num_preamble; j++) {
|
||||
rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index;
|
||||
rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance;
|
||||
rach_ind->pdu_list[i].preamble_list[j].preamble_pwr = ind->pdu_list[i].preamble_list[j].preamble_pwr;
|
||||
}
|
||||
}
|
||||
if (!put_queue(&gnb_rach_ind_queue, rach_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for rach_ind\n");
|
||||
for (int i = 0; i < ind->number_of_pdus; i++) {
|
||||
free(rach_ind->pdu_list[i].preamble_list);
|
||||
}
|
||||
free(rach_ind->pdu_list);
|
||||
free(rach_ind);
|
||||
} else {
|
||||
LOG_I(NR_MAC, "RACH.indication put_queue successfull\n");
|
||||
nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
|
||||
rach_ind->header.message_id = ind->header.message_id;
|
||||
rach_ind->sfn = ind->sfn;
|
||||
rach_ind->slot = ind->slot;
|
||||
rach_ind->number_of_pdus = ind->number_of_pdus;
|
||||
rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list));
|
||||
AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication.");
|
||||
for (int i = 0; i < ind->number_of_pdus; i++) {
|
||||
rach_ind->pdu_list[i].phy_cell_id = ind->pdu_list[i].phy_cell_id;
|
||||
rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index;
|
||||
rach_ind->pdu_list[i].slot_index = ind->pdu_list[i].slot_index;
|
||||
rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index;
|
||||
rach_ind->pdu_list[i].avg_rssi = ind->pdu_list[i].avg_rssi;
|
||||
rach_ind->pdu_list[i].avg_snr = ind->pdu_list[i].avg_snr;
|
||||
rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble;
|
||||
for (int j = 0; j < ind->pdu_list[i].num_preamble; j++) {
|
||||
rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index;
|
||||
rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance;
|
||||
rach_ind->pdu_list[i].preamble_list[j].preamble_pwr = ind->pdu_list[i].preamble_list[j].preamble_pwr;
|
||||
}
|
||||
}
|
||||
if (!put_queue(&gnb_rach_ind_queue, rach_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for rach_ind\n");
|
||||
free(rach_ind->pdu_list);
|
||||
free(rach_ind);
|
||||
} else {
|
||||
LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode());
|
||||
LOG_I(NR_MAC, "RACH.indication put_queue successfull\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
|
||||
{
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
|
||||
AssertFatal(uci_ind, "Memory not allocated for uci_ind in phy_nr_uci_indication.");
|
||||
*uci_ind = *ind;
|
||||
nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
|
||||
AssertFatal(uci_ind, "Memory not allocated for uci_ind in phy_nr_uci_indication.");
|
||||
*uci_ind = *ind;
|
||||
|
||||
uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t));
|
||||
AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication.");
|
||||
for (int i = 0; i < ind->num_ucis; i++) {
|
||||
uci_ind->uci_list[i] = ind->uci_list[i];
|
||||
uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t));
|
||||
AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication.");
|
||||
for (int i = 0; i < ind->num_ucis; i++) {
|
||||
uci_ind->uci_list[i] = ind->uci_list[i];
|
||||
|
||||
switch (uci_ind->uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
||||
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
|
||||
break;
|
||||
switch (uci_ind->uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
||||
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
// nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
|
||||
// nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1;
|
||||
// if (ind_pdu->sr) {
|
||||
@@ -455,49 +189,49 @@ int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
|
||||
// for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++)
|
||||
// uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value;
|
||||
// }
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4;
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4;
|
||||
*uci_ind_pdu = *ind_pdu;
|
||||
if (ind_pdu->harq.harq_payload) {
|
||||
uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
|
||||
AssertFatal(uci_ind_pdu->harq.harq_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
|
||||
*uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload;
|
||||
}
|
||||
if (ind_pdu->sr.sr_payload) {
|
||||
uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload));
|
||||
AssertFatal(uci_ind_pdu->sr.sr_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication.");
|
||||
//SCF222.10.02 sr_bit_len values from 1 to 8, payload always just one byte
|
||||
uci_ind_pdu->sr.sr_payload[0] = ind_pdu->sr.sr_payload[0];
|
||||
}
|
||||
if (ind_pdu->csi_part1.csi_part1_payload) {
|
||||
uint8_t byte_len = (ind_pdu->csi_part1.csi_part1_bit_len / 8) + 1;
|
||||
uci_ind_pdu->csi_part1.csi_part1_payload = calloc(byte_len, sizeof(uint8_t));
|
||||
AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
|
||||
memcpy(uci_ind_pdu->csi_part1.csi_part1_payload,ind_pdu->csi_part1.csi_part1_payload,byte_len);
|
||||
}
|
||||
if (ind_pdu->csi_part2.csi_part2_payload) {
|
||||
uint8_t byte_len = (ind_pdu->csi_part2.csi_part2_bit_len / 8) + 1;
|
||||
uci_ind_pdu->csi_part2.csi_part2_payload = calloc(byte_len, sizeof(uint8_t));
|
||||
AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
|
||||
memcpy(uci_ind_pdu->csi_part2.csi_part2_payload,ind_pdu->csi_part2.csi_part2_payload,byte_len);
|
||||
}
|
||||
break;
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4;
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4;
|
||||
*uci_ind_pdu = *ind_pdu;
|
||||
if (ind_pdu->harq.harq_payload) {
|
||||
uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
|
||||
AssertFatal(uci_ind_pdu->harq.harq_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
|
||||
*uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload;
|
||||
}
|
||||
if (ind_pdu->sr.sr_payload) {
|
||||
uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload));
|
||||
AssertFatal(uci_ind_pdu->sr.sr_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication.");
|
||||
//SCF222.10.02 sr_bit_len values from 1 to 8, payload always just one byte
|
||||
uci_ind_pdu->sr.sr_payload[0] = ind_pdu->sr.sr_payload[0];
|
||||
}
|
||||
if (ind_pdu->csi_part1.csi_part1_payload) {
|
||||
uint8_t byte_len = (ind_pdu->csi_part1.csi_part1_bit_len / 8) + 1;
|
||||
uci_ind_pdu->csi_part1.csi_part1_payload = calloc(byte_len, sizeof(uint8_t));
|
||||
AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
|
||||
memcpy(uci_ind_pdu->csi_part1.csi_part1_payload,ind_pdu->csi_part1.csi_part1_payload,byte_len);
|
||||
}
|
||||
if (ind_pdu->csi_part2.csi_part2_payload) {
|
||||
uint8_t byte_len = (ind_pdu->csi_part2.csi_part2_bit_len / 8) + 1;
|
||||
uci_ind_pdu->csi_part2.csi_part2_payload = calloc(byte_len, sizeof(uint8_t));
|
||||
AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL,
|
||||
"Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
|
||||
memcpy(uci_ind_pdu->csi_part2.csi_part2_payload,ind_pdu->csi_part2.csi_part2_payload,byte_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!put_queue(&gnb_uci_ind_queue, uci_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for uci_ind\n");
|
||||
for (int i = 0; i < ind->num_ucis; i++) {
|
||||
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) {
|
||||
if (!put_queue(&gnb_uci_ind_queue, uci_ind)) {
|
||||
LOG_E(NR_MAC, "Put_queue failed for uci_ind\n");
|
||||
for (int i = 0; i < ind->num_ucis; i++) {
|
||||
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) {
|
||||
// if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) {
|
||||
// free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list);
|
||||
// uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL;
|
||||
@@ -508,210 +242,21 @@ int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
|
||||
// free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr);
|
||||
// uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL;
|
||||
// }
|
||||
}
|
||||
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) {
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
|
||||
}
|
||||
}
|
||||
free(uci_ind->uci_list);
|
||||
uci_ind->uci_list = NULL;
|
||||
free(uci_ind);
|
||||
uci_ind = NULL;
|
||||
}
|
||||
} else {
|
||||
LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_AERIAL(3)\n", nfapi_getmode());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind)
|
||||
{
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_srs_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind)
|
||||
{
|
||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||
LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs);
|
||||
AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed");
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf);
|
||||
|
||||
UL_RCC_INFO.sr_ind[index] = *ind;
|
||||
LOG_D(MAC,
|
||||
"%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n",
|
||||
__FUNCTION__,
|
||||
index,
|
||||
eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs);
|
||||
if (ind->sr_indication_body.number_of_srs > 0) {
|
||||
assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t) * NFAPI_SR_IND_MAX_PDU);
|
||||
}
|
||||
|
||||
assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
for (int i = 0; i < ind->sr_indication_body.number_of_srs; i++) {
|
||||
nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list[i];
|
||||
nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i];
|
||||
|
||||
LOG_D(MAC,
|
||||
"SR_IND[PDU:%d %d][rnti:%x cqi:%d channel:%d]\n",
|
||||
index,
|
||||
i,
|
||||
src_pdu->rx_ue_information.rnti,
|
||||
src_pdu->ul_cqi_information.ul_cqi,
|
||||
src_pdu->ul_cqi_information.channel);
|
||||
|
||||
memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
|
||||
}
|
||||
} else {
|
||||
nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind;
|
||||
nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list;
|
||||
*dest_ind = *ind;
|
||||
dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list;
|
||||
LOG_D(MAC,
|
||||
"%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n",
|
||||
__FUNCTION__,
|
||||
eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs);
|
||||
|
||||
assert(eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU);
|
||||
for (int i = 0; i < eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs; i++) {
|
||||
nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i];
|
||||
nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i];
|
||||
LOG_D(MAC,
|
||||
"SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n",
|
||||
i,
|
||||
src_pdu->rx_ue_information.rnti,
|
||||
src_pdu->ul_cqi_information.ul_cqi,
|
||||
src_pdu->ul_cqi_information.channel);
|
||||
memcpy(dest_pdu, src_pdu, sizeof(*src_pdu));
|
||||
}
|
||||
}
|
||||
AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed");
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_sr_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool aerial_is_ue_same(uint16_t ue_id_1, uint16_t ue_id_2)
|
||||
{
|
||||
return (ue_id_1 == ue_id_2);
|
||||
}
|
||||
|
||||
static void aerial_analyze_cqi_pdus_for_duplicates(nfapi_cqi_indication_t *ind)
|
||||
{
|
||||
uint16_t num_cqis = ind->cqi_indication_body.number_of_cqis;
|
||||
assert(num_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
for (int i = 0; i < num_cqis; i++) {
|
||||
nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
|
||||
|
||||
LOG_I(MAC,
|
||||
"CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n",
|
||||
i,
|
||||
src_pdu->rx_ue_information.rnti,
|
||||
src_pdu->ul_cqi_information.ul_cqi,
|
||||
src_pdu->ul_cqi_information.channel);
|
||||
|
||||
for (int j = i + 1; j < num_cqis; j++) {
|
||||
uint16_t rnti_i = ind->cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti;
|
||||
uint16_t rnti_j = ind->cqi_indication_body.cqi_pdu_list[j].rx_ue_information.rnti;
|
||||
if (aerial_is_ue_same(rnti_i, rnti_j)) {
|
||||
LOG_E(MAC, "Problem, two cqis received from a single UE for rnti %x\n", rnti_i);
|
||||
// abort(); This will be fixed in merge request which handles multiple CQIs.
|
||||
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) {
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
|
||||
free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
|
||||
}
|
||||
}
|
||||
free(uci_ind->uci_list);
|
||||
uci_ind->uci_list = NULL;
|
||||
free(uci_ind);
|
||||
uci_ind = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind)
|
||||
{
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_cqi_ind(p7_vnf->mac, ind);
|
||||
struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
|
||||
LOG_D(MAC,
|
||||
"%s() NFAPI SFN/SF:%d number_of_cqis:%u\n",
|
||||
__FUNCTION__,
|
||||
NFAPI_SFNSF2DEC(ind->sfn_sf),
|
||||
ind->cqi_indication_body.number_of_cqis);
|
||||
AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex) == 0, "Mutex lock failed");
|
||||
if (NFAPI_MODE == NFAPI_MODE_VNF) {
|
||||
int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf);
|
||||
|
||||
UL_RCC_INFO.cqi_ind[index] = *ind;
|
||||
assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
if (ind->cqi_indication_body.number_of_cqis > 0) {
|
||||
UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list =
|
||||
malloc(sizeof(nfapi_cqi_indication_pdu_t) * NFAPI_CQI_IND_MAX_PDU);
|
||||
UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list =
|
||||
malloc(sizeof(nfapi_cqi_indication_raw_pdu_t) * NFAPI_CQI_IND_MAX_PDU);
|
||||
}
|
||||
|
||||
aerial_analyze_cqi_pdus_for_duplicates(ind);
|
||||
|
||||
assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
for (int i = 0; i < ind->cqi_indication_body.number_of_cqis; i++) {
|
||||
nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
|
||||
LOG_D(MAC,
|
||||
"SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n",
|
||||
i,
|
||||
src_pdu->rx_ue_information.rnti,
|
||||
src_pdu->ul_cqi_information.ul_cqi,
|
||||
src_pdu->ul_cqi_information.channel);
|
||||
memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list[i], src_pdu, sizeof(nfapi_cqi_indication_pdu_t));
|
||||
|
||||
memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list[i],
|
||||
&ind->cqi_indication_body.cqi_raw_pdu_list[i],
|
||||
sizeof(nfapi_cqi_indication_raw_pdu_t));
|
||||
}
|
||||
} else {
|
||||
nfapi_cqi_indication_t *dest_ind = &eNB->UL_INFO.cqi_ind;
|
||||
*dest_ind = *ind;
|
||||
dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list;
|
||||
dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list;
|
||||
assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU);
|
||||
for (int i = 0; i < ind->cqi_indication_body.number_of_cqis; i++) {
|
||||
nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i];
|
||||
LOG_D(MAC,
|
||||
"CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n",
|
||||
i,
|
||||
src_pdu->rx_ue_information.rnti,
|
||||
src_pdu->ul_cqi_information.ul_cqi,
|
||||
src_pdu->ul_cqi_information.channel);
|
||||
memcpy(&dest_ind->cqi_indication_body.cqi_pdu_list[i], src_pdu, sizeof(nfapi_cqi_indication_pdu_t));
|
||||
memcpy(&dest_ind->cqi_indication_body.cqi_raw_pdu_list[i],
|
||||
&ind->cqi_indication_body.cqi_raw_pdu_list[i],
|
||||
sizeof(nfapi_cqi_indication_raw_pdu_t));
|
||||
}
|
||||
}
|
||||
AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex) == 0, "Mutex unlock failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind)
|
||||
{
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_lbt_dl_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind)
|
||||
{
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_nb_harq_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind)
|
||||
{
|
||||
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
|
||||
// mac_nrach_ind(p7_vnf->mac, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
NR_Sched_Rsp_t g_sched_resp;
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot, NR_Sched_Rsp_t* sched_info);
|
||||
int oai_fapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req);
|
||||
@@ -728,29 +273,26 @@ int trigger_scheduler(nfapi_nr_slot_indication_scf_t *slot_ind)
|
||||
// Call into the scheduler (this is hardcoded and should be init properly!)
|
||||
// memset(sched_resp, 0, sizeof(*sched_resp));
|
||||
gNB_dlsch_ulsch_scheduler(0, slot_ind->sfn, slot_ind->slot, &g_sched_resp);
|
||||
if (NFAPI_MODE == NFAPI_MODE_AERIAL) {
|
||||
#ifdef ENABLE_AERIAL
|
||||
bool send_slt_resp = false;
|
||||
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) {
|
||||
oai_fapi_dl_tti_req(&g_sched_resp.DL_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_tti_req.n_pdus > 0) {
|
||||
oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.TX_req.Number_of_PDUs > 0) {
|
||||
oai_fapi_tx_data_req(&g_sched_resp.TX_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_dci_req.numPdus > 0) {
|
||||
oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (send_slt_resp) {
|
||||
oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool send_slt_resp = false;
|
||||
if (g_sched_resp.DL_req.dl_tti_request_body.nPDUs> 0) {
|
||||
oai_fapi_dl_tti_req(&g_sched_resp.DL_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_tti_req.n_pdus > 0) {
|
||||
oai_fapi_ul_tti_req(&g_sched_resp.UL_tti_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.TX_req.Number_of_PDUs > 0) {
|
||||
oai_fapi_tx_data_req(&g_sched_resp.TX_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (g_sched_resp.UL_dci_req.numPdus > 0) {
|
||||
oai_fapi_ul_dci_req(&g_sched_resp.UL_dci_req);
|
||||
send_slt_resp = true;
|
||||
}
|
||||
if (send_slt_resp) {
|
||||
oai_fapi_send_end_request(0,slot_ind->sfn, slot_ind->slot);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -772,26 +314,10 @@ int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind)
|
||||
|
||||
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind)
|
||||
{
|
||||
struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
|
||||
|
||||
gNB->UL_INFO.srs_ind = *ind;
|
||||
|
||||
if (ind->number_of_pdus > 0)
|
||||
gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t) * ind->number_of_pdus);
|
||||
|
||||
for (int i = 0; i < ind->number_of_pdus; i++) {
|
||||
memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
|
||||
|
||||
LOG_D(MAC,
|
||||
"%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
|
||||
__FUNCTION__,
|
||||
ind->sfn,
|
||||
ind->slot,
|
||||
ind->number_of_pdus,
|
||||
gNB->UL_INFO.srs_ind.number_of_pdus);
|
||||
}
|
||||
|
||||
|
||||
// or queue to decouple, but I think it should be fast (in all likelihood,
|
||||
// the VNF has nothing to do)
|
||||
for (int i = 0; i < ind->number_of_pdus; ++i)
|
||||
handle_nr_srs_measurements(0, ind->sfn, ind->slot, &ind->pdu_list[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1314,4 +840,3 @@ int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t
|
||||
return aerial_send_P7_msg(FAPI_buffer, len_FAPI, header);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_AERIAL
|
||||
#ifndef OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#define OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
|
||||
@@ -180,21 +179,10 @@ typedef struct {
|
||||
|
||||
} vnf_info;
|
||||
|
||||
int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot);
|
||||
int aerial_wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf);
|
||||
int aerial_phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync);
|
||||
int aerial_phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
||||
int aerial_phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind);
|
||||
int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind);
|
||||
int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind);
|
||||
int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind);
|
||||
int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind);
|
||||
int aerial_phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind);
|
||||
int aerial_phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind);
|
||||
int aerial_phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind);
|
||||
int aerial_phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind);
|
||||
int aerial_phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind);
|
||||
int aerial_phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind);
|
||||
int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
|
||||
int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
|
||||
void *aerial_vnf_allocate(size_t size);
|
||||
@@ -241,4 +229,3 @@ uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
|
||||
// int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
|
||||
int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
|
||||
#endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
|
||||
#endif
|
||||
|
||||
@@ -4,3 +4,6 @@ add_library(nr_fapi_p5
|
||||
)
|
||||
target_include_directories(nr_fapi_p5 PUBLIC inc)
|
||||
target_link_libraries(nr_fapi_p5 PUBLIC nfapi_common)
|
||||
if(OAI_AERIAL)
|
||||
target_compile_definitions(nr_fapi_p5 PRIVATE ENABLE_AERIAL)
|
||||
endif()
|
||||
|
||||
@@ -1227,6 +1227,29 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
|
||||
numTLVs++;
|
||||
}
|
||||
#endif
|
||||
|
||||
AssertFatal(pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext.tl.tag == 0, "BF Vendor extension shouldn't be set!");
|
||||
// The call to pack the TLV would be the same as any other TLV, it is only packed if the tag is set,
|
||||
// so, it's safe to add the call to pack_nr_tlv even if it is not always set
|
||||
retval &= pack_nr_tlv(NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG,
|
||||
&(pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
// only increase if it was set
|
||||
numTLVs += pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext.tl.tag == NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG;
|
||||
|
||||
AssertFatal(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag == 0, "BF Vendor extension shouldn't be set!");
|
||||
// The call to pack the TLV would be the same as any other TLV, it is only packed if the tag is set,
|
||||
// so, it's safe to add the call to pack_nr_tlv even if it is not always set
|
||||
retval &= pack_nr_tlv(NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG,
|
||||
&(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext),
|
||||
ppWritePackedMsg,
|
||||
end,
|
||||
&pack_uint8_tlv_value);
|
||||
// only increase if it was set
|
||||
numTLVs += pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag == NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG;
|
||||
|
||||
pNfapiMsg->num_tlv = numTLVs;
|
||||
retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end);
|
||||
return retval;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
|
||||
#define NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG 0xA000
|
||||
#define NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG 0xA001
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=1,
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#define NFAPI_MAX_NUM_UCI_INDICATION 8
|
||||
#define NFAPI_MAX_NUM_GROUPS 8
|
||||
#define NFAPI_MAX_NUM_CB 8
|
||||
#define NFAPI_MAX_NUM_PRGS 1
|
||||
#define NFAPI_MAX_NUM_BG_IF 1
|
||||
|
||||
// Extension to the generic structures for single tlv values
|
||||
|
||||
@@ -443,6 +445,27 @@ typedef struct
|
||||
|
||||
} nfapi_nr_measurement_config_t;
|
||||
|
||||
//-----------------------//
|
||||
//3.3.6 Storing Precoding and Beamforming Tables
|
||||
|
||||
//table 3-32
|
||||
|
||||
typedef struct {
|
||||
uint16_t dig_beam_weight_Re;
|
||||
uint16_t dig_beam_weight_Im;
|
||||
} nfapi_nr_txru_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t beam_idx; //0~65535
|
||||
nfapi_nr_txru_t *txru_list;
|
||||
} nfapi_nr_dig_beam_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t num_dig_beams; //0~65535
|
||||
uint16_t num_txrus; //0~65535
|
||||
nfapi_nr_dig_beam_t *dig_beam_list;
|
||||
} nfapi_nr_dbt_pdu_t;
|
||||
|
||||
// Table 3–62 Precoding matrix (PM) PDU (v.222.10.04)
|
||||
typedef struct {
|
||||
int16_t precoder_weight_Re;
|
||||
@@ -463,6 +486,11 @@ typedef struct {
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu;
|
||||
} nfapi_nr_pm_list_t;
|
||||
|
||||
typedef struct {
|
||||
nfapi_uint8_tlv_t num_beams_period_vendor_ext;
|
||||
nfapi_uint8_tlv_t analog_bf_vendor_ext;
|
||||
} nfapi_nr_analog_beamforming_ve_t;
|
||||
|
||||
// ERROR enums
|
||||
typedef enum { // Table 2-22
|
||||
NFAPI_NR_PARAM_MSG_OK = 0,
|
||||
@@ -575,6 +603,8 @@ typedef struct {
|
||||
nfapi_nr_measurement_config_t measurement_config;
|
||||
nfapi_nr_nfapi_t nfapi_config;
|
||||
nfapi_nr_pm_list_t pmi_list;
|
||||
nfapi_nr_dbt_pdu_t dbt_config;
|
||||
nfapi_nr_analog_beamforming_ve_t analog_beamforming_ve;
|
||||
} nfapi_nr_config_request_scf_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -669,28 +699,6 @@ typedef struct {
|
||||
nfapi_nr_phy_notifications_errors_e error_code;
|
||||
} nfapi_nr_phy_notifications_error_indicate_t;
|
||||
|
||||
//-----------------------//
|
||||
//3.3.6 Storing Precoding and Beamforming Tables
|
||||
|
||||
//table 3-32
|
||||
//?
|
||||
typedef struct {
|
||||
uint16_t beam_idx; //0~65535
|
||||
} nfapi_nr_dig_beam_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t dig_beam_weight_Re;
|
||||
uint16_t dig_beam_weight_Im;
|
||||
} nfapi_nr_txru_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t num_dig_beams; //0~65535
|
||||
uint16_t num_txrus; //0~65535
|
||||
nfapi_nr_dig_beam_t* dig_beam_list;
|
||||
nfapi_nr_txru_t* txru_list;
|
||||
} nfapi_nr_dbt_pdu_t;
|
||||
|
||||
|
||||
// Section 3.4
|
||||
|
||||
// Section 3.4.1 slot indication
|
||||
@@ -719,7 +727,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535.
|
||||
nfapi_nr_dig_bf_interface_t dig_bf_interface_list[1];//max dig_bf_interfaces
|
||||
nfapi_nr_dig_bf_interface_t dig_bf_interface_list[NFAPI_MAX_NUM_BG_IF];//max dig_bf_interfaces
|
||||
|
||||
}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t;
|
||||
|
||||
@@ -730,7 +738,7 @@ typedef struct
|
||||
uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
|
||||
//watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface
|
||||
uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
|
||||
nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[1];//max prg_size
|
||||
nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[NFAPI_MAX_NUM_PRGS];//max prg_size
|
||||
|
||||
}nfapi_nr_tx_precoding_and_beamforming_t;
|
||||
|
||||
@@ -1135,7 +1143,7 @@ typedef struct {
|
||||
//for prach_pdu:
|
||||
typedef struct
|
||||
{
|
||||
nfapi_nr_dig_bf_interface_t* dig_bf_interface_list;
|
||||
nfapi_nr_dig_bf_interface_t dig_bf_interface_list[NFAPI_MAX_NUM_BG_IF];
|
||||
} nfapi_nr_ul_beamforming_number_of_prgs_t;
|
||||
|
||||
typedef struct
|
||||
@@ -1144,7 +1152,7 @@ typedef struct
|
||||
uint16_t num_prgs; // Number of PRGs spanning this allocation. Value : 1->275
|
||||
uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG) – to which the same digital beamforming gets applied. Value: 1->275
|
||||
uint8_t dig_bf_interface; // Number of logical antenna ports (parallel streams) resulting from the Rx combining. Value: 0->255
|
||||
nfapi_nr_ul_beamforming_number_of_prgs_t *prgs_list;
|
||||
nfapi_nr_ul_beamforming_number_of_prgs_t prgs_list[NFAPI_MAX_NUM_PRGS];
|
||||
} nfapi_nr_ul_beamforming_t;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -935,10 +935,6 @@ static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (prach_pdu->beamforming.num_prgs > 0 || prach_pdu->beamforming.prg_size > 0 || prach_pdu->beamforming.dig_bf_interface > 0) {
|
||||
AssertFatal(1 == 0, "PRACH PDU Beamforming not supported yet");
|
||||
}
|
||||
|
||||
// Pack RX Beamforming PDU
|
||||
if (!(push16(prach_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
|
||||
&& push16(prach_pdu->beamforming.prg_size, ppWritePackedMsg, end)
|
||||
@@ -4772,15 +4768,6 @@ static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPacked
|
||||
&& pull8(ppReadPackedMsg, &prach_pdu->beamforming.dig_bf_interface, end))) {
|
||||
return 0;
|
||||
}
|
||||
if (prach_pdu->beamforming.num_prgs > 0) {
|
||||
prach_pdu->beamforming.prgs_list = calloc(prach_pdu->beamforming.num_prgs, sizeof(*prach_pdu->beamforming.prgs_list));
|
||||
if (prach_pdu->beamforming.dig_bf_interface > 0) {
|
||||
for(int prg_idx = 0; prg_idx < prach_pdu->beamforming.num_prgs;prg_idx++){
|
||||
prach_pdu->beamforming.prgs_list[prg_idx].dig_bf_interface_list =
|
||||
calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) {
|
||||
for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) {
|
||||
if (!pull16(ppReadPackedMsg, &prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
|
||||
|
||||
+43
-34
@@ -41,7 +41,6 @@
|
||||
#include "SCHED_NR/fapi_nr_l1.h"
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
|
||||
int l1_north_init_gNB() {
|
||||
|
||||
if (RC.nb_nr_L1_inst > 0 && RC.gNB != NULL) {
|
||||
@@ -104,7 +103,7 @@ void reset_active_stats(PHY_VARS_gNB *gNB, int frame)
|
||||
// A global var to reduce the changes size
|
||||
ldpc_interface_t ldpc_interface = {0}, ldpc_interface_offload = {0};
|
||||
|
||||
int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
{
|
||||
// shortcuts
|
||||
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
||||
@@ -112,16 +111,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||
NR_gNB_PRACH *const prach_vars = &gNB->prach_vars;
|
||||
|
||||
int i;
|
||||
int Ptx=cfg->carrier_config.num_tx_ant.value;
|
||||
int Prx=cfg->carrier_config.num_rx_ant.value;
|
||||
common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
|
||||
LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out");
|
||||
if (common_vars->analog_bf) {
|
||||
common_vars->num_beams_period = cfg->analog_beamforming_ve.num_beams_period_vendor_ext.value;
|
||||
LOG_I(PHY, "Max number of concurrent beams: %d\n", common_vars->num_beams_period);
|
||||
} else
|
||||
common_vars->num_beams_period = 1;
|
||||
|
||||
int Ptx = cfg->carrier_config.num_tx_ant.value;
|
||||
int Prx = cfg->carrier_config.num_rx_ant.value;
|
||||
int max_ul_mimo_layers = 4;
|
||||
|
||||
AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx);
|
||||
AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx);
|
||||
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
|
||||
AssertFatal(Ptx > 0 && Ptx < 9,"Ptx %d is not supported\n", Ptx);
|
||||
AssertFatal(Prx > 0 && Prx < 9,"Prx %d is not supported\n", Prx);
|
||||
LOG_I(PHY, "[gNB %d]About to wait for gNB to be configured\n", gNB->Mod_id);
|
||||
|
||||
while(gNB->configured == 0) usleep(10000);
|
||||
while(gNB->configured == 0)
|
||||
usleep(10000);
|
||||
|
||||
load_dftslib();
|
||||
|
||||
@@ -150,10 +157,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
nr_generate_modulation_table();
|
||||
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
||||
|
||||
// CSI RS init
|
||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||
gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
||||
|
||||
generate_ul_reference_signal_sequences(SHRT_MAX);
|
||||
|
||||
/* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */
|
||||
@@ -172,19 +175,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
}
|
||||
}
|
||||
|
||||
common_vars->txdataF = (c16_t **)malloc16(Ptx*sizeof(c16_t*));
|
||||
common_vars->rxdataF = (c16_t **)malloc16(Prx*sizeof(c16_t*));
|
||||
/* Do NOT allocate per-antenna txdataF/rxdataF: the gNB gets a pointer to the
|
||||
/* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the
|
||||
* RU to copy/recover freq-domain memory from there */
|
||||
common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*));
|
||||
common_vars->rxdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
|
||||
for (int i = 0; i < common_vars->num_beams_period; i++)
|
||||
common_vars->rxdataF[i] = (c16_t **)malloc16(Prx * sizeof(c16_t*));
|
||||
|
||||
for (i=0;i<Ptx;i++){
|
||||
common_vars->txdataF[i] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(c16_t)); // [hna] samples_per_frame without CP
|
||||
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
|
||||
i,common_vars->txdataF[i],
|
||||
fp->samples_per_frame_wCP*sizeof(c16_t));
|
||||
common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
|
||||
memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
|
||||
common_vars->num_beams = cfg->dbt_config.num_dig_beams;
|
||||
if (common_vars->num_beams > 0) {
|
||||
common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*));
|
||||
for (int i = 0; i < common_vars->num_beams_period; i++)
|
||||
common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
|
||||
}
|
||||
common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
|
||||
for (int i = 0; i < common_vars->num_beams_period; i++) {
|
||||
common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*));
|
||||
for (int j = 0; j < Ptx; j++)
|
||||
common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t));
|
||||
}
|
||||
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
|
||||
common_vars->debugBuff_sample_offset = 0;
|
||||
@@ -209,14 +216,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
pusch->ul_ch_estimates_time = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
|
||||
pusch->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers * sizeof(int32_t *));
|
||||
for (i = 0; i < n_buf; i++) {
|
||||
for (int i = 0; i < n_buf; i++) {
|
||||
pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot);
|
||||
pusch->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size);
|
||||
pusch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->symbols_per_slot); // symbols per slot
|
||||
pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
|
||||
}
|
||||
|
||||
for (i=0; i< max_ul_mimo_layers; i++) {
|
||||
for (int i = 0; i < max_ul_mimo_layers; i++) {
|
||||
pusch->llr_layers[i] = (int16_t *)malloc16_clear((8 * ((3 * 8 * 6144) + 12))
|
||||
* sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
|
||||
}
|
||||
@@ -224,8 +231,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
* sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
|
||||
pusch->ul_valid_re_per_slot = (int16_t *)malloc16_clear(sizeof(int16_t) * fp->symbols_per_slot);
|
||||
} // ulsch_id
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
@@ -241,8 +246,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
free_and_zero(meas->n0_subband_power);
|
||||
free_and_zero(meas->n0_subband_power_dB);
|
||||
|
||||
free_and_zero(gNB->nr_csi_info);
|
||||
|
||||
for (int id = 0; id < gNB->max_nb_srs; id++) {
|
||||
for(int i=0; i<MAX_NUM_NR_SRS_AP; i++) {
|
||||
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal[i]);
|
||||
@@ -258,13 +261,19 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
reset_nr_transport(gNB);
|
||||
|
||||
NR_gNB_COMMON * common_vars = &gNB->common_vars;
|
||||
for (int i = 0; i < Ptx; i++) {
|
||||
free_and_zero(common_vars->txdataF[i]);
|
||||
free_and_zero(common_vars->beam_id[i]);
|
||||
for (int j = 0; j < common_vars->num_beams_period; j++) {
|
||||
if (common_vars->beam_id)
|
||||
free_and_zero(common_vars->beam_id[j]);
|
||||
for (int i = 0; i < Ptx; i++) {
|
||||
free_and_zero(common_vars->txdataF[j][i]);
|
||||
}
|
||||
free_and_zero(common_vars->txdataF[j]);
|
||||
}
|
||||
|
||||
/* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the
|
||||
* RU's txdataF/rxdataF, and the RU will free that */
|
||||
for (int j = 0; j < common_vars->num_beams_period; j++)
|
||||
free_and_zero(common_vars->rxdataF[j]);
|
||||
free_and_zero(common_vars->txdataF);
|
||||
free_and_zero(common_vars->rxdataF);
|
||||
free_and_zero(common_vars->beam_id);
|
||||
@@ -495,7 +504,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB)
|
||||
|
||||
gNB->max_nb_pucch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
|
||||
gNB->max_nb_pusch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
|
||||
gNB->max_nb_srs = buffer_ul_slots << 1; // assuming at most 2 SRS per slot
|
||||
gNB->max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot
|
||||
|
||||
gNB->pucch = (NR_gNB_PUCCH_t *)malloc16(gNB->max_nb_pucch * sizeof(NR_gNB_PUCCH_t));
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
|
||||
@@ -29,31 +29,35 @@
|
||||
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
|
||||
int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
int nr_phy_init_RU(RU_t *ru)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int i,j;
|
||||
int p;
|
||||
int re;
|
||||
|
||||
LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d, nb_rx %d\n",ru_if_types[ru->if_south],ru->nb_tx, ru->nb_rx);
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg;
|
||||
ru->nb_log_antennas=0;
|
||||
for (int n=0;n<ru->num_gNB;n++) {
|
||||
cfg = &ru->config;
|
||||
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->config;
|
||||
ru->nb_log_antennas = 0;
|
||||
for (int n = 0; n < ru->num_gNB; n++) {
|
||||
if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas)
|
||||
ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
|
||||
}
|
||||
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH)
|
||||
|
||||
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration
|
||||
// (at least the parts that are needed by the RU, numerology and PRACH)
|
||||
|
||||
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
|
||||
|
||||
ru->common.beam_id = malloc16_clear(MAX_NUM_BEAM_PERIODS * sizeof(int*));
|
||||
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; i++)
|
||||
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
|
||||
// Time-domain signals
|
||||
ru->common.txdata = (int32_t**)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
ru->common.rxdata = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
|
||||
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
// Allocate 10 subframes of I/Q TX signal data (time) if not
|
||||
ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t));
|
||||
LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i],
|
||||
@@ -63,7 +67,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
LOG_I(PHY,"[INIT] common.txdata[%d] = %p \n",i,ru->common.txdata[i]);
|
||||
|
||||
}
|
||||
for (i=0;i<ru->nb_rx;i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdata[i] = (int32_t*)malloc16_clear( fp->samples_per_frame*sizeof(int32_t) );
|
||||
}
|
||||
} // IF5 or local RF
|
||||
@@ -76,7 +80,7 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
|
||||
LOG_I(PHY,"nb_tx %d\n",ru->nb_tx);
|
||||
ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
for (i=0;i<ru->nb_rx;i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
ru->common.rxdata_7_5kHz[i] = (int32_t*)malloc16_clear( 2*fp->samples_per_subframe*2*sizeof(int32_t) );
|
||||
LOG_I(PHY,"rxdata_7_5kHz[%d] %p for RU %d\n",i,ru->common.rxdata_7_5kHz[i],ru->idx);
|
||||
}
|
||||
@@ -84,31 +88,33 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
// allocate precoding input buffers (TX)
|
||||
ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
for(i=0; i< ru->nb_tx; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
|
||||
// [hna] samples_per_frame without CP
|
||||
for(int i = 0; i < ru->nb_tx; ++i)
|
||||
ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||
|
||||
// allocate IFFT input buffers (TX)
|
||||
ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
|
||||
LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF,
|
||||
ru->nb_tx*sizeof(int32_t*));
|
||||
for (i=0; i<ru->nb_tx; i++) {
|
||||
LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, ru->nb_tx*sizeof(int32_t*));
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP*sizeof(int32_t) );
|
||||
LOG_I(PHY,"txdataF_BF[%d] %p for RU %d\n",i,ru->common.txdataF_BF[i],ru->idx);
|
||||
}
|
||||
// allocate FFT output buffers (RX)
|
||||
ru->common.rxdataF = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) );
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
// allocate 4 slots of I/Q signal data (frequency)
|
||||
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF)*(RU_RX_SLOT_DEPTH*fp->symbols_per_slot*fp->ofdm_symbol_size) );
|
||||
int size = RU_RX_SLOT_DEPTH * fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
ru->common.rxdataF[i] = (int32_t*)malloc16_clear(sizeof(**ru->common.rxdataF) * size);
|
||||
LOG_I(PHY,"rxdataF[%d] %p for RU %d\n",i,ru->common.rxdataF[i],ru->idx);
|
||||
}
|
||||
|
||||
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
|
||||
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
// "nb_antennas_rx too large");
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
// largest size for PRACH FFT is 4x98304 (16*24576)
|
||||
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
|
||||
@@ -120,44 +126,8 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
int beam_count = 0;
|
||||
if (ru->nb_tx>1) { //Enable beamforming when nb_tx > 1
|
||||
|
||||
for (p=0;p<ru->nb_log_antennas;p++) {
|
||||
//if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
|
||||
beam_count++;
|
||||
}
|
||||
AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
|
||||
|
||||
for (i=0; i<ru->num_gNB; i++) {
|
||||
int l_ind = 0;
|
||||
for (p=0;p<ru->nb_log_antennas;p++) {
|
||||
//if ((fp->L_ssb >> (63-p)) & 0x01) {
|
||||
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
|
||||
for (j=0; j<ru->nb_tx; j++) {
|
||||
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i);
|
||||
for (re=0; re<fp->ofdm_symbol_size; re++)
|
||||
ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
|
||||
//printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
|
||||
l_ind++;
|
||||
} // for j
|
||||
//}
|
||||
} // for p
|
||||
} // for i
|
||||
}
|
||||
|
||||
ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
|
||||
for(i=0; i< ru->nb_tx; ++i) {
|
||||
ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
|
||||
memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
|
||||
}
|
||||
}
|
||||
} // !=IF5
|
||||
|
||||
ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
|
||||
|
||||
init_prach_ru_list(ru);
|
||||
|
||||
return(0);
|
||||
@@ -165,56 +135,48 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
|
||||
void nr_phy_free_RU(RU_t *ru)
|
||||
{
|
||||
int i,j;
|
||||
int p;
|
||||
|
||||
LOG_I(PHY, "Freeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx);
|
||||
|
||||
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals
|
||||
// Hack: undo what is done at allocation
|
||||
for (i = 0; i < ru->nb_tx; i++) {
|
||||
for (int i = 0; i < ru->nb_tx; i++) {
|
||||
int32_t *p = &ru->common.txdata[i][-ru->sf_extension];
|
||||
free_and_zero(p);
|
||||
}
|
||||
free_and_zero(ru->common.txdata);
|
||||
|
||||
for (i = 0; i < ru->nb_rx; i++)
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdata[i]);
|
||||
free_and_zero(ru->common.rxdata);
|
||||
} // else: IF5 or local RF -> nothing to free()
|
||||
|
||||
if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing
|
||||
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]);
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdata_7_5kHz[i]);
|
||||
free_and_zero(ru->common.rxdata_7_5kHz);
|
||||
|
||||
// free beamforming input buffers (TX)
|
||||
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF[i]);
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
free_and_zero(ru->common.txdataF[i]);
|
||||
free_and_zero(ru->common.txdataF);
|
||||
|
||||
// free IFFT input buffers (TX)
|
||||
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]);
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
free_and_zero(ru->common.txdataF_BF[i]);
|
||||
free_and_zero(ru->common.txdataF_BF);
|
||||
|
||||
// free FFT output buffers (RX)
|
||||
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
for (i = 0; i < ru->nb_rx; i++)
|
||||
for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
free_and_zero(ru->prach_rxsigF[j][i]);
|
||||
free_and_zero(ru->prach_rxsigF[j]);
|
||||
}
|
||||
if (ru->do_precoding == 1) {
|
||||
for (i = 0; i < ru->num_gNB; i++) {
|
||||
for (p = 0; p < ru->nb_log_antennas; p++) {
|
||||
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
|
||||
free_and_zero(ru->beam_weights[i][p]);
|
||||
}
|
||||
}
|
||||
for(i=0; i< ru->nb_tx; ++i)
|
||||
free_and_zero(ru->common.beam_id[i]);
|
||||
free_and_zero(ru->common.beam_id);
|
||||
}
|
||||
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; ++i)
|
||||
free_and_zero(ru->common.beam_id[i]);
|
||||
free_and_zero(ru->common.beam_id);
|
||||
}
|
||||
free_and_zero(ru->common.sync_corr);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB);
|
||||
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
|
||||
void init_N_TA_offset(PHY_VARS_NR_UE *ue);
|
||||
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
|
||||
int phy_init_nr_gNB(PHY_VARS_gNB *gNB);
|
||||
void phy_init_nr_gNB(PHY_VARS_gNB *gNB);
|
||||
int init_codebook_gNB(PHY_VARS_gNB *gNB);
|
||||
void nr_phy_config_request(NR_PHY_Config_t *gNB);
|
||||
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
|
||||
|
||||
@@ -137,32 +137,25 @@ int beam_precoding_one_eNB(int32_t **txdataF,
|
||||
}
|
||||
|
||||
|
||||
int nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset)
|
||||
void nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset)
|
||||
{
|
||||
|
||||
|
||||
uint8_t p;
|
||||
|
||||
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
|
||||
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, sizeof(c16_t) *(frame_parms->ofdm_symbol_size));
|
||||
|
||||
for (p=0; p<nb_antenna_ports; p++) {
|
||||
//if ((frame_parms->L_ssb >> (63-p)) & 0x01) {
|
||||
multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
|
||||
(int16_t*)beam_weights[p][aa],
|
||||
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
//}
|
||||
for (int p = 0; p < nb_antenna_ports; p++) {
|
||||
multadd_cpx_vector((int16_t*)&txdataF[p][(symbol*frame_parms->ofdm_symbol_size)+offset],
|
||||
(int16_t*)beam_weights[p][aa],
|
||||
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,16 +95,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
*/
|
||||
void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH);
|
||||
|
||||
int nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset
|
||||
);
|
||||
void nr_beam_precoding(c16_t **txdataF,
|
||||
c16_t **txdataF_BF,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t ***beam_weights,
|
||||
int slot,
|
||||
int symbol,
|
||||
int aa,
|
||||
int nb_antenna_ports,
|
||||
int offset);
|
||||
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
|
||||
@@ -119,7 +119,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
NR_gNB_COMMON *common_vars = &gNB->common_vars;
|
||||
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
|
||||
int rb, nb_symb[275]={0};
|
||||
int nb_symb[275]={0};
|
||||
|
||||
allocCast2D(n0_subband_power,
|
||||
unsigned int,
|
||||
@@ -135,20 +135,20 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
|
||||
frame_parms->N_RB_UL,
|
||||
false);
|
||||
|
||||
for (int s=first_symb;s<(first_symb+num_symb);s++) {
|
||||
// TODO modify the measurements to take into account concurrent beams
|
||||
for (int s = first_symb; s < first_symb + num_symb; s++) {
|
||||
int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
|
||||
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
|
||||
for (int rb = 0; rb < frame_parms->N_RB_UL; rb++) {
|
||||
if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe
|
||||
!(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT
|
||||
int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
||||
nb_symb[rb]++;
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
c16_t *ul_ch = &common_vars->rxdataF[aarx][offset];
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
c16_t *ul_ch = &common_vars->rxdataF[0][aarx][offset];
|
||||
int32_t signal_energy;
|
||||
if (((frame_parms->N_RB_UL&1) == 1) &&
|
||||
(rb==(frame_parms->N_RB_UL>>1))) {
|
||||
if (((frame_parms->N_RB_UL & 1) == 1) && (rb == (frame_parms->N_RB_UL >> 1))) {
|
||||
signal_energy = signal_energy_nodc(ul_ch, 6);
|
||||
ul_ch = &common_vars->rxdataF[aarx][offset0];
|
||||
ul_ch = &common_vars->rxdataF[0][aarx][offset0];
|
||||
signal_energy += signal_energy_nodc(ul_ch, 6);
|
||||
} else {
|
||||
signal_energy = signal_energy_nodc(ul_ch, 12);
|
||||
|
||||
@@ -71,6 +71,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
int ul_id,
|
||||
int beam_nb,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
int *max_ch,
|
||||
@@ -153,7 +154,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
memset(delay, 0, sizeof(*delay));
|
||||
|
||||
for (int aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
|
||||
c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[aarx][symbol_offset + slot_offset];
|
||||
c16_t *rxdataF = (c16_t *)&gNB->common_vars.rxdataF[beam_nb][aarx][symbol_offset + slot_offset];
|
||||
c16_t *ul_ch = &ul_ch_estimates[nl * gNB->frame_parms.nb_antennas_rx + aarx][symbol_offset];
|
||||
|
||||
memset(ul_ch, 0, sizeof(*ul_ch) * symbolSize);
|
||||
@@ -596,17 +597,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
} // Antenna loop
|
||||
}
|
||||
|
||||
uint32_t calc_power(const int16_t *x, const uint32_t size) {
|
||||
int64_t sum_x = 0;
|
||||
int64_t sum_x2 = 0;
|
||||
for(int k = 0; k<size; k++) {
|
||||
sum_x = sum_x + x[k];
|
||||
sum_x2 = sum_x2 + x[k]*x[k];
|
||||
}
|
||||
|
||||
return sum_x2/size - (sum_x/size)*(sum_x/size);
|
||||
}
|
||||
|
||||
int nr_srs_channel_estimation(
|
||||
const PHY_VARS_gNB *gNB,
|
||||
const int frame,
|
||||
@@ -643,27 +633,20 @@ int nr_srs_channel_estimation(
|
||||
|
||||
const uint32_t arr_len = frame_parms->nb_antennas_rx * N_ap * M_sc_b_SRS;
|
||||
|
||||
int16_t ch_real[arr_len];
|
||||
memset(ch_real, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t ch_imag[arr_len];
|
||||
memset(ch_imag, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t noise_real[arr_len];
|
||||
memset(noise_real, 0, arr_len * sizeof(int16_t));
|
||||
|
||||
int16_t noise_imag[arr_len];
|
||||
memset(noise_imag, 0, arr_len * sizeof(int16_t));
|
||||
c16_t ch[arr_len];
|
||||
memset(ch, 0, arr_len * sizeof(c16_t));
|
||||
|
||||
int16_t ls_estimated[2];
|
||||
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) >> 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 multadd_real_vector_complex_scalar applies the remaining 8 zeros of filter, therefore, to avoid a buffer overflow,
|
||||
// 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)));
|
||||
int32_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++) {
|
||||
|
||||
@@ -681,14 +664,12 @@ int nr_srs_channel_estimation(
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
int16_t *srs_estimated_channel16 = (int16_t *)&srs_est[subcarrier + mem_offset];
|
||||
c16_t *srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier + mem_offset];
|
||||
|
||||
for (int k = 0; k < M_sc_b_SRS; k++) {
|
||||
|
||||
if (k%fd_cdm==0) {
|
||||
|
||||
ls_estimated[0] = 0;
|
||||
ls_estimated[1] = 0;
|
||||
ls_estimated = (c16_t){0, 0};
|
||||
uint16_t subcarrier_cdm = subcarrier;
|
||||
|
||||
for (int cdm_idx = 0; cdm_idx < fd_cdm; cdm_idx++) {
|
||||
@@ -700,8 +681,8 @@ int nr_srs_channel_estimation(
|
||||
|
||||
// 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 bits.
|
||||
ls_estimated[0] += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
|
||||
ls_estimated[1] += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
|
||||
ls_estimated.r += (int16_t)(((int32_t)generated_real*received_real + (int32_t)generated_imag*received_imag)>>nr_srs_info->srs_generated_signal_bits);
|
||||
ls_estimated.i += (int16_t)(((int32_t)generated_real*received_imag - (int32_t)generated_imag*received_real)>>nr_srs_info->srs_generated_signal_bits);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier_cdm += K_TC;
|
||||
@@ -711,8 +692,7 @@ int nr_srs_channel_estimation(
|
||||
}
|
||||
}
|
||||
|
||||
srs_ls_estimated_channel[subcarrier].r = ls_estimated[0];
|
||||
srs_ls_estimated_channel[subcarrier].i = ls_estimated[1];
|
||||
srs_ls_estimated_channel[subcarrier] = ls_estimated;
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
int subcarrier_log = subcarrier-subcarrier_offset;
|
||||
@@ -727,48 +707,48 @@ int nr_srs_channel_estimation(
|
||||
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,
|
||||
ls_estimated[0], ls_estimated[1]);
|
||||
ls_estimated.r, ls_estimated.i);
|
||||
#endif
|
||||
|
||||
const uint16_t sc_offset = subcarrier + mem_offset;
|
||||
|
||||
// Channel interpolation
|
||||
if(srs_pdu->comb_size == 0) {
|
||||
if(k == 0) { // First subcarrier case
|
||||
if (srs_pdu->comb_size == 0) {
|
||||
if (k == 0) { // First subcarrier case
|
||||
// filt8_start is {12288,8192,4096,0,0,0,0,0}
|
||||
multadd_real_vector_complex_scalar(filt8_start, ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
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 = (int16_t *)&srs_est[subcarrier];
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[subcarrier];
|
||||
const short *filter = mem_offset == 0 ? filt8_start : filt8_start_shift2;
|
||||
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt8_end is {4096,8192,12288,16384,0,0,0,0}
|
||||
const short *filter = mem_offset == 0 || k == (M_sc_b_SRS - 1) ? filt8_end : filt8_end_shift2;
|
||||
multadd_real_vector_complex_scalar(filter, ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if(k%2 == 1) { // 1st middle case
|
||||
c16multaddVectRealComplex(filter, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 1) { // 1st middle case
|
||||
// filt8_middle2 is {4096,8192,8192,8192,4096,0,0,0}
|
||||
multadd_real_vector_complex_scalar(filt8_middle2, ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if(k%2 == 0) { // 2nd middle case
|
||||
c16multaddVectRealComplex(filt8_middle2, &ls_estimated, srs_estimated_channel16, 8);
|
||||
} else if (k % 2 == 0) { // 2nd middle case
|
||||
// filt8_middle4 is {0,0,4096,8192,8192,8192,4096,0}
|
||||
multadd_real_vector_complex_scalar(filt8_middle4, ls_estimated, srs_estimated_channel16, 8);
|
||||
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
|
||||
c16multaddVectRealComplex(filt8_middle4, &ls_estimated, srs_estimated_channel16, 8);
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset];
|
||||
}
|
||||
} else {
|
||||
if(k == 0) { // First subcarrier case
|
||||
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}
|
||||
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if(subcarrier < K_TC) { // Start of OFDM symbol case
|
||||
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
|
||||
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];
|
||||
// filt16_start is {12288,8192,8192,8192,4096,0,0,0,0,0,0,0,0,0,0,0}
|
||||
multadd_real_vector_complex_scalar(filt16_start, ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if((subcarrier+K_TC)>=frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS-1)) { // End of OFDM symbol or last subcarrier cases
|
||||
c16multaddVectRealComplex(filt16_start, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else if ((subcarrier + K_TC) >= frame_parms->ofdm_symbol_size || k == (M_sc_b_SRS - 1)) { // End of OFDM symbol or last subcarrier cases
|
||||
// filt16_end is {4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0}
|
||||
multadd_real_vector_complex_scalar(filt16_end, ls_estimated, srs_estimated_channel16, 16);
|
||||
c16multaddVectRealComplex(filt16_end, &ls_estimated, srs_estimated_channel16, 16);
|
||||
} else { // Middle case
|
||||
// filt16_middle4 is {4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0}
|
||||
multadd_real_vector_complex_scalar(filt16_middle4, ls_estimated, srs_estimated_channel16, 16);
|
||||
srs_estimated_channel16 = (int16_t *)&srs_est[sc_offset];
|
||||
c16multaddVectRealComplex(filt16_middle4, &ls_estimated, srs_estimated_channel16, 16);
|
||||
srs_estimated_channel16 = (c16_t *)&srs_est[sc_offset];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,15 +769,14 @@ int nr_srs_channel_estimation(
|
||||
if (subcarrier>frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS;
|
||||
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_real[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].r;
|
||||
ch_imag[base_idx+k] = ((c16_t*)srs_estimated_channel_freq[ant][p_index])[subcarrier].i;
|
||||
noise_real[base_idx+k] = abs(srs_ls_estimated_channel[subcarrier].r - ch_real[base_idx+k]);
|
||||
noise_imag[base_idx+k] = abs(srs_ls_estimated_channel[subcarrier].i - ch_imag[base_idx+k]);
|
||||
ch[base_idx + k] = ((c16_t *)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;
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
|
||||
subcarrier = subcarrier - frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,9 +802,10 @@ 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,
|
||||
noise_real[base_idx+(k/K_TC)], noise_imag[base_idx+(k/K_TC)]);
|
||||
((c16_t *)srs_estimated_channel_freq[ant][p_index])[subcarrier].r,
|
||||
((c16_t *)srs_estimated_channel_freq[ant][p_index])[subcarrier].i,
|
||||
noise[base_idx + (k / K_TC)].r,
|
||||
noise[base_idx + (k / K_TC)].i);
|
||||
|
||||
// Subcarrier increment
|
||||
subcarrier++;
|
||||
@@ -852,7 +832,7 @@ int nr_srs_channel_estimation(
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
|
||||
// Compute signal power
|
||||
uint32_t signal_power = calc_power(ch_real, arr_len) + calc_power(ch_imag, arr_len);
|
||||
uint32_t signal_power = max(signal_energy_nodc(ch, arr_len), 1);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"signal_power = %u\n", signal_power);
|
||||
@@ -864,11 +844,6 @@ int nr_srs_channel_estimation(
|
||||
}
|
||||
|
||||
// Compute noise power
|
||||
|
||||
const uint8_t signal_power_bits = log2_approx(signal_power);
|
||||
const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x)
|
||||
const int32_t factor_dB = dB_fixed(1<<factor_bits);
|
||||
|
||||
const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3;
|
||||
const uint8_t n_noise_est = frame_parms->nb_antennas_rx*N_ap*srs_symbols_per_rb;
|
||||
uint64_t sum_re = 0;
|
||||
@@ -885,19 +860,19 @@ int nr_srs_channel_estimation(
|
||||
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) {
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
uint16_t base_idx = ant*N_ap*M_sc_b_SRS + p_index*M_sc_b_SRS + rb*srs_symbols_per_rb;
|
||||
uint16_t base_idx = ant * N_ap * M_sc_b_SRS + p_index * M_sc_b_SRS + rb * srs_symbols_per_rb;
|
||||
for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++) {
|
||||
sum_re = sum_re + noise_real[base_idx+srs_symb];
|
||||
sum_re2 = sum_re2 + noise_real[base_idx+srs_symb]*noise_real[base_idx+srs_symb];
|
||||
sum_im = sum_im + noise_imag[base_idx+srs_symb];
|
||||
sum_im2 = sum_im2 + noise_imag[base_idx+srs_symb]*noise_imag[base_idx+srs_symb];
|
||||
sum_re = sum_re + noise[base_idx + srs_symb].r;
|
||||
sum_re2 = sum_re2 + noise[base_idx + srs_symb].r * noise[base_idx + srs_symb].r;
|
||||
sum_im = sum_im + noise[base_idx + srs_symb].i;
|
||||
sum_im2 = sum_im2 + noise[base_idx + srs_symb].i * noise[base_idx + srs_symb].i;
|
||||
} // for (int srs_symb = 0; srs_symb < srs_symbols_per_rb; srs_symb++)
|
||||
} // for (int p_index = 0; p_index < N_ap; p_index++)
|
||||
} // for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++)
|
||||
|
||||
noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) +
|
||||
sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1);
|
||||
snr_per_rb[rb] = dB_fixed((int32_t)((signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB;
|
||||
snr_per_rb[rb] = dB_fixed(signal_power) - dB_fixed(noise_power_per_rb[rb]);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]);
|
||||
@@ -905,9 +880,9 @@ int nr_srs_channel_estimation(
|
||||
|
||||
} // for (int rb = 0; rb < m_SRS_b; rb++)
|
||||
|
||||
const uint32_t noise_power = max(calc_power(noise_real, arr_len) + calc_power(noise_imag, arr_len), 1);
|
||||
const uint32_t noise_power = max(signal_energy_nodc(noise, arr_len), 1);
|
||||
|
||||
*snr = dB_fixed((int32_t)((signal_power<<factor_bits)/(noise_power))) - factor_dB;
|
||||
*snr = dB_fixed(signal_power) - dB_fixed(noise_power);
|
||||
|
||||
#ifdef SRS_DEBUG
|
||||
LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", noise_power, *snr);
|
||||
|
||||
@@ -47,6 +47,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
int ul_id,
|
||||
int beam_nb,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
int *max_ch,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
|
||||
|
||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
@@ -40,17 +41,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **dataF,
|
||||
const int16_t amp,
|
||||
nr_csi_info_t *nr_csi_info,
|
||||
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
const int slot,
|
||||
uint8_t *N_cdm_groups,
|
||||
uint8_t *CDM_group_size,
|
||||
uint8_t *k_prime,
|
||||
uint8_t *l_prime,
|
||||
uint8_t *N_ports,
|
||||
uint8_t *j_cdm,
|
||||
uint8_t *k_overline,
|
||||
uint8_t *l_overline);
|
||||
const csi_mapping_parms_t *phy_csi_parms);
|
||||
|
||||
void init_scrambling_luts(void);
|
||||
void nr_generate_modulation_table(void);
|
||||
|
||||
@@ -27,17 +27,9 @@
|
||||
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **dataF,
|
||||
const int16_t amp,
|
||||
nr_csi_info_t *nr_csi_info,
|
||||
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
const int slot,
|
||||
uint8_t *N_cdm_groups,
|
||||
uint8_t *CDM_group_size,
|
||||
uint8_t *k_prime,
|
||||
uint8_t *l_prime,
|
||||
uint8_t *N_ports,
|
||||
uint8_t *j_cdm,
|
||||
uint8_t *k_overline,
|
||||
uint8_t *l_overline)
|
||||
const csi_mapping_parms_t *phy_csi_parms)
|
||||
{
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
|
||||
@@ -56,405 +48,34 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss);
|
||||
#endif
|
||||
|
||||
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
//*8(max allocation per RB)*2(QPSK))
|
||||
int csi_rs_length = frame_parms->N_RB_DL << 4;
|
||||
int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
|
||||
uint16_t b = csi_params->freq_domain;
|
||||
uint32_t beta = amp;
|
||||
nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp);
|
||||
|
||||
AssertFatal(b != 0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||
int size, ports, kprime, lprime;
|
||||
int j[16], k_n[6], koverline[16], loverline[16];
|
||||
int found = 0;
|
||||
int fi = 0;
|
||||
// implementation of table 7.4.1.5.3-1 of 38.211
|
||||
// lprime and kprime are the max value of l' and k'
|
||||
switch (csi_params->row) {
|
||||
case 1:
|
||||
ports = 1;
|
||||
kprime = 0;
|
||||
lprime = 0;
|
||||
size = 3;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0] + (i<<2);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ports = 1;
|
||||
kprime = 0;
|
||||
lprime = 0;
|
||||
size = 1;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ports = 2;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 1;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = 0;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
ports = 4;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 2;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 2;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[0] + (i << 1);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
ports = 4;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 2;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0 + i;
|
||||
koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
ports = 8;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
ports = 8;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 4;
|
||||
while (found < 2) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0 + (i >> 1);
|
||||
koverline[i] = k_n[i % 2];
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
ports = 8;
|
||||
kprime = 1;
|
||||
lprime = 1;
|
||||
size = 2;
|
||||
while (found < 2) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
ports = 12;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 6;
|
||||
while (found < 6) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
ports = 12;
|
||||
kprime = 1;
|
||||
lprime = 1;
|
||||
size = 3;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
ports = 16;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 8;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0 + (i >> 2);
|
||||
koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
ports = 16;
|
||||
kprime = 1;
|
||||
lprime = 1;
|
||||
size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
ports = 24;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 12;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
if (i < 6)
|
||||
loverline[i] = csi_params->symb_l0 + i / 3;
|
||||
else
|
||||
loverline[i] = csi_params->symb_l1 + i / 9;
|
||||
koverline[i] = k_n[i % 3];
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
ports = 24;
|
||||
kprime = 1;
|
||||
lprime = 1;
|
||||
size = 6;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
if (i < 3)
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
else
|
||||
loverline[i] = csi_params->symb_l1;
|
||||
koverline[i] = k_n[i%3];
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
ports = 24;
|
||||
kprime = 1;
|
||||
lprime = 3;
|
||||
size = 3;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
ports = 32;
|
||||
kprime = 1;
|
||||
lprime = 0;
|
||||
size = 16;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
if (i < 8)
|
||||
loverline[i] = csi_params->symb_l0 + (i>>2);
|
||||
else
|
||||
loverline[i] = csi_params->symb_l1 + (i/12);
|
||||
koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
ports = 32;
|
||||
kprime = 1;
|
||||
lprime = 1;
|
||||
size = 8;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
if (i < 4)
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
else
|
||||
loverline[i] = csi_params->symb_l1;
|
||||
koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
ports = 32;
|
||||
kprime = 1;
|
||||
lprime = 3;
|
||||
size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
j[i] = i;
|
||||
loverline[i] = csi_params->symb_l0;
|
||||
koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params->row);
|
||||
}
|
||||
// setting the frequency density from its index
|
||||
double rho = get_csi_rho(csi_params->freq_density);
|
||||
int csi_length = get_csi_modulation_length(rho,
|
||||
csi_params->freq_density,
|
||||
phy_csi_parms->kprime,
|
||||
csi_params->start_rb,
|
||||
csi_params->nr_of_rbs);
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
printf(" row %d, n. of ports %d\n k' ",csi_params->row,ports);
|
||||
for (int kp = 0; kp <= kprime; kp++)
|
||||
printf("%d, ",kp);
|
||||
printf("l' ");
|
||||
for (int lp = 0; lp <= lprime; lp++)
|
||||
printf("%d, ", lp);
|
||||
printf("\n k overline ");
|
||||
for (int i = 0; i < size; i++)
|
||||
printf("%d, ",koverline[i]);
|
||||
printf("\n l overline ");
|
||||
for (int i = 0; i < size; i++)
|
||||
printf("%d, ",loverline[i]);
|
||||
printf("\n");
|
||||
printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
|
||||
#endif
|
||||
|
||||
//*8(max allocation per RB)*2(QPSK))
|
||||
int16_t mod_csi[frame_parms->symbols_per_slot][(frame_parms->N_RB_DL << 4) >> 1] __attribute__((aligned(16)));
|
||||
get_modulated_csi_symbols(frame_parms->symbols_per_slot,
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
csi_length,
|
||||
mod_csi,
|
||||
phy_csi_parms->lprime,
|
||||
csi_params->symb_l0,
|
||||
csi_params->symb_l1,
|
||||
csi_params->row,
|
||||
csi_params->scramb_id);
|
||||
|
||||
// setting the frequency density from its index
|
||||
double rho = 0;
|
||||
switch (csi_params->freq_density) {
|
||||
case 0:
|
||||
rho = 0.5;
|
||||
break;
|
||||
case 1:
|
||||
rho = 0.5;
|
||||
break;
|
||||
case 2:
|
||||
rho = 1;
|
||||
break;
|
||||
case 3:
|
||||
rho = 3;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid frequency density index for CSI\n");
|
||||
}
|
||||
|
||||
uint32_t beta = get_csi_beta_amplitude(amp, csi_params->power_control_offset_ss);
|
||||
double alpha = 0;
|
||||
if (ports == 1)
|
||||
if (phy_csi_parms->ports == 1)
|
||||
alpha = rho;
|
||||
else
|
||||
alpha = 2 * rho;
|
||||
@@ -464,167 +85,22 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
#endif
|
||||
|
||||
// CDM group size from CDM type index
|
||||
int gs = 0;
|
||||
switch (csi_params->cdm_type) {
|
||||
case 0:
|
||||
gs = 1;
|
||||
break;
|
||||
case 1:
|
||||
gs = 2;
|
||||
break;
|
||||
case 2:
|
||||
gs = 4;
|
||||
break;
|
||||
case 3:
|
||||
gs = 8;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid cdm type index for CSI\n");
|
||||
}
|
||||
int gs = get_cdm_group_size(csi_params->cdm_type);
|
||||
|
||||
int csi_length;
|
||||
if (rho < 1) {
|
||||
if (csi_params->freq_density == 0) {
|
||||
csi_length = (((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) << 1;
|
||||
} else {
|
||||
csi_length = ((((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) + 1) << 1;
|
||||
}
|
||||
} else {
|
||||
csi_length = (((uint16_t) rho * (csi_params->start_rb + csi_params->nr_of_rbs)) << kprime) << 1;
|
||||
}
|
||||
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
|
||||
#endif
|
||||
|
||||
if (N_cdm_groups)
|
||||
*N_cdm_groups = size;
|
||||
if (CDM_group_size)
|
||||
*CDM_group_size = gs;
|
||||
if (k_prime)
|
||||
*k_prime = kprime;
|
||||
if (l_prime)
|
||||
*l_prime = lprime;
|
||||
if (N_ports)
|
||||
*N_ports = ports;
|
||||
if (j_cdm)
|
||||
memcpy(j_cdm, j, 16 * sizeof(uint8_t));
|
||||
if (k_overline)
|
||||
memcpy(k_overline, koverline, 16 * sizeof(uint8_t));
|
||||
if (l_overline)
|
||||
memcpy(l_overline, loverline, 16 * sizeof(uint8_t));
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
if (N_ports)
|
||||
LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports);
|
||||
if (N_cdm_groups)
|
||||
LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups);
|
||||
if (CDM_group_size)
|
||||
LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size);
|
||||
if (k_prime)
|
||||
LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime);
|
||||
if (l_prime)
|
||||
LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime);
|
||||
if (N_cdm_groups) {
|
||||
for(int ji = 0; ji < *N_cdm_groups; ji++) {
|
||||
LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (csi_params->csi_type == 2) // ZP-CSI
|
||||
return;
|
||||
|
||||
// assuming amp is the amplitude of SSB channels
|
||||
switch (csi_params->power_control_offset_ss) {
|
||||
case 0:
|
||||
beta = (amp*ONE_OVER_SQRT2_Q15)>>15;
|
||||
break;
|
||||
case 1:
|
||||
beta = amp;
|
||||
break;
|
||||
case 2:
|
||||
beta = (amp*ONE_OVER_SQRT2_Q15)>>14;
|
||||
break;
|
||||
case 3:
|
||||
beta = amp << 1;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid SS power offset density index for CSI\n");
|
||||
}
|
||||
|
||||
for (int lp = 0; lp <= lprime; lp++) {
|
||||
int symb = csi_params->symb_l0;
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
uint8_t row = csi_params->row;
|
||||
if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) {
|
||||
symb = csi_params->symb_l1;
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset;
|
||||
|
||||
// resource mapping according to 38.211 7.4.1.5.3
|
||||
for (int n = csi_params->start_rb; n < (csi_params->start_rb + csi_params->nr_of_rbs); n++) {
|
||||
if ((csi_params->freq_density > 1) || (csi_params->freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB
|
||||
for (int ji = 0; ji < size; ji++) { // loop over CDM groups
|
||||
for (int s = 0 ; s < gs; s++) { // loop over each CDM group size
|
||||
int p = s + j[ji] * gs; // port index
|
||||
for (int kp = 0; kp <= kprime; kp++) { // loop over frequency resource elements within a group
|
||||
// frequency index of current resource element
|
||||
int k = (start_sc + (n * NR_NB_SC_PER_RB) + koverline[ji] + kp) % (frame_parms->ofdm_symbol_size);
|
||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
|
||||
int na = n * alpha;
|
||||
int kpn = (rho * koverline[ji]) / NR_NB_SC_PER_RB;
|
||||
int mprime = na + kp + kpn; // sequence index
|
||||
for (int lp = 0; lp <= lprime; lp++) { // loop over frequency resource elements within a group
|
||||
int l = lp + loverline[ji];
|
||||
// wt according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
int wt;
|
||||
if (s < 2)
|
||||
wt = 1;
|
||||
else if (s < 4)
|
||||
wt = -2*(lp % 2) + 1;
|
||||
else if (s < 6)
|
||||
wt = -2 * (lp / 2) + 1;
|
||||
else {
|
||||
if ((lp == 0) || (lp == 3))
|
||||
wt = 1;
|
||||
else
|
||||
wt = -1;
|
||||
}
|
||||
int index = ((l * frame_parms->ofdm_symbol_size + k) << 1) + (2 * dataF_offset);
|
||||
((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
|
||||
((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",
|
||||
l,
|
||||
k,
|
||||
mprime,
|
||||
p + 3000,
|
||||
((int16_t*)dataF[p])[index],
|
||||
((int16_t*)dataF[p])[index + 1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
csi_rs_resource_mapping(dataF,
|
||||
frame_parms->N_RB_DL << 4,
|
||||
mod_csi,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
dataF_offset,
|
||||
frame_parms->first_carrier_offset,
|
||||
phy_csi_parms,
|
||||
csi_params->start_rb,
|
||||
csi_params->nr_of_rbs,
|
||||
alpha,
|
||||
beta,
|
||||
rho,
|
||||
gs,
|
||||
csi_params->freq_density);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "nr_sch_dmrs.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
|
||||
//#define DEBUG_PDCCH_DMRS
|
||||
//#define DEBUG_DCI
|
||||
@@ -50,17 +51,12 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3
|
||||
out[i] = in[i] ^ seq[i];
|
||||
}
|
||||
|
||||
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot) {
|
||||
|
||||
uint16_t cset_start_sc;
|
||||
uint8_t cset_start_symb, cset_nsymb;
|
||||
int k,l,k_prime,dci_idx, dmrs_idx;
|
||||
|
||||
static void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
int txdataF_offset,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot)
|
||||
{
|
||||
// fill reg list per symbol
|
||||
int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE];
|
||||
nr_fill_reg_list(reg_list, pdcch_pdu_rel15);
|
||||
@@ -68,20 +64,29 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
int rb_offset;
|
||||
int n_rb;
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
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)));
|
||||
|
||||
int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(((n_rb+rb_offset+pdcch_pdu_rel15->BWPStart)*6+15)>>4)<<4] __attribute__((aligned(16))); // 3 for the max coreset duration
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
for (int d = 0; d < pdcch_pdu_rel15->numDlDci; d++) {
|
||||
/*The coreset is initialised
|
||||
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
|
||||
* or the rb_offset for other coresets
|
||||
* in time: by its first slot and its first symbol*/
|
||||
const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
|
||||
|
||||
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
|
||||
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
||||
dci_idx = 0;
|
||||
uint32_t cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
|
||||
uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
||||
int dci_idx = 0;
|
||||
// multi-beam number (for concurrent beams)
|
||||
int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
cset_start_symb,
|
||||
pdcch_pdu_rel15->DurationSymbols);
|
||||
|
||||
LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart);
|
||||
LOG_D(NR_PHY_DCI,
|
||||
"pdcch: Coreset starting subcarrier %d on symbol %d (%d symbols)\n",
|
||||
@@ -107,16 +112,18 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
|
||||
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, mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
if(dci_pdu->RNTI!=0xFFFF) {
|
||||
for (int i=0; i<dmrs_length>>1; i++)
|
||||
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]);
|
||||
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]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -163,7 +170,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
|
||||
/// Resource mapping
|
||||
|
||||
uint16_t amp = gNB->TX_AMP;
|
||||
int32_t *txdataF = (int32_t *)&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;
|
||||
|
||||
@@ -172,20 +180,21 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) {
|
||||
// allocating rbs per symbol
|
||||
for (int reg_count = 0; reg_count < num_regs; reg_count++) {
|
||||
k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
|
||||
int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
|
||||
LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k);
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
l = cset_start_symb + symbol_idx;
|
||||
int l = cset_start_symb + symbol_idx;
|
||||
|
||||
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
|
||||
int dmrs_idx;
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
||||
dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart) * 3;
|
||||
else
|
||||
dmrs_idx = (reg_list[d][reg_count] + rb_offset) * 3;
|
||||
|
||||
k_prime = 0;
|
||||
int k_prime = 0;
|
||||
|
||||
for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
|
||||
if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
|
||||
@@ -235,16 +244,13 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
|
||||
}
|
||||
|
||||
void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
||||
int slot,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
|
||||
for (int i=0; i<msgTx->num_ul_pdcch; i++)
|
||||
nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
|
||||
for (int i=0; i<msgTx->num_dl_pdcch; i++)
|
||||
nr_generate_dci(msgTx->gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
|
||||
|
||||
void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset)
|
||||
{
|
||||
PHY_VARS_gNB *gNB = msgTx->gNB;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
for (int i = 0; i < msgTx->num_ul_pdcch; i++)
|
||||
nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
|
||||
for (int i = 0; i < msgTx->num_dl_pdcch; i++)
|
||||
nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,7 @@
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
|
||||
|
||||
void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
||||
int slot,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset);
|
||||
|
||||
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
|
||||
//#define DEBUG_DLSCH
|
||||
//#define DEBUG_DLSCH_MAPPING
|
||||
@@ -468,7 +469,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
// The Precoding matrix:
|
||||
// The Codebook Type I
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
c16_t **txdataF = gNB->common_vars.txdataF;
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
// beam number in multi-beam scenario (concurrent beams)
|
||||
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
rel15->StartSymbolIndex,
|
||||
rel15->NrOfSymbols);
|
||||
|
||||
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
|
||||
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
|
||||
@@ -477,10 +487,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
int rb = 0;
|
||||
while(rb < rel15->rbSize) {
|
||||
//get pmi info
|
||||
const int pmi = (rel15->precodingAndBeamforming.prg_size > 0) ?
|
||||
(rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && rel15->precodingAndBeamforming.prg_size > 0) ?
|
||||
(rel15->precodingAndBeamforming.prgs_list[(int)(rb+1)/rel15->precodingAndBeamforming.prg_size].pm_idx) : -1;
|
||||
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb+1)/pb->prg_size].pm_idx) : -1;
|
||||
|
||||
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
|
||||
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
|
||||
@@ -576,21 +584,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
|
||||
// TODO: handle precoding
|
||||
// this maps the layers onto antenna ports
|
||||
|
||||
// handle beamforming ID
|
||||
// each antenna port is assigned a beam_index
|
||||
// since PHY can only handle BF on slot basis we set the whole slot
|
||||
|
||||
// first check if this slot has not already been allocated to another beam
|
||||
if (gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot]==255) {
|
||||
for (int j=0;j<frame_parms->symbols_per_slot;j++)
|
||||
gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
}
|
||||
else {
|
||||
LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
|
||||
}
|
||||
}// dlsch loop
|
||||
}
|
||||
|
||||
|
||||
@@ -73,13 +73,6 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
|
||||
}
|
||||
free(harq->c);
|
||||
free(harq->pdu);
|
||||
|
||||
for (int layer = 0; layer < max_layers; layer++) {
|
||||
for (int aa = 0; aa < 64; aa++)
|
||||
free(dlsch->ue_spec_bf_weights[layer][aa]);
|
||||
free(dlsch->ue_spec_bf_weights[layer]);
|
||||
}
|
||||
free(dlsch->ue_spec_bf_weights);
|
||||
}
|
||||
|
||||
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
@@ -96,19 +89,6 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
|
||||
NR_gNB_DLSCH_t dlsch;
|
||||
|
||||
dlsch.ue_spec_bf_weights = (int32_t ***)malloc16(max_layers * sizeof(int32_t **));
|
||||
for (int layer=0; layer<max_layers; layer++) {
|
||||
dlsch.ue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *));
|
||||
|
||||
for (int aa=0; aa<64; aa++) {
|
||||
dlsch.ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t));
|
||||
|
||||
for (int re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
|
||||
dlsch.ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
|
||||
bzero(harq, sizeof(NR_DL_gNB_HARQ_t));
|
||||
harq->b = malloc16(dlsch_bytes);
|
||||
|
||||
@@ -31,23 +31,26 @@
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "openair1/PHY/NR_TRANSPORT/nr_prach.h"
|
||||
|
||||
void init_prach_list(PHY_VARS_gNB *gNB)
|
||||
{
|
||||
AssertFatal(gNB!=NULL,"gNB is null\n");
|
||||
for (int i=0; i<NUMBER_OF_NR_PRACH_MAX; i++){
|
||||
AssertFatal(gNB != NULL, "gNB is null\n");
|
||||
for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++){
|
||||
gNB->prach_vars.list[i].frame = -1;
|
||||
gNB->prach_vars.list[i].slot = -1;
|
||||
gNB->prach_vars.list[i].slot = -1;
|
||||
gNB->prach_vars.list[i].beam_nb = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id)
|
||||
{
|
||||
gNB->prach_vars.list[prach_id].frame = -1;
|
||||
gNB->prach_vars.list[prach_id].slot = -1;
|
||||
gNB->prach_vars.list[prach_id].slot = -1;
|
||||
gNB->prach_vars.list[prach_id].beam_nb = -1;
|
||||
}
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
|
||||
@@ -70,47 +73,54 @@ int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
int SFN,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
{
|
||||
int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE);
|
||||
int prach_id = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id);
|
||||
|
||||
gNB->prach_vars.list[prach_id].frame=SFN;
|
||||
gNB->prach_vars.list[prach_id].slot=Slot;
|
||||
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n",(int)sizeof(*prach_pdu),prach_id);
|
||||
memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu));
|
||||
|
||||
gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id];
|
||||
prach->frame = SFN;
|
||||
prach->slot = Slot;
|
||||
prach->beam_nb = 0;
|
||||
if (gNB->common_vars.beam_id) {
|
||||
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
// TODO no idea how to compute final prach symbol here so for now we go til the end of the slot
|
||||
int temp_nb_symbols = NR_NUMBER_OF_SYMBOLS_PER_SLOT - prach_pdu->prach_start_symbol;
|
||||
prach->beam_nb = beam_index_allocation(fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
Slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
prach_pdu->prach_start_symbol,
|
||||
temp_nb_symbols);
|
||||
}
|
||||
LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id);
|
||||
memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu));
|
||||
}
|
||||
|
||||
void init_prach_ru_list(RU_t *ru) {
|
||||
|
||||
AssertFatal(ru!=NULL,"ruis null\n");
|
||||
for (int i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
ru->prach_list[i].frame = -1;
|
||||
ru->prach_list[i].slot = -1;
|
||||
}
|
||||
pthread_mutex_init(&ru->prach_list_mutex,NULL);
|
||||
void init_prach_ru_list(RU_t *ru)
|
||||
{
|
||||
AssertFatal(ru != NULL, "ru is null\n");
|
||||
for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
ru->prach_list[i].frame = -1;
|
||||
ru->prach_list[i].slot = -1;
|
||||
}
|
||||
pthread_mutex_init(&ru->prach_list_mutex, NULL);
|
||||
}
|
||||
|
||||
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
|
||||
|
||||
AssertFatal(ru!=NULL,"ru is null\n");
|
||||
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type)
|
||||
{
|
||||
AssertFatal(ru != NULL, "ru is null\n");
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
for (uint16_t i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame,slot,i,
|
||||
for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n",
|
||||
frame,
|
||||
slot,
|
||||
i,
|
||||
ru->prach_list[i].frame,ru->prach_list[i].slot);
|
||||
if((type == SEARCH_EXIST_OR_FREE) &&
|
||||
(ru->prach_list[i].frame == -1) &&
|
||||
(ru->prach_list[i].slot == -1)) {
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
return i;
|
||||
if((type == SEARCH_EXIST_OR_FREE) && (ru->prach_list[i].frame == -1) && (ru->prach_list[i].slot == -1)) {
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
return i;
|
||||
}
|
||||
else if ((type == SEARCH_EXIST) &&
|
||||
(ru->prach_list[i].frame == frame) &&
|
||||
(ru->prach_list[i].slot == slot)) {
|
||||
else if ((type == SEARCH_EXIST) && (ru->prach_list[i].frame == frame) && (ru->prach_list[i].slot == slot)) {
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
return i;
|
||||
}
|
||||
@@ -119,55 +129,42 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach_ru(RU_t *ru,
|
||||
int SFN,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu) {
|
||||
|
||||
int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0) ,
|
||||
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
|
||||
void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
|
||||
{
|
||||
int prach_id = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
|
||||
"illegal or no prach_id found!!! prach_id %d\n",
|
||||
prach_id);
|
||||
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
ru->prach_list[prach_id].frame = SFN;
|
||||
ru->prach_list[prach_id].slot = Slot;
|
||||
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
|
||||
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
|
||||
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
|
||||
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
|
||||
ru->prach_list[prach_id].frame = SFN;
|
||||
ru->prach_list[prach_id].slot = Slot;
|
||||
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
|
||||
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
|
||||
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
|
||||
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
}
|
||||
|
||||
void free_nr_ru_prach_entry(RU_t *ru,
|
||||
int prach_id) {
|
||||
|
||||
void free_nr_ru_prach_entry(RU_t *ru, int prach_id)
|
||||
{
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
ru->prach_list[prach_id].frame = -1;
|
||||
ru->prach_list[prach_id].slot = -1;
|
||||
ru->prach_list[prach_id].slot = -1;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void rx_nr_prach_ru(RU_t *ru,
|
||||
int prachFormat,
|
||||
int numRA,
|
||||
int prachStartSymbol,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int slot) {
|
||||
|
||||
AssertFatal(ru!=NULL,"ru is null\n");
|
||||
|
||||
int16_t **rxsigF=NULL;
|
||||
NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
|
||||
int slot2=slot;
|
||||
void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol, int prachOccasion, int frame, int slot)
|
||||
{
|
||||
AssertFatal(ru != NULL,"ru is null\n");
|
||||
|
||||
int16_t **rxsigF = NULL;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int slot2 = slot;
|
||||
int16_t *prach[ru->nb_rx];
|
||||
int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value;
|
||||
|
||||
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
|
||||
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
|
||||
|
||||
int sample_offset_slot;
|
||||
if (prachStartSymbol == 0) {
|
||||
@@ -184,16 +181,24 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
|
||||
}
|
||||
|
||||
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
|
||||
LOG_D(PHY,
|
||||
"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",
|
||||
frame,
|
||||
slot,
|
||||
prachFormat,
|
||||
numRA,
|
||||
prachStartSymbol,
|
||||
prachOccasion);
|
||||
|
||||
rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
|
||||
AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5,
|
||||
"we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n");
|
||||
|
||||
for (int aa=0; aa<ru->nb_rx; aa++){
|
||||
if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe;
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2,fp,0)+sample_offset_slot-ru->N_TA_offset];
|
||||
if (prach_sequence_length == 0)
|
||||
slot2 = (slot / fp->slots_per_subframe) * fp->slots_per_subframe;
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset];
|
||||
}
|
||||
|
||||
int reps;
|
||||
@@ -202,8 +207,13 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
int mu = fp->numerology_index;
|
||||
|
||||
if (prach_sequence_length == 0) {
|
||||
LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n",
|
||||
ru->idx,frame,slot2,prachFormat,msg1_frequencystart);
|
||||
LOG_D(PHY,
|
||||
"PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n",
|
||||
ru->idx,
|
||||
frame,
|
||||
slot2,
|
||||
prachFormat,
|
||||
msg1_frequencystart);
|
||||
switch (prachFormat) {
|
||||
case 0:
|
||||
reps = 1;
|
||||
@@ -235,8 +245,14 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n",
|
||||
ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
|
||||
LOG_D(PHY,
|
||||
"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n",
|
||||
ru->idx,
|
||||
frame,
|
||||
slot,
|
||||
prachfmt[prachFormat],
|
||||
msg1_frequencystart,
|
||||
prachStartSymbol);
|
||||
switch (prachFormat) {
|
||||
case 4: //A1
|
||||
reps = 2;
|
||||
@@ -293,7 +309,9 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
dftlen = 2048 >> mu;
|
||||
}
|
||||
|
||||
//actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary
|
||||
//actually what we should be checking here is how often the current prach crosses a 0.5ms boundary.
|
||||
//I am not quite sure for which paramter set this would be the case,
|
||||
//so I will ignore it for now and just check if the prach starts on a 0.5ms boundary
|
||||
if(fp->numerology_index == 0) {
|
||||
if (prachStartSymbol == 0 || prachStartSymbol == 7)
|
||||
Ncp += 16;
|
||||
|
||||
@@ -127,7 +127,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
uint8_t ulsch_id,
|
||||
uint32_t frame,
|
||||
uint8_t slot,
|
||||
unsigned char harq_pid);
|
||||
unsigned char harq_pid,
|
||||
int beam_nb);
|
||||
|
||||
/*!
|
||||
\brief This function implements the idft transform precoding in PUSCH
|
||||
@@ -297,6 +298,7 @@ void nr_fill_srs(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu);
|
||||
|
||||
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
frame_t frame,
|
||||
slot_t slot,
|
||||
nfapi_nr_srs_pdu_t *srs_pdu,
|
||||
@@ -326,12 +328,14 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
uint8_t nr_bit);
|
||||
|
||||
void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu);
|
||||
|
||||
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdint.h>
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
|
||||
static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
|
||||
{
|
||||
@@ -71,6 +72,16 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t
|
||||
ulsch->harq_pid = harq_pid;
|
||||
ulsch->handled = 0;
|
||||
ulsch->active = true;
|
||||
ulsch->beam_nb = 0;
|
||||
if (gNB->common_vars.beam_id) {
|
||||
int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
ulsch->beam_nb = beam_index_allocation(fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
ulsch_pdu->start_symbol_index,
|
||||
ulsch_pdu->nr_of_symbols);
|
||||
}
|
||||
ulsch->frame = frame;
|
||||
ulsch->slot = slot;
|
||||
|
||||
|
||||
@@ -1394,6 +1394,7 @@ typedef struct puschSymbolProc_s {
|
||||
int16_t **llr_layers;
|
||||
int16_t *scramblingSequence;
|
||||
uint32_t nvar;
|
||||
int beam_nb;
|
||||
} puschSymbolProc_t;
|
||||
|
||||
static void nr_pusch_symbol_processing(void *arg)
|
||||
@@ -1416,7 +1417,7 @@ static void nr_pusch_symbol_processing(void *arg)
|
||||
frame_parms,
|
||||
pusch_vars,
|
||||
rel15_ul,
|
||||
gNB->common_vars.rxdataF,
|
||||
gNB->common_vars.rxdataF[rdata->beam_nb],
|
||||
(c16_t**)gNB->pusch_vars[ulsch_id].ul_ch_estimates,
|
||||
rdata->llr_layers,
|
||||
soffset,
|
||||
@@ -1471,7 +1472,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
uint8_t ulsch_id,
|
||||
uint32_t frame,
|
||||
uint8_t slot,
|
||||
unsigned char harq_pid)
|
||||
unsigned char harq_pid,
|
||||
int beam_nb)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id].harq_process->ulsch_pdu;
|
||||
@@ -1503,6 +1505,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
get_dmrs_port(nl, rel15_ul->dmrs_ports),
|
||||
symbol,
|
||||
ulsch_id,
|
||||
beam_nb,
|
||||
bwp_start_subcarrier,
|
||||
rel15_ul,
|
||||
&max_ch,
|
||||
@@ -1535,10 +1538,10 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) {
|
||||
int offset0 = ((slot & 3) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
|
||||
int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size;
|
||||
c16_t *ul_ch = &gNB->common_vars.rxdataF[aarx][offset];
|
||||
c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset];
|
||||
if (end_sc < start_sc) {
|
||||
int64_t symb_energy_aux = signal_energy_nodc(ul_ch, middle_sc - start_sc) * (middle_sc - start_sc);
|
||||
ul_ch = &gNB->common_vars.rxdataF[aarx][offset0];
|
||||
ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset0];
|
||||
symb_energy_aux += (signal_energy_nodc(ul_ch, end_sc + 1) * (end_sc + 1));
|
||||
symb_energy += symb_energy_aux / (rel15_ul->rb_size * NR_NB_SC_PER_RB);
|
||||
} else {
|
||||
@@ -1644,7 +1647,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
c16_t temp_rxFext[frame_parms->nb_antennas_rx][buffer_length] __attribute__((aligned(32)));
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
for (int nl = 0; nl < rel15_ul->nrOfLayers; nl++)
|
||||
nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[aarx],
|
||||
nr_ulsch_extract_rbs(gNB->common_vars.rxdataF[beam_nb][aarx],
|
||||
(c16_t *)pusch_vars->ul_ch_estimates[nl * frame_parms->nb_antennas_rx + aarx],
|
||||
temp_rxFext[aarx],
|
||||
(c16_t*)&ul_ch_estimates_ext[nl * frame_parms->nb_antennas_rx + aarx][meas_symbol * nb_re_pusch],
|
||||
@@ -1723,6 +1726,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
rdata->llr_layers = pusch_vars->llr_layers;
|
||||
rdata->scramblingSequence = scramblingSequence;
|
||||
rdata->nvar = nvar;
|
||||
rdata->beam_nb = beam_nb;
|
||||
|
||||
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
nr_pusch_symbol_processing(rdata);
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
|
||||
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
|
||||
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
|
||||
#include "T.h"
|
||||
|
||||
@@ -62,15 +63,25 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MODE_PNF)
|
||||
gNB->pucch[0].active = 0; // check if ture in monolithic mode
|
||||
gNB->pucch[0].active = false; // check if true in monolithic mode
|
||||
|
||||
bool found = false;
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
|
||||
if (pucch->active == 0) {
|
||||
if (pucch->active == false) {
|
||||
pucch->frame = frame;
|
||||
pucch->slot = slot;
|
||||
pucch->active = 1;
|
||||
pucch->active = true;
|
||||
pucch->beam_nb = 0;
|
||||
if (gNB->common_vars.beam_id) {
|
||||
int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
pucch->beam_nb = beam_index_allocation(fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
pucch_pdu->start_symbol_index,
|
||||
pucch_pdu->nr_of_symbols);
|
||||
}
|
||||
memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t));
|
||||
LOG_D(PHY,
|
||||
"Programming PUCCH[%d] for %d.%d, format %d, nb_harq %d, nb_sr %d, nb_csi %d\n",
|
||||
@@ -148,12 +159,12 @@ static const int16_t idft12_im[12][12] = {
|
||||
};
|
||||
//************************************************************************//
|
||||
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
{
|
||||
c16_t **rxdataF = gNB->common_vars.rxdataF;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
|
||||
|
||||
@@ -1012,13 +1023,12 @@ void init_pucch2_luts() {
|
||||
|
||||
|
||||
void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu)
|
||||
{
|
||||
|
||||
c16_t **rxdataF = gNB->common_vars.rxdataF;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
//pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
#include "T.h"
|
||||
@@ -50,11 +50,21 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
|
||||
bool found = false;
|
||||
for (int i = 0; i < gNB->max_nb_srs; i++) {
|
||||
NR_gNB_SRS_t *srs = &gNB->srs[i];
|
||||
if (srs->active == 0) {
|
||||
if (srs->active == false) {
|
||||
found = true;
|
||||
srs->frame = frame;
|
||||
srs->slot = slot;
|
||||
srs->active = 1;
|
||||
srs->active = true;
|
||||
srs->beam_nb = 0;
|
||||
if (gNB->common_vars.beam_id) {
|
||||
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
|
||||
srs->beam_nb = beam_index_allocation(fapi_beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT,
|
||||
srs_pdu->time_start_position,
|
||||
1 << srs_pdu->num_symbols);
|
||||
}
|
||||
memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t));
|
||||
break;
|
||||
}
|
||||
@@ -63,13 +73,13 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
|
||||
}
|
||||
|
||||
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
frame_t frame,
|
||||
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 **rxdataF = gNB->common_vars.rxdataF;
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
|
||||
const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot
|
||||
|
||||
@@ -177,21 +177,16 @@ bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
const nr_csi_info_t *nr_csi_info,
|
||||
const uint8_t N_cdm_groups,
|
||||
const uint8_t CDM_group_size,
|
||||
const uint8_t k_prime,
|
||||
const uint8_t l_prime,
|
||||
const uint8_t *j_cdm,
|
||||
const uint8_t *k_overline,
|
||||
const uint8_t *l_overline,
|
||||
int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
|
||||
uint32_t *rsrp,
|
||||
int *rsrp_dBm,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
static int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
const nr_csi_info_t *nr_csi_info,
|
||||
const csi_mapping_parms_t *csi_mapping,
|
||||
const int CDM_group_size,
|
||||
int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
|
||||
uint32_t *rsrp,
|
||||
int *rsrp_dBm,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
{
|
||||
const NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
uint16_t meas_count = 0;
|
||||
@@ -206,17 +201,17 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
|
||||
for (int cdm_id = 0; cdm_id < csi_mapping->size; cdm_id++) {
|
||||
for (int s = 0; s < CDM_group_size; s++) {
|
||||
|
||||
// loop over frequency resource elements within a group
|
||||
for (int kp = 0; kp <= k_prime; kp++) {
|
||||
for (int kp = 0; kp <= csi_mapping->kprime; kp++) {
|
||||
|
||||
uint16_t k = (fp->first_carrier_offset + (rb * NR_NB_SC_PER_RB) + k_overline[cdm_id] + kp) % fp->ofdm_symbol_size;
|
||||
uint16_t k = (fp->first_carrier_offset + (rb * NR_NB_SC_PER_RB) + csi_mapping->koverline[cdm_id] + kp) % fp->ofdm_symbol_size;
|
||||
|
||||
// loop over time resource elements within a group
|
||||
for (int lp = 0; lp <= l_prime; lp++) {
|
||||
uint16_t symb = lp + l_overline[cdm_id];
|
||||
for (int lp = 0; lp <= csi_mapping->lprime; lp++) {
|
||||
uint16_t symb = lp + csi_mapping->loverline[cdm_id];
|
||||
uint64_t symbol_offset = symb * fp->ofdm_symbol_size;
|
||||
c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset];
|
||||
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
@@ -230,7 +225,7 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP;
|
||||
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
|
||||
uint16_t port_tx = s + csi_mapping->j[cdm_id] * CDM_group_size;
|
||||
c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset + dataF_offset];
|
||||
LOG_I(NR_PHY,
|
||||
"l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
|
||||
@@ -278,39 +273,32 @@ uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_r
|
||||
return sum_x2 / size - (sum_x / size) * (sum_x / size);
|
||||
}
|
||||
|
||||
int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
const nr_csi_info_t *nr_csi_info,
|
||||
const int32_t **csi_rs_generated_signal,
|
||||
const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
|
||||
const uint8_t N_cdm_groups,
|
||||
const uint8_t CDM_group_size,
|
||||
const uint8_t k_prime,
|
||||
const uint8_t l_prime,
|
||||
const uint8_t N_ports,
|
||||
const uint8_t *j_cdm,
|
||||
const uint8_t *k_overline,
|
||||
const uint8_t *l_overline,
|
||||
uint8_t mem_offset,
|
||||
int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size],
|
||||
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
|
||||
int16_t *log2_re,
|
||||
int16_t *log2_maxh,
|
||||
uint32_t *noise_power) {
|
||||
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
|
||||
static int nr_csi_rs_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
const nr_csi_info_t *nr_csi_info,
|
||||
const int32_t **csi_rs_generated_signal,
|
||||
const int32_t csi_rs_received_signal[][fp->samples_per_slot_wCP],
|
||||
const csi_mapping_parms_t *csi_mapping,
|
||||
const int CDM_group_size,
|
||||
uint8_t mem_offset,
|
||||
int32_t csi_rs_ls_estimated_channel[][csi_mapping->ports][fp->ofdm_symbol_size],
|
||||
int32_t csi_rs_estimated_channel_freq[][csi_mapping->ports][fp->ofdm_symbol_size + FILTER_MARGIN],
|
||||
int16_t *log2_re,
|
||||
int16_t *log2_maxh,
|
||||
uint32_t *noise_power)
|
||||
{
|
||||
const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP;
|
||||
*noise_power = 0;
|
||||
int maxh = 0;
|
||||
int count = 0;
|
||||
|
||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||
for (int ant_rx = 0; ant_rx < fp->nb_antennas_rx; ant_rx++) {
|
||||
|
||||
/// LS channel estimation
|
||||
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
}
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
@@ -320,21 +308,21 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) {
|
||||
for (int cdm_id = 0; cdm_id < csi_mapping->size; cdm_id++) {
|
||||
for (int s = 0; s < CDM_group_size; s++) {
|
||||
|
||||
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
|
||||
uint16_t port_tx = s + csi_mapping->j[cdm_id] * CDM_group_size;
|
||||
|
||||
// loop over frequency resource elements within a group
|
||||
for (int kp = 0; kp <= k_prime; kp++) {
|
||||
for (int kp = 0; kp <= csi_mapping->kprime; kp++) {
|
||||
|
||||
uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k = kinit + k_overline[cdm_id] + kp;
|
||||
uint16_t kinit = (fp->first_carrier_offset + rb*NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
|
||||
uint16_t k = kinit + csi_mapping->koverline[cdm_id] + kp;
|
||||
|
||||
// loop over time resource elements within a group
|
||||
for (int lp = 0; lp <= l_prime; lp++) {
|
||||
uint16_t symb = lp + l_overline[cdm_id];
|
||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||
for (int lp = 0; lp <= csi_mapping->lprime; lp++) {
|
||||
uint16_t symb = lp + csi_mapping->loverline[cdm_id];
|
||||
uint64_t symbol_offset = symb * fp->ofdm_symbol_size;
|
||||
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
@@ -357,10 +345,10 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
if(!is_csi_rs_in_symbol(*csirs_config_pdu,symb)) {
|
||||
continue;
|
||||
}
|
||||
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||
for(int k = 0; k < fp->ofdm_symbol_size; k++) {
|
||||
LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
uint64_t symbol_offset = symb * fp->ofdm_symbol_size;
|
||||
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
|
||||
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
|
||||
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
@@ -377,8 +365,8 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
/// Channel interpolation
|
||||
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, (frame_parms->ofdm_symbol_size + FILTER_MARGIN) * sizeof(int32_t));
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, (fp->ofdm_symbol_size + FILTER_MARGIN) * sizeof(int32_t));
|
||||
}
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
@@ -390,15 +378,15 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
count++;
|
||||
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k = (fp->first_carrier_offset + rb * NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
|
||||
uint16_t k_offset = k + mem_offset;
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset];
|
||||
if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
|
||||
if( (k == 0) || (k == fp->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
|
||||
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24);
|
||||
} else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
|
||||
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
|
||||
} else if(((k + NR_NB_SC_PER_RB) >= fp->ofdm_symbol_size) ||
|
||||
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1))) { // End of OFDM symbol case or Last occupied subcarrier case
|
||||
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||
} else { // Middle case
|
||||
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
|
||||
@@ -408,15 +396,15 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
/// Power noise estimation
|
||||
AssertFatal(csirs_config_pdu->nr_of_rbs > 0, " nr_of_rbs needs to be greater than 0\n");
|
||||
uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs];
|
||||
uint16_t noise_real[fp->nb_antennas_rx][csi_mapping->ports][csirs_config_pdu->nr_of_rbs];
|
||||
uint16_t noise_imag[fp->nb_antennas_rx][csi_mapping->ports][csirs_config_pdu->nr_of_rbs];
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
|
||||
continue;
|
||||
}
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k = (fp->first_carrier_offset + rb*NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
|
||||
uint16_t k_offset = k + mem_offset;
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
|
||||
c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset];
|
||||
noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->r-csi_rs_estimated_channel16->r);
|
||||
@@ -424,17 +412,17 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i));
|
||||
}
|
||||
}
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
*noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu));
|
||||
}
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||
int rb = k >= frame_parms->first_carrier_offset ?
|
||||
(k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB :
|
||||
(k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
|
||||
for(int k = 0; k < fp->ofdm_symbol_size; k++) {
|
||||
int rb = k >= fp->first_carrier_offset ?
|
||||
(k - fp->first_carrier_offset)/NR_NB_SC_PER_RB :
|
||||
(k + fp->ofdm_symbol_size - fp->first_carrier_offset)/NR_NB_SC_PER_RB;
|
||||
LOG_I(NR_PHY, "(k = %4d) |\t", k);
|
||||
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
|
||||
for(uint16_t port_tx = 0; port_tx < csi_mapping->ports; port_tx++) {
|
||||
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
|
||||
c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][mem_offset];
|
||||
printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
|
||||
@@ -450,14 +438,13 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
|
||||
}
|
||||
|
||||
*noise_power /= (frame_parms->nb_antennas_rx*N_ports);
|
||||
*log2_maxh = log2_approx(maxh-1);
|
||||
*log2_re = log2_approx(count-1);
|
||||
*noise_power /= (fp->nb_antennas_rx * csi_mapping->ports);
|
||||
*log2_maxh = log2_approx(maxh - 1);
|
||||
*log2_re = log2_approx(count - 1);
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -828,24 +815,64 @@ void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue,
|
||||
ue->nr_csi_info->csi_im_meas_computed = true;
|
||||
}
|
||||
|
||||
static nfapi_nr_dl_tti_csi_rs_pdu_rel15_t convert_csirs_pdu(const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu)
|
||||
static void nr_ue_generate_csi_rs(const fapi_nr_dl_config_csirs_pdu_rel15_t *csi_params,
|
||||
const csi_mapping_parms_t *mapping_parms,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int slot,
|
||||
int32_t **dataF)
|
||||
{
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t dl_tti_csi_rs_pdu;
|
||||
dl_tti_csi_rs_pdu.subcarrier_spacing = csirs_config_pdu->subcarrier_spacing;
|
||||
dl_tti_csi_rs_pdu.cyclic_prefix = csirs_config_pdu->cyclic_prefix;
|
||||
dl_tti_csi_rs_pdu.start_rb = csirs_config_pdu->start_rb;
|
||||
dl_tti_csi_rs_pdu.nr_of_rbs = csirs_config_pdu->nr_of_rbs;
|
||||
dl_tti_csi_rs_pdu.csi_type = csirs_config_pdu->csi_type;
|
||||
dl_tti_csi_rs_pdu.row = csirs_config_pdu->row;
|
||||
dl_tti_csi_rs_pdu.freq_domain = csirs_config_pdu->freq_domain;
|
||||
dl_tti_csi_rs_pdu.symb_l0 = csirs_config_pdu->symb_l0;
|
||||
dl_tti_csi_rs_pdu.symb_l1 = csirs_config_pdu->symb_l1;
|
||||
dl_tti_csi_rs_pdu.cdm_type = csirs_config_pdu->cdm_type;
|
||||
dl_tti_csi_rs_pdu.freq_density = csirs_config_pdu->freq_density;
|
||||
dl_tti_csi_rs_pdu.scramb_id = csirs_config_pdu->scramb_id;
|
||||
dl_tti_csi_rs_pdu.power_control_offset = csirs_config_pdu->power_control_offset;
|
||||
dl_tti_csi_rs_pdu.power_control_offset_ss = csirs_config_pdu->power_control_offset_ss;
|
||||
return dl_tti_csi_rs_pdu;
|
||||
// setting the frequency density from its index
|
||||
double rho = get_csi_rho(csi_params->freq_density);
|
||||
int csi_length = get_csi_modulation_length(rho,
|
||||
csi_params->freq_density,
|
||||
mapping_parms->kprime,
|
||||
csi_params->start_rb,
|
||||
csi_params->nr_of_rbs);
|
||||
|
||||
//*8(max allocation per RB)*2(QPSK))
|
||||
int16_t mod_csi[frame_parms->symbols_per_slot][(frame_parms->N_RB_DL << 4) >> 1] __attribute__((aligned(16)));
|
||||
get_modulated_csi_symbols(frame_parms->symbols_per_slot,
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
csi_length,
|
||||
mod_csi,
|
||||
mapping_parms->lprime,
|
||||
csi_params->symb_l0,
|
||||
csi_params->symb_l1,
|
||||
csi_params->row,
|
||||
csi_params->scramb_id);
|
||||
|
||||
uint32_t beta = get_csi_beta_amplitude(amp, csi_params->power_control_offset_ss);
|
||||
double alpha = 0;
|
||||
if (mapping_parms->ports == 1)
|
||||
alpha = rho;
|
||||
else
|
||||
alpha = 2 * rho;
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
printf(" rho %f, alpha %f\n", rho, alpha);
|
||||
#endif
|
||||
|
||||
// CDM group size from CDM type index
|
||||
int gs = get_cdm_group_size(csi_params->cdm_type);
|
||||
|
||||
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
|
||||
csi_rs_resource_mapping(dataF,
|
||||
frame_parms->N_RB_DL << 4,
|
||||
mod_csi,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
dataF_offset,
|
||||
frame_parms->first_carrier_offset,
|
||||
mapping_parms,
|
||||
csi_params->start_rb,
|
||||
csi_params->nr_of_rbs,
|
||||
alpha,
|
||||
beta,
|
||||
rho,
|
||||
gs,
|
||||
csi_params->freq_density);
|
||||
}
|
||||
|
||||
void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
@@ -857,6 +884,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
if(!ue->csirs_vars[gNB_id]->active) {
|
||||
return;
|
||||
}
|
||||
ue->csirs_vars[gNB_id]->active = 0;
|
||||
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &ue->csirs_vars[gNB_id]->csirs_config_pdu;
|
||||
|
||||
@@ -882,83 +910,63 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
return;
|
||||
}
|
||||
|
||||
if(csirs_config_pdu->csi_type == 2) {
|
||||
LOG_E(NR_PHY, "Handling of ZP CSI-RS not handled yet at PHY\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
|
||||
uint8_t N_cdm_groups = 0;
|
||||
uint8_t CDM_group_size = 0;
|
||||
uint8_t k_prime = 0;
|
||||
uint8_t l_prime = 0;
|
||||
uint8_t N_ports = 0;
|
||||
uint8_t j_cdm[16];
|
||||
uint8_t k_overline[16];
|
||||
uint8_t l_overline[16];
|
||||
int16_t log2_re = 0;
|
||||
int16_t log2_maxh = 0;
|
||||
uint32_t rsrp = 0;
|
||||
int rsrp_dBm = 0;
|
||||
uint32_t noise_power = 0;
|
||||
uint8_t rank_indicator = 0;
|
||||
uint32_t precoded_sinr_dB = 0;
|
||||
uint8_t cqi = 0;
|
||||
uint8_t i1[3] = {0};
|
||||
uint8_t i2[1] = {0};
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params = convert_csirs_pdu(csirs_config_pdu);
|
||||
nr_generate_csi_rs(frame_parms,
|
||||
ue->nr_csi_info->csi_rs_generated_signal,
|
||||
AMP,
|
||||
ue->nr_csi_info,
|
||||
&csi_params,
|
||||
proc->nr_slot_rx,
|
||||
&N_cdm_groups,
|
||||
&CDM_group_size,
|
||||
&k_prime,
|
||||
&l_prime,
|
||||
&N_ports,
|
||||
j_cdm,
|
||||
k_overline,
|
||||
l_overline);
|
||||
csi_mapping_parms_t mapping_parms = get_csi_mapping_parms(csirs_config_pdu->row,
|
||||
csirs_config_pdu->freq_domain,
|
||||
csirs_config_pdu->symb_l0,
|
||||
csirs_config_pdu->symb_l1);
|
||||
nr_csi_info_t *csi_info = ue->nr_csi_info;
|
||||
nr_ue_generate_csi_rs(csirs_config_pdu,
|
||||
&mapping_parms,
|
||||
frame_parms,
|
||||
AMP,
|
||||
proc->nr_slot_rx,
|
||||
csi_info->csi_rs_generated_signal);
|
||||
|
||||
int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
|
||||
int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN];
|
||||
csi_info->csi_rs_generated_signal_bits = log2_approx(AMP);
|
||||
|
||||
// (long)&csi_rs_estimated_channel_freq[0][0][frame_parms->first_carrier_offset] & 0x1F gives us the remainder of the integer division by 32 of the memory address
|
||||
int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][mapping_parms.ports][frame_parms->ofdm_symbol_size];
|
||||
int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][mapping_parms.ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN];
|
||||
|
||||
// (long)&csi_rs_estimated_channel_freq[0][0][frame_parms->first_carrier_offset] & 0x1F
|
||||
// gives us the remainder of the integer division by 32 of the memory address
|
||||
// By subtracting the previous value of 32, we know how much is left to have a multiple of 32.
|
||||
// Doing >> 2 <=> /sizeof(int32_t), we know what is the index offset of the array.
|
||||
uint8_t mem_offset = (((32 - ((long)&csi_rs_estimated_channel_freq[0][0][frame_parms->first_carrier_offset])) & 0x1F) >> 2);
|
||||
|
||||
int CDM_group_size = get_cdm_group_size(csirs_config_pdu->cdm_type);
|
||||
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
|
||||
uint32_t rsrp = 0;
|
||||
int rsrp_dBm = 0;
|
||||
nr_get_csi_rs_signal(ue,
|
||||
proc,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_info,
|
||||
N_cdm_groups,
|
||||
csi_info,
|
||||
&mapping_parms,
|
||||
CDM_group_size,
|
||||
k_prime,
|
||||
l_prime,
|
||||
j_cdm,
|
||||
k_overline,
|
||||
l_overline,
|
||||
csi_rs_received_signal,
|
||||
&rsrp,
|
||||
&rsrp_dBm,
|
||||
rxdataF);
|
||||
|
||||
|
||||
uint32_t noise_power = 0;
|
||||
int16_t log2_re = 0;
|
||||
int16_t log2_maxh = 0;
|
||||
// if we need to measure only RSRP no need to do channel estimation
|
||||
if (csirs_config_pdu->measurement_bitmap > 1)
|
||||
nr_csi_rs_channel_estimation(ue,
|
||||
nr_csi_rs_channel_estimation(frame_parms,
|
||||
proc,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_info,
|
||||
(const int32_t **) ue->nr_csi_info->csi_rs_generated_signal,
|
||||
csi_info,
|
||||
(const int32_t **) csi_info->csi_rs_generated_signal,
|
||||
csi_rs_received_signal,
|
||||
N_cdm_groups,
|
||||
&mapping_parms,
|
||||
CDM_group_size,
|
||||
k_prime,
|
||||
l_prime,
|
||||
N_ports,
|
||||
j_cdm,
|
||||
k_overline,
|
||||
l_overline,
|
||||
mem_offset,
|
||||
csi_rs_ls_estimated_channel,
|
||||
csi_rs_estimated_channel_freq,
|
||||
@@ -966,27 +974,32 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
&log2_maxh,
|
||||
&noise_power);
|
||||
|
||||
uint8_t rank_indicator = 0;
|
||||
// bit 1 in bitmap to indicate RI measurment
|
||||
if (csirs_config_pdu->measurement_bitmap & 2) {
|
||||
nr_csi_rs_ri_estimation(ue,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_info,
|
||||
N_ports,
|
||||
csi_info,
|
||||
mapping_parms.ports,
|
||||
mem_offset,
|
||||
csi_rs_estimated_channel_freq,
|
||||
log2_maxh,
|
||||
&rank_indicator);
|
||||
}
|
||||
|
||||
uint8_t i1[3] = {0};
|
||||
uint8_t i2[1] = {0};
|
||||
uint8_t cqi = 0;
|
||||
uint32_t precoded_sinr_dB = 0;
|
||||
// bit 3 in bitmap to indicate RI measurment
|
||||
if (csirs_config_pdu->measurement_bitmap & 8) {
|
||||
nr_csi_rs_pmi_estimation(ue,
|
||||
csirs_config_pdu,
|
||||
ue->nr_csi_info,
|
||||
N_ports,
|
||||
csi_info,
|
||||
mapping_parms.ports,
|
||||
mem_offset,
|
||||
csi_rs_estimated_channel_freq,
|
||||
ue->nr_csi_info->csi_im_meas_computed ? ue->nr_csi_info->interference_plus_noise_power : noise_power,
|
||||
csi_info->csi_im_meas_computed ? csi_info->interference_plus_noise_power : noise_power,
|
||||
rank_indicator,
|
||||
log2_re,
|
||||
i1,
|
||||
@@ -1029,6 +1042,4 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements, NULL);
|
||||
if (ue->if_inst && ue->if_inst->dl_indication)
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
|
||||
k += kbar;
|
||||
k *= 2;
|
||||
|
||||
LOG_I(PHY, "PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n",
|
||||
LOG_I(PHY,
|
||||
"PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, Msg1/MsgA-Preamble frequency start %d (k1 %d), "
|
||||
"preamble_offset %d, first_nonzero_root_idx %d\n",
|
||||
Mod_id,
|
||||
frame,
|
||||
slot,
|
||||
|
||||
@@ -111,7 +111,7 @@ int32_t signal_energy_amp_shift(int32_t *input,uint32_t length)
|
||||
return((temp>0)?temp:1);
|
||||
}
|
||||
|
||||
int32_t signal_energy_nodc(const c16_t *input, uint32_t length)
|
||||
uint32_t signal_energy_nodc(const c16_t *input, uint32_t length)
|
||||
{
|
||||
// init
|
||||
simde__m128 mm0 = simde_mm_setzero_ps();
|
||||
@@ -134,7 +134,7 @@ int32_t signal_energy_nodc(const c16_t *input, uint32_t length)
|
||||
// Ave
|
||||
float sums[4];
|
||||
simde_mm_store_ps(sums, mm0);
|
||||
return (int)((sums[0] + sums[1] + sums[2] + sums[3] + leftover_sum) / (float)length);
|
||||
return (uint32_t)((sums[0] + sums[1] + sums[2] + sums[3] + leftover_sum) / (float)length);
|
||||
}
|
||||
|
||||
double signal_energy_fp(double *s_re[2],double *s_im[2],uint32_t nb_antennas,uint32_t length,uint32_t offset)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
extern "C" {
|
||||
#include "openair1/PHY/TOOLS/tools_defs.h"
|
||||
extern int32_t signal_energy_nodc(const c16_t *input, uint32_t length);
|
||||
extern uint32_t signal_energy_nodc(const c16_t *input, uint32_t length);
|
||||
}
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -758,10 +758,10 @@ int32_t signal_energy_amp_shift(int32_t *input, uint32_t length);
|
||||
int32_t subcarrier_energy(int32_t *,uint32_t, int32_t *subcarrier_energy, uint16_t rx_power_correction);
|
||||
#endif
|
||||
|
||||
/*!\fn int32_t signal_energy_nodc(int32_t *,uint32_t);
|
||||
/*!\fn uint32_t signal_energy_nodc(c16_t *,uint32_t);
|
||||
\brief Computes the signal energy per subcarrier, without DC removal
|
||||
*/
|
||||
int32_t signal_energy_nodc(const c16_t *input, uint32_t length);
|
||||
uint32_t signal_energy_nodc(const c16_t *input, uint32_t length);
|
||||
|
||||
int32_t signal_power(int32_t *,uint32_t);
|
||||
int32_t interference_power(int32_t *,uint32_t);
|
||||
|
||||
@@ -130,9 +130,9 @@ typedef struct {
|
||||
/// - third index: frequency [0..]
|
||||
int32_t **tdd_calib_coeffs;
|
||||
/// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
|
||||
/// - first index: antenna port
|
||||
/// - first index: concurrent beam
|
||||
/// - second index: beam_id [0.. symbols_per_frame[
|
||||
uint8_t **beam_id;
|
||||
int **beam_id;
|
||||
} RU_COMMON;
|
||||
|
||||
|
||||
|
||||
+20
-12
@@ -123,8 +123,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
/// Pointers to variables related to DLSCH harq process
|
||||
NR_DL_gNB_HARQ_t harq_process;
|
||||
/// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
|
||||
int32_t ***ue_spec_bf_weights;
|
||||
/// Active flag for baseband transmitter processing
|
||||
uint8_t active;
|
||||
/// Number of soft channel bits
|
||||
@@ -139,6 +137,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
int frame;
|
||||
int slot;
|
||||
// identifier for concurrent beams
|
||||
int beam_nb;
|
||||
nfapi_nr_prach_pdu_t pdu;
|
||||
} gNB_PRACH_list_t;
|
||||
|
||||
@@ -223,6 +223,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t frame;
|
||||
uint32_t slot;
|
||||
// identifier for concurrent beams
|
||||
int beam_nb;
|
||||
uint32_t unav_res;
|
||||
/// Pointers to 16 HARQ processes for the ULSCH
|
||||
NR_UL_gNB_HARQ_t *harq_process;
|
||||
@@ -243,7 +245,9 @@ typedef struct {
|
||||
} NR_gNB_ULSCH_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t active;
|
||||
bool active;
|
||||
// identifier for concurrent beams
|
||||
int beam_nb;
|
||||
/// Frame where current PUCCH pdu was sent
|
||||
uint32_t frame;
|
||||
/// Slot where current PUCCH pdu was sent
|
||||
@@ -253,11 +257,15 @@ typedef struct {
|
||||
} NR_gNB_PUCCH_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t active;
|
||||
bool active;
|
||||
// identifier for concurrent beams
|
||||
int beam_nb;
|
||||
/// Frame where current SRS pdu was received
|
||||
uint32_t frame;
|
||||
/// Slot where current SRS pdu was received
|
||||
uint32_t slot;
|
||||
/// Measured SNR
|
||||
int8_t snr;
|
||||
/// ULSCH PDU
|
||||
nfapi_nr_srs_pdu_t srs_pdu;
|
||||
} NR_gNB_SRS_t;
|
||||
@@ -266,17 +274,20 @@ typedef struct {
|
||||
/// \brief Pointers (dynamic) to the received data in the frequency domain.
|
||||
/// - first index: rx antenna [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
|
||||
c16_t **rxdataF;
|
||||
c16_t ***rxdataF;
|
||||
/// \brief holds the transmit data in the frequency domain.
|
||||
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
|
||||
/// - first index: eNB id [0..2] (hard coded)
|
||||
/// - first index: beam (for concurrent beams)
|
||||
/// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
|
||||
/// - third index: sample [0..samples_per_frame_woCP]
|
||||
c16_t **txdataF;
|
||||
c16_t ***txdataF;
|
||||
/// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
|
||||
/// - first index: antenna port
|
||||
/// - first index: beam index (for concurrent beams)
|
||||
/// - second index: beam_id [0.. symbols_per_frame[
|
||||
uint8_t **beam_id;
|
||||
int **beam_id;
|
||||
int num_beams;
|
||||
int num_beams_period;
|
||||
bool analog_bf;
|
||||
int32_t *debugBuff;
|
||||
int32_t debugBuff_sample_offset;
|
||||
} NR_gNB_COMMON;
|
||||
@@ -464,9 +475,6 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/// SRS variables
|
||||
nr_srs_info_t **nr_srs_info;
|
||||
|
||||
/// CSI variables
|
||||
nr_csi_info_t *nr_csi_info;
|
||||
|
||||
// reference amplitude for TX
|
||||
int16_t TX_AMP;
|
||||
|
||||
|
||||
@@ -310,6 +310,13 @@ typedef struct {
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu;
|
||||
} NR_UE_CSI_RS;
|
||||
|
||||
typedef struct {
|
||||
uint8_t csi_rs_generated_signal_bits;
|
||||
int32_t **csi_rs_generated_signal;
|
||||
bool csi_im_meas_computed;
|
||||
uint32_t interference_plus_noise_power;
|
||||
} nr_csi_info_t;
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
fapi_nr_ul_config_srs_pdu srs_config_pdu;
|
||||
|
||||
@@ -119,13 +119,6 @@ typedef struct {
|
||||
nfapi_nr_srs_pdu_t srs_pdu;
|
||||
} nr_srs_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t csi_rs_generated_signal_bits;
|
||||
int32_t **csi_rs_generated_signal;
|
||||
bool csi_im_meas_computed;
|
||||
uint32_t interference_plus_noise_power;
|
||||
} nr_csi_info_t;
|
||||
|
||||
typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
|
||||
|
||||
typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp);
|
||||
|
||||
@@ -23,7 +23,47 @@
|
||||
#define __NR_PHY_COMMON__H__
|
||||
#include "PHY/impl_defs_top.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
int ports;
|
||||
int kprime;
|
||||
int lprime;
|
||||
int j[16];
|
||||
int koverline[16];
|
||||
int loverline[16];
|
||||
} csi_mapping_parms_t;
|
||||
void get_modulated_csi_symbols(int symbols_per_slot,
|
||||
int slot,
|
||||
int N_RB_DL,
|
||||
int mod_length,
|
||||
int16_t mod_csi[][(N_RB_DL << 4) >> 1],
|
||||
int lprime,
|
||||
int l0,
|
||||
int l1,
|
||||
int row,
|
||||
int scramb_id);
|
||||
void csi_rs_resource_mapping(int32_t **dataF,
|
||||
int csi_rs_length,
|
||||
int16_t mod_csi[][csi_rs_length >> 1],
|
||||
int ofdm_symbol_size,
|
||||
int dataF_offset,
|
||||
int start_sc,
|
||||
const csi_mapping_parms_t *mapping_parms,
|
||||
int start_rb,
|
||||
int nb_rbs,
|
||||
double alpha,
|
||||
int beta,
|
||||
double rho,
|
||||
int gs,
|
||||
int freq_density);
|
||||
csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1);
|
||||
int get_cdm_group_size(int cdm_type);
|
||||
double get_csi_rho(int freq_density);
|
||||
uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss);
|
||||
int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nb_rbs);
|
||||
void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re);
|
||||
void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re);
|
||||
void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re);
|
||||
|
||||
@@ -0,0 +1,563 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
|
||||
|
||||
void csi_rs_resource_mapping(int32_t **dataF,
|
||||
int csi_rs_length,
|
||||
int16_t mod_csi[][csi_rs_length >> 1],
|
||||
int ofdm_symbol_size,
|
||||
int dataF_offset,
|
||||
int start_sc,
|
||||
const csi_mapping_parms_t *mapping_parms,
|
||||
int start_rb,
|
||||
int nb_rbs,
|
||||
double alpha,
|
||||
int beta,
|
||||
double rho,
|
||||
int gs,
|
||||
int freq_density)
|
||||
{
|
||||
// resource mapping according to 38.211 7.4.1.5.3
|
||||
for (int n = start_rb; n < (start_rb + nb_rbs); n++) {
|
||||
if ((freq_density > 1) || (freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB
|
||||
for (int ji = 0; ji < mapping_parms->size; ji++) { // loop over CDM groups
|
||||
for (int s = 0 ; s < gs; s++) { // loop over each CDM group size
|
||||
int p = s + mapping_parms->j[ji] * gs; // port index
|
||||
for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group
|
||||
// frequency index of current resource element
|
||||
int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size);
|
||||
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
|
||||
int na = n * alpha;
|
||||
int kpn = (rho * mapping_parms->koverline[ji]) / NR_NB_SC_PER_RB;
|
||||
int mprime = na + kp + kpn; // sequence index
|
||||
for (int lp = 0; lp <= mapping_parms->lprime; lp++) { // loop over frequency resource elements within a group
|
||||
int l = lp + mapping_parms->loverline[ji];
|
||||
// wt according to tables 7.4.5.3-2 to 7.4.5.3-5
|
||||
int wt;
|
||||
if (s < 2)
|
||||
wt = 1;
|
||||
else if (s < 4)
|
||||
wt = -2 * (lp % 2) + 1;
|
||||
else if (s < 6)
|
||||
wt = -2 * (lp / 2) + 1;
|
||||
else {
|
||||
if ((lp == 0) || (lp == 3))
|
||||
wt = 1;
|
||||
else
|
||||
wt = -1;
|
||||
}
|
||||
int index = ((l * ofdm_symbol_size + k) << 1) + (2 * dataF_offset);
|
||||
((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
|
||||
((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
|
||||
LOG_D(PHY,
|
||||
"l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",
|
||||
l,
|
||||
k,
|
||||
mprime,
|
||||
p + 3000,
|
||||
((int16_t*)dataF[p])[index],
|
||||
((int16_t*)dataF[p])[index + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_modulated_csi_symbols(int symbols_per_slot,
|
||||
int slot,
|
||||
int N_RB_DL,
|
||||
int mod_length,
|
||||
int16_t mod_csi[][(N_RB_DL << 4) >> 1],
|
||||
int lprime,
|
||||
int l0,
|
||||
int l1,
|
||||
int row,
|
||||
int scramb_id)
|
||||
{
|
||||
for (int lp = 0; lp <= lprime; lp++) {
|
||||
int symb = l0;
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id);
|
||||
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id);
|
||||
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) {
|
||||
symb = l1;
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id);
|
||||
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id);
|
||||
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss)
|
||||
{
|
||||
uint32_t beta = amp;
|
||||
// assuming amp is the amplitude of SSB channels
|
||||
switch (power_control_offset_ss) {
|
||||
case 0:
|
||||
beta = (amp * ONE_OVER_SQRT2_Q15) >> 15;
|
||||
break;
|
||||
case 1:
|
||||
beta = amp;
|
||||
break;
|
||||
case 2:
|
||||
beta = (amp * ONE_OVER_SQRT2_Q15) >> 14;
|
||||
break;
|
||||
case 3:
|
||||
beta = amp << 1;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid SS power offset density index for CSI\n");
|
||||
}
|
||||
return beta;
|
||||
}
|
||||
|
||||
int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nr_rbs)
|
||||
{
|
||||
int csi_length = 0;
|
||||
if (rho < 1) {
|
||||
if (freq_density == 0) {
|
||||
csi_length = (((start_rb + nr_rbs) >> 1) << kprime) << 1;
|
||||
} else {
|
||||
csi_length = ((((start_rb + nr_rbs) >> 1) << kprime) + 1) << 1;
|
||||
}
|
||||
} else {
|
||||
csi_length = (((uint16_t) rho * (start_rb + nr_rbs)) << kprime) << 1;
|
||||
}
|
||||
return csi_length;
|
||||
}
|
||||
|
||||
double get_csi_rho(int freq_density)
|
||||
{
|
||||
// setting the frequency density from its index
|
||||
double rho = 0;
|
||||
switch (freq_density) {
|
||||
case 0:
|
||||
rho = 0.5;
|
||||
break;
|
||||
case 1:
|
||||
rho = 0.5;
|
||||
break;
|
||||
case 2:
|
||||
rho = 1;
|
||||
break;
|
||||
case 3:
|
||||
rho = 3;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid frequency density index for CSI\n");
|
||||
}
|
||||
return rho;
|
||||
}
|
||||
|
||||
int get_cdm_group_size(int cdm_type)
|
||||
{
|
||||
// CDM group size from CDM type index
|
||||
int gs = 0;
|
||||
switch (cdm_type) {
|
||||
case 0:
|
||||
gs = 1;
|
||||
break;
|
||||
case 1:
|
||||
gs = 2;
|
||||
break;
|
||||
case 2:
|
||||
gs = 4;
|
||||
break;
|
||||
case 3:
|
||||
gs = 8;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Invalid cdm type index for CSI\n");
|
||||
}
|
||||
return gs;
|
||||
}
|
||||
|
||||
csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1)
|
||||
{
|
||||
AssertFatal(b != 0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||
csi_mapping_parms_t csi_parms = {0};
|
||||
int found = 0;
|
||||
int fi = 0;
|
||||
int k_n[6];
|
||||
// implementation of table 7.4.1.5.3-1 of 38.211
|
||||
// lprime and kprime are the max value of l' and k'
|
||||
switch (row) {
|
||||
case 1:
|
||||
csi_parms.ports = 1;
|
||||
csi_parms.kprime = 0;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 3;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = 0;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[0] + (i << 2);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
csi_parms.ports = 1;
|
||||
csi_parms.kprime = 0;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 1;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = 0;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
csi_parms.ports = 2;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 1;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = 0;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
csi_parms.ports = 4;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 2;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 2;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[0] + (i << 1);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
csi_parms.ports = 4;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 2;
|
||||
while (found < 1) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
else
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0 + i;
|
||||
csi_parms.koverline[i] = k_n[0];
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
csi_parms.ports = 8;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
csi_parms.ports = 8;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 4;
|
||||
while (found < 2) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0 + (i >> 1);
|
||||
csi_parms.koverline[i] = k_n[i % 2];
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
csi_parms.ports = 8;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 1;
|
||||
csi_parms.size = 2;
|
||||
while (found < 2) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
csi_parms.ports = 12;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 6;
|
||||
while (found < 6) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
csi_parms.ports = 12;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 1;
|
||||
csi_parms.size = 3;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
csi_parms.ports = 16;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 8;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0 + (i >> 2);
|
||||
csi_parms.koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
csi_parms.ports = 16;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 1;
|
||||
csi_parms.size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
csi_parms.ports = 24;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 12;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
if (i < 6)
|
||||
csi_parms.loverline[i] = l0 + i / 3;
|
||||
else
|
||||
csi_parms.loverline[i] = l1 + i / 9;
|
||||
csi_parms.koverline[i] = k_n[i % 3];
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
csi_parms.ports = 24;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 1;
|
||||
csi_parms.size = 6;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
if (i < 3)
|
||||
csi_parms.loverline[i] = l0;
|
||||
else
|
||||
csi_parms.loverline[i] = l1;
|
||||
csi_parms.koverline[i] = k_n[i % 3];
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
csi_parms.ports = 24;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 3;
|
||||
csi_parms.size = 3;
|
||||
while (found < 3) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
csi_parms.ports = 32;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 0;
|
||||
csi_parms.size = 16;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
if (i < 8)
|
||||
csi_parms.loverline[i] = l0 + (i >> 2);
|
||||
else
|
||||
csi_parms.loverline[i] = l1 + (i / 12);
|
||||
csi_parms.koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
csi_parms.ports = 32;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 1;
|
||||
csi_parms.size = 8;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
if (i < 4)
|
||||
csi_parms.loverline[i] = l0;
|
||||
else
|
||||
csi_parms.loverline[i] = l1;
|
||||
csi_parms.koverline[i] = k_n[i % 4];
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
csi_parms.ports = 32;
|
||||
csi_parms.kprime = 1;
|
||||
csi_parms.lprime = 3;
|
||||
csi_parms.size = 4;
|
||||
while (found < 4) {
|
||||
if ((b >> fi) & 0x01) {
|
||||
k_n[found] = fi << 1;
|
||||
found++;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
for (int i = 0; i < csi_parms.size; i++) {
|
||||
csi_parms.j[i] = i;
|
||||
csi_parms.loverline[i] = l0;
|
||||
csi_parms.koverline[i] = k_n[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", row);
|
||||
}
|
||||
return csi_parms;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,9 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
|
||||
uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus;
|
||||
uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs;
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC){
|
||||
clear_slot_beamid(gNB, slot); // reset beam_id information for the slot to be processed
|
||||
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC) {
|
||||
if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT) {
|
||||
processingData_L1tx_t *msgTx = gNB->msgDataTx;
|
||||
msgTx->num_pdsch_slot = 0;
|
||||
@@ -227,8 +229,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO)
|
||||
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
|
||||
nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
if (gNB->RU_list[0]->if_south == LOCAL_RF ||
|
||||
gNB->RU_list[0]->if_south == REMOTE_IF5) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
if (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)
|
||||
nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
|
||||
break;
|
||||
case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
|
||||
LOG_D(NR_PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
|
||||
|
||||
@@ -52,28 +52,37 @@
|
||||
extern int oai_exit;
|
||||
|
||||
// OFDM modulation core routine, generates a first_symbol to first_symbol+num_symbols on a particular slot and TX antenna port
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
unsigned int slot_offset,slot_offsetF;
|
||||
int slot = tti_tx;
|
||||
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 );
|
||||
|
||||
if (aa==0 && first_symbol == 0) start_meas(&ru->ofdm_mod_stats);
|
||||
slot_offset = fp->get_samples_slot_timestamp(slot,fp,0);
|
||||
slot_offsetF = first_symbol*fp->ofdm_symbol_size;
|
||||
if (aa == 0 && first_symbol == 0)
|
||||
start_meas(&ru->ofdm_mod_stats);
|
||||
slot_offset = fp->get_samples_slot_timestamp(slot, fp, 0);
|
||||
slot_offsetF = first_symbol * fp->ofdm_symbol_size;
|
||||
|
||||
int abs_first_symbol = slot*fp->symbols_per_slot;
|
||||
int abs_first_symbol = slot * fp->symbols_per_slot;
|
||||
|
||||
for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+first_symbol; idx_sym++)
|
||||
slot_offset += (idx_sym%(0x7<<fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
|
||||
for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol + first_symbol; idx_sym++)
|
||||
slot_offset += (idx_sym % (0x7 << fp->numerology_index)) ? fp->nb_prefix_samples : fp->nb_prefix_samples0;
|
||||
|
||||
slot_offset += fp->ofdm_symbol_size*first_symbol;
|
||||
slot_offset += fp->ofdm_symbol_size * first_symbol;
|
||||
|
||||
LOG_D(PHY,"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",ru->proc.frame_tx, ru->proc.tti_tx,aa,slot,first_symbol,num_symbols,slot_offset,slot_offsetF);
|
||||
LOG_D(PHY,
|
||||
"SFN/SF:RU:TX:%d/%d aa %d Generating slot %d (first_symbol %d num_symbols %d) slot_offset %d, slot_offsetF %d\n",
|
||||
ru->proc.frame_tx,
|
||||
ru->proc.tti_tx,
|
||||
aa,
|
||||
slot,
|
||||
first_symbol,
|
||||
num_symbols,
|
||||
slot_offset,
|
||||
slot_offsetF);
|
||||
|
||||
if (fp->Ncp == 1) {
|
||||
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
|
||||
@@ -110,8 +119,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
}
|
||||
} // numerology_index!=0
|
||||
else { //numerology_index == 0
|
||||
for (uint16_t idx_sym=abs_first_symbol; idx_sym<abs_first_symbol+num_symbols; idx_sym++) {
|
||||
if (idx_sym%0x7) {
|
||||
for (int idx_sym = abs_first_symbol; idx_sym < abs_first_symbol+num_symbols; idx_sym++) {
|
||||
if (idx_sym % 0x7) {
|
||||
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
|
||||
(int*)&ru->common.txdata[aa][slot_offset],
|
||||
fp->ofdm_symbol_size,
|
||||
@@ -135,7 +144,8 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
|
||||
} // numerology 0
|
||||
}
|
||||
|
||||
if (aa==0 && first_symbol==0) stop_meas(&ru->ofdm_mod_stats);
|
||||
if (aa == 0 && first_symbol == 0)
|
||||
stop_meas(&ru->ofdm_mod_stats);
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0);
|
||||
}
|
||||
@@ -170,167 +180,165 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
}
|
||||
|
||||
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx) {
|
||||
|
||||
int l,aa;
|
||||
void nr_feptx_prec(RU_t *ru, int frame_tx, int tti_tx)
|
||||
{
|
||||
PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int32_t ***bw;
|
||||
int i=0;
|
||||
int slot_tx = tti_tx;
|
||||
int txdataF_offset = (tti_tx*fp->samples_per_slot_wCP);
|
||||
|
||||
start_meas(&ru->precoding_stats);
|
||||
AssertFatal(ru->nb_log_antennas > 0,"ru->nb_log_antennas is 0!\n");
|
||||
if (ru->num_gNB == 1){
|
||||
AssertFatal(ru->nb_log_antennas > 0, "ru->nb_log_antennas is 0!\n");
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
|
||||
if (ru->num_gNB == 1) {
|
||||
gNB = gNB_list[0];
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) return;
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
if (!ru->do_precoding || (ru->nb_tx == 1 && ru->nb_log_antennas == 1)) {
|
||||
for (i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
//ru->common.txdataF_BF[i] = (int32_t *)&gNB->common_vars.txdataF[i][txdataF_offset];
|
||||
memcpy(ru->common.txdataF_BF[i],
|
||||
&gNB->common_vars.txdataF[i][txdataF_offset],
|
||||
fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || gNB->common_vars.analog_bf) {
|
||||
for (int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
// TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i=0; i<ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*)ru->common.txdataF[i],
|
||||
(void*)&gNB->common_vars.txdataF[i][txdataF_offset],
|
||||
fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
memcpy((void*)&ru->common.beam_id[i][slot_tx*fp->symbols_per_slot],
|
||||
(void*)&gNB->common_vars.beam_id[i][slot_tx*fp->symbols_per_slot],
|
||||
fp->symbols_per_slot*sizeof(uint8_t));
|
||||
for(int i = 0; i < ru->nb_log_antennas; ++i) {
|
||||
// TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
memcpy(ru->common.txdataF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
bw = ru->beam_weights[0];
|
||||
for (l=0;l<fp->symbols_per_slot;l++) {
|
||||
for (aa=0;aa<ru->nb_tx;aa++) {
|
||||
for (int l = 0; l < fp->symbols_per_slot; l++) {
|
||||
for (int aa = 0; aa < ru->nb_tx; aa++) {
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
nr_beam_precoding((c16_t **)ru->common.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
ru->beam_weights[0],
|
||||
tti_tx,
|
||||
l,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
0);
|
||||
}// for (aa=0;aa<ru->nb_tx;aa++)
|
||||
}// for (l=0;l<fp->symbols_per_slot;l++)
|
||||
}// ru->do_precoding
|
||||
}// if (ru->num_gNB == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stop_meas(&ru->precoding_stats);
|
||||
}
|
||||
|
||||
// core routine for FEP TX, called from threads in RU TX thread-pool
|
||||
void nr_feptx(void *arg) {
|
||||
|
||||
void nr_feptx(void *arg)
|
||||
{
|
||||
feptx_cmd_t *feptx = (feptx_cmd_t *)arg;
|
||||
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols*fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot*fp->samples_per_slot_wCP) + startSymbol*fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol*fp->ofdm_symbol_size;
|
||||
RU_t *ru = feptx->ru;
|
||||
int slot = feptx->slot;
|
||||
int aa = feptx->aid;
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
int numSymbols = feptx->numSymbols;
|
||||
int numSamples = feptx->numSymbols * fp->ofdm_symbol_size;
|
||||
int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size;
|
||||
int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
|
||||
|
||||
////////////precoding////////////
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 1);
|
||||
|
||||
if (aa==0) start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->do_precoding == 1) {
|
||||
for(int i=0; i<ru->nb_log_antennas; ++i) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot)*sizeof(uint8_t));
|
||||
if (aa == 0)
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->config.dbt_config.num_dig_beams != 0) {
|
||||
for(int i = 0; i < ru->gNB_list[0]->common_vars.num_beams_period; i++) {
|
||||
memcpy(&ru->common.beam_id[i][slot * fp->symbols_per_slot],
|
||||
&ru->gNB_list[0]->common_vars.beam_id[i][slot * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) {
|
||||
memcpy((void*)&ru->common.txdataF_BF[0][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
else if (ru->do_precoding == 0) {
|
||||
int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx;
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf)
|
||||
memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset],
|
||||
numSamples*sizeof(int32_t));
|
||||
}
|
||||
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][aa][txdataF_offset], // TODO hardcoded beam to 0, still need to understand how to handle this properly
|
||||
numSamples * sizeof(int32_t));
|
||||
else {
|
||||
AssertFatal(1==0,"This needs to be fixed, do not use beamforming.\n");
|
||||
int32_t ***bw = ru->beam_weights[0];
|
||||
for(int i=0; i<fp->symbols_per_slot; ++i){
|
||||
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
|
||||
for(int i = 0; i < fp->symbols_per_slot; ++i) {
|
||||
nr_beam_precoding((c16_t **)ru->gNB_list[0]->common_vars.txdataF,
|
||||
(c16_t **)ru->common.txdataF_BF,
|
||||
fp,
|
||||
bw,
|
||||
ru->beam_weights[0],
|
||||
slot,
|
||||
i,
|
||||
aa,
|
||||
ru->nb_log_antennas,
|
||||
txdataF_offset);//here
|
||||
txdataF_offset);
|
||||
}
|
||||
}
|
||||
if (aa==0) stop_meas(&ru->precoding_stats);
|
||||
|
||||
if (aa==0)
|
||||
stop_meas(&ru->precoding_stats);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->aid , 0);
|
||||
|
||||
////////////FEPTX////////////
|
||||
nr_feptx0(ru,slot,startSymbol,numSymbols,aa);
|
||||
nr_feptx0(ru, slot, startSymbol, numSymbols, aa);
|
||||
}
|
||||
|
||||
// RU FEP TX using thread-pool
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot) {
|
||||
|
||||
void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
|
||||
int nbfeptx=0;
|
||||
if (nr_slot_select(cfg,frame_tx,slot) == NR_UPLINK_SLOT) return;
|
||||
// for (int aa=0; aa<ru->nb_tx; aa++) memset(ru->common.txdataF[aa],0,ru->nr_frame_parms->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1 );
|
||||
int nbfeptx = 0;
|
||||
if (nr_slot_select(cfg, frame_tx, slot) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
if (ru->idx == 0)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1);
|
||||
start_meas(&ru->ofdm_total_stats);
|
||||
for (int aid=0;aid<ru->nb_tx;aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols = (ru->half_slot_parallelization>0)?ru->nr_frame_parms->symbols_per_slot>>1:ru->nr_frame_parms->symbols_per_slot;
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization>0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx,ru->respfeptx,nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd=(feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot>>1;
|
||||
pushTpool(ru->threadPool,req);
|
||||
nbfeptx++;
|
||||
}
|
||||
for (int aid = 0; aid < ru->nb_tx; aid++) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = 0;
|
||||
feptx_cmd->numSymbols = (ru->half_slot_parallelization > 0) ?
|
||||
ru->nr_frame_parms->symbols_per_slot >> 1 :
|
||||
ru->nr_frame_parms->symbols_per_slot;
|
||||
pushTpool(ru->threadPool, req);
|
||||
nbfeptx++;
|
||||
if (ru->half_slot_parallelization > 0) {
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx);
|
||||
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
|
||||
feptx_cmd->aid = aid;
|
||||
feptx_cmd->ru = ru;
|
||||
feptx_cmd->slot = slot;
|
||||
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
|
||||
pushTpool(ru->threadPool, req);
|
||||
nbfeptx++;
|
||||
}
|
||||
}
|
||||
while (nbfeptx>0) {
|
||||
while (nbfeptx > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool);
|
||||
delNotifiedFIFO_elt(req);
|
||||
nbfeptx--;
|
||||
}
|
||||
stop_meas(&ru->ofdm_total_stats);
|
||||
if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0 );
|
||||
if (ru->idx == 0)
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 0);
|
||||
}
|
||||
|
||||
// core RX FEP routine, called by threads in RU thread-pool
|
||||
void nr_fep(void* arg)
|
||||
{
|
||||
feprx_cmd_t *feprx_cmd = (feprx_cmd_t *)arg;
|
||||
|
||||
RU_t *ru = feprx_cmd->ru;
|
||||
int aid = feprx_cmd->aid;
|
||||
int tti_rx = feprx_cmd->slot;
|
||||
@@ -338,7 +346,7 @@ void nr_fep(void* arg)
|
||||
int endSymbol = feprx_cmd->endSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
|
||||
LOG_D(PHY,"In nr_fep for aid %d, slot = %d, startSymbol %d, endSymbol %d\n", aid, tti_rx,startSymbol,endSymbol);
|
||||
LOG_D(PHY,"aid %d, frame %d slot %d, startSymbol %d, endSymbol %d\n", aid, ru->proc.frame_rx, tti_rx, startSymbol, endSymbol);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+aid, 1);
|
||||
|
||||
|
||||
@@ -43,23 +43,42 @@
|
||||
//#define DEBUG_RXDATA
|
||||
//#define SRS_IND_DEBUG
|
||||
|
||||
extern uint8_t nfapi_mode;
|
||||
int beam_index_allocation(int fapi_beam_index,
|
||||
NR_gNB_COMMON *common_vars,
|
||||
int slot,
|
||||
int symbols_per_slot,
|
||||
int start_symbol,
|
||||
int nb_symbols)
|
||||
{
|
||||
if (!common_vars->beam_id)
|
||||
return 0;
|
||||
|
||||
void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu)
|
||||
int idx = -1;
|
||||
for (int j = 0; j < common_vars->num_beams_period; j++) {
|
||||
for (int i = start_symbol; i < start_symbol + nb_symbols; i++) {
|
||||
int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i];
|
||||
if (current_beam == -1 || current_beam == fapi_beam_index)
|
||||
idx = j;
|
||||
else {
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx != -1)
|
||||
break;
|
||||
}
|
||||
AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index);
|
||||
for (int j = start_symbol; j < start_symbol + nb_symbols; j++)
|
||||
common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index;
|
||||
LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot);
|
||||
return idx;
|
||||
}
|
||||
|
||||
void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_dl_tti_ssb_pdu ssb_pdu)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
c16_t **txdataF = gNB->common_vars.txdataF;
|
||||
uint8_t n_hf;
|
||||
int txdataF_offset = slot*fp->samples_per_slot_wCP;
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
|
||||
|
||||
if (slot<slots_per_hf)
|
||||
n_hf=0;
|
||||
else
|
||||
n_hf=1;
|
||||
|
||||
uint8_t ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
|
||||
nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu = &ssb_pdu.ssb_pdu_rel15;
|
||||
uint8_t ssb_index = pdu->SsbBlockIndex;
|
||||
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n", frame, slot, ssb_index);
|
||||
|
||||
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index); // computing the starting symbol for current ssb
|
||||
@@ -70,11 +89,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr
|
||||
// for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS
|
||||
// for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the subcarrier spacing provided
|
||||
// by the higher-layer parameter subCarrierSpacingCommon
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
const int scs = cfg->ssb_config.scs_common.value;
|
||||
const int prb_offset = (fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> scs
|
||||
: ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA >> (scs - 2);
|
||||
const int sc_offset =
|
||||
(fp->freq_range == FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset;
|
||||
const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2);
|
||||
const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset;
|
||||
fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset);
|
||||
|
||||
if (fp->print_ue_help_cmdline_log && get_softmodem_params()->sa) {
|
||||
@@ -99,20 +117,34 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr
|
||||
}
|
||||
LOG_D(PHY,
|
||||
"ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n",
|
||||
ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA,
|
||||
ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset,
|
||||
pdu->ssbOffsetPointA,
|
||||
pdu->SsbSubcarrierOffset,
|
||||
prb_offset,
|
||||
sc_offset,
|
||||
scs,
|
||||
fp->ssb_start_subcarrier);
|
||||
|
||||
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
|
||||
nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol);
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming;
|
||||
c16_t ***txdataF = gNB->common_vars.txdataF;
|
||||
int txdataF_offset = slot * fp->samples_per_slot_wCP;
|
||||
// beam number in a scenario with multiple concurrent beams
|
||||
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
fp->symbols_per_slot,
|
||||
ssb_start_symbol,
|
||||
4); // 4 ssb symbols
|
||||
|
||||
nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
|
||||
int n_hf = slot < slots_per_hf ? 0 : 1;
|
||||
|
||||
int hf = fp->Lmax == 4 ? n_hf : 0;
|
||||
nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7),
|
||||
&txdataF[0][txdataF_offset],
|
||||
&txdataF[beam_nb][0][txdataF_offset],
|
||||
gNB->TX_AMP,
|
||||
ssb_start_symbol,
|
||||
cfg,
|
||||
@@ -121,23 +153,16 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr
|
||||
#if T_TRACER
|
||||
if (T_ACTIVE(T_GNB_PHY_MIB)) {
|
||||
unsigned char bch[3];
|
||||
bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
|
||||
bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
|
||||
bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
|
||||
bch[0] = pdu->bchPayload & 0xff;
|
||||
bch[1] = (pdu->bchPayload >> 8) & 0xff;
|
||||
bch[2] = (pdu->bchPayload >> 16) & 0xff;
|
||||
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Beam_id is currently used only for FR2
|
||||
if (fp->freq_range == FR2){
|
||||
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
|
||||
for (int j=0;j<fp->symbols_per_slot;j++)
|
||||
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
|
||||
}
|
||||
|
||||
nr_generate_pbch(gNB,
|
||||
&ssb_pdu,
|
||||
&txdataF[0][txdataF_offset],
|
||||
&txdataF[beam_nb][0][txdataF_offset],
|
||||
ssb_start_symbol,
|
||||
n_hf,
|
||||
frame,
|
||||
@@ -145,29 +170,39 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame,int slot, nfapi_nr
|
||||
fp);
|
||||
}
|
||||
|
||||
// clearing beam information to be provided to RU for all slots (DL and UL)
|
||||
void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot)
|
||||
{
|
||||
LOG_D(PHY, "Clearing beam_id structure for slot %d\n", slot);
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
for (int i = 0; i < gNB->common_vars.num_beams_period; i++) {
|
||||
if (gNB->common_vars.beam_id)
|
||||
memset(&gNB->common_vars.beam_id[i][slot * fp->symbols_per_slot], -1, fp->symbols_per_slot * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
int frame,
|
||||
int slot,
|
||||
int do_meas) {
|
||||
|
||||
int aa;
|
||||
int do_meas)
|
||||
{
|
||||
PHY_VARS_gNB *gNB = msgTx->gNB;
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
int slot_prs = 0;
|
||||
int txdataF_offset = slot*fp->samples_per_slot_wCP;
|
||||
int txdataF_offset = slot * fp->samples_per_slot_wCP;
|
||||
prs_config_t *prs_config = NULL;
|
||||
|
||||
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
|
||||
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
|
||||
if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT))
|
||||
return;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 1);
|
||||
|
||||
// clear the transmit data array and beam index for the current slot
|
||||
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
memset(&gNB->common_vars.beam_id[aa][slot*fp->symbols_per_slot],255,fp->symbols_per_slot*sizeof(uint8_t));
|
||||
for (int i = 0; i < gNB->common_vars.num_beams_period; i++) {
|
||||
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
memset(&gNB->common_vars.txdataF[i][aa][txdataF_offset], 0, fp->samples_per_slot_wCP * sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
|
||||
// Check for PRS slot - section 7.4.1.7.4 in 3GPP rel16 38.211
|
||||
@@ -180,19 +215,19 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
{
|
||||
slot_prs = (slot - i*prs_config->PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame;
|
||||
LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id);
|
||||
nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp);
|
||||
nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, cfg, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
|
||||
for (int i=0; i<fp->Lmax; i++) {
|
||||
for (int i = 0; i < fp->Lmax; i++) {
|
||||
if (msgTx->ssb[i].active) {
|
||||
nr_common_signal_procedures(gNB,frame,slot,msgTx->ssb[i].ssb_pdu);
|
||||
nr_common_signal_procedures(gNB, frame, slot, msgTx->ssb[i].ssb_pdu);
|
||||
msgTx->ssb[i].active = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
|
||||
|
||||
int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch;
|
||||
@@ -203,7 +238,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
|
||||
|
||||
nr_generate_dci_top(msgTx, slot, (int32_t *)&gNB->common_vars.txdataF[0][txdataF_offset], gNB->TX_AMP, fp);
|
||||
nr_generate_dci_top(msgTx, slot, txdataF_offset);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
|
||||
}
|
||||
@@ -218,42 +253,42 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){
|
||||
NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
|
||||
if (csirs->active == 1) {
|
||||
AssertFatal(gNB->common_vars.beam_id == NULL, "Cannot handle CSI in the framework of beamforming yet\n");
|
||||
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
|
||||
if (csi_params->csi_type == 2) { // ZP-CSI
|
||||
csirs->active = 0;
|
||||
return;
|
||||
}
|
||||
csi_mapping_parms_t mapping_parms = get_csi_mapping_parms(csi_params->row,
|
||||
csi_params->freq_domain,
|
||||
csi_params->symb_l0,
|
||||
csi_params->symb_l1);
|
||||
nr_generate_csi_rs(&gNB->frame_parms,
|
||||
(int32_t **)gNB->common_vars.txdataF,
|
||||
(int32_t **)gNB->common_vars.txdataF[0],
|
||||
gNB->TX_AMP,
|
||||
gNB->nr_csi_info,
|
||||
csi_params,
|
||||
slot,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
&mapping_parms);
|
||||
csirs->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// if ((frame&127) == 0) dump_pdsch_stats(gNB);
|
||||
|
||||
//apply the OFDM symbol rotation here
|
||||
if (gNB->phase_comp) {
|
||||
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
apply_nr_rotation_TX(fp,
|
||||
&gNB->common_vars.txdataF[aa][txdataF_offset],
|
||||
fp->symbol_rotation[0],
|
||||
slot,
|
||||
fp->N_RB_DL,
|
||||
0,
|
||||
fp->Ncp == EXTENDED ? 12 : 14);
|
||||
|
||||
T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0),
|
||||
T_INT(frame), T_INT(slot),
|
||||
T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
|
||||
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
|
||||
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
apply_nr_rotation_TX(fp,
|
||||
&gNB->common_vars.txdataF[i][aa][txdataF_offset],
|
||||
fp->symbol_rotation[0],
|
||||
slot,
|
||||
fp->N_RB_DL,
|
||||
0,
|
||||
fp->Ncp == EXTENDED ? 12 : 14);
|
||||
T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0),
|
||||
T_INT(frame), T_INT(slot),
|
||||
T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +374,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
|
||||
int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
|
||||
|
||||
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
|
||||
LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][0][(ulsch_harq->slot%RU_RX_SLOT_DEPTH)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
|
||||
LOG_M("rxsigF0_ext.m","rxsF0_ext",
|
||||
&gNB->pusch_vars[0].rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB *
|
||||
ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB *
|
||||
@@ -728,13 +763,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
gNB_I0_measurements(gNB, slot_rx, first_symb, num_symb, rb_mask_ul);
|
||||
|
||||
const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
|
||||
int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
|
||||
LOG_D(PHY,
|
||||
"frame %d, slot %d: UL signal energy %d\n",
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset + offset + (47 * 12)], 12 * 18));
|
||||
|
||||
start_meas(&gNB->phy_proc_rx);
|
||||
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
@@ -742,13 +770,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
if (pucch) {
|
||||
if (NFAPI_MODE == NFAPI_MODE_PNF)
|
||||
pucch->frame = frame_rx;
|
||||
if ((pucch->active == 1) &&
|
||||
(pucch->frame == frame_rx) &&
|
||||
(pucch->slot == slot_rx) ) {
|
||||
|
||||
if (pucch->active && (pucch->frame == frame_rx) && (pucch->slot == slot_rx)) {
|
||||
c16_t **rxdataF = gNB->common_vars.rxdataF[pucch->beam_nb];
|
||||
pucch_decode_done = 1;
|
||||
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||
uint16_t num_ucis;
|
||||
switch (pucch_pdu->format_type) {
|
||||
case 0:
|
||||
@@ -760,21 +785,17 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1;
|
||||
|
||||
offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
|
||||
LOG_D(PHY,
|
||||
int offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
|
||||
LOG_D(NR_PHY,
|
||||
"frame %d, slot %d: PUCCH signal energy %d\n",
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
signal_energy_nodc(&gNB->common_vars.rxdataF[0][soffset + offset], 12));
|
||||
signal_energy_nodc(&rxdataF[0][soffset + offset], 12));
|
||||
|
||||
nr_decode_pucch0(gNB,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
uci_pdu_format0,
|
||||
pucch_pdu);
|
||||
nr_decode_pucch0(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format0, pucch_pdu);
|
||||
|
||||
gNB->UL_INFO.uci_ind.num_ucis += 1;
|
||||
pucch->active = 0;
|
||||
pucch->active = false;
|
||||
break;
|
||||
case 2:
|
||||
num_ucis = gNB->UL_INFO.uci_ind.num_ucis;
|
||||
@@ -786,14 +807,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_2_3_4;
|
||||
|
||||
LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx);
|
||||
nr_decode_pucch2(gNB,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
uci_pdu_format2,
|
||||
pucch_pdu);
|
||||
nr_decode_pucch2(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format2, pucch_pdu);
|
||||
|
||||
gNB->UL_INFO.uci_ind.num_ucis += 1;
|
||||
pucch->active = 0;
|
||||
pucch->active = false;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n");
|
||||
@@ -852,7 +869,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 1);
|
||||
start_meas(&gNB->rx_pusch_stats);
|
||||
nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
|
||||
nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid, ulsch->beam_nb);
|
||||
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
|
||||
pusch_vars->ulsch_power_tot = 0;
|
||||
pusch_vars->ulsch_noise_power_tot = 0;
|
||||
@@ -923,7 +940,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
for (int i = 0; i < gNB->max_nb_srs; i++) {
|
||||
NR_gNB_SRS_t *srs = &gNB->srs[i];
|
||||
if (srs) {
|
||||
if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
|
||||
if ((srs->active == true) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
|
||||
LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i);
|
||||
|
||||
start_meas(&gNB->rx_srs_stats);
|
||||
@@ -936,16 +953,15 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
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];
|
||||
int8_t snr_per_rb[srs_pdu->bwp_size];
|
||||
int8_t snr = 0;
|
||||
|
||||
start_meas(&gNB->generate_srs_stats);
|
||||
if (check_srs_pdu(srs_pdu, &gNB->nr_srs_info[i]->srs_pdu) == 0) {
|
||||
generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
|
||||
}
|
||||
stop_meas(&gNB->generate_srs_stats);
|
||||
|
||||
c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb];
|
||||
start_meas(&gNB->get_srs_signal_stats);
|
||||
int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
|
||||
int srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
|
||||
stop_meas(&gNB->get_srs_signal_stats);
|
||||
|
||||
if (srs_est >= 0) {
|
||||
@@ -961,11 +977,11 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
srs_estimated_channel_time,
|
||||
srs_estimated_channel_time_shifted,
|
||||
snr_per_rb,
|
||||
&snr);
|
||||
&gNB->srs->snr);
|
||||
stop_meas(&gNB->srs_channel_estimation_stats);
|
||||
}
|
||||
|
||||
if ((snr * 10) < gNB->srs_thres) {
|
||||
if ((gNB->srs->snr * 10) < gNB->srs_thres) {
|
||||
srs_est = -1;
|
||||
}
|
||||
|
||||
@@ -1038,7 +1054,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
nfapi_nr_srs_beamforming_report_t nr_srs_bf_report;
|
||||
nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size;
|
||||
nr_srs_bf_report.num_symbols = 1 << srs_pdu->num_symbols;
|
||||
nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
|
||||
nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (gNB->srs->snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
|
||||
nr_srs_bf_report.num_reported_symbols = 1 << srs_pdu->num_symbols;
|
||||
fill_srs_reported_symbol_list(&nr_srs_bf_report.prgs, srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
|
||||
|
||||
@@ -1131,7 +1147,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
#endif
|
||||
|
||||
gNB->UL_INFO.srs_ind.number_of_pdus += 1;
|
||||
srs->active = 0;
|
||||
srs->active = false;
|
||||
|
||||
stop_meas(&gNB->rx_srs_stats);
|
||||
}
|
||||
@@ -1141,7 +1157,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
stop_meas(&gNB->phy_proc_rx);
|
||||
|
||||
if (pucch_decode_done || pusch_decode_done) {
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
|
||||
|
||||
@@ -39,7 +39,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
|
||||
|
||||
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx);
|
||||
void nr_fep_tp(RU_t *ru, int slot);
|
||||
@@ -47,5 +46,11 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot);
|
||||
void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
|
||||
int nr_phy_init_RU(RU_t *ru);
|
||||
void nr_phy_free_RU(RU_t *ru);
|
||||
|
||||
void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot);
|
||||
int beam_index_allocation(int fapi_beam_index,
|
||||
NR_gNB_COMMON *common_vars,
|
||||
int slot,
|
||||
int symbols_per_slot,
|
||||
int start_symbol,
|
||||
int nb_symbols);
|
||||
#endif
|
||||
|
||||
@@ -1081,7 +1081,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
}
|
||||
}
|
||||
nr_ue_csi_rs_procedures(ue, proc, rxdataF);
|
||||
ue->csirs_vars[gNB_id]->active = 0;
|
||||
}
|
||||
|
||||
if (dlsch[0].active) {
|
||||
|
||||
@@ -82,7 +82,7 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu;
|
||||
if (typeSpecific) {
|
||||
uint8_t *psbch_decoded_output = (uint8_t *)typeSpecific;
|
||||
memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, sizeof(4)); // 4 bytes of PSBCH payload bytes
|
||||
memcpy(ssb_pdu->psbch_payload, psbch_decoded_output, 4); // 4 bytes of PSBCH payload bytes
|
||||
ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE;
|
||||
ssb_pdu->rx_slss_id = rx_slss_id;
|
||||
ssb_pdu->decode_status = true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user