SL PSBCH: MAC->PHY cfg, PSBCH scheduler + supporting functions + enable system testing & scope
- Phy config update and Sidelink frame parameters initialisation - PSBCH scheduler to trigger TX PSBCH/RX PSBCH actions - Sidelink indication with rx ind to trigger send SL-MIB to MAC - Enable Scope for PSBCH use -d or --dqt - Enable system testing of PSBCH for example using RFSIMULATOR: - UE1 is a SYNCRONISATION SOURCE UE which transmits PSBCH started using command - sudo ./nr-uesoftmodem --sl-mode 2 --sync-ref 4 --rfsim --rfsimulator.serveraddr server - UE2 syncs onto UE1 during sidelink search, gets the timing and continues to receive PSBCH started using command - sudo ./nr-uesoftmodem --sl-mode 2 --rfsim --rfsimulator.serveraddr 127.0.0.1 - In the default use case 2 Sidelink SSBs sent over 16 frames. - In case SL-SSB configuration needs to be changed use -O option in the above command like -O ../../../targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1txpool.conf
This commit is contained in:
@@ -296,8 +296,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
||||
// init RX buffers
|
||||
common_vars->rxdata = malloc16(fp->nb_antennas_rx * sizeof(c16_t *));
|
||||
|
||||
int num_samples = 2 * fp->samples_per_frame + fp->ofdm_symbol_size;
|
||||
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++) {
|
||||
common_vars->rxdata[i] = malloc16_clear((2 * (fp->samples_per_frame) + fp->ofdm_symbol_size) * sizeof(c16_t));
|
||||
common_vars->rxdata[i] = malloc16_clear(num_samples * sizeof(c16_t));
|
||||
}
|
||||
|
||||
// ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
|
||||
@@ -655,7 +659,8 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
|
||||
if (fp->frame_type == FDD) {
|
||||
// No timing offset for Sidelink, refer to 3GPP 38.211 Section 8.5
|
||||
if (fp->frame_type == FDD || ue->sl_mode == 2) {
|
||||
ue->N_TA_offset = 0;
|
||||
} else {
|
||||
int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
|
||||
@@ -771,6 +776,4 @@ void sl_ue_phy_init(PHY_VARS_NR_UE *UE)
|
||||
// Generate PSS time domain samples used for correlation during SLSS reception.
|
||||
sl_generate_pss_ifft_samples(&UE->SL_UE_PHY_PARAMS, &UE->SL_UE_PHY_PARAMS.init_params);
|
||||
|
||||
init_symbol_rotation(sl_fp);
|
||||
init_timeshift_rotation(sl_fp);
|
||||
}
|
||||
|
||||
+145
-37
@@ -23,6 +23,7 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
|
||||
/// Subcarrier spacings in Hz indexed by numerology index
|
||||
static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
|
||||
@@ -86,18 +87,6 @@ static const int nr_ssb_table[54][3] = {
|
||||
{96, 30, nr_ssb_type_C}};
|
||||
|
||||
void set_Lmax(NR_DL_FRAME_PARMS *fp) {
|
||||
if (get_softmodem_params()->sl_mode == 2) {
|
||||
int sl_NumSSB_WithinPeriod = 1; //TODO: Needs to be updated from RRC parameters
|
||||
int sl_TimeOffsetSSB = 1; //TODO: Needs to be updated from RRC parameters
|
||||
int sl_TimeInterval = 1; //TODO: Needs to be updated from RRC parameters
|
||||
if ((sl_NumSSB_WithinPeriod == 4) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + 3 * sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME * 2))
|
||||
fp->Lmax = 4;
|
||||
else if ((sl_NumSSB_WithinPeriod == 2) && ((sl_TimeOffsetSSB % fp->slots_per_frame) + sl_TimeInterval < NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
|
||||
fp->Lmax = 2;
|
||||
else
|
||||
fp->Lmax = 1;
|
||||
return;
|
||||
}
|
||||
// definition of Lmax according to ts 38.213 section 4.1
|
||||
if (fp->dl_CarrierFreq < 6e9) {
|
||||
if(fp->frame_type && (fp->ssb_type==2))
|
||||
@@ -159,19 +148,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
|
||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
|
||||
fp->ssb_type = nr_ssb_type_A;
|
||||
while(nr_ssb_table[idx][0]!=fp->nr_band)
|
||||
while (nr_ssb_table[idx][0] != fp->nr_band)
|
||||
idx++;
|
||||
AssertFatal(nr_ssb_table[idx][1]==15,"SCS %d not applicable to band %d\n",
|
||||
AssertFatal(nr_ssb_table[idx][1] == 15,"SCS %d not applicable to band %d\n",
|
||||
fp->subcarrier_spacing,fp->nr_band);
|
||||
break;
|
||||
|
||||
case NR_MU_1: //30kHz scs
|
||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
|
||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
|
||||
while(nr_ssb_table[idx][0]!=fp->nr_band ||
|
||||
nr_ssb_table[idx][1]!=30) {
|
||||
AssertFatal(nr_ssb_table[idx][0]<=fp->nr_band,"SCS %d not applicable to band %d\n",
|
||||
fp->subcarrier_spacing,fp->nr_band);
|
||||
while(nr_ssb_table[idx][0] != fp->nr_band ||
|
||||
nr_ssb_table[idx][1] != 30) {
|
||||
AssertFatal(nr_ssb_table[idx][0] <= fp->nr_band,
|
||||
"SCS %d not applicable to band %d\n",
|
||||
fp->subcarrier_spacing,
|
||||
fp->nr_band);
|
||||
idx++;
|
||||
}
|
||||
fp->ssb_type = nr_ssb_table[idx][2];
|
||||
@@ -207,9 +198,6 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
||||
fp->ofdm_symbol_size <<= 1;
|
||||
|
||||
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
|
||||
// TODO: Temporarily setting fp->first_carrier_offset = 0 for SL until MAC is developed
|
||||
if (get_softmodem_params()->sl_mode == 2)
|
||||
fp->first_carrier_offset = 0;
|
||||
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
|
||||
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
|
||||
LOG_I(PHY,
|
||||
@@ -221,6 +209,34 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
||||
fp->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
void sl_set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_SL)
|
||||
{
|
||||
|
||||
AssertFatal(mu >= NR_MU_0 && mu <= NR_MU_4,"Invalid numerology index %d", mu);
|
||||
|
||||
fp->subcarrier_spacing = nr_subcarrier_spacing[mu];
|
||||
fp->slots_per_subframe = nr_slots_per_subframe[mu];
|
||||
|
||||
if(fp->threequarter_fs)
|
||||
fp->ofdm_symbol_size = 3 * 128;
|
||||
else
|
||||
fp->ofdm_symbol_size = 4 * 128;
|
||||
|
||||
while(fp->ofdm_symbol_size < N_RB_SL * 12)
|
||||
fp->ofdm_symbol_size <<= 1;
|
||||
|
||||
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_SL * 12 / 2);
|
||||
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
|
||||
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
|
||||
LOG_I(PHY,
|
||||
"Init: N_RB_SL %d, first_carrier_offset %d, nb_prefix_samples %d,nb_prefix_samples0 %d, ofdm_symbol_size %d\n",
|
||||
N_RB_SL,
|
||||
fp->first_carrier_offset,
|
||||
fp->nb_prefix_samples,
|
||||
fp->nb_prefix_samples0,
|
||||
fp->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
uint32_t samp_count;
|
||||
@@ -344,11 +360,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
|
||||
LOG_D(PHY,"dl_bw_kHz %lu\n",dl_bw_khz);
|
||||
LOG_D(PHY,"dl_CarrierFreq %lu\n",fp->dl_CarrierFreq);
|
||||
|
||||
if (get_softmodem_params()->sl_mode == 2) {
|
||||
uint64_t sl_bw_khz = (12 * config->carrier_config.sl_grid_size[config->ssb_config.scs_common]) * (15 << config->ssb_config.scs_common);
|
||||
fp->sl_CarrierFreq = ((sl_bw_khz >> 1) + config->carrier_config.sl_frequency) * 1000;
|
||||
}
|
||||
|
||||
uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
|
||||
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ;
|
||||
|
||||
@@ -374,7 +385,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
|
||||
AssertFatal(fp->numerology_index == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, fp->numerology_index);
|
||||
|
||||
fp->Ncp = Ncp;
|
||||
int N_RB = (get_softmodem_params()->sl_mode == 2) ? fp->N_RB_SL : fp->N_RB_DL;
|
||||
int N_RB = fp->N_RB_DL;
|
||||
set_scs_parameters(fp, fp->numerology_index, N_RB);
|
||||
|
||||
fp->slots_per_frame = 10* fp->slots_per_subframe;
|
||||
@@ -401,10 +412,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
|
||||
}
|
||||
|
||||
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
|
||||
// TODO: Temporarily setting fp->ssb_start_subcarrier = 0 for SL until MAC is developed
|
||||
if (get_softmodem_params()->sl_mode == 2) {
|
||||
fp->ssb_start_subcarrier = 0;
|
||||
}
|
||||
set_Lmax(fp);
|
||||
|
||||
fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask;
|
||||
@@ -454,12 +461,6 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
|
||||
|
||||
}
|
||||
|
||||
void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band) {
|
||||
LOG_D(NR_PHY, "SL init parameters. SL freq %lu\n", sidelink_frequency);
|
||||
frame_parms->sl_CarrierFreq = sidelink_frequency;
|
||||
frame_parms->nr_band = nr_band;
|
||||
}
|
||||
|
||||
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
LOG_I(PHY,"fp->scs=%d\n",fp->subcarrier_spacing);
|
||||
@@ -476,4 +477,111 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
|
||||
LOG_I(PHY, "fp->Nid_cell=%d\n", fp->Nid_cell);
|
||||
LOG_I(PHY, "fp->first_carrier_offset=%d\n", fp->first_carrier_offset);
|
||||
LOG_I(PHY, "fp->ssb_start_subcarrier=%d\n", fp->ssb_start_subcarrier);
|
||||
LOG_I(PHY, "fp->Ncp=%d\n", fp->Ncp);
|
||||
LOG_I(PHY, "fp->N_RB_DL=%d\n", fp->N_RB_DL);
|
||||
LOG_I(PHY, "fp->numerology_index=%d\n", fp->numerology_index);
|
||||
LOG_I(PHY, "fp->nr_band=%d\n", fp->nr_band);
|
||||
LOG_I(PHY, "fp->ofdm_offset_divisor=%d\n", fp->ofdm_offset_divisor);
|
||||
LOG_I(PHY, "fp->threequarter_fs=%d\n", fp->threequarter_fs);
|
||||
LOG_I(PHY, "fp->sl_CarrierFreq=%lu\n", fp->sl_CarrierFreq);
|
||||
LOG_I(PHY, "fp->N_RB_SL=%d\n", fp->N_RB_SL);
|
||||
}
|
||||
|
||||
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
|
||||
sl_nr_phy_config_request_t *config,
|
||||
int threequarter_fs,
|
||||
uint32_t ofdm_offset_divisor)
|
||||
{
|
||||
// Set also these parameters here instead of some where else.
|
||||
fp->ofdm_offset_divisor = ofdm_offset_divisor;
|
||||
fp->threequarter_fs = threequarter_fs;
|
||||
|
||||
fp->nr_band = get_band(config->sl_carrier_config.sl_frequency, 0);
|
||||
|
||||
fp->att_rx = 0;
|
||||
fp->att_tx = 0;
|
||||
fp->nb_antennas_rx = config->sl_carrier_config.sl_num_rx_ant;
|
||||
fp->nb_antennas_tx = config->sl_carrier_config.sl_num_tx_ant;
|
||||
|
||||
fp->numerology_index = config->sl_bwp_config.sl_scs;
|
||||
fp->N_RB_SL = config->sl_carrier_config.sl_grid_size;
|
||||
fp->N_RB_DL = fp->N_RB_SL;
|
||||
fp->N_RB_UL = fp->N_RB_SL;
|
||||
fp->Ncp = config->sl_bwp_config.sl_cyclic_prefix;
|
||||
|
||||
fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index);
|
||||
int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index);
|
||||
uplink_frequency_offset *= 1000;
|
||||
|
||||
uint64_t bw_khz = (12 * config->sl_carrier_config.sl_grid_size) * (15 << config->sl_bwp_config.sl_scs);
|
||||
// REfer to section 3GPP spec 38.101 5.4E.2.1
|
||||
// FrefV2x = Fref + deltashift + valueN*5Khz
|
||||
uint32_t deltashift = (config->sl_carrier_config.sl_frequency_shift_7p5khz) ? 7500 : 0; // In Hz
|
||||
deltashift += config->sl_carrier_config.sl_value_N * 5000; // In Hz
|
||||
fp->sl_CarrierFreq = ((bw_khz >> 1) + config->sl_carrier_config.sl_frequency);
|
||||
fp->sl_CarrierFreq += (deltashift >> 1);
|
||||
fp->dl_CarrierFreq = fp->sl_CarrierFreq;
|
||||
fp->ul_CarrierFreq = fp->sl_CarrierFreq;
|
||||
|
||||
LOG_D(PHY, "bw_kHz %lu, deltashift:%d Hz\n", bw_khz, deltashift);
|
||||
LOG_D(PHY, "CarrierFreq %lu Hz\n", fp->sl_CarrierFreq);
|
||||
|
||||
LOG_I(PHY,
|
||||
"Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz SL frequency %lu Hz: band %d, uldl offset %d Hz\n",
|
||||
fp->dl_CarrierFreq,
|
||||
fp->ul_CarrierFreq,
|
||||
fp->sl_CarrierFreq,
|
||||
fp->nr_band,
|
||||
uplink_frequency_offset);
|
||||
|
||||
AssertFatal(fp->frame_type == TDD, "Sidelink bands only support TDD");
|
||||
|
||||
AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset),
|
||||
"Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n",
|
||||
fp->nr_band,
|
||||
fp->ul_CarrierFreq,
|
||||
fp->dl_CarrierFreq + uplink_frequency_offset);
|
||||
|
||||
LOG_I(PHY, "Initializing frame parms for mu %d, N_RB %d, Ncp %d\n", fp->numerology_index, fp->N_RB_DL, fp->Ncp);
|
||||
|
||||
if (fp->Ncp == EXTENDED)
|
||||
AssertFatal(fp->numerology_index == NR_MU_2,
|
||||
"Invalid cyclic prefix %d for numerology index %d\n",
|
||||
fp->Ncp,
|
||||
fp->numerology_index);
|
||||
|
||||
sl_set_scs_parameters(fp, fp->numerology_index, fp->N_RB_SL);
|
||||
|
||||
fp->slots_per_frame = 10 * fp->slots_per_subframe;
|
||||
fp->symbols_per_slot = ((fp->Ncp == NORMAL) ? 14 : 12); // to redefine for different slot formats
|
||||
fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
|
||||
fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
|
||||
fp->samples_per_slot_wCP = fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
fp->samples_per_slotN0 = (fp->nb_prefix_samples + fp->ofdm_symbol_size) * fp->symbols_per_slot;
|
||||
fp->samples_per_slot0 =
|
||||
fp->nb_prefix_samples0 + ((fp->symbols_per_slot - 1) * fp->nb_prefix_samples) + (fp->symbols_per_slot * fp->ofdm_symbol_size);
|
||||
fp->samples_per_subframe = (fp->nb_prefix_samples0 + fp->ofdm_symbol_size) * 2
|
||||
+ (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2);
|
||||
fp->get_samples_per_slot = &get_samples_per_slot;
|
||||
fp->get_samples_slot_timestamp = &get_samples_slot_timestamp;
|
||||
fp->samples_per_frame = 10 * fp->samples_per_subframe;
|
||||
fp->freq_range = (fp->sl_CarrierFreq < 6e9) ? FR1 : FR2;
|
||||
|
||||
// ssb_offset_pointa points to the first RE where Sidelink-PSBCH starts
|
||||
fp->ssb_start_subcarrier = config->sl_bwp_config.sl_ssb_offset_point_a;
|
||||
|
||||
perform_symbol_rotation(fp, fp->sl_CarrierFreq, fp->symbol_rotation[link_type_sl]);
|
||||
init_timeshift_rotation(fp);
|
||||
|
||||
// Not used for Sidelink
|
||||
fp->Lmax = 0;
|
||||
fp->L_ssb = 0;
|
||||
fp->N_ssb = 0;
|
||||
fp->half_frame_bit = 0;
|
||||
fp->ssb_index = 0;
|
||||
fp->ssb_type = 0;
|
||||
|
||||
LOG_I(PHY, "Dumping Sidelink Frame Parameters\n");
|
||||
nr_dump_frame_parms(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
|
||||
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
|
||||
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
|
||||
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
|
||||
void nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *frame_parms, uint64_t sidelink_frequency, uint16_t nr_band);
|
||||
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
|
||||
sl_nr_phy_config_request_t *config,
|
||||
int threequarter_fs,
|
||||
uint32_t ofdm_offset_divisor);
|
||||
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB);
|
||||
void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB);
|
||||
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
|
||||
|
||||
@@ -578,61 +578,59 @@ void nr_dft(c16_t *z, c16_t *d, uint32_t Msc_PUSCH)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
|
||||
|
||||
uint64_t dl_CarrierFreq = fp->dl_CarrierFreq;
|
||||
uint64_t ul_CarrierFreq = fp->ul_CarrierFreq;
|
||||
uint64_t sl_CarrierFreq = fp->sl_CarrierFreq;
|
||||
double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq};
|
||||
|
||||
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation)
|
||||
{
|
||||
const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10;
|
||||
const double Tc=(1/480e3/4096);
|
||||
const double Nu=2048*64*(1/(float)(1<<fp->numerology_index));
|
||||
const double Ncp0=16*64 + (144*64*(1/(float)(1<<fp->numerology_index)));
|
||||
const double Ncp1=(144*64*(1/(float)(1<<fp->numerology_index)));
|
||||
|
||||
for (uint8_t ll = 0; ll < 2; ll++){
|
||||
LOG_I(PHY, "Doing symbol rotation calculation for TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
|
||||
|
||||
double tl = 0.0;
|
||||
double poff = 0.0;
|
||||
double exp_re = 0.0;
|
||||
double exp_im = 0.0;
|
||||
|
||||
for (int l = 0; l < nsymb; l++) {
|
||||
double Ncp;
|
||||
if (l == 0 || l == (7 * (1 << fp->numerology_index))) {
|
||||
Ncp = Ncp0;
|
||||
} else {
|
||||
Ncp = Ncp1;
|
||||
}
|
||||
|
||||
poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0;
|
||||
exp_re = cos(poff);
|
||||
exp_im = sin(-poff);
|
||||
symbol_rotation[l].r = (int16_t)floor(exp_re * 32767);
|
||||
symbol_rotation[l].i = (int16_t)floor(exp_im * 32767);
|
||||
|
||||
LOG_D(PHY,
|
||||
"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",
|
||||
l,
|
||||
nsymb,
|
||||
tl,
|
||||
symbol_rotation[l].r,
|
||||
symbol_rotation[l].i,
|
||||
(poff / 2 / M_PI) - floor(poff / 2 / M_PI));
|
||||
|
||||
tl += (Nu + Ncp) * Tc;
|
||||
}
|
||||
}
|
||||
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
double f[2] = {(double)fp->dl_CarrierFreq, (double)fp->ul_CarrierFreq};
|
||||
|
||||
for (int ll = 0; ll < 2; ll++) {
|
||||
double f0 = f[ll];
|
||||
LOG_D(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
|
||||
c16_t *symbol_rotation = fp->symbol_rotation[ll];
|
||||
if (get_softmodem_params()->sl_mode == 2) {
|
||||
f0 = (double)sl_CarrierFreq;
|
||||
symbol_rotation = fp->symbol_rotation[link_type_sl];
|
||||
}
|
||||
if (f0 == 0)
|
||||
continue;
|
||||
c16_t *rot = fp->symbol_rotation[ll];
|
||||
|
||||
double tl = 0.0;
|
||||
double poff = 0.0;
|
||||
double exp_re = 0.0;
|
||||
double exp_im = 0.0;
|
||||
|
||||
for (int l = 0; l < nsymb; l++) {
|
||||
|
||||
double Ncp;
|
||||
if (l == 0 || l == (7 * (1 << fp->numerology_index))) {
|
||||
Ncp = Ncp0;
|
||||
} else {
|
||||
Ncp = Ncp1;
|
||||
}
|
||||
|
||||
poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0;
|
||||
exp_re = cos(poff);
|
||||
exp_im = sin(-poff);
|
||||
symbol_rotation[l].r = (int16_t)floor(exp_re * 32767);
|
||||
symbol_rotation[l].i = (int16_t)floor(exp_im * 32767);
|
||||
|
||||
LOG_D(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",
|
||||
l,
|
||||
nsymb,
|
||||
tl,
|
||||
symbol_rotation[l].r,
|
||||
symbol_rotation[l].i,
|
||||
(poff / 2 / M_PI) - floor(poff / 2 / M_PI));
|
||||
|
||||
tl += (Nu + Ncp) * Tc;
|
||||
|
||||
}
|
||||
perform_symbol_rotation(fp, f0, rot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,8 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
int first_symbol,
|
||||
int nsymb);
|
||||
|
||||
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation);
|
||||
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
|
||||
|
||||
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp);
|
||||
|
||||
@@ -94,7 +94,7 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
dft(dftsize, rxdata_ptr, (int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size * symbol], 1);
|
||||
|
||||
int symb_offset = (Ns % frame_params->slots_per_subframe) * frame_params->symbols_per_slot;
|
||||
int32_t rot2 = ((uint32_t *)frame_params->symbol_rotation[1])[symbol + symb_offset];
|
||||
int32_t rot2 = ((uint32_t *)frame_params->symbol_rotation[2])[symbol + symb_offset];
|
||||
((int16_t *)&rot2)[1] = -((int16_t *)&rot2)[1];
|
||||
|
||||
#ifdef SL_DEBUG_SLOT_FEP
|
||||
|
||||
@@ -351,7 +351,7 @@ 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);
|
||||
|
||||
LOG_I(PHY,
|
||||
LOG_D(PHY,
|
||||
"PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n",
|
||||
num_re,
|
||||
psbch_rx->rsrp_dB_per_RE,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/TOOLS/phy_scope_interface.h"
|
||||
|
||||
// #define DEBUG_PSBCH
|
||||
|
||||
@@ -109,7 +110,7 @@ static void nr_psbch_extract(uint32_t rxdataF_sz,
|
||||
}
|
||||
|
||||
int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -122,6 +123,7 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
// Extra 2 bits needed as polar decoder expects a multiple of 4 as encoder length
|
||||
// If these 2 bits are not added, runs compiled with --sanitize will fail.
|
||||
int16_t psbch_e_rx[SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2] = {0};
|
||||
int16_t psbch_unClipped[SL_NR_POLAR_PSBCH_E_NORMAL_CP + 2] = {0};
|
||||
|
||||
#ifdef DEBUG_PSBCH
|
||||
write_output("psbch_rxdataF.m",
|
||||
@@ -174,6 +176,9 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
nr_pbch_quantize(psbch_e_rx + psbch_e_rx_idx, (short *)rxdataF_comp[0], SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL);
|
||||
|
||||
if (ue->scopeData)
|
||||
memcpy(psbch_unClipped + psbch_e_rx_idx, rxdataF_comp[0], SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL * sizeof(int16_t));
|
||||
|
||||
psbch_e_rx_idx += SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL;
|
||||
|
||||
// SKIP 2 SL-PSS AND 2 SL-SSS symbols
|
||||
@@ -181,10 +186,8 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
symbol = (symbol == 0) ? 5 : symbol + 1;
|
||||
}
|
||||
|
||||
#if 0 // ENABLE SCOPE LATER
|
||||
UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(struct complex16), frame_parms->nb_antennas_rx, psbch_e_rx_idx/2);
|
||||
UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx);
|
||||
#endif
|
||||
UEscopeCopy(ue, psbchRxdataF_comp, psbch_unClipped, sizeof(c16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx / 2, 0);
|
||||
UEscopeCopy(ue, psbchLlr, psbch_e_rx, sizeof(int16_t), frame_parms->nb_antennas_rx, psbch_e_rx_idx, 0);
|
||||
|
||||
#ifdef DEBUG_PSBCH
|
||||
write_output("psbch_rxdataFcomp.m", "psbch_rxFcomp", psbch_unClipped, SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS, 1, 1);
|
||||
|
||||
@@ -257,7 +257,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF);
|
||||
c16_t **txdataF,
|
||||
uint32_t linktype);
|
||||
|
||||
void clean_UE_harq(PHY_VARS_NR_UE *UE);
|
||||
|
||||
@@ -429,7 +430,7 @@ void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned
|
||||
void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb);
|
||||
|
||||
int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
@@ -47,15 +47,7 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64
|
||||
}
|
||||
|
||||
|
||||
void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue, uint64_t *sl_carrier) {
|
||||
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
if (ue->if_freq!=0) {
|
||||
*sl_carrier = ue->if_freq;
|
||||
} else {
|
||||
*sl_carrier = fp->sl_CarrierFreq;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
|
||||
double rx_gain_off){
|
||||
|
||||
@@ -571,17 +571,20 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint8_t slot,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint8_t n_antenna_ports,
|
||||
c16_t **txdataF)
|
||||
c16_t **txdataF,
|
||||
uint32_t linktype)
|
||||
{
|
||||
const int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
|
||||
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
|
||||
|
||||
c16_t **txdata = UE->common_vars.txData;
|
||||
for(int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
txdataF[ap],
|
||||
frame_parms->symbol_rotation[1],
|
||||
frame_parms->symbol_rotation[linktype],
|
||||
slot,
|
||||
frame_parms->N_RB_UL,
|
||||
N_RB,
|
||||
0,
|
||||
NR_NUMBER_OF_SYMBOLS_PER_SLOT);
|
||||
}
|
||||
|
||||
@@ -64,10 +64,11 @@ float Limits_KPI_gNB[4][2] = {
|
||||
@UE: These are the (default) lower and upper threshold values for BLER and Throughput at the UE side.
|
||||
These threshold values can be further updated in run-time through the option 'Configs' in the drop-down list
|
||||
*/
|
||||
float Limits_KPI_ue[2][2] = {
|
||||
float Limits_KPI_ue[3][2] = {
|
||||
// {lower Limit, Upper Limit}
|
||||
{0.0, 0.8}, // DL BLER
|
||||
{0.2, 10} // Throughput in Mbs
|
||||
{0.2, 10}, // Throughput in Mbs
|
||||
{0, 60} // psbch RSRP db/RE
|
||||
};
|
||||
|
||||
// Plot updater
|
||||
@@ -192,6 +193,9 @@ KPIListSelectUE::KPIListSelectUE(QWidget *parent) : QComboBox(parent)
|
||||
this->addItem("Time Adv.", static_cast<int>(PlotTypeUE::timingAdvance));
|
||||
|
||||
this->addItem("Configs", static_cast<int>(PlotTypeUE::config));
|
||||
this->addItem("LLR PSBCH", static_cast<int>(PlotTypeUE::psbchLLR));
|
||||
this->addItem("I/Q PSBCH", static_cast<int>(PlotTypeUE::psbchIQ));
|
||||
this->addItem("PSBCH RSRP dB/RE", static_cast<int>(PlotTypeUE::psbchRSRP));
|
||||
}
|
||||
|
||||
WaterFall::WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget *parent)
|
||||
@@ -951,6 +955,9 @@ float PainterWidgetUE::getValue()
|
||||
case PlotTypeUE::timingAdvance:
|
||||
return (float)this->ue->timing_advance;
|
||||
|
||||
case PlotTypeUE::psbchRSRP:
|
||||
return (float)this->ue->SL_UE_PHY_PARAMS.psbch.rsrp_dB_per_RE;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -960,15 +967,22 @@ scopeGraphData_t *PainterWidgetUE::getPlotValue()
|
||||
{
|
||||
scopeData_t *scope = (scopeData_t *)this->ue->scopeData;
|
||||
scopeGraphData_t **data = (scopeGraphData_t **)scope->liveData;
|
||||
bool is_sl = this->ue->sl_mode;
|
||||
|
||||
switch (this->plotType) {
|
||||
case PlotTypeUE::CIR:
|
||||
return data[pbchDlChEstimateTime];
|
||||
return (is_sl ? data[psbchDlChEstimateTime] : data[pbchDlChEstimateTime]);
|
||||
|
||||
case PlotTypeUE::pbchLLR:
|
||||
return data[pbchLlr];
|
||||
case PlotTypeUE::pbchIQ:
|
||||
return data[pbchRxdataF_comp];
|
||||
|
||||
case PlotTypeUE::psbchLLR:
|
||||
return data[psbchLlr];
|
||||
case PlotTypeUE::psbchIQ:
|
||||
return data[psbchRxdataF_comp];
|
||||
|
||||
case PlotTypeUE::pdcchLLR:
|
||||
return data[pdcchLlr];
|
||||
|
||||
@@ -1039,13 +1053,14 @@ void PainterWidgetUE::makeConnections(int type)
|
||||
break;
|
||||
}
|
||||
case PlotTypeUE::CIR: {
|
||||
if (!data[pbchDlChEstimateTime]) {
|
||||
enum scopeDataType typ = (this->ue->sl_mode) ? psbchDlChEstimateTime : pbchDlChEstimateTime;
|
||||
if (!data[typ]) {
|
||||
newChart = new QChart();
|
||||
this->plotType = PlotTypeUE::empty;
|
||||
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
|
||||
break;
|
||||
}
|
||||
newChart = new CIRPlot((complex16 *)(data[pbchDlChEstimateTime] + 1), data[pbchDlChEstimateTime]->lineSz);
|
||||
newChart = new CIRPlot((complex16 *)(data[typ] + 1), data[typ]->lineSz);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1069,6 +1084,26 @@ void PainterWidgetUE::makeConnections(int type)
|
||||
newChart = new IQPlotUE((complex16 *)(data[pbchRxdataF_comp] + 1), data[pbchRxdataF_comp]->lineSz, this);
|
||||
break;
|
||||
}
|
||||
case PlotTypeUE::psbchLLR: {
|
||||
if (!data[psbchLlr]) {
|
||||
newChart = new QChart();
|
||||
this->plotType = PlotTypeUE::empty;
|
||||
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
|
||||
break;
|
||||
}
|
||||
newChart = new LLRPlotUE((int16_t *)(data[psbchLlr] + 1), data[psbchLlr]->lineSz, this);
|
||||
break;
|
||||
}
|
||||
case PlotTypeUE::psbchIQ: {
|
||||
if (!data[psbchRxdataF_comp]) {
|
||||
newChart = new QChart();
|
||||
this->plotType = PlotTypeUE::empty;
|
||||
this->comboBox->setCurrentIndex(static_cast<int>(PlotTypeUE::empty));
|
||||
break;
|
||||
}
|
||||
newChart = new IQPlotUE((complex16 *)(data[psbchRxdataF_comp] + 1), data[psbchRxdataF_comp]->lineSz, this);
|
||||
break;
|
||||
}
|
||||
case PlotTypeUE::pdcchLLR: {
|
||||
if (!data[pdcchLlr]) {
|
||||
newChart = new QChart();
|
||||
@@ -1138,7 +1173,10 @@ void PainterWidgetUE::makeConnections(int type)
|
||||
newChart = new KPIPlot(this);
|
||||
break;
|
||||
}
|
||||
|
||||
case PlotTypeUE::psbchRSRP: {
|
||||
newChart = new KPIPlot(this, Limits_KPI_ue[2]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1223,6 +1261,7 @@ void *nrgNBQtscopeThread(void *arg)
|
||||
void *nrUEQtscopeThread(void *arg)
|
||||
{
|
||||
PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)arg;
|
||||
bool is_sl = ue->sl_mode;
|
||||
|
||||
sleep(1);
|
||||
|
||||
@@ -1256,14 +1295,20 @@ void *nrUEQtscopeThread(void *arg)
|
||||
mainLayout.addWidget(&pwidgetueCombo2, 1, 1);
|
||||
|
||||
KPIListSelectUE combo3;
|
||||
combo3.setCurrentIndex(static_cast<int>(PlotTypeUE::pbchLLR));
|
||||
if (is_sl)
|
||||
combo3.setCurrentIndex(static_cast<int>(PlotTypeUE::psbchLLR));
|
||||
else
|
||||
combo3.setCurrentIndex(static_cast<int>(PlotTypeUE::psbchLLR));
|
||||
PainterWidgetUE pwidgetueCombo3(&config, &combo3, ue);
|
||||
|
||||
mainLayout.addWidget(&combo3, 2, 0);
|
||||
mainLayout.addWidget(&pwidgetueCombo3, 3, 0);
|
||||
|
||||
KPIListSelectUE combo4;
|
||||
combo4.setCurrentIndex(static_cast<int>(PlotTypeUE::pbchIQ));
|
||||
if (is_sl)
|
||||
combo4.setCurrentIndex(static_cast<int>(PlotTypeUE::psbchIQ));
|
||||
else
|
||||
combo4.setCurrentIndex(static_cast<int>(PlotTypeUE::psbchIQ));
|
||||
PainterWidgetUE pwidgetueCombo4(&config, &combo4, ue);
|
||||
|
||||
mainLayout.addWidget(&combo4, 2, 1);
|
||||
|
||||
@@ -81,7 +81,10 @@ enum class PlotTypeUE {
|
||||
pdschRBs,
|
||||
frequencyOffset,
|
||||
timingAdvance,
|
||||
config
|
||||
config,
|
||||
psbchLLR,
|
||||
psbchIQ,
|
||||
psbchRSRP,
|
||||
};
|
||||
|
||||
/// This abstract class defines an interface how the KPIPlot class can access values for the different KPI plot types
|
||||
|
||||
@@ -786,14 +786,14 @@ static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int
|
||||
*/
|
||||
|
||||
static void ueChannelResponse (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
enum scopeDataType typ = (phy_vars_ue->sl_mode) ? psbchDlChEstimateTime : pbchDlChEstimateTime;
|
||||
|
||||
// Channel Impulse Response
|
||||
if (!data[pbchDlChEstimateTime])
|
||||
if (!data[typ])
|
||||
return;
|
||||
|
||||
const scopeSample_t *tmp=(scopeSample_t *)(data[pbchDlChEstimateTime]+1);
|
||||
genericPowerPerAntena(graph, data[pbchDlChEstimateTime]->colSz,
|
||||
&tmp,
|
||||
data[pbchDlChEstimateTime]->lineSz);
|
||||
const scopeSample_t *tmp = (scopeSample_t *)(data[typ] + 1);
|
||||
genericPowerPerAntena(graph, data[typ]->colSz, &tmp, data[typ]->lineSz);
|
||||
}
|
||||
|
||||
static void ueFreqWaterFall (scopeGraphData_t **data, OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
|
||||
@@ -847,14 +847,16 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
|
||||
}
|
||||
*/
|
||||
static void uePbchLLR (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
enum scopeDataType typ = (phy_vars_ue->sl_mode) ? psbchLlr : pbchLlr;
|
||||
|
||||
// PBCH LLRs
|
||||
if ( !data[pbchLlr])
|
||||
if (!data[typ])
|
||||
return;
|
||||
|
||||
const int sz=data[pbchLlr]->lineSz;
|
||||
//const int antennas=data[pbchLlr]->colSz;
|
||||
const int sz = data[typ]->lineSz;
|
||||
// const int antennas=data[typ]->colSz;
|
||||
// We take the first antenna only for now
|
||||
int16_t *llrs = (int16_t *) (data[pbchLlr]+1);
|
||||
int16_t *llrs = (int16_t *)(data[typ] + 1);
|
||||
float *llr_pbch=NULL, *bit_pbch=NULL;
|
||||
int nx = sz;
|
||||
#ifdef WEBSRVSCOPE
|
||||
@@ -870,12 +872,14 @@ static void uePbchLLR (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_
|
||||
}
|
||||
|
||||
static void uePbchIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
enum scopeDataType typ = (phy_vars_ue->sl_mode) ? psbchRxdataF_comp : pbchRxdataF_comp;
|
||||
|
||||
// PBCH I/Q of MF Output
|
||||
if (!data[pbchRxdataF_comp])
|
||||
if (!data[typ])
|
||||
return;
|
||||
|
||||
scopeSample_t *pbch_comp = (scopeSample_t *) (data[pbchRxdataF_comp]+1);
|
||||
const int sz=data[pbchRxdataF_comp]->lineSz;
|
||||
scopeSample_t *pbch_comp = (scopeSample_t *)(data[typ] + 1);
|
||||
const int sz = data[typ]->lineSz;
|
||||
int newsz = sz;
|
||||
float *I=NULL, *Q=NULL;
|
||||
#ifdef WEBSRVSCOPE
|
||||
|
||||
@@ -67,6 +67,9 @@ enum scopeDataType {
|
||||
pdschRxdataF_comp,
|
||||
commonRxdataF,
|
||||
gNBRxdataF,
|
||||
psbchDlChEstimateTime,
|
||||
psbchLlr,
|
||||
psbchRxdataF_comp,
|
||||
MAX_SCOPE_TYPES
|
||||
};
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#define SL_NR_NUM_IDs_IN_PSS 2
|
||||
#define SL_NR_NUM_IDs_IN_SSS 336
|
||||
#define SL_NR_NUM_SLSS_IDs 672
|
||||
#define SL_NR_PSBCH_REPETITION_IN_FRAMES 16
|
||||
|
||||
typedef enum sl_nr_sidelink_mode { SL_NOT_SUPPORTED = 0, SL_MODE1_SUPPORTED, SL_MODE2_SUPPORTED } sl_nr_sidelink_mode_t;
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ SystemInformationBlockType1_nr_t;
|
||||
#define NR_DOWNLINK_SLOT (0x01)
|
||||
#define NR_UPLINK_SLOT (0x02)
|
||||
#define NR_MIXED_SLOT (0x03)
|
||||
#define NR_SIDELINK_SLOT NR_UPLINK_SLOT
|
||||
|
||||
#define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */
|
||||
|
||||
|
||||
@@ -159,21 +159,21 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
|
||||
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
|
||||
/*! \brief This function prepares the sl indication to pass to the MAC
|
||||
*/
|
||||
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
|
||||
sl_nr_rx_indication_t *rx_ind,
|
||||
sl_nr_sci_indication_t *sci_ind,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
void *phy_data);
|
||||
void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
uint8_t pdu_type,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
uint16_t n_pdus,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
void *typeSpecific,
|
||||
uint16_t rx_slss_id);
|
||||
|
||||
|
||||
@@ -523,7 +523,8 @@ static void nr_ue_scheduled_response_ul(PHY_VARS_NR_UE *phy, fapi_nr_ul_config_r
|
||||
int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
|
||||
{
|
||||
PHY_VARS_NR_UE *phy = PHY_vars_UE_g[scheduled_response->module_id][scheduled_response->CC_id];
|
||||
AssertFatal(!scheduled_response->dl_config || !scheduled_response->ul_config,
|
||||
AssertFatal(!scheduled_response->dl_config || !scheduled_response->ul_config || !scheduled_response->sl_rx_config
|
||||
|| !scheduled_response->sl_tx_config,
|
||||
"phy_data parameter will be cast to two different types!\n");
|
||||
|
||||
if (scheduled_response->dl_config)
|
||||
@@ -533,6 +534,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
|
||||
(nr_phy_data_t *)scheduled_response->phy_data);
|
||||
if (scheduled_response->ul_config)
|
||||
nr_ue_scheduled_response_ul(phy, scheduled_response->ul_config, (nr_phy_data_tx_t *)scheduled_response->phy_data);
|
||||
|
||||
if (scheduled_response->sl_rx_config || scheduled_response->sl_tx_config) {
|
||||
sl_handle_scheduled_response(scheduled_response);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -552,3 +558,78 @@ void nr_ue_synch_request(nr_synch_request_t *synch_request)
|
||||
PHY_vars_UE_g[synch_request->Mod_id][synch_request->CC_id]->synch_request.received_synch_request = 1;
|
||||
}
|
||||
|
||||
void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config)
|
||||
{
|
||||
sl_nr_phy_config_request_t *sl_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->SL_UE_PHY_PARAMS.sl_config;
|
||||
if (phy_config != NULL) {
|
||||
memcpy(sl_config, &phy_config->sl_config_req, sizeof(sl_nr_phy_config_request_t));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MAC sends the scheduled response with either TX configrequest for Sidelink Transmission requests
|
||||
* or RX config request for Sidelink Reception requests.
|
||||
* This procedure handles these TX/RX config requests received in this slot and configures PHY
|
||||
* with a TTI action to be performed in this slot(TTI)
|
||||
*/
|
||||
void sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response)
|
||||
{
|
||||
module_id_t module_id = scheduled_response->module_id;
|
||||
const char *sl_rx_action[] = {"NONE", "RX_PSBCH", "RX_PSCCH", "RX_SCI2_ON_PSSCH", "RX_SLSCH_ON_PSSCH"};
|
||||
const char *sl_tx_action[] = {"TX_PSBCH", "TX_PSCCH_PSSCH", "TX_PSFCH"};
|
||||
|
||||
if (scheduled_response->sl_rx_config != NULL) {
|
||||
sl_nr_rx_config_request_t *sl_rx_config = scheduled_response->sl_rx_config;
|
||||
nr_phy_data_t *phy_data = (nr_phy_data_t *)scheduled_response->phy_data;
|
||||
|
||||
AssertFatal(sl_rx_config->number_pdus == SL_NR_RX_CONFIG_LIST_NUM, "sl_rx_config->number_pdus incorrect\n");
|
||||
|
||||
switch (sl_rx_config->sl_rx_config_list[0].pdu_type) {
|
||||
case SL_NR_CONFIG_TYPE_RX_PSBCH:
|
||||
phy_data->sl_rx_action = SL_NR_CONFIG_TYPE_RX_PSBCH;
|
||||
LOG_D(PHY, "Recvd CONFIG_TYPE_RX_PSBCH\n");
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Incorrect sl_rx config req pdutype \n");
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D(PHY,
|
||||
"[UE%d] TTI %d:%d, SL-RX action:%s\n",
|
||||
module_id,
|
||||
sl_rx_config->sfn,
|
||||
sl_rx_config->slot,
|
||||
sl_rx_action[phy_data->sl_rx_action]);
|
||||
|
||||
} else if (scheduled_response->sl_tx_config != NULL) {
|
||||
sl_nr_tx_config_request_t *sl_tx_config = scheduled_response->sl_tx_config;
|
||||
nr_phy_data_tx_t *phy_data_tx = (nr_phy_data_tx_t *)scheduled_response->phy_data;
|
||||
|
||||
AssertFatal(sl_tx_config->number_pdus == SL_NR_TX_CONFIG_LIST_NUM, "sl_tx_config->number_pdus incorrect \n");
|
||||
|
||||
switch (sl_tx_config->tx_config_list[0].pdu_type) {
|
||||
case SL_NR_CONFIG_TYPE_TX_PSBCH:
|
||||
phy_data_tx->sl_tx_action = SL_NR_CONFIG_TYPE_TX_PSBCH;
|
||||
LOG_D(PHY, "Recvd CONFIG_TYPE_TX_PSBCH\n");
|
||||
*((uint32_t *)phy_data_tx->psbch_vars.psbch_payload) =
|
||||
*((uint32_t *)sl_tx_config->tx_config_list[0].tx_psbch_config_pdu.psbch_payload);
|
||||
phy_data_tx->psbch_vars.psbch_tx_power = sl_tx_config->tx_config_list[0].tx_psbch_config_pdu.psbch_tx_power;
|
||||
phy_data_tx->psbch_vars.tx_slss_id = sl_tx_config->tx_config_list[0].tx_psbch_config_pdu.tx_slss_id;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0, "Incorrect sl_tx config req pdutype \n");
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D(PHY,
|
||||
"[UE%d] TTI %d:%d, SL-TX action:%s slss_id:%d, sl-mib:%x, psbch pwr:%d\n",
|
||||
module_id,
|
||||
sl_tx_config->sfn,
|
||||
sl_tx_config->slot,
|
||||
sl_tx_action[phy_data_tx->sl_tx_action - 6],
|
||||
phy_data_tx->psbch_vars.tx_slss_id,
|
||||
*((uint32_t *)phy_data_tx->psbch_vars.psbch_payload),
|
||||
phy_data_tx->psbch_vars.psbch_tx_power);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,12 +40,14 @@
|
||||
/**\brief NR UE FAPI-like P7 messages, scheduled response from L2 indicating L1
|
||||
\param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/
|
||||
int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response);
|
||||
void sl_handle_scheduled_response(nr_scheduled_response_t *scheduled_response);
|
||||
|
||||
int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response);
|
||||
|
||||
/**\brief NR UE FAPI-like P5 message, physical configuration from L2 to configure L1
|
||||
\param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/
|
||||
int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config);
|
||||
void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config);
|
||||
|
||||
/**\brief NR UE FAPI message to schedule a synchronization with target gNB
|
||||
\param synch_request including target_Nid_cell*/
|
||||
|
||||
@@ -76,3 +76,67 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_slot)
|
||||
// if here, all the symbols where DL
|
||||
return NR_DOWNLINK_SLOT;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function determines if the mixed slot is a Sidelink slot
|
||||
*/
|
||||
uint8_t sl_determine_if_sidelink_slot(uint8_t sl_startsym, uint8_t sl_lensym, uint8_t num_ulsym)
|
||||
{
|
||||
uint8_t ul_startsym = NR_NUMBER_OF_SYMBOLS_PER_SLOT - num_ulsym;
|
||||
|
||||
if ((sl_startsym >= ul_startsym) && (sl_lensym <= NR_NUMBER_OF_SYMBOLS_PER_SLOT)) {
|
||||
LOG_D(MAC,
|
||||
"MIXED SLOT is a SIDELINK SLOT. Sidelink Symbols: %d-%d, Uplink Symbols: %d-%d\n",
|
||||
sl_startsym,
|
||||
sl_lensym - 1,
|
||||
ul_startsym,
|
||||
ul_startsym + num_ulsym - 1);
|
||||
return NR_SIDELINK_SLOT;
|
||||
} else {
|
||||
LOG_D(MAC,
|
||||
"MIXED SLOT is NOT SIDELINK SLOT. Sidelink Symbols: %d-%d, Uplink Symbols: %d-%d\n",
|
||||
sl_startsym,
|
||||
sl_lensym - 1,
|
||||
ul_startsym,
|
||||
ul_startsym + num_ulsym - 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function determines if the Slot is a SIDELINK SLOT
|
||||
* Every Uplink Slot is a Sidelink slot
|
||||
* Mixed Slot is a sidelink slot if the uplink symbols in Mixed slot
|
||||
* overlaps with Sidelink start symbol and number of symbols.
|
||||
*/
|
||||
int sl_nr_ue_slot_select(sl_nr_phy_config_request_t *cfg, int slot, uint8_t frame_duplex_type)
|
||||
{
|
||||
int ul_sym = 0, slot_type = 0;
|
||||
|
||||
// All PC5 bands are TDD bands , hence handling only TDD in this function.
|
||||
AssertFatal(frame_duplex_type == TDD, "No Sidelink operation defined for FDD in 3GPP rel16\n");
|
||||
|
||||
if (cfg->tdd_table.max_tdd_periodicity_list == NULL) { // this happens before receiving TDD configuration
|
||||
return slot_type;
|
||||
}
|
||||
|
||||
int period = cfg->tdd_table.tdd_period_in_slots;
|
||||
int rel_slot = slot % period;
|
||||
fapi_nr_tdd_table_t *tdd_table = &cfg->tdd_table;
|
||||
|
||||
fapi_nr_max_tdd_periodicity_t *current_slot = &tdd_table->max_tdd_periodicity_list[rel_slot];
|
||||
|
||||
for (int symbol_count = 0; symbol_count < NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
|
||||
if (current_slot->max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) {
|
||||
ul_sym++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ul_sym == NR_NUMBER_OF_SYMBOLS_PER_SLOT) {
|
||||
slot_type = NR_SIDELINK_SLOT;
|
||||
} else if (ul_sym) {
|
||||
slot_type = sl_determine_if_sidelink_slot(cfg->sl_bwp_config.sl_start_symbol, cfg->sl_bwp_config.sl_num_symbols, ul_sym);
|
||||
}
|
||||
|
||||
return slot_type;
|
||||
}
|
||||
@@ -288,7 +288,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
pucch_procedures_ue_nr(ue, proc, phy_data, (c16_t **)&txdataF);
|
||||
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, &ue->frame_parms, ue->frame_parms.nb_antennas_tx, (c16_t **)txdataF);
|
||||
nr_ue_pusch_common_procedures(ue,
|
||||
proc->nr_slot_tx,
|
||||
&ue->frame_parms,
|
||||
ue->frame_parms.nb_antennas_tx,
|
||||
(c16_t **)txdataF,
|
||||
link_type_ul);
|
||||
|
||||
nr_ue_prach_procedures(ue, proc);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
|
||||
sl_nr_rx_indication_t *rx_ind,
|
||||
sl_nr_sci_indication_t *sci_ind,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
void *phy_data)
|
||||
{
|
||||
@@ -49,6 +49,7 @@ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
|
||||
sl_ind->frame_tx = proc->frame_tx;
|
||||
sl_ind->slot_tx = proc->nr_slot_tx;
|
||||
sl_ind->phy_data = phy_data;
|
||||
sl_ind->slot_type = SIDELINK_SLOT_TYPE_RX;
|
||||
|
||||
if (rx_ind) {
|
||||
sl_ind->rx_ind = rx_ind; // hang on rx_ind instance
|
||||
@@ -64,12 +65,12 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
uint8_t pdu_type,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
uint16_t n_pdus,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
void *typeSpecific,
|
||||
uint16_t rx_slss_id)
|
||||
{
|
||||
if (n_pdus > 1) {
|
||||
LOG_E(PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__);
|
||||
LOG_E(NR_PHY, "In %s: multiple number of SL PDUs not supported yet...\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
|
||||
@@ -85,7 +86,7 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
ssb_pdu->rsrp_dbm = sl_phy_params->psbch.rsrp_dBm_per_RE;
|
||||
ssb_pdu->rx_slss_id = rx_slss_id;
|
||||
ssb_pdu->decode_status = true;
|
||||
LOG_D(PHY,
|
||||
LOG_D(NR_PHY,
|
||||
"SL-IND: SSB to MAC. rsrp:%d, slssid:%d, payload:%x\n",
|
||||
ssb_pdu->rsrp_dbm,
|
||||
ssb_pdu->rx_slss_id,
|
||||
@@ -103,7 +104,7 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
|
||||
static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
int estimateSz,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
nr_phy_data_t *phy_data,
|
||||
@@ -120,7 +121,7 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PSBCH_PROCEDURES, VCD_FUNCTION_IN);
|
||||
|
||||
LOG_D(PHY,
|
||||
LOG_D(NR_PHY,
|
||||
"[UE %d] Frame %d Slot %d, Trying PSBCH (SLSS ID %d)\n",
|
||||
ue->Mod_id,
|
||||
frame_rx,
|
||||
@@ -144,11 +145,11 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
uint8_t *result = NULL;
|
||||
if (ret) {
|
||||
sl_phy_params->psbch.rx_errors++;
|
||||
LOG_E(PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx);
|
||||
LOG_E(NR_PHY, "%d:%d PSBCH RX: NOK \n", proc->frame_rx, proc->nr_slot_rx);
|
||||
} else {
|
||||
result = decoded_pdu;
|
||||
sl_phy_params->psbch.rx_ok++;
|
||||
LOG_D(PHY, "%d:%d PSBCH RX: OK \n", proc->frame_rx, proc->nr_slot_rx);
|
||||
LOG_I(NR_PHY, "%d:%d PSBCH RX:OK. RSRP: %d dB/RE\n", proc->frame_rx, proc->nr_slot_rx, sl_phy_params->psbch.rsrp_dB_per_RE);
|
||||
}
|
||||
|
||||
nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data);
|
||||
@@ -161,7 +162,7 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
{
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
@@ -172,7 +173,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX_SL, VCD_FUNCTION_IN);
|
||||
start_meas(&sl_phy_params->phy_proc_sl_rx);
|
||||
|
||||
LOG_D(PHY, " ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx % 1024, nr_slot_rx);
|
||||
LOG_D(NR_PHY, " ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx % 1024, nr_slot_rx);
|
||||
|
||||
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
|
||||
@@ -181,7 +182,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
|
||||
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_IN);
|
||||
LOG_D(PHY, " ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
LOG_D(NR_PHY, " ----- PSBCH RX TTI: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
|
||||
__attribute__((aligned(32))) struct complex16 dl_ch_estimates[fp->nb_antennas_rx][estimateSz];
|
||||
__attribute__((aligned(32))) struct complex16 dl_ch_estimates_time[fp->nb_antennas_rx][fp->ofdm_symbol_size];
|
||||
@@ -190,7 +191,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
const int numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
|
||||
|
||||
for (int sym = 0; sym < numsym;) {
|
||||
nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul);
|
||||
nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_sl);
|
||||
|
||||
start_meas(&sl_phy_params->channel_estimation_stats);
|
||||
nr_pbch_channel_estimation(fp,
|
||||
@@ -211,7 +212,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
stop_meas(&sl_phy_params->channel_estimation_stats);
|
||||
if (sym == 12)
|
||||
UEscopeCopy(ue,
|
||||
pbchDlChEstimateTime,
|
||||
psbchDlChEstimateTime,
|
||||
(void *)dl_ch_estimates_time,
|
||||
sizeof(c16_t),
|
||||
fp->nb_antennas_rx,
|
||||
@@ -224,17 +225,17 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
|
||||
nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false);
|
||||
|
||||
LOG_D(PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
|
||||
const int psbchSuccess = nr_ue_psbch_procedures(ue, fp, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF);
|
||||
|
||||
if (ue->no_timing_correction == 0 && psbchSuccess == 0) {
|
||||
LOG_D(PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
|
||||
LOG_D(NR_PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
|
||||
sampleShift =
|
||||
nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384);
|
||||
}
|
||||
|
||||
LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
|
||||
LOG_D(NR_PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
|
||||
// nr_ue_rrc_measurements(ue, proc, rxdataF);
|
||||
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PSBCH, VCD_FUNCTION_OUT);
|
||||
|
||||
@@ -254,10 +255,12 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
|
||||
}
|
||||
}
|
||||
|
||||
UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), fp->nb_antennas_rx, rxdataF_sz, 0);
|
||||
|
||||
return sampleShift;
|
||||
}
|
||||
|
||||
int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data)
|
||||
{
|
||||
int slot_tx = proc->nr_slot_tx;
|
||||
int frame_tx = proc->frame_tx;
|
||||
@@ -275,7 +278,7 @@ int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_ph
|
||||
for (int i = 0; i < fp->nb_antennas_tx; ++i)
|
||||
txdataF[i] = &txdataF_buf[i * samplesF_per_slot];
|
||||
|
||||
LOG_D(PHY, "****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
LOG_D(NR_PHY, "****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
start_meas(&sl_phy_params->phy_proc_sl_tx);
|
||||
|
||||
@@ -302,14 +305,13 @@ int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_ph
|
||||
}
|
||||
|
||||
if (tx_action) {
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF);
|
||||
LOG_D(NR_PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, link_type_sl);
|
||||
}
|
||||
|
||||
LOG_D(PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_SL, VCD_FUNCTION_OUT);
|
||||
stop_meas(&sl_phy_params->phy_proc_sl_tx);
|
||||
|
||||
return tx_action;
|
||||
}
|
||||
|
||||
@@ -57,3 +57,15 @@ void *rrc_nrue(void *notUsed)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
int8_t nr_mac_rrc_sl_mib_ind(const module_id_t module_id,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_index,
|
||||
const frame_t frame,
|
||||
const int slot,
|
||||
const int channel,
|
||||
const uint8_t *pduP,
|
||||
const sdu_size_t pdu_len,
|
||||
const uint16_t rx_slss_id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -89,6 +89,12 @@ uint8_t check_if_ue_is_sl_syncsource()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
|
||||
NR_SL_SSB_TimeAllocation_r16_t *ssb_ta,
|
||||
uint16_t rx_slss_id,
|
||||
uint8_t *sl_mib)
|
||||
{
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static void prepare_mib_bits(uint8_t *buf, uint32_t frame_tx, uint32_t slot_tx)
|
||||
{
|
||||
@@ -178,7 +184,8 @@ static void sl_init_frame_parameters(PHY_VARS_NR_UE *UE)
|
||||
sl_fp->att_tx = 1;
|
||||
sl_fp->att_rx = 1;
|
||||
// band47 //UL freq will be set to Sidelink freq
|
||||
sl_fp->ul_CarrierFreq = 5880000000;
|
||||
sl_fp->sl_CarrierFreq = 5880000000;
|
||||
sl_fp->N_RB_SL = sl_fp->N_RB_DL;
|
||||
|
||||
sl_fp->ssb_start_subcarrier = UE->SL_UE_PHY_PARAMS.sl_config.sl_bwp_config.sl_ssb_offset_point_a;
|
||||
sl_fp->Nid_cell = UE->SL_UE_PHY_PARAMS.sl_config.sl_sync_source.rx_slss_id;
|
||||
@@ -202,7 +209,7 @@ static void configure_SL_UE(PHY_VARS_NR_UE *UE, int mu, int N_RB, int ssb_offset
|
||||
|
||||
sl_init_frame_parameters(UE);
|
||||
sl_ue_phy_init(UE);
|
||||
init_symbol_rotation(fp);
|
||||
perform_symbol_rotation(fp, fp->sl_CarrierFreq, fp->symbol_rotation[link_type_sl]);
|
||||
init_timeshift_rotation(fp);
|
||||
LOG_I(PHY, "Dumping Sidelink Frame Parameters\n");
|
||||
nr_dump_frame_parms(fp);
|
||||
|
||||
Reference in New Issue
Block a user