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_scrambling.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/refsig.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
||||
)
|
||||
|
||||
@@ -1042,7 +1043,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.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_gold.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ptrs_nr.c
|
||||
|
||||
@@ -269,6 +269,14 @@ install_usrp_uhd_driver_from_source(){
|
||||
# - 3.15.0.0
|
||||
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"
|
||||
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
|
||||
# Tested that patch for the following versions:
|
||||
# - 4.0.0.0
|
||||
|
||||
@@ -9,6 +9,11 @@ ID = USRP_RX_ANT0
|
||||
GROUP = ALL:HEAVY
|
||||
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
|
||||
ID = ENB_PHY_UL_TICK
|
||||
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
|
||||
}
|
||||
|
||||
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.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
|
||||
// Notes:
|
||||
@@ -299,64 +309,30 @@ void check_ssb_raster(uint64_t freq, int band, int scs)
|
||||
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) {
|
||||
switch (bw_index) {
|
||||
case 0 :
|
||||
return 5; // 5MHz
|
||||
case 1 :
|
||||
return 10;
|
||||
case 2 :
|
||||
return 15;
|
||||
case 3 :
|
||||
return 20;
|
||||
case 4 :
|
||||
return 25;
|
||||
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);
|
||||
}
|
||||
int bandwidth_index_to_mhz[] = {5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 90, 100};
|
||||
AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
|
||||
"Bandwidth index %d is invalid\n",
|
||||
bw_index);
|
||||
return bandwidth_index_to_mhz[bw_index];
|
||||
} else {
|
||||
int bandwidth_index_to_mhz[] = {50, 100, 200, 400};
|
||||
AssertFatal(bw_index >= 0 && bw_index <= sizeofArray(bandwidth_index_to_mhz),
|
||||
"Bandwidth index %d is invalid\n",
|
||||
bw_index);
|
||||
return bandwidth_index_to_mhz[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
|
||||
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -224,8 +224,8 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports);
|
||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
||||
int get_nb_periods_per_frame(uint8_t tdd_period);
|
||||
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);
|
||||
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb);
|
||||
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 bw_index);
|
||||
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
|
||||
void get_samplerate_and_bw(int mu,
|
||||
int n_rb,
|
||||
@@ -248,6 +248,7 @@ int get_scan_ssb_first_sc(const double fc,
|
||||
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
|
||||
|
||||
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 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
|
||||
- Single and multiple DMRS symbols
|
||||
- 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 256 QAM
|
||||
* NR-CSIRS Generation of sequence at PHY
|
||||
@@ -79,7 +79,7 @@ These modes of operation are supported:
|
||||
- DMRS configuration type 1 and 2
|
||||
- Single and multiple DMRS symbols
|
||||
- PTRS support
|
||||
- Support for up to 2 RX antenna
|
||||
- Support for up to 4 RX antennas
|
||||
- Support for up to 2 layers
|
||||
- Support for 256 QAM
|
||||
* NR-PUCCH
|
||||
@@ -205,6 +205,7 @@ These modes of operation are supported:
|
||||
- F1 UE Context modification required
|
||||
- F1 UE Context release req/cmd/complete
|
||||
- F1 gNB CU configuration update
|
||||
- F1 Reset (handled at DU only, full reset only)
|
||||
- Interface with RRC
|
||||
- Interface with GTP-u (tunnel creation/handling for F1-U interface)
|
||||
- One CU(-CP) can handle multiple DUs
|
||||
@@ -237,7 +238,8 @@ These modes of operation are supported:
|
||||
## NR UE PHY Layer ##
|
||||
|
||||
* 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
|
||||
* Frequency offset estimation based on PSS and SSS
|
||||
* 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
|
||||
* Basic MAC to control PHY via UE FAPI P7 interface
|
||||
* PHY -> MAC indication (needs some improvement)
|
||||
* PHY -> MAC indication
|
||||
|
||||
## NR UE Higher Layers ##
|
||||
|
||||
@@ -314,19 +316,21 @@ These modes of operation are supported:
|
||||
- format 01 (C-RNTI)
|
||||
* UCI processing
|
||||
- ACK/NACK processing
|
||||
- Triggering periodic SR
|
||||
- CSI measurement reporting
|
||||
- Scheduling request procedures
|
||||
- CSI measurement reporting (periodic and aperiodic)
|
||||
* DLSCH scheduler
|
||||
- Configuration of fapi PDU according to DCI
|
||||
- HARQ procedures
|
||||
* ULSCH scheduler
|
||||
- Configuration of fapi PDU according to DCI
|
||||
- Buffer status reporting procedures
|
||||
- Logical channel prioritization of 'data from any logical channel'
|
||||
- UCI on PUSCH
|
||||
* NR-CSIRS scheduler
|
||||
- Scheduling of NR-CSIRS reception
|
||||
- Fill UCI for CSI measurement reporting
|
||||
* Scheduler procedures for SRS transmission
|
||||
- Periodic SRS transmission
|
||||
- Periodic and aperiodic SRS transmission
|
||||
* Bandwidth part (BWP) operation
|
||||
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
|
||||
|
||||
@@ -363,6 +367,7 @@ These modes of operation are supported:
|
||||
- RRCSetupRequest/RRCSetup/RRCSetupComplete
|
||||
- RRC Uplink/Downlink Information transfer carrying NAS messages transparently
|
||||
- RRC Reconfiguration/Reconfiguration complete
|
||||
- RRCReestablishmentRequest/RRC Reestablishment/Reestablishment complete
|
||||
- Support for master cell group configuration
|
||||
- Reception of UECapabilityEnquiry, encoding and transmission of UECapability
|
||||
* Interface with PDCP: configuration, DCCH and CCCH message handling
|
||||
|
||||
@@ -38,7 +38,7 @@ RUN /bin/sh oaienv && \
|
||||
./build_oai -w AW2SORI -t Ethernet
|
||||
|
||||
#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 TZ=Europe
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\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_AGC "Rx Gain control used for UE"
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters for LOG utility */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
|
||||
+38
-5
@@ -348,10 +348,31 @@ typedef struct {
|
||||
int rx_offset;
|
||||
} 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) {
|
||||
syncData_t *syncD = (syncData_t *)arg;
|
||||
PHY_VARS_NR_UE *UE = syncD->UE;
|
||||
UE->is_synchronized = 0;
|
||||
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
|
||||
|
||||
if (UE->target_Nid_cell != -1) {
|
||||
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
|
||||
// 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,
|
||||
"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n",
|
||||
hw_slot_offset,
|
||||
freq_offset,
|
||||
openair0_cfg[UE->rf_map.card].rx_gain[0],
|
||||
openair0_cfg[UE->rf_map.card].rx_freq[0],
|
||||
openair0_cfg[UE->rf_map.card].tx_freq[0]);
|
||||
cfg0->rx_gain[0] - cfg0->rx_gain_offset[0],
|
||||
cfg0->rx_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;
|
||||
} 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}, \
|
||||
{"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}, \
|
||||
{"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -87,6 +88,7 @@ typedef struct {
|
||||
int ldpc_offload_flag;
|
||||
unsigned int ntn_koffset;
|
||||
double ntn_ta_common;
|
||||
int agc;
|
||||
} nrUE_params_t;
|
||||
extern uint64_t get_nrUE_optmask(void);
|
||||
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;
|
||||
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;
|
||||
if (gNB->TX_AMP == 0)
|
||||
gNB->TX_AMP = AMP;
|
||||
// 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();
|
||||
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);
|
||||
|
||||
//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
|
||||
// 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_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);
|
||||
|
||||
@@ -330,7 +237,6 @@ int phy_init_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 Prx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
||||
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_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);
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
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
|
||||
* RU's txdataF/rxdataF, and the RU will free that */
|
||||
free_and_zero(common_vars->txdataF);
|
||||
@@ -518,7 +376,9 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -162,32 +162,6 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue)
|
||||
|
||||
// load the config file params
|
||||
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)
|
||||
@@ -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_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);
|
||||
|
||||
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" );
|
||||
// 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;
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ue->rx_gain_max[i] = 135;
|
||||
ue->rx_gain_med[i] = 128;
|
||||
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;
|
||||
|
||||
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_last[gNB_id] = 0;
|
||||
ue->bitrate[gNB_id] = 0;
|
||||
ue->total_received_bits[gNB_id] = 0;
|
||||
|
||||
}
|
||||
// init NR modulation lookup tables
|
||||
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/////////////////////////
|
||||
///////////
|
||||
|
||||
// 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;
|
||||
|
||||
// init TX buffers
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -300,51 +251,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
if (ue->sl_mode == 2)
|
||||
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));
|
||||
}
|
||||
|
||||
// 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
|
||||
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));
|
||||
csiim_vars[gNB_id] = malloc16_clear(sizeof(NR_UE_CSI_IM));
|
||||
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;
|
||||
|
||||
// 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->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 *));
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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 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);
|
||||
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_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]);
|
||||
}
|
||||
|
||||
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 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
|
||||
};
|
||||
|
||||
void nr_modulation(uint32_t *in,
|
||||
void nr_modulation(const uint32_t *in,
|
||||
uint32_t length,
|
||||
uint16_t mod_order,
|
||||
int16_t *out)
|
||||
@@ -120,8 +120,8 @@ void nr_modulation(uint32_t *in,
|
||||
uint16_t mask = ((1<<mod_order)-1);
|
||||
int32_t* nr_mod_table32;
|
||||
int32_t* out32 = (int32_t*) out;
|
||||
uint8_t* in_bytes = (uint8_t*) in;
|
||||
uint64_t* in64 = (uint64_t*) in;
|
||||
const uint8_t *in_bytes = (const uint8_t *)in;
|
||||
const uint64_t *in64 = (const uint64_t *)in;
|
||||
int64_t* out64 = (int64_t*) out;
|
||||
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
|
||||
*/
|
||||
|
||||
void nr_modulation(uint32_t *in,
|
||||
void nr_modulation(const uint32_t *in,
|
||||
uint32_t length,
|
||||
uint16_t mod_order,
|
||||
int16_t *out);
|
||||
|
||||
@@ -103,16 +103,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
//------------------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) {
|
||||
// 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,
|
||||
Ns,
|
||||
gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol],
|
||||
gold,
|
||||
pilot,
|
||||
(1000 + p),
|
||||
0,
|
||||
@@ -552,6 +554,12 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 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,
|
||||
*ptrsReOffset,
|
||||
*nb_rb,
|
||||
@@ -560,7 +568,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
symbol,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
(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],
|
||||
ptrs_re_symbol);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void nr_gen_ref_conj_symbols(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);
|
||||
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);
|
||||
|
||||
@@ -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,
|
||||
unsigned int Ns,
|
||||
unsigned int *nr_gold_pusch,
|
||||
const uint32_t *nr_gold_pusch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
@@ -120,9 +120,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
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 *nr_gold_pdsch,
|
||||
const unsigned int *nr_gold_pdsch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
@@ -170,9 +170,9 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
|
||||
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 *nr_gold_pdcch,
|
||||
const unsigned int *nr_gold_pdcch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
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 *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;
|
||||
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"
|
||||
|
||||
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
|
||||
}
|
||||
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic()
|
||||
|
||||
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
|
||||
{
|
||||
|
||||
@@ -25,35 +25,13 @@
|
||||
#define __NR_REFSIG__H__
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.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);
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
|
||||
int nr_pusch_dmrs_delta(uint8_t dmrs_config_type, unsigned short p);
|
||||
|
||||
int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
unsigned int Ns,
|
||||
unsigned int *nr_gold_pusch,
|
||||
const uint32_t *nr_gold_pusch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
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,
|
||||
uint16_t ofdm_symbol_size,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t *gold_seq,
|
||||
const uint32_t *gold_seq,
|
||||
int16_t *error_est,
|
||||
int32_t *ptrs_sc)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
|
||||
unsigned char symbol,
|
||||
uint16_t ofdm_symbol_size,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t *gold_seq,
|
||||
const uint32_t *gold_seq,
|
||||
int16_t *error_est,
|
||||
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__
|
||||
|
||||
#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.
|
||||
@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.
|
||||
@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 *nr_gold_pdcch,
|
||||
const unsigned int *nr_gold_pdcch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
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 *nr_gold_pdsch,
|
||||
const unsigned int *nr_gold_pdsch,
|
||||
c16_t *output,
|
||||
unsigned short p,
|
||||
unsigned char lp,
|
||||
unsigned short nb_pdsch_rb,
|
||||
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_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);
|
||||
|
||||
@@ -24,23 +24,6 @@
|
||||
|
||||
//#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,
|
||||
int32_t **dataF,
|
||||
const int16_t amp,
|
||||
@@ -74,7 +57,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
#endif
|
||||
|
||||
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))
|
||||
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)));
|
||||
@@ -82,19 +64,11 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint32_t beta = amp;
|
||||
nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp);
|
||||
|
||||
AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
AssertFatal(b != 0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
|
||||
int size, ports, kprime, lprime;
|
||||
int j[16], k_n[6], koverline[16], loverline[16];
|
||||
int found = 0;
|
||||
int fi = 0;
|
||||
|
||||
// implementation of table 7.4.1.5.3-1 of 38.211
|
||||
// lprime and kprime are the max value of l' and k'
|
||||
switch (csi_params->row) {
|
||||
@@ -581,14 +555,25 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
for (int lp = 0; lp <= lprime; lp++) {
|
||||
int symb = csi_params->symb_l0;
|
||||
nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16))
|
||||
nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
uint8_t row = csi_params->row;
|
||||
if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) {
|
||||
symb = csi_params->symb_l1;
|
||||
nr_modulation(nr_gold_csi_rs[symb + lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((csi_params->row == 13) || (csi_params->row == 16))
|
||||
nr_modulation(nr_gold_csi_rs[symb + 1], csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
|
||||
if ((row == 13) || (row == 16)) {
|
||||
const uint32_t *gold =
|
||||
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
|
||||
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,29 +41,13 @@
|
||||
//#define DEBUG_DCI
|
||||
//#define DEBUG_CHANNEL_CODING
|
||||
|
||||
void nr_pdcch_scrambling(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t scrambling_RNTI,
|
||||
uint32_t *out) {
|
||||
uint8_t reset;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
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);
|
||||
}
|
||||
static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint32_t scrambling_RNTI, uint32_t *out)
|
||||
{
|
||||
int roundedSz = ((size + 31) / 32);
|
||||
uint32_t *seq = gold_cache((scrambling_RNTI << 16) + Nid, roundedSz);
|
||||
LOG_D(NR_PHY_DCI, "PDCCH scrambling_RNTI %x \n", scrambling_RNTI);
|
||||
for (int i = 0; i < roundedSz; i++)
|
||||
out[i] = in[i] ^ seq[i];
|
||||
}
|
||||
|
||||
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*/
|
||||
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_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
||||
dci_idx = 0;
|
||||
@@ -131,8 +108,9 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
|
||||
|
||||
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
|
||||
const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb);
|
||||
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER,
|
||||
mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
if(dci_pdu->RNTI!=0xFFFF) {
|
||||
|
||||
@@ -32,12 +32,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx,
|
||||
int16_t amp,
|
||||
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);
|
||||
|
||||
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);
|
||||
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 xOverhead = 0;
|
||||
const int nb_re =
|
||||
@@ -251,9 +245,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
l_prime = 0;
|
||||
}
|
||||
/// DMRS QPSK modulation
|
||||
nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID],
|
||||
n_dmrs * DMRS_MOD_ORDER,
|
||||
DMRS_MOD_ORDER,
|
||||
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_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER,
|
||||
(int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_DLSCH
|
||||
@@ -276,7 +271,10 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
if(ptrs_symbol) {
|
||||
/* 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);
|
||||
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;
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
|
||||
//#define DEBUG_PBCH
|
||||
//#define DEBUG_PBCH_ENCODING
|
||||
@@ -148,22 +148,17 @@ static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
||||
uint16_t M,
|
||||
uint16_t length,
|
||||
uint8_t encoded,
|
||||
uint32_t unscrambling_mask) {
|
||||
uint8_t reset, offset;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
uint32_t unscrambling_mask)
|
||||
{
|
||||
uint32_t *pbch_e = pbch->pbch_e;
|
||||
reset = 1;
|
||||
// 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
|
||||
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
int goldIdx = (nushift * M + 31) / 32 - 1;
|
||||
// Scrambling is now done with offset (nushift*M)%32
|
||||
offset = (nushift*M)&0x1f;
|
||||
uint8_t offset = (nushift * M) & 0x1f;
|
||||
#ifdef DEBUG_PBCH_ENCODING
|
||||
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset);
|
||||
#endif
|
||||
@@ -178,29 +173,22 @@ static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
||||
if ((unscrambling_mask>>i)&1)
|
||||
pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<<i;
|
||||
else {
|
||||
if (((k+offset)&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
||||
if (((k + offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved >> i) & 1) ^ ((s[goldIdx] >> ((k + offset) & 0x1f)) & 1)) << i;
|
||||
k++; /// k increase only when payload bit is not special bit
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/// 2nd Scrambling
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (((i+offset)&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f));
|
||||
if (((i + offset) & 0x1f) == 0)
|
||||
goldIdx++;
|
||||
pbch_e[i >> 5] ^= (((s[goldIdx] >> ((i + offset) & 0x1f)) & 1) << (i & 0x1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_init_pbch_interleaver(uint8_t *interleaver) {
|
||||
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
|
||||
memset((void *)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
|
||||
#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
//#define DEBUG_PRS_MOD
|
||||
//#define DEBUG_PRS_MAP
|
||||
|
||||
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,
|
||||
int16_t amp,
|
||||
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;
|
||||
|
||||
// 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++) {
|
||||
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)+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* out)
|
||||
{
|
||||
uint32_t x1;
|
||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
||||
uint32_t s = lte_gold_generic(&x1, &x2, 1);
|
||||
for (int i = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++) {
|
||||
const int roundedSz = (size + 31) / 32;
|
||||
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||
for (int i = 0; i < roundedSz; i++) {
|
||||
simde__m256i c = ((simde__m256i*)in)[i];
|
||||
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]));
|
||||
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)
|
||||
{
|
||||
uint32_t x1;
|
||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
||||
uint32_t s = 0;
|
||||
|
||||
const int roundedSz = (size + 31) / 32;
|
||||
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
|
||||
uint8_t *s8=(uint8_t *)&s;
|
||||
simde__m128i *llr128 = (simde__m128i*)llr;
|
||||
s = lte_gold_generic(&x1, &x2, 1);
|
||||
|
||||
for (int i = 0, j = 0; i < ((size >> 5) + ((size & 0x1f) > 0 ? 1 : 0)); i++, j += 4) {
|
||||
for (int i = 0, j = 0; i < roundedSz; i++, j += 4) {
|
||||
uint8_t *s8 = (uint8_t *)(seq + i);
|
||||
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+2] = simde_mm_mullo_epi16(llr128[j+2],byte2m128i[s8[2]]);
|
||||
llr128[j+3] = simde_mm_mullo_epi16(llr128[j+3],byte2m128i[s8[3]]);
|
||||
s = lte_gold_generic(&x1, &x2, 0);
|
||||
llr128[j + 3] = simde_mm_mullo_epi16(llr128[j + 3], byte2m128i[s8[3]]);
|
||||
}
|
||||
#else
|
||||
uint8_t reset = 1;
|
||||
|
||||
for (uint32_t i=0; i<size; i++) {
|
||||
if ((i&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
if (((s>>(i&0x1f))&1)==1)
|
||||
if (seq[i / 32] & (1U << (i % 32)))
|
||||
llr[i] = -llr[i];
|
||||
}
|
||||
#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)
|
||||
{
|
||||
uint32_t x1;
|
||||
uint32_t x2 = (n_RNTI << 15) + (q << 14) + Nid;
|
||||
const int roundedSz = (size + 31) / 32;
|
||||
uint32_t *seq = gold_cache((n_RNTI << 15) + (q << 14) + Nid, roundedSz);
|
||||
simde__m128i *s128=(simde__m128i *)s2;
|
||||
|
||||
uint32_t s = lte_gold_generic(&x1, &x2, 1);
|
||||
uint8_t *s8=(uint8_t *)&s;
|
||||
|
||||
for (int i = 0; i < (size +31) >> 5; i++) {
|
||||
for (int i = 0; i < roundedSz; i++) {
|
||||
uint8_t *s8 = (uint8_t *)(seq + i);
|
||||
*s128++ = byte2m128i[s8[0]];
|
||||
*s128++ = byte2m128i[s8[1]];
|
||||
*s128++ = byte2m128i[s8[2]];
|
||||
*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);
|
||||
|
||||
int nr_generate_prs(uint32_t **nr_gold_prs,
|
||||
int nr_generate_prs(int slot,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
prs_config_t *prs_cfg,
|
||||
|
||||
@@ -63,11 +63,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
||||
#endif
|
||||
uint8_t f_ss=0,f_gh=0;
|
||||
*u=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;
|
||||
*v = 0;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_group_sequence_hopping] calculating u,v -> ");
|
||||
#endif
|
||||
@@ -77,41 +73,39 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
||||
}
|
||||
|
||||
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
|
||||
s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
|
||||
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
|
||||
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++) {
|
||||
while(minShift >= l) {
|
||||
s = lte_gold_generic(&x1, &c_init, 0);
|
||||
goldIdx++;
|
||||
l = l+32;
|
||||
}
|
||||
|
||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
||||
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1)));
|
||||
AssertFatal(goldIdx < 8 + (minShift + 31) / 32, "");
|
||||
int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32;
|
||||
f_gh = f_gh + ((1 << m) * ((uint8_t)((seq[goldIdx] >> tmpShift) & 1)));
|
||||
minShift ++;
|
||||
}
|
||||
|
||||
f_gh = f_gh%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;*/
|
||||
f_ss = n_id % 30;
|
||||
}
|
||||
|
||||
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
|
||||
s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
|
||||
uint32_t c_init = (1 << 5) * floor(n_id / 30) + (n_id % 30); // we initialize c_init to calculate u,v
|
||||
int goldIdx = 0;
|
||||
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) {
|
||||
s = lte_gold_generic(&x1, &c_init, 0);
|
||||
goldIdx++;
|
||||
l = l+32;
|
||||
}
|
||||
|
||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
||||
*v = (uint8_t)((s>>tmpShift)&1);
|
||||
// TS 38.211 Subclause 5.2.1
|
||||
uint32_t *seq = gold_cache(c_init, goldIdx + 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!!!
|
||||
}
|
||||
|
||||
@@ -139,28 +133,27 @@ double nr_cyclic_shift_hopping(uint32_t n_id,
|
||||
double alpha = 0.5235987756;
|
||||
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;
|
||||
int l = 32, minShift = (14*8*nr_slot_tx )+ 8*(lnormal+lprime);
|
||||
int tmpShift =0;
|
||||
int l = 32, minShift = (14 * 8 * nr_slot_tx) + 8 * (lnormal + lprime);
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init);
|
||||
#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++) {
|
||||
while(minShift >= l) {
|
||||
s = lte_gold_generic(&x1, &c_init, 0);
|
||||
goldIdx++;
|
||||
l = l+32;
|
||||
}
|
||||
|
||||
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
|
||||
AssertFatal(goldIdx < 8 + (minShift + 31) / 32, "");
|
||||
int tmpShift = (minShift & ((1 << 5) - 1)); // minShift%32;
|
||||
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!!!)
|
||||
// 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
|
||||
printf("n_cs=%d -> %lf\n",n_cs,alpha);
|
||||
#endif
|
||||
|
||||
@@ -1145,26 +1145,21 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
|
||||
// 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;
|
||||
// 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)
|
||||
% (1U << 31); // c_init calculation according to TS38.211 subclause
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
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);
|
||||
#endif
|
||||
int reset = 1;
|
||||
for (int i=0; i<=(pucch_pdu->prb_start>>2); i++) {
|
||||
sGold = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
for (int group = 0; group < ngroup; group++) {
|
||||
uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2);
|
||||
for (int group = 0, goldIdx = pucch_pdu->prb_start / 4; group < ngroup; group++) {
|
||||
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
||||
// non-coherent combining across groups
|
||||
uint8_t *sGold8 = (uint8_t *)&sGold[goldIdx];
|
||||
simde__m64 dmrs_re = byte2m64_re[sGold8[(group & 1) << 1]];
|
||||
int16_t *dmrs_re16 = (int16_t *)&dmrs_re;
|
||||
simde__m64 dmrs_im = byte2m64_im[sGold8[(group & 1) << 1]];
|
||||
@@ -1237,22 +1232,22 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
} //aa
|
||||
|
||||
if ((group & 1) == 1)
|
||||
sGold = lte_gold_generic(&x1, &x2, 0);
|
||||
goldIdx++;
|
||||
} // group
|
||||
} // symb
|
||||
|
||||
uint32_t x1, x2, sGold = 0;
|
||||
// unscrambling
|
||||
x2 = ((pucch_pdu->rnti)<<15)+pucch_pdu->data_scrambling_id;
|
||||
sGold = lte_gold_generic(&x1, &x2, 1);
|
||||
uint8_t *sGold8 = (uint8_t *)&sGold;
|
||||
uint32_t x2 = ((pucch_pdu->rnti) << 15) + pucch_pdu->data_scrambling_id;
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("x2 %x\n", x2);
|
||||
#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++) {
|
||||
simde__m64 c_re[4], c_im[4];
|
||||
int re_off=0;
|
||||
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++) {
|
||||
c_re[z] = byte2m64_re[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]);
|
||||
#endif
|
||||
}
|
||||
sGold = lte_gold_generic(&x1, &x2, 0);
|
||||
goldIdx++;
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
@@ -90,8 +90,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
|
||||
memset(chF_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;
|
||||
uint32_t **nr_gold_prs = ue->nr_gold_prs[gNB_id][rsc_id][slot_prs];
|
||||
int slot_prs =
|
||||
(proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame;
|
||||
|
||||
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
|
||||
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;
|
||||
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;
|
||||
if (prs_cfg->CombSize == 2) {
|
||||
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");
|
||||
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)+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,
|
||||
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,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
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);
|
||||
|
||||
gold_seq = nr_gold_pbch[n_hf][ssb_index];
|
||||
gold_seq = nr_gold_pbch(fp->Lmax, Nid, n_hf, ssb_index);
|
||||
lastsymbol = 2;
|
||||
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 rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
{
|
||||
|
||||
int Ns = proc->nr_slot_rx;
|
||||
int gNB_id = proc->gNB_id;
|
||||
int slot = proc->nr_slot_rx;
|
||||
unsigned char aarx;
|
||||
unsigned short k;
|
||||
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;
|
||||
|
||||
#ifdef DEBUG_PDCCH
|
||||
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n",
|
||||
gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol);
|
||||
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,
|
||||
slot,
|
||||
symbol);
|
||||
#endif
|
||||
|
||||
#if CH_INTERP
|
||||
@@ -880,19 +883,14 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
|
||||
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;
|
||||
if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
||||
dmrs_ref = BWPStart;
|
||||
// generate pilot
|
||||
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
|
||||
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++) {
|
||||
|
||||
@@ -1422,19 +1420,22 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
c16_t rxdataF[][rxdataFsize],
|
||||
uint32_t *nvar)
|
||||
{
|
||||
int gNB_id = proc->gNB_id;
|
||||
int Ns = proc->nr_slot_rx;
|
||||
const int ch_offset = ue->frame_parms.ofdm_symbol_size * symbol;
|
||||
const int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol;
|
||||
// int gNB_id = proc->gNB_id;
|
||||
int slot = proc->nr_slot_rx;
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
const int ch_offset = fp->ofdm_symbol_size * symbol;
|
||||
const int symbol_offset = fp->ofdm_symbol_size * symbol;
|
||||
|
||||
#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,
|
||||
ch_offset,
|
||||
symbol_offset,
|
||||
ue->frame_parms.ofdm_symbol_size,
|
||||
ue->frame_parms.Ncp,
|
||||
Ns,
|
||||
fp->ofdm_symbol_size,
|
||||
fp->Ncp,
|
||||
slot,
|
||||
bwp_start_subcarrier,
|
||||
symbol);
|
||||
#endif
|
||||
@@ -1442,20 +1443,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
// generate pilot for gNB port number 1000+p
|
||||
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)));
|
||||
// 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};
|
||||
|
||||
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
|
||||
printf("\n============================================\n");
|
||||
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
|
||||
|
||||
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];
|
||||
memset(dl_ch, 0, sizeof(*dl_ch) * ue->frame_parms.ofdm_symbol_size);
|
||||
c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
|
||||
memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size);
|
||||
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
|
||||
NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms,
|
||||
@@ -1478,7 +1473,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
nvar);
|
||||
|
||||
} 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,
|
||||
&pilot[4 * rb_offset],
|
||||
dl_ch,
|
||||
@@ -1490,24 +1485,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
nvar);
|
||||
|
||||
} else if (config_type == NFAPI_NR_DMRS_TYPE1) {
|
||||
NFAPI_NR_DMRS_TYPE1_average_prb(&ue->frame_parms,
|
||||
rxF,
|
||||
&pilot[6 * rb_offset],
|
||||
dl_ch,
|
||||
bwp_start_subcarrier,
|
||||
nb_rb_pdsch);
|
||||
NFAPI_NR_DMRS_TYPE1_average_prb(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch);
|
||||
|
||||
} else {
|
||||
NFAPI_NR_DMRS_TYPE2_average_prb(&ue->frame_parms,
|
||||
rxF,
|
||||
&pilot[4 * rb_offset],
|
||||
dl_ch,
|
||||
bwp_start_subcarrier,
|
||||
nb_rb_pdsch);
|
||||
NFAPI_NR_DMRS_TYPE2_average_prb(fp, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_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 (uint8_t idxI = 0; idxI < 8; idxI++) {
|
||||
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 */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
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,
|
||||
*ptrsReOffset,
|
||||
*nb_rb,
|
||||
@@ -1646,8 +1633,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
||||
symbol,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
(int16_t *)(rxdataF_comp[0][aarx] + symbol * nb_re_pdsch),
|
||||
ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][nscid],
|
||||
(int16_t*)&phase_per_symbol[symbol],
|
||||
gold,
|
||||
(int16_t *)&phase_per_symbol[symbol],
|
||||
&ptrs_re_symbol[symbol]);
|
||||
}
|
||||
}// 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,
|
||||
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,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
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,
|
||||
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,
|
||||
uint8_t gNB_index,
|
||||
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);
|
||||
|
||||
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,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
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:
|
||||
// - 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)
|
||||
@@ -183,52 +227,27 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
|
||||
{
|
||||
int k_start = 56;
|
||||
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);
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
|
||||
if (ue->frame_parms.half_frame_bit)
|
||||
symbol_offset += (ue->frame_parms.slots_per_frame>>1)*ue->frame_parms.symbols_per_slot;
|
||||
int symbol_offset = nr_get_ssb_start_symbol(fp, ssb_index);
|
||||
|
||||
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);
|
||||
int nb_re = 0;
|
||||
openair0_config_t *cfg0 = &openair0_cfg[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];
|
||||
|
||||
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__,
|
||||
LOG_D(PHY,
|
||||
"[UE %d] ssb %d SS-RSRP: %d dBm/RE (%d dB/RE)\n",
|
||||
ue->Mod_id,
|
||||
ssb_index,
|
||||
ue->measurements.ssb_rsrp_dBm[ssb_index],
|
||||
rsrp);
|
||||
rsrp_db_per_re);
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// PSBCH RSRP calculations according to 38.215 section 5.1.22
|
||||
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
// This function implements:
|
||||
// - 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,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
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])
|
||||
- dB_fixed(fp->ofdm_symbol_size);
|
||||
|
||||
int adjust_rxgain = TARGET_RX_POWER - psbch_rx->rsrp_dB_per_RE;
|
||||
|
||||
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,
|
||||
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 "common/utils/nr/nr_common.h"
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "T.h"
|
||||
@@ -655,25 +656,13 @@ static void nr_pdcch_unscrambling(c16_t *e_rx,
|
||||
uint16_t pdcch_DMRS_scrambling_id,
|
||||
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;
|
||||
reset = 1;
|
||||
// x1 is set in first call to lte_gold_generic
|
||||
n_id = pdcch_DMRS_scrambling_id;
|
||||
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);
|
||||
uint16_t n_id = pdcch_DMRS_scrambling_id;
|
||||
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
|
||||
LOG_D(NR_PHY_DCI, "PDCCH Unscrambling: scrambling_RNTI %x\n", rnti);
|
||||
int16_t *ptr = &e_rx[0].r;
|
||||
for (i = 0; i < length; i++) {
|
||||
if ((i & 0x1f) == 0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
if (((s >> (i % 32)) & 1) == 1)
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (seq[i / 32] & (1UL << (i % 32)))
|
||||
z2[i] = -ptr[i];
|
||||
else
|
||||
z2[i] = ptr[i];
|
||||
|
||||
@@ -71,7 +71,6 @@ static bool nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
|
||||
int *ssb_index,
|
||||
int *symbol_offset,
|
||||
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 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,
|
||||
Nid_cell,
|
||||
ssb_start_subcarrier,
|
||||
nr_gold_pbch_ref[hf][l],
|
||||
nr_gold_pbch(frame_parms->Lmax, Nid_cell, hf, l),
|
||||
rxdataF);
|
||||
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++)
|
||||
nr_pbch_channel_estimation(frame_parms,
|
||||
NULL,
|
||||
nr_gold_pbch_ref,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
@@ -277,9 +275,7 @@ void nr_scan_ssb(void *arg)
|
||||
#endif
|
||||
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
|
||||
nr_gold_pbch(nr_gold_pbch_ref, ssbInfo->nidCell, fp->Lmax);
|
||||
ssbInfo->syncRes.cell_detected = nr_pbch_detection(ssbInfo->proc,
|
||||
ssbInfo->fp,
|
||||
ssbInfo->nidCell,
|
||||
@@ -289,8 +285,12 @@ void nr_scan_ssb(void *arg)
|
||||
&ssbInfo->ssbIndex,
|
||||
&ssbInfo->symbolOffset,
|
||||
&ssbInfo->pbchResult,
|
||||
nr_gold_pbch_ref,
|
||||
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;
|
||||
ue->symbol_offset = res.symbolOffset;
|
||||
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.
|
||||
@@ -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.
|
||||
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
|
||||
// computing the offset wrt the beginning of the frame
|
||||
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
|
||||
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
|
||||
if (res.ssbOffset < sync_pos_frame) {
|
||||
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;
|
||||
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
|
||||
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;) {
|
||||
nr_pbch_channel_estimation(frame_parms,
|
||||
&UE->SL_UE_PHY_PARAMS,
|
||||
UE->nr_gold_pbch,
|
||||
rxdataF_sz,
|
||||
dl_ch_estimates,
|
||||
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->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;
|
||||
result.rx_offset = sync_params->rx_offset;
|
||||
|
||||
@@ -33,12 +33,11 @@
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/LTE_REFSIG/lte_refsig.h"
|
||||
#include "PHY/INIT/nr_phy_init.h"
|
||||
#include "openair1/SCHED_NR_UE/defs.h"
|
||||
#include <openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h>
|
||||
#include <openair1/PHY/TOOLS/phy_scope_interface.h>
|
||||
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
|
||||
//#define DEBUG_PBCH
|
||||
//#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_interleaved)
|
||||
{
|
||||
uint8_t reset, offset;
|
||||
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
|
||||
|
||||
uint32_t *seq = gold_cache(Nid, (nushift * M + length + 31) / 32); // this is c_init
|
||||
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
|
||||
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
int idxGold = (nushift * M + 31) / 32 - 1;
|
||||
|
||||
// Scrambling is now done with offset (nushift*M)%32
|
||||
offset = (nushift*M)&0x1f;
|
||||
|
||||
for (int i=0; i<length; i++) {
|
||||
/*if (((i+offset)&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}*/
|
||||
int offset = (nushift * M) & 0x1f;
|
||||
uint8_t k = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (bitwise) {
|
||||
if (((k+offset)&0x1f)==0 && (!((unscrambling_mask>>i)&1))) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
*pbch_a_interleaved ^= ((unscrambling_mask>>i)&1)? ((pbch_a_prime>>i)&1)<<i : (((pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
||||
if (((k + offset) & 0x1f) == 0 && (!((unscrambling_mask >> i) & 1)))
|
||||
idxGold++;
|
||||
*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;
|
||||
k += (!((unscrambling_mask>>i)&1));
|
||||
#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,
|
||||
(!((unscrambling_mask>>i)&1)));
|
||||
#endif
|
||||
} else {
|
||||
if (((i+offset)&0x1f)==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
if (((i + offset) & 0x1f) == 0)
|
||||
idxGold++;
|
||||
|
||||
if (((s>>((i+offset)&0x1f))&1)==1)
|
||||
if (seq[idxGold] & (1UL << ((i + offset) % 32)))
|
||||
demod_pbch_e[i] = -demod_pbch_e[i];
|
||||
|
||||
#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)
|
||||
{
|
||||
uint8_t reset, b_idx;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0, temp_out = 0;
|
||||
|
||||
reset = 1;
|
||||
x2 = (n_RNTI<<15) + Nid;
|
||||
|
||||
uint32_t *seq = gold_cache((n_RNTI << 15) + Nid, (size + 31) / 32);
|
||||
for (int i=0; i<size; i++) {
|
||||
b_idx = i&0x1f;
|
||||
if (b_idx==0) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
if (i)
|
||||
out++;
|
||||
}
|
||||
int idx = i / 32;
|
||||
int b_idx = i % 32;
|
||||
if (in[i]==NR_PUSCH_x)
|
||||
*out ^= 1<<b_idx;
|
||||
out[idx] ^= 1 << b_idx;
|
||||
else if (in[i]==NR_PUSCH_y){
|
||||
if (b_idx!=0)
|
||||
*out ^= (*out & (1<<(b_idx-1)))<<1;
|
||||
if (b_idx)
|
||||
out[idx] ^= (out[idx] & (1 << (b_idx - 1))) << 1;
|
||||
else{
|
||||
|
||||
temp_out = *(out-1);
|
||||
*out ^= temp_out>>31;
|
||||
|
||||
uint32_t temp_out = out[idx - 1];
|
||||
out[idx] ^= temp_out >> 31;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -240,12 +228,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
/////////////////////////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);
|
||||
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
|
||||
// Perform this on gold sequence, not required when SC FDMA operation is done,
|
||||
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,
|
||||
DMRS_MOD_ORDER,
|
||||
(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)) {
|
||||
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 "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "openair1/PHY/NR_REFSIG/nr_refsig.h"
|
||||
|
||||
#include "T.h"
|
||||
//#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) {
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
int i;
|
||||
uint8_t c;
|
||||
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)
|
||||
{
|
||||
// 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));
|
||||
x2 = ((rnti)<<15)+n_id;
|
||||
const int roundedSz = (M_bit + 31) / 32;
|
||||
uint32_t *seq = gold_cache((rnti << 15) + n_id, roundedSz);
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit);
|
||||
#endif
|
||||
|
||||
uint8_t *btildep=btilde;
|
||||
int M_bit2=M_bit > 31 ? 32 : (M_bit&31), M_bit3=M_bit;
|
||||
uint32_t B;
|
||||
for (int iprime=0;iprime<=(M_bit>>5);iprime++,btildep+=32) {
|
||||
s = lte_gold_generic(&x1, &x2, (iprime==0) ? 1 : 0);
|
||||
B=((uint32_t*)B64)[iprime];
|
||||
for (int n=0;n<M_bit2;n+=8)
|
||||
LOG_D(PHY,"PUCCH2 encoded %d : %d,%d,%d,%d,%d,%d,%d,%d\n",n,
|
||||
(B>>n)&1,
|
||||
(B>>(n+1))&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);
|
||||
uint8_t *btildep = btilde;
|
||||
uint32_t *B32 = (uint32_t *)B64;
|
||||
|
||||
for (int iprime = 0; iprime < roundedSz; iprime++, btildep += 32) {
|
||||
const uint32_t s = seq[iprime];
|
||||
const uint32_t B = B32[iprime];
|
||||
LOG_D(PHY, "PUCCH2 encoded: %02x\n", B);
|
||||
int M_bit2 = iprime == M_bit / 32 ? M_bit % 32 : 32;
|
||||
for (int i = 0; i < M_bit2; i++) {
|
||||
uint8_t c = (uint8_t)((s >> i) & 1);
|
||||
btildep[i] = (((B>>i)&1) ^ c);
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
M_bit3-=32;
|
||||
M_bit2=M_bit3 > 31 ? 32 : (M_bit3&31);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
|
||||
#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
|
||||
*/
|
||||
// int32_t *txptr;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
int i=0;
|
||||
int m=0;
|
||||
int outSample = 0;
|
||||
uint8_t startingSymbolIndex = pucch_pdu->start_symbol_index;
|
||||
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;
|
||||
temp_x2 *= 14UL * nr_slot_tx + l + startingSymbolIndex + 1;
|
||||
temp_x2 *= 2UL * pucch_pdu->dmrs_scrambling_id + 1;
|
||||
x2 = (temp_x2 + 2UL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31);
|
||||
|
||||
int reset = 1;
|
||||
for (int ii=0; ii<=(startingPRB>>2); ii++) {
|
||||
s = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
m = 0;
|
||||
temp_x2 = (temp_x2 + 2ULL * pucch_pdu->dmrs_scrambling_id) % (1UL << 31);
|
||||
uint idxGold = startingPRB >> 2;
|
||||
uint32_t *seq = gold_cache(temp_x2, idxGold + pucch_pdu->prb_size);
|
||||
int m = 0;
|
||||
for (int rb=0; rb<pucch_pdu->prb_size; rb++) {
|
||||
//startingPRB = startingPRB + rb;
|
||||
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
|
||||
txdataF[0][re_offset] = d[i + k];
|
||||
txdataF[0][re_offset] = d[outSample + k];
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf(
|
||||
"\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
|
||||
txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m)) & 1)))));
|
||||
txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m + 1)) & 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)((seq[idxGold] >> (2 * m + 1)) & 1)))));
|
||||
m++;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf(
|
||||
@@ -821,10 +802,10 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
||||
re_offset++;
|
||||
}
|
||||
|
||||
i+=8;
|
||||
outSample += 8;
|
||||
|
||||
if ((m&((1<<4)-1))==0) {
|
||||
s = lte_gold_generic(&x1, &x2, 0);
|
||||
if (m % 16 == 0) {
|
||||
idxGold++;
|
||||
m = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,24 +606,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
// PUCCH0 Look-up table for cyclic-shifts
|
||||
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
|
||||
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
|
||||
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
|
||||
int prach_energy_counter;
|
||||
|
||||
int pdcch_gold_init;
|
||||
int pdsch_gold_init[2];
|
||||
int pusch_gold_init[2];
|
||||
|
||||
int ap_N1;
|
||||
int ap_N2;
|
||||
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];
|
||||
|
||||
#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
|
||||
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];
|
||||
|
||||
// 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_p_received[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 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_mtch_received[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_mcch_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_MIB;
|
||||
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];
|
||||
|
||||
// Gain change required for automation RX gain change
|
||||
int adjust_rxgain;
|
||||
|
||||
// Sidelink parameters
|
||||
sl_nr_sidelink_mode_t sl_mode;
|
||||
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
|
||||
@@ -645,6 +623,7 @@ typedef struct {
|
||||
fapiPbch_t pbchResult;
|
||||
int pssCorrPeakPower;
|
||||
int pssCorrAvgPower;
|
||||
int adjust_rxgain;
|
||||
} nr_ue_ssb_scan_t;
|
||||
|
||||
typedef struct nr_phy_data_tx_s {
|
||||
|
||||
@@ -122,8 +122,6 @@ typedef struct {
|
||||
} nr_srs_info_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t csi_gold_init;
|
||||
uint32_t ***nr_gold_csi_rs;
|
||||
uint8_t csi_rs_generated_signal_bits;
|
||||
int32_t **csi_rs_generated_signal;
|
||||
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_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
|
||||
//#define MAX_RF_GAIN 160
|
||||
//#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_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
if (fp->Lmax == 4)
|
||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_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],
|
||||
int hf = fp->Lmax == 4 ? n_hf : 0;
|
||||
nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7),
|
||||
&txdataF[0][txdataF_offset],
|
||||
gNB->TX_AMP,
|
||||
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;
|
||||
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);
|
||||
nr_pbch_channel_estimation(&ue->frame_parms,
|
||||
NULL,
|
||||
ue->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
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);
|
||||
}
|
||||
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;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
|
||||
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);
|
||||
nr_pbch_channel_estimation(fp,
|
||||
&ue->SL_UE_PHY_PARAMS,
|
||||
ue->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -840,18 +840,6 @@ int main(int argc, char **argv)
|
||||
|
||||
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);
|
||||
UE_mac = get_mac_inst(0);
|
||||
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;
|
||||
else fp->nr_band = 78;
|
||||
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);
|
||||
|
||||
fp->ofdm_offset_divisor = UINT_MAX;
|
||||
nr_init_frame_parms(gNB_config, fp);
|
||||
@@ -618,8 +619,6 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax);
|
||||
|
||||
processingData_L1tx_t msgDataTx;
|
||||
// generate signal
|
||||
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,
|
||||
&UE->SL_UE_PHY_PARAMS,
|
||||
UE->nr_gold_pbch,
|
||||
estimateSz,
|
||||
dl_ch_estimates,
|
||||
dl_ch_estimates_time,
|
||||
|
||||
@@ -703,11 +703,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
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
|
||||
nr_l2_init_ue(1);
|
||||
NR_UE_MAC_INST_t* UE_mac = get_mac_inst(0);
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
/* To setup F1 at DU */
|
||||
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*/
|
||||
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)
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
|
||||
#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_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_resp
|
||||
#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_UE_ID 1024
|
||||
|
||||
#define F1AP_MAX_NO_OF_INDIVIDUAL_CONNECTIONS_TO_RESET 65536
|
||||
|
||||
typedef net_ip_address_t f1ap_net_ip_address_t;
|
||||
|
||||
typedef struct f1ap_net_config_t {
|
||||
@@ -534,4 +539,29 @@ typedef struct f1ap_lost_connection_t {
|
||||
int dummy;
|
||||
} 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_ */
|
||||
|
||||
@@ -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_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 {
|
||||
/* Unique pdusession_id for the UE. */
|
||||
uint8_t pdusession_id;
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
#include "f1ap_itti_messaging.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");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
/*
|
||||
* Reset
|
||||
*/
|
||||
int CU_send_RESET(sctp_assoc_t assoc_id, 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_send_RESET(sctp_assoc_t assoc_id, const f1ap_reset_t *reset);
|
||||
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_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
|
||||
|
||||
@@ -160,6 +160,10 @@ void *F1AP_CU_task(void *arg) {
|
||||
&received_msg->ittiMsg.sctp_data_ind);
|
||||
break;
|
||||
|
||||
case F1AP_RESET_ACK:
|
||||
CU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_SETUP_RESP: // from rrc
|
||||
CU_send_F1_SETUP_RESPONSE(assoc_id,
|
||||
&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)
|
||||
{
|
||||
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) {
|
||||
AssertFatal(1==0,"Not implemented yet\n");
|
||||
int DU_send_RESET_ACKNOWLEDGE(sctp_assoc_t assoc_id, const f1ap_reset_ack_t *ack)
|
||||
{
|
||||
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");
|
||||
}
|
||||
@@ -223,6 +324,8 @@ static F1AP_GNB_DU_System_Information_t *encode_system_info(const f1ap_gnb_du_sy
|
||||
// SETUP REQUEST
|
||||
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};
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
* Reset
|
||||
*/
|
||||
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(sctp_assoc_t assoc_id, F1AP_Reset_t *Reset);
|
||||
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, 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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -134,6 +134,10 @@ void *F1AP_DU_task(void *arg) {
|
||||
DUuniqInstance = gtpInst;
|
||||
} break;
|
||||
|
||||
case F1AP_RESET_ACK:
|
||||
DU_send_RESET_ACKNOWLEDGE(assoc_id, &F1AP_RESET_ACK(msg));
|
||||
break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(assoc_id,
|
||||
&F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(msg));
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
/* Handlers matrix. Only f1 related procedure present here */
|
||||
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 */
|
||||
{0, 0, 0}, /* ErrorIndication */
|
||||
{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;
|
||||
int max_fb_time;
|
||||
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;
|
||||
|
||||
// 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;
|
||||
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
|
||||
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);
|
||||
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) *
|
||||
(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;
|
||||
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);
|
||||
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||
|
||||
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
|
||||
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->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
|
||||
|
||||
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);
|
||||
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||
|
||||
cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
|
||||
*scc->ssbSubcarrierSpacing,
|
||||
@@ -284,9 +289,10 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
|
||||
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,
|
||||
int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
mac->frequency_range,
|
||||
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;
|
||||
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->BWPSize = NRRIV2BW(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) {
|
||||
mac->sc_info.initial_ul_BWPSize = bwp->BWPSize;
|
||||
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");
|
||||
|
||||
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 =
|
||||
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,
|
||||
frame_type_t frame_type,
|
||||
frequency_range_t frequency_range,
|
||||
int channel_bandwidth_index,
|
||||
int Qm,
|
||||
bool powerBoostPi2BPSK,
|
||||
int scs,
|
||||
@@ -256,7 +257,7 @@ float nr_get_Pcmax(int p_Max,
|
||||
int n_prbs,
|
||||
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);
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ void init_RA(NR_UE_MAC_INST_t *mac,
|
||||
mac->nr_band,
|
||||
mac->frame_type,
|
||||
mac->frequency_range,
|
||||
mac->current_UL_BWP->channel_bandwidth,
|
||||
2,
|
||||
false,
|
||||
prach_scs,
|
||||
|
||||
@@ -66,16 +66,16 @@ static int get_deltatf(uint16_t nb_of_prbs,
|
||||
int O_UCI);
|
||||
|
||||
// ∆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 ((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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +168,7 @@ float nr_get_Pcmax(int p_Max,
|
||||
uint16_t nr_band,
|
||||
frame_type_t frame_type,
|
||||
frequency_range_t frequency_range,
|
||||
int channel_bandwidth,
|
||||
int Qm,
|
||||
bool powerBoostPi2BPSK,
|
||||
int scs,
|
||||
@@ -197,7 +198,7 @@ float nr_get_Pcmax(int p_Max,
|
||||
int delta_TC = 0;
|
||||
|
||||
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 delta_rx_SRS = 0; // TODO for SRS
|
||||
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
|
||||
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;
|
||||
} else {
|
||||
// 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) {
|
||||
int band_index = get_supported_band_index(nr_band > 256 ? FR2 : FR1, scs, N_RB_UL);
|
||||
float nr_get_Pcmin(int bandwidth_index) {
|
||||
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
|
||||
};
|
||||
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
|
||||
@@ -341,6 +347,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
|
||||
mac->nr_band,
|
||||
mac->frame_type,
|
||||
mac->frequency_range,
|
||||
current_UL_BWP->channel_bandwidth,
|
||||
2,
|
||||
false,
|
||||
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,
|
||||
1,
|
||||
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);
|
||||
|
||||
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->frame_type,
|
||||
mac->frequency_range,
|
||||
mac->current_UL_BWP->channel_bandwidth,
|
||||
qm,
|
||||
false,
|
||||
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
|
||||
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;
|
||||
|
||||
|
||||
@@ -44,24 +44,27 @@ TEST(test_pcmax, test_mpr)
|
||||
int nr_band = 20;
|
||||
float expected_power = 23 - (1.5 / 2);
|
||||
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
|
||||
prb_start = 0;
|
||||
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
|
||||
N_RB_UL = 78;
|
||||
nr_band = 28;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -70,11 +73,12 @@ TEST(test_pcmax, test_pucch_max_power)
|
||||
int prb_start = 0;
|
||||
int N_RB_UL = 51; // 10Mhz
|
||||
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
|
||||
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)
|
||||
@@ -108,6 +112,7 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
||||
mac.nr_band,
|
||||
mac.frame_type,
|
||||
FR1,
|
||||
current_UL_BWP.channel_bandwidth,
|
||||
2,
|
||||
false,
|
||||
current_UL_BWP.scs,
|
||||
@@ -177,9 +182,9 @@ TEST(test_pucch_power_state, test_accumulated_delta_pucch)
|
||||
|
||||
TEST(pc_min, check_all_bw_indexes)
|
||||
{
|
||||
const int NB_RB_UL[] = {11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273};
|
||||
for (auto i = 0U; i < sizeof(NB_RB_UL) / sizeof(NB_RB_UL[0]); i++) {
|
||||
(void)nr_get_Pcmin(1, 20, NB_RB_UL[i]);
|
||||
const int bws[] = {5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100};
|
||||
for (auto i = 0U; i < sizeofArray(bws); 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};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
current_UL_BWP.channel_bandwidth = 40;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||
@@ -218,6 +224,7 @@ TEST(pusch_power_control, pusch_power_control_msg3)
|
||||
mac.nr_band,
|
||||
mac.frame_type,
|
||||
FR1,
|
||||
current_UL_BWP.channel_bandwidth,
|
||||
Qm,
|
||||
false,
|
||||
current_UL_BWP.scs,
|
||||
@@ -286,6 +293,7 @@ TEST(pusch_power_control, pusch_power_data)
|
||||
NR_UE_UL_BWP_t current_UL_BWP = {0};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
current_UL_BWP.channel_bandwidth = 40;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||
@@ -317,6 +325,7 @@ TEST(pusch_power_control, pusch_power_data)
|
||||
mac.nr_band,
|
||||
mac.frame_type,
|
||||
FR1,
|
||||
current_UL_BWP.channel_bandwidth,
|
||||
Qm,
|
||||
false,
|
||||
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};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
current_UL_BWP.channel_bandwidth = 40;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||
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};
|
||||
current_UL_BWP.scs = 1;
|
||||
current_UL_BWP.BWPSize = 106;
|
||||
current_UL_BWP.channel_bandwidth = 40;
|
||||
mac.current_UL_BWP = ¤t_UL_BWP;
|
||||
NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0};
|
||||
current_UL_BWP.rach_ConfigCommon = &nr_rach_ConfigCommon;
|
||||
@@ -443,6 +454,7 @@ TEST(pusch_power_control, pusch_power_control_state)
|
||||
mac.nr_band,
|
||||
mac.frame_type,
|
||||
FR1,
|
||||
current_UL_BWP.channel_bandwidth,
|
||||
Qm,
|
||||
false,
|
||||
current_UL_BWP.scs,
|
||||
@@ -569,9 +581,25 @@ TEST(pusch_power_control, pusch_power_100_rb)
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
@@ -280,9 +280,11 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
|
||||
|
||||
// Carrier configuration
|
||||
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,
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
frequency_range_t frequency_range = *frequencyInfoDL->frequencyBandList.list.array[0] > 256 ? FR2 : FR1;
|
||||
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
frequency_range,
|
||||
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->num_tlv++;
|
||||
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;
|
||||
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
frequency_range = *frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1;
|
||||
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
|
||||
frequency_range,
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
cfg->carrier_config.uplink_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
|
||||
cfg->carrier_config.uplink_bandwidth.tl.tag = NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG; // temporary
|
||||
cfg->num_tlv++;
|
||||
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];
|
||||
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);
|
||||
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) {
|
||||
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_trigger_release_complete(mac, ra->rnti);
|
||||
nr_clear_ra_proc(ra);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
// 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
|
||||
// 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
|
||||
if (du_exists_f1_ue_data(rnti)) {
|
||||
if (!du_exists_f1_ue_data(rnti))
|
||||
return;
|
||||
|
||||
// unlock the scheduler temporarily to prevent possible deadlocks with
|
||||
// du_remove_f1_ue_data() (and also while sending the message to RRC)
|
||||
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);
|
||||
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,
|
||||
@@ -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;
|
||||
|
||||
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);
|
||||
// go back to examine the next UE, which is at the position the
|
||||
// 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);
|
||||
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_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 "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
#include "uper_decoder.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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
@@ -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) {
|
||||
/* 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_trigger_release_complete(mac, cmd->gNB_DU_ue_id);
|
||||
} else {
|
||||
/* UE is in sync: forward release message and mark to be deleted
|
||||
* after UL failure */
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "f1ap_messages_types.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_failure(const f1ap_setup_failure_t *failure);
|
||||
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 "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 (*gnb_du_configuration_update_t)(const f1ap_gnb_du_configuration_update_t *upd);
|
||||
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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->gnb_du_configuration_update = gnb_du_configuration_update_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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
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->gnb_du_configuration_update = gnb_du_configuration_update_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;
|
||||
|
||||
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;
|
||||
gnb_du_configuration_update_t gnb_du_configuration_update;
|
||||
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,
|
||||
&DRB_configList,
|
||||
&security_parameters);
|
||||
ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list);
|
||||
if (f1inst >= 0) { /* we have F1(-U) */
|
||||
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
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "common/platform_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_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,
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
#include "mac_rrc_dl.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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_failure = f1_setup_failure_direct;
|
||||
mac_rrc->gnb_du_configuration_update_acknowledge = gnb_du_configuration_update_ack_direct;
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
#include "mac_rrc_dl.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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_failure = f1_setup_failure_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;
|
||||
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
|
||||
for (int i = 0; i < fs->featureSetsDownlinkPerCC->list.count; 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;
|
||||
|
||||
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_failure_func_t f1_setup_failure;
|
||||
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)
|
||||
rrc_gNB_generate_UeContextSetupRequest(rrc, ue_context_p, nb_drb, drbs);
|
||||
else
|
||||
|
||||
@@ -335,13 +335,14 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,pdusessionTransfer );
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, pdusessionTransfer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_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;
|
||||
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];
|
||||
LOG_I(NR_RRC, "[gNB %ld] gNB_ue_ngap_id %u \n", instance, msg->gNB_ue_ngap_id);
|
||||
|
||||
if (ue_context_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 ;
|
||||
}
|
||||
|
||||
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;
|
||||
trigger_bearer_setup(rrc, UE, msg->nb_pdusessions_tosetup, msg->pdusession_setup_params, msg->ueAggMaxBitRateDownlink);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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 );
|
||||
@@ -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()) {
|
||||
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());
|
||||
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]);
|
||||
@@ -1424,25 +1427,27 @@ extern "C" {
|
||||
}
|
||||
|
||||
for(int i=0; i<((int) s->usrp->get_rx_num_channels()); i++) {
|
||||
if (i<openair0_cfg[0].rx_num_channels) {
|
||||
s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i+choffset);
|
||||
uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[i],
|
||||
openair0_cfg[0].tune_offset);
|
||||
openair0_config_t *cfg = &openair0_cfg[0];
|
||||
if (i < cfg->rx_num_channels) {
|
||||
s->usrp->set_rx_rate(cfg->sample_rate, i + choffset);
|
||||
uhd::tune_request_t rx_tune_req(cfg->rx_freq[i], cfg->tune_offset);
|
||||
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);
|
||||
// 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()) {
|
||||
LOG_E(HW,"RX Gain too high, lower by %f dB\n",
|
||||
gain - gain_range.stop());
|
||||
gain=gain_range.stop();
|
||||
LOG_E(HW, "RX Gain too high, lower by %f dB\n", gain - gain_range.stop());
|
||||
gain = gain_range.stop();
|
||||
}
|
||||
|
||||
s->usrp->set_rx_gain(gain,i+choffset);
|
||||
LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i,
|
||||
openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i],
|
||||
openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop());
|
||||
LOG_I(HW,
|
||||
"RX Gain %d %f (%f) => %f (max %f)\n",
|
||||
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