Merge branch 'integration_2024_w30' into 'develop'
Integration: `2024.w30` See merge request oai/openairinterface5g!2877 * !2830 NR feature set update * !2868 Fix support for USRP UHD Versions => 4.5.0.0 * !2870 fix(docker): base image for target oai-gnb-aw2s shall be jammy * !2874 Fix memory leaks in gNB PDU Session Setup Request processing * !2866 RRC: reject PDU sessions if security is not active * !2829 Automatic update of USRP RX gain during initial search using --agc option * !2878 USRP: add a T trace to record the TX IQ data on antenna 0 * !2633 Handle F1 Reset at DU, and ensure state re-init on F1Setup * !2864 Fix an assert in power control * !2754 Introduce gold sequence cache
This commit is contained in:
+1
-1
@@ -1017,6 +1017,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
|
||||||
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/refsig.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1042,7 +1043,6 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
|
||||||
|
|||||||
@@ -269,6 +269,14 @@ install_usrp_uhd_driver_from_source(){
|
|||||||
# - 3.15.0.0
|
# - 3.15.0.0
|
||||||
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff
|
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-3.15-tdd-patch.diff
|
||||||
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||||
|
elif [[ "$UHD_VERSION" == "4.7.0.0" || "$UHD_VERSION" == "4.6.0.0" || "$UHD_VERSION" == "4.5.0.0" ]]; then
|
||||||
|
# Tested that patch for the following versions:
|
||||||
|
# - 4.7.0.0
|
||||||
|
cp $OPENAIR_DIR/cmake_targets/tools/uhd-4.x-tdd-patch.diff $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||||
|
sed -i '9,13 s/STATE_OFF/STATE_RX1_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||||
|
sed -i '24,28 s/STATE_OFF/STATE_RX2_OFF/' $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||||
|
git apply $OPENAIR_DIR/cmake_targets/tools/uhd-4.5plus-tdd-patch.diff
|
||||||
|
ret=$?;[[ $ret -ne 0 ]] && echo_fatal "Could not apply the TDD patch"
|
||||||
else
|
else
|
||||||
# Tested that patch for the following versions:
|
# Tested that patch for the following versions:
|
||||||
# - 4.0.0.0
|
# - 4.0.0.0
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ ID = USRP_RX_ANT0
|
|||||||
GROUP = ALL:HEAVY
|
GROUP = ALL:HEAVY
|
||||||
FORMAT = int,timestap : buffer,data
|
FORMAT = int,timestap : buffer,data
|
||||||
|
|
||||||
|
ID = USRP_TX_ANT0
|
||||||
|
DESC = TX IQ data as sent by USRP driver on antenna 0
|
||||||
|
GROUP = ALL:HEAVY
|
||||||
|
FORMAT = int,timestap : buffer,data
|
||||||
|
|
||||||
#PHY logs
|
#PHY logs
|
||||||
ID = ENB_PHY_UL_TICK
|
ID = ENB_PHY_UL_TICK
|
||||||
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
|
DESC = eNodeB uplink tick - one tick per ms at start of uplink processing
|
||||||
|
|||||||
+24
-48
@@ -105,6 +105,16 @@ int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs)
|
|||||||
return (-1); // not found
|
return (-1); // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs)
|
||||||
|
{
|
||||||
|
int scs_index = scs + frequency_range;
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
if (n_rbs <= tables_5_3_2[scs_index][i])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1; // not found
|
||||||
|
}
|
||||||
|
|
||||||
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
|
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
|
||||||
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
|
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
|
||||||
// Notes:
|
// Notes:
|
||||||
@@ -299,64 +309,30 @@ void check_ssb_raster(uint64_t freq, int band, int scs)
|
|||||||
band);
|
band);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb)
|
int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index)
|
||||||
{
|
{
|
||||||
int bw_index = get_supported_band_index(scs, frequency_range, nb_rb);
|
|
||||||
if (frequency_range == FR1) {
|
if (frequency_range == FR1) {
|
||||||
switch (bw_index) {
|
int bandwidth_index_to_mhz[] = {5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100};
|
||||||
case 0 :
|
AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
|
||||||
return 5; // 5MHz
|
"Bandwidth index %d is invalid\n",
|
||||||
case 1 :
|
bw_index);
|
||||||
return 10;
|
return bandwidth_index_to_mhz[bw_index];
|
||||||
case 2 :
|
} else {
|
||||||
return 15;
|
int bandwidth_index_to_mhz[] = {50, 100, 200, 400};
|
||||||
case 3 :
|
AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
|
||||||
return 20;
|
"Bandwidth index %d is invalid\n",
|
||||||
case 4 :
|
bw_index);
|
||||||
return 25;
|
return bandwidth_index_to_mhz[bw_index];
|
||||||
case 5 :
|
|
||||||
return 30;
|
|
||||||
case 6 :
|
|
||||||
return 40;
|
|
||||||
case 7 :
|
|
||||||
return 50;
|
|
||||||
case 8 :
|
|
||||||
return 60;
|
|
||||||
case 9 :
|
|
||||||
return 80;
|
|
||||||
case 10 :
|
|
||||||
return 90;
|
|
||||||
case 11 :
|
|
||||||
return 100;
|
|
||||||
default :
|
|
||||||
AssertFatal(false, "Invalid band index for FR1 %d\n", bw_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (bw_index) {
|
|
||||||
case 0 :
|
|
||||||
return 50; // 50MHz
|
|
||||||
case 1 :
|
|
||||||
return 100;
|
|
||||||
case 2 :
|
|
||||||
return 200;
|
|
||||||
case 3 :
|
|
||||||
return 400;
|
|
||||||
default :
|
|
||||||
AssertFatal(false, "Invalid band index for FR2 %d\n", bw_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type)
|
bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type)
|
||||||
{
|
{
|
||||||
// 38.101-1 section 6.2.2
|
// 38.101-1 section 6.2.2
|
||||||
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
|
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
|
||||||
int index = get_nr_table_idx(nr_band, scs);
|
int index = get_nr_table_idx(nr_band, scs);
|
||||||
|
|
||||||
int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, nb_ul) * 1000;
|
|
||||||
float limit = frame_type == TDD ? 0.04 : 0.03;
|
float limit = frame_type == TDD ? 0.04 : 0.03;
|
||||||
float rel_bw = (float) (band_size_khz) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min);
|
float rel_bw = (float) (2 * channel_bandwidth * 1000) / (float) (nr_bandtable[index].ul_max - nr_bandtable[index].ul_min);
|
||||||
return rel_bw > limit;
|
return rel_bw > limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -224,8 +224,8 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports);
|
|||||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
||||||
int get_nb_periods_per_frame(uint8_t tdd_period);
|
int get_nb_periods_per_frame(uint8_t tdd_period);
|
||||||
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
|
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
|
||||||
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type);
|
bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, frame_type_t frame_type);
|
||||||
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb);
|
int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index);
|
||||||
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
|
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
|
||||||
void get_samplerate_and_bw(int mu,
|
void get_samplerate_and_bw(int mu,
|
||||||
int n_rb,
|
int n_rb,
|
||||||
@@ -248,6 +248,7 @@ int get_scan_ssb_first_sc(const double fc,
|
|||||||
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
|
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
|
||||||
|
|
||||||
void check_ssb_raster(uint64_t freq, int band, int scs);
|
void check_ssb_raster(uint64_t freq, int band, int scs);
|
||||||
|
int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs);
|
||||||
|
|
||||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||||
|
|||||||
+12
-7
@@ -70,7 +70,7 @@ These modes of operation are supported:
|
|||||||
- DMRS configuration type 1 and 2
|
- DMRS configuration type 1 and 2
|
||||||
- Single and multiple DMRS symbols
|
- Single and multiple DMRS symbols
|
||||||
- PTRS support
|
- PTRS support
|
||||||
- Support for 1, 2 and 4 TX antennas
|
- Support for up to 4 TX antennas
|
||||||
- Support for up to 2 layers
|
- Support for up to 2 layers
|
||||||
- Support for 256 QAM
|
- Support for 256 QAM
|
||||||
* NR-CSIRS Generation of sequence at PHY
|
* NR-CSIRS Generation of sequence at PHY
|
||||||
@@ -79,7 +79,7 @@ These modes of operation are supported:
|
|||||||
- DMRS configuration type 1 and 2
|
- DMRS configuration type 1 and 2
|
||||||
- Single and multiple DMRS symbols
|
- Single and multiple DMRS symbols
|
||||||
- PTRS support
|
- PTRS support
|
||||||
- Support for up to 2 RX antenna
|
- Support for up to 4 RX antennas
|
||||||
- Support for up to 2 layers
|
- Support for up to 2 layers
|
||||||
- Support for 256 QAM
|
- Support for 256 QAM
|
||||||
* NR-PUCCH
|
* NR-PUCCH
|
||||||
@@ -205,6 +205,7 @@ These modes of operation are supported:
|
|||||||
- F1 UE Context modification required
|
- F1 UE Context modification required
|
||||||
- F1 UE Context release req/cmd/complete
|
- F1 UE Context release req/cmd/complete
|
||||||
- F1 gNB CU configuration update
|
- F1 gNB CU configuration update
|
||||||
|
- F1 Reset (handled at DU only, full reset only)
|
||||||
- Interface with RRC
|
- Interface with RRC
|
||||||
- Interface with GTP-u (tunnel creation/handling for F1-U interface)
|
- Interface with GTP-u (tunnel creation/handling for F1-U interface)
|
||||||
- One CU(-CP) can handle multiple DUs
|
- One CU(-CP) can handle multiple DUs
|
||||||
@@ -237,7 +238,8 @@ These modes of operation are supported:
|
|||||||
## NR UE PHY Layer ##
|
## NR UE PHY Layer ##
|
||||||
|
|
||||||
* Initial synchronization
|
* Initial synchronization
|
||||||
- the UE needs to know the position in frequency of the SSBs (via command line parameter in SA)
|
- non-blind synchronization (information required: carrier frequency, bandwidth, numerology)
|
||||||
|
- option to search SSB inside the bandwidth available
|
||||||
* Time tracking based on PBCH DMRS
|
* Time tracking based on PBCH DMRS
|
||||||
* Frequency offset estimation based on PSS and SSS
|
* Frequency offset estimation based on PSS and SSS
|
||||||
* 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2
|
* 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2
|
||||||
@@ -292,7 +294,7 @@ These modes of operation are supported:
|
|||||||
|
|
||||||
* MAC -> PHY configuration via UE FAPI P5 interface
|
* MAC -> PHY configuration via UE FAPI P5 interface
|
||||||
* Basic MAC to control PHY via UE FAPI P7 interface
|
* Basic MAC to control PHY via UE FAPI P7 interface
|
||||||
* PHY -> MAC indication (needs some improvement)
|
* PHY -> MAC indication
|
||||||
|
|
||||||
## NR UE Higher Layers ##
|
## NR UE Higher Layers ##
|
||||||
|
|
||||||
@@ -314,19 +316,21 @@ These modes of operation are supported:
|
|||||||
- format 01 (C-RNTI)
|
- format 01 (C-RNTI)
|
||||||
* UCI processing
|
* UCI processing
|
||||||
- ACK/NACK processing
|
- ACK/NACK processing
|
||||||
- Triggering periodic SR
|
- Scheduling request procedures
|
||||||
- CSI measurement reporting
|
- CSI measurement reporting (periodic and aperiodic)
|
||||||
* DLSCH scheduler
|
* DLSCH scheduler
|
||||||
- Configuration of fapi PDU according to DCI
|
- Configuration of fapi PDU according to DCI
|
||||||
- HARQ procedures
|
- HARQ procedures
|
||||||
* ULSCH scheduler
|
* ULSCH scheduler
|
||||||
- Configuration of fapi PDU according to DCI
|
- Configuration of fapi PDU according to DCI
|
||||||
|
- Buffer status reporting procedures
|
||||||
- Logical channel prioritization of 'data from any logical channel'
|
- Logical channel prioritization of 'data from any logical channel'
|
||||||
|
- UCI on PUSCH
|
||||||
* NR-CSIRS scheduler
|
* NR-CSIRS scheduler
|
||||||
- Scheduling of NR-CSIRS reception
|
- Scheduling of NR-CSIRS reception
|
||||||
- Fill UCI for CSI measurement reporting
|
- Fill UCI for CSI measurement reporting
|
||||||
* Scheduler procedures for SRS transmission
|
* Scheduler procedures for SRS transmission
|
||||||
- Periodic SRS transmission
|
- Periodic and aperiodic SRS transmission
|
||||||
* Bandwidth part (BWP) operation
|
* Bandwidth part (BWP) operation
|
||||||
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
|
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
|
||||||
|
|
||||||
@@ -363,6 +367,7 @@ These modes of operation are supported:
|
|||||||
- RRCSetupRequest/RRCSetup/RRCSetupComplete
|
- RRCSetupRequest/RRCSetup/RRCSetupComplete
|
||||||
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
|
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
|
||||||
- RRC Reconfiguration/Reconfiguration complete
|
- RRC Reconfiguration/Reconfiguration complete
|
||||||
|
- RRCReestablishmentRequest/RRC Reestablishment/Reestablishment complete
|
||||||
- Support for master cell group configuration
|
- Support for master cell group configuration
|
||||||
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
|
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
|
||||||
* Interface with PDCP: configuration, DCCH and CCCH message handling
|
* Interface with PDCP: configuration, DCCH and CCCH message handling
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ RUN /bin/sh oaienv && \
|
|||||||
./build_oai -w AW2SORI -t Ethernet
|
./build_oai -w AW2SORI -t Ethernet
|
||||||
|
|
||||||
#start from scratch for target executable
|
#start from scratch for target executable
|
||||||
FROM ubuntu:bionic as oai-gnb-aw2s
|
FROM ubuntu:jammy as oai-gnb-aw2s
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
ENV TZ=Europe
|
ENV TZ=Europe
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
|
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
|
||||||
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
|
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
|
||||||
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
|
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
|
||||||
|
#define CONFIG_HLP_AGC "Rx Gain control used for UE"
|
||||||
/*--------------------------------------------------------------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
/* command line parameters for LOG utility */
|
/* command line parameters for LOG utility */
|
||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
|
|||||||
+38
-5
@@ -348,10 +348,31 @@ typedef struct {
|
|||||||
int rx_offset;
|
int rx_offset;
|
||||||
} syncData_t;
|
} syncData_t;
|
||||||
|
|
||||||
|
static int nr_ue_adjust_rx_gain(PHY_VARS_NR_UE *UE, openair0_config_t *cfg0, int gain_change)
|
||||||
|
{
|
||||||
|
// Increase the RX gain by the value determined by adjust_rxgain
|
||||||
|
cfg0->rx_gain[0] += gain_change;
|
||||||
|
|
||||||
|
// Set new RX gain.
|
||||||
|
int ret_gain = UE->rfdevice.trx_set_gains_func(&UE->rfdevice, cfg0);
|
||||||
|
// APPLY RX gain again if crossed the MAX RX gain threshold
|
||||||
|
if (ret_gain < 0) {
|
||||||
|
gain_change += ret_gain;
|
||||||
|
cfg0->rx_gain[0] += ret_gain;
|
||||||
|
ret_gain = UE->rfdevice.trx_set_gains_func(&UE->rfdevice, cfg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int applied_rxgain = cfg0->rx_gain[0] - cfg0->rx_gain_offset[0];
|
||||||
|
LOG_I(PHY, "Rxgain adjusted by %d dB, RX gain: %d dB \n", gain_change, applied_rxgain);
|
||||||
|
|
||||||
|
return gain_change;
|
||||||
|
}
|
||||||
|
|
||||||
static void UE_synch(void *arg) {
|
static void UE_synch(void *arg) {
|
||||||
syncData_t *syncD = (syncData_t *)arg;
|
syncData_t *syncD = (syncData_t *)arg;
|
||||||
PHY_VARS_NR_UE *UE = syncD->UE;
|
PHY_VARS_NR_UE *UE = syncD->UE;
|
||||||
UE->is_synchronized = 0;
|
UE->is_synchronized = 0;
|
||||||
|
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
|
||||||
|
|
||||||
if (UE->target_Nid_cell != -1) {
|
if (UE->target_Nid_cell != -1) {
|
||||||
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
|
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
|
||||||
@@ -383,18 +404,30 @@ static void UE_synch(void *arg) {
|
|||||||
|
|
||||||
// rerun with new cell parameters and frequency-offset
|
// rerun with new cell parameters and frequency-offset
|
||||||
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
|
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
|
||||||
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_carrier, dl_carrier, freq_offset);
|
nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset);
|
||||||
|
|
||||||
|
if (get_nrUE_params()->agc) {
|
||||||
|
nr_ue_adjust_rx_gain(UE, cfg0, UE->adjust_rxgain);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_I(PHY,
|
LOG_I(PHY,
|
||||||
"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
|
"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
|
||||||
hw_slot_offset,
|
hw_slot_offset,
|
||||||
freq_offset,
|
freq_offset,
|
||||||
openair0_cfg[UE->rf_map.card].rx_gain[0],
|
cfg0->rx_gain[0] - cfg0->rx_gain_offset[0],
|
||||||
openair0_cfg[UE->rf_map.card].rx_freq[0],
|
cfg0->rx_freq[0],
|
||||||
openair0_cfg[UE->rf_map.card].tx_freq[0]);
|
cfg0->tx_freq[0]);
|
||||||
|
|
||||||
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
|
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, cfg0);
|
||||||
UE->is_synchronized = 1;
|
UE->is_synchronized = 1;
|
||||||
|
} else {
|
||||||
|
int gain_change = 0;
|
||||||
|
if (get_nrUE_params()->agc)
|
||||||
|
gain_change = nr_ue_adjust_rx_gain(UE, cfg0, INCREASE_IN_RXGAIN);
|
||||||
|
if (gain_change)
|
||||||
|
LOG_I(PHY, "synch retry: Rx gain increased \n");
|
||||||
|
else
|
||||||
|
LOG_E(PHY, "synch Failed: \n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
{"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
|
{"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \
|
||||||
{"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \
|
{"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \
|
||||||
{"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \
|
{"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \
|
||||||
|
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ typedef struct {
|
|||||||
int ldpc_offload_flag;
|
int ldpc_offload_flag;
|
||||||
unsigned int ntn_koffset;
|
unsigned int ntn_koffset;
|
||||||
double ntn_ta_common;
|
double ntn_ta_common;
|
||||||
|
int agc;
|
||||||
} nrUE_params_t;
|
} nrUE_params_t;
|
||||||
extern uint64_t get_nrUE_optmask(void);
|
extern uint64_t get_nrUE_optmask(void);
|
||||||
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
|
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
|
||||||
|
|||||||
+3
-143
@@ -143,109 +143,16 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
|||||||
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
||||||
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
|
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
|
||||||
|
|
||||||
// PBCH DMRS gold sequences generation
|
|
||||||
nr_init_pbch_dmrs(gNB);
|
|
||||||
//PDCCH DMRS init
|
|
||||||
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
|
||||||
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
|
||||||
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
|
|
||||||
|
|
||||||
gNB->bad_pucch = 0;
|
gNB->bad_pucch = 0;
|
||||||
if (gNB->TX_AMP == 0)
|
if (gNB->TX_AMP == 0)
|
||||||
gNB->TX_AMP = AMP;
|
gNB->TX_AMP = AMP;
|
||||||
// ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
|
// ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
|
||||||
int pdcch_dmrs_init_length = (((fp->N_RB_DL<<1)*3)>>5)+1;
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
|
||||||
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(pdcch_dmrs_init_length*sizeof(uint32_t));
|
|
||||||
LOG_D(PHY,"pdcch_dmrs[%d][%d] %p\n",slot,symb,pdcch_dmrs[slot][symb]);
|
|
||||||
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_generate_modulation_table();
|
nr_generate_modulation_table();
|
||||||
gNB->pdcch_gold_init = cfg->cell_config.phy_cell_id.value;
|
|
||||||
nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
|
|
||||||
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
||||||
|
|
||||||
//PDSCH DMRS init
|
|
||||||
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
|
||||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
|
||||||
|
|
||||||
// ceil(((NB_RB*12(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
|
||||||
const int pdsch_dmrs_init_length = ((fp->N_RB_DL*24)>>5)+1;
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
|
|
||||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_NB_NSCID*sizeof(uint32_t *));
|
|
||||||
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
|
|
||||||
for (int q=0; q<NR_NB_NSCID; q++) {
|
|
||||||
pdsch_dmrs[slot][symb][q] = malloc16(pdsch_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
|
|
||||||
memset(pdsch_dmrs[slot][symb][q], 0, sizeof(uint32_t) * pdsch_dmrs_init_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (int nscid = 0; nscid < NR_NB_NSCID; nscid++) {
|
|
||||||
gNB->pdsch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
|
|
||||||
nr_init_pdsch_dmrs(gNB, nscid, cfg->cell_config.phy_cell_id.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//PUSCH DMRS init
|
|
||||||
gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(NR_NB_NSCID*sizeof(uint32_t ***));
|
|
||||||
|
|
||||||
uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
|
|
||||||
|
|
||||||
int pusch_dmrs_init_length = ((fp->N_RB_UL*12)>>5)+1;
|
|
||||||
for(int nscid=0; nscid<NR_NB_NSCID; nscid++) {
|
|
||||||
pusch_dmrs[nscid] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
|
||||||
AssertFatal(pusch_dmrs[nscid]!=NULL, "NR init: pusch_dmrs for nscid %d - malloc failed\n", nscid);
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pusch_dmrs[nscid][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
|
||||||
AssertFatal(pusch_dmrs[nscid][slot]!=NULL, "NR init: pusch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pusch_dmrs[nscid][slot][symb] = (uint32_t *)malloc16(pusch_dmrs_init_length*sizeof(uint32_t));
|
|
||||||
AssertFatal(pusch_dmrs[nscid][slot][symb]!=NULL, "NR init: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int nscid=0; nscid<NR_NB_NSCID; nscid++) {
|
|
||||||
gNB->pusch_gold_init[nscid] = cfg->cell_config.phy_cell_id.value;
|
|
||||||
nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CSI RS init
|
// CSI RS init
|
||||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
|
||||||
gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t));
|
||||||
gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
|
||||||
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
|
||||||
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
|
|
||||||
nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value);
|
|
||||||
|
|
||||||
//PRS init
|
|
||||||
nr_init_prs(gNB);
|
|
||||||
|
|
||||||
generate_ul_reference_signal_sequences(SHRT_MAX);
|
generate_ul_reference_signal_sequences(SHRT_MAX);
|
||||||
|
|
||||||
@@ -330,7 +237,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
|||||||
|
|
||||||
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||||
{
|
{
|
||||||
NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
|
|
||||||
const int Ptx = gNB->gNB_config.carrier_config.num_tx_ant.value;
|
const int Ptx = gNB->gNB_config.carrier_config.num_tx_ant.value;
|
||||||
const int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
const int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
||||||
const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
|
const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB()
|
||||||
@@ -342,43 +248,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
|||||||
free_and_zero(meas->n0_subband_power);
|
free_and_zero(meas->n0_subband_power);
|
||||||
free_and_zero(meas->n0_subband_power_dB);
|
free_and_zero(meas->n0_subband_power_dB);
|
||||||
|
|
||||||
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
|
||||||
free_and_zero(pdcch_dmrs[slot][symb]);
|
|
||||||
free_and_zero(pdcch_dmrs[slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(pdcch_dmrs);
|
|
||||||
|
|
||||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
for (int q = 0; q < NR_NB_NSCID; q++)
|
|
||||||
free_and_zero(pdsch_dmrs[slot][symb][q]);
|
|
||||||
free_and_zero(pdsch_dmrs[slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(pdsch_dmrs[slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(gNB->nr_gold_pdsch_dmrs);
|
|
||||||
|
|
||||||
uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs;
|
|
||||||
for(int nscid = 0; nscid < 2; nscid++) {
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
|
||||||
free_and_zero(pusch_dmrs[nscid][slot][symb]);
|
|
||||||
free_and_zero(pusch_dmrs[nscid][slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(pusch_dmrs[nscid]);
|
|
||||||
}
|
|
||||||
free_and_zero(pusch_dmrs);
|
|
||||||
|
|
||||||
uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
|
||||||
free_and_zero(nr_gold_csi_rs[slot][symb]);
|
|
||||||
free_and_zero(nr_gold_csi_rs[slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(nr_gold_csi_rs);
|
|
||||||
free_and_zero(gNB->nr_csi_info);
|
free_and_zero(gNB->nr_csi_info);
|
||||||
|
|
||||||
for (int id = 0; id < gNB->max_nb_srs; id++) {
|
for (int id = 0; id < gNB->max_nb_srs; id++) {
|
||||||
@@ -401,17 +270,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
|||||||
free_and_zero(common_vars->beam_id[i]);
|
free_and_zero(common_vars->beam_id[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int rsc=0; rsc < gNB->prs_vars.NumPRSResources; rsc++) {
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
free_and_zero(gNB->nr_gold_prs[rsc][slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(gNB->nr_gold_prs[rsc][slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(gNB->nr_gold_prs[rsc]);
|
|
||||||
}
|
|
||||||
free_and_zero(gNB->nr_gold_prs);
|
|
||||||
|
|
||||||
/* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the
|
/* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the
|
||||||
* RU's txdataF/rxdataF, and the RU will free that */
|
* RU's txdataF/rxdataF, and the RU will free that */
|
||||||
free_and_zero(common_vars->txdataF);
|
free_and_zero(common_vars->txdataF);
|
||||||
@@ -518,7 +376,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fp->threequarter_fs = 0;
|
fp->threequarter_fs = 0;
|
||||||
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL);
|
frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1;
|
||||||
|
int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL);
|
||||||
|
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||||
|
|
||||||
nr_init_frame_parms(gNB_config, fp);
|
nr_init_frame_parms(gNB_config, fp);
|
||||||
|
|
||||||
|
|||||||
@@ -162,32 +162,6 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue)
|
|||||||
|
|
||||||
// load the config file params
|
// load the config file params
|
||||||
RCconfig_nrUE_prs(ue);
|
RCconfig_nrUE_prs(ue);
|
||||||
|
|
||||||
//PRS sequence init
|
|
||||||
ue->nr_gold_prs = malloc16(ue->prs_active_gNBs * sizeof(uint32_t ****));
|
|
||||||
uint32_t *****prs = ue->nr_gold_prs;
|
|
||||||
AssertFatal(prs!=NULL, "%s: positioning reference signal malloc failed\n", __FUNCTION__);
|
|
||||||
for (int gnb = 0; gnb < ue->prs_active_gNBs; gnb++) {
|
|
||||||
prs[gnb] = malloc16(ue->prs_vars[gnb]->NumPRSResources * sizeof(uint32_t ***));
|
|
||||||
AssertFatal(prs[gnb]!=NULL, "%s: positioning reference signal for gnb %d - malloc failed\n", __FUNCTION__, gnb);
|
|
||||||
|
|
||||||
for (int rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) {
|
|
||||||
prs[gnb][rsc] = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
|
||||||
AssertFatal(prs[gnb][rsc]!=NULL, "%s: positioning reference signal for gnb %d rsc %d- malloc failed\n", __FUNCTION__, gnb, rsc);
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
prs[gnb][rsc][slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
|
||||||
AssertFatal(prs[gnb][rsc][slot]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
prs[gnb][rsc][slot][symb] = malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD * sizeof(uint32_t));
|
|
||||||
AssertFatal(prs[gnb][rsc][slot][symb]!=NULL, "%s: positioning reference signal for gnb %d rsc %d slot %d symbol %d - malloc failed\n", __FUNCTION__, gnb, rsc, slot, symb);
|
|
||||||
} // for symb
|
|
||||||
} // for slot
|
|
||||||
} // for rsc
|
|
||||||
} // for gnb
|
|
||||||
|
|
||||||
init_nr_gold_prs(ue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||||
@@ -200,8 +174,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
|
NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars;
|
||||||
NR_UE_SRS **const srs_vars = ue->srs_vars;
|
NR_UE_SRS **const srs_vars = ue->srs_vars;
|
||||||
|
|
||||||
int i, slot, symb, gNB_id;
|
|
||||||
|
|
||||||
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
|
LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
|
||||||
|
|
||||||
phy_init_nr_top(ue);
|
phy_init_nr_top(ue);
|
||||||
@@ -210,10 +182,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
|
AssertFatal( nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" );
|
||||||
// init phy_vars_ue
|
// init phy_vars_ue
|
||||||
|
|
||||||
for (i=0; i<fp->Lmax; i++)
|
for (int i = 0; i < fp->Lmax; i++)
|
||||||
ue->measurements.ssb_rsrp_dBm[i] = INT_MIN;
|
ue->measurements.ssb_rsrp_dBm[i] = INT_MIN;
|
||||||
|
|
||||||
for (i=0; i<4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ue->rx_gain_max[i] = 135;
|
ue->rx_gain_max[i] = 135;
|
||||||
ue->rx_gain_med[i] = 128;
|
ue->rx_gain_med[i] = 128;
|
||||||
ue->rx_gain_byp[i] = 120;
|
ue->rx_gain_byp[i] = 120;
|
||||||
@@ -221,12 +193,11 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
|
|
||||||
ue->n_connected_gNB = nb_connected_gNB;
|
ue->n_connected_gNB = nb_connected_gNB;
|
||||||
|
|
||||||
for(gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||||
ue->total_TBS[gNB_id] = 0;
|
ue->total_TBS[gNB_id] = 0;
|
||||||
ue->total_TBS_last[gNB_id] = 0;
|
ue->total_TBS_last[gNB_id] = 0;
|
||||||
ue->bitrate[gNB_id] = 0;
|
ue->bitrate[gNB_id] = 0;
|
||||||
ue->total_received_bits[gNB_id] = 0;
|
ue->total_received_bits[gNB_id] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
// init NR modulation lookup tables
|
// init NR modulation lookup tables
|
||||||
nr_generate_modulation_table();
|
nr_generate_modulation_table();
|
||||||
@@ -245,26 +216,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
/////////////////////////PUSCH DMRS init/////////////////////////
|
/////////////////////////PUSCH DMRS init/////////////////////////
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
// ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
|
||||||
int pusch_dmrs_init_length = ((fp->N_RB_UL*12)>>5)+1;
|
|
||||||
ue->nr_gold_pusch_dmrs = malloc16(fp->slots_per_frame * sizeof(uint32_t ***));
|
|
||||||
uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
|
|
||||||
|
|
||||||
for (slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pusch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **));
|
|
||||||
AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pusch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *));
|
|
||||||
AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
|
|
||||||
for (int q=0; q<NR_NB_NSCID; q++) {
|
|
||||||
pusch_dmrs[slot][symb][q] = malloc16(pusch_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(pusch_dmrs[slot][symb][q]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -283,13 +234,13 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
for (i=0; i<10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
ue->tx_power_dBm[i]=-127;
|
ue->tx_power_dBm[i]=-127;
|
||||||
|
|
||||||
// init TX buffers
|
// init TX buffers
|
||||||
common_vars->txData = malloc16(fp->nb_antennas_tx * sizeof(c16_t *));
|
common_vars->txData = malloc16(fp->nb_antennas_tx * sizeof(c16_t *));
|
||||||
|
|
||||||
for (i=0; i<fp->nb_antennas_tx; i++) {
|
for (int i = 0; i < fp->nb_antennas_tx; i++) {
|
||||||
common_vars->txData[i] = malloc16_clear((fp->samples_per_frame) * sizeof(c16_t));
|
common_vars->txData[i] = malloc16_clear((fp->samples_per_frame) * sizeof(c16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,51 +251,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
if (ue->sl_mode == 2)
|
if (ue->sl_mode == 2)
|
||||||
num_samples = (SL_NR_PSBCH_REPETITION_IN_FRAMES * fp->samples_per_frame) + fp->ofdm_symbol_size;
|
num_samples = (SL_NR_PSBCH_REPETITION_IN_FRAMES * fp->samples_per_frame) + fp->ofdm_symbol_size;
|
||||||
|
|
||||||
for (i=0; i<fp->nb_antennas_rx; i++) {
|
for (int i = 0; i < fp->nb_antennas_rx; i++) {
|
||||||
common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t));
|
common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
|
|
||||||
int pdcch_dmrs_init_length = (((fp->N_RB_DL<<1)*3)>>5)+1;
|
|
||||||
//PDCCH DMRS init (gNB offset = 0)
|
|
||||||
ue->nr_gold_pdcch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
|
||||||
uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0];
|
|
||||||
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pdcch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
|
||||||
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pdcch_dmrs[slot][symb] = malloc16(pdcch_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ceil(((NB_RB*6(k)*2(QPSK)/32) // 3 RE *2(QPSK)
|
|
||||||
int pdsch_dmrs_init_length = ((fp->N_RB_DL*12)>>5)+1;
|
|
||||||
|
|
||||||
//PDSCH DMRS init (eNB offset = 0)
|
|
||||||
ue->nr_gold_pdsch[0] = malloc16(fp->slots_per_frame * sizeof(uint32_t ***));
|
|
||||||
uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
pdsch_dmrs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t **));
|
|
||||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
pdsch_dmrs[slot][symb] = malloc16(NR_NB_NSCID * sizeof(uint32_t *));
|
|
||||||
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
|
|
||||||
for (int q=0; q<NR_NB_NSCID; q++) {
|
|
||||||
pdsch_dmrs[slot][symb][q] = malloc16(pdsch_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d nscid %d - malloc failed\n", slot, symb, q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DLSCH
|
// DLSCH
|
||||||
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||||
prach_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_PRACH));
|
prach_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_PRACH));
|
||||||
csiim_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_IM));
|
csiim_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_IM));
|
||||||
csirs_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_RS));
|
csirs_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_RS));
|
||||||
@@ -355,20 +267,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
srs_vars[gNB_id]->active = false;
|
srs_vars[gNB_id]->active = false;
|
||||||
|
|
||||||
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
// ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1;
|
|
||||||
ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t));
|
ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t));
|
||||||
ue->nr_csi_info->nr_gold_csi_rs = malloc16(fp->slots_per_frame * sizeof(uint32_t **));
|
|
||||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n");
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
ue->nr_csi_info->nr_gold_csi_rs[slot] = malloc16(fp->symbols_per_slot * sizeof(uint32_t *));
|
|
||||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = malloc16(csi_dmrs_init_length * sizeof(uint32_t));
|
|
||||||
AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *));
|
||||||
for (i=0; i<NR_MAX_NB_PORTS; i++) {
|
for (int i = 0; i < NR_MAX_NB_PORTS; i++) {
|
||||||
ue->nr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
ue->nr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,16 +303,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
const NR_DL_FRAME_PARMS* fp = &ue->frame_parms;
|
const NR_DL_FRAME_PARMS* fp = &ue->frame_parms;
|
||||||
phy_term_nr_top();
|
phy_term_nr_top();
|
||||||
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
for (int q=0; q<NR_NB_NSCID; q++)
|
|
||||||
free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb][q]);
|
|
||||||
free_and_zero(ue->nr_gold_pusch_dmrs[slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_pusch_dmrs[slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_pusch_dmrs);
|
|
||||||
|
|
||||||
NR_UE_COMMON* common_vars = &ue->common_vars;
|
NR_UE_COMMON* common_vars = &ue->common_vars;
|
||||||
|
|
||||||
for (int i = 0; i < fp->nb_antennas_tx; i++) {
|
for (int i = 0; i < fp->nb_antennas_tx; i++) {
|
||||||
@@ -425,41 +316,12 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
}
|
}
|
||||||
free_and_zero(common_vars->rxdata);
|
free_and_zero(common_vars->rxdata);
|
||||||
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++)
|
|
||||||
free_and_zero(ue->nr_gold_pdcch[0][slot][symb]);
|
|
||||||
free_and_zero(ue->nr_gold_pdcch[0][slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_pdcch[0]);
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
for (int q=0; q<NR_NB_NSCID; q++)
|
|
||||||
free_and_zero(ue->nr_gold_pdsch[0][slot][symb][q]);
|
|
||||||
free_and_zero(ue->nr_gold_pdsch[0][slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_pdsch[0][slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_pdsch[0]);
|
|
||||||
|
|
||||||
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
|
|
||||||
|
|
||||||
// PDSCH
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||||
|
|
||||||
for (int i=0; i<NR_MAX_NB_PORTS; i++) {
|
for (int i=0; i<NR_MAX_NB_PORTS; i++) {
|
||||||
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]);
|
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]);
|
||||||
}
|
}
|
||||||
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal);
|
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal);
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_csi_info->nr_gold_csi_rs);
|
|
||||||
free_and_zero(ue->nr_csi_info);
|
free_and_zero(ue->nr_csi_info);
|
||||||
|
|
||||||
free_and_zero(ue->nr_srs_info);
|
free_and_zero(ue->nr_srs_info);
|
||||||
@@ -471,24 +333,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
free_and_zero(ue->prach_vars[gNB_id]);
|
free_and_zero(ue->prach_vars[gNB_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int gnb = 0; gnb < ue->prs_active_gNBs; gnb++)
|
|
||||||
{
|
|
||||||
for (int rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++)
|
|
||||||
{
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++)
|
|
||||||
{
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++)
|
|
||||||
{
|
|
||||||
free_and_zero(ue->nr_gold_prs[gnb][rsc][slot][symb]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_prs[gnb][rsc][slot]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_prs[gnb][rsc]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_prs[gnb]);
|
|
||||||
}
|
|
||||||
free_and_zero(ue->nr_gold_prs);
|
|
||||||
|
|
||||||
for(int idx = 0; idx < NR_MAX_PRS_COMB_SIZE; idx++)
|
for(int idx = 0; idx < NR_MAX_PRS_COMB_SIZE; idx++)
|
||||||
{
|
{
|
||||||
for(int k = 0; k < NR_MAX_PRS_RESOURCES_PER_SET; k++)
|
for(int k = 0; k < NR_MAX_PRS_RESOURCES_PER_SET; k++)
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ const char nr_W_4l_4p[5][4][4] = {
|
|||||||
{{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}} // pmi 4
|
{{'1', '1', '1', '1'}, {'1', 'n', '1', 'n'}, {'j', 'j', 'o', 'o'}, {'j', 'o', 'o', 'j'}} // pmi 4
|
||||||
};
|
};
|
||||||
|
|
||||||
void nr_modulation(uint32_t *in,
|
void nr_modulation(const uint32_t *in,
|
||||||
uint32_t length,
|
uint32_t length,
|
||||||
uint16_t mod_order,
|
uint16_t mod_order,
|
||||||
int16_t *out)
|
int16_t *out)
|
||||||
@@ -120,8 +120,8 @@ void nr_modulation(uint32_t *in,
|
|||||||
uint16_t mask = ((1<<mod_order)-1);
|
uint16_t mask = ((1<<mod_order)-1);
|
||||||
int32_t* nr_mod_table32;
|
int32_t* nr_mod_table32;
|
||||||
int32_t* out32 = (int32_t*) out;
|
int32_t* out32 = (int32_t*) out;
|
||||||
uint8_t* in_bytes = (uint8_t*) in;
|
const uint8_t *in_bytes = (const uint8_t *)in;
|
||||||
uint64_t* in64 = (uint64_t*) in;
|
const uint64_t *in64 = (const uint64_t *)in;
|
||||||
int64_t* out64 = (int64_t*) out;
|
int64_t* out64 = (int64_t*) out;
|
||||||
uint32_t i=0;
|
uint32_t i=0;
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ extern const char nr_W_4l_4p[5][4][4];
|
|||||||
@param[out] out, complex valued modulated symbols
|
@param[out] out, complex valued modulated symbols
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void nr_modulation(uint32_t *in,
|
void nr_modulation(const uint32_t *in,
|
||||||
uint32_t length,
|
uint32_t length,
|
||||||
uint16_t mod_order,
|
uint16_t mod_order,
|
||||||
int16_t *out);
|
int16_t *out);
|
||||||
|
|||||||
@@ -103,16 +103,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
//------------------generate DMRS------------------//
|
//------------------generate DMRS------------------//
|
||||||
|
|
||||||
if(pusch_pdu->ul_dmrs_scrambling_id != gNB->pusch_gold_init[pusch_pdu->scid]) {
|
|
||||||
gNB->pusch_gold_init[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
|
|
||||||
nr_gold_pusch(gNB, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pusch_pdu->transform_precoding == transformPrecoder_disabled) {
|
if (pusch_pdu->transform_precoding == transformPrecoder_disabled) {
|
||||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||||
|
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||||
|
const uint32_t *gold = nr_gold_pusch(fp->N_RB_UL,
|
||||||
|
fp->symbols_per_slot,
|
||||||
|
gNB->gNB_config.cell_config.phy_cell_id.value,
|
||||||
|
pusch_pdu->scid,
|
||||||
|
Ns,
|
||||||
|
symbol);
|
||||||
nr_pusch_dmrs_rx(gNB,
|
nr_pusch_dmrs_rx(gNB,
|
||||||
Ns,
|
Ns,
|
||||||
gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol],
|
gold,
|
||||||
pilot,
|
pilot,
|
||||||
(1000 + p),
|
(1000 + p),
|
||||||
0,
|
0,
|
||||||
@@ -552,6 +554,12 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
|||||||
/*------------------------------------------------------------------------------------------------------- */
|
/*------------------------------------------------------------------------------------------------------- */
|
||||||
/* 1) Estimate common phase error per PTRS symbol */
|
/* 1) Estimate common phase error per PTRS symbol */
|
||||||
/*------------------------------------------------------------------------------------------------------- */
|
/*------------------------------------------------------------------------------------------------------- */
|
||||||
|
const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL,
|
||||||
|
frame_parms->symbols_per_slot,
|
||||||
|
gNB->gNB_config.cell_config.phy_cell_id.value,
|
||||||
|
rel15_ul->scid,
|
||||||
|
nr_tti_rx,
|
||||||
|
symbol);
|
||||||
nr_ptrs_cpe_estimation(*K_ptrs,
|
nr_ptrs_cpe_estimation(*K_ptrs,
|
||||||
*ptrsReOffset,
|
*ptrsReOffset,
|
||||||
*nb_rb,
|
*nb_rb,
|
||||||
@@ -560,7 +568,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
|||||||
symbol,
|
symbol,
|
||||||
frame_parms->ofdm_symbol_size,
|
frame_parms->ofdm_symbol_size,
|
||||||
(int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
|
(int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
|
||||||
gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol],
|
gold,
|
||||||
(int16_t *)&phase_per_symbol[symbol],
|
(int16_t *)&phase_per_symbol[symbol],
|
||||||
ptrs_re_symbol);
|
ptrs_re_symbol);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
|
|||||||
uint8_t numDmrsCdmGrpsNoData,
|
uint8_t numDmrsCdmGrpsNoData,
|
||||||
uint8_t dmrs_type);
|
uint8_t dmrs_type);
|
||||||
|
|
||||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
||||||
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start);
|
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start);
|
||||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
|
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p) {
|
|||||||
|
|
||||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pusch,
|
const uint32_t *nr_gold_pusch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned char lp,
|
unsigned char lp,
|
||||||
@@ -120,9 +120,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pdsch,
|
const unsigned int *nr_gold_pdsch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned char lp,
|
unsigned char lp,
|
||||||
@@ -170,9 +170,9 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pdcch,
|
const unsigned int *nr_gold_pdcch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned short nb_rb_coreset)
|
unsigned short nb_rb_coreset)
|
||||||
@@ -245,7 +245,7 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output
|
|||||||
\param length is number of RE in a OFDM symbol
|
\param length is number of RE in a OFDM symbol
|
||||||
\param *output pointer to all ptrs RE in a OFDM symbol
|
\param *output pointer to all ptrs RE in a OFDM symbol
|
||||||
*/
|
*/
|
||||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order)
|
void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order)
|
||||||
{
|
{
|
||||||
uint8_t idx, b_idx;
|
uint8_t idx, b_idx;
|
||||||
for (int i=0; i<length/mod_order; i++)
|
for (int i=0; i<length/mod_order; i++)
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
||||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.openairinterface.org/?page_id=698
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*-------------------------------------------------------------------------------
|
|
||||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
||||||
* contact@openairinterface.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nr_refsig.h"
|
|
||||||
|
|
||||||
void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
|
|
||||||
{
|
|
||||||
unsigned int x1 = 0, x2 = 0;
|
|
||||||
uint16_t Nid, i_ssb, i_ssb2;
|
|
||||||
unsigned char Lmax, l, n_hf, N_hf;
|
|
||||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
|
||||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
|
||||||
uint8_t reset;
|
|
||||||
|
|
||||||
Nid = cfg->cell_config.phy_cell_id.value;
|
|
||||||
|
|
||||||
Lmax = fp->Lmax;
|
|
||||||
N_hf = (Lmax == 4)? 2:1;
|
|
||||||
|
|
||||||
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
|
||||||
for (l = 0; l < Lmax ; l++) {
|
|
||||||
i_ssb = l & (Lmax-1);
|
|
||||||
i_ssb2 = i_ssb + (n_hf<<2);
|
|
||||||
|
|
||||||
reset = 1;
|
|
||||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
|
||||||
|
|
||||||
for (uint8_t n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
|
|
||||||
gNB->nr_gold_pbch_dmrs[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
|
|
||||||
{
|
|
||||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
|
||||||
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
|
||||||
int pdcch_dmrs_init_length = (((fp->N_RB_DL << 1) * 3) >> 5) + 1;
|
|
||||||
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
uint8_t reset = 1;
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + (Nid << 1));
|
|
||||||
uint32_t x2 = temp_x2 % (1U << 31);
|
|
||||||
LOG_D(PHY,"PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", slot, symb, Nid, x2);
|
|
||||||
for (uint32_t n = 0; n < pdcch_dmrs_init_length; n++) {
|
|
||||||
pdcch_dmrs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid)
|
|
||||||
{
|
|
||||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
|
||||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
|
||||||
int pdsch_dmrs_init_length = ((fp->N_RB_DL * 12) >> 5) + 1;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
uint8_t reset = 1;
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + ((Nid << 1) + nscid));
|
|
||||||
uint32_t x2 = temp_x2 % (1U << 31);
|
|
||||||
LOG_D(PHY,"PDSCH DMRS slot %d, symb %d, Nid %d, nscid %d, x2 %x\n",slot, symb, Nid, nscid, x2);
|
|
||||||
for (uint32_t n = 0; n < pdsch_dmrs_init_length; n++) {
|
|
||||||
pdsch_dmrs[slot][symb][nscid][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid)
|
|
||||||
{
|
|
||||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
|
||||||
int pusch_dmrs_init_length = ((fp->N_RB_UL * 12) >> 5) + 1;
|
|
||||||
for (int ns = 0; ns < fp->slots_per_frame; ns++) {
|
|
||||||
for (int l = 0; l < fp->symbols_per_slot; l++) {
|
|
||||||
int reset = 1;
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint64_t temp_x2 = ((1UL << 17) * (fp->symbols_per_slot * ns + l + 1) * ((nid << 1) + 1) + ((nid << 1) + nscid));
|
|
||||||
uint32_t x2 = temp_x2 % (1U << 31);
|
|
||||||
LOG_D(PHY,"DMRS slot %d, symb %d, nscid %d, nid %d, x2 %x\n", ns, l, nscid, nid, x2);
|
|
||||||
for (int n = 0; n < pusch_dmrs_init_length; n++) {
|
|
||||||
gNB->nr_gold_pusch_dmrs[nscid][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nr_init_prs(PHY_VARS_gNB* gNB)
|
|
||||||
{
|
|
||||||
unsigned int x1 = 0, x2 = 0;
|
|
||||||
uint16_t Nid;
|
|
||||||
|
|
||||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
|
||||||
gNB->nr_gold_prs = (uint32_t ****)malloc16(gNB->prs_vars.NumPRSResources*sizeof(uint32_t ***));
|
|
||||||
uint32_t ****prs = gNB->nr_gold_prs;
|
|
||||||
AssertFatal(prs!=NULL, "NR init: positioning reference signal malloc failed\n");
|
|
||||||
for (int rsc=0; rsc < gNB->prs_vars.NumPRSResources; rsc++) {
|
|
||||||
prs[rsc] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
|
||||||
AssertFatal(prs[rsc]!=NULL, "NR init: positioning reference signal for rsc %d - malloc failed\n", rsc);
|
|
||||||
|
|
||||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
|
||||||
prs[rsc][slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
|
||||||
AssertFatal(prs[rsc][slot]!=NULL, "NR init: positioning reference signal for slot %d - malloc failed\n", slot);
|
|
||||||
|
|
||||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
|
||||||
prs[rsc][slot][symb] = (uint32_t *)malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
|
||||||
AssertFatal(prs[rsc][slot][symb]!=NULL, "NR init: positioning reference signal for rsc %d slot %d symbol %d - malloc failed\n", rsc, slot, symb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t reset;
|
|
||||||
uint8_t slotNum, symNum, rsc_id;
|
|
||||||
|
|
||||||
for (rsc_id = 0; rsc_id < gNB->prs_vars.NumPRSResources; rsc_id++) {
|
|
||||||
Nid = gNB->prs_vars.prs_cfg[rsc_id].NPRSID; // seed value
|
|
||||||
LOG_I(PHY, "Initiaized NR-PRS sequence with PRS_ID %3d for resource %d\n", Nid, rsc_id);
|
|
||||||
for (slotNum = 0; slotNum < fp->slots_per_frame; slotNum++) {
|
|
||||||
for (symNum = 0; symNum < fp->symbols_per_slot ; symNum++) {
|
|
||||||
reset = 1;
|
|
||||||
// initial x2 for prs as ts138.211
|
|
||||||
uint32_t c_init1, c_init2, c_init3;
|
|
||||||
uint32_t pow22=1<<22;
|
|
||||||
uint32_t pow10=1<<10;
|
|
||||||
c_init1 = pow22*ceil(Nid/1024);
|
|
||||||
c_init2 = pow10*(slotNum+symNum+1)*(2*(Nid%1024)+1);
|
|
||||||
c_init3 = Nid%1024;
|
|
||||||
x2 = c_init1 + c_init2 + c_init3;
|
|
||||||
|
|
||||||
for (uint8_t n=0; n<NR_MAX_PRS_INIT_LENGTH_DWORD; n++) {
|
|
||||||
gNB->nr_gold_prs[rsc_id][slotNum][symNum][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
//printf("%d \n",gNB->nr_gold_prs[slotNum][symNum][n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,132 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "refsig_defs_ue.h"
|
#include "refsig_defs_ue.h"
|
||||||
|
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic()
|
||||||
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax)
|
|
||||||
{
|
|
||||||
unsigned int n = 0, x1 = 0, x2 = 0;
|
|
||||||
unsigned int i_ssb, i_ssb2;
|
|
||||||
unsigned char l, n_hf, N_hf;
|
|
||||||
uint8_t reset;
|
|
||||||
|
|
||||||
N_hf = (Lmax == 4)? 2:1;
|
|
||||||
|
|
||||||
for (n_hf = 0; n_hf < N_hf; n_hf++) {
|
|
||||||
|
|
||||||
for (l = 0; l < Lmax ; l++) {
|
|
||||||
i_ssb = l & (Lmax-1);
|
|
||||||
i_ssb2 = i_ssb + (n_hf<<2);
|
|
||||||
|
|
||||||
reset = 1;
|
|
||||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
|
||||||
|
|
||||||
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
|
|
||||||
nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
|
||||||
unsigned short nid)
|
|
||||||
{
|
|
||||||
int pdcch_dmrs_init_length = (((ue->frame_parms.N_RB_DL << 1) * 3) >> 5) + 1;
|
|
||||||
for (int ns = 0; ns < ue->frame_parms.slots_per_frame; ns++) {
|
|
||||||
for (int l = 0; l < ue->frame_parms.symbols_per_slot; l++) {
|
|
||||||
uint8_t reset = 1;
|
|
||||||
uint64_t x2tmp0 = ((ue->frame_parms.symbols_per_slot * ns + l + 1) * ((nid << 1) + 1));
|
|
||||||
x2tmp0 <<= 17;
|
|
||||||
x2tmp0 += (nid << 1);
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint32_t x2 = x2tmp0 % (1U << 31); //cinit
|
|
||||||
LOG_D(PHY,"PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", ns, l, nid, x2);
|
|
||||||
for (int n = 0; n < pdcch_dmrs_init_length; n++) {
|
|
||||||
ue->nr_gold_pdcch[0][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
|
||||||
int nscid,
|
|
||||||
uint32_t nid)
|
|
||||||
{
|
|
||||||
int pdsch_dmrs_init_length = ((ue->frame_parms.N_RB_DL * 12) >> 5) + 1;
|
|
||||||
for (int ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
|
|
||||||
for (int l=0; l<ue->frame_parms.symbols_per_slot; l++) {
|
|
||||||
uint8_t reset = 1;
|
|
||||||
uint64_t x2tmp0 = ((ue->frame_parms.symbols_per_slot * ns + l + 1) * ((nid << 1) + 1)) << 17;
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint32_t x2 = (x2tmp0 + (nid << 1) + nscid) % (1U << 31); //cinit
|
|
||||||
LOG_D(PHY,"UE DMRS slot %d, symb %d, nscid %d, x2 %x\n", ns, l, nscid, x2);
|
|
||||||
for (int n = 0; n < pdsch_dmrs_init_length; n++) {
|
|
||||||
ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid)
|
|
||||||
{
|
|
||||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
|
||||||
uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
|
|
||||||
int pusch_dmrs_init_length = ((fp->N_RB_UL * 12) >> 5) + 1;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
int reset = 1;
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
uint64_t t_x2 = ((1UL << 17) * (fp->symbols_per_slot*slot + symb + 1) * ((N_n_scid << 1) + 1) + ((N_n_scid << 1) + n_scid));
|
|
||||||
uint32_t x2 = t_x2 % (1U << 31);
|
|
||||||
LOG_D(PHY,"DMRS slot %d, symb %d, N_n_scid %d, n_scid %d, x2 %x\n", slot, symb, N_n_scid, n_scid, x2);
|
|
||||||
for (int n = 0; n < pusch_dmrs_init_length; n++) {
|
|
||||||
pusch_dmrs[slot][symb][n_scid][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_nr_gold_prs(PHY_VARS_NR_UE* ue)
|
|
||||||
{
|
|
||||||
unsigned int x1 = 0, x2 = 0;
|
|
||||||
uint16_t Nid;
|
|
||||||
|
|
||||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
|
||||||
uint8_t reset;
|
|
||||||
uint8_t slotNum, symNum, gnb, rsc;
|
|
||||||
|
|
||||||
for(gnb = 0; gnb < ue->prs_active_gNBs; gnb++) {
|
|
||||||
for(rsc = 0; rsc < ue->prs_vars[gnb]->NumPRSResources; rsc++) {
|
|
||||||
Nid = ue->prs_vars[gnb]->prs_resource[rsc].prs_cfg.NPRSID; // seed value
|
|
||||||
LOG_I(PHY,"Initialised NR-PRS sequence with PRS_ID %3d for resource %d\n",Nid, rsc);
|
|
||||||
for (slotNum = 0; slotNum < fp->slots_per_frame; slotNum++) {
|
|
||||||
for (symNum = 0; symNum < fp->symbols_per_slot ; symNum++) {
|
|
||||||
reset = 1;
|
|
||||||
// initial x2 for prs as ts138.211
|
|
||||||
uint32_t c_init1, c_init2, c_init3;
|
|
||||||
uint32_t pow22=1<<22;
|
|
||||||
uint32_t pow10=1<<10;
|
|
||||||
c_init1 = pow22*ceil(Nid/1024);
|
|
||||||
c_init2 = pow10*(slotNum+symNum+1)*(2*(Nid%1024)+1);
|
|
||||||
c_init3 = Nid%1024;
|
|
||||||
x2 = c_init1 + c_init2 + c_init3;
|
|
||||||
|
|
||||||
for (uint8_t n=0; n<NR_MAX_PRS_INIT_LENGTH_DWORD; n++) {
|
|
||||||
ue->nr_gold_prs[gnb][rsc][slotNum][symNum][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
//printf("%d \n",gNB->nr_gold_prs[slotNum][symNum][n]);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // for rsc
|
|
||||||
} // for gnb
|
|
||||||
}
|
|
||||||
|
|
||||||
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
|
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,35 +25,13 @@
|
|||||||
#define __NR_REFSIG__H__
|
#define __NR_REFSIG__H__
|
||||||
|
|
||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||||
#include "PHY/sse_intrin.h"
|
|
||||||
|
|
||||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
|
|
||||||
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
|
||||||
*/
|
|
||||||
void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
|
|
||||||
|
|
||||||
/*
|
|
||||||
This function generates NR Gold Sequence(ts 138.211) for the PRS.
|
|
||||||
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
|
||||||
*/
|
|
||||||
void nr_init_prs(PHY_VARS_gNB* gNB);
|
|
||||||
|
|
||||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
|
|
||||||
@param PHY_VARS_gNB* gNB structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
|
||||||
@param Nid is used for the initialization of x2, Physical cell Id by default or upper layer configured pdcch_scrambling_ID
|
|
||||||
*/
|
|
||||||
void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
|
|
||||||
void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
|
|
||||||
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
|
||||||
|
|
||||||
void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
|
|
||||||
|
|
||||||
int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p);
|
int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p);
|
||||||
|
|
||||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pusch,
|
const uint32_t *nr_gold_pusch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned char lp,
|
unsigned char lp,
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Definitions for NR Reference signals */
|
||||||
|
|
||||||
|
#ifndef __NR_REFSIG_COMMON_H__
|
||||||
|
#define __NR_REFSIG_COMMON_H__
|
||||||
|
|
||||||
|
uint32_t *gold_cache(uint32_t key, int length);
|
||||||
|
uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb);
|
||||||
|
uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l);
|
||||||
|
uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol);
|
||||||
|
uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol);
|
||||||
|
uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid);
|
||||||
|
uint32_t *nr_gold_prs(int nid, int slot, int symbol);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -191,7 +191,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
|
|||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
uint16_t ofdm_symbol_size,
|
uint16_t ofdm_symbol_size,
|
||||||
int16_t *rxF_comp,
|
int16_t *rxF_comp,
|
||||||
uint32_t *gold_seq,
|
const uint32_t *gold_seq,
|
||||||
int16_t *error_est,
|
int16_t *error_est,
|
||||||
int32_t *ptrs_sc)
|
int32_t *ptrs_sc)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
|
|||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
uint16_t ofdm_symbol_size,
|
uint16_t ofdm_symbol_size,
|
||||||
int16_t *rxF_comp,
|
int16_t *rxF_comp,
|
||||||
uint32_t *gold_seq,
|
const uint32_t *gold_seq,
|
||||||
int16_t *error_est,
|
int16_t *error_est,
|
||||||
int32_t *ptrs_sc);
|
int32_t *ptrs_sc);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* 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 "nr_refsig.h"
|
||||||
|
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic()
|
||||||
|
|
||||||
|
#define REFRESH_RATE (1000 * 100)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int key;
|
||||||
|
int length;
|
||||||
|
int usage;
|
||||||
|
} gold_cache_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t *table;
|
||||||
|
uint32_t tblSz;
|
||||||
|
int calls;
|
||||||
|
int iterate;
|
||||||
|
} gold_cache_table_t;
|
||||||
|
static const int roundedHeaderSz = (((sizeof(gold_cache_t) + 63) / 64) * 64) / sizeof(uint32_t);
|
||||||
|
static const int grain = 64 / sizeof(uint32_t);
|
||||||
|
|
||||||
|
// Allocate, also reorder to have the most frequent first, so the cache search is optimized
|
||||||
|
static void refresh_table(gold_cache_table_t *t, int sizeIncrease)
|
||||||
|
{
|
||||||
|
uint32_t *old = t->table;
|
||||||
|
uint oldSz = t->tblSz;
|
||||||
|
if (t->tblSz == 0)
|
||||||
|
t->tblSz = PAGE_SIZE / sizeof(*t->table);
|
||||||
|
if (sizeIncrease)
|
||||||
|
t->tblSz += max(sizeIncrease, PAGE_SIZE / sizeof(*t->table));
|
||||||
|
int ret = posix_memalign((void **)&t->table, 64, t->tblSz * sizeof(*t->table));
|
||||||
|
AssertFatal(ret == 0, "No more memory");
|
||||||
|
LOG_D(PHY,
|
||||||
|
"re-organize gold sequence table to %lu pages of memory calls since last reorder: %d, search rate: %f\n",
|
||||||
|
t->tblSz * sizeof(*t->table) / PAGE_SIZE,
|
||||||
|
t->calls,
|
||||||
|
t->calls ? t->iterate / (float)t->calls : 0.0);
|
||||||
|
int maxUsage;
|
||||||
|
uint32_t *currentTmp = t->table;
|
||||||
|
do {
|
||||||
|
maxUsage = 0;
|
||||||
|
gold_cache_t *entryToCopy = NULL;
|
||||||
|
for (uint32_t *searchmax = old; searchmax < old + oldSz; searchmax += roundedHeaderSz) {
|
||||||
|
gold_cache_t *tbl = (gold_cache_t *)searchmax;
|
||||||
|
if (!tbl->length)
|
||||||
|
break;
|
||||||
|
if (tbl->usage > maxUsage) {
|
||||||
|
maxUsage = tbl->usage;
|
||||||
|
entryToCopy = tbl;
|
||||||
|
}
|
||||||
|
searchmax += tbl->length;
|
||||||
|
}
|
||||||
|
if (maxUsage) {
|
||||||
|
memcpy(currentTmp, entryToCopy, (roundedHeaderSz + entryToCopy->length) * sizeof(*t->table));
|
||||||
|
currentTmp += roundedHeaderSz + entryToCopy->length;
|
||||||
|
entryToCopy->usage = 0;
|
||||||
|
}
|
||||||
|
} while (maxUsage);
|
||||||
|
const uint usedSz = currentTmp - t->table;
|
||||||
|
memset(t->table + usedSz, 0, (t->tblSz - usedSz) * sizeof(*t->table));
|
||||||
|
free(old);
|
||||||
|
t->calls = 0;
|
||||||
|
t->iterate = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_key_t gold_table_key;
|
||||||
|
static pthread_once_t gold_key_once = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
|
static void delete_table(void *ptr)
|
||||||
|
{
|
||||||
|
gold_cache_table_t *table = (gold_cache_table_t *)ptr;
|
||||||
|
if (table->table)
|
||||||
|
free(table->table);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void make_table_key()
|
||||||
|
{
|
||||||
|
(void)pthread_key_create(&gold_table_key, delete_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *gold_cache(uint32_t key, int length)
|
||||||
|
{
|
||||||
|
(void)pthread_once(&gold_key_once, make_table_key);
|
||||||
|
gold_cache_table_t *tableCache;
|
||||||
|
if ((tableCache = pthread_getspecific(gold_table_key)) == NULL) {
|
||||||
|
tableCache = calloc(1, sizeof(gold_cache_table_t));
|
||||||
|
(void)pthread_setspecific(gold_table_key, tableCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// align for AVX512
|
||||||
|
length = ((length + grain - 1) / grain) * grain;
|
||||||
|
tableCache->calls++;
|
||||||
|
|
||||||
|
// periodic refresh
|
||||||
|
if (tableCache->calls > REFRESH_RATE)
|
||||||
|
refresh_table(tableCache, 0);
|
||||||
|
|
||||||
|
uint32_t *ptr = tableCache->table;
|
||||||
|
// check if already cached
|
||||||
|
for (; ptr < tableCache->table + tableCache->tblSz; ptr += roundedHeaderSz) {
|
||||||
|
gold_cache_t *tbl = (gold_cache_t *)ptr;
|
||||||
|
tableCache->iterate++;
|
||||||
|
if (tbl->length >= length && tbl->key == key) {
|
||||||
|
tbl->usage++;
|
||||||
|
return ptr + roundedHeaderSz;
|
||||||
|
}
|
||||||
|
if (tbl->key == key) {
|
||||||
|
// We use a longer sequence, same key
|
||||||
|
// let's delete the shorter and force reorganize
|
||||||
|
tbl->usage = 0;
|
||||||
|
tableCache->calls += REFRESH_RATE;
|
||||||
|
}
|
||||||
|
if (!tbl->length)
|
||||||
|
break;
|
||||||
|
ptr += tbl->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not enough space in the table
|
||||||
|
if (!ptr || ptr > tableCache->table + tableCache->tblSz - (2 * roundedHeaderSz + length))
|
||||||
|
refresh_table(tableCache, 2 * roundedHeaderSz + length);
|
||||||
|
|
||||||
|
// We will add a new entry
|
||||||
|
uint32_t *firstFree;
|
||||||
|
int size = 0;
|
||||||
|
for (firstFree = tableCache->table; firstFree < tableCache->table + tableCache->tblSz; firstFree += roundedHeaderSz) {
|
||||||
|
gold_cache_t *tbl = (gold_cache_t *)firstFree;
|
||||||
|
if (!tbl->length)
|
||||||
|
break;
|
||||||
|
firstFree += tbl->length;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
if (!tableCache->calls)
|
||||||
|
LOG_D(PHY, "Number of entries (after reorganization) in gold cache: %d\n", size);
|
||||||
|
|
||||||
|
gold_cache_t *new = (gold_cache_t *)firstFree;
|
||||||
|
*new = (gold_cache_t){.key = key, .length = length, .usage = 1};
|
||||||
|
unsigned int x1 = 0, x2 = key;
|
||||||
|
uint32_t *sequence = firstFree + roundedHeaderSz;
|
||||||
|
*sequence++ = lte_gold_generic(&x1, &x2, 1);
|
||||||
|
for (int n = 1; n < length; n++)
|
||||||
|
*sequence++ = lte_gold_generic(&x1, &x2, 0);
|
||||||
|
LOG_D(PHY, "created a gold sequence, start %d; len %d\n", key, length);
|
||||||
|
return firstFree + roundedHeaderSz;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int l)
|
||||||
|
{
|
||||||
|
int i_ssb = l & (Lmax - 1);
|
||||||
|
int i_ssb2 = i_ssb + (n_hf << 2);
|
||||||
|
uint32_t x2 = (1 << 11) * (i_ssb2 + 1) * ((Nid >> 2) + 1) + (1 << 6) * (i_ssb2 + 1) + (Nid & 3);
|
||||||
|
return gold_cache(x2, NR_PBCH_DMRS_LENGTH_DWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short nid, int ns, int l)
|
||||||
|
{
|
||||||
|
int pdcch_dmrs_init_length = (((N_RB_DL << 1) * 3) >> 5) + 1;
|
||||||
|
uint64_t x2tmp0 = (((uint64_t)symbols_per_slot * ns + l + 1) * ((nid << 1) + 1));
|
||||||
|
x2tmp0 <<= 17;
|
||||||
|
x2tmp0 += (nid << 1);
|
||||||
|
uint32_t x2 = x2tmp0 % (1U << 31); // cinit
|
||||||
|
LOG_D(PHY, "PDCCH DMRS slot %d, symb %d, Nid %d, x2 %x\n", ns, l, nid, x2);
|
||||||
|
return gold_cache(x2, pdcch_dmrs_init_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol)
|
||||||
|
{
|
||||||
|
int pdsch_dmrs_init_length = ((N_RB_DL * 24) >> 5) + 1;
|
||||||
|
uint64_t x2tmp0 = (((uint64_t)symbols_per_slot * slot + symbol + 1) * (((uint64_t)nid << 1) + 1)) << 17;
|
||||||
|
uint32_t x2 = (x2tmp0 + (nid << 1) + nscid) % (1U << 31); // cinit
|
||||||
|
LOG_D(PHY, "UE DMRS slot %d, symb %d, nscid %d, x2 %x\n", slot, symbol, nscid, x2);
|
||||||
|
return gold_cache(x2, pdsch_dmrs_init_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol)
|
||||||
|
{
|
||||||
|
return nr_gold_pdsch(N_RB_UL, symbols_per_slot, Nid, nscid, slot, symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid)
|
||||||
|
{
|
||||||
|
int csi_dmrs_init_length = ((N_RB_DL << 4) >> 5) + 1;
|
||||||
|
uint64_t temp_x2 = (1ULL << 10) * ((uint64_t)symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + Nid;
|
||||||
|
uint32_t x2 = temp_x2 % (1U << 31);
|
||||||
|
return gold_cache(x2, csi_dmrs_init_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t *nr_gold_prs(int Nid, int slotNum, int symNum)
|
||||||
|
{
|
||||||
|
LOG_D(PHY, "Initialised NR-PRS sequence for PCI %d\n", Nid);
|
||||||
|
// initial x2 for prs as ts138.211
|
||||||
|
uint32_t pow22 = 1 << 22;
|
||||||
|
uint32_t pow10 = 1 << 10;
|
||||||
|
uint32_t c_init1 = pow22 * ceil(Nid / 1024);
|
||||||
|
uint32_t c_init2 = pow10 * (slotNum + symNum + 1) * (2 * (Nid % 1024) + 1);
|
||||||
|
uint32_t c_init3 = Nid % 1024;
|
||||||
|
uint32_t x2 = c_init1 + c_init2 + c_init3;
|
||||||
|
return gold_cache(x2, NR_MAX_PRS_INIT_LENGTH_DWORD);
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
#define __NR_REFSIG_DEFS__H__
|
#define __NR_REFSIG_DEFS__H__
|
||||||
|
|
||||||
#include "PHY/defs_nr_UE.h"
|
#include "PHY/defs_nr_UE.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "nr_refsig_common.h"
|
||||||
|
|
||||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
|
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
|
||||||
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
||||||
@@ -35,37 +35,22 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output,
|
|||||||
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
|
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
|
||||||
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
|
||||||
*/
|
*/
|
||||||
int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pdcch,
|
const unsigned int *nr_gold_pdcch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned short nb_rb_corset);
|
unsigned short nb_rb_corset);
|
||||||
|
|
||||||
int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue,
|
||||||
unsigned int Ns,
|
unsigned int Ns,
|
||||||
unsigned int *nr_gold_pdsch,
|
const unsigned int *nr_gold_pdsch,
|
||||||
c16_t *output,
|
c16_t *output,
|
||||||
unsigned short p,
|
unsigned short p,
|
||||||
unsigned char lp,
|
unsigned char lp,
|
||||||
unsigned short nb_pdsch_rb,
|
unsigned short nb_pdsch_rb,
|
||||||
uint8_t config_type);
|
uint8_t config_type);
|
||||||
|
|
||||||
void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax);
|
|
||||||
|
|
||||||
void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
|
||||||
unsigned short n_idDMRS);
|
|
||||||
|
|
||||||
void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
|
||||||
int nscid,
|
|
||||||
uint32_t nid);
|
|
||||||
|
|
||||||
void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
|
||||||
uint16_t N_n_scid,
|
|
||||||
uint8_t n_scid);
|
|
||||||
|
|
||||||
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
|
|
||||||
void init_nr_gold_prs(PHY_VARS_NR_UE* ue);
|
|
||||||
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
|
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
|
||||||
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
|
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
|
||||||
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling);
|
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling);
|
||||||
|
|||||||
@@ -24,23 +24,6 @@
|
|||||||
|
|
||||||
//#define NR_CSIRS_DEBUG
|
//#define NR_CSIRS_DEBUG
|
||||||
|
|
||||||
|
|
||||||
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid)
|
|
||||||
{
|
|
||||||
uint32_t x1 = 0;
|
|
||||||
int csi_dmrs_init_length = ((fp->N_RB_DL << 4) >> 5) + 1;
|
|
||||||
for (int slot = 0; slot < fp->slots_per_frame; slot++) {
|
|
||||||
for (int symb = 0; symb < fp->symbols_per_slot; symb++) {
|
|
||||||
uint8_t reset = 1;
|
|
||||||
uint32_t x2 = ((1 << 10) * (fp->symbols_per_slot * slot + symb + 1) * ((Nid << 1) + 1) + Nid);
|
|
||||||
for (uint32_t n = 0; n < csi_dmrs_init_length; n++) {
|
|
||||||
csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||||
int32_t **dataF,
|
int32_t **dataF,
|
||||||
const int16_t amp,
|
const int16_t amp,
|
||||||
@@ -74,7 +57,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||||
uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot];
|
|
||||||
//*8(max allocation per RB)*2(QPSK))
|
//*8(max allocation per RB)*2(QPSK))
|
||||||
int csi_rs_length = frame_parms->N_RB_DL << 4;
|
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)));
|
int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
|
||||||
@@ -82,19 +64,11 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
uint32_t beta = amp;
|
uint32_t beta = amp;
|
||||||
nr_csi_info->csi_rs_generated_signal_bits = log2_approx(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");
|
AssertFatal(b != 0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||||
|
|
||||||
// if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
|
|
||||||
if (csi_params->scramb_id != nr_csi_info->csi_gold_init) {
|
|
||||||
nr_csi_info->csi_gold_init = csi_params->scramb_id;
|
|
||||||
nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
int size, ports, kprime, lprime;
|
int size, ports, kprime, lprime;
|
||||||
int j[16], k_n[6], koverline[16], loverline[16];
|
int j[16], k_n[6], koverline[16], loverline[16];
|
||||||
int found = 0;
|
int found = 0;
|
||||||
int fi = 0;
|
int fi = 0;
|
||||||
|
|
||||||
// implementation of table 7.4.1.5.3-1 of 38.211
|
// implementation of table 7.4.1.5.3-1 of 38.211
|
||||||
// lprime and kprime are the max value of l' and k'
|
// lprime and kprime are the max value of l' and k'
|
||||||
switch (csi_params->row) {
|
switch (csi_params->row) {
|
||||||
@@ -581,14 +555,25 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
|||||||
|
|
||||||
for (int lp = 0; lp <= lprime; lp++) {
|
for (int lp = 0; lp <= lprime; lp++) {
|
||||||
int symb = csi_params->symb_l0;
|
int symb = csi_params->symb_l0;
|
||||||
nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
const uint32_t *gold =
|
||||||
if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16))
|
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||||
nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||||
if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) {
|
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;
|
symb = csi_params->symb_l1;
|
||||||
nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
const uint32_t *gold =
|
||||||
if ((csi_params->row == 13) || (csi_params->row == 16))
|
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||||
nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,29 +41,13 @@
|
|||||||
//#define DEBUG_DCI
|
//#define DEBUG_DCI
|
||||||
//#define DEBUG_CHANNEL_CODING
|
//#define DEBUG_CHANNEL_CODING
|
||||||
|
|
||||||
void nr_pdcch_scrambling(uint32_t *in,
|
static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint32_t scrambling_RNTI, uint32_t *out)
|
||||||
uint32_t size,
|
{
|
||||||
uint32_t Nid,
|
int roundedSz = ((size + 31) / 32);
|
||||||
uint32_t scrambling_RNTI,
|
uint32_t *seq = gold_cache((scrambling_RNTI << 16) + Nid, roundedSz);
|
||||||
uint32_t *out) {
|
LOG_D(NR_PHY_DCI, "PDCCH scrambling_RNTI %x \n", scrambling_RNTI);
|
||||||
uint8_t reset;
|
for (int i = 0; i < roundedSz; i++)
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
out[i] = in[i] ^ seq[i];
|
||||||
reset = 1;
|
|
||||||
x2 = (scrambling_RNTI<<16) + Nid;
|
|
||||||
LOG_D(NR_PHY_DCI, "PDCCH Scrambling x2 %x : scrambling_RNTI %x \n", x2, scrambling_RNTI);
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
if ((i&0x1f)==0) {
|
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
in++;
|
|
||||||
out++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(*out) ^= ((((*in)>>(i&0x1f))&1) ^ ((s>>(i&0x1f))&1))<<(i&0x1f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||||
@@ -95,13 +79,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
* in time: by its first slot and its first symbol*/
|
* 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];
|
const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
|
||||||
|
|
||||||
if(dci_pdu->ScramblingId != gNB->pdcch_gold_init) {
|
|
||||||
gNB->pdcch_gold_init = dci_pdu->ScramblingId;
|
|
||||||
nr_init_pdcch_dmrs(gNB, dci_pdu->ScramblingId);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t **gold_pdcch_dmrs = gNB->nr_gold_pdcch_dmrs[slot];
|
|
||||||
|
|
||||||
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
|
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
|
||||||
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
||||||
dci_idx = 0;
|
dci_idx = 0;
|
||||||
@@ -131,8 +108,9 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
/// DMRS QPSK modulation
|
/// 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_pdcch_dmrs[symb], 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
|
#ifdef DEBUG_PDCCH_DMRS
|
||||||
if(dci_pdu->RNTI!=0xFFFF) {
|
if(dci_pdu->RNTI!=0xFFFF) {
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
|||||||
int16_t amp,
|
int16_t amp,
|
||||||
NR_DL_FRAME_PARMS *frame_parms);
|
NR_DL_FRAME_PARMS *frame_parms);
|
||||||
|
|
||||||
void nr_pdcch_scrambling(uint32_t *in,
|
|
||||||
uint32_t size,
|
|
||||||
uint32_t Nid,
|
|
||||||
uint32_t n_RNTI,
|
|
||||||
uint32_t *out);
|
|
||||||
|
|
||||||
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
|
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
|
||||||
|
|
||||||
void nr_fill_dci(PHY_VARS_gNB *gNB,
|
void nr_fill_dci(PHY_VARS_gNB *gNB,
|
||||||
|
|||||||
@@ -76,12 +76,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
|||||||
rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize);
|
rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize);
|
||||||
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
|
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
|
||||||
|
|
||||||
if(rel15->dlDmrsScramblingId != gNB->pdsch_gold_init[rel15->SCID]) {
|
|
||||||
gNB->pdsch_gold_init[rel15->SCID] = rel15->dlDmrsScramblingId;
|
|
||||||
nr_init_pdsch_dmrs(gNB, rel15->SCID, rel15->dlDmrsScramblingId);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
|
|
||||||
const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100
|
const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100
|
||||||
const int xOverhead = 0;
|
const int xOverhead = 0;
|
||||||
const int nb_re =
|
const int nb_re =
|
||||||
@@ -251,9 +245,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
|||||||
l_prime = 0;
|
l_prime = 0;
|
||||||
}
|
}
|
||||||
/// DMRS QPSK modulation
|
/// DMRS QPSK modulation
|
||||||
nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID],
|
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||||
n_dmrs * DMRS_MOD_ORDER,
|
const uint32_t *gold =
|
||||||
DMRS_MOD_ORDER,
|
nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol);
|
||||||
|
nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER,
|
||||||
(int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
|
(int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH
|
#ifdef DEBUG_DLSCH
|
||||||
@@ -276,7 +271,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
|||||||
if(ptrs_symbol) {
|
if(ptrs_symbol) {
|
||||||
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
||||||
LOG_D(PHY, "Doing ptrs modulation for symbol %d, n_ptrs %d\n", l_symbol, n_ptrs);
|
LOG_D(PHY, "Doing ptrs modulation for symbol %d, n_ptrs %d\n", l_symbol, n_ptrs);
|
||||||
nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID], n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||||
|
const uint32_t *gold =
|
||||||
|
nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol);
|
||||||
|
nr_modulation(gold, n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint16_t k = start_sc;
|
uint16_t k = start_sc;
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "executables/softmodem-common.h"
|
#include "executables/softmodem-common.h"
|
||||||
|
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||||
|
|
||||||
//#define DEBUG_PBCH
|
//#define DEBUG_PBCH
|
||||||
//#define DEBUG_PBCH_ENCODING
|
//#define DEBUG_PBCH_ENCODING
|
||||||
@@ -148,22 +148,17 @@ static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
|||||||
uint16_t M,
|
uint16_t M,
|
||||||
uint16_t length,
|
uint16_t length,
|
||||||
uint8_t encoded,
|
uint8_t encoded,
|
||||||
uint32_t unscrambling_mask) {
|
uint32_t unscrambling_mask)
|
||||||
uint8_t reset, offset;
|
{
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
|
||||||
uint32_t *pbch_e = pbch->pbch_e;
|
uint32_t *pbch_e = pbch->pbch_e;
|
||||||
reset = 1;
|
|
||||||
// x1 is set in lte_gold_generic
|
// x1 is set in lte_gold_generic
|
||||||
x2 = Nid;
|
|
||||||
|
|
||||||
|
const int len = (nushift * M + 31) / 32 + (length + 31) / 32;
|
||||||
|
uint32_t *s = gold_cache(Nid, len);
|
||||||
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
||||||
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
|
int goldIdx = (nushift * M + 31) / 32 - 1;
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scrambling is now done with offset (nushift*M)%32
|
// Scrambling is now done with offset (nushift*M)%32
|
||||||
offset = (nushift*M)&0x1f;
|
uint8_t offset = (nushift * M) & 0x1f;
|
||||||
#ifdef DEBUG_PBCH_ENCODING
|
#ifdef DEBUG_PBCH_ENCODING
|
||||||
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
|
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
|
||||||
#endif
|
#endif
|
||||||
@@ -178,29 +173,22 @@ static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
|||||||
if ((unscrambling_mask>>i)&1)
|
if ((unscrambling_mask>>i)&1)
|
||||||
pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<<i;
|
pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<<i;
|
||||||
else {
|
else {
|
||||||
if (((k+offset)&0x1f)==0) {
|
if (((k + offset) & 0x1f) == 0)
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
goldIdx++;
|
||||||
reset = 0;
|
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved >> i) & 1) ^ ((s[goldIdx] >> ((k + offset) & 0x1f)) & 1)) << i;
|
||||||
}
|
|
||||||
|
|
||||||
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
|
||||||
k++; /// k increase only when payload bit is not special bit
|
k++; /// k increase only when payload bit is not special bit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/// 2nd Scrambling
|
/// 2nd Scrambling
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
if (((i+offset)&0x1f)==0) {
|
if (((i + offset) & 0x1f) == 0)
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
goldIdx++;
|
||||||
reset = 0;
|
pbch_e[i >> 5] ^= (((s[goldIdx] >> ((i + offset) & 0x1f)) & 1) << (i & 0x1f));
|
||||||
}
|
|
||||||
|
|
||||||
pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void nr_init_pbch_interleaver(uint8_t *interleaver) {
|
void nr_init_pbch_interleaver(uint8_t *interleaver) {
|
||||||
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
|
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
|
||||||
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
|
#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||||
//#define DEBUG_PRS_MOD
|
//#define DEBUG_PRS_MOD
|
||||||
//#define DEBUG_PRS_MAP
|
//#define DEBUG_PRS_MAP
|
||||||
|
|
||||||
extern short nr_qpsk_mod_table[8];
|
extern short nr_qpsk_mod_table[8];
|
||||||
|
|
||||||
int nr_generate_prs(uint32_t **nr_gold_prs,
|
int nr_generate_prs(int slot,
|
||||||
c16_t *txdataF,
|
c16_t *txdataF,
|
||||||
int16_t amp,
|
int16_t amp,
|
||||||
prs_config_t *prs_cfg,
|
prs_config_t *prs_cfg,
|
||||||
@@ -42,8 +42,9 @@ int nr_generate_prs(uint32_t **nr_gold_prs,
|
|||||||
k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset;
|
k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset;
|
||||||
|
|
||||||
// QPSK modulation
|
// QPSK modulation
|
||||||
|
uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l);
|
||||||
for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) {
|
for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) {
|
||||||
idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3);
|
idx = (((gold[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
|
||||||
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||||
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||||
|
|
||||||
|
|||||||
@@ -31,45 +31,32 @@ void nr_codeword_scrambling(uint8_t *in,
|
|||||||
uint32_t n_RNTI,
|
uint32_t n_RNTI,
|
||||||
uint32_t* out)
|
uint32_t* out)
|
||||||
{
|
{
|
||||||
uint32_t x1;
|
const int roundedSz = (size + 31) / 32;
|
||||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||||
uint32_t s = lte_gold_generic(&x1, &x2, 1);
|
for (int i = 0; i < roundedSz; i++) {
|
||||||
for (int i = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++) {
|
|
||||||
simde__m256i c = ((simde__m256i*)in)[i];
|
simde__m256i c = ((simde__m256i*)in)[i];
|
||||||
uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c, 7));
|
uint32_t in32 = simde_mm256_movemask_epi8(simde_mm256_slli_epi16(c, 7));
|
||||||
out[i] = (in32 ^ s);
|
out[i] = in32 ^ seq[i];
|
||||||
DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i]));
|
DEBUG_SCRAMBLING(LOG_D(PHY, "in[%d] %x => %x\n", i, in32, out[i]));
|
||||||
s = lte_gold_generic(&x1, &x2, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
|
void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
|
||||||
{
|
{
|
||||||
uint32_t x1;
|
const int roundedSz = (size + 31) / 32;
|
||||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||||
uint32_t s = 0;
|
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
|
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
|
||||||
uint8_t *s8=(uint8_t *)&s;
|
|
||||||
simde__m128i *llr128 = (simde__m128i*)llr;
|
simde__m128i *llr128 = (simde__m128i*)llr;
|
||||||
s = lte_gold_generic(&x1, &x2, 1);
|
for (int i = 0, j = 0; i < roundedSz; i++, j += 4) {
|
||||||
|
uint8_t *s8 = (uint8_t *)(seq + i);
|
||||||
for (int i = 0, j = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++, j += 4) {
|
|
||||||
llr128[j] = simde_mm_mullo_epi16(llr128[j],byte2m128i[s8[0]]);
|
llr128[j] = simde_mm_mullo_epi16(llr128[j],byte2m128i[s8[0]]);
|
||||||
llr128[j+1] = simde_mm_mullo_epi16(llr128[j+1],byte2m128i[s8[1]]);
|
llr128[j+1] = simde_mm_mullo_epi16(llr128[j+1],byte2m128i[s8[1]]);
|
||||||
llr128[j+2] = simde_mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]);
|
llr128[j+2] = simde_mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]);
|
||||||
llr128[j+3] = simde_mm_mullo_epi16(llr128[j+3],byte2m128i[s8[3]]);
|
llr128[j + 3] = simde_mm_mullo_epi16(llr128[j + 3], byte2m128i[s8[3]]);
|
||||||
s = lte_gold_generic(&x1, &x2, 0);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uint8_t reset = 1;
|
|
||||||
|
|
||||||
for (uint32_t i=0; i<size; i++) {
|
for (uint32_t i=0; i<size; i++) {
|
||||||
if ((i&0x1f)==0) {
|
if (seq[i / 32] & (1U << (i % 32)))
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
if (((s>>(i&0x1f))&1)==1)
|
|
||||||
llr[i] = -llr[i];
|
llr[i] = -llr[i];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -77,18 +64,14 @@ void nr_codeword_unscrambling(int16_t* llr, uint32_t size, uint8_t q, uint32_t N
|
|||||||
|
|
||||||
void nr_codeword_unscrambling_init(int16_t *s2, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
|
void nr_codeword_unscrambling_init(int16_t *s2, uint32_t size, uint8_t q, uint32_t Nid, uint32_t n_RNTI)
|
||||||
{
|
{
|
||||||
uint32_t x1;
|
const int roundedSz = (size + 31) / 32;
|
||||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||||
simde__m128i *s128=(simde__m128i *)s2;
|
simde__m128i *s128=(simde__m128i *)s2;
|
||||||
|
for (int i = 0; i < roundedSz; i++) {
|
||||||
uint32_t s = lte_gold_generic(&x1, &x2, 1);
|
uint8_t *s8 = (uint8_t *)(seq + i);
|
||||||
uint8_t *s8=(uint8_t *)&s;
|
|
||||||
|
|
||||||
for (int i = 0; i < (size +31) >> 5; i++) {
|
|
||||||
*s128++ = byte2m128i[s8[0]];
|
*s128++ = byte2m128i[s8[0]];
|
||||||
*s128++ = byte2m128i[s8[1]];
|
*s128++ = byte2m128i[s8[1]];
|
||||||
*s128++ = byte2m128i[s8[2]];
|
*s128++ = byte2m128i[s8[2]];
|
||||||
*s128++ = byte2m128i[s8[3]];
|
*s128++ = byte2m128i[s8[3]];
|
||||||
s = lte_gold_generic(&x1, &x2, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti);
|
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti);
|
||||||
|
|
||||||
int nr_generate_prs(uint32_t **nr_gold_prs,
|
int nr_generate_prs(int slot,
|
||||||
c16_t *txdataF,
|
c16_t *txdataF,
|
||||||
int16_t amp,
|
int16_t amp,
|
||||||
prs_config_t *prs_cfg,
|
prs_config_t *prs_cfg,
|
||||||
|
|||||||
@@ -63,11 +63,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
|||||||
#endif
|
#endif
|
||||||
uint8_t f_ss=0,f_gh=0;
|
uint8_t f_ss=0,f_gh=0;
|
||||||
*u=0;
|
*u=0;
|
||||||
*v=0;
|
*v = 0;
|
||||||
uint32_t c_init = 0;
|
|
||||||
uint32_t x1,s; // TS 38.211 Subclause 5.2.1
|
|
||||||
int l = 32, minShift = ((2*nr_slot_tx+n_hop)<<3);
|
|
||||||
int tmpShift =0;
|
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t [nr_group_sequence_hopping] calculating u,v -> ");
|
printf("\t\t [nr_group_sequence_hopping] calculating u,v -> ");
|
||||||
#endif
|
#endif
|
||||||
@@ -77,41 +73,39 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled'
|
if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled'
|
||||||
c_init = floor(n_id/30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211
|
uint32_t c_init = floor(n_id / 30); // we initialize c_init to calculate u,v according to 6.3.2.2.1 of 38.211
|
||||||
s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
|
int l = 32, minShift = (2 * nr_slot_tx + n_hop) << 3;
|
||||||
|
uint32_t *seq = gold_cache(c_init, (minShift + 31) / 32 + 8); // TS 38.211 Subclause 5.2.1
|
||||||
|
int goldIdx = 0;
|
||||||
for (int m=0; m<8; m++) {
|
for (int m=0; m<8; m++) {
|
||||||
while(minShift >= l) {
|
while(minShift >= l) {
|
||||||
s = lte_gold_generic(&x1, &c_init, 0);
|
goldIdx++;
|
||||||
l = l+32;
|
l = l+32;
|
||||||
}
|
}
|
||||||
|
AssertFatal(goldIdx < 8 + (minShift + 31) / 32, "");
|
||||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32;
|
||||||
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1)));
|
f_gh = f_gh + ((1 << m) * ((uint8_t)((seq[goldIdx] >> tmpShift) & 1)));
|
||||||
minShift ++;
|
minShift ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
f_gh = f_gh%30;
|
f_gh = f_gh%30;
|
||||||
f_ss = n_id%30;
|
f_ss = n_id % 30;
|
||||||
/* for (int m=0; m<8; m++){
|
|
||||||
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_slot_tx+n_hop)+m))&1))); // Not sure we have to use nr_slot_tx FIXME!!!
|
|
||||||
}
|
|
||||||
f_gh = f_gh%30;
|
|
||||||
f_ss = n_id%30;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled'
|
if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled'
|
||||||
c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v
|
uint32_t c_init = (1 << 5) * floor(n_id / 30) + (n_id % 30); // we initialize c_init to calculate u,v
|
||||||
s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
|
int goldIdx = 0;
|
||||||
f_ss = n_id%30;
|
f_ss = n_id%30;
|
||||||
l = 32, minShift = (2*nr_slot_tx+n_hop);
|
int l = 32, minShift = (2 * nr_slot_tx + n_hop);
|
||||||
|
|
||||||
while(minShift >= l) {
|
while(minShift >= l) {
|
||||||
s = lte_gold_generic(&x1, &c_init, 0);
|
goldIdx++;
|
||||||
l = l+32;
|
l = l+32;
|
||||||
}
|
}
|
||||||
|
// TS 38.211 Subclause 5.2.1
|
||||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
uint32_t *seq = gold_cache(c_init, goldIdx + 1);
|
||||||
*v = (uint8_t)((s>>tmpShift)&1);
|
int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32;
|
||||||
|
*v = (uint8_t)((seq[goldIdx] >> tmpShift) & 1);
|
||||||
// *v = (uint8_t)((s>>(2*nr_slot_tx+n_hop))&1); // Not sure we have to use nr_slot_tx FIXME!!!
|
// *v = (uint8_t)((s>>(2*nr_slot_tx+n_hop))&1); // Not sure we have to use nr_slot_tx FIXME!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,28 +133,27 @@ double nr_cyclic_shift_hopping(uint32_t n_id,
|
|||||||
double alpha = 0.5235987756;
|
double alpha = 0.5235987756;
|
||||||
uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs
|
uint32_t c_init = n_id; // we initialize c_init again to calculate n_cs
|
||||||
|
|
||||||
uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
|
|
||||||
uint8_t n_cs=0;
|
uint8_t n_cs=0;
|
||||||
int l = 32, minShift = (14*8*nr_slot_tx )+ 8*(lnormal+lprime);
|
int l = 32, minShift = (14 * 8 * nr_slot_tx) + 8 * (lnormal + lprime);
|
||||||
int tmpShift =0;
|
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init);
|
printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init);
|
||||||
#endif
|
#endif
|
||||||
|
uint32_t *seq = gold_cache(c_init, 8 + (minShift + 31) / 32); // TS 38.211 Subclause 5.2.1
|
||||||
|
int goldIdx = 0;
|
||||||
for (int m=0; m<8; m++) {
|
for (int m=0; m<8; m++) {
|
||||||
while(minShift >= l) {
|
while(minShift >= l) {
|
||||||
s = lte_gold_generic(&x1, &c_init, 0);
|
goldIdx++;
|
||||||
l = l+32;
|
l = l+32;
|
||||||
}
|
}
|
||||||
|
AssertFatal(goldIdx < 8 + (minShift + 31) / 32, "");
|
||||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32;
|
||||||
minShift ++;
|
minShift ++;
|
||||||
n_cs = n_cs+((1<<m)*((uint8_t)((s>>tmpShift)&1)));
|
n_cs += (1 << m) * (uint8_t)((seq[goldIdx] >> tmpShift) & 1);
|
||||||
// calculating n_cs (Not sure we have to use nr_slot_tx FIXME!!!)
|
// calculating n_cs (Not sure we have to use nr_slot_tx FIXME!!!)
|
||||||
// n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_slot_tx) + 8*(lnormal+lprime) + m))&1)));
|
// n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_slot_tx) + 8*(lnormal+lprime) + m))&1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha = (alpha * (double)((m0+mcs+n_cs)%12));
|
alpha = alpha * (double)((m0 + mcs + n_cs) % 12);
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("n_cs=%d -> %lf\n",n_cs,alpha);
|
printf("n_cs=%d -> %lf\n",n_cs,alpha);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1145,26 +1145,21 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
// first compute DMRS component
|
// first compute DMRS component
|
||||||
|
|
||||||
uint32_t x1 = 0, x2 = 0, sGold = 0;
|
|
||||||
uint8_t *sGold8 = (uint8_t *)&sGold;
|
|
||||||
const int scramble = pucch_pdu->dmrs_scrambling_id * 2;
|
const int scramble = pucch_pdu->dmrs_scrambling_id * 2;
|
||||||
// fixme: when MR2754 will be merged, use the gold sequence cache instead of regenerate each time
|
// fixme: when MR2754 will be merged, use the gold sequence cache instead of regenerate each time
|
||||||
x2 = ((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1))
|
uint32_t x2 =
|
||||||
|
((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1))
|
||||||
+ scramble)
|
+ scramble)
|
||||||
% (1U << 31); // c_init calculation according to TS38.211 subclause
|
% (1U << 31); // c_init calculation according to TS38.211 subclause
|
||||||
#ifdef DEBUG_NR_PUCCH_RX
|
#ifdef DEBUG_NR_PUCCH_RX
|
||||||
printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n",
|
printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n",
|
||||||
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id);
|
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id);
|
||||||
#endif
|
#endif
|
||||||
int reset = 1;
|
uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2);
|
||||||
for (int i=0; i<=(pucch_pdu->prb_start>>2); i++) {
|
for (int group = 0, goldIdx = pucch_pdu->prb_start / 4; group < ngroup; group++) {
|
||||||
sGold = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int group = 0; group < ngroup; group++) {
|
|
||||||
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
||||||
// non-coherent combining across groups
|
// non-coherent combining across groups
|
||||||
|
uint8_t *sGold8 = (uint8_t *)&sGold[goldIdx];
|
||||||
simde__m64 dmrs_re = byte2m64_re[sGold8[(group & 1) << 1]];
|
simde__m64 dmrs_re = byte2m64_re[sGold8[(group & 1) << 1]];
|
||||||
int16_t *dmrs_re16 = (int16_t *)&dmrs_re;
|
int16_t *dmrs_re16 = (int16_t *)&dmrs_re;
|
||||||
simde__m64 dmrs_im = byte2m64_im[sGold8[(group & 1) << 1]];
|
simde__m64 dmrs_im = byte2m64_im[sGold8[(group & 1) << 1]];
|
||||||
@@ -1237,22 +1232,22 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
|||||||
} //aa
|
} //aa
|
||||||
|
|
||||||
if ((group & 1) == 1)
|
if ((group & 1) == 1)
|
||||||
sGold = lte_gold_generic(&x1, &x2, 0);
|
goldIdx++;
|
||||||
} // group
|
} // group
|
||||||
} // symb
|
} // symb
|
||||||
|
|
||||||
uint32_t x1, x2, sGold = 0;
|
|
||||||
// unscrambling
|
// unscrambling
|
||||||
x2 = ((pucch_pdu->rnti)<<15)+pucch_pdu->data_scrambling_id;
|
uint32_t x2 = ((pucch_pdu->rnti) << 15) + pucch_pdu->data_scrambling_id;
|
||||||
sGold = lte_gold_generic(&x1, &x2, 1);
|
|
||||||
uint8_t *sGold8 = (uint8_t *)&sGold;
|
|
||||||
#ifdef DEBUG_NR_PUCCH_RX
|
#ifdef DEBUG_NR_PUCCH_RX
|
||||||
printf("x2 %x\n", x2);
|
printf("x2 %x\n", x2);
|
||||||
#endif
|
#endif
|
||||||
|
uint32_t *sGold = gold_cache(x2, pucch_pdu->nr_of_symbols * prb_size_ext / 2);
|
||||||
|
int goldIdx = 0;
|
||||||
for (int symb=0;symb<pucch_pdu->nr_of_symbols;symb++) {
|
for (int symb=0;symb<pucch_pdu->nr_of_symbols;symb++) {
|
||||||
simde__m64 c_re[4], c_im[4];
|
simde__m64 c_re[4], c_im[4];
|
||||||
int re_off=0;
|
int re_off=0;
|
||||||
for (int prb=0;prb<prb_size_ext;prb+=2,re_off+=16) {
|
for (int prb=0;prb<prb_size_ext;prb+=2,re_off+=16) {
|
||||||
|
uint8_t *sGold8 = (uint8_t *)(sGold + goldIdx);
|
||||||
for (int z = 0; z < 4; z++) {
|
for (int z = 0; z < 4; z++) {
|
||||||
c_re[z] = byte2m64_re[sGold8[z]];
|
c_re[z] = byte2m64_re[sGold8[z]];
|
||||||
c_im[z] = byte2m64_im[sGold8[z]];
|
c_im[z] = byte2m64_im[sGold8[z]];
|
||||||
@@ -1332,7 +1327,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
|||||||
r_re_ext[aa][symb][re_off+15],r_im_ext[aa][symb][re_off+15]);
|
r_re_ext[aa][symb][re_off+15],r_im_ext[aa][symb][re_off+15]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
sGold = lte_gold_generic(&x1, &x2, 0);
|
goldIdx++;
|
||||||
#ifdef DEBUG_NR_PUCCH_RX
|
#ifdef DEBUG_NR_PUCCH_RX
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
|||||||
memset(chF_interpol,0,sizeof(chF_interpol));
|
memset(chF_interpol,0,sizeof(chF_interpol));
|
||||||
memset(chT_interpol,0,sizeof(chF_interpol));
|
memset(chT_interpol,0,sizeof(chF_interpol));
|
||||||
|
|
||||||
int slot_prs = (proc->nr_slot_rx - rep_num*prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame)%frame_params->slots_per_frame;
|
int slot_prs =
|
||||||
uint32_t **nr_gold_prs = ue->nr_gold_prs[gNB_id][rsc_id][slot_prs];
|
(proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame;
|
||||||
|
|
||||||
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
|
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
|
||||||
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
|
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
|
||||||
@@ -113,6 +113,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
|||||||
int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE;
|
int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE;
|
||||||
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
|
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
|
||||||
{
|
{
|
||||||
|
uint32_t *gold_prs = nr_gold_prs(ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg.NPRSID, slot_prs, l);
|
||||||
int symInd = l-prs_cfg->SymbolStart;
|
int symInd = l-prs_cfg->SymbolStart;
|
||||||
if (prs_cfg->CombSize == 2) {
|
if (prs_cfg->CombSize == 2) {
|
||||||
k_prime = k_prime_table[0][symInd];
|
k_prime = k_prime_table[0][symInd];
|
||||||
@@ -135,7 +136,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
|||||||
AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB");
|
AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB");
|
||||||
for (int m = 0; m < num_pilots; m++)
|
for (int m = 0; m < num_pilots; m++)
|
||||||
{
|
{
|
||||||
idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3);
|
idx = (((gold_prs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
|
||||||
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||||
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||||
}
|
}
|
||||||
@@ -644,7 +645,6 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
|
|||||||
|
|
||||||
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
||||||
const sl_nr_ue_phy_params_t *sl_phy_params,
|
const sl_nr_ue_phy_params_t *sl_phy_params,
|
||||||
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
|
||||||
int estimateSz,
|
int estimateSz,
|
||||||
struct complex16 dl_ch_estimates[][estimateSz],
|
struct complex16 dl_ch_estimates[][estimateSz],
|
||||||
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
||||||
@@ -679,7 +679,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
|||||||
|
|
||||||
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
|
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
|
||||||
|
|
||||||
gold_seq = nr_gold_pbch[n_hf][ssb_index];
|
gold_seq = nr_gold_pbch(fp->Lmax, Nid, n_hf, ssb_index);
|
||||||
lastsymbol = 2;
|
lastsymbol = 2;
|
||||||
num_rbs = 20;
|
num_rbs = 20;
|
||||||
}
|
}
|
||||||
@@ -843,9 +843,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
|
c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
|
||||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||||
{
|
{
|
||||||
|
int slot = proc->nr_slot_rx;
|
||||||
int Ns = proc->nr_slot_rx;
|
|
||||||
int gNB_id = proc->gNB_id;
|
|
||||||
unsigned char aarx;
|
unsigned char aarx;
|
||||||
unsigned short k;
|
unsigned short k;
|
||||||
unsigned int pilot_cnt;
|
unsigned int pilot_cnt;
|
||||||
@@ -869,8 +867,13 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
|
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
|
||||||
|
|
||||||
#ifdef DEBUG_PDCCH
|
#ifdef DEBUG_PDCCH
|
||||||
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n",
|
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
|
||||||
gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol);
|
gNB_id,
|
||||||
|
ch_offset,
|
||||||
|
ue->frame_parms.ofdm_symbol_size,
|
||||||
|
ue->frame_parms.Ncp,
|
||||||
|
slot,
|
||||||
|
symbol);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CH_INTERP
|
#if CH_INTERP
|
||||||
@@ -880,19 +883,14 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id;
|
unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id;
|
||||||
// checking if re-initialization of scrambling IDs is needed (should be done here but scrambling ID for PDCCH is not taken from RRC)
|
|
||||||
if (scrambling_id != ue->scramblingID_pdcch){
|
|
||||||
ue->scramblingID_pdcch = scrambling_id;
|
|
||||||
nr_gold_pdcch(ue,ue->scramblingID_pdcch);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dmrs_ref = 0;
|
int dmrs_ref = 0;
|
||||||
if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
||||||
dmrs_ref = BWPStart;
|
dmrs_ref = BWPStart;
|
||||||
// generate pilot
|
// generate pilot
|
||||||
int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
|
int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
|
||||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||||
nr_pdcch_dmrs_rx(ue, Ns, ue->nr_gold_pdcch[gNB_id][Ns][symbol], (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref));
|
const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol);
|
||||||
|
nr_pdcch_dmrs_rx(ue, slot, gold, (c16_t *)pilot, 2000, (nb_rb_coreset + dmrs_ref));
|
||||||
|
|
||||||
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||||
|
|
||||||
@@ -1422,19 +1420,22 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
c16_t rxdataF[][rxdataFsize],
|
c16_t rxdataF[][rxdataFsize],
|
||||||
uint32_t *nvar)
|
uint32_t *nvar)
|
||||||
{
|
{
|
||||||
int gNB_id = proc->gNB_id;
|
// int gNB_id = proc->gNB_id;
|
||||||
int Ns = proc->nr_slot_rx;
|
int slot = proc->nr_slot_rx;
|
||||||
const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol;
|
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||||
const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
|
const int ch_offset = fp->ofdm_symbol_size * symbol;
|
||||||
|
const int symbol_offset = fp->ofdm_symbol_size * symbol;
|
||||||
|
|
||||||
#ifdef DEBUG_PDSCH
|
#ifdef DEBUG_PDSCH
|
||||||
printf("PDSCH Channel Estimation : gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, bwp_start_subcarrier=%d symbol %d\n",
|
printf(
|
||||||
|
"PDSCH Channel Estimation : gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, bwp_start_subcarrier=%d "
|
||||||
|
"symbol %d\n",
|
||||||
gNB_id,
|
gNB_id,
|
||||||
ch_offset,
|
ch_offset,
|
||||||
symbol_offset,
|
symbol_offset,
|
||||||
ue->frame_parms.ofdm_symbol_size,
|
fp->ofdm_symbol_size,
|
||||||
ue->frame_parms.Ncp,
|
fp->Ncp,
|
||||||
Ns,
|
slot,
|
||||||
bwp_start_subcarrier,
|
bwp_start_subcarrier,
|
||||||
symbol);
|
symbol);
|
||||||
#endif
|
#endif
|
||||||
@@ -1442,20 +1443,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
// generate pilot for gNB port number 1000+p
|
// generate pilot for gNB port number 1000+p
|
||||||
int8_t delta = get_delta(p, config_type);
|
int8_t delta = get_delta(p, config_type);
|
||||||
|
|
||||||
// checking if re-initialization of scrambling IDs is needed
|
|
||||||
if (scrambling_id != ue->scramblingID_dlsch[nscid]) {
|
|
||||||
ue->scramblingID_dlsch[nscid] = scrambling_id;
|
|
||||||
nr_gold_pdsch(ue, nscid, scrambling_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
c16_t pilot[3280] __attribute__((aligned(16)));
|
c16_t pilot[3280] __attribute__((aligned(16)));
|
||||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||||
nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][nscid], pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
|
const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol);
|
||||||
|
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type);
|
||||||
|
|
||||||
delay_t delay = {0};
|
delay_t delay = {0};
|
||||||
|
|
||||||
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
|
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||||
|
|
||||||
#ifdef DEBUG_PDSCH
|
#ifdef DEBUG_PDSCH
|
||||||
printf("\n============================================\n");
|
printf("\n============================================\n");
|
||||||
printf("==== Tx port %i, Rx antenna %i, Symbol %i ====\n", p, aarx, symbol);
|
printf("==== Tx port %i, Rx antenna %i, Symbol %i ====\n", p, aarx, symbol);
|
||||||
@@ -1463,8 +1458,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
c16_t *rxF = &rxdataF[aarx][symbol_offset + delta];
|
c16_t *rxF = &rxdataF[aarx][symbol_offset + delta];
|
||||||
c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset];
|
c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
|
||||||
memset(dl_ch, 0, sizeof(*dl_ch) * ue->frame_parms.ofdm_symbol_size);
|
memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size);
|
||||||
|
|
||||||
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
|
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
|
||||||
NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms,
|
NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms,
|
||||||
@@ -1478,7 +1473,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
nvar);
|
nvar);
|
||||||
|
|
||||||
} else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0) {
|
} else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0) {
|
||||||
NFAPI_NR_DMRS_TYPE2_linear_interp(&ue->frame_parms,
|
NFAPI_NR_DMRS_TYPE2_linear_interp(fp,
|
||||||
rxF,
|
rxF,
|
||||||
&pilot[4 * rb_offset],
|
&pilot[4 * rb_offset],
|
||||||
dl_ch,
|
dl_ch,
|
||||||
@@ -1490,24 +1485,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
nvar);
|
nvar);
|
||||||
|
|
||||||
} else if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
} else if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
||||||
NFAPI_NR_DMRS_TYPE1_average_prb(&ue->frame_parms,
|
NFAPI_NR_DMRS_TYPE1_average_prb(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch);
|
||||||
rxF,
|
|
||||||
&pilot[6 * rb_offset],
|
|
||||||
dl_ch,
|
|
||||||
bwp_start_subcarrier,
|
|
||||||
nb_rb_pdsch);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
NFAPI_NR_DMRS_TYPE2_average_prb(&ue->frame_parms,
|
NFAPI_NR_DMRS_TYPE2_average_prb(fp, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch);
|
||||||
rxF,
|
|
||||||
&pilot[4 * rb_offset],
|
|
||||||
dl_ch,
|
|
||||||
bwp_start_subcarrier,
|
|
||||||
nb_rb_pdsch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_PDSCH
|
#ifdef DEBUG_PDSCH
|
||||||
dl_ch = (c16_t *)&dl_ch_estimates[nl * ue->frame_parms.nb_antennas_rx + aarx][ch_offset];
|
dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
|
||||||
for (uint16_t idxP = 0; idxP < ceil((float)nb_rb_pdsch * 12 / 8); idxP++) {
|
for (uint16_t idxP = 0; idxP < ceil((float)nb_rb_pdsch * 12 / 8); idxP++) {
|
||||||
for (uint8_t idxI = 0; idxI < 8; idxI++) {
|
for (uint8_t idxI = 0; idxI < 8; idxI++) {
|
||||||
printf("%4d\t%4d\t", dl_ch[idxP * 8 + idxI].r, dl_ch[idxP * 8 + idxI].i);
|
printf("%4d\t%4d\t", dl_ch[idxP * 8 + idxI].r, dl_ch[idxP * 8 + idxI].i);
|
||||||
@@ -1638,6 +1623,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
|||||||
/*------------------------------------------------------------------------------------------------------- */
|
/*------------------------------------------------------------------------------------------------------- */
|
||||||
/* 1) Estimate common phase error per PTRS symbol */
|
/* 1) Estimate common phase error per PTRS symbol */
|
||||||
/*------------------------------------------------------------------------------------------------------- */
|
/*------------------------------------------------------------------------------------------------------- */
|
||||||
|
const uint32_t *gold =
|
||||||
|
nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, frame_parms->Nid_cell, nscid, nr_slot_rx, symbol);
|
||||||
nr_ptrs_cpe_estimation(*K_ptrs,
|
nr_ptrs_cpe_estimation(*K_ptrs,
|
||||||
*ptrsReOffset,
|
*ptrsReOffset,
|
||||||
*nb_rb,
|
*nb_rb,
|
||||||
@@ -1646,8 +1633,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
|||||||
symbol,
|
symbol,
|
||||||
frame_parms->ofdm_symbol_size,
|
frame_parms->ofdm_symbol_size,
|
||||||
(int16_t *)(rxdataF_comp[0][aarx] + symbol * nb_re_pdsch),
|
(int16_t *)(rxdataF_comp[0][aarx] + symbol * nb_re_pdsch),
|
||||||
ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][nscid],
|
gold,
|
||||||
(int16_t*)&phase_per_symbol[symbol],
|
(int16_t *)&phase_per_symbol[symbol],
|
||||||
&ptrs_re_symbol[symbol]);
|
&ptrs_re_symbol[symbol]);
|
||||||
}
|
}
|
||||||
}// HARQ 0
|
}// HARQ 0
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
|
|||||||
|
|
||||||
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
|
||||||
const sl_nr_ue_phy_params_t *sl_phy_params,
|
const sl_nr_ue_phy_params_t *sl_phy_params,
|
||||||
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
|
||||||
int estimateSz,
|
int estimateSz,
|
||||||
struct complex16 dl_ch_estimates[][estimateSz],
|
struct complex16 dl_ch_estimates[][estimateSz],
|
||||||
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
|
||||||
@@ -115,6 +114,12 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
uint32_t pdsch_est_size,
|
uint32_t pdsch_est_size,
|
||||||
int32_t dl_ch_estimates[][pdsch_est_size]);
|
int32_t dl_ch_estimates[][pdsch_est_size]);
|
||||||
|
|
||||||
|
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||||
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
|
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
|
int symbol_offset,
|
||||||
|
int ssb_start_subcarrier);
|
||||||
|
|
||||||
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||||
uint8_t gNB_index,
|
uint8_t gNB_index,
|
||||||
const UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
@@ -146,7 +151,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
|
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
|
||||||
|
|
||||||
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||||
NR_DL_FRAME_PARMS *fp,
|
NR_DL_FRAME_PARMS *fp,
|
||||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
bool use_SSS);
|
bool use_SSS);
|
||||||
|
|||||||
@@ -170,6 +170,50 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function calculates:
|
||||||
|
// - SS reference signal received digital power in dB/RE
|
||||||
|
int nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp,
|
||||||
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
|
const c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
|
int symbol_offset,
|
||||||
|
int ssb_start_subcarrier)
|
||||||
|
{
|
||||||
|
int k_start = 56;
|
||||||
|
int k_end = 183;
|
||||||
|
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
|
||||||
|
|
||||||
|
uint8_t l_sss = (symbol_offset + 2) % fp->symbols_per_slot;
|
||||||
|
|
||||||
|
uint32_t rsrp = 0;
|
||||||
|
|
||||||
|
LOG_D(PHY, "In %s: l_sss %d ssb_offset %d\n", __FUNCTION__, l_sss, ssb_offset);
|
||||||
|
int nb_re = 0;
|
||||||
|
|
||||||
|
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||||
|
int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][l_sss * fp->ofdm_symbol_size];
|
||||||
|
|
||||||
|
for(int k = k_start; k < k_end; k++){
|
||||||
|
int re = (ssb_offset + k) % fp->ofdm_symbol_size;
|
||||||
|
|
||||||
|
#ifdef DEBUG_MEAS_UE
|
||||||
|
LOG_I(PHY, "In %s rxF_sss[%d] %d %d\n", __FUNCTION__, re, rxF_sss[re * 2], rxF_sss[re * 2 + 1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rsrp += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1]));
|
||||||
|
nb_re++;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rsrp /= nb_re;
|
||||||
|
|
||||||
|
LOG_D(PHY, "In %s: RSRP/nb_re: %d nb_re :%d\n", __FUNCTION__, rsrp, nb_re);
|
||||||
|
|
||||||
|
int rsrp_db_per_re = 10 * log10(rsrp);
|
||||||
|
|
||||||
|
return rsrp_db_per_re;
|
||||||
|
}
|
||||||
|
|
||||||
// This function implements:
|
// This function implements:
|
||||||
// - SS reference signal received power (SS-RSRP) as per clause 5.1.1 of 3GPP TS 38.215 version 16.3.0 Release 16
|
// - SS reference signal received power (SS-RSRP) as per clause 5.1.1 of 3GPP TS 38.215 version 16.3.0 Release 16
|
||||||
// - no Layer 3 filtering implemented (no filterCoefficient provided from RRC)
|
// - no Layer 3 filtering implemented (no filterCoefficient provided from RRC)
|
||||||
@@ -183,52 +227,27 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
const UE_nr_rxtx_proc_t *proc,
|
const UE_nr_rxtx_proc_t *proc,
|
||||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||||
{
|
{
|
||||||
int k_start = 56;
|
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||||
int k_end = 183;
|
|
||||||
int slot = proc->nr_slot_rx;
|
|
||||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
|
||||||
int symbol_offset = nr_get_ssb_start_symbol(&ue->frame_parms,ssb_index);
|
|
||||||
|
|
||||||
if (ue->frame_parms.half_frame_bit)
|
int symbol_offset = nr_get_ssb_start_symbol(fp, ssb_index);
|
||||||
symbol_offset += (ue->frame_parms.slots_per_frame>>1)*ue->frame_parms.symbols_per_slot;
|
|
||||||
|
|
||||||
uint8_t l_sss = (symbol_offset + 2) % ue->frame_parms.symbols_per_slot;
|
if (fp->half_frame_bit)
|
||||||
|
symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot;
|
||||||
|
|
||||||
uint32_t rsrp = 0;
|
int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
|
||||||
|
|
||||||
LOG_D(PHY, "In %s: [UE %d] slot %d l_sss %d ssb_offset %d\n", __FUNCTION__, ue->Mod_id, slot, l_sss, ssb_offset);
|
openair0_config_t *cfg0 = &openair0_cfg[0];
|
||||||
int nb_re = 0;
|
|
||||||
|
|
||||||
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
|
ue->measurements.ssb_rsrp_dBm[ssb_index] = rsrp_db_per_re + 30 - SQ15_SQUARED_NORM_FACTOR_DB
|
||||||
|
- ((int)cfg0->rx_gain[0] - (int)cfg0->rx_gain_offset[0])
|
||||||
|
- dB_fixed(fp->ofdm_symbol_size);
|
||||||
|
|
||||||
int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][l_sss*ue->frame_parms.ofdm_symbol_size];
|
LOG_D(PHY,
|
||||||
|
"[UE %d] ssb %d SS-RSRP: %d dBm/RE (%d dB/RE)\n",
|
||||||
for(int k = k_start; k < k_end; k++){
|
|
||||||
|
|
||||||
int re = (ssb_offset + k) % ue->frame_parms.ofdm_symbol_size;
|
|
||||||
|
|
||||||
#ifdef DEBUG_MEAS_UE
|
|
||||||
LOG_I(PHY, "In %s rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rsrp += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1]));
|
|
||||||
nb_re++;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rsrp /= nb_re;
|
|
||||||
ue->measurements.ssb_rsrp_dBm[ssb_index] = 10*log10(rsrp) +
|
|
||||||
30 - SQ15_SQUARED_NORM_FACTOR_DB -
|
|
||||||
((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) -
|
|
||||||
dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
|
||||||
|
|
||||||
LOG_D(PHY, "In %s: [UE %d] ssb %d SS-RSRP: %d dBm/RE (%d)\n",
|
|
||||||
__FUNCTION__,
|
|
||||||
ue->Mod_id,
|
ue->Mod_id,
|
||||||
ssb_index,
|
ssb_index,
|
||||||
ue->measurements.ssb_rsrp_dBm[ssb_index],
|
ue->measurements.ssb_rsrp_dBm[ssb_index],
|
||||||
rsrp);
|
rsrp_db_per_re);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function computes the received noise power
|
// This function computes the received noise power
|
||||||
@@ -310,8 +329,14 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
|||||||
- ((int)rx_gain - (int)rx_gain_offset));
|
- ((int)rx_gain - (int)rx_gain_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// PSBCH RSRP calculations according to 38.215 section 5.1.22
|
// This function implements:
|
||||||
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
// - PSBCH RSRP calculations according to 38.215 section 5.1.22 Release 16
|
||||||
|
// - PSBCH DMRS used for calculations
|
||||||
|
// - TBD: SSS REs for calculation.
|
||||||
|
// Measurement units:
|
||||||
|
// - RSRP: W (dBW)
|
||||||
|
// returns RXgain to be adjusted based on target rx power (50db) - received digital power in db/RE
|
||||||
|
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||||
NR_DL_FRAME_PARMS *fp,
|
NR_DL_FRAME_PARMS *fp,
|
||||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||||
bool use_SSS)
|
bool use_SSS)
|
||||||
@@ -351,9 +376,14 @@ void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
|||||||
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0])
|
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0])
|
||||||
- dB_fixed(fp->ofdm_symbol_size);
|
- dB_fixed(fp->ofdm_symbol_size);
|
||||||
|
|
||||||
|
int adjust_rxgain = TARGET_RX_POWER - psbch_rx->rsrp_dB_per_RE;
|
||||||
|
|
||||||
LOG_D(PHY,
|
LOG_D(PHY,
|
||||||
"PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n",
|
"PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE, adjust_rxgain:%d dB\n",
|
||||||
num_re,
|
num_re,
|
||||||
psbch_rx->rsrp_dB_per_RE,
|
psbch_rx->rsrp_dB_per_RE,
|
||||||
psbch_rx->rsrp_dBm_per_RE);
|
psbch_rx->rsrp_dBm_per_RE,
|
||||||
|
adjust_rxgain);
|
||||||
|
|
||||||
|
return adjust_rxgain;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "common/utils/nr/nr_common.h"
|
#include "common/utils/nr/nr_common.h"
|
||||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||||
|
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||||
|
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
@@ -655,25 +656,13 @@ static void nr_pdcch_unscrambling(c16_t *e_rx,
|
|||||||
uint16_t pdcch_DMRS_scrambling_id,
|
uint16_t pdcch_DMRS_scrambling_id,
|
||||||
int16_t *z2)
|
int16_t *z2)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
uint8_t reset;
|
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
|
||||||
uint16_t n_id; //{0,1,...,65535}
|
|
||||||
uint32_t rnti = (uint32_t) scrambling_RNTI;
|
uint32_t rnti = (uint32_t) scrambling_RNTI;
|
||||||
reset = 1;
|
uint16_t n_id = pdcch_DMRS_scrambling_id;
|
||||||
// x1 is set in first call to lte_gold_generic
|
uint32_t *seq = gold_cache(((rnti << 16) + n_id) % (1U << 31), length / 32); // this is c_init in 38.211 v15.1.0 Section 7.3.2.3
|
||||||
n_id = pdcch_DMRS_scrambling_id;
|
LOG_D(NR_PHY_DCI, "PDCCH Unscrambling: scrambling_RNTI %x\n", rnti);
|
||||||
x2 = ((rnti << 16) + n_id) % (1U << 31); // this is c_init in 38.211 v15.1.0 Section 7.3.2.3
|
|
||||||
|
|
||||||
LOG_D(NR_PHY_DCI, "PDCCH Unscrambling x2 %x : scrambling_RNTI %x\n", x2, rnti);
|
|
||||||
int16_t *ptr = &e_rx[0].r;
|
int16_t *ptr = &e_rx[0].r;
|
||||||
for (i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
if ((i & 0x1f) == 0) {
|
if (seq[i / 32] & (1UL << (i % 32)))
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((s >> (i % 32)) & 1) == 1)
|
|
||||||
z2[i] = -ptr[i];
|
z2[i] = -ptr[i];
|
||||||
else
|
else
|
||||||
z2[i] = ptr[i];
|
z2[i] = ptr[i];
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
|||||||
int *ssb_index,
|
int *ssb_index,
|
||||||
int *symbol_offset,
|
int *symbol_offset,
|
||||||
fapiPbch_t *result,
|
fapiPbch_t *result,
|
||||||
const uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
|
|
||||||
const c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
const c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
|
||||||
{
|
{
|
||||||
const int N_L = (frame_parms->Lmax == 4) ? 4 : 8;
|
const int N_L = (frame_parms->Lmax == 4) ? 4 : 8;
|
||||||
@@ -90,7 +89,7 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
|||||||
i - pbch_initial_symbol,
|
i - pbch_initial_symbol,
|
||||||
Nid_cell,
|
Nid_cell,
|
||||||
ssb_start_subcarrier,
|
ssb_start_subcarrier,
|
||||||
nr_gold_pbch_ref[hf][l],
|
nr_gold_pbch(frame_parms->Lmax, Nid_cell, hf, l),
|
||||||
rxdataF);
|
rxdataF);
|
||||||
csum(cumul, cumul, meas);
|
csum(cumul, cumul, meas);
|
||||||
}
|
}
|
||||||
@@ -110,7 +109,6 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
|||||||
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
|
||||||
nr_pbch_channel_estimation(frame_parms,
|
nr_pbch_channel_estimation(frame_parms,
|
||||||
NULL,
|
NULL,
|
||||||
nr_gold_pbch_ref,
|
|
||||||
estimateSz,
|
estimateSz,
|
||||||
dl_ch_estimates,
|
dl_ch_estimates,
|
||||||
dl_ch_estimates_time,
|
dl_ch_estimates_time,
|
||||||
@@ -277,9 +275,7 @@ void nr_scan_ssb(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
ssbInfo->freqOffset = freq_offset_pss + freq_offset_sss;
|
ssbInfo->freqOffset = freq_offset_pss + freq_offset_sss;
|
||||||
|
|
||||||
uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
|
||||||
if (ssbInfo->syncRes.cell_detected) { // we got sss channel
|
if (ssbInfo->syncRes.cell_detected) { // we got sss channel
|
||||||
nr_gold_pbch(nr_gold_pbch_ref, ssbInfo->nidCell, fp->Lmax);
|
|
||||||
ssbInfo->syncRes.cell_detected = nr_pbch_detection(ssbInfo->proc,
|
ssbInfo->syncRes.cell_detected = nr_pbch_detection(ssbInfo->proc,
|
||||||
ssbInfo->fp,
|
ssbInfo->fp,
|
||||||
ssbInfo->nidCell,
|
ssbInfo->nidCell,
|
||||||
@@ -289,8 +285,12 @@ void nr_scan_ssb(void *arg)
|
|||||||
&ssbInfo->ssbIndex,
|
&ssbInfo->ssbIndex,
|
||||||
&ssbInfo->symbolOffset,
|
&ssbInfo->symbolOffset,
|
||||||
&ssbInfo->pbchResult,
|
&ssbInfo->pbchResult,
|
||||||
nr_gold_pbch_ref,
|
|
||||||
rxdataF); // start pbch detection at first symbol after pss
|
rxdataF); // start pbch detection at first symbol after pss
|
||||||
|
if (ssbInfo->syncRes.cell_detected) {
|
||||||
|
int rsrp_db_per_re = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC);
|
||||||
|
ssbInfo->adjust_rxgain = TARGET_RX_POWER - rsrp_db_per_re;
|
||||||
|
LOG_I(PHY, "pbch rx ok. rsrp:%d dB/RE, adjust_rxgain:%d dB\n", rsrp_db_per_re, ssbInfo->adjust_rxgain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,6 +370,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
fp->ssb_index = res.ssbIndex;
|
fp->ssb_index = res.ssbIndex;
|
||||||
ue->symbol_offset = res.symbolOffset;
|
ue->symbol_offset = res.symbolOffset;
|
||||||
ue->common_vars.freq_offset = res.freqOffset;
|
ue->common_vars.freq_offset = res.freqOffset;
|
||||||
|
ue->adjust_rxgain = res.adjust_rxgain;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In initial sync, we indicate PBCH to MAC after the scan is complete.
|
// In initial sync, we indicate PBCH to MAC after the scan is complete.
|
||||||
@@ -400,7 +401,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
// and we do not know yet in which slot it goes.
|
// and we do not know yet in which slot it goes.
|
||||||
compensate_freq_offset(ue->common_vars.rxdata, fp, res.freqOffset, res.syncRes.frame_id);
|
compensate_freq_offset(ue->common_vars.rxdata, fp, res.freqOffset, res.syncRes.frame_id);
|
||||||
}
|
}
|
||||||
nr_gold_pbch(ue->nr_gold_pbch, fp->Nid_cell, fp->Lmax);
|
|
||||||
// sync at symbol ue->symbol_offset
|
// sync at symbol ue->symbol_offset
|
||||||
// computing the offset wrt the beginning of the frame
|
// computing the offset wrt the beginning of the frame
|
||||||
int mu = fp->numerology_index;
|
int mu = fp->numerology_index;
|
||||||
@@ -413,24 +413,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
// the n_frames we got sync
|
// the n_frames we got sync
|
||||||
ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id;
|
ue->init_sync_frame = n_frames - 1 - res.syncRes.frame_id;
|
||||||
|
|
||||||
// compute the scramblingID_pdcch and the gold pdcch
|
|
||||||
ue->scramblingID_pdcch = fp->Nid_cell;
|
|
||||||
nr_gold_pdcch(ue, fp->Nid_cell);
|
|
||||||
|
|
||||||
// compute the scrambling IDs for PDSCH DMRS
|
|
||||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
|
||||||
ue->scramblingID_dlsch[i] = fp->Nid_cell;
|
|
||||||
nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell);
|
|
||||||
|
|
||||||
// initialize the pusch dmrs
|
|
||||||
for (int i = 0; i < NR_NB_NSCID; i++) {
|
|
||||||
ue->scramblingID_ulsch[i] = fp->Nid_cell;
|
|
||||||
nr_init_pusch_dmrs(ue, ue->scramblingID_ulsch[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we also need to take into account the shift by samples_per_frame in case the if is true
|
// we also need to take into account the shift by samples_per_frame in case the if is true
|
||||||
if (res.ssbOffset < sync_pos_frame) {
|
if (res.ssbOffset < sync_pos_frame) {
|
||||||
res.syncRes.rx_offset = fp->samples_per_frame - sync_pos_frame + res.ssbOffset;
|
res.syncRes.rx_offset = fp->samples_per_frame - sync_pos_frame + res.ssbOffset;
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
uint16_t rx_slss_id = 65535;
|
uint16_t rx_slss_id = 65535;
|
||||||
|
|
||||||
nr_initial_sync_t result = {true, 0};
|
nr_initial_sync_t result = {false, 0};
|
||||||
|
|
||||||
#ifdef SL_DEBUG_SEARCH_SLSS
|
#ifdef SL_DEBUG_SEARCH_SLSS
|
||||||
LOG_D(PHY, "SIDELINK SEARCH SLSS: Function:%s\n", __func__);
|
LOG_D(PHY, "SIDELINK SEARCH SLSS: Function:%s\n", __func__);
|
||||||
@@ -464,7 +464,6 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
|||||||
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
|
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
|
||||||
nr_pbch_channel_estimation(frame_parms,
|
nr_pbch_channel_estimation(frame_parms,
|
||||||
&UE->SL_UE_PHY_PARAMS,
|
&UE->SL_UE_PHY_PARAMS,
|
||||||
UE->nr_gold_pbch,
|
|
||||||
rxdataF_sz,
|
rxdataF_sz,
|
||||||
dl_ch_estimates,
|
dl_ch_estimates,
|
||||||
dl_ch_estimates_time,
|
dl_ch_estimates_time,
|
||||||
@@ -512,7 +511,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
|
|||||||
sync_params->DFN,
|
sync_params->DFN,
|
||||||
sync_params->slot_offset);
|
sync_params->slot_offset);
|
||||||
|
|
||||||
nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
|
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false);
|
||||||
|
|
||||||
UE->init_sync_frame = sync_params->remaining_frames;
|
UE->init_sync_frame = sync_params->remaining_frames;
|
||||||
result.rx_offset = sync_params->rx_offset;
|
result.rx_offset = sync_params->rx_offset;
|
||||||
|
|||||||
@@ -33,12 +33,11 @@
|
|||||||
#include "PHY/CODING/coding_extern.h"
|
#include "PHY/CODING/coding_extern.h"
|
||||||
#include "PHY/phy_extern_nr_ue.h"
|
#include "PHY/phy_extern_nr_ue.h"
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
|
||||||
#include "PHY/INIT/nr_phy_init.h"
|
#include "PHY/INIT/nr_phy_init.h"
|
||||||
#include "openair1/SCHED_NR_UE/defs.h"
|
#include "openair1/SCHED_NR_UE/defs.h"
|
||||||
#include <openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h>
|
#include <openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h>
|
||||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||||
|
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||||
//#define DEBUG_PBCH
|
//#define DEBUG_PBCH
|
||||||
//#define DEBUG_PBCH_ENCODING
|
//#define DEBUG_PBCH_ENCODING
|
||||||
|
|
||||||
@@ -294,46 +293,30 @@ void nr_pbch_unscrambling(int16_t *demod_pbch_e,
|
|||||||
uint32_t pbch_a_prime,
|
uint32_t pbch_a_prime,
|
||||||
uint32_t *pbch_a_interleaved)
|
uint32_t *pbch_a_interleaved)
|
||||||
{
|
{
|
||||||
uint8_t reset, offset;
|
uint32_t *seq = gold_cache(Nid, (nushift * M + length + 31) / 32); // this is c_init
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
|
||||||
uint8_t k=0;
|
|
||||||
reset = 1;
|
|
||||||
// x1 is set in first call to lte_gold_generic
|
|
||||||
x2 = Nid; //this is c_init
|
|
||||||
|
|
||||||
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
||||||
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
|
int idxGold = (nushift * M + 31) / 32 - 1;
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scrambling is now done with offset (nushift*M)%32
|
// Scrambling is now done with offset (nushift*M)%32
|
||||||
offset = (nushift*M)&0x1f;
|
int offset = (nushift * M) & 0x1f;
|
||||||
|
uint8_t k = 0;
|
||||||
for (int i=0; i<length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
/*if (((i+offset)&0x1f)==0) {
|
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}*/
|
|
||||||
if (bitwise) {
|
if (bitwise) {
|
||||||
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
|
if (((k + offset) & 0x1f) == 0 && (!((unscrambling_mask >> i) & 1)))
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
idxGold++;
|
||||||
reset = 0;
|
*pbch_a_interleaved ^= ((unscrambling_mask >> i) & 1)
|
||||||
}
|
? ((pbch_a_prime >> i) & 1) << i
|
||||||
|
: (((pbch_a_prime >> i) & 1) ^ ((seq[idxGold] >> ((k + offset) & 0x1f)) & 1)) << i;
|
||||||
*pbch_a_interleaved ^= ((unscrambling_mask>>i)&1)? ((pbch_a_prime>>i)&1)<<i : (((pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
|
||||||
k += (!((unscrambling_mask>>i)&1));
|
k += (!((unscrambling_mask>>i)&1));
|
||||||
#ifdef DEBUG_PBCH_ENCODING
|
#ifdef DEBUG_PBCH_ENCODING
|
||||||
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, *pbch_a_interleaved,
|
printf("i %d k %d offset %d (unscrambling_mask>>i)&1) %d s: %08x\t pbch_a_interleaved 0x%08x (!((unscrambling_mask>>i)&1)) %d\n", i, k, offset, (unscrambling_mask>>i)&1, s, *pbch_a_interleaved,
|
||||||
(!((unscrambling_mask>>i)&1)));
|
(!((unscrambling_mask>>i)&1)));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (((i+offset)&0x1f)==0) {
|
if (((i + offset) & 0x1f) == 0)
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
idxGold++;
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((s>>((i+offset)&0x1f))&1)==1)
|
if (seq[idxGold] & (1UL << ((i + offset) % 32)))
|
||||||
demod_pbch_e[i] = -demod_pbch_e[i];
|
demod_pbch_e[i] = -demod_pbch_e[i];
|
||||||
|
|
||||||
#ifdef DEBUG_PBCH_ENCODING
|
#ifdef DEBUG_PBCH_ENCODING
|
||||||
|
|||||||
@@ -57,34 +57,22 @@
|
|||||||
|
|
||||||
void nr_pusch_codeword_scrambling_uci(uint8_t *in, uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out)
|
void nr_pusch_codeword_scrambling_uci(uint8_t *in, uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out)
|
||||||
{
|
{
|
||||||
uint8_t reset, b_idx;
|
uint32_t *seq = gold_cache((n_RNTI << 15) + Nid, (size + 31) / 32);
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0, temp_out = 0;
|
|
||||||
|
|
||||||
reset = 1;
|
|
||||||
x2 = (n_RNTI<<15) + Nid;
|
|
||||||
|
|
||||||
for (int i=0; i<size; i++) {
|
for (int i=0; i<size; i++) {
|
||||||
b_idx = i&0x1f;
|
int idx = i / 32;
|
||||||
if (b_idx==0) {
|
int b_idx = i % 32;
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
if (i)
|
|
||||||
out++;
|
|
||||||
}
|
|
||||||
if (in[i]==NR_PUSCH_x)
|
if (in[i]==NR_PUSCH_x)
|
||||||
*out ^= 1<<b_idx;
|
out[idx] ^= 1 << b_idx;
|
||||||
else if (in[i]==NR_PUSCH_y){
|
else if (in[i]==NR_PUSCH_y){
|
||||||
if (b_idx!=0)
|
if (b_idx)
|
||||||
*out ^= (*out & (1<<(b_idx-1)))<<1;
|
out[idx] ^= (out[idx] & (1 << (b_idx - 1))) << 1;
|
||||||
else{
|
else{
|
||||||
|
uint32_t temp_out = out[idx - 1];
|
||||||
temp_out = *(out-1);
|
out[idx] ^= temp_out >> 31;
|
||||||
*out ^= temp_out>>31;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
|
out[idx] ^= (((in[i]) & 1) ^ ((seq[idx] >> b_idx) & 1)) << b_idx;
|
||||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,12 +228,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
/////////////////////////DMRS Modulation/////////////////////////
|
/////////////////////////DMRS Modulation/////////////////////////
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
if(pusch_pdu->ul_dmrs_scrambling_id != UE->scramblingID_ulsch[pusch_pdu->scid]) {
|
|
||||||
UE->scramblingID_ulsch[pusch_pdu->scid] = pusch_pdu->ul_dmrs_scrambling_id;
|
|
||||||
nr_init_pusch_dmrs(UE, pusch_pdu->scid, pusch_pdu->ul_dmrs_scrambling_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
|
||||||
uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
|
uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
|
||||||
c16_t mod_dmrs[n_dmrs] __attribute((aligned(16)));
|
c16_t mod_dmrs[n_dmrs] __attribute((aligned(16)));
|
||||||
|
|
||||||
@@ -382,7 +364,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
|
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
|
||||||
// Perform this on gold sequence, not required when SC FDMA operation is done,
|
// Perform this on gold sequence, not required when SC FDMA operation is done,
|
||||||
LOG_D(PHY,"DMRS in symbol %d\n",l);
|
LOG_D(PHY,"DMRS in symbol %d\n",l);
|
||||||
nr_modulation(pusch_dmrs[l][pusch_pdu->scid],
|
const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL,
|
||||||
|
frame_parms->symbols_per_slot,
|
||||||
|
pusch_pdu->ul_dmrs_scrambling_id,
|
||||||
|
pusch_pdu->scid,
|
||||||
|
slot,
|
||||||
|
l);
|
||||||
|
nr_modulation(gold,
|
||||||
n_dmrs * 2,
|
n_dmrs * 2,
|
||||||
DMRS_MOD_ORDER,
|
DMRS_MOD_ORDER,
|
||||||
(int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
(int16_t *)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||||
@@ -395,7 +383,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
|
|
||||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
||||||
is_ptrs_sym = 1;
|
is_ptrs_sym = 1;
|
||||||
nr_modulation(pusch_dmrs[l][pusch_pdu->scid], nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
const uint32_t *gold = nr_gold_pusch(frame_parms->N_RB_UL,
|
||||||
|
frame_parms->symbols_per_slot,
|
||||||
|
pusch_pdu->ul_dmrs_scrambling_id,
|
||||||
|
pusch_pdu->scid,
|
||||||
|
slot,
|
||||||
|
l);
|
||||||
|
nr_modulation(gold, nb_rb, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
|
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
|
||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
|
#include "openair1/PHY/NR_REFSIG/nr_refsig.h"
|
||||||
|
|
||||||
#include "T.h"
|
#include "T.h"
|
||||||
//#define NR_UNIT_TEST 1
|
//#define NR_UNIT_TEST 1
|
||||||
@@ -484,46 +485,32 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) {
|
static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint16_t n_id, uint64_t *B64, uint8_t *btilde)
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
{
|
||||||
int i;
|
|
||||||
uint8_t c;
|
|
||||||
// c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1
|
// c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1
|
||||||
//x2 = (rnti) + ((uint32_t)(1+nr_slot_tx)<<16)*(1+(fp->Nid_cell<<1));
|
const int roundedSz = (M_bit + 31) / 32;
|
||||||
x2 = ((rnti)<<15)+n_id;
|
uint32_t *seq = gold_cache((rnti << 15) + n_id, roundedSz);
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit);
|
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t *btildep=btilde;
|
uint8_t *btildep = btilde;
|
||||||
int M_bit2=M_bit > 31 ? 32 : (M_bit&31), M_bit3=M_bit;
|
uint32_t *B32 = (uint32_t *)B64;
|
||||||
uint32_t B;
|
|
||||||
for (int iprime=0;iprime<=(M_bit>>5);iprime++,btildep+=32) {
|
for (int iprime = 0; iprime < roundedSz; iprime++, btildep += 32) {
|
||||||
s = lte_gold_generic(&x1, &x2, (iprime==0) ? 1 : 0);
|
const uint32_t s = seq[iprime];
|
||||||
B=((uint32_t*)B64)[iprime];
|
const uint32_t B = B32[iprime];
|
||||||
for (int n=0;n<M_bit2;n+=8)
|
LOG_D(PHY, "PUCCH2 encoded: %02x\n", B);
|
||||||
LOG_D(PHY,"PUCCH2 encoded %d : %d,%d,%d,%d,%d,%d,%d,%d\n",n,
|
int M_bit2 = iprime == M_bit / 32 ? M_bit % 32 : 32;
|
||||||
(B>>n)&1,
|
for (int i = 0; i < M_bit2; i++) {
|
||||||
(B>>(n+1))&1,
|
uint8_t c = (uint8_t)((s >> i) & 1);
|
||||||
(B>>(n+2))&1,
|
|
||||||
(B>>(n+3))&1,
|
|
||||||
(B>>(n+4))&1,
|
|
||||||
(B>>(n+5))&1,
|
|
||||||
(B>>(n+6))&1,
|
|
||||||
(B>>(n+7))&1
|
|
||||||
);
|
|
||||||
for (i=0; i<M_bit2; i++) {
|
|
||||||
c = (uint8_t)((s>>i)&1);
|
|
||||||
btildep[i] = (((B>>i)&1) ^ c);
|
btildep[i] = (((B>>i)&1) ^ c);
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t\t btilde[%d]=%x from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
|
printf("\t\t\t btilde[%d]=%x from unscrambled bit %d and scrambling %d (%x)\n",i+(iprime<<5),btilde[i],((B>>i)&1),c,s>>i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
M_bit3-=32;
|
|
||||||
M_bit2=M_bit3 > 31 ? 32 : (M_bit3&31);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
|
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
|
||||||
#endif
|
#endif
|
||||||
@@ -721,9 +708,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
|||||||
* Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources
|
* Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources
|
||||||
*/
|
*/
|
||||||
// int32_t *txptr;
|
// int32_t *txptr;
|
||||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
int outSample = 0;
|
||||||
int i=0;
|
|
||||||
int m=0;
|
|
||||||
uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index;
|
uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index;
|
||||||
uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
||||||
|
|
||||||
@@ -732,14 +717,10 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
|||||||
uint64_t temp_x2 = 1ll << 17;
|
uint64_t temp_x2 = 1ll << 17;
|
||||||
temp_x2 *= 14UL * nr_slot_tx + l + startingSymbolIndex + 1;
|
temp_x2 *= 14UL * nr_slot_tx + l + startingSymbolIndex + 1;
|
||||||
temp_x2 *= 2UL * pucch_pdu->dmrs_scrambling_id + 1;
|
temp_x2 *= 2UL * pucch_pdu->dmrs_scrambling_id + 1;
|
||||||
x2 = (temp_x2 + 2UL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31);
|
temp_x2 = (temp_x2 + 2ULL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31);
|
||||||
|
uint idxGold = startingPRB >> 2;
|
||||||
int reset = 1;
|
uint32_t *seq = gold_cache(temp_x2, idxGold + pucch_pdu->prb_size);
|
||||||
for (int ii=0; ii<=(startingPRB>>2); ii++) {
|
int m = 0;
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
m = 0;
|
|
||||||
for (int rb=0; rb<pucch_pdu->prb_size; rb++) {
|
for (int rb=0; rb<pucch_pdu->prb_size; rb++) {
|
||||||
//startingPRB = startingPRB + rb;
|
//startingPRB = startingPRB + rb;
|
||||||
const bool nb_rb_is_even = frame_parms->N_RB_DL & 1;
|
const bool nb_rb_is_even = frame_parms->N_RB_DL & 1;
|
||||||
@@ -773,7 +754,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3
|
if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3
|
||||||
txdataF[0][re_offset] = d[i + k];
|
txdataF[0][re_offset] = d[outSample + k];
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf(
|
printf(
|
||||||
"\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
"\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d "
|
||||||
@@ -795,8 +776,8 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2
|
if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2
|
||||||
txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m)) & 1)))));
|
txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((seq[idxGold] >> (2 * m)) & 1)))));
|
||||||
txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m + 1)) & 1)))));
|
txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((seq[idxGold] >> (2 * m + 1)) & 1)))));
|
||||||
m++;
|
m++;
|
||||||
#ifdef DEBUG_NR_PUCCH_TX
|
#ifdef DEBUG_NR_PUCCH_TX
|
||||||
printf(
|
printf(
|
||||||
@@ -821,10 +802,10 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
|||||||
re_offset++;
|
re_offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i+=8;
|
outSample += 8;
|
||||||
|
|
||||||
if ((m&((1<<4)-1))==0) {
|
if (m % 16 == 0) {
|
||||||
s = lte_gold_generic(&x1, &x2, 0);
|
idxGold++;
|
||||||
m = 0;
|
m = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -606,24 +606,9 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
// PUCCH0 Look-up table for cyclic-shifts
|
// PUCCH0 Look-up table for cyclic-shifts
|
||||||
NR_gNB_PUCCH0_LUT_t pucch0_lut;
|
NR_gNB_PUCCH0_LUT_t pucch0_lut;
|
||||||
|
|
||||||
/// PBCH DMRS sequence
|
|
||||||
uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
|
||||||
|
|
||||||
/// PBCH interleaver
|
/// PBCH interleaver
|
||||||
uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS];
|
uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS];
|
||||||
|
|
||||||
/// PDCCH DMRS sequence
|
|
||||||
uint32_t ***nr_gold_pdcch_dmrs;
|
|
||||||
|
|
||||||
/// PDSCH DMRS sequence
|
|
||||||
uint32_t ****nr_gold_pdsch_dmrs;
|
|
||||||
|
|
||||||
/// PUSCH DMRS
|
|
||||||
uint32_t ****nr_gold_pusch_dmrs;
|
|
||||||
|
|
||||||
/// PRS sequence
|
|
||||||
uint32_t ****nr_gold_prs;
|
|
||||||
|
|
||||||
/// PRACH root sequence
|
/// PRACH root sequence
|
||||||
c16_t X_u[64][839];
|
c16_t X_u[64][839];
|
||||||
|
|
||||||
@@ -641,10 +626,6 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
/// counter to average prach energh over first 100 prach opportunities
|
/// counter to average prach energh over first 100 prach opportunities
|
||||||
int prach_energy_counter;
|
int prach_energy_counter;
|
||||||
|
|
||||||
int pdcch_gold_init;
|
|
||||||
int pdsch_gold_init[2];
|
|
||||||
int pusch_gold_init[2];
|
|
||||||
|
|
||||||
int ap_N1;
|
int ap_N1;
|
||||||
int ap_N2;
|
int ap_N2;
|
||||||
int ap_XP;
|
int ap_XP;
|
||||||
|
|||||||
@@ -407,32 +407,7 @@ typedef struct PHY_VARS_NR_UE_s {
|
|||||||
uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE];
|
uint32_t dmrs_pbch_bitmap_nr[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// PBCH DMRS sequence
|
|
||||||
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
|
||||||
|
|
||||||
/// PDSCH DMRS
|
|
||||||
uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
|
|
||||||
|
|
||||||
// Scrambling IDs used in PDSCH DMRS
|
|
||||||
uint16_t scramblingID_dlsch[2];
|
|
||||||
|
|
||||||
// Scrambling IDs used in PUSCH DMRS
|
// Scrambling IDs used in PUSCH DMRS
|
||||||
uint16_t scramblingID_ulsch[2];
|
|
||||||
|
|
||||||
/// PDCCH DMRS
|
|
||||||
uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX];
|
|
||||||
|
|
||||||
// Scrambling IDs used in PDCCH DMRS
|
|
||||||
uint16_t scramblingID_pdcch;
|
|
||||||
|
|
||||||
/// PUSCH DMRS sequence
|
|
||||||
uint32_t ****nr_gold_pusch_dmrs;
|
|
||||||
|
|
||||||
// PRS sequence per gNB, per resource
|
|
||||||
uint32_t *****nr_gold_prs;
|
|
||||||
|
|
||||||
c16_t X_u[64][839];
|
c16_t X_u[64][839];
|
||||||
|
|
||||||
// flag to activate PRB based averaging of channel estimates
|
// flag to activate PRB based averaging of channel estimates
|
||||||
@@ -465,15 +440,15 @@ typedef struct PHY_VARS_NR_UE_s {
|
|||||||
int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
|
||||||
int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
|
int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
|
int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX];
|
|
||||||
uint8_t decode_SIB;
|
uint8_t decode_SIB;
|
||||||
uint8_t decode_MIB;
|
uint8_t decode_MIB;
|
||||||
uint8_t init_sync_frame;
|
uint8_t init_sync_frame;
|
||||||
@@ -600,6 +575,9 @@ typedef struct PHY_VARS_NR_UE_s {
|
|||||||
|
|
||||||
notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
|
notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
|
||||||
|
|
||||||
|
// Gain change required for automation RX gain change
|
||||||
|
int adjust_rxgain;
|
||||||
|
|
||||||
// Sidelink parameters
|
// Sidelink parameters
|
||||||
sl_nr_sidelink_mode_t sl_mode;
|
sl_nr_sidelink_mode_t sl_mode;
|
||||||
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
|
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
|
||||||
@@ -645,6 +623,7 @@ typedef struct {
|
|||||||
fapiPbch_t pbchResult;
|
fapiPbch_t pbchResult;
|
||||||
int pssCorrPeakPower;
|
int pssCorrPeakPower;
|
||||||
int pssCorrAvgPower;
|
int pssCorrAvgPower;
|
||||||
|
int adjust_rxgain;
|
||||||
} nr_ue_ssb_scan_t;
|
} nr_ue_ssb_scan_t;
|
||||||
|
|
||||||
typedef struct nr_phy_data_tx_s {
|
typedef struct nr_phy_data_tx_s {
|
||||||
|
|||||||
@@ -122,8 +122,6 @@ typedef struct {
|
|||||||
} nr_srs_info_t;
|
} nr_srs_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t csi_gold_init;
|
|
||||||
uint32_t ***nr_gold_csi_rs;
|
|
||||||
uint8_t csi_rs_generated_signal_bits;
|
uint8_t csi_rs_generated_signal_bits;
|
||||||
int32_t **csi_rs_generated_signal;
|
int32_t **csi_rs_generated_signal;
|
||||||
bool csi_im_meas_computed;
|
bool csi_im_meas_computed;
|
||||||
|
|||||||
@@ -181,6 +181,9 @@
|
|||||||
#define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation)
|
#define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation)
|
||||||
#define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation)
|
#define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation)
|
||||||
|
|
||||||
|
// Increase USRP rx gain in steps of 3dB during Initial search
|
||||||
|
#define INCREASE_IN_RXGAIN 3
|
||||||
|
|
||||||
//the min and max gains have to match the calibrated gain table
|
//the min and max gains have to match the calibrated gain table
|
||||||
//#define MAX_RF_GAIN 160
|
//#define MAX_RF_GAIN 160
|
||||||
//#define MIN_RF_GAIN 96
|
//#define MIN_RF_GAIN 96
|
||||||
|
|||||||
@@ -108,15 +108,8 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB,int frame,int slot, nfapi_nr_
|
|||||||
nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
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);
|
nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||||
|
|
||||||
if (fp->Lmax == 4)
|
int hf = fp->Lmax == 4 ? n_hf : 0;
|
||||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index & 7],
|
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],
|
|
||||||
gNB->TX_AMP,
|
|
||||||
ssb_start_symbol,
|
|
||||||
cfg,
|
|
||||||
fp);
|
|
||||||
else
|
|
||||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index & 7],
|
|
||||||
&txdataF[0][txdataF_offset],
|
&txdataF[0][txdataF_offset],
|
||||||
gNB->TX_AMP,
|
gNB->TX_AMP,
|
||||||
ssb_start_symbol,
|
ssb_start_symbol,
|
||||||
@@ -186,7 +179,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
|||||||
{
|
{
|
||||||
slot_prs = (slot - i*prs_config->PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame;
|
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);
|
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(gNB->nr_gold_prs[rsc_id][slot_prs],&gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp);
|
nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -916,7 +916,6 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
|||||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||||
nr_pbch_channel_estimation(&ue->frame_parms,
|
nr_pbch_channel_estimation(&ue->frame_parms,
|
||||||
NULL,
|
NULL,
|
||||||
ue->nr_gold_pbch,
|
|
||||||
estimateSz,
|
estimateSz,
|
||||||
dl_ch_estimates,
|
dl_ch_estimates,
|
||||||
dl_ch_estimates_time,
|
dl_ch_estimates_time,
|
||||||
@@ -1037,7 +1036,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
|||||||
}
|
}
|
||||||
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF);
|
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF);
|
||||||
}
|
}
|
||||||
LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
|
LOG_D(PHY, "[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
|
||||||
phy_pdcch_config->nb_search_space = 0;
|
phy_pdcch_config->nb_search_space = 0;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
|
||||||
return sampleShift;
|
return sampleShift;
|
||||||
|
|||||||
@@ -196,7 +196,6 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
|||||||
start_meas(&sl_phy_params->channel_estimation_stats);
|
start_meas(&sl_phy_params->channel_estimation_stats);
|
||||||
nr_pbch_channel_estimation(fp,
|
nr_pbch_channel_estimation(fp,
|
||||||
&ue->SL_UE_PHY_PARAMS,
|
&ue->SL_UE_PHY_PARAMS,
|
||||||
ue->nr_gold_pbch,
|
|
||||||
estimateSz,
|
estimateSz,
|
||||||
dl_ch_estimates,
|
dl_ch_estimates,
|
||||||
dl_ch_estimates_time,
|
dl_ch_estimates_time,
|
||||||
@@ -223,7 +222,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
|||||||
sym = (sym == 0) ? 5 : sym + 1;
|
sym = (sym == 0) ? 5 : sym + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
|
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
|
||||||
|
|
||||||
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||||
|
|
||||||
|
|||||||
@@ -840,18 +840,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
init_nr_ue_transport(UE);
|
init_nr_ue_transport(UE);
|
||||||
|
|
||||||
nr_gold_pbch(UE->nr_gold_pbch, frame_parms->Nid_cell, frame_parms->Lmax);
|
|
||||||
|
|
||||||
// compute the scramblingID_pdcch and the gold pdcch
|
|
||||||
UE->scramblingID_pdcch = frame_parms->Nid_cell;
|
|
||||||
nr_gold_pdcch(UE, frame_parms->Nid_cell);
|
|
||||||
|
|
||||||
// compute the scrambling IDs for PDSCH DMRS
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
UE->scramblingID_dlsch[i] = frame_parms->Nid_cell;
|
|
||||||
nr_gold_pdsch(UE, i, UE->scramblingID_dlsch[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_l2_init_ue(1);
|
nr_l2_init_ue(1);
|
||||||
UE_mac = get_mac_inst(0);
|
UE_mac = get_mac_inst(0);
|
||||||
ue_init_config_request(UE_mac, mu);
|
ue_init_config_request(UE_mac, mu);
|
||||||
|
|||||||
@@ -161,8 +161,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
|
|||||||
if (mu>2) fp->nr_band = 257;
|
if (mu>2) fp->nr_band = 257;
|
||||||
else fp->nr_band = 78;
|
else fp->nr_band = 78;
|
||||||
fp->threequarter_fs= 0;
|
fp->threequarter_fs= 0;
|
||||||
|
frequency_range_t frequency_range = fp->nr_band > 256 ? FR2 : FR1;
|
||||||
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, mu, N_RB_DL);
|
int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL);
|
||||||
|
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||||
|
|
||||||
fp->ofdm_offset_divisor = UINT_MAX;
|
fp->ofdm_offset_divisor = UINT_MAX;
|
||||||
nr_init_frame_parms(gNB_config, fp);
|
nr_init_frame_parms(gNB_config, fp);
|
||||||
@@ -618,8 +619,6 @@ int main(int argc, char **argv)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax);
|
|
||||||
|
|
||||||
processingData_L1tx_t msgDataTx;
|
processingData_L1tx_t msgDataTx;
|
||||||
// generate signal
|
// generate signal
|
||||||
const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP;
|
const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP;
|
||||||
@@ -803,7 +802,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
nr_pbch_channel_estimation(&UE->frame_parms,
|
nr_pbch_channel_estimation(&UE->frame_parms,
|
||||||
&UE->SL_UE_PHY_PARAMS,
|
&UE->SL_UE_PHY_PARAMS,
|
||||||
UE->nr_gold_pbch,
|
|
||||||
estimateSz,
|
estimateSz,
|
||||||
dl_ch_estimates,
|
dl_ch_estimates,
|
||||||
dl_ch_estimates_time,
|
dl_ch_estimates_time,
|
||||||
|
|||||||
@@ -703,11 +703,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
init_nr_ue_transport(UE);
|
init_nr_ue_transport(UE);
|
||||||
|
|
||||||
for(int n_scid = 0; n_scid<2; n_scid++) {
|
|
||||||
UE->scramblingID_ulsch[n_scid] = frame_parms->Nid_cell;
|
|
||||||
nr_init_pusch_dmrs(UE, frame_parms->Nid_cell, n_scid);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Configure UE
|
//Configure UE
|
||||||
nr_l2_init_ue(1);
|
nr_l2_init_ue(1);
|
||||||
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
|
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
/* To setup F1 at DU */
|
/* To setup F1 at DU */
|
||||||
MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t, f1ap_du_register_req)
|
MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t, f1ap_du_register_req)
|
||||||
|
|
||||||
|
/* RESET */
|
||||||
|
MESSAGE_DEF(F1AP_RESET, MESSAGE_PRIORITY_MED, f1ap_reset_t, f1ap_reset)
|
||||||
|
MESSAGE_DEF(F1AP_RESET_ACK, MESSAGE_PRIORITY_MED, f1ap_reset_ack_t, f1ap_reset_ack)
|
||||||
|
|
||||||
/* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/
|
/* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/
|
||||||
MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req)
|
MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req)
|
||||||
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge)
|
MESSAGE_DEF(F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE , MESSAGE_PRIORITY_MED, f1ap_gnb_cu_configuration_update_acknowledge_t , f1ap_gnb_cu_configuration_update_acknowledge)
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
#define F1AP_DU_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_du_register_req
|
#define F1AP_DU_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_du_register_req
|
||||||
|
|
||||||
|
#define F1AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.f1ap_reset
|
||||||
|
#define F1AP_RESET_ACK(mSGpTR) (mSGpTR)->ittiMsg.f1ap_reset_ack
|
||||||
|
|
||||||
#define F1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_req
|
#define F1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_req
|
||||||
#define F1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_resp
|
#define F1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_resp
|
||||||
#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
|
#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
|
||||||
@@ -78,6 +81,8 @@
|
|||||||
#define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32
|
#define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32
|
||||||
#define F1AP_MAX_NO_UE_ID 1024
|
#define F1AP_MAX_NO_UE_ID 1024
|
||||||
|
|
||||||
|
#define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536
|
||||||
|
|
||||||
typedef net_ip_address_t f1ap_net_ip_address_t;
|
typedef net_ip_address_t f1ap_net_ip_address_t;
|
||||||
|
|
||||||
typedef struct f1ap_net_config_t {
|
typedef struct f1ap_net_config_t {
|
||||||
@@ -534,4 +539,29 @@ typedef struct f1ap_lost_connection_t {
|
|||||||
int dummy;
|
int dummy;
|
||||||
} f1ap_lost_connection_t;
|
} f1ap_lost_connection_t;
|
||||||
|
|
||||||
|
typedef enum F1AP_ResetType_e {
|
||||||
|
F1AP_RESET_ALL,
|
||||||
|
F1AP_RESET_PART_OF_F1_INTERFACE
|
||||||
|
} f1ap_ResetType_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_reset_t {
|
||||||
|
uint64_t transaction_id;
|
||||||
|
f1ap_Cause_t cause;
|
||||||
|
long cause_value;
|
||||||
|
f1ap_ResetType_t reset_type;
|
||||||
|
struct {
|
||||||
|
uint32_t gNB_CU_ue_id;
|
||||||
|
uint32_t gNB_DU_ue_id;
|
||||||
|
} ue_to_reset[F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET];
|
||||||
|
} f1ap_reset_t;
|
||||||
|
|
||||||
|
typedef struct f1ap_reset_ack_t {
|
||||||
|
uint64_t transaction_id;
|
||||||
|
struct {
|
||||||
|
uint32_t gNB_CU_ue_id;
|
||||||
|
uint32_t gNB_DU_ue_id;
|
||||||
|
} ue_to_reset[F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET];
|
||||||
|
uint16_t criticality_diagnostics;
|
||||||
|
} f1ap_reset_ack_t;
|
||||||
|
|
||||||
#endif /* F1AP_MESSAGES_TYPES_H_ */
|
#endif /* F1AP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -409,6 +409,19 @@ typedef enum ngap_Cause_radio_network_e {
|
|||||||
NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES
|
NGAP_CAUSE_RADIO_NETWORK_MULTIPLE_LOCATION_REPORTING_REFERENCE_ID_INSTANCES
|
||||||
} ngap_Cause_radio_network_t;
|
} ngap_Cause_radio_network_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NGAP protocol cause values as per 9.3.1.2 `Cause` section in 3GPP TS 38.413.
|
||||||
|
*/
|
||||||
|
typedef enum ngap_cause_protocol_e {
|
||||||
|
NGAP_CAUSE_PROTOCOL_TRANSFER_SYNTAX_ERROR,
|
||||||
|
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_REJECT,
|
||||||
|
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_IGNORE,
|
||||||
|
NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE,
|
||||||
|
NGAP_CAUSE_PROTOCOL_SEMANTIC_ERROR,
|
||||||
|
NGAP_CAUSE_PROTOCOL_ABSTRACT_SYNTAX_ERROR_FCM,
|
||||||
|
NGAP_CAUSE_PROTOCOL_UNSPECIFIED
|
||||||
|
} ngap_cause_protocol_t;
|
||||||
|
|
||||||
typedef struct pdusession_failed_s {
|
typedef struct pdusession_failed_s {
|
||||||
/* Unique pdusession_id for the UE. */
|
/* Unique pdusession_id for the UE. */
|
||||||
uint8_t pdusession_id;
|
uint8_t pdusession_id;
|
||||||
|
|||||||
@@ -35,12 +35,12 @@
|
|||||||
#include "f1ap_itti_messaging.h"
|
#include "f1ap_itti_messaging.h"
|
||||||
#include "f1ap_cu_interface_management.h"
|
#include "f1ap_cu_interface_management.h"
|
||||||
|
|
||||||
int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset)
|
int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||||
{
|
{
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
AssertFatal(1==0,"Not implemented yet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||||
{
|
{
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
AssertFatal(1==0,"Not implemented yet\n");
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream,
|
|||||||
AssertFatal(1==0,"Not implemented yet\n");
|
AssertFatal(1==0,"Not implemented yet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge)
|
int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack)
|
||||||
{
|
{
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
AssertFatal(1==0,"Not implemented yet\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,10 @@
|
|||||||
/*
|
/*
|
||||||
* Reset
|
* Reset
|
||||||
*/
|
*/
|
||||||
int CU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset);
|
int CU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||||
int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
int CU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||||
int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
int CU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||||
int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge);
|
int CU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error Indication
|
* Error Indication
|
||||||
|
|||||||
@@ -160,6 +160,10 @@ void *F1AP_CU_task(void *arg) {
|
|||||||
&received_msg->ittiMsg.sctp_data_ind);
|
&received_msg->ittiMsg.sctp_data_ind);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F1AP_RESET_ACK:
|
||||||
|
CU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(received_msg));
|
||||||
|
break;
|
||||||
|
|
||||||
case F1AP_SETUP_RESP: // from rrc
|
case F1AP_SETUP_RESP: // from rrc
|
||||||
CU_send_F1_SETUP_RESPONSE(assoc_id,
|
CU_send_F1_SETUP_RESPONSE(assoc_id,
|
||||||
&F1AP_SETUP_RESP(received_msg));
|
&F1AP_SETUP_RESP(received_msg));
|
||||||
|
|||||||
@@ -52,14 +52,115 @@ int to_NRNRB(int nrb) {
|
|||||||
|
|
||||||
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||||
{
|
{
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
LOG_D(F1AP, "DU_handle_RESET\n");\
|
||||||
|
F1AP_Reset_t *container;
|
||||||
|
F1AP_ResetIEs_t *ie;
|
||||||
|
DevAssert(pdu != NULL);
|
||||||
|
container = &pdu->choice.initiatingMessage->value.choice.Reset;
|
||||||
|
|
||||||
|
/* Reset == Non UE-related procedure -> stream 0 */
|
||||||
|
if (stream != 0) {
|
||||||
|
LOG_W(F1AP, "[SCTP %d] Received Reset on stream != 0 (%d)\n",
|
||||||
|
assoc_id, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDef *msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_RESET);
|
||||||
|
msg_p->ittiMsgHeader.originInstance = assoc_id;
|
||||||
|
f1ap_reset_t *f1ap_reset = &F1AP_RESET(msg_p);
|
||||||
|
|
||||||
|
/* Transaction ID */
|
||||||
|
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||||
|
f1ap_reset->transaction_id = ie->value.choice.TransactionID;
|
||||||
|
LOG_D(F1AP, "req->transaction_id %lu \n", f1ap_reset->transaction_id);
|
||||||
|
|
||||||
|
/* Cause */
|
||||||
|
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true);
|
||||||
|
switch(ie->value.choice.Cause.present)
|
||||||
|
{
|
||||||
|
case F1AP_Cause_PR_radioNetwork:
|
||||||
|
LOG_D(F1AP, "Cause: Radio Network\n");
|
||||||
|
f1ap_reset->cause = F1AP_CAUSE_RADIO_NETWORK;
|
||||||
|
f1ap_reset->cause_value = ie->value.choice.Cause.choice.radioNetwork;
|
||||||
|
break;
|
||||||
|
case F1AP_Cause_PR_transport:
|
||||||
|
LOG_D(F1AP, "Cause: Transport\n");
|
||||||
|
f1ap_reset->cause = F1AP_CAUSE_TRANSPORT;
|
||||||
|
f1ap_reset->cause_value = ie->value.choice.Cause.choice.transport;
|
||||||
|
break;
|
||||||
|
case F1AP_Cause_PR_protocol:
|
||||||
|
LOG_D(F1AP, "Cause: Protocol\n");
|
||||||
|
f1ap_reset->cause = F1AP_CAUSE_PROTOCOL;
|
||||||
|
f1ap_reset->cause_value = ie->value.choice.Cause.choice.protocol;
|
||||||
|
break;
|
||||||
|
case F1AP_Cause_PR_misc:
|
||||||
|
LOG_D(F1AP, "Cause: Misc\n");
|
||||||
|
f1ap_reset->cause = F1AP_CAUSE_MISC;
|
||||||
|
f1ap_reset->cause_value = ie->value.choice.Cause.choice.misc;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Unknown cause\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ResetType */
|
||||||
|
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ResetIEs_t, ie, container, F1AP_ProtocolIE_ID_id_ResetType, true);
|
||||||
|
switch(ie->value.choice.ResetType.present) {
|
||||||
|
case F1AP_ResetType_PR_f1_Interface:
|
||||||
|
LOG_D(F1AP, "ResetType: F1 Interface\n");
|
||||||
|
f1ap_reset->reset_type = F1AP_RESET_ALL;
|
||||||
|
break;
|
||||||
|
case F1AP_ResetType_PR_partOfF1_Interface:
|
||||||
|
LOG_D(F1AP, "ResetType: Part of F1 Interface\n");
|
||||||
|
f1ap_reset->reset_type = F1AP_RESET_PART_OF_F1_INTERFACE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AssertFatal(1==0,"Unknown reset type\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Part of F1 Interface */
|
||||||
|
if (f1ap_reset->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE) {
|
||||||
|
AssertFatal(1==0, "Not implemented yet\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
f1_reset_cu_initiated(f1ap_reset);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge) {
|
int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack)
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
{
|
||||||
|
F1AP_F1AP_PDU_t pdu= {0};
|
||||||
|
uint8_t *buffer;
|
||||||
|
uint32_t len;
|
||||||
|
/* Create */
|
||||||
|
/* 0. pdu Type */
|
||||||
|
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
|
||||||
|
asn1cCalloc(pdu.choice.successfulOutcome, successMsg);
|
||||||
|
successMsg->procedureCode = F1AP_ProcedureCode_id_Reset;
|
||||||
|
successMsg->criticality = F1AP_Criticality_reject;
|
||||||
|
successMsg->value.present = F1AP_SuccessfulOutcome__value_PR_ResetAcknowledge;
|
||||||
|
F1AP_ResetAcknowledge_t *f1ResetAcknowledge = &successMsg->value.choice.ResetAcknowledge;
|
||||||
|
/* mandatory */
|
||||||
|
/* c1. Transaction ID (integer value) */
|
||||||
|
asn1cSequenceAdd(f1ResetAcknowledge->protocolIEs.list, F1AP_ResetAcknowledgeIEs_t, ieC1);
|
||||||
|
ieC1->id = F1AP_ProtocolIE_ID_id_TransactionID;
|
||||||
|
ieC1->criticality = F1AP_Criticality_reject;
|
||||||
|
ieC1->value.present = F1AP_ResetAcknowledgeIEs__value_PR_TransactionID;
|
||||||
|
ieC1->value.choice.TransactionID = ack->transaction_id;
|
||||||
|
|
||||||
|
/* TODO: (Optional) partialF1Interface, criticality diagnostics */
|
||||||
|
|
||||||
|
/* encode */
|
||||||
|
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
|
||||||
|
LOG_E(F1AP, "Failed to encode F1ResetAcknowledge\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send */
|
||||||
|
ASN_STRUCT_RESET(asn_DEF_F1AP_F1AP_PDU, &pdu);
|
||||||
|
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset)
|
int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||||
{
|
{
|
||||||
AssertFatal(1==0,"Not implemented yet\n");
|
AssertFatal(1==0,"Not implemented yet\n");
|
||||||
}
|
}
|
||||||
@@ -223,6 +324,8 @@ static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_sy
|
|||||||
// SETUP REQUEST
|
// SETUP REQUEST
|
||||||
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req)
|
int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_setup_req_t *setup_req)
|
||||||
{
|
{
|
||||||
|
LOG_D(F1AP, "DU_send_F1_SETUP_REQUEST\n");
|
||||||
|
|
||||||
F1AP_F1AP_PDU_t pdu= {0};
|
F1AP_F1AP_PDU_t pdu= {0};
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
* Reset
|
* Reset
|
||||||
*/
|
*/
|
||||||
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
int DU_handle_RESET(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||||
int DU_send_RESET_ACKKNOWLEDGE(sctp_assoc_t assoc_id, F1AP_ResetAcknowledge_t *ResetAcknowledge);
|
int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack);
|
||||||
int DU_send_RESET(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset);
|
int DU_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||||
int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -134,6 +134,10 @@ void *F1AP_DU_task(void *arg) {
|
|||||||
DUuniqInstance = gtpInst;
|
DUuniqInstance = gtpInst;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case F1AP_RESET_ACK:
|
||||||
|
DU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(msg));
|
||||||
|
break;
|
||||||
|
|
||||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id,
|
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id,
|
||||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg));
|
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg));
|
||||||
|
|||||||
@@ -42,7 +42,10 @@
|
|||||||
/* Handlers matrix. Only f1 related procedure present here */
|
/* Handlers matrix. Only f1 related procedure present here */
|
||||||
static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
|
||||||
|
|
||||||
{0, 0, 0}, /* Reset */
|
// TODO: How to handle RESET if CU/DU has their respective handlers?
|
||||||
|
// We need to check node type and call the right handler.
|
||||||
|
{DU_handle_RESET, CU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */
|
||||||
|
// {CU_handle_RESET, DU_handle_RESET_ACKNOWLEDGE, 0}, /* Reset */
|
||||||
{CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */
|
{CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE}, /* F1Setup */
|
||||||
{0, 0, 0}, /* ErrorIndication */
|
{0, 0, 0}, /* ErrorIndication */
|
||||||
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */
|
{CU_handle_gNB_DU_CONFIGURATION_UPDATE, 0, 0}, /* gNBDUConfigurationUpdate */
|
||||||
|
|||||||
@@ -573,6 +573,10 @@ typedef struct NR_UE_UL_BWP {
|
|||||||
nr_dci_format_t dci_format;
|
nr_dci_format_t dci_format;
|
||||||
int max_fb_time;
|
int max_fb_time;
|
||||||
long *p0_NominalWithGrant;
|
long *p0_NominalWithGrant;
|
||||||
|
// UE Channel bandwidth according to 38.101 5.3.2
|
||||||
|
int channel_bandwidth;
|
||||||
|
// Minimum transmission power according to 38.101 6.3.1
|
||||||
|
float P_CMIN;
|
||||||
} NR_UE_UL_BWP_t;
|
} NR_UE_UL_BWP_t;
|
||||||
|
|
||||||
// non-BWP serving cell configuration
|
// non-BWP serving cell configuration
|
||||||
|
|||||||
@@ -118,9 +118,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
|
|||||||
NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL;
|
NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL;
|
||||||
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
|
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
|
||||||
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
|
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
|
||||||
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range,
|
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
|
mac->frequency_range,
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||||
|
|
||||||
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
|
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
|
||||||
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
|
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
|
||||||
@@ -139,9 +141,11 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
|
NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
|
||||||
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
|
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
|
||||||
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range,
|
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
|
mac->frequency_range,
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||||
|
|
||||||
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
|
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
|
||||||
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
|
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
|
||||||
@@ -260,9 +264,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
|
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
|
||||||
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
|
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
|
||||||
|
|
||||||
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range,
|
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
mac->frequency_range,
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||||
|
|
||||||
cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
|
cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
|
||||||
*scc->ssbSubcarrierSpacing,
|
*scc->ssbSubcarrierSpacing,
|
||||||
@@ -284,9 +289,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||||
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
|
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
|
||||||
|
|
||||||
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range,
|
int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
mac->frequency_range,
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||||
|
|
||||||
long *UL_pointA = NULL;
|
long *UL_pointA = NULL;
|
||||||
if (frequencyInfoUL->absoluteFrequencyPointA)
|
if (frequencyInfoUL->absoluteFrequencyPointA)
|
||||||
@@ -1488,6 +1494,11 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
|
|||||||
bwp->cyclicprefix = ul_genericParameters->cyclicPrefix;
|
bwp->cyclicprefix = ul_genericParameters->cyclicPrefix;
|
||||||
bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||||
bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||||
|
// For power calculations assume the UE channel is the smallest channel that can support the BWP
|
||||||
|
int bw_index = get_smallest_supported_bandwidth_index(bwp->scs, mac->frequency_range, bwp->BWPSize);
|
||||||
|
bwp->channel_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||||
|
// Minumum transmission power depends on bandwidth, precalculate it here
|
||||||
|
bwp->P_CMIN = nr_get_Pcmin(bw_index);
|
||||||
if (bwp_id == 0) {
|
if (bwp_id == 0) {
|
||||||
mac->sc_info.initial_ul_BWPSize = bwp->BWPSize;
|
mac->sc_info.initial_ul_BWPSize = bwp->BWPSize;
|
||||||
mac->sc_info.initial_ul_BWPStart = bwp->BWPStart;
|
mac->sc_info.initial_ul_BWPStart = bwp->BWPStart;
|
||||||
|
|||||||
@@ -138,7 +138,8 @@ static void sl_prepare_phy_config(int module_id,
|
|||||||
|
|
||||||
AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL");
|
AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL");
|
||||||
|
|
||||||
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, carriercfg->subcarrierSpacing, carriercfg->carrierBandwidth);
|
int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing, FR1, carriercfg->carrierBandwidth);
|
||||||
|
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index);
|
||||||
|
|
||||||
phycfg->sl_carrier_config.sl_frequency =
|
phycfg->sl_carrier_config.sl_frequency =
|
||||||
from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz
|
from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz
|
||||||
|
|||||||
@@ -248,6 +248,7 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
uint16_t nr_band,
|
uint16_t nr_band,
|
||||||
frame_type_t frame_type,
|
frame_type_t frame_type,
|
||||||
frequency_range_t frequency_range,
|
frequency_range_t frequency_range,
|
||||||
|
int channel_bandwidth_index,
|
||||||
int Qm,
|
int Qm,
|
||||||
bool powerBoostPi2BPSK,
|
bool powerBoostPi2BPSK,
|
||||||
int scs,
|
int scs,
|
||||||
@@ -256,7 +257,7 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
int n_prbs,
|
int n_prbs,
|
||||||
int start_prb);
|
int start_prb);
|
||||||
|
|
||||||
float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL);
|
float nr_get_Pcmin(int bandwidth_index);
|
||||||
|
|
||||||
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
|
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->nr_band,
|
mac->nr_band,
|
||||||
mac->frame_type,
|
mac->frame_type,
|
||||||
mac->frequency_range,
|
mac->frequency_range,
|
||||||
|
mac->current_UL_BWP->channel_bandwidth,
|
||||||
2,
|
2,
|
||||||
false,
|
false,
|
||||||
prach_scs,
|
prach_scs,
|
||||||
|
|||||||
@@ -66,16 +66,16 @@ static int get_deltatf(uint16_t nb_of_prbs,
|
|||||||
int O_UCI);
|
int O_UCI);
|
||||||
|
|
||||||
// ∆MPR according to Table 6.2.2-3 38.101-1
|
// ∆MPR according to Table 6.2.2-3 38.101-1
|
||||||
static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int N_RB_UL, int n_prbs, int start_prb, int power_class)
|
static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class)
|
||||||
{
|
{
|
||||||
if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) {
|
if (compare_relative_ul_channel_bw(nr_band, scs, channel_bandwidth, frame_type)) {
|
||||||
if (power_class == 3) {
|
if (power_class == 3) {
|
||||||
if ((nr_band == 28 || nr_band == 83) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 30) {
|
if ((nr_band == 28 || nr_band == 83) && channel_bandwidth == 30) {
|
||||||
return 0.5f;
|
return 0.5f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (power_class == 3 || power_class == 2) {
|
if (power_class == 3 || power_class == 2) {
|
||||||
if ((nr_band == 40 || nr_band == 97) && get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL) == 100) {
|
if ((nr_band == 40 || nr_band == 97) && channel_bandwidth == 100) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,6 +168,7 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
uint16_t nr_band,
|
uint16_t nr_band,
|
||||||
frame_type_t frame_type,
|
frame_type_t frame_type,
|
||||||
frequency_range_t frequency_range,
|
frequency_range_t frequency_range,
|
||||||
|
int channel_bandwidth,
|
||||||
int Qm,
|
int Qm,
|
||||||
bool powerBoostPi2BPSK,
|
bool powerBoostPi2BPSK,
|
||||||
int scs,
|
int scs,
|
||||||
@@ -197,7 +198,7 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
int delta_TC = 0;
|
int delta_TC = 0;
|
||||||
|
|
||||||
float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class);
|
float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class);
|
||||||
float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, N_RB_UL, n_prbs, start_prb, power_class);
|
float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, n_prbs, start_prb, power_class);
|
||||||
int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1)
|
int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1)
|
||||||
int delta_rx_SRS = 0; // TODO for SRS
|
int delta_rx_SRS = 0; // TODO for SRS
|
||||||
int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements
|
int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements
|
||||||
@@ -216,7 +217,13 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
}
|
}
|
||||||
// TODO we need a strategy to select a value between minimum and maximum allowed PC_max
|
// TODO we need a strategy to select a value between minimum and maximum allowed PC_max
|
||||||
float pcmax = (pcmax_low + pcmax_high) / 2;
|
float pcmax = (pcmax_low + pcmax_high) / 2;
|
||||||
LOG_D(MAC, "Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm \n", pcmax_low, pcmax, pcmax_high);
|
LOG_D(MAC,
|
||||||
|
"Configured maximum output power: %f dBm <= PCMAX %f dBm <= %f dBm MPR=%.2f deltaMPR=%.2f\n",
|
||||||
|
pcmax_low,
|
||||||
|
pcmax,
|
||||||
|
pcmax_high,
|
||||||
|
MPR,
|
||||||
|
delta_MPR);
|
||||||
return pcmax;
|
return pcmax;
|
||||||
} else {
|
} else {
|
||||||
// FR2 TODO it is even more complex because it is radiated power
|
// FR2 TODO it is even more complex because it is radiated power
|
||||||
@@ -224,12 +231,11 @@ float nr_get_Pcmax(int p_Max,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float nr_get_Pcmin(int scs, int nr_band, int N_RB_UL) {
|
float nr_get_Pcmin(int bandwidth_index) {
|
||||||
int band_index = get_supported_band_index(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL);
|
|
||||||
const float table_38101_6_3_1_1[] = {
|
const float table_38101_6_3_1_1[] = {
|
||||||
-40, -40, -40, -40, -39, -38.2, -37.5, -37, -36.5, -35.2, -34.6, -34, -33.5, -33
|
-40, -40, -40, -40, -39, -38.2, -37.5, -37, -36.5, -35.2, -34.6, -34, -33.5, -33
|
||||||
};
|
};
|
||||||
return table_38101_6_3_1_1[band_index];
|
return table_38101_6_3_1_1[bandwidth_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
|
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
|
||||||
@@ -341,6 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->nr_band,
|
mac->nr_band,
|
||||||
mac->frame_type,
|
mac->frame_type,
|
||||||
mac->frequency_range,
|
mac->frequency_range,
|
||||||
|
current_UL_BWP->channel_bandwidth,
|
||||||
2,
|
2,
|
||||||
false,
|
false,
|
||||||
mac->current_UL_BWP->scs,
|
mac->current_UL_BWP->scs,
|
||||||
@@ -348,7 +355,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
format_type == 2,
|
format_type == 2,
|
||||||
1,
|
1,
|
||||||
start_prb);
|
start_prb);
|
||||||
int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize);
|
float P_CMIN = current_UL_BWP->P_CMIN;
|
||||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||||
|
|
||||||
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
if (power_config->twoPUCCH_PC_AdjustmentStates && *power_config->twoPUCCH_PC_AdjustmentStates > 1) {
|
||||||
@@ -522,6 +529,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->nr_band,
|
mac->nr_band,
|
||||||
mac->frame_type,
|
mac->frame_type,
|
||||||
mac->frequency_range,
|
mac->frequency_range,
|
||||||
|
mac->current_UL_BWP->channel_bandwidth,
|
||||||
qm,
|
qm,
|
||||||
false,
|
false,
|
||||||
mac->current_UL_BWP->scs,
|
mac->current_UL_BWP->scs,
|
||||||
@@ -553,7 +561,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
// TODO: compute pathoss using correct reference
|
// TODO: compute pathoss using correct reference
|
||||||
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
|
||||||
int P_CMIN = nr_get_Pcmin(mac->current_UL_BWP->scs, mac->nr_band, mac->current_UL_BWP->BWPSize);
|
int P_CMIN = mac->current_UL_BWP->P_CMIN;
|
||||||
|
|
||||||
float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
|
float pusch_power_without_f_b_f_c = P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF;
|
||||||
|
|
||||||
|
|||||||
@@ -44,24 +44,27 @@ TEST(test_pcmax, test_mpr)
|
|||||||
int nr_band = 20;
|
int nr_band = 20;
|
||||||
float expected_power = 23 - (1.5 / 2);
|
float expected_power = 23 - (1.5 / 2);
|
||||||
frame_type_t frame_type = TDD;
|
frame_type_t frame_type = TDD;
|
||||||
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
int channel_bandwidth = 20;
|
||||||
|
EXPECT_EQ(expected_power,
|
||||||
|
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
||||||
|
|
||||||
// Outer PRB, MPR = 3, no delta MPR
|
// Outer PRB, MPR = 3, no delta MPR
|
||||||
prb_start = 0;
|
prb_start = 0;
|
||||||
expected_power = 23 - (3.0 / 2);
|
expected_power = 23 - (3.0 / 2);
|
||||||
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
EXPECT_EQ(expected_power,
|
||||||
|
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
||||||
|
|
||||||
// Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB
|
// Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB
|
||||||
N_RB_UL = 78;
|
N_RB_UL = 78;
|
||||||
nr_band = 28;
|
nr_band = 28;
|
||||||
expected_power = 23 - ((3.0 + 0.5) / 2);
|
expected_power = 23 - ((3.0 + 0.5) / 2);
|
||||||
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 2, false, 1, N_RB_UL, false, 100, prb_start));
|
EXPECT_EQ(expected_power, nr_get_Pcmax(23, nr_band, frame_type, FR1, 30, 2, false, 1, N_RB_UL, false, 100, prb_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(test_pcmax, test_not_implemented)
|
TEST(test_pcmax, test_not_implemented)
|
||||||
{
|
{
|
||||||
int N_RB_UL = 51;
|
int N_RB_UL = 51;
|
||||||
EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet");
|
EXPECT_DEATH(nr_get_Pcmax(23, 20, TDD, FR1, 20, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(test_pcmax, test_pucch_max_power)
|
TEST(test_pcmax, test_pucch_max_power)
|
||||||
@@ -70,11 +73,12 @@ TEST(test_pcmax, test_pucch_max_power)
|
|||||||
int prb_start = 0;
|
int prb_start = 0;
|
||||||
int N_RB_UL = 51; // 10Mhz
|
int N_RB_UL = 51; // 10Mhz
|
||||||
float expected_power = 23 - (1.0 / 2);
|
float expected_power = 23 - (1.0 / 2);
|
||||||
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, true, 1, prb_start));
|
int channel_bandwidth = 20;
|
||||||
|
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, true, 1, prb_start));
|
||||||
|
|
||||||
// Other fromats, no transform precoding, MPR = 3
|
// Other fromats, no transform precoding, MPR = 3
|
||||||
expected_power = 23 - (3.0 / 2);
|
expected_power = 23 - (3.0 / 2);
|
||||||
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, 2, false, 1, N_RB_UL, false, 1, prb_start));
|
EXPECT_EQ(expected_power, nr_get_Pcmax(23, 20, TDD, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 1, prb_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
||||||
@@ -108,6 +112,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
|||||||
mac.nr_band,
|
mac.nr_band,
|
||||||
mac.frame_type,
|
mac.frame_type,
|
||||||
FR1,
|
FR1,
|
||||||
|
current_UL_BWP.channel_bandwidth,
|
||||||
2,
|
2,
|
||||||
false,
|
false,
|
||||||
current_UL_BWP.scs,
|
current_UL_BWP.scs,
|
||||||
@@ -177,9 +182,9 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
|||||||
|
|
||||||
TEST(pc_min, check_all_bw_indexes)
|
TEST(pc_min, check_all_bw_indexes)
|
||||||
{
|
{
|
||||||
const int NB_RB_UL[] = {11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273};
|
const int bws[] = {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100};
|
||||||
for (auto i = 0U; i < sizeof(NB_RB_UL) / sizeof(NB_RB_UL[0]); i++) {
|
for (auto i = 0U; i < sizeofArray(bws); i++) {
|
||||||
(void)nr_get_Pcmin(1, 20, NB_RB_UL[i]);
|
(void)nr_get_Pcmin(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +194,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
|
|||||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
current_UL_BWP.scs = 1;
|
current_UL_BWP.scs = 1;
|
||||||
current_UL_BWP.BWPSize = 106;
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
current_UL_BWP.channel_bandwidth = 40;
|
||||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
@@ -218,6 +224,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
|
|||||||
mac.nr_band,
|
mac.nr_band,
|
||||||
mac.frame_type,
|
mac.frame_type,
|
||||||
FR1,
|
FR1,
|
||||||
|
current_UL_BWP.channel_bandwidth,
|
||||||
Qm,
|
Qm,
|
||||||
false,
|
false,
|
||||||
current_UL_BWP.scs,
|
current_UL_BWP.scs,
|
||||||
@@ -286,6 +293,7 @@ TEST(pusch_power_control, pusch_power_data)
|
|||||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
current_UL_BWP.scs = 1;
|
current_UL_BWP.scs = 1;
|
||||||
current_UL_BWP.BWPSize = 106;
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
current_UL_BWP.channel_bandwidth = 40;
|
||||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
@@ -317,6 +325,7 @@ TEST(pusch_power_control, pusch_power_data)
|
|||||||
mac.nr_band,
|
mac.nr_band,
|
||||||
mac.frame_type,
|
mac.frame_type,
|
||||||
FR1,
|
FR1,
|
||||||
|
current_UL_BWP.channel_bandwidth,
|
||||||
Qm,
|
Qm,
|
||||||
false,
|
false,
|
||||||
current_UL_BWP.scs,
|
current_UL_BWP.scs,
|
||||||
@@ -365,6 +374,7 @@ TEST(pusch_power_control, pusch_power_control_state_initialization)
|
|||||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
current_UL_BWP.scs = 1;
|
current_UL_BWP.scs = 1;
|
||||||
current_UL_BWP.BWPSize = 106;
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
current_UL_BWP.channel_bandwidth = 40;
|
||||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
@@ -412,6 +422,7 @@ TEST(pusch_power_control, pusch_power_control_state)
|
|||||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||||
current_UL_BWP.scs = 1;
|
current_UL_BWP.scs = 1;
|
||||||
current_UL_BWP.BWPSize = 106;
|
current_UL_BWP.BWPSize = 106;
|
||||||
|
current_UL_BWP.channel_bandwidth = 40;
|
||||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||||
@@ -443,6 +454,7 @@ TEST(pusch_power_control, pusch_power_control_state)
|
|||||||
mac.nr_band,
|
mac.nr_band,
|
||||||
mac.frame_type,
|
mac.frame_type,
|
||||||
FR1,
|
FR1,
|
||||||
|
current_UL_BWP.channel_bandwidth,
|
||||||
Qm,
|
Qm,
|
||||||
false,
|
false,
|
||||||
current_UL_BWP.scs,
|
current_UL_BWP.scs,
|
||||||
@@ -569,9 +581,25 @@ TEST(pusch_power_control, pusch_power_100_rb)
|
|||||||
EXPECT_GT(power_100_prbs, power);
|
EXPECT_GT(power_100_prbs, power);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(test_pcmax, test_non_obvious_bwp_size)
|
||||||
|
{
|
||||||
|
// Inner PRB, MPR = 1.5, no delta MPR
|
||||||
|
int prb_start = 4;
|
||||||
|
int N_RB_UL = 48;
|
||||||
|
int nr_band = 20;
|
||||||
|
frame_type_t frame_type = TDD;
|
||||||
|
int channel_bandwidth = 10;
|
||||||
|
float expected_power = 23 - 1.5 / 2;
|
||||||
|
EXPECT_EQ(expected_power,
|
||||||
|
nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start));
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
logInit();
|
logInit();
|
||||||
|
uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY);
|
||||||
|
g_log->log_component[MAC].level = OAILOG_DEBUG;
|
||||||
|
g_log->log_component[NR_MAC].level = OAILOG_DEBUG;
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,9 +280,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
|
|||||||
|
|
||||||
// Carrier configuration
|
// Carrier configuration
|
||||||
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
||||||
cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(*frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1,
|
frequency_range_t frequency_range = *frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1;
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
|
frequency_range,
|
||||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||||
cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary
|
cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary
|
||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value);
|
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.dl_bandwidth.value);
|
||||||
@@ -308,9 +310,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
struct NR_FrequencyInfoUL *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||||
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
|
frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||||
|
frequency_range,
|
||||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||||
|
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||||
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
||||||
cfg->num_tlv++;
|
cfg->num_tlv++;
|
||||||
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value);
|
LOG_I(NR_MAC, "DL_Bandwidth:%d\n", cfg->carrier_config.uplink_bandwidth.value);
|
||||||
@@ -343,7 +347,7 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0];
|
||||||
frequency_range_t frequency_range = band < 100 ? FR1 : FR2;
|
frequency_range = band < 100 ? FR1 : FR2;
|
||||||
|
|
||||||
frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||||
nrmac->common_channels[0].frame_type = frame_type;
|
nrmac->common_channels[0].frame_type = frame_type;
|
||||||
|
|||||||
@@ -2190,6 +2190,7 @@ void nr_schedule_RA(module_id_t module_idP,
|
|||||||
if (ra->contention_resolution_timer < 0) {
|
if (ra->contention_resolution_timer < 0) {
|
||||||
LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti);
|
LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti);
|
||||||
nr_mac_release_ue(mac, ra->rnti);
|
nr_mac_release_ue(mac, ra->rnti);
|
||||||
|
nr_mac_trigger_release_complete(mac, ra->rnti);
|
||||||
nr_clear_ra_proc(ra);
|
nr_clear_ra_proc(ra);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3013,19 +3013,16 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti)
|
void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti)
|
||||||
{
|
{
|
||||||
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
|
|
||||||
|
|
||||||
nr_rlc_remove_ue(rnti);
|
|
||||||
mac_remove_nr_ue(mac, rnti);
|
|
||||||
|
|
||||||
// the CU might not know such UE, e.g., because we never sent a message to
|
// the CU might not know such UE, e.g., because we never sent a message to
|
||||||
// it, so there might not be a corresponding entry for such UE in the look up
|
// it, so there might not be a corresponding entry for such UE in the look up
|
||||||
// table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE
|
// table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE
|
||||||
// MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the
|
// MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the
|
||||||
// newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f
|
// newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f
|
||||||
if (du_exists_f1_ue_data(rnti)) {
|
if (!du_exists_f1_ue_data(rnti))
|
||||||
|
return;
|
||||||
|
|
||||||
// unlock the scheduler temporarily to prevent possible deadlocks with
|
// unlock the scheduler temporarily to prevent possible deadlocks with
|
||||||
// du_remove_f1_ue_data() (and also while sending the message to RRC)
|
// du_remove_f1_ue_data() (and also while sending the message to RRC)
|
||||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||||
@@ -3038,7 +3035,14 @@ void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti)
|
|||||||
|
|
||||||
du_remove_f1_ue_data(rnti);
|
du_remove_f1_ue_data(rnti);
|
||||||
NR_SCHED_LOCK(&mac->sched_lock);
|
NR_SCHED_LOCK(&mac->sched_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti)
|
||||||
|
{
|
||||||
|
NR_SCHED_ENSURE_LOCKED(&mac->sched_lock);
|
||||||
|
|
||||||
|
nr_rlc_remove_ue(rnti);
|
||||||
|
mac_remove_nr_ue(mac, rnti);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_mac_update_timers(module_id_t module_id,
|
void nr_mac_update_timers(module_id_t module_id,
|
||||||
@@ -3055,6 +3059,8 @@ void nr_mac_update_timers(module_id_t module_id,
|
|||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
|
|
||||||
if (nr_mac_check_release(sched_ctrl, UE->rnti)) {
|
if (nr_mac_check_release(sched_ctrl, UE->rnti)) {
|
||||||
|
// trigger release first as nr_mac_release_ue() invalidates UE ptr
|
||||||
|
nr_mac_trigger_release_complete(mac, UE->rnti);
|
||||||
nr_mac_release_ue(mac, UE->rnti);
|
nr_mac_release_ue(mac, UE->rnti);
|
||||||
// go back to examine the next UE, which is at the position the
|
// go back to examine the next UE, which is at the position the
|
||||||
// current UE was
|
// current UE was
|
||||||
|
|||||||
@@ -438,6 +438,7 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid);
|
|||||||
|
|
||||||
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing);
|
void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing);
|
||||||
bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti);
|
bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti);
|
||||||
|
void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti);
|
||||||
void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti);
|
void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti);
|
||||||
|
|
||||||
void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing);
|
void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing);
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||||
|
|
||||||
|
#include "executables/softmodem-common.h"
|
||||||
|
|
||||||
#include "uper_decoder.h"
|
#include "uper_decoder.h"
|
||||||
#include "uper_encoder.h"
|
#include "uper_encoder.h"
|
||||||
|
|
||||||
@@ -95,6 +97,52 @@ static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t
|
|||||||
return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc;
|
return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void du_clear_all_ue_states()
|
||||||
|
{
|
||||||
|
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||||
|
NR_SCHED_LOCK(&mac->sched_lock);
|
||||||
|
|
||||||
|
NR_UE_info_t *UE = *mac->UE_info.list;
|
||||||
|
|
||||||
|
instance_t f1inst = get_f1_gtp_instance();
|
||||||
|
|
||||||
|
while (UE != NULL) {
|
||||||
|
int rnti = UE->rnti;
|
||||||
|
nr_mac_release_ue(mac, rnti);
|
||||||
|
// free all F1 contexts
|
||||||
|
if (du_exists_f1_ue_data(rnti))
|
||||||
|
du_remove_f1_ue_data(rnti);
|
||||||
|
newGtpuDeleteAllTunnels(f1inst, rnti);
|
||||||
|
UE = *mac->UE_info.list;
|
||||||
|
}
|
||||||
|
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1_reset_cu_initiated(const f1ap_reset_t *reset)
|
||||||
|
{
|
||||||
|
LOG_I(MAC, "F1 Reset initiated by CU\n");
|
||||||
|
|
||||||
|
f1ap_reset_ack_t ack = {0};
|
||||||
|
if(reset->reset_type == F1AP_RESET_ALL) {
|
||||||
|
du_clear_all_ue_states();
|
||||||
|
ack = (f1ap_reset_ack_t) {
|
||||||
|
.transaction_id = reset->transaction_id
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// reset->reset_type == F1AP_RESET_PART_OF_F1_INTERFACE
|
||||||
|
AssertFatal(1==0, "Not implemented yet\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||||
|
mac->mac_rrc.f1_reset_acknowledge(&ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void f1_reset_acknowledge_du_initiated(const f1ap_reset_ack_t *ack)
|
||||||
|
{
|
||||||
|
(void) ack;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
void f1_setup_response(const f1ap_setup_resp_t *resp)
|
void f1_setup_response(const f1ap_setup_resp_t *resp)
|
||||||
{
|
{
|
||||||
LOG_I(MAC, "received F1 Setup Response from CU %s\n", resp->gNB_CU_name);
|
LOG_I(MAC, "received F1 Setup Response from CU %s\n", resp->gNB_CU_name);
|
||||||
@@ -126,6 +174,24 @@ void f1_setup_response(const f1ap_setup_resp_t *resp)
|
|||||||
mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name);
|
mac->f1_config.setup_resp->gNB_CU_name = strdup(resp->gNB_CU_name);
|
||||||
|
|
||||||
NR_SCHED_UNLOCK(&mac->sched_lock);
|
NR_SCHED_UNLOCK(&mac->sched_lock);
|
||||||
|
|
||||||
|
// NOTE: Before accepting any UEs, we should initialize the UE states.
|
||||||
|
// This is to handle cases when DU loses the existing SCTP connection,
|
||||||
|
// and reestablishes a new connection to either a new CU or the same CU.
|
||||||
|
// This triggers a new F1 Setup Request from DU to CU as per the specs.
|
||||||
|
// Reinitializing the UE states is necessary to avoid any inconsistent states
|
||||||
|
// between DU and CU.
|
||||||
|
// NOTE2: do not reset in phy_test, because there is a pre-configured UE in
|
||||||
|
// this case. Once NSA/phy-test use F1, this might be lifted, because
|
||||||
|
// creation of a UE will be requested from higher layers.
|
||||||
|
|
||||||
|
// TS38.473 [Sec 8.2.3.1]: "This procedure also re-initialises the F1AP UE-related
|
||||||
|
// contexts (if any) and erases all related signalling connections
|
||||||
|
// in the two nodes like a Reset procedure would do."
|
||||||
|
if (!get_softmodem_params()->phy_test) {
|
||||||
|
LOG_I(MAC, "Clearing the DU's UE states before, if any.\n");
|
||||||
|
du_clear_all_ue_states();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void f1_setup_failure(const f1ap_setup_failure_t *failure)
|
void f1_setup_failure(const f1ap_setup_failure_t *failure)
|
||||||
@@ -615,6 +681,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
|||||||
if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) {
|
if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) {
|
||||||
/* The UE is already not connected anymore or we have nothing to forward*/
|
/* The UE is already not connected anymore or we have nothing to forward*/
|
||||||
nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);
|
nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);
|
||||||
|
nr_mac_trigger_release_complete(mac, cmd->gNB_DU_ue_id);
|
||||||
} else {
|
} else {
|
||||||
/* UE is in sync: forward release message and mark to be deleted
|
/* UE is in sync: forward release message and mark to be deleted
|
||||||
* after UL failure */
|
* after UL failure */
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
||||||
|
|
||||||
|
void f1_reset_cu_initiated(const f1ap_reset_t *reset);
|
||||||
|
void f1_reset_acknowledge_du_initiated(const f1ap_reset_ack_t *ack);
|
||||||
void f1_setup_response(const f1ap_setup_resp_t *resp);
|
void f1_setup_response(const f1ap_setup_resp_t *resp);
|
||||||
void f1_setup_failure(const f1ap_setup_failure_t *failure);
|
void f1_setup_failure(const f1ap_setup_failure_t *failure);
|
||||||
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
|
void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack);
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
#include "common/platform_types.h"
|
#include "common/platform_types.h"
|
||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
|
|
||||||
|
typedef void (*f1_reset_du_initiated_func_t)(const f1ap_reset_t *reset);
|
||||||
|
typedef void (*f1_reset_acknowledge_cu_initiated_func_t)(const f1ap_reset_ack_t *ack);
|
||||||
|
|
||||||
typedef void (*f1_setup_request_func_t)(const f1ap_setup_req_t* req);
|
typedef void (*f1_setup_request_func_t)(const f1ap_setup_req_t* req);
|
||||||
typedef void (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd);
|
typedef void (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,18 @@
|
|||||||
|
|
||||||
#include "mac_rrc_ul.h"
|
#include "mac_rrc_ul.h"
|
||||||
|
|
||||||
|
static void f1_reset_du_initiated_direct(const f1ap_reset_t *reset)
|
||||||
|
{
|
||||||
|
(void) reset;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f1_reset_acknowledge_cu_initiated_direct(const f1ap_reset_ack_t *ack)
|
||||||
|
{
|
||||||
|
(void) ack;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static void f1_setup_request_direct(const f1ap_setup_req_t *req)
|
static void f1_setup_request_direct(const f1ap_setup_req_t *req)
|
||||||
{
|
{
|
||||||
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ);
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_SETUP_REQ);
|
||||||
@@ -284,6 +296,8 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
|
|||||||
|
|
||||||
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||||
{
|
{
|
||||||
|
mac_rrc->f1_reset = f1_reset_du_initiated_direct;
|
||||||
|
mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_cu_initiated_direct;
|
||||||
mac_rrc->f1_setup_request = f1_setup_request_direct;
|
mac_rrc->f1_setup_request = f1_setup_request_direct;
|
||||||
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_direct;
|
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_direct;
|
||||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
|
mac_rrc->ue_context_setup_response = ue_context_setup_response_direct;
|
||||||
|
|||||||
@@ -53,6 +53,19 @@ static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const
|
|||||||
return nc;
|
return nc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void f1_reset_du_initiated_f1ap(const f1ap_reset_t *reset)
|
||||||
|
{
|
||||||
|
(void) reset;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f1_reset_acknowledge_cu_initiated_f1ap(const f1ap_reset_ack_t *ack)
|
||||||
|
{
|
||||||
|
MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_RESET_ACK);
|
||||||
|
f1ap_reset_ack_t *f1ap_msg = &F1AP_RESET_ACK(msg);
|
||||||
|
*f1ap_msg = *ack;
|
||||||
|
itti_send_msg_to_task(TASK_DU_F1, 0, msg);
|
||||||
|
}
|
||||||
|
|
||||||
static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
|
static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
|
||||||
{
|
{
|
||||||
@@ -275,6 +288,8 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
|
|||||||
|
|
||||||
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc)
|
||||||
{
|
{
|
||||||
|
mac_rrc->f1_reset = f1_reset_du_initiated_f1ap;
|
||||||
|
mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_cu_initiated_f1ap;
|
||||||
mac_rrc->f1_setup_request = f1_setup_request_f1ap;
|
mac_rrc->f1_setup_request = f1_setup_request_f1ap;
|
||||||
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_f1ap;
|
mac_rrc->gnb_du_configuration_update = gnb_du_configuration_update_f1ap;
|
||||||
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
|
mac_rrc->ue_context_setup_response = ue_context_setup_response_f1ap;
|
||||||
|
|||||||
@@ -690,6 +690,8 @@ typedef struct NR_bler_options {
|
|||||||
} NR_bler_options_t;
|
} NR_bler_options_t;
|
||||||
|
|
||||||
typedef struct nr_mac_rrc_ul_if_s {
|
typedef struct nr_mac_rrc_ul_if_s {
|
||||||
|
f1_reset_du_initiated_func_t f1_reset;
|
||||||
|
f1_reset_acknowledge_cu_initiated_func_t f1_reset_acknowledge;
|
||||||
f1_setup_request_func_t f1_setup_request;
|
f1_setup_request_func_t f1_setup_request;
|
||||||
gnb_du_configuration_update_t gnb_du_configuration_update;
|
gnb_du_configuration_update_t gnb_du_configuration_update;
|
||||||
ue_context_setup_response_func_t ue_context_setup_response;
|
ue_context_setup_response_func_t ue_context_setup_response;
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
|
|||||||
cu_up_ue_id,
|
cu_up_ue_id,
|
||||||
&DRB_configList,
|
&DRB_configList,
|
||||||
&security_parameters);
|
&security_parameters);
|
||||||
|
ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list);
|
||||||
if (f1inst >= 0) { /* we have F1(-U) */
|
if (f1inst >= 0) { /* we have F1(-U) */
|
||||||
teid_t dummy_teid = 0xffff; // we will update later with answer from DU
|
teid_t dummy_teid = 0xffff; // we will update later with answer from DU
|
||||||
in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
|
in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
#include "common/platform_types.h"
|
#include "common/platform_types.h"
|
||||||
#include "f1ap_messages_types.h"
|
#include "f1ap_messages_types.h"
|
||||||
|
|
||||||
|
typedef void (*f1_reset_cu_initiated_func_t)(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||||
|
typedef void (*f1_reset_acknowledge_du_initiated_func_t)(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack);
|
||||||
|
|
||||||
typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp);
|
typedef void (*f1_setup_response_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp);
|
||||||
typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
|
typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *fail);
|
||||||
typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id,
|
typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id,
|
||||||
|
|||||||
@@ -24,6 +24,18 @@
|
|||||||
#include "mac_rrc_dl.h"
|
#include "mac_rrc_dl.h"
|
||||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||||
|
|
||||||
|
static void f1_reset_cu_initiated_direct(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||||
|
{
|
||||||
|
(void)reset;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f1_reset_acknowledge_du_initiated_direct(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack)
|
||||||
|
{
|
||||||
|
(void)ack;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
|
static void f1_setup_response_direct(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
|
||||||
{
|
{
|
||||||
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
|
AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id);
|
||||||
@@ -80,6 +92,8 @@ static void dl_rrc_message_transfer_direct(sctp_assoc_t assoc_id, const f1ap_dl_
|
|||||||
|
|
||||||
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||||
{
|
{
|
||||||
|
mac_rrc->f1_reset = f1_reset_cu_initiated_direct;
|
||||||
|
mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_du_initiated_direct;
|
||||||
mac_rrc->f1_setup_response = f1_setup_response_direct;
|
mac_rrc->f1_setup_response = f1_setup_response_direct;
|
||||||
mac_rrc->f1_setup_failure = f1_setup_failure_direct;
|
mac_rrc->f1_setup_failure = f1_setup_failure_direct;
|
||||||
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct;
|
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct;
|
||||||
|
|||||||
@@ -24,6 +24,18 @@
|
|||||||
#include "mac_rrc_dl.h"
|
#include "mac_rrc_dl.h"
|
||||||
#include "nr_rrc_defs.h"
|
#include "nr_rrc_defs.h"
|
||||||
|
|
||||||
|
static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset)
|
||||||
|
{
|
||||||
|
(void)reset;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void f1_reset_acknowledge_du_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack)
|
||||||
|
{
|
||||||
|
(void)ack;
|
||||||
|
AssertFatal(false, "%s() not implemented yet\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
|
static void f1_setup_response_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_resp_t *resp)
|
||||||
{
|
{
|
||||||
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP);
|
MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_SETUP_RESP);
|
||||||
@@ -215,6 +227,8 @@ static void dl_rrc_message_transfer_f1ap(sctp_assoc_t assoc_id, const f1ap_dl_rr
|
|||||||
|
|
||||||
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
|
||||||
{
|
{
|
||||||
|
mac_rrc->f1_reset = f1_reset_cu_initiated_f1ap;
|
||||||
|
mac_rrc->f1_reset_acknowledge = f1_reset_acknowledge_du_initiated_f1ap;
|
||||||
mac_rrc->f1_setup_response = f1_setup_response_f1ap;
|
mac_rrc->f1_setup_response = f1_setup_response_f1ap;
|
||||||
mac_rrc->f1_setup_failure = f1_setup_failure_f1ap;
|
mac_rrc->f1_setup_failure = f1_setup_failure_f1ap;
|
||||||
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap;
|
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_f1ap;
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig,
|
|||||||
|
|
||||||
NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL;
|
NR_FeatureSets_t *fs = uecap ? uecap->featureSets : NULL;
|
||||||
if (fs) {
|
if (fs) {
|
||||||
const int bw_mhz = get_supported_bw_mhz(freq_range, scs, bw_size);
|
const int bw_mhz = get_supported_bw_mhz(freq_range, get_supported_band_index(scs, freq_range, bw_size));
|
||||||
// go through UL feature sets and look for one with current SCS
|
// go through UL feature sets and look for one with current SCS
|
||||||
for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) {
|
for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; i++) {
|
||||||
NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i];
|
NR_FeatureSetDownlinkPerCC_t *dl_fs = fs->featureSetsDownlinkPerCC->list.array[i];
|
||||||
|
|||||||
@@ -398,6 +398,8 @@ typedef struct neighbour_cell_configuration_s {
|
|||||||
} neighbour_cell_configuration_t;
|
} neighbour_cell_configuration_t;
|
||||||
|
|
||||||
typedef struct nr_mac_rrc_dl_if_s {
|
typedef struct nr_mac_rrc_dl_if_s {
|
||||||
|
f1_reset_cu_initiated_func_t f1_reset;
|
||||||
|
f1_reset_acknowledge_du_initiated_func_t f1_reset_acknowledge;
|
||||||
f1_setup_response_func_t f1_setup_response;
|
f1_setup_response_func_t f1_setup_response;
|
||||||
f1_setup_failure_func_t f1_setup_failure;
|
f1_setup_failure_func_t f1_setup_failure;
|
||||||
gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge;
|
gnb_du_configuration_update_ack_func_t gnb_du_configuration_update_acknowledge;
|
||||||
|
|||||||
@@ -2200,8 +2200,6 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertFatal(UE->as_security_active, "logic bug: security should be active when activating DRBs\n");
|
|
||||||
|
|
||||||
if (!UE->f1_ue_context_active)
|
if (!UE->f1_ue_context_active)
|
||||||
rrc_gNB_generate_UeContextSetupRequest(rrc, ue_context_p, nb_drb, drbs);
|
rrc_gNB_generate_UeContextSetupRequest(rrc, ue_context_p, nb_drb, drbs);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -335,13 +335,14 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,pdusessionTransfer );
|
ASN_STRUCT_FREE(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, pdusessionTransfer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink)
|
void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession_t *sessions, uint64_t ueAggMaxBitRateDownlink)
|
||||||
{
|
{
|
||||||
|
AssertFatal(UE->as_security_active, "logic bug: security should be active when activating DRBs\n");
|
||||||
e1ap_bearer_setup_req_t bearer_req = {0};
|
e1ap_bearer_setup_req_t bearer_req = {0};
|
||||||
|
|
||||||
e1ap_nssai_t cuup_nssai = {0};
|
e1ap_nssai_t cuup_nssai = {0};
|
||||||
@@ -813,7 +814,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
|
|||||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, UE->rnti, 0, 0, 0);
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
|
||||||
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id);
|
|
||||||
|
|
||||||
if (ue_context_p == NULL) {
|
if (ue_context_p == NULL) {
|
||||||
MessageDef *msg_fail_p = NULL;
|
MessageDef *msg_fail_p = NULL;
|
||||||
@@ -825,7 +825,25 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertFatal(UE->rrc_ue_id == msg->gNB_ue_ngap_id, "logic bug\n");
|
DevAssert(UE->rrc_ue_id == msg->gNB_ue_ngap_id);
|
||||||
|
LOG_I(NR_RRC, "UE %d: received PDU session setup request\n", UE->rrc_ue_id);
|
||||||
|
|
||||||
|
if (!UE->as_security_active) {
|
||||||
|
LOG_E(NR_RRC, "UE %d: no security context active for UE, rejecting PDU session setup request\n", UE->rrc_ue_id);
|
||||||
|
MessageDef *msg_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP);
|
||||||
|
ngap_pdusession_setup_resp_t *resp = &NGAP_PDUSESSION_SETUP_RESP(msg_resp);
|
||||||
|
resp->gNB_ue_ngap_id = UE->rrc_ue_id;
|
||||||
|
resp->nb_of_pdusessions_failed = msg->nb_pdusessions_tosetup;
|
||||||
|
for (int i = 0; i < resp->nb_of_pdusessions_failed; ++i) {
|
||||||
|
pdusession_failed_t *f = &resp->pdusessions_failed[i];
|
||||||
|
f->pdusession_id = msg->pdusession_setup_params[i].pdusession_id;
|
||||||
|
f->cause = NGAP_CAUSE_PROTOCOL;
|
||||||
|
f->cause_value = NGAP_CAUSE_PROTOCOL_MSG_NOT_COMPATIBLE_WITH_RECEIVER_STATE;
|
||||||
|
}
|
||||||
|
itti_send_msg_to_task(TASK_NGAP, instance, msg_resp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
UE->amf_ue_ngap_id = msg->amf_ue_ngap_id;
|
||||||
trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink);
|
trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+19
-14
@@ -643,6 +643,8 @@ void *trx_usrp_write_thread(void * arg){
|
|||||||
ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
|
ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T(T_USRP_TX_ANT0, T_INT(timestamp), T_BUFFER(buff_tx[0], nsamps*4));
|
||||||
|
|
||||||
if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps);
|
if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps);
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret );
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret );
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 );
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 );
|
||||||
@@ -869,7 +871,8 @@ int trx_usrp_set_gains(openair0_device *device,
|
|||||||
if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) {
|
if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) {
|
||||||
LOG_E(HW,"RX Gain 0 too high, reduce by %f dB\n",
|
LOG_E(HW,"RX Gain 0 too high, reduce by %f dB\n",
|
||||||
openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop());
|
openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop());
|
||||||
exit(-1);
|
int gain_diff = gain_range.stop() - (openair0_cfg[0].rx_gain[0] - openair0_cfg[0].rx_gain_offset[0]);
|
||||||
|
return gain_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]);
|
s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]);
|
||||||
@@ -1424,25 +1427,27 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) {
|
for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) {
|
||||||
if (i<openair0_cfg[0].rx_num_channels) {
|
openair0_config_t *cfg = &openair0_cfg[0];
|
||||||
s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i+choffset);
|
if (i < cfg->rx_num_channels) {
|
||||||
uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[i],
|
s->usrp->set_rx_rate(cfg->sample_rate, i + choffset);
|
||||||
openair0_cfg[0].tune_offset);
|
uhd::tune_request_t rx_tune_req(cfg->rx_freq[i], cfg->tune_offset);
|
||||||
s->usrp->set_rx_freq(rx_tune_req, i+choffset);
|
s->usrp->set_rx_freq(rx_tune_req, i+choffset);
|
||||||
set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust);
|
set_rx_gain_offset(cfg, i, bw_gain_adjust);
|
||||||
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i+choffset);
|
::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i+choffset);
|
||||||
// limit to maximum gain
|
// limit to maximum gain
|
||||||
double gain=openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i];
|
double gain = cfg->rx_gain[i] - cfg->rx_gain_offset[i];
|
||||||
if ( gain > gain_range.stop()) {
|
if ( gain > gain_range.stop()) {
|
||||||
LOG_E(HW,"RX Gain too high, lower by %f dB\n",
|
LOG_E(HW, "RX Gain too high, lower by %f dB\n", gain - gain_range.stop());
|
||||||
gain - gain_range.stop());
|
gain = gain_range.stop();
|
||||||
gain=gain_range.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s->usrp->set_rx_gain(gain,i+choffset);
|
s->usrp->set_rx_gain(gain,i+choffset);
|
||||||
LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i,
|
LOG_I(HW,
|
||||||
openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i],
|
"RX Gain %d %f (%f) => %f (max %f)\n",
|
||||||
openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop());
|
i,
|
||||||
|
cfg->rx_gain[i],
|
||||||
|
cfg->rx_gain_offset[i],
|
||||||
|
cfg->rx_gain[i] - cfg->rx_gain_offset[i],
|
||||||
|
gain_range.stop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user