Commit 13d1be07 authored by Raymond Knopp's avatar Raymond Knopp

added TDL channel models and use them in nr_ulsim

parent 7989afbb
...@@ -707,7 +707,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -707,7 +707,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx]; Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx); LOG_I(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx);
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t)); memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
...@@ -790,7 +790,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -790,7 +790,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
else *TA = *TA/2; else *TA = *TA/2;
if (LOG_DUMPFLAG(PRACH)) { //if (LOG_DUMPFLAG(PRACH)) {
//int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); //int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
// if (en>60) { // if (en>60) {
int k = (12*n_ra_prb) - 6*fp->N_RB_UL; int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
...@@ -807,7 +807,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -807,7 +807,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
LOG_M("Xu.m","xu",Xu,N_ZC,1,1); LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
// } // }
} /* LOG_DUMPFLAG(PRACH) */ //} /* LOG_DUMPFLAG(PRACH) */
stop_meas(&gNB->rx_prach); stop_meas(&gNB->rx_prach);
} }
......
...@@ -729,6 +729,7 @@ int main(int argc, char **argv) { ...@@ -729,6 +729,7 @@ int main(int argc, char **argv) {
channel_model, channel_model,
N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
30e-9,
forgetting_factor, forgetting_factor,
delay, delay,
0); 0);
......
...@@ -106,6 +106,12 @@ uint16_t n_rnti = 0x1234; ...@@ -106,6 +106,12 @@ uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS]; openair0_config_t openair0_cfg[MAX_CARDS];
//const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3}; //const uint8_t nr_rv_round_map[4] = {0, 2, 1, 3};
channel_desc_t *UE2gNB[NUMBER_OF_UE_MAX][NUMBER_OF_gNB_MAX];
double s_re0[122880],s_im0[122880],r_re0[122880],r_im0[122880];
double s_re1[122880],s_im1[122880],r_re1[122880],r_im1[122880];
double r_re2[122880],r_im2[122880];
double r_re3[122880],r_im3[122880];
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char c; char c;
...@@ -116,23 +122,31 @@ int main(int argc, char **argv) ...@@ -116,23 +122,31 @@ int main(int argc, char **argv)
uint8_t snr1set = 0; uint8_t snr1set = 0;
int slot = 8, frame = 0; int slot = 8, frame = 0;
FILE *output_fd = NULL; FILE *output_fd = NULL;
double *s_re[2]= {s_re0,s_re1};
double *s_im[2]= {s_im0,s_im1};
double *r_re[4]= {r_re0,r_re1,r_re2,r_re3};
double *r_im[4]= {r_im0,r_im1,r_im2,r_im3};
//uint8_t write_output_file = 0; //uint8_t write_output_file = 0;
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0; int trial, n_trials = 1, n_errors = 0, n_false_positive = 0, delay = 0;
double maxDoppler = 0.0;
uint8_t n_tx = 1, n_rx = 1; uint8_t n_tx = 1, n_rx = 1;
//uint8_t transmission_mode = 1; //uint8_t transmission_mode = 1;
//uint16_t Nid_cell = 0; //uint16_t Nid_cell = 0;
channel_desc_t *gNB2UE; channel_desc_t *UE2gNB;
uint8_t extended_prefix_flag = 0; uint8_t extended_prefix_flag = 0;
//int8_t interf1 = -21, interf2 = -21; //int8_t interf1 = -21, interf2 = -21;
FILE *input_fd = NULL; FILE *input_fd = NULL;
SCM_t channel_model = AWGN; //Rayleigh1_anticorr; SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
double tx_gain=1.0;
double N0=30;
//unsigned char frame_type = 0; //unsigned char frame_type = 0;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
int loglvl = OAILOG_WARNING; int loglvl = OAILOG_WARNING;
//uint64_t SSB_positions=0x01; //uint64_t SSB_positions=0x01;
uint16_t nb_symb_sch = 12; uint16_t nb_symb_sch = 12;
int start_symbol = 2; int start_symbol = 0;
uint16_t nb_rb = 50; uint16_t nb_rb = 50;
uint8_t Imcs = 9; uint8_t Imcs = 9;
uint8_t precod_nbr_layers = 1; uint8_t precod_nbr_layers = 1;
...@@ -156,6 +170,8 @@ int main(int argc, char **argv) ...@@ -156,6 +170,8 @@ int main(int argc, char **argv)
UE_nr_rxtx_proc_t UE_proc; UE_nr_rxtx_proc_t UE_proc;
FILE *scg_fd=NULL; FILE *scg_fd=NULL;
double TDL_DS = 30e-9;
int ibwps=24; int ibwps=24;
int ibwp_rboffset=41; int ibwp_rboffset=41;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) { if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
...@@ -234,7 +250,22 @@ int main(int argc, char **argv) ...@@ -234,7 +250,22 @@ int main(int argc, char **argv)
case 'G': case 'G':
channel_model = ETU; channel_model = ETU;
break; break;
case 'H':
channel_model = TDL_C;
TDL_DS = 30e-9;
break;
case 'I':
channel_model = TDL_C;
TDL_DS = 300e-9;
break;
case 'J':
channel_model=TDL_D;
TDL_DS = 30e-9;
break;
default: default:
printf("Unsupported channel model!\n"); printf("Unsupported channel model!\n");
exit(-1); exit(-1);
...@@ -401,13 +432,26 @@ int main(int argc, char **argv) ...@@ -401,13 +432,26 @@ int main(int argc, char **argv)
if (snr1set == 0) if (snr1set == 0)
snr1 = snr0 + 10; snr1 = snr0 + 10;
double sampling_frequency;
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, double bandwidth;
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL), if (N_RB_UL >= 217) sampling_frequency = 122.88e6;
else if (N_RB_UL >= 106) sampling_frequency = 61.44e6;
else { printf("Need at least 106 PRBs\b"); exit(-1); }
if (N_RB_UL == 273) bandwidth = 100e6;
else if (N_RB_UL == 217) bandwidth = 80e6;
else if (N_RB_UL == 106) bandwidth = 40e6;
else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
sampling_frequency,
bandwidth,
TDL_DS,
0, 0, 0); 0, 0, 0);
if (gNB2UE == NULL) { UE2gNB->max_Doppler = maxDoppler;
if (UE2gNB == NULL) {
printf("Problem generating channel model. Exiting.\n"); printf("Problem generating channel model. Exiting.\n");
exit(-1); exit(-1);
} }
...@@ -470,7 +514,6 @@ int main(int argc, char **argv) ...@@ -470,7 +514,6 @@ int main(int argc, char **argv)
N_RB_DL = gNB->frame_parms.N_RB_DL; N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0];
//crcTableInit(); //crcTableInit();
...@@ -574,6 +617,8 @@ int main(int argc, char **argv) ...@@ -574,6 +617,8 @@ int main(int argc, char **argv)
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table); uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb); uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
if (input_fd != NULL) max_rounds=1;
if(1<<ptrs_time_density >= nb_symb_sch) if(1<<ptrs_time_density >= nb_symb_sch)
pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
...@@ -774,22 +819,38 @@ int main(int argc, char **argv) ...@@ -774,22 +819,38 @@ int main(int argc, char **argv)
} }
else n_trials = 1; else n_trials = 1;
if (input_fd == NULL ) {
sigma_dB = 10*log10(txlev_float)-SNR; sigma_dB = N0;
sigma = pow(10,sigma_dB/10); sigma = pow(10,sigma_dB/10);
if(n_trials==1) printf("txlev_float %f, sigma_dB %f\n",10*log10(txlev_float),sigma_dB);
//---------------------------------------------------------- tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/txlev_float);
//------------------------ add noise ----------------------- if(n_trials==1) printf("txlev_float %f, sigma_dB %f, tx_gain %f tx_offset %d, slot_offset %d\n",10*log10(txlev_float),sigma_dB,tx_gain,tx_offset,slot_offset);
//----------------------------------------------------------
if (input_fd == NULL ) { for (i=0; i<slot_length; i++) {
for (i=0; i<slot_length; i++) { for (int aa=0; aa<1; aa++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) { s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)])/sqrt(scale) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((double)(((int16_t *)&UE->common_vars.txdata[ap][slot_offset])[(i<<1)+1])/sqrt(scale) + (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);
} else {
multipath_tv_channel(UE2gNB,s_re,s_im,r_re,r_im,
2*slot_length,0);
}
for (i=0; i<slot_length; i++) {
if (n_trials== 1 && i<256) printf("i %d : (%f,%f)*%f = (%f,%f) \n",i,r_re[0][i],r_im[0][i],tx_gain,r_re[0][i]*tx_gain,r_im[0][i]*tx_gain);
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)((tx_gain*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)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
} }
} }
}
else { else {
AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n"); AssertFatal(frame_parms->nb_antennas_rx == 1, "nb_ant != 1\n");
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s, // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
...@@ -799,7 +860,7 @@ int main(int argc, char **argv) ...@@ -799,7 +860,7 @@ int main(int argc, char **argv)
int ta_offset=1600; int ta_offset=1600;
if (N_RB_DL <217) ta_offset=800; if (N_RB_DL <217) ta_offset=800;
else if (N_RB_DL < 106) ta_offset = 400; else if (N_RB_DL < 106) ta_offset = 400;
fseek(input_fd,(slot_length<<2)+2000,SEEK_SET);
fread((void*)&gNB->common_vars.rxdata[0][slot_offset], fread((void*)&gNB->common_vars.rxdata[0][slot_offset],
sizeof(int16_t), sizeof(int16_t),
slot_length<<1, slot_length<<1,
...@@ -821,14 +882,14 @@ int main(int argc, char **argv) ...@@ -821,14 +882,14 @@ int main(int argc, char **argv)
start_meas(&gNB->phy_proc_rx); start_meas(&gNB->phy_proc_rx);
phy_procedures_gNB_common_RX(gNB, frame, slot); phy_procedures_gNB_common_RX(gNB, frame, slot);
if (n_trials==1) { if (n_trials==1 && round==0) {
LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][0],frame_parms->samples_per_subframe*10,1,1); LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][0],frame_parms->samples_per_subframe*10,1,1);
LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1); LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
} }
phy_procedures_gNB_uespec_RX(gNB, frame, slot); phy_procedures_gNB_uespec_RX(gNB, frame, slot);
if (n_trials == 1) { if (n_trials == 1 && round==0) {
LOG_M("rxsigF0_ext.m","rxsF0_ext", LOG_M("rxsigF0_ext.m","rxsF0_ext",
&gNB->pusch_vars[0]->rxdataF_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1); &gNB->pusch_vars[0]->rxdataF_ext[0][(start_symbol+1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size,1,1);
LOG_M("chestF0.m","chF0", LOG_M("chestF0.m","chF0",
......
...@@ -201,11 +201,11 @@ void multipath_channel(channel_desc_t *desc, ...@@ -201,11 +201,11 @@ void multipath_channel(channel_desc_t *desc,
rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss; rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss; rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
/*
if ((ii==0)&&((i%32)==0)) { /* if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]); printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
} }*/
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]); //rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]); //rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
......
...@@ -173,6 +173,223 @@ double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6 ...@@ -173,6 +173,223 @@ double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6
double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250}; double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62}; double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
double tdl_a_delays[] = {0.0000,
0.3819,
0.4025,
0.5868,
0.4610,
0.5375,
0.6708,
0.5750,
0.7618,
1.5375,
1.8978,
2.2242,
2.1718,
2.4942,
2.5119,
3.0582,
4.0810,
4.4579,
4.5695,
4.7966,
5.0066,
5.3043,
9.6586};
double tdl_a_amps_dB[] = {-13.4,
0,
-2.2,
-4,
-6,
-8.2,
-9.9,
-10.5,
-7.5,
-15.9,
-6.6,
-16.7,
-12.4,
-15.2,
-10.8,
-11.3,
-12.7,
-16.2,
-18.3,
-18.9,
-16.6,
-19.9,
-29.7};
#define TDL_A_PATHS 23
double tdl_b_delays[] = {0.0000,
0.1072,
0.2155,
0.2095,
0.2870,
0.2986,
0.3752,
0.5055,
0.3681,
0.3697,
0.5700,
0.5283,
1.1021,
1.2756,
1.5474,
1.7842,
2.0169,
2.8294,
3.0219,
3.6187,
4.1067,
4.2790,
4.7834};
double tdl_b_amps_dB[] = {0,
-2.2,
-4,
-3.2,
-9.8,
-1.2,
-3.4,
-5.2,
-7.6,
-3,
-8.9,
-9,
-4.8,
-5.7,
-7.5,
-1.9,
-7.6,
-12.2,
-9.8,
-11.4,
-14.9,
-9.2,
-11.3};
#define TDL_B_PATHS 23
double tdl_c_delays[] = {0,
0.2099,
0.2219,
0.2329,
0.2176,
0.6366,
0.6448,
0.6560,
0.6584,
0.7935,
0.8213,
0.9336,
1.2285,
1.3083,
2.1704,
2.7105,
4.2589,
4.6003,
5.4902,
5.6077,
6.3065,
6.6374,
7.0427,
8.6523};
double tdl_c_amps_dB[] = {-4.4,
-1.2,
-3.5,
-5.2,
-2.5,
0,
-2.2,
-3.9,
-7.4,
-7.1,
-10.7,
-11.1,
-5.1,
-6.8,
-8.7,
-13.2,
-13.9,
-13.9,
-15.8,
-17.1,
-16,
-15.7,
-21.6,
-22.8};
#define TDL_C_PATHS 24
double tdl_d_delays[] = {//0,
0,
0.035,
0.612,
1.363,
1.405,
1.804,
2.596,
1.775,
4.042,
7.937,
9.424,
9.708,
12.525};
double tdl_d_amps_dB[] = {//-0.2,
//-13.5,
-.00147,
-18.8,
-21,
-22.8,
-17.9,
-20.1,
-21.9,
-22.9,
-27.8,
-23.6,
-24.8,
-30.0,
-27.7};
#define TDL_D_PATHS 13
#define TDL_D_RICEAN_FACTOR .046774
double tdl_e_delays[] = {0,
0.5133,
0.5440,
0.5630,
0.5440,
0.7112,
1.9092,
1.9293,
1.9589,
2.6426,
3.7136,
5.4524,
12.0034,
20.6519};
double tdl_e_amps_dB[] = {//-0.03,
//-22.03,
-.00433,
-15.8,
-18.1,
-19.8,
-22.9,
-22.4,
-18.6,
-20.8,
-22.6,
-22.3,
-25.6,
-20.2,
-29.8,
-29.2};
#define TDL_E_PATHS 14
#define TDL_E_RICEAN_FACTOR 0.0063096
double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41}; double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41};
double epa_amps_dB[] = {0.0,-1.0,-2.0,-3.0,-8.0,-17.2,-20.8}; double epa_amps_dB[] = {0.0,-1.0,-2.0,-3.0,-8.0,-17.2,-20.8};
...@@ -277,6 +494,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -277,6 +494,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
SCM_t channel_model, SCM_t channel_model,
double sampling_rate, double sampling_rate,
double channel_bandwidth, double channel_bandwidth,
double DS_TDL,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB) { double path_loss_dB) {
...@@ -284,6 +502,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -284,6 +502,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint16_t i,j; uint16_t i,j;
double sum_amps; double sum_amps;
double aoa,ricean_factor,Td,maxDoppler; double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps; int channel_length,nb_taps;
chan_desc->nb_tx = nb_tx; chan_desc->nb_tx = nb_tx;
chan_desc->nb_rx = nb_rx; chan_desc->nb_rx = nb_rx;
...@@ -296,6 +515,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -296,6 +515,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->ip = 0.0; chan_desc->ip = 0.0;
LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model); LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
int tdl_paths=0;
double tdl_ricean_factor = 1;
double *tdl_amps_dB;
double *tdl_delays;
switch (channel_model) { switch (channel_model) {
case SCM_A: case SCM_A:
LOG_W(OCM,"channel model not yet supported\n"); LOG_W(OCM,"channel model not yet supported\n");
...@@ -423,6 +647,99 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -423,6 +647,99 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
} }
break; break;
case TDL_A:
case TDL_B:
case TDL_C:
case TDL_D:
case TDL_E:
if (channel_model == TDL_A) {
tdl_paths=TDL_A_PATHS;
tdl_delays=tdl_a_delays;
tdl_amps_dB=tdl_a_amps_dB;
}else if (channel_model == TDL_B) {
tdl_paths=TDL_B_PATHS;
tdl_delays=tdl_b_delays;
tdl_amps_dB=tdl_b_amps_dB;
}
else if (channel_model == TDL_C) {
tdl_paths=TDL_C_PATHS;
tdl_delays=tdl_c_delays;
tdl_amps_dB=tdl_c_amps_dB;
printf("Initializing TDL_C channel with %d paths\n",TDL_C_PATHS);
} else if (channel_model == TDL_D) {
tdl_paths=TDL_D_PATHS;
tdl_delays=tdl_d_delays;
tdl_amps_dB=tdl_d_amps_dB;
tdl_ricean_factor = TDL_D_RICEAN_FACTOR;
} else if (channel_model == TDL_E) {
tdl_paths=TDL_E_PATHS-1;
tdl_delays=tdl_e_delays+1;
tdl_amps_dB=tdl_e_amps_dB;
tdl_ricean_factor = TDL_E_RICEAN_FACTOR;
}
int tdl_pathsby3 = tdl_paths/3;
if ((tdl_paths%3)>0) tdl_pathsby3++;
chan_desc->nb_taps = tdl_paths;
chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL;
printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]);
sum_amps += chan_desc->amps[i];
}
for (i = 0; i<chan_desc->nb_taps; i++)
chan_desc->amps[i] /= sum_amps;
chan_desc->delays = tdl_delays;
chan_desc->ricean_factor = tdl_ricean_factor;
chan_desc->aoa = 0;
chan_desc->random_aoa = 0;
chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
for (i = 0; i<nb_tx*nb_rx; i++)
chan_desc->chF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
for (i = 0; i<chan_desc->nb_taps; i++)
chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
if (nb_tx==2 && nb_rx==2) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else if (nb_tx==2 && nb_rx==1) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
} else if (nb_tx==1 && nb_rx==2) {
for (i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
for (i = 0; i<(tdl_pathsby3); i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
}
LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
}
}
break;
case EPA: case EPA:
chan_desc->nb_taps = 7; chan_desc->nb_taps = 7;
......
...@@ -160,6 +160,11 @@ typedef enum { ...@@ -160,6 +160,11 @@ typedef enum {
EVA, EVA,
ETU, ETU,
MBSFN, MBSFN,
TDL_A,
TDL_B,
TDL_C,
TDL_D,
TDL_E,
Rayleigh8, Rayleigh8,
Rayleigh1, Rayleigh1,
Rayleigh1_800, Rayleigh1_800,
...@@ -190,6 +195,11 @@ typedef enum { ...@@ -190,6 +195,11 @@ typedef enum {
{"EVA",EVA},\ {"EVA",EVA},\
{"ETU",ETU},\ {"ETU",ETU},\
{"MBSFN",MBSFN},\ {"MBSFN",MBSFN},\
{"TDL_A",TDL_A},\
{"TDL_B",TDL_B},\
{"TDL_C",TDL_C},\
{"TDL_D",TDL_D},\
{"TDL_E",TDL_E},\
{"Rayleigh8",Rayleigh8},\ {"Rayleigh8",Rayleigh8},\
{"Rayleigh1",Rayleigh1},\ {"Rayleigh1",Rayleigh1},\
{"Rayleigh1_800",Rayleigh1_800},\ {"Rayleigh1_800",Rayleigh1_800},\
...@@ -243,33 +253,12 @@ typedef struct { ...@@ -243,33 +253,12 @@ typedef struct {
} sim_t; } sim_t;
/**
\brief This routine initializes a new channel descriptor
\param nb_tx Number of TX antennas
\param nb_rx Number of RX antennas
\param nb_taps Number of taps
\param channel_length Length of the interpolated channel impulse response
\param amps Linear amplitudes of the taps (length(amps)=channel_length). The values should sum up to 1.
\param delays Delays of the taps. If delays==NULL the taps are assumed to be spaced equidistantly between 0 and t_max.
\param R_sqrt Channel correlation matrix. If R_sqrt==NULL, no channel correlation is applied.
\param Td Maximum path delay in mus.
\param BW Channel bandwidth in MHz.
\param ricean_factor Ricean factor applied to all taps.
\param aoa Anlge of arrival
\param forgetting_factor This parameter (0...1) allows for simple 1st order temporal variation
\param max_Doppler This is the maximum Doppler frequency for Jakes' Model
\param channel_offset This is a time delay to apply to channel
\param path_loss_dB This is the path loss in dB
\param random_aoa If set to 1, AoA of ricean component is randomized
*/
//channel_desc_t *new_channel_desc(uint8_t nb_tx,uint8_t nb_rx, uint8_t nb_taps, uint8_t channel_length, double *amps, double* delays, struct complex** R_sqrt, double Td, double BW, double ricean_factor, double aoa, double forgetting_factor, double max_Doppler, int32_t channel_offset, double path_loss_dB,uint8_t random_aoa);
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx, uint8_t nb_rx,
SCM_t channel_model, SCM_t channel_model,
double sampling_rate, double sampling_rate,
double channel_bandwidth, double channel_bandwidth,
double TDL_DS,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB); double path_loss_dB);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment