Merge remote-tracking branch 'origin/develop' into nr_power_measurement_fixes
This commit is contained in:
+42
-17
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/phy_extern.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
@@ -45,10 +46,42 @@
|
||||
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
/*
|
||||
extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
*/
|
||||
static
|
||||
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
|
||||
{
|
||||
const uint64_t dl_freq_khz = downlink_frequency / 1000;
|
||||
const int32_t delta_duplex_khz = delta_duplex / 1000;
|
||||
|
||||
uint64_t center_freq_diff_khz = 999999999999999999; // 2^64
|
||||
uint16_t current_band = 0;
|
||||
|
||||
for (int ind = 0; ind < nr_bandtable_size; ind++) {
|
||||
|
||||
LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min);
|
||||
|
||||
if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
|
||||
continue;
|
||||
|
||||
int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
|
||||
|
||||
if (current_offset_khz != delta_duplex_khz)
|
||||
continue;
|
||||
|
||||
uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
|
||||
|
||||
if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
|
||||
current_band = nr_bandtable[ind].band;
|
||||
center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
|
||||
downlink_frequency, current_band, downlink_frequency+delta_duplex);
|
||||
|
||||
AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex);
|
||||
|
||||
return current_band;
|
||||
}
|
||||
|
||||
int l1_north_init_gNB() {
|
||||
|
||||
@@ -431,8 +464,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
|
||||
|
||||
gNB->mac_enabled = 1;
|
||||
if (mu==1) {
|
||||
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
|
||||
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||
fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
|
||||
fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||
fp->nr_band = 78;
|
||||
// fp->threequarter_fs= 0;
|
||||
} else if (mu==3) {
|
||||
@@ -455,7 +488,6 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
||||
uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
|
||||
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
|
||||
int32_t dlul_offset = 0;
|
||||
|
||||
memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg));
|
||||
RC.gNB[Mod_id]->mac_enabled = 1;
|
||||
@@ -466,16 +498,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
||||
uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<<gNB_config->ssb_config.scs_common.value);
|
||||
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
|
||||
|
||||
//fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
lte_frame_type_t frame_type = 0; // FDD
|
||||
|
||||
get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); //RC.nrmac[Mod_id] cannot be accessed in NFAPI
|
||||
int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq;
|
||||
fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset);
|
||||
|
||||
get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset);
|
||||
dlul_offset *= 1000;
|
||||
|
||||
AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_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 + dlul_offset);
|
||||
|
||||
LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset);
|
||||
|
||||
fp->threequarter_fs = openair0_cfg[0].threequarter_fs;
|
||||
@@ -504,7 +529,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
||||
// }
|
||||
RC.gNB[Mod_id]->configured = 1;
|
||||
|
||||
init_symbol_rotation(fp,fp->dl_CarrierFreq);
|
||||
init_symbol_rotation(fp);
|
||||
|
||||
LOG_I(PHY,"gNB %d configured\n",Mod_id);
|
||||
}
|
||||
|
||||
@@ -507,50 +507,36 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
|
||||
if (fp->frame_type == FDD) {
|
||||
ue->N_TA_offset = 0;
|
||||
} else {
|
||||
int N_RB = fp->N_RB_DL;
|
||||
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
|
||||
double factor = 1;
|
||||
|
||||
double factor = 1.0;
|
||||
switch (fp->numerology_index) {
|
||||
case 0: //15 kHz scs
|
||||
AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
|
||||
if (N_RB <= 25) factor = .25; // 7.68 Ms/s
|
||||
else if (N_RB <=50) factor = .5; // 15.36 Ms/s
|
||||
else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
|
||||
else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
|
||||
else AssertFatal(1==0, "Too many PRBS for mu=0\n");
|
||||
factor = fp->samples_per_subframe / 30720.0;
|
||||
break;
|
||||
case 1: //30 kHz sc
|
||||
AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
|
||||
if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
|
||||
else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
|
||||
factor = fp->samples_per_subframe / 30720.0;
|
||||
break;
|
||||
case 2: //60 kHz scs
|
||||
AssertFatal(1==0, "scs_common should not be 60 kHz\n");
|
||||
break;
|
||||
case 3: //120 kHz scs
|
||||
AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
|
||||
factor = fp->samples_per_subframe / 61440.0;
|
||||
break;
|
||||
case 4: //240 kHz scs
|
||||
AssertFatal(1==0, "scs_common should not be 60 kHz\n");
|
||||
if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
|
||||
else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
|
||||
else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB);
|
||||
AssertFatal(N_TA_offset == 431, "scs_common 240kHz only for FR2\n");
|
||||
factor = fp->samples_per_subframe / 61440.0;
|
||||
break;
|
||||
|
||||
if (N_RB == 100)
|
||||
ue->N_TA_offset = 624;
|
||||
else if (N_RB == 50)
|
||||
ue->N_TA_offset = 624/2;
|
||||
else if (N_RB == 25)
|
||||
ue->N_TA_offset = 624/4;
|
||||
default:
|
||||
AssertFatal(1==0, "Invalid scs_common!\n");
|
||||
}
|
||||
|
||||
if (fp->threequarter_fs == 1)
|
||||
factor = factor*.75;
|
||||
|
||||
ue->N_TA_offset = (int)(N_TA_offset * factor);
|
||||
|
||||
LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB);
|
||||
LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d, mu %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, fp->N_RB_DL, fp->numerology_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-100
@@ -75,9 +75,8 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
|
||||
return symbol;
|
||||
}
|
||||
|
||||
void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
|
||||
void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL)
|
||||
{
|
||||
|
||||
switch(mu) {
|
||||
|
||||
case NR_MU_0: //15kHz scs
|
||||
@@ -99,108 +98,17 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
|
||||
else
|
||||
AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
|
||||
}
|
||||
|
||||
switch(bw){
|
||||
case 5:
|
||||
case 15:
|
||||
case 20:
|
||||
case 25:
|
||||
case 30:
|
||||
case 40: //40 MHz
|
||||
if (fp->threequarter_fs) {
|
||||
fp->ofdm_symbol_size = 1536;
|
||||
fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 132;
|
||||
fp->nb_prefix_samples = 108;
|
||||
}
|
||||
else {
|
||||
fp->ofdm_symbol_size = 2048;
|
||||
fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 176;
|
||||
fp->nb_prefix_samples = 144;
|
||||
}
|
||||
break;
|
||||
|
||||
case 50:
|
||||
case 60:
|
||||
case 70:
|
||||
|
||||
case 80: //80 MHz
|
||||
if (fp->threequarter_fs) {
|
||||
fp->ofdm_symbol_size = 3072;
|
||||
fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 264;
|
||||
fp->nb_prefix_samples = 216;
|
||||
}
|
||||
else {
|
||||
fp->ofdm_symbol_size = 4096;
|
||||
fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 352;
|
||||
fp->nb_prefix_samples = 288;
|
||||
}
|
||||
break;
|
||||
|
||||
case 90:
|
||||
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
|
||||
fp->ofdm_symbol_size = 4096;
|
||||
fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 352;
|
||||
fp->nb_prefix_samples = 288;
|
||||
break;
|
||||
case 100:
|
||||
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for %d MHz band and MU %d\n",bw,mu);
|
||||
fp->ofdm_symbol_size = 4096;
|
||||
fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 352;
|
||||
fp->nb_prefix_samples = 288;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_MU_2: //60kHz scs
|
||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
|
||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
|
||||
|
||||
switch(bw){ //FR1 bands only
|
||||
case 10:
|
||||
case 15:
|
||||
case 20:
|
||||
case 25:
|
||||
case 30:
|
||||
case 40:
|
||||
case 50:
|
||||
case 60:
|
||||
case 70:
|
||||
case 80:
|
||||
case 90:
|
||||
case 100:
|
||||
default:
|
||||
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_MU_3:
|
||||
fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
|
||||
fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
|
||||
fp->ssb_type = nr_ssb_type_D;
|
||||
switch(bw){
|
||||
case 100:
|
||||
fp->ofdm_symbol_size = 1024;
|
||||
fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 136;
|
||||
fp->nb_prefix_samples = 72;
|
||||
break;
|
||||
case 50:
|
||||
fp->ofdm_symbol_size = 512;
|
||||
fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 )
|
||||
fp->nb_prefix_samples0 = 68;
|
||||
fp->nb_prefix_samples = 36;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"%d MHz band undefined for mu %d, frame parms = %p\n", bw, mu, fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_MU_4:
|
||||
@@ -209,9 +117,21 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw)
|
||||
fp->ssb_type = nr_ssb_type_E;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid numerology index %d", mu);
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid numerology index %d", 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_DL * 12)
|
||||
fp->ofdm_symbol_size <<= 1;
|
||||
|
||||
fp->first_carrier_offset = fp->ofdm_symbol_size - (N_RB_DL * 12 / 2);
|
||||
fp->nb_prefix_samples = fp->ofdm_symbol_size / 128 * 9;
|
||||
fp->nb_prefix_samples0 = fp->ofdm_symbol_size / 128 * (9 + (1 << mu));
|
||||
}
|
||||
|
||||
uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
|
||||
@@ -280,7 +200,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg,
|
||||
fp->half_frame_bit = 0; // half frame bit initialized to 0 here
|
||||
fp->numerology_index = mu;
|
||||
|
||||
set_scs_parameters(fp, mu, cfg->carrier_config.dl_bandwidth.value);
|
||||
set_scs_parameters(fp, mu, fp->N_RB_DL);
|
||||
|
||||
fp->slots_per_frame = 10* fp->slots_per_subframe;
|
||||
|
||||
@@ -352,9 +272,8 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
|
||||
fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index];
|
||||
fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];
|
||||
|
||||
int32_t uplink_frequency_offset = 0;
|
||||
get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset);
|
||||
get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type);
|
||||
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;
|
||||
|
||||
LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
|
||||
@@ -374,7 +293,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
|
||||
|
||||
fp->Ncp = Ncp;
|
||||
|
||||
set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth);
|
||||
set_scs_parameters(fp, fp->numerology_index, fp->N_RB_DL);
|
||||
|
||||
fp->slots_per_frame = 10* fp->slots_per_subframe;
|
||||
fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
|
||||
|
||||
@@ -51,16 +51,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
|
||||
int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
unsigned char l,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix);
|
||||
unsigned char Ns);
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix);
|
||||
int sample_offset);
|
||||
|
||||
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
|
||||
unsigned char l,
|
||||
|
||||
@@ -591,35 +591,63 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
|
||||
}
|
||||
|
||||
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) {
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
|
||||
|
||||
uint64_t dl_CarrierFreq = fp->dl_CarrierFreq;
|
||||
uint64_t ul_CarrierFreq = fp->ul_CarrierFreq;
|
||||
double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq};
|
||||
|
||||
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 f0= (double)CarrierFreq;
|
||||
const double Ncp0=16*64 + (144*64*(1/(float)(1<<fp->numerology_index)));
|
||||
const double Ncp1=(144*64*(1/(float)(1<<fp->numerology_index)));
|
||||
double tl=0,poff,exp_re,exp_im;
|
||||
double Ncp,Ncpm1=Ncp0;
|
||||
|
||||
poff = 2*M_PI*((Ncp0*Tc))*f0;
|
||||
exp_re = cos(poff);
|
||||
exp_im = sin(-poff);
|
||||
fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767);
|
||||
fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767);
|
||||
LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb);
|
||||
LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]);
|
||||
for (int l=1;l<nsymb;l++) {
|
||||
if (l==(7*(1<<fp->numerology_index))) Ncp=Ncp0;
|
||||
else Ncp=Ncp1;
|
||||
tl += (Nu+Ncpm1)*Tc;
|
||||
poff = 2*M_PI*(tl + (Ncp*Tc))*f0;
|
||||
exp_re = cos(poff);
|
||||
exp_im = sin(-poff);
|
||||
fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767);
|
||||
fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767);
|
||||
LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",l,nsymb,tl,fp->symbol_rotation[l<<1],fp->symbol_rotation[1+(l<<1)],
|
||||
(poff/2/M_PI)-floor(poff/2/M_PI));
|
||||
Ncpm1=Ncp;
|
||||
for (uint8_t ll = 0; ll < 2; ll++){
|
||||
|
||||
double f0 = f[ll];
|
||||
double Ncpm1 = Ncp0;
|
||||
int16_t *symbol_rotation = fp->symbol_rotation[ll];
|
||||
|
||||
double tl = 0;
|
||||
double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0;
|
||||
double exp_re = cos(poff);
|
||||
double exp_im = sin(-poff);
|
||||
symbol_rotation[0] = (int16_t)floor(exp_re * 32767);
|
||||
symbol_rotation[1] = (int16_t)floor(exp_im * 32767);
|
||||
LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
|
||||
LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n",
|
||||
0,
|
||||
nsymb,
|
||||
symbol_rotation[0],
|
||||
symbol_rotation[1]);
|
||||
|
||||
for (int l = 1; l < nsymb; l++) {
|
||||
|
||||
double Ncp;
|
||||
if (l == (7 * (1 << fp->numerology_index))) {
|
||||
Ncp = Ncp0;
|
||||
} else {
|
||||
Ncp = Ncp1;
|
||||
}
|
||||
|
||||
tl += (Nu + Ncpm1) * Tc;
|
||||
poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0;
|
||||
exp_re = cos(poff);
|
||||
exp_im = sin(-poff);
|
||||
symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767);
|
||||
symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767);
|
||||
|
||||
LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",
|
||||
l,
|
||||
nsymb,
|
||||
tl,
|
||||
symbol_rotation[l<<1],
|
||||
symbol_rotation[1 + (l<<1)],
|
||||
(poff / 2 / M_PI) - floor(poff / 2 / M_PI));
|
||||
|
||||
Ncpm1 = Ncp;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
|
||||
\param symbol symbol within slot (0..12/14)
|
||||
\param Ns Slot number (0..19)
|
||||
\param sample_offset offset within rxdata (points to beginning of subframe)
|
||||
\param no_prefix if 1 prefix is removed by HW
|
||||
*/
|
||||
|
||||
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -82,8 +81,7 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *rxdataF,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix);
|
||||
int sample_offset);
|
||||
|
||||
/*!
|
||||
\brief This function implements the dft transform precoding in PUSCH
|
||||
@@ -110,7 +108,7 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
|
||||
int nsymb,
|
||||
int length);
|
||||
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq);
|
||||
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
|
||||
|
||||
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *rxdataF,
|
||||
|
||||
@@ -306,15 +306,23 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
|
||||
int length) {
|
||||
int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot;
|
||||
|
||||
int16_t *symbol_rotation = fp->symbol_rotation[0];
|
||||
|
||||
for (int sidx=0;sidx<nsymb;sidx++) {
|
||||
|
||||
LOG_D(PHY,"Rotating symbol %d, slot %d, symbol_subframe_index %d, length %d (%d,%d)\n",
|
||||
first_symbol+sidx,slot,sidx+first_symbol+symb_offset,length,
|
||||
fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]);
|
||||
rotate_cpx_vector(trxdata+(sidx*length*2),
|
||||
&fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],
|
||||
trxdata+(sidx*length*2),
|
||||
length,
|
||||
15);
|
||||
first_symbol + sidx,
|
||||
slot,
|
||||
sidx + first_symbol + symb_offset,
|
||||
length,
|
||||
symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
|
||||
symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]);
|
||||
|
||||
rotate_cpx_vector(trxdata + (sidx * length * 2),
|
||||
&symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
|
||||
trxdata + (sidx * length * 2),
|
||||
length,
|
||||
15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,364 +29,121 @@
|
||||
|
||||
//#define DEBUG_FEP
|
||||
|
||||
#define SOFFSET 0
|
||||
|
||||
/*#ifdef LOG_I
|
||||
#undef LOG_I
|
||||
#define LOG_I(A,B...) printf(A)
|
||||
#endif*/
|
||||
|
||||
dft_size_idx_t get_dft_size_idx(uint16_t ofdm_symbol_size)
|
||||
{
|
||||
switch (ofdm_symbol_size) {
|
||||
case 128:
|
||||
return DFT_128;
|
||||
|
||||
case 256:
|
||||
return DFT_256;
|
||||
|
||||
case 512:
|
||||
return DFT_512;
|
||||
|
||||
case 1024:
|
||||
return DFT_1024;
|
||||
|
||||
case 1536:
|
||||
return DFT_1536;
|
||||
|
||||
case 2048:
|
||||
return DFT_2048;
|
||||
|
||||
case 3072:
|
||||
return DFT_3072;
|
||||
|
||||
case 4096:
|
||||
return DFT_4096;
|
||||
|
||||
case 6144:
|
||||
return DFT_6144;
|
||||
|
||||
case 8192:
|
||||
return DFT_8192;
|
||||
|
||||
default:
|
||||
printf("unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return DFT_SIZE_IDXTABLESIZE;
|
||||
}
|
||||
|
||||
int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix)
|
||||
unsigned char Ns)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
unsigned char aa;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
|
||||
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
|
||||
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
|
||||
|
||||
unsigned int nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0;
|
||||
unsigned int abs_symbol;
|
||||
if (ue->is_synchronized) {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
}
|
||||
else {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
}
|
||||
//unsigned int subframe_offset;//,subframe_offset_F;
|
||||
unsigned int slot_offset;
|
||||
//int i;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||
unsigned int rx_offset;
|
||||
|
||||
|
||||
dft_size_idx_t dftsize;
|
||||
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dftsize = DFT_128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
dftsize = DFT_256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
dftsize = DFT_512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
dftsize = DFT_1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
dftsize = DFT_1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
dftsize = DFT_2048;
|
||||
break;
|
||||
|
||||
case 3072:
|
||||
dftsize = DFT_3072;
|
||||
break;
|
||||
|
||||
case 4096:
|
||||
dftsize = DFT_4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
dftsize = DFT_8192;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (no_prefix) {
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
||||
} else {
|
||||
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
|
||||
}
|
||||
|
||||
/*if (l<0 || l>=7-frame_parms->Ncp) {
|
||||
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
|
||||
return(-1);
|
||||
}*/
|
||||
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
|
||||
// This is for misalignment issues
|
||||
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
|
||||
|
||||
if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
|
||||
printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
|
||||
return(-1);
|
||||
}
|
||||
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
|
||||
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
rx_offset = sample_offset + slot_offset - SOFFSET;
|
||||
// Align with 256 bit
|
||||
// rx_offset = rx_offset&0xfffffff8;
|
||||
// use OFDM symbol from within 1/8th of the CP to avoid ISI
|
||||
rx_offset -= nb_prefix_samples / 8;
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
/*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
|
||||
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
|
||||
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
|
||||
#endif
|
||||
|
||||
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
|
||||
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
|
||||
if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
|
||||
|
||||
rx_offset += nb_prefix_samples;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(short*) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft(dftsize,(int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
||||
rx_offset += nb_prefix_samples0;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(void *) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft(dftsize,(int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
|
||||
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
}
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
|
||||
|
||||
// if input to dft is not 256-bit aligned
|
||||
if ((rx_offset & 7) != 0) {
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||
|
||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: symbol %d rx_offset %u\n", symbol, rx_offset);
|
||||
#endif
|
||||
|
||||
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
|
||||
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
|
||||
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
|
||||
rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
(int16_t*)&rot2,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
unsigned char aa;
|
||||
unsigned int nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0;
|
||||
unsigned int abs_symbol;
|
||||
if (ue->is_synchronized) {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
}
|
||||
else {
|
||||
nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
}
|
||||
//unsigned int subframe_offset;//,subframe_offset_F;
|
||||
unsigned int slot_offset;
|
||||
//int i;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||
unsigned int rx_offset;
|
||||
|
||||
|
||||
dft_size_idx_t dftsize;
|
||||
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dftsize = DFT_128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
dftsize = DFT_256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
dftsize = DFT_512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
dftsize = DFT_1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
dftsize = DFT_1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
dftsize = DFT_2048;
|
||||
break;
|
||||
|
||||
case 3072:
|
||||
dftsize = DFT_3072;
|
||||
break;
|
||||
|
||||
case 4096:
|
||||
dftsize = DFT_4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
dftsize = DFT_8192;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (no_prefix) {
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_slot) * (Ns);
|
||||
} else {
|
||||
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
}
|
||||
|
||||
/*if (l<0 || l>=7-frame_parms->Ncp) {
|
||||
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
|
||||
return(-1);
|
||||
}*/
|
||||
|
||||
if (Ns<0 || Ns>(frame_parms->slots_per_frame-1)) {
|
||||
printf("slot_fep: Ns must be between 0 and %d\n",frame_parms->slots_per_frame-1);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
rx_offset = sample_offset + slot_offset - SOFFSET;
|
||||
// Align with 256 bit
|
||||
// rx_offset = rx_offset&0xfffffff8;
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
/*LOG_I(PHY,*/printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
|
||||
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
|
||||
#endif
|
||||
|
||||
abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb < abs_symbol; idx_symb++)
|
||||
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
|
||||
if (abs_symbol%(0x7<<frame_parms->numerology_index)) {
|
||||
|
||||
rx_offset += nb_prefix_samples;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((short*) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(short*) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft(dftsize,(int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
dft(dftsize,
|
||||
rxdata_ptr,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
1);
|
||||
|
||||
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
||||
rx_offset += nb_prefix_samples0;
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((void *) &common_vars->rxdata[aa][frame_length_samples],
|
||||
(void *) &common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft(dftsize,(int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
}
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
|
||||
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
|
||||
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset];
|
||||
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
@@ -400,14 +157,121 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
return(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
|
||||
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
|
||||
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
|
||||
|
||||
unsigned int nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0;
|
||||
if (ue->is_synchronized) {
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
||||
}
|
||||
else {
|
||||
nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
|
||||
}
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_frame;
|
||||
|
||||
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
|
||||
// This is for misalignment issues
|
||||
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
|
||||
|
||||
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
unsigned int rx_offset = sample_offset + slot_offset;
|
||||
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
|
||||
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
|
||||
rx_offset += (abs_symbol%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
|
||||
rx_offset += frame_parms->ofdm_symbol_size * symbol;
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, slot_offset %u, sample_offset %d,rx_offset %u, frame_length_samples %u\n",
|
||||
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, slot_offset, sample_offset, rx_offset, frame_length_samples);
|
||||
#endif
|
||||
|
||||
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
|
||||
|
||||
int16_t *rxdata_ptr;
|
||||
|
||||
if (frame_length_samples - rx_offset < frame_parms->ofdm_symbol_size) {
|
||||
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&common_vars->rxdata[aa][rx_offset],
|
||||
(frame_length_samples - rx_offset) * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[frame_length_samples - rx_offset],
|
||||
(void *)&common_vars->rxdata[aa][0],
|
||||
(frame_parms->ofdm_symbol_size - (frame_length_samples - rx_offset)) * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
|
||||
|
||||
} else if ((rx_offset & 7) != 0) {
|
||||
|
||||
// if input to dft is not 256-bit aligned
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&common_vars->rxdata[aa][rx_offset],
|
||||
frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
|
||||
|
||||
} else {
|
||||
|
||||
// use dft input from RX buffer directly
|
||||
rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
|
||||
|
||||
}
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
dft(dftsize,
|
||||
rxdata_ptr,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
1);
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
|
||||
int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
|
||||
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
|
||||
symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
|
||||
#endif
|
||||
|
||||
rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
(int16_t*)&rot2,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -416,89 +280,60 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *rxdataF,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix)
|
||||
int sample_offset)
|
||||
{
|
||||
int32_t slot_offset, rxdata_offset;
|
||||
|
||||
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
|
||||
unsigned int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
||||
|
||||
int tmp_dft_in[8192] __attribute__ ((aligned (32)));
|
||||
dft_size_idx_t dftsize = get_dft_size_idx(frame_parms->ofdm_symbol_size);
|
||||
// This is for misalignment issues
|
||||
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
|
||||
|
||||
dft_size_idx_t dftsize;
|
||||
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dftsize = DFT_128;
|
||||
break;
|
||||
// offset of first OFDM symbol
|
||||
int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
|
||||
// offset of n-th OFDM symbol
|
||||
rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
|
||||
// use OFDM symbol from within 1/8th of the CP to avoid ISI
|
||||
rxdata_offset -= nb_prefix_samples / 8;
|
||||
|
||||
case 256:
|
||||
dftsize = DFT_256;
|
||||
break;
|
||||
int16_t *rxdata_ptr;
|
||||
|
||||
case 512:
|
||||
dftsize = DFT_512;
|
||||
break;
|
||||
if(sample_offset > rxdata_offset) {
|
||||
|
||||
case 1024:
|
||||
dftsize = DFT_1024;
|
||||
break;
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&rxdata[frame_parms->samples_per_frame - sample_offset + rxdata_offset],
|
||||
(sample_offset - rxdata_offset) * sizeof(int32_t));
|
||||
memcpy((void *)&tmp_dft_in[sample_offset - rxdata_offset],
|
||||
(void *)&rxdata[0],
|
||||
(frame_parms->ofdm_symbol_size - sample_offset + rxdata_offset) * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
|
||||
|
||||
case 1536:
|
||||
dftsize = DFT_1536;
|
||||
break;
|
||||
} else if (((rxdata_offset - sample_offset) & 7) != 0) {
|
||||
|
||||
case 2048:
|
||||
dftsize = DFT_2048;
|
||||
break;
|
||||
// if input to dft is not 256-bit aligned
|
||||
memcpy((void *)&tmp_dft_in[0],
|
||||
(void *)&rxdata[rxdata_offset - sample_offset],
|
||||
(frame_parms->ofdm_symbol_size) * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)&tmp_dft_in[0];
|
||||
|
||||
case 4096:
|
||||
dftsize = DFT_4096;
|
||||
break;
|
||||
} else {
|
||||
|
||||
case 8192:
|
||||
dftsize = DFT_8192;
|
||||
break;
|
||||
// use dft input from RX buffer directly
|
||||
rxdata_ptr = (int16_t *)&rxdata[rxdata_offset - sample_offset];
|
||||
|
||||
default:
|
||||
dftsize = DFT_512;
|
||||
break;
|
||||
}
|
||||
|
||||
slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
|
||||
|
||||
if(symbol == 0)
|
||||
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
|
||||
else
|
||||
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
|
||||
|
||||
if(sample_offset>rxdata_offset) {
|
||||
memcpy1((void *)tmp_dft_in,
|
||||
(void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset],
|
||||
(sample_offset-rxdata_offset)*sizeof(int));
|
||||
|
||||
memcpy1((void *)&tmp_dft_in[sample_offset-rxdata_offset],
|
||||
(void *) &rxdata[0],
|
||||
(frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int));
|
||||
|
||||
dft(dftsize,(int16_t *)&tmp_dft_in,
|
||||
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
|
||||
}
|
||||
else {
|
||||
//dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset],
|
||||
// (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *) &rxdata[rxdata_offset-sample_offset],
|
||||
(frame_parms->ofdm_symbol_size)*sizeof(int));
|
||||
dft(dftsize,(int16_t *)&tmp_dft_in,
|
||||
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
|
||||
}
|
||||
dft(dftsize,
|
||||
rxdata_ptr,
|
||||
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
|
||||
1);
|
||||
|
||||
// clear DC carrier from OFDM symbols
|
||||
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -513,7 +348,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
for (int symbol=0;symbol<nsymb;symbol++) {
|
||||
|
||||
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
|
||||
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
|
||||
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
|
||||
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
|
||||
rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
|
||||
|
||||
@@ -39,22 +39,20 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
|
||||
{
|
||||
int temp, i, aa, max_pos = 0, max_val = 0;
|
||||
short Re, Im;
|
||||
uint8_t cyclic_shift = 0;
|
||||
int i, aa, max_pos = 0, max_val = 0;
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
|
||||
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
|
||||
|
||||
int sync_pos = (frame_parms->ofdm_symbol_size - cyclic_shift*frame_parms->ofdm_symbol_size/12) % (frame_parms->ofdm_symbol_size);
|
||||
int sync_pos = frame_parms->nb_prefix_samples / 8;
|
||||
|
||||
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
|
||||
temp = 0;
|
||||
int temp = 0;
|
||||
|
||||
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
|
||||
Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
|
||||
short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
|
||||
short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
|
||||
temp += (Re*Re/2) + (Im*Im/2);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
debug_ch_est = fopen("debug_ch_est.txt","w");
|
||||
#endif
|
||||
|
||||
//uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
|
||||
|
||||
uint8_t nushift;
|
||||
int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates;
|
||||
int **rxdataF = gNB->common_vars.rxdataF;
|
||||
@@ -79,12 +77,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
uint16_t nb_rb_pusch = pusch_pdu->rb_size;
|
||||
|
||||
/*
|
||||
#ifdef DEBUG_CH
|
||||
printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
|
||||
gNB->frame_parms.Ncp,l,Ns,k, symbol);
|
||||
LOG_D(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
|
||||
__FUNCTION__,
|
||||
ch_offset,
|
||||
symbol_offset,
|
||||
gNB->frame_parms.ofdm_symbol_size,
|
||||
Ns,
|
||||
k,
|
||||
symbol);
|
||||
#endif
|
||||
*/
|
||||
|
||||
switch (nushift) {
|
||||
case 0:
|
||||
fl = filt8_l0;
|
||||
@@ -124,9 +127,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
//------------------generate DMRS------------------//
|
||||
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_disabled)
|
||||
if (pusch_pdu->transform_precoding == transform_precoder_disabled) {
|
||||
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
|
||||
|
||||
}
|
||||
else { // if transform precoding or SC-FDMA is enabled in Uplink
|
||||
|
||||
// NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
|
||||
@@ -151,11 +154,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
//------------------------------------------------//
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
for (int i=0;i<(6*nb_rb_pusch);i++)
|
||||
printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
|
||||
for (int i = 0; i < (6 * nb_rb_pusch); i++) {
|
||||
LOG_I(PHY, "In %s: %d + j*(%d)\n",
|
||||
__FUNCTION__,
|
||||
((int16_t*)pilot)[2 * i],
|
||||
((int16_t*)pilot)[1 + (2 * i)]);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
|
||||
|
||||
re_offset = k; /* Initializing the Resource element offset for each Rx antenna */
|
||||
@@ -167,11 +174,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift);
|
||||
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
|
||||
printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch);
|
||||
printf("rxF addr %p p %d\n", rxF,p);
|
||||
printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
|
||||
LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift);
|
||||
LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL);
|
||||
LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch);
|
||||
LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p);
|
||||
LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift);
|
||||
#endif
|
||||
//if ((gNB->frame_parms.N_RB_UL&1)==0) {
|
||||
|
||||
@@ -182,9 +189,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
printf("pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
|
||||
printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
|
||||
LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
|
||||
LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
|
||||
__FUNCTION__,
|
||||
rxF[0],
|
||||
rxF[1],
|
||||
dBc(rxF[0],rxF[1]),
|
||||
ch[0],
|
||||
ch[1],
|
||||
dBc(ch[0],ch[1]),
|
||||
pil[0],
|
||||
pil[1]);
|
||||
LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3]));
|
||||
#endif
|
||||
|
||||
multadd_real_vector_complex_scalar(fl,
|
||||
@@ -201,9 +217,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
|
||||
printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
|
||||
LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
|
||||
__FUNCTION__,
|
||||
rxF[0],
|
||||
rxF[1],
|
||||
dBc(rxF[0],rxF[1]),
|
||||
ch[0],
|
||||
ch[1],
|
||||
dBc(ch[0],ch[1]),
|
||||
pil[0],
|
||||
pil[1]);
|
||||
LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n",
|
||||
__FUNCTION__,
|
||||
rxF[2],
|
||||
rxF[3],
|
||||
dBc(rxF[2],rxF[3]));
|
||||
#endif
|
||||
|
||||
multadd_real_vector_complex_scalar(fml,
|
||||
ch,
|
||||
ul_ch,
|
||||
@@ -217,9 +247,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
|
||||
printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
|
||||
LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
|
||||
__FUNCTION__,
|
||||
rxF[0],
|
||||
rxF[1],
|
||||
dBc(rxF[0],rxF[1]),
|
||||
ch[0],
|
||||
ch[1],
|
||||
dBc(ch[0],ch[1]),
|
||||
pil[0],
|
||||
pil[1]);
|
||||
LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n",
|
||||
__FUNCTION__,
|
||||
rxF[2],
|
||||
rxF[3],
|
||||
dBc(rxF[2],rxF[3]));
|
||||
#endif
|
||||
|
||||
multadd_real_vector_complex_scalar(fmm,
|
||||
ch,
|
||||
ul_ch,
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
/*Table 7.4.1.1.2-1/2 from 38.211 */
|
||||
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
|
||||
int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
|
||||
int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
|
||||
int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}};
|
||||
int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
|
||||
int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}};
|
||||
|
||||
// complex conjugate of mod table
|
||||
|
||||
@@ -147,19 +147,18 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
uint16_t n_dmrs;
|
||||
if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
|
||||
nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
|
||||
n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
|
||||
}
|
||||
else {
|
||||
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
|
||||
n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
|
||||
}
|
||||
n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs;
|
||||
|
||||
uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
|
||||
uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
|
||||
uint8_t Qm = rel15->qamModOrder[0];
|
||||
uint32_t encoded_length = nb_re*Qm;
|
||||
int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16)));
|
||||
int16_t mod_dmrs[14][n_dmrs<<1] __attribute__ ((aligned(16)));
|
||||
|
||||
/* PTRS */
|
||||
uint16_t beta_ptrs = 1;
|
||||
@@ -271,10 +270,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
/// DMRS QPSK modulation
|
||||
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
|
||||
if (rel15->dlDmrsSymbPos & (1 << l)) {
|
||||
nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type);
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
|
||||
for (int i=0; i<n_dmrs>>4; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[l][((i<<3)+j)<<1], mod_dmrs[l][(((i<<3)+j)<<1)+1]);
|
||||
|
||||
@@ -301,205 +301,300 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
|
||||
// do DFT
|
||||
if (mu==1) {
|
||||
if (fp->N_RB_UL <= 100)
|
||||
AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL);
|
||||
else if (fp->N_RB_UL < 137) {
|
||||
if (fp->threequarter_fs==0) {
|
||||
//40 MHz @ 61.44 Ms/s
|
||||
//50 MHz @ 61.44 Ms/s
|
||||
prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=49152;
|
||||
dft(DFT_49152,prach2,rxsigF[aa],1);
|
||||
switch(fp->samples_per_subframe) {
|
||||
case 15360:
|
||||
// 10, 15 MHz @ 15.36 Ms/s
|
||||
prach2 = prach[aa] + (1*Ncp); // Ncp is for 30.72 Ms/s, so divide by 2 to bring to 15.36 Ms/s and multiply by 2 for I/Q
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=12288;
|
||||
dft(DFT_12288,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_12288,prach2+24576,rxsigF[aa]+24576,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_12288,prach2+(24576*2),rxsigF[aa]+(24576*2),1);
|
||||
dft(DFT_12288,prach2+(24576*3),rxsigF[aa]+(24576*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=3072;
|
||||
for (int i=0;i<4;i++) dft(DFT_3072,prach2+(i*3072*2),rxsigF[aa]+(i*3072*2),1);
|
||||
reps=4;
|
||||
}
|
||||
} else { // 839 sequence
|
||||
if (prachStartSymbol == 0) prach2+=16; // 8 samples @ 15.36 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
dftlen=512;
|
||||
dft(DFT_512,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_512,prach2+1024,rxsigF[aa]+1024,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_512,prach2+1024*2,rxsigF[aa]+1024*2,1);
|
||||
dft(DFT_512,prach2+1024*3,rxsigF[aa]+1024*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_512,prach2+1024*4,rxsigF[aa]+1024*4,1);
|
||||
dft(DFT_512,prach2+1024*5,rxsigF[aa]+1024*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_512,prach2+(1024*i),rxsigF[aa]+(1024*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
|
||||
dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=12288;
|
||||
for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
|
||||
reps=4;
|
||||
}
|
||||
}// 839 sequence
|
||||
else {
|
||||
if (prachStartSymbol == 0)
|
||||
prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
break;
|
||||
|
||||
dftlen=2048;
|
||||
dft(DFT_2048,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
|
||||
dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
|
||||
dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
} else { // threequarter sampling
|
||||
// 40 MHz @ 46.08 Ms/s
|
||||
prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
|
||||
if (prach_sequence_length == 0) {
|
||||
AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n");
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=36864;
|
||||
dft(DFT_36864,prach2,rxsigF[aa],1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
|
||||
dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=9216;
|
||||
for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
|
||||
reps=4;
|
||||
}
|
||||
} else {
|
||||
if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
dftlen=1536;
|
||||
dft(DFT_1536,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
|
||||
dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
|
||||
dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
} // short format
|
||||
} // 3/4 sampling
|
||||
} // <=50 MHz BW
|
||||
else if (fp->N_RB_UL <= 273) {
|
||||
if (fp->threequarter_fs==0) {
|
||||
prach2 = prach[aa] + (Ncp<<3);
|
||||
//80,90,100 MHz @ 122.88 Ms/s
|
||||
case 30720:
|
||||
// 20, 25, 30 MHz @ 30.72 Ms/s
|
||||
prach2 = prach[aa] + (2*Ncp); // Ncp is for 30.72 Ms/s, so just multiply by 2 for I/Q
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=24576;
|
||||
dft(DFT_24576,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_24576,prach2+49152,rxsigF[aa]+49152,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_24576,prach2+(49152*2),rxsigF[aa]+(49152*2),1);
|
||||
dft(DFT_24576,prach2+(49152*3),rxsigF[aa]+(49152*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=6144;
|
||||
for (int i=0;i<4;i++) dft(DFT_6144,prach2+(i*6144*2),rxsigF[aa]+(i*6144*2),1);
|
||||
reps=4;
|
||||
}
|
||||
} else { // 839 sequence
|
||||
if (prachStartSymbol == 0) prach2+=32; // 16 samples @ 30.72 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=98304;
|
||||
dft(DFT_98304,prach2,rxsigF[aa],1);
|
||||
dftlen=1024;
|
||||
dft(DFT_1024,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_1024,prach2+2048,rxsigF[aa]+2048,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_1024,prach2+2048*2,rxsigF[aa]+2048*2,1);
|
||||
dft(DFT_1024,prach2+2048*3,rxsigF[aa]+2048*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_1024,prach2+2048*4,rxsigF[aa]+2048*4,1);
|
||||
dft(DFT_1024,prach2+2048*5,rxsigF[aa]+2048*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_1024,prach2+(2048*i),rxsigF[aa]+(2048*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
|
||||
dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=24576;
|
||||
for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
|
||||
reps=4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
break;
|
||||
|
||||
dftlen=4096;
|
||||
dft(DFT_4096,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
|
||||
dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
|
||||
dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n");
|
||||
prach2 = prach[aa] + (6*Ncp);
|
||||
// 80 MHz @ 92.16 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=73728;
|
||||
dft(DFT_73728,prach2,rxsigF[aa],1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_73728,prach2+(2*73728),rxsigF[aa]+(2*73728),1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=18432;
|
||||
for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
|
||||
reps=4;
|
||||
}
|
||||
} else {
|
||||
if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
case 61440:
|
||||
// 40, 50, 60 MHz @ 61.44 Ms/s
|
||||
prach2 = prach[aa] + (4*Ncp); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=49152;
|
||||
dft(DFT_49152,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_49152,prach2+98304,rxsigF[aa]+98304,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_49152,prach2+(98304*2),rxsigF[aa]+(98304*2),1);
|
||||
dft(DFT_49152,prach2+(98304*3),rxsigF[aa]+(98304*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=12288;
|
||||
for (int i=0;i<4;i++) dft(DFT_12288,prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1);
|
||||
reps=4;
|
||||
}
|
||||
} else { // 839 sequence
|
||||
if (prachStartSymbol == 0) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
dftlen=3072;
|
||||
dft(DFT_3072,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
|
||||
dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
|
||||
dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
dftlen=2048;
|
||||
dft(DFT_2048,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
|
||||
dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
|
||||
dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 46080:
|
||||
// 40 MHz @ 46.08 Ms/s
|
||||
prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=36864;
|
||||
dft(DFT_36864,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_36864,prach2+73728,rxsigF[aa]+73728,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_36864,prach2+(73728*2),rxsigF[aa]+(73728*2),1);
|
||||
dft(DFT_36864,prach2+(73728*3),rxsigF[aa]+(73728*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=9216;
|
||||
for (int i=0;i<4;i++) dft(DFT_9216,prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1);
|
||||
reps=4;
|
||||
}
|
||||
} else { // 839 sequence
|
||||
if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
dftlen=1536;
|
||||
dft(DFT_1536,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
|
||||
dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
|
||||
dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 122880:
|
||||
// 70, 80, 90, 100 MHz @ 122.88 Ms/s
|
||||
prach2 = prach[aa] + (8*Ncp);
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=98304;
|
||||
dft(DFT_98304,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_98304,prach2+196608,rxsigF[aa]+196608,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_98304,prach2+(196608*2),rxsigF[aa]+(196608*2),1);
|
||||
dft(DFT_98304,prach2+(196608*3),rxsigF[aa]+(196608*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=24576;
|
||||
for (int i=0;i<4;i++) dft(DFT_24576,prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1);
|
||||
reps=4;
|
||||
}
|
||||
} else { // 839 sequence
|
||||
if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
dftlen=4096;
|
||||
dft(DFT_4096,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
|
||||
dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
|
||||
dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 92160:
|
||||
// 80, 90 MHz @ 92.16 Ms/s
|
||||
prach2 = prach[aa] + (6*Ncp);
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) {
|
||||
dftlen=73728;
|
||||
dft(DFT_73728,prach2,rxsigF[aa],1);
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2) {
|
||||
dft(DFT_73728,prach2+147456,rxsigF[aa]+147456,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 2) {
|
||||
dft(DFT_73728,prach2+(147456*2),rxsigF[aa]+(147456*2),1);
|
||||
dft(DFT_73728,prach2+(147456*3),rxsigF[aa]+(147456*3),1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 3) {
|
||||
dftlen=18432;
|
||||
for (int i=0;i<4;i++) dft(DFT_18432,prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1);
|
||||
reps=4;
|
||||
}
|
||||
} else {
|
||||
if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only)
|
||||
|
||||
dftlen=3072;
|
||||
dft(DFT_3072,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
|
||||
dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
|
||||
dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"sample_rate %f MHz not support for NR PRACH yet\n", fp->samples_per_subframe / 1000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mu==3) {
|
||||
if (fp->threequarter_fs) {
|
||||
AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu);
|
||||
|
||||
@@ -345,6 +345,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
|
||||
n = 0;
|
||||
k_prime = 0;
|
||||
rxF_ext_index = ul_ch0_ext_index = ul_ch0_index = 0; /* In RX Antenna(aarx) loop, Reset the index */
|
||||
|
||||
if (is_dmrs_symbol == 0) {
|
||||
//
|
||||
|
||||
@@ -1604,7 +1604,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset;
|
||||
// estimate CQI for MAC (from antenna port 0 only)
|
||||
int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB);
|
||||
int cqi;
|
||||
int cqi,bit_left;
|
||||
if (SNRtimes10 < -640) cqi=0;
|
||||
else if (SNRtimes10 > 635) cqi=255;
|
||||
else cqi=(640+SNRtimes10)/5;
|
||||
@@ -1628,7 +1628,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & 255;
|
||||
decodedPayload[0]>>=8;
|
||||
}
|
||||
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_harq&7))-1);
|
||||
bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3);
|
||||
uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
|
||||
decodedPayload[0] >>= pucch_pdu->bit_len_harq;
|
||||
}
|
||||
|
||||
@@ -1642,6 +1643,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
// csi
|
||||
if (pucch_pdu->bit_len_csi_part1>0) {
|
||||
uci_pdu->pduBitmap|=4;
|
||||
uci_pdu->csi_part1.csi_part1_bit_len=pucch_pdu->bit_len_csi_part1;
|
||||
int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3;
|
||||
if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
|
||||
uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
|
||||
@@ -1651,7 +1653,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
|
||||
decodedPayload[0]>>=8;
|
||||
}
|
||||
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<(pucch_pdu->bit_len_csi_part1&7))-1);
|
||||
bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3);
|
||||
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1<<bit_left)-1);
|
||||
decodedPayload[0] >>= pucch_pdu->bit_len_csi_part1;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
if ((reg % reg_bundle_size_L) == 0) r++;
|
||||
}
|
||||
|
||||
|
||||
// Get cce_list indices by reg_idx in ascending order
|
||||
int f_bundle_j_list_id = 0;
|
||||
int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {};
|
||||
@@ -175,7 +174,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) {
|
||||
|
||||
f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L);
|
||||
@@ -404,11 +402,12 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
c_rb = 0;
|
||||
for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
|
||||
c_rb_by6 = c_rb/6;
|
||||
|
||||
// skip zeros in frequency domain bitmap
|
||||
while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) {
|
||||
c_rb+=6;
|
||||
c_rb_by6 = c_rb/6;
|
||||
}
|
||||
c_rb+=6;
|
||||
c_rb_by6 = c_rb/6;
|
||||
}
|
||||
|
||||
LOG_DDD("c_rb=%d\n",c_rb);
|
||||
rxF=NULL;
|
||||
|
||||
@@ -289,8 +289,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames)
|
||||
proc,
|
||||
i,
|
||||
0,
|
||||
is*fp->samples_per_frame+ue->ssb_offset,
|
||||
0);
|
||||
is*fp->samples_per_frame+ue->ssb_offset);
|
||||
|
||||
#ifdef DEBUG_INITIAL_SYNCH
|
||||
LOG_I(PHY,"Calling sss detection (normal CP)\n");
|
||||
|
||||
@@ -244,86 +244,82 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
*********************************************************/
|
||||
|
||||
if (mu==1) {
|
||||
if (fp->N_RB_UL <= 100)
|
||||
AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
|
||||
else if (fp->N_RB_UL < 137) {
|
||||
if (fp->threequarter_fs == 0) {
|
||||
//40 MHz @ 61.44 Ms/s
|
||||
//50 MHz @ 61.44 Ms/s
|
||||
switch(fp->samples_per_subframe) {
|
||||
case 15360:
|
||||
// 10, 15 MHz @ 15.36 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 49152;
|
||||
dftlen = 12288;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 12288;
|
||||
} // 839 sequence
|
||||
else {
|
||||
switch (mu){
|
||||
case 1:
|
||||
dftlen = 2048;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Shouldn't get here\n");
|
||||
break;
|
||||
}
|
||||
dftlen = 3072;
|
||||
} else { // 839 sequence
|
||||
dftlen = 512;
|
||||
}
|
||||
} else { // threequarter sampling
|
||||
// 40 MHz @ 46.08 Ms/s
|
||||
break;
|
||||
|
||||
case 30720:
|
||||
// 20, 25, 30 MHz @ 30.72 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 24576;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 6144;
|
||||
} else { // 839 sequence
|
||||
dftlen = 1024;
|
||||
}
|
||||
break;
|
||||
|
||||
case 46080:
|
||||
// 40 MHz @ 46.08 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 36864;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 9216;
|
||||
} else {
|
||||
switch (mu){
|
||||
case 1:
|
||||
dftlen = 1536;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Shouldn't get here\n");
|
||||
break;
|
||||
}
|
||||
} // short format
|
||||
} // 3/4 sampling
|
||||
} // <=50 MHz BW
|
||||
else if (fp->N_RB_UL <= 273) {
|
||||
if (fp->threequarter_fs == 0) {
|
||||
//80,90,100 MHz @ 122.88 Ms/s
|
||||
} else { // 839 sequence
|
||||
dftlen = 1536;
|
||||
}
|
||||
break;
|
||||
|
||||
case 61440:
|
||||
// 40, 50, 60 MHz @ 61.44 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 49152;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 12288;
|
||||
} else { // 839 sequence
|
||||
dftlen = 2048;
|
||||
}
|
||||
break;
|
||||
|
||||
case 92160:
|
||||
// 50, 60, 70, 80, 90 MHz @ 92.16 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 73728;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 18432;
|
||||
} else { // 839 sequence
|
||||
dftlen = 3072;
|
||||
}
|
||||
break;
|
||||
|
||||
case 122880:
|
||||
// 70, 80, 90, 100 MHz @ 122.88 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 98304;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 24576;
|
||||
} else { // 839 sequence
|
||||
dftlen = 4096;
|
||||
}
|
||||
} else { // threequarter sampling
|
||||
switch (mu){
|
||||
case 1:
|
||||
dftlen = 4096;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Shouldn't get here\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
|
||||
}
|
||||
} else {
|
||||
AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
|
||||
// 80 MHz @ 92.16 Ms/s
|
||||
if (prach_sequence_length == 0) {
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
|
||||
dftlen = 73728;
|
||||
if (prach_fmt_id == 3)
|
||||
dftlen = 18432;
|
||||
} else {
|
||||
switch (mu){
|
||||
case 1:
|
||||
dftlen = 3072;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1 == 0, "Shouldn't get here\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mu==3) {
|
||||
if (fp->threequarter_fs)
|
||||
@@ -425,15 +421,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
uint8_t use_extended_prach_prefix = 0;
|
||||
if(fp->numerology_index == 0) {
|
||||
if (prachStartSymbol == 0 || prachStartSymbol == 7)
|
||||
use_extended_prach_prefix = 1;
|
||||
use_extended_prach_prefix = 1;
|
||||
}
|
||||
else {
|
||||
if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0)
|
||||
use_extended_prach_prefix = 1;
|
||||
use_extended_prach_prefix = 1;
|
||||
}
|
||||
|
||||
if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps
|
||||
if (fp->threequarter_fs == 0) {
|
||||
|
||||
if (mu == 3) {
|
||||
switch (fp->samples_per_subframe) {
|
||||
case 61440: // 32 PRB case, 61.44 Msps
|
||||
Ncp<<=1; //to account for 61.44Mbps
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(Ncp<<1); //times 2 for complex samples
|
||||
@@ -491,13 +488,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (512*12)+Ncp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
|
||||
|
||||
}
|
||||
else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps
|
||||
if (fp->threequarter_fs == 0) {
|
||||
break;
|
||||
|
||||
case 122880: // 66 PRB case, 122.88 Msps
|
||||
Ncp<<=2; //to account for 122.88Mbps
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(Ncp<<1); //times 2 for complex samples
|
||||
@@ -555,13 +548,211 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (1024*12)+Ncp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL);
|
||||
}
|
||||
else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
|
||||
if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
|
||||
Ncp<<=1; //to account for 61.44Mbps
|
||||
} else if (mu == 1) {
|
||||
switch (fp->samples_per_subframe) {
|
||||
case 15360: // full sampling @ 15.36 Ms/s
|
||||
Ncp = Ncp/2; // to account for 15.36 Ms/s
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(2*Ncp); // times 2 for complex samples
|
||||
if (prach_sequence_length == 0){
|
||||
if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
|
||||
idft(IDFT_12288,prachF,prach2,1);
|
||||
// here we have | empty | Prach12288 |
|
||||
memmove(prach,prach+(12288<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach12288 |
|
||||
prach_len = 12288+Ncp;
|
||||
} else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
|
||||
idft(IDFT_12288,prachF,prach2,1);
|
||||
// here we have | empty | Prach12288 | empty12288 |
|
||||
memmove(prach2+(12288<<1),prach2,(12288<<2));
|
||||
// here we have | empty | Prach12288 | Prach12288 |
|
||||
memmove(prach,prach+(12288<<2),(Ncp<<2));
|
||||
// here we have | Prefix | Prach12288 | Prach12288 |
|
||||
prach_len = (12288*2)+Ncp;
|
||||
} else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s, 12288 samples @ 15.36 Ms/s
|
||||
idft(IDFT_12288,prachF,prach2,1);
|
||||
// here we have | empty | Prach12288 | empty12288 | empty12288 | empty12288 |
|
||||
memmove(prach2+(12288<<1),prach2,(12288<<2));
|
||||
// here we have | empty | Prach12288 | Prach12288 | empty12288 | empty12288 |
|
||||
memmove(prach2+(12288<<2),prach2,(12288<<3));
|
||||
// here we have | empty | Prach12288 | Prach12288 | Prach12288 | Prach12288 |
|
||||
memmove(prach,prach+(12288<<3),(Ncp<<2));
|
||||
// here we have | Prefix | Prach12288 | Prach12288 | Prach12288 | Prach12288 |
|
||||
prach_len = (12288*4)+Ncp;
|
||||
} else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 3072 samples @ 15.36 Ms/s
|
||||
idft(IDFT_3072,prachF,prach2,1);
|
||||
// here we have | empty | Prach3072 | empty3072 | empty3072 | empty3072 |
|
||||
memmove(prach2+(3072<<1),prach2,(3072<<2));
|
||||
// here we have | empty | Prach3072 | Prach3072 | empty3072 | empty3072 |
|
||||
memmove(prach2+(3072<<2),prach2,(3072<<3));
|
||||
// here we have | empty | Prach3072 | Prach3072 | Prach3072 | Prach3072 |
|
||||
memmove(prach,prach+(3072<<3),(Ncp<<2));
|
||||
// here we have | Prefix | Prach3072 | Prach3072 | Prach3072 | Prach3072 |
|
||||
prach_len = (3072*4)+Ncp;
|
||||
}
|
||||
} else { // short PRACH sequence
|
||||
if (use_extended_prach_prefix)
|
||||
Ncp += 8; // 16*kappa, kappa=0.5 for 15.36 Ms/s
|
||||
prach2 = prach+(2*Ncp); // times 2 for complex samples
|
||||
if (prach_fmt_id == 9) {
|
||||
idft(IDFT_512,prachF,prach2,1);
|
||||
// here we have | empty | Prach512 |
|
||||
memmove(prach,prach+(512<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach512 |
|
||||
prach_len = (512*1)+Ncp;
|
||||
} else if (prach_fmt_id == 4 || prach_fmt_id == 7) {
|
||||
idft(IDFT_512,prachF,prach2,1);
|
||||
// here we have | empty | Prach512 | empty512 |
|
||||
memmove(prach2+(512<<1),prach2,(512<<2));
|
||||
// here we have | empty | Prach512 | Prach512 |
|
||||
memmove(prach,prach+(512<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach512 | Prach512 |
|
||||
prach_len = (512*2)+Ncp;
|
||||
} else if (prach_fmt_id == 5) { // 4x512
|
||||
idft(IDFT_512,prachF,prach2,1);
|
||||
// here we have | empty | Prach512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<1),prach2,(512<<2));
|
||||
// here we have | empty | Prach512 | Prach512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<2),prach2,(512<<3));
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
memmove(prach,prach+(512<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
prach_len = (512*4)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 6x512
|
||||
idft(IDFT_512,prachF,prach2,1);
|
||||
// here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<1),prach2,(512<<2));
|
||||
// here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<2),prach2,(512<<3));
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<3),prach2,(512<<3));
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
memmove(prach,prach+(512<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
prach_len = (512*6)+Ncp;
|
||||
} else if (prach_fmt_id == 8) { // 12x512
|
||||
idft(IDFT_512,prachF,prach2,1);
|
||||
// here we have | empty | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<1),prach2,(512<<2));
|
||||
// here we have | empty | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<2),prach2,(512<<3));
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<3),prach2,(512<<3));
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | empty512 | empty512 | empty512 | empty512 | empty512 | empty512 |
|
||||
memmove(prach2+(512<<1)*6,prach2,(512<<2)*6);
|
||||
// here we have | empty | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
memmove(prach,prach+(512<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512 |
|
||||
prach_len = (512*12)+Ncp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 30720: // full sampling @ 30.72 Ms/s
|
||||
Ncp = Ncp*1; // to account for 30.72 Ms/s
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(2*Ncp); // times 2 for complex samples
|
||||
if (prach_sequence_length == 0){
|
||||
if (prach_fmt_id == 0) { // 24576 samples @ 30.72 Ms/s
|
||||
idft(IDFT_24576,prachF,prach2,1);
|
||||
// here we have | empty | Prach24576 |
|
||||
memmove(prach,prach+(24576<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach24576 |
|
||||
prach_len = 24576+Ncp;
|
||||
} else if (prach_fmt_id == 1) { // 24576 samples @ 30.72 Ms/s
|
||||
idft(IDFT_24576,prachF,prach2,1);
|
||||
// here we have | empty | Prach24576 | empty24576 |
|
||||
memmove(prach2+(24576<<1),prach2,(24576<<2));
|
||||
// here we have | empty | Prach24576 | Prach24576 |
|
||||
memmove(prach,prach+(24576<<2),(Ncp<<2));
|
||||
// here we have | Prefix | Prach24576 | Prach24576 |
|
||||
prach_len = (24576*2)+Ncp;
|
||||
} else if (prach_fmt_id == 2) { // 24576 samples @ 30.72 Ms/s
|
||||
idft(IDFT_24576,prachF,prach2,1);
|
||||
// here we have | empty | Prach24576 | empty24576 | empty24576 | empty24576 |
|
||||
memmove(prach2+(24576<<1),prach2,(24576<<2));
|
||||
// here we have | empty | Prach24576 | Prach24576 | empty24576 | empty24576 |
|
||||
memmove(prach2+(24576<<2),prach2,(24576<<3));
|
||||
// here we have | empty | Prach24576 | Prach24576 | Prach24576 | Prach24576 |
|
||||
memmove(prach,prach+(24576<<3),(Ncp<<2));
|
||||
// here we have | Prefix | Prach24576 | Prach24576 | Prach24576 | Prach24576 |
|
||||
prach_len = (24576*4)+Ncp;
|
||||
} else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s
|
||||
idft(IDFT_6144,prachF,prach2,1);
|
||||
// here we have | empty | Prach6144 | empty6144 | empty6144 | empty6144 |
|
||||
memmove(prach2+(6144<<1),prach2,(6144<<2));
|
||||
// here we have | empty | Prach6144 | Prach6144 | empty6144 | empty6144 |
|
||||
memmove(prach2+(6144<<2),prach2,(6144<<3));
|
||||
// here we have | empty | Prach6144 | Prach6144 | Prach6144 | Prach6144 |
|
||||
memmove(prach,prach+(6144<<3),(Ncp<<2));
|
||||
// here we have | Prefix | Prach6144 | Prach6144 | Prach6144 | Prach6144 |
|
||||
prach_len = (6144*4)+Ncp;
|
||||
}
|
||||
} else { // short PRACH sequence
|
||||
if (use_extended_prach_prefix)
|
||||
Ncp += 16; // 16*kappa, kappa=1 for 30.72Msps
|
||||
prach2 = prach+(2*Ncp); // times 2 for complex samples
|
||||
if (prach_fmt_id == 9) {
|
||||
idft(IDFT_1024,prachF,prach2,1);
|
||||
// here we have | empty | Prach1024 |
|
||||
memmove(prach,prach+(1024<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach1024 |
|
||||
prach_len = (1024*1)+Ncp;
|
||||
} else if (prach_fmt_id == 4 || prach_fmt_id == 7) {
|
||||
idft(IDFT_1024,prachF,prach2,1);
|
||||
// here we have | empty | Prach1024 | empty1024 |
|
||||
memmove(prach2+(1024<<1),prach2,(1024<<2));
|
||||
// here we have | empty | Prach1024 | Prach1024 |
|
||||
memmove(prach,prach+(1024<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach1024 | Prach1024 |
|
||||
prach_len = (1024*2)+Ncp;
|
||||
} else if (prach_fmt_id == 5) { // 4x1024
|
||||
idft(IDFT_1024,prachF,prach2,1);
|
||||
// here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<1),prach2,(1024<<2));
|
||||
// here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<2),prach2,(1024<<3));
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
memmove(prach,prach+(1024<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
prach_len = (1024*4)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 6x1024
|
||||
idft(IDFT_1024,prachF,prach2,1);
|
||||
// here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<1),prach2,(1024<<2));
|
||||
// here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<2),prach2,(1024<<3));
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<3),prach2,(1024<<3));
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
memmove(prach,prach+(1024<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
prach_len = (1024*6)+Ncp;
|
||||
} else if (prach_fmt_id == 8) { // 12x1024
|
||||
idft(IDFT_1024,prachF,prach2,1);
|
||||
// here we have | empty | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<1),prach2,(1024<<2));
|
||||
// here we have | empty | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<2),prach2,(1024<<3));
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<3),prach2,(1024<<3));
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 | empty1024 |
|
||||
memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6);
|
||||
// here we have | empty | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
memmove(prach,prach+(1024<<1),(Ncp<<2));
|
||||
// here we have | Prefix | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 |
|
||||
prach_len = (1024*12)+Ncp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 61440: // full sampling @ 61.44 Ms/s
|
||||
Ncp = Ncp*2; // to account for 61.44 Ms/s
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(Ncp<<1); //times 2 for complex samples
|
||||
if (prach_sequence_length == 0){
|
||||
@@ -587,7 +778,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(49152<<3),(Ncp<<2));
|
||||
// here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
|
||||
prach_len = (49152*4)+Ncp;
|
||||
} else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
|
||||
} else if (prach_fmt_id == 3) { // 6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
|
||||
idft(IDFT_12288,prachF,prach2,1);
|
||||
memmove(prach2+(12288<<1),prach2,(12288<<2));
|
||||
// here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
|
||||
@@ -649,7 +840,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (2048*12)+Ncp;
|
||||
}
|
||||
}
|
||||
} else { // threequarter sampling @ 46.08 Ms/s
|
||||
break;
|
||||
|
||||
case 46080: // threequarter sampling @ 46.08 Ms/s
|
||||
Ncp = (Ncp*3)/2;
|
||||
prach2 = prach+(Ncp<<1);
|
||||
if (prach_sequence_length == 0){
|
||||
@@ -738,9 +931,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (1536*12)+Ncp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
|
||||
if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
|
||||
break;
|
||||
|
||||
case 122880: // full sampling @ 122.88 Ms/s
|
||||
Ncp<<=2; //to account for 122.88Mbps
|
||||
// This is after cyclic prefix
|
||||
prach2 = prach+(Ncp<<1); //times 2 for complex samples
|
||||
@@ -828,7 +1021,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (4096*12)+Ncp;
|
||||
}
|
||||
}
|
||||
} else { // three quarter sampling @ 92.16 Ms/s
|
||||
break;
|
||||
|
||||
case 92160: // three quarter sampling @ 92.16 Ms/s
|
||||
Ncp = (Ncp*3); //to account for 92.16 Msps
|
||||
prach2 = prach+(Ncp<<1); //times 2 for complex samples
|
||||
if (prach_sequence_length == 0){
|
||||
@@ -915,6 +1110,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (3072*12)+Ncp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0,"sample rate %f MHz not supported for numerology %d\n", fp->samples_per_subframe / 1000.0, mu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,8 @@ typedef struct {
|
||||
uint8_t O_ACK;
|
||||
/// Index of current HARQ round for this ULSCH
|
||||
uint8_t round;
|
||||
/// Last Ndi for this harq process
|
||||
uint8_t ndi;
|
||||
/// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
|
||||
unsigned char *a;
|
||||
/// Pointer to the payload + CRC
|
||||
|
||||
@@ -78,13 +78,15 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg,
|
||||
|
||||
openair0_cfg->autocal[i] = 1;
|
||||
|
||||
LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
|
||||
i,
|
||||
rf_chain,
|
||||
openair0_cfg->tx_gain[i],
|
||||
openair0_cfg->rx_gain[i],
|
||||
openair0_cfg->tx_freq[i],
|
||||
openair0_cfg->rx_freq[i]);
|
||||
if (i < openair0_cfg->rx_num_channels) {
|
||||
LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
|
||||
i,
|
||||
rf_chain,
|
||||
openair0_cfg->tx_gain[i],
|
||||
openair0_cfg->rx_gain[i],
|
||||
openair0_cfg->tx_freq[i],
|
||||
openair0_cfg->rx_freq[i]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
|
||||
for (i=0; i<number_of_harq_pids; i++) {
|
||||
ulsch->harq_processes[i]->round=0;
|
||||
}
|
||||
|
||||
return(ulsch);
|
||||
}
|
||||
}
|
||||
@@ -257,7 +256,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
Ilbrm = 0;
|
||||
Tbslbrm = 950984; //max tbs
|
||||
Coderate = 0.0;
|
||||
harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index];
|
||||
|
||||
///////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -267,8 +265,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
|
||||
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
|
||||
|
||||
// if (harq_process->Ndi == 1) { // this is a new packet
|
||||
if (harq_process->round == 0) { // this is a new packet
|
||||
if (harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
@@ -415,7 +412,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
///////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
harq_process->ndi = harq_process->pusch_pdu.pusch_data.new_data_indicator;
|
||||
}
|
||||
F = harq_process->F;
|
||||
Kr = harq_process->K;
|
||||
|
||||
@@ -496,13 +496,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
|
||||
for(ap = 0; ap < Nl; ap++) {
|
||||
for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT;s++){
|
||||
LOG_D(PHY,"rotating txdataF symbol %d (%d) => (%d.%d)\n",
|
||||
s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]);
|
||||
rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
|
||||
&frame_parms->symbol_rotation[2*(s+symb_offset)],
|
||||
(int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
|
||||
LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n",
|
||||
__FUNCTION__,
|
||||
s,
|
||||
s + symb_offset,
|
||||
frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
|
||||
frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]);
|
||||
|
||||
rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
|
||||
&frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
|
||||
(int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -282,30 +282,6 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
|
||||
graph->iteration++;
|
||||
}
|
||||
|
||||
static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
|
||||
for (int ant=0; ant<nb_ant; ant++) {
|
||||
if (data[ant] != NULL) {
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, ant);
|
||||
|
||||
for (int i=0; i<len; i+=8) {
|
||||
float *vals=values+i;
|
||||
const scopeSample_t *in=&(data[ant][i]);
|
||||
|
||||
// TRY AUTOMATIC simd BY GCC
|
||||
for (int k=0; k<8; k++ ) {
|
||||
vals[k] = 10*log10(1.0+SquaredNorm(in[k]));
|
||||
}
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ant, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
|
||||
@@ -741,4 +741,10 @@ typedef struct RRU_config_s {
|
||||
MBSFN_config_t MBSFN_config[8];
|
||||
} RRU_config_t;
|
||||
|
||||
typedef struct processingData_RU {
|
||||
int frame_tx;
|
||||
int slot_tx;
|
||||
openair0_timestamp timestamp_tx;
|
||||
RU_t *ru;
|
||||
} processingData_RU_t;
|
||||
#endif //__PHY_DEFS_RU__H__
|
||||
|
||||
@@ -830,6 +830,9 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t ulsch_freq_offset_estimation_stats;
|
||||
*/
|
||||
notifiedFIFO_t *respDecode;
|
||||
notifiedFIFO_t *resp_L1;
|
||||
notifiedFIFO_t *resp_L1_tx;
|
||||
notifiedFIFO_t *resp_RU_tx;
|
||||
tpool_t *threadPool;
|
||||
int nbDecode;
|
||||
uint8_t pusch_proc_threads;
|
||||
@@ -871,4 +874,13 @@ union ldpcReqUnion {
|
||||
uint64_t p;
|
||||
};
|
||||
|
||||
typedef struct processingData_L1 {
|
||||
int frame_rx;
|
||||
int frame_tx;
|
||||
int slot_rx;
|
||||
int slot_tx;
|
||||
openair0_timestamp timestamp_tx;
|
||||
PHY_VARS_gNB *gNB;
|
||||
} processingData_L1_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -327,7 +327,8 @@ struct NR_DL_FRAME_PARMS {
|
||||
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
|
||||
lte_prefix_type_t Ncp;
|
||||
/// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
|
||||
int16_t symbol_rotation[224*2];
|
||||
/// First dimension is for the direction of the link (0 DL, 1 UL)
|
||||
int16_t symbol_rotation[2][224*2];
|
||||
/// shift of pilot position in one RB
|
||||
uint8_t nushift;
|
||||
/// SRS configuration from TS 38.331 RRC
|
||||
@@ -368,20 +369,4 @@ struct NR_DL_FRAME_PARMS {
|
||||
#define KHz (1000UL)
|
||||
#define MHz (1000*KHz)
|
||||
|
||||
typedef struct nr_bandentry_s {
|
||||
int16_t band;
|
||||
uint64_t ul_min;
|
||||
uint64_t ul_max;
|
||||
uint64_t dl_min;
|
||||
uint64_t dl_max;
|
||||
uint64_t step_size;
|
||||
uint64_t N_OFFs_DL;
|
||||
uint8_t deltaf_raster;
|
||||
} nr_bandentry_t;
|
||||
|
||||
typedef struct nr_band_info_s {
|
||||
int nbands;
|
||||
nr_bandentry_t band_info[100];
|
||||
} nr_band_info_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -520,8 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) {
|
||||
ru->common.rxdataF[aa],
|
||||
l,
|
||||
proc->tti_rx,
|
||||
ru->N_TA_offset,
|
||||
0);
|
||||
ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX+proc->tti_rx, 0);
|
||||
@@ -657,8 +656,7 @@ void nr_fep_full(RU_t *ru, int slot) {
|
||||
ru->common.rxdataF[aa],
|
||||
l,
|
||||
proc->tti_rx,
|
||||
ru->N_TA_offset,
|
||||
0);
|
||||
ru->N_TA_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -367,7 +367,6 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
||||
|
||||
int timing_advance_update, cqi;
|
||||
int sync_pos;
|
||||
uint16_t mu = gNB->frame_parms.numerology_index;
|
||||
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id][0];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
|
||||
|
||||
@@ -375,18 +374,10 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
|
||||
|
||||
// pdu->data = gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b;
|
||||
sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
|
||||
timing_advance_update = sync_pos * (1 << mu); // scale by the used scs numerology
|
||||
|
||||
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
|
||||
switch (gNB->frame_parms.N_RB_DL) {
|
||||
case 106: timing_advance_update /= 16; break;
|
||||
case 217: timing_advance_update /= 32; break;
|
||||
case 245: timing_advance_update /= 32; break;
|
||||
case 273: timing_advance_update /= 32; break;
|
||||
case 66: timing_advance_update /= 12; break;
|
||||
case 32: timing_advance_update /= 12; break;
|
||||
default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL);
|
||||
}
|
||||
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
|
||||
timing_advance_update = sync_pos / bw_scaling;
|
||||
|
||||
// put timing advance command in 0..63 range
|
||||
timing_advance_update += 31;
|
||||
@@ -517,15 +508,12 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
unsigned char aa;
|
||||
|
||||
for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) {
|
||||
// nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
|
||||
|
||||
for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
|
||||
nr_slot_fep_ul(&gNB->frame_parms,
|
||||
gNB->common_vars.rxdata[aa],
|
||||
gNB->common_vars.rxdataF[aa],
|
||||
symbol,
|
||||
slot_rx,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
||||
@@ -542,6 +530,9 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
}
|
||||
|
||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
/* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
|
||||
int pucch_decode_done = 0;
|
||||
int pusch_decode_done = 0;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
|
||||
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
|
||||
@@ -563,6 +554,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
(pucch->frame == frame_rx) &&
|
||||
(pucch->slot == slot_rx) ) {
|
||||
|
||||
pucch_decode_done = 1;
|
||||
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||
uint16_t num_ucis;
|
||||
switch (pucch_pdu->format_type) {
|
||||
@@ -651,7 +644,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
}
|
||||
#endif
|
||||
|
||||
T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], 2048*4*14));
|
||||
pusch_decode_done = 1;
|
||||
|
||||
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
|
||||
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
|
||||
@@ -680,5 +673,9 @@ T(T_BENETEL, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF
|
||||
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
|
||||
if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB);
|
||||
|
||||
if (pucch_decode_done || pusch_decode_done) {
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
|
||||
}
|
||||
|
||||
@@ -132,6 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
||||
}
|
||||
|
||||
switch (pdu_type){
|
||||
case FAPI_NR_RX_PDU_TYPE_SIB:
|
||||
case FAPI_NR_RX_PDU_TYPE_DLSCH:
|
||||
case FAPI_NR_RX_PDU_TYPE_RAR:
|
||||
harq_pid = dlsch0->current_harq_pid;
|
||||
@@ -202,20 +203,15 @@ uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){
|
||||
|
||||
}
|
||||
|
||||
|
||||
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
|
||||
uint16_t get_bw_scaling(uint16_t nb_rb){
|
||||
uint16_t bw_scaling;
|
||||
switch (nb_rb) {
|
||||
case 32: bw_scaling = 4; break;
|
||||
case 66: bw_scaling = 8; break;
|
||||
case 106: bw_scaling = 16; break;
|
||||
case 217: bw_scaling = 32; break;
|
||||
case 245: bw_scaling = 32; break;
|
||||
case 273: bw_scaling = 32; break;
|
||||
default: abort();
|
||||
}
|
||||
return bw_scaling;
|
||||
// convert time factor "16 * 64 * T_c / (2^mu)" in N_TA calculation in TS38.213 section 4.2 to samples by multiplying with samples per second
|
||||
// 16 * 64 * T_c / (2^mu) * samples_per_second
|
||||
// = 16 * T_s / (2^mu) * samples_per_second
|
||||
// = 16 * 1 / (15 kHz * 2048) / (2^mu) * (15 kHz * 2^mu * ofdm_symbol_size)
|
||||
// = 16 * 1 / 2048 * ofdm_symbol_size
|
||||
// = 16 * ofdm_symbol_size / 2048
|
||||
static inline
|
||||
uint16_t get_bw_scaling(uint16_t ofdm_symbol_size){
|
||||
return 16 * ofdm_symbol_size / 2048;
|
||||
}
|
||||
|
||||
// UL time alignment procedures:
|
||||
@@ -233,38 +229,18 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
|
||||
|
||||
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) {
|
||||
|
||||
uint8_t numerology = ue->frame_parms.numerology_index;
|
||||
uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL;
|
||||
int factor_mu = 1 << numerology;
|
||||
uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
|
||||
uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
|
||||
uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]);
|
||||
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling;
|
||||
|
||||
if (ue->UE_mode[gNB_id] == RA_RESPONSE){
|
||||
|
||||
ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu;
|
||||
|
||||
LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n",
|
||||
__FUNCTION__,
|
||||
ue->Mod_id,
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
ul_time_alignment->ta_command,
|
||||
ue->timing_advance);
|
||||
|
||||
} else if (ue->UE_mode[gNB_id] == PUSCH){
|
||||
|
||||
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu;
|
||||
|
||||
LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
|
||||
__FUNCTION__,
|
||||
ue->Mod_id,
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
ul_time_alignment->ta_command,
|
||||
ue->timing_advance);
|
||||
|
||||
}
|
||||
LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
|
||||
__FUNCTION__,
|
||||
ue->Mod_id,
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
ul_time_alignment->ta_command,
|
||||
ue->timing_advance);
|
||||
|
||||
ul_time_alignment->ta_frame = -1;
|
||||
ul_time_alignment->ta_slot = -1;
|
||||
@@ -927,33 +903,19 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
int ret=0, ret1=0;
|
||||
NR_UE_PDSCH *pdsch_vars;
|
||||
uint8_t is_cw0_active = 0;
|
||||
uint8_t is_cw1_active = 0;
|
||||
uint8_t dmrs_type, nb_re_dmrs;
|
||||
uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
|
||||
uint16_t nb_symb_sch = 9;
|
||||
nr_downlink_indication_t dl_indication;
|
||||
fapi_nr_rx_indication_t rx_ind;
|
||||
uint16_t number_pdus = 1;
|
||||
// params for UL time alignment procedure
|
||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
|
||||
uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
|
||||
uint16_t slots_per_subframe = ue->frame_parms.slots_per_subframe;
|
||||
uint8_t numerology = ue->frame_parms.numerology_index, mapping_type_ul, mapping_type_dl;
|
||||
int ul_tx_timing_adjustment, N_TA_max, factor_mu, N_t_1, N_t_2, N_1, N_2, d_1_1 = 0, d_2_1, d;
|
||||
uint8_t d_2_2 = 0;// set to 0 because there is only 1 BWP
|
||||
// TODO this should corresponds to the switching time as defined in
|
||||
// TS 38.133
|
||||
uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
|
||||
uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
|
||||
uint32_t t_subframe = 1; // subframe duration of 1 msec
|
||||
uint16_t start_symbol;
|
||||
float tc_factor;
|
||||
|
||||
is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
|
||||
nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
|
||||
start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
|
||||
dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
|
||||
uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status;
|
||||
uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols;
|
||||
uint16_t start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol;
|
||||
uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType;
|
||||
|
||||
uint8_t nb_re_dmrs;
|
||||
if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
|
||||
nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
||||
}
|
||||
@@ -961,6 +923,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
||||
}
|
||||
|
||||
uint8_t is_cw1_active = 0;
|
||||
if(dlsch1)
|
||||
is_cw1_active = dlsch1->harq_processes[harq_pid]->status;
|
||||
|
||||
@@ -1208,7 +1171,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
|
||||
break;
|
||||
case SI_PDSCH:
|
||||
rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB;
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1222,53 +1186,29 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO CRC check for CW0
|
||||
|
||||
// Check CRC for CW 0
|
||||
/*if (ret == (1+dlsch0->max_turbo_iterations)) {
|
||||
*dlsch_errors=*dlsch_errors+1;
|
||||
if(dlsch0->rnti != 0xffff){
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
|
||||
ue->Mod_id,dlsch0->rnti,
|
||||
harq_pid,frame_rx,nr_slot_rx,
|
||||
dlsch0->harq_processes[harq_pid]->rvidx,
|
||||
dlsch0->harq_processes[harq_pid]->round,
|
||||
dlsch0->harq_processes[harq_pid]->mcs,
|
||||
dlsch0->harq_processes[harq_pid]->TBS);
|
||||
}
|
||||
} else {
|
||||
if(dlsch0->rnti != 0xffff){
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n",
|
||||
ue->Mod_id,dlsch0->rnti,
|
||||
harq_pid,frame_rx,nr_slot_rx,
|
||||
dlsch0->harq_processes[harq_pid]->rvidx,
|
||||
dlsch0->harq_processes[harq_pid]->round,
|
||||
dlsch0->harq_processes[harq_pid]->mcs,
|
||||
dlsch0->harq_processes[harq_pid]->TBS);
|
||||
}
|
||||
if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){
|
||||
int j;
|
||||
LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
|
||||
|
||||
for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
|
||||
LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
|
||||
LOG_T(PHY,"\n");
|
||||
}*/
|
||||
|
||||
if (ue->mac_enabled == 1) {
|
||||
|
||||
uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL);
|
||||
|
||||
/* Time Alignment procedure
|
||||
// - UE processing capability 1
|
||||
// - Setting the TA update to be applied after the reception of the TA command
|
||||
// - Timing adjustment computed according to TS 38.213 section 4.2
|
||||
// - Durations of N1 and N2 symbols corresponding to PDSCH and PUSCH are
|
||||
// computed according to sections 5.3 and 6.4 of TS 38.214 */
|
||||
factor_mu = 1 << numerology;
|
||||
N_TA_max = 3846 * bw_scaling / factor_mu;
|
||||
const int numerology = ue->frame_parms.numerology_index;
|
||||
const int ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size;
|
||||
const int nb_prefix_samples = ue->frame_parms.nb_prefix_samples;
|
||||
const int samples_per_subframe = ue->frame_parms.samples_per_subframe;
|
||||
const int slots_per_frame = ue->frame_parms.slots_per_frame;
|
||||
const int slots_per_subframe = ue->frame_parms.slots_per_subframe;
|
||||
|
||||
const double tc_factor = 1.0 / samples_per_subframe;
|
||||
const uint16_t bw_scaling = get_bw_scaling(ofdm_symbol_size);
|
||||
|
||||
const int Ta_max = 3846; // Max value of 12 bits TA Command
|
||||
const double N_TA_max = Ta_max * bw_scaling * tc_factor;
|
||||
|
||||
/* PDSCH decoding time N_1 for processing capability 1 */
|
||||
int N_1;
|
||||
if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0)
|
||||
N_1 = pdsch_N_1_capability_1[numerology][1];
|
||||
else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available
|
||||
@@ -1277,12 +1217,12 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
N_1 = pdsch_N_1_capability_1[numerology][3];
|
||||
|
||||
/* PUSCH preapration time N_2 for processing capability 1 */
|
||||
N_2 = pusch_N_2_timing_capability_1[numerology][1];
|
||||
mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
|
||||
mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
|
||||
const int N_2 = pusch_N_2_timing_capability_1[numerology][1];
|
||||
|
||||
/* d_1_1 depending on the number of PDSCH symbols allocated */
|
||||
d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
|
||||
const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH
|
||||
int d_1_1 = 0;
|
||||
mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType;
|
||||
if (mapping_type_dl == typeA)
|
||||
if (nb_symb_sch + start_symbol < 7)
|
||||
d_1_1 = 7 - (nb_symb_sch + start_symbol);
|
||||
@@ -1297,22 +1237,26 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
/* d_2_1 */
|
||||
int d_2_1;
|
||||
mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType;
|
||||
if (mapping_type_ul == typeB && start_symbol != 0)
|
||||
d_2_1 = 0;
|
||||
else
|
||||
d_2_1 = 1;
|
||||
|
||||
/* d_2_2 */
|
||||
const double d_2_2 = 0.0; // set to 0 because there is only 1 BWP: TODO this should corresponds to the switching time as defined in TS 38.133
|
||||
|
||||
/* N_t_1 time duration in msec of N_1 symbols corresponding to a PDSCH reception time
|
||||
// N_t_2 time duration in msec of N_2 symbols corresponding to a PUSCH preparation time */
|
||||
N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
|
||||
N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) / factor_mu;
|
||||
double N_t_1 = (N_1 + d_1_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
|
||||
double N_t_2 = (N_2 + d_2_1) * (ofdm_symbol_size + nb_prefix_samples) * tc_factor;
|
||||
if (N_t_2 < d_2_2) N_t_2 = d_2_2;
|
||||
|
||||
/* Time alignment procedure */
|
||||
// N_t_1 + N_t_2 + N_TA_max is in unit of Ts, therefore must be converted to Tc
|
||||
// N_t_1 + N_t_2 + N_TA_max must be in msec
|
||||
tc_factor = 64 * 0.509 * 10e-7;
|
||||
ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe);
|
||||
const double t_subframe = 1.0; // subframe duration of 1 msec
|
||||
const int ul_tx_timing_adjustment = 1 + (int)ceil(slots_per_subframe*(N_t_1 + N_t_2 + N_TA_max + 0.5)/t_subframe);
|
||||
|
||||
if (ul_time_alignment->apply_ta == 1){
|
||||
ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame;
|
||||
@@ -1326,13 +1270,6 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
|
||||
}
|
||||
}
|
||||
|
||||
/*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
|
||||
ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
|
||||
}*/
|
||||
|
||||
// TODO CRC check for CW1
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1736,9 +1673,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
nr_slot_fep(ue,
|
||||
proc,
|
||||
(ue->symbol_offset+i)%(fp->symbols_per_slot),
|
||||
nr_slot_rx,
|
||||
0,
|
||||
0);
|
||||
nr_slot_rx);
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
@@ -1791,9 +1726,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
nr_slot_fep(ue,
|
||||
proc,
|
||||
l,
|
||||
nr_slot_rx,
|
||||
0,
|
||||
0);
|
||||
nr_slot_rx);
|
||||
|
||||
dci_cnt = 0;
|
||||
for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
|
||||
@@ -1852,9 +1785,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
nr_slot_fep(ue,
|
||||
proc,
|
||||
m, //to be updated from higher layer
|
||||
nr_slot_rx,
|
||||
0,
|
||||
0);
|
||||
nr_slot_rx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -79,8 +79,8 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
|
||||
int sf_ahead=4 ;
|
||||
int sl_ahead=0;
|
||||
uint16_t sf_ahead=4 ;
|
||||
uint16_t sl_ahead=0;
|
||||
//uint8_t nfapi_mode = 0;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
@@ -97,6 +97,21 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_id,
|
||||
const frame_t frameP,
|
||||
const rb_id_t Srb_id,
|
||||
uint8_t *buffer_pP)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -185,14 +200,11 @@ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0);
|
||||
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
|
||||
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
|
||||
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// needed for some functions
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
|
||||
void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
|
||||
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
|
||||
dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
|
||||
@@ -248,7 +260,10 @@ int main(int argc, char **argv)
|
||||
int i,aa;//,l;
|
||||
double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
|
||||
uint8_t snr1set=0;
|
||||
float roundStats[50];
|
||||
double roundStats[500] = {0};
|
||||
double blerStats[500] = {0};
|
||||
double berStats[500] = {0};
|
||||
double snrStats[500] = {0};
|
||||
float effRate;
|
||||
//float psnr;
|
||||
float eff_tp_check = 0.7;
|
||||
@@ -659,6 +674,7 @@ int main(int argc, char **argv)
|
||||
rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
|
||||
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
|
||||
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
|
||||
prepare_scc(rrc.carrier.servingcellconfigcommon);
|
||||
uint64_t ssb_bitmap;
|
||||
@@ -666,13 +682,18 @@ int main(int argc, char **argv)
|
||||
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
|
||||
fill_default_secondaryCellGroup(scc,
|
||||
secondaryCellGroup,
|
||||
0,
|
||||
1,
|
||||
n_tx,
|
||||
0);
|
||||
prepare_scd(scd);
|
||||
|
||||
fill_default_secondaryCellGroup(scc,
|
||||
scd,
|
||||
secondaryCellGroup,
|
||||
0,
|
||||
1,
|
||||
n_tx,
|
||||
0);
|
||||
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
fix_scd(scd);
|
||||
/* -U option modify DMRS */
|
||||
if(modify_dmrs) {
|
||||
update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
|
||||
@@ -1114,7 +1135,9 @@ int main(int argc, char **argv)
|
||||
if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
|
||||
} // noise trials
|
||||
|
||||
blerStats[snrRun] = (float) n_errors / (float) n_trials;
|
||||
roundStats[snrRun]/=((float)n_trials);
|
||||
berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials;
|
||||
effRate /= n_trials;
|
||||
printf("*****************************************\n");
|
||||
printf("SNR %f, (false positive %f)\n", SNR,
|
||||
@@ -1122,7 +1145,7 @@ int main(int argc, char **argv)
|
||||
printf("*****************************************\n");
|
||||
printf("\n");
|
||||
dump_pdsch_stats(gNB);
|
||||
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
|
||||
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS);
|
||||
printf("\n");
|
||||
|
||||
if (print_perf==1) {
|
||||
@@ -1187,15 +1210,19 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
//if ((float)n_errors/(float)n_trials <= target_error_rate) {
|
||||
if (effRate > (eff_tp_check*TBS)) {
|
||||
printf("PDSCH test OK\n");
|
||||
break;
|
||||
}
|
||||
|
||||
snrStats[snrRun] = SNR;
|
||||
snrRun++;
|
||||
} // NSR
|
||||
|
||||
LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7);
|
||||
LOG_MM("dlsimStats.m","BLER",blerStats,snrRun,1,7);
|
||||
LOG_MM("dlsimStats.m","BER",berStats,snrRun,1,7);
|
||||
LOG_MM("dlsimStats.m","rounds",roundStats,snrRun,1,7);
|
||||
/*if (n_trials>1) {
|
||||
printf("HARQ stats:\nSNR\tRounds\n");
|
||||
psnr = snr0;
|
||||
|
||||
@@ -55,19 +55,6 @@ signed char quantize(double D, double x, unsigned char B) {
|
||||
return ((char) qxd);
|
||||
}
|
||||
|
||||
|
||||
int8_t
|
||||
mac_rrc_data_req_ue(
|
||||
const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
const frame_t frameP,
|
||||
const rb_id_t Srb_id,
|
||||
const uint8_t Nb_tb,
|
||||
uint8_t *const buffer_pP,
|
||||
const mac_enb_index_t eNB_indexP,
|
||||
const uint8_t mbsfn_sync_area
|
||||
) { return(0);}
|
||||
|
||||
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
|
||||
//NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
|
||||
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
|
||||
@@ -235,6 +222,7 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL
|
||||
|
||||
void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap);
|
||||
void prepare_scc(NR_ServingCellConfigCommon_t *scc);
|
||||
void prepare_scd(NR_ServingCellConfig_t *scd);
|
||||
ngap_gNB_config_t ngap_config;
|
||||
uint32_t ngap_generate_gNB_id(void) {return 0;}
|
||||
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
|
||||
|
||||
@@ -101,8 +101,8 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
|
||||
//gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED;
|
||||
|
||||
gNB->mac_enabled = 1;
|
||||
fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
|
||||
fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||
fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value);
|
||||
fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000);
|
||||
if (mu>2) fp->nr_band = 257;
|
||||
else fp->nr_band = 78;
|
||||
fp->threequarter_fs= 0;
|
||||
@@ -111,7 +111,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
|
||||
|
||||
nr_init_frame_parms(gNB_config, fp);
|
||||
|
||||
init_symbol_rotation(fp,fp->dl_CarrierFreq);
|
||||
init_symbol_rotation(fp);
|
||||
|
||||
gNB->configured = 1;
|
||||
LOG_I(PHY,"gNB configured\n");
|
||||
@@ -540,7 +540,7 @@ int main(int argc, char **argv)
|
||||
if (input_fd==NULL) {
|
||||
gNB->pbch_configured = 1;
|
||||
|
||||
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0;
|
||||
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
|
||||
|
||||
for (int slot=0;slot<frame_parms->slots_per_frame;slot++) {
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
|
||||
@@ -692,9 +692,7 @@ int main(int argc, char **argv)
|
||||
nr_slot_fep(UE,
|
||||
&proc,
|
||||
i%frame_parms->symbols_per_slot,
|
||||
ssb_slot,
|
||||
0,
|
||||
0);
|
||||
ssb_slot);
|
||||
|
||||
nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
|
||||
|
||||
@@ -718,9 +716,9 @@ int main(int argc, char **argv)
|
||||
|
||||
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
|
||||
for (i=0;i<3;i++){
|
||||
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)));
|
||||
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
|
||||
}
|
||||
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits);
|
||||
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
|
||||
//printf("ret %d\n", payload_ret);
|
||||
if (payload_ret!=4)
|
||||
n_errors_payload++;
|
||||
|
||||
@@ -64,7 +64,7 @@ double cpuf;
|
||||
extern uint16_t prach_root_sequence_map0_3[838];
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
//uint8_t nfapi_mode=0;
|
||||
int sl_ahead = 0;
|
||||
uint16_t sl_ahead = 0;
|
||||
|
||||
//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
|
||||
|
||||
@@ -132,13 +132,24 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
|
||||
|
||||
// Dummy function to avoid linking error at compilation of nr-prachsim
|
||||
int is_x2ap_enabled(void)
|
||||
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_id,
|
||||
const frame_t frameP,
|
||||
const rb_id_t Srb_id,
|
||||
uint8_t *buffer_pP)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
// Dummy function to avoid linking error at compilation of nr-prachsim
|
||||
int is_x2ap_enabled(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -454,7 +465,10 @@ int main(int argc, char **argv){
|
||||
|
||||
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
|
||||
|
||||
uint64_t absoluteFrequencyPointA = (mu==1 ? 640000 : 2070833);
|
||||
uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band,
|
||||
frame_parms->dl_CarrierFreq,
|
||||
frame_parms->numerology_index,
|
||||
frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index));
|
||||
|
||||
uint8_t subframe = slot/frame_parms->slots_per_subframe;
|
||||
|
||||
|
||||
@@ -75,13 +75,14 @@ PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
|
||||
int sf_ahead=4 ;
|
||||
uint16_t sf_ahead=4 ;
|
||||
int slot_ahead=6 ;
|
||||
int sl_ahead=0;
|
||||
uint16_t sl_ahead=0;
|
||||
double cpuf;
|
||||
//uint8_t nfapi_mode = 0;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
|
||||
const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
|
||||
@@ -155,15 +156,27 @@ int is_x2ap_enabled(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//nFAPI P7 dummy functions
|
||||
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_id,
|
||||
const frame_t frameP,
|
||||
const rb_id_t Srb_id,
|
||||
uint8_t *buffer_pP)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//nFAPI P7 dummy functions
|
||||
|
||||
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
|
||||
int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
|
||||
int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
|
||||
int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_derive_key(int alg_type, uint8_t alg_id,
|
||||
const uint8_t key[32], uint8_t **out)
|
||||
@@ -607,8 +620,8 @@ int main(int argc, char **argv)
|
||||
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||
|
||||
|
||||
frame_parms->nb_antennas_tx = n_tx;
|
||||
frame_parms->nb_antennas_rx = n_rx;
|
||||
//frame_parms->nb_antennas_tx = n_tx;
|
||||
//frame_parms->nb_antennas_rx = n_rx;
|
||||
frame_parms->N_RB_DL = N_RB_DL;
|
||||
frame_parms->N_RB_UL = N_RB_UL;
|
||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
@@ -626,6 +639,7 @@ int main(int argc, char **argv)
|
||||
rrc.carrier.servingcellconfigcommon = calloc(1,sizeof(*rrc.carrier.servingcellconfigcommon));
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = rrc.carrier.servingcellconfigcommon;
|
||||
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
|
||||
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
|
||||
prepare_scc(rrc.carrier.servingcellconfigcommon);
|
||||
uint64_t ssb_bitmap;
|
||||
@@ -633,7 +647,10 @@ int main(int argc, char **argv)
|
||||
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
|
||||
prepare_scd(scd);
|
||||
|
||||
fill_default_secondaryCellGroup(scc,
|
||||
scd,
|
||||
secondaryCellGroup,
|
||||
0,
|
||||
1,
|
||||
@@ -642,11 +659,14 @@ int main(int argc, char **argv)
|
||||
|
||||
// xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
fix_scd(scd);
|
||||
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
|
||||
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
// common configuration
|
||||
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
|
||||
rrc_mac_config_req_gNB(0,0,n_rx,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
|
||||
// UE dedicated configuration
|
||||
rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
|
||||
phy_init_nr_gNB(gNB,0,0);
|
||||
@@ -1053,70 +1073,69 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
|
||||
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
|
||||
//nr_fill_ulsch(gNB,frame,slot,pusch_pdu); // Not needed as its its already filled as apart of "nr_schedule_response(Sched_INFO);"
|
||||
|
||||
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
if (input_fd == NULL) {
|
||||
|
||||
// set FAPI parameters for UE, put them in the scheduled response and call
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
|
||||
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
|
||||
///////////
|
||||
|
||||
phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
|
||||
|
||||
|
||||
if (n_trials==1) {
|
||||
LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
|
||||
LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
}
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
|
||||
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
// set FAPI parameters for UE, put them in the scheduled response and call
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
|
||||
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
|
||||
///////////
|
||||
|
||||
phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id);
|
||||
|
||||
|
||||
if (n_trials==1) {
|
||||
LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
|
||||
LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
}
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
|
||||
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
}
|
||||
else n_trials = 1;
|
||||
|
||||
if (input_fd == NULL ) {
|
||||
|
||||
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
|
||||
sigma = pow(10,sigma_dB/10);
|
||||
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
|
||||
sigma = pow(10,sigma_dB/10);
|
||||
|
||||
|
||||
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb));
|
||||
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)
|
||||
frame_parms->ofdm_symbol_size/(12*nb_rb));
|
||||
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (int aa=0; aa<1; aa++) {
|
||||
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
|
||||
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
|
||||
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (UE2gNB->max_Doppler == 0) {
|
||||
multipath_channel(UE2gNB,s_re,s_im,r_re,r_im,
|
||||
slot_length,0,(n_trials==1)?1:0);
|
||||
} else {
|
||||
multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
|
||||
2*slot_length,0);
|
||||
}
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
|
||||
|
||||
if (UE2gNB->max_Doppler == 0) {
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
|
||||
} else {
|
||||
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
|
||||
}
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
|
||||
/* Add phase noise if enabled */
|
||||
if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
|
||||
&((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} /*End input_fd */
|
||||
|
||||
|
||||
if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
Reference in New Issue
Block a user