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:
Robert Schmidt
2024-07-30 16:24:27 +00:00
90 changed files with 1226 additions and 1377 deletions
+1 -1
View File
@@ -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
+8
View File
@@ -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
+5
View File
@@ -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
View File
@@ -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;
}
+3 -2
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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");
}
}
+2
View File
@@ -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
View File
@@ -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);
+8 -164
View File
@@ -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++)
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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);
+6 -6
View File
@@ -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++)
-169
View File
@@ -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]);
}
}
}
}
}
+1 -126
View File
@@ -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)
{
+2 -24
View File
@@ -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,
+35
View File
@@ -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
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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);
+220
View File
@@ -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);
}
+5 -20
View File
@@ -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);
+19 -34
View File
@@ -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]);
}
}
}
+10 -32
View File
@@ -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,9 +108,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
/// DMRS QPSK modulation
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb);
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER,
mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
if(dci_pdu->RNTI!=0xFFFF) {
for (int i=0; i<dmrs_length>>1; i++)
-6
View File
@@ -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,
+8 -10
View File
@@ -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;
+18 -30
View File
@@ -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
@@ -143,27 +143,22 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
}
static void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
uint32_t Nid,
uint8_t nushift,
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 Nid,
uint8_t nushift,
uint16_t M,
uint16_t length,
uint8_t encoded,
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);
+9 -8
View File
@@ -3,18 +3,18 @@
#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,
c16_t *txdataF,
int16_t amp,
prs_config_t *prs_cfg,
nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms)
int nr_generate_prs(int slot,
c16_t *txdataF,
int16_t amp,
prs_config_t *prs_cfg,
nfapi_nr_config_request_scf_t *config,
NR_DL_FRAME_PARMS *frame_parms)
{
int k_prime = 0, k = 0, idx;
@@ -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];
+14 -31
View File
@@ -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,
+26 -33
View File
@@ -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
+13 -18
View File
@@ -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))
+ scramble)
% (1U << 31); // c_init calculation according to TS38.211 subclause
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
@@ -89,9 +89,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
memset(ch_tmp_buf,0,sizeof(ch_tmp_buf));
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,40 +1420,37 @@ 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",
gNB_id,
ch_offset,
symbol_offset,
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,
Ns,
bwp_start_subcarrier,
symbol);
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,
fp->ofdm_symbol_size,
fp->Ncp,
slot,
bwp_start_subcarrier,
symbol);
#endif
// 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
+10 -5
View File
@@ -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,9 +151,9 @@ 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,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS);
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);
/** @}*/
#endif
@@ -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__,
ue->Mod_id,
ssb_index,
ue->measurements.ssb_rsrp_dBm[ssb_index],
rsrp);
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_db_per_re);
}
// This function computes the received noise power
@@ -310,11 +329,17 @@ 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,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS)
// 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)
{
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
@@ -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;
}
+6 -17
View File
@@ -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];
+7 -25
View File
@@ -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;
+14 -31
View File
@@ -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
+23 -29
View File
@@ -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);
}
}
+26 -45
View File
@@ -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;
}
}
-19
View File
@@ -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;
+6 -27
View File
@@ -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 {
-2
View File
@@ -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;
+3
View File
@@ -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
+8 -15
View File
@@ -108,20 +108,13 @@ 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],
&txdataF[0][txdataF_offset],
gNB->TX_AMP,
ssb_start_symbol,
cfg,
fp);
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,
cfg,
fp);
#if T_TRACER
if (T_ACTIVE(T_GNB_PHY_MIB)) {
@@ -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);
}
}
}
+1 -2
View File
@@ -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);
-12
View File
@@ -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);
+3 -5
View File
@@ -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,
-5
View File
@@ -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);
+4
View File
@@ -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)
+30
View File
@@ -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_ */
+13
View File
@@ -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;
+3 -3
View File
@@ -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");
}
+3 -3
View File
@@ -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
+4
View File
@@ -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));
+107 -4
View File
@@ -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;
+2 -2
View File
@@ -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);
/*
+4
View File
@@ -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));
+4 -1
View File
@@ -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 */
+4
View File
@@ -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
+23 -12
View File
@@ -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,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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;
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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 = &current_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 = &current_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 = &current_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 = &current_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();
}
+11 -7
View File
@@ -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,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
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,32 +3013,36 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b
return 0;
}
void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int 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))
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);
f1_ue_data_t ue_data = du_get_f1_ue_data(rnti);
f1ap_ue_context_release_complete_t complete = {
.gNB_CU_ue_id = ue_data.secondary_ue,
.gNB_DU_ue_id = rnti,
};
mac->mac_rrc.ue_context_release_complete(&complete);
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);
// 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)) {
// 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);
f1_ue_data_t ue_data = du_get_f1_ue_data(rnti);
f1ap_ue_context_release_complete_t complete = {
.gNB_CU_ue_id = ue_data.secondary_ue,
.gNB_DU_ue_id = rnti,
};
mac->mac_rrc.ue_context_release_complete(&complete);
du_remove_f1_ue_data(rnti);
NR_SCHED_LOCK(&mac->sched_lock);
}
}
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
+1
View File
@@ -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);
+3
View File
@@ -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;
+2
View File
@@ -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
+3
View File
@@ -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,
+14
View File
@@ -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;
+14
View File
@@ -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;
+1 -1
View File
@@ -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];
+2
View File
@@ -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;
-2
View File
@@ -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
+21 -3
View File
@@ -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
View File
@@ -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());
}
}