Commit 01ef8c2f authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/develop-channel-models' into integration_2022_wk43

parents dd1d80bd f4982ca0
......@@ -166,10 +166,10 @@ class PhySim:
isRunning = True
podNames = re.findall('oai-[\S\d\w]+', mySSH.getBefore())
count +=1
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc describe pod $pod >> cmake_targets/log/physim_pods_summary.txt; done', '\$', 10)
if isRunning == False:
logging.error('\u001B[1m Some PODS Running FAILED \u001B[0m')
mySSH.command('oc get pods -l app.kubernetes.io/instance=physim 2>&1 | tee -a cmake_targets/log/physim_pods_summary.txt', '\$', 6)
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc describe pod $pod >> cmake_targets/log/physim_pods_summary.txt; done', '\$', 10)
mySSH.command('helm uninstall physim 2>&1 >> cmake_targets/log/physim_helm_summary.txt', '\$', 6)
self.AnalyzeLogFile_phySim()
isFinished1 = False
......@@ -206,6 +206,7 @@ class PhySim:
# Getting the logs of each executables running in individual pods
for podName in podNames:
mySSH.command(f'oc logs {podName} >> cmake_targets/log/physim_test.txt 2>&1', '\$', 15, resync=True)
mySSH.command('for pod in $(oc get pods | tail -n +2 | awk \'{print $1}\'); do oc describe pod $pod >> cmake_targets/log/physim_pods_summary.txt; done', '\$', 10)
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/log/physim_test.txt', '.')
try:
listLogFiles = subprocess.check_output('egrep --colour=never "Execution Log file|Linux oai-" physim_test.txt', shell=True, universal_newlines=True)
......
......@@ -354,10 +354,10 @@
(Test3: MCS 28 50 PRBs),
(Test4: MCS 9 217 PRBs),
(Test5: MCS 9 273 PRBs),
(Test6: DMRS Type A, 2 DMRS Symbols),
(Test7: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
(Test9: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test6: PUSCH Type A, 2 DMRS Symbols),
(Test7: PUSCH Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
(Test8: PUSCH Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
(Test9: PUSCH Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test10: 25 PRBs, 15 kHz SCS),
(Test11: MCS 0, low SNR performance)</desc>
<main_exec>nr_ulsim</main_exec>
......@@ -366,12 +366,12 @@
-n100 -m28 -s20
-n100 -m9 -R217 -r217 -s5
-n100 -m9 -R273 -r273 -s5
-n100 -s5 -U 4 0 1 1 1
-n100 -s5 -T 2 1 2 -U 4 0 2 1 1
-n100 -s5 -T 2 2 2 -U 4 1 2 1 1
-n100 -s5 -a4 -b8 -T 2 1 2 -U 4 1 3 1 1
-n100 -u0 -m0 -R25 -r25 -i 2 1 0
-n100 -m0 -S -0.6 -i 2 1 0</main_exec_args>
-n100 -s5 -U 0,1,1,1
-n100 -s5 -T 1,2 -U 0,2,1,1
-n100 -s5 -T 2,2 -U 1,2,1,1
-n100 -s5 -a4 -b8 -T 1,2 -U 1,3,1,1
-n100 -u0 -m0 -R25 -r25 -i 1,0
-n100 -m0 -S -0.6 -i 1,0</main_exec_args>
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
......@@ -389,7 +389,7 @@
-n100 -s5 -Z -r75
-n50 -s5 -Z -r216 -R217
-n50 -s5 -Z -r270 -R273
-n100 -s5 -Z -U 4 0 2 1 2</main_exec_args>
-n100 -s5 -Z -U 0,2,1,2</main_exec_args>
<tags>test1 test2 test3 test4 test5</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
......@@ -402,8 +402,8 @@
(Test3: MCS 9 106 PRBs MIMO 4 layers)</desc>
<main_exec>nr_ulsim</main_exec>
<main_exec_args>-n100 -m19 -s10 -S15 -z2
-n100 -m9 -r106 -s10 -W2 -y2 -z2
-n100 -m9 -r106 -s20 -W4 -y4 -z4</main_exec_args>
-n100 -m9 -r106 -s8 -W2 -y2 -z2
-n100 -m9 -r106 -s10 -W4 -y4 -z4</main_exec_args>
<tags>test1 test2 test3</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
......@@ -411,14 +411,56 @@
</testCase>
<testCase id="nr_ulsim.3gpp">
<desc>nr_ulsim Test cases. (Test1: 3GPP G-FR1-A4-13 2 RX Antennas Requirements Test),
(Test2: 3GPP G-FR1-A4-13 4 RX Antennas Requirements Test),
(Test3: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test)</desc>
<desc>nr_ulsim Test cases. (Test1: 3GPP G-FR1-A5-13, PUSCH Type A, 40 MHz BW, 30 kHz SCS, 2 RX Antennas Requirements Test),
(Test2: 3GPP G-FR1-A5-13, PUSCH Type A, 40 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
(Test3: 3GPP G-FR1-A5-13, PUSCH Type A, 40 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test),
(Test4: 3GPP G-FR1-A5-8, PUSCH Type B, 5 MHz BW, 15 kHz SCS, 2 RX Antennas Requirements Test),
(Test5: 3GPP G-FR1-A5-8, PUSCH Type B, 5 MHz BW, 15 kHz SCS, 4 RX Antennas Requirements Test),
(Test6: 3GPP G-FR1-A5-8, PUSCH Type B, 5 MHz BW, 15 kHz SCS, 8 RX Antennas Requirements Test),
(Test7: 3GPP G-FR1-A5-9, PUSCH Type B, 10 MHz BW, 15 kHz SCS, 2 RX Antennas Requirements Test),
(Test8: 3GPP G-FR1-A5-9, PUSCH Type B, 10 MHz BW, 15 kHz SCS, 4 RX Antennas Requirements Test),
(Test9: 3GPP G-FR1-A5-9, PUSCH Type B, 10 MHz BW, 15 kHz SCS, 8 RX Antennas Requirements Test),
(Test10: 3GPP G-FR1-A5-10, PUSCH Type B, 20 MHz BW, 15 kHz SCS, 2 RX Antennas Requirements Test),
(Test11: 3GPP G-FR1-A5-10, PUSCH Type B, 20 MHz BW, 15 kHz SCS, 4 RX Antennas Requirements Test),
(Test12: 3GPP G-FR1-A5-10, PUSCH Type B, 20 MHz BW, 15 kHz SCS, 8 RX Antennas Requirements Test),
(Test13: 3GPP G-FR1-A5-11, PUSCH Type B, 10 MHz BW, 30 kHz SCS, 2 RX Antennas Requirements Test),
(Test14: 3GPP G-FR1-A5-11, PUSCH Type B, 10 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
(Test15: 3GPP G-FR1-A5-11, PUSCH Type B, 10 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test),
(Test16: 3GPP G-FR1-A5-12, PUSCH Type B, 20 MHz BW, 30 kHz SCS, 2 RX Antennas Requirements Test),
(Test17: 3GPP G-FR1-A5-12, PUSCH Type B, 20 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
(Test18: 3GPP G-FR1-A5-12, PUSCH Type B, 20 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test),
(Test19: 3GPP G-FR1-A5-13, PUSCH Type B, 40 MHz BW, 30 kHz SCS, 2 RX Antennas Requirements Test),
(Test20: 3GPP G-FR1-A5-13, PUSCH Type B, 40 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
(Test21: 3GPP G-FR1-A5-13, PUSCH Type B, 40 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test),
(Test22: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 2 RX Antennas Requirements Test),
(Test23: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
(Test24: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test)</desc>
<main_exec>nr_ulsim</main_exec>
<main_exec_args>-m16 -r106 -s8.8 -S9.4 -z2 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s5.4 -S6 -z4 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0</main_exec_args>
<tags>test1 test2 test3</tags>
<main_exec_args>-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z2 -s12.4 -S12.4
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z4 -s8.5 -S8.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z8 -s5.4 -S5.4
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z2 -s12.5 -S12.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z4 -s8.9 -S8.9
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z8 -s5.7 -S5.7
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z2 -s12.6 -S12.6
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z4 -s8.9 -S8.9
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z8 -s5.8 -S5.8
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.3 -S12.3
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.8 -S8.8
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.7 -S5.7
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z2 -s12.5 -S12.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z4 -s8.6 -S8.6
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z8 -s5.6 -S5.6
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z2 -s12.5 -S12.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z4 -s8.6 -S8.6
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z8 -s5.6 -S5.6
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.5 -S12.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.7 -S8.7
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.5 -S5.5
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z2 -s13.1 -S13.1
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z4 -s9.2 -S9.2
-n100 -b14 -I15 -i 1,1 -g A,l -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z8 -s5.9 -S5.9</main_exec_args>
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 test22 test23 test24</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
......
......@@ -397,11 +397,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
*ul_ch=ch;
#else
c16multaddVectRealComplex(filt8_avlip0, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip0, &ch, ul_ch, 8);
ul_ch += 8;
c16multaddVectRealComplex(filt8_avlip1, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip1, &ch, ul_ch, 8);
ul_ch += 8;
c16multaddVectRealComplex(filt8_avlip2, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip2, &ch, ul_ch, 8);
ul_ch -= 12;
#endif
......@@ -416,13 +416,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384
ul_ch += 4;
multadd_real_vector_complex_scalar(filt8_avlip3, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip4, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip4, &ch, ul_ch, 8);
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip5, ch, ul_ch, 8);
c16multaddVectRealComplex(filt8_avlip5, &ch, ul_ch, 8);
ul_ch -= 8;
#endif
}
......@@ -437,16 +435,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384
ul_ch += 4;
c16multaddVectRealComplex(filt8_avlip3,
ch,
ul_ch,
8);
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
ul_ch += 8;
c16multaddVectRealComplex(filt8_avlip6,
ch,
ul_ch,
8);
c16multaddVectRealComplex(filt8_avlip6, &ch, ul_ch, 8);
#endif
} else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB
LOG_D(PHY,"PUSCH estimation DMRS type 2, no Freq-domain interpolation");
......@@ -514,7 +505,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
*ul_ch=ch;
#else
ul_ch[3]=c16maddShift(ch,(c16_t) {1365,1365},15); // 1365 = 1/12*16384 (full range is +/- 32768)
ul_ch[3] = c16maddShift(ch, (c16_t){1365, 1365}, (c16_t){0, 0}, 15); // 1365 = 1/12*16384 (full range is +/- 32768)
ul_ch += 4;
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
ul_ch += 8;
......@@ -547,7 +538,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
*ul_ch=ch;
#else
ul_ch[3]=c16maddShift(ch, c16_t {1365,1365},15);// 1365 = 1/12*16384 (full range is +/- 32768)
ul_ch[3] = c16maddShift(ch, (c16_t){1365, 1365}, (c16_t){0, 0}, 15); // 1365 = 1/12*16384 (full range is +/- 32768)
ul_ch += 4;
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
ul_ch += 8;
......
......@@ -1954,6 +1954,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
uint32_t rxdataF_ext_offset = 0;
uint8_t ad_shift = 1 + log2_approx(frame_parms->nb_antennas_rx >> 2);
for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) {
uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
......@@ -2021,7 +2022,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++)
avgs = cmax(avgs,avg[aatx*frame_parms->nb_antennas_rx+aarx]);
gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs)/2)+2;
gNB->pusch_vars[ulsch_id]->log2_maxh = (log2_approx(avgs) / 2) + ad_shift;
gNB->pusch_vars[ulsch_id]->cl_done = 1;
}
......
......@@ -1192,9 +1192,11 @@ int main(int argc, char **argv) {
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
DS_TDL,
CORR_LEVEL_LOW,
forgetting_factor,
rx_sample_offset,
0, 0);
0,
0);
reset_meas(&eNB2UE[0]->random_channel);
reset_meas(&eNB2UE[0]->interp_time);
......@@ -1206,9 +1208,11 @@ int main(int argc, char **argv) {
N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
DS_TDL,
CORR_LEVEL_LOW,
forgetting_factor,
rx_sample_offset,
0, 0);
0,
0);
reset_meas(&eNB2UE[n]->random_channel);
reset_meas(&eNB2UE[n]->interp_time);
}
......
......@@ -741,9 +741,11 @@ int main(int argc, char **argv) {
N_RB2sampling_rate(eNB->frame_parms.N_RB_UL),
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
30e-9,
CORR_LEVEL_LOW,
forgetting_factor,
delay,
0, 0);
0,
0);
// set Doppler
UE2eNB->max_Doppler = maxDoppler;
......
......@@ -336,11 +336,15 @@ int main(int argc, char **argv)
if (ouput_vcd)
vcd_signal_dumper_init("/tmp/openair_dump_nr_dlschsim.vcd");
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
DS_TDL,
0, 0, 0, 0);
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model,
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
DS_TDL,
CORR_LEVEL_LOW,
0,
0,
0,
0);
if (gNB2UE == NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -901,11 +901,13 @@ int main(int argc, char **argv)
n_rx,
channel_model,
fs/1e6,//sampling frequency in MHz
txbw,
30e-9,
txbw,
30e-9,
CORR_LEVEL_LOW,
0,
0,
0, 0);
0,
0);
if (gNB2UE==NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -534,12 +534,14 @@ int main(int argc, char **argv)
gNB2UE = new_channel_desc_scm(n_tx,
n_rx,
channel_model,
fs,
bw,
300e-9,
fs,
bw,
300e-9,
CORR_LEVEL_LOW,
0,
0,
0, 0);
0,
0);
if (gNB2UE==NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -734,9 +734,11 @@ int main(int argc, char **argv){
fs,
bw,
DS_TDL,
CORR_LEVEL_LOW,
0.0,
delay,
0, 0);
0,
0);
if (UE2gNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -354,7 +354,7 @@ int main(int argc, char **argv)
printf("-b number of HARQ bits (1-2)\n");
printf("-B payload to be transmitted on PUCCH\n");
printf("-m initial cyclic shift m0\n");
printf("-T to check nacktoack miss for format 1");
printf("-T to check nacktoack miss for format 1\n");
exit (-1);
break;
}
......@@ -415,7 +415,7 @@ int main(int argc, char **argv)
&txbw,
&rxbw);
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, txbw, DS_TDL,0, 0, 0, 0);
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, txbw, DS_TDL, CORR_LEVEL_LOW, 0, 0, 0, 0);
if (UE2gNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -383,7 +383,11 @@ int main(int argc, char **argv)
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
DS_TDL,
0,0,0, 0);
CORR_LEVEL_LOW,
0,
0,
0,
0);
if (gNB2UE == NULL) {
printf("Problem generating channel model. Exiting.\n");
......
......@@ -291,6 +291,7 @@ int main(int argc, char **argv)
//int8_t interf1 = -21, interf2 = -21;
FILE *input_fd = NULL;
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
corr_level_t corr_level = CORR_LEVEL_LOW;
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
NB_UE_INST = 1;
......@@ -304,7 +305,6 @@ int main(int argc, char **argv)
int Imcs = 9;
uint8_t precod_nbr_layers = 1;
int gNB_id = 0;
int ap;
int tx_offset;
int32_t txlev_sum = 0, atxlev[4];
int start_rb = 0;
......@@ -398,61 +398,52 @@ int main(int argc, char **argv)
break;
case 'g':
switch ((char) *optarg) {
case 'A':
channel_model = SCM_A;
break;
case 'B':
channel_model = SCM_B;
break;
case 'C':
channel_model = SCM_C;
break;
case 'D':
channel_model = SCM_D;
break;
case 'E':
channel_model = EPA;
break;
case 'F':
channel_model = EVA;
break;
case 'G':
channel_model = ETU;
break;
case 'H':
channel_model = TDL_C;
DS_TDL = .030; // 30 ns
break;
case 'I':
channel_model = TDL_C;
DS_TDL = .3; // 300ns
break;
case 'J':
channel_model=TDL_D;
DS_TDL = .03;
break;
switch ((char) *optarg) {
case 'A':
channel_model = TDL_A;
DS_TDL = 0.030; // 30 ns
printf("Channel model: TDLA30\n");
break;
case 'B':
channel_model = TDL_B;
DS_TDL = 0.100; // 100ns
printf("Channel model: TDLB100\n");
break;
case 'C':
channel_model = TDL_C;
DS_TDL = 0.300; // 300 ns
printf("Channel model: TDLC300\n");
break;
default:
printf("Unsupported channel model!\n");
exit(-1);
}
default:
printf("Unsupported channel model!\n");
exit(-1);
if (optarg[1] == ',') {
switch (optarg[2]) {
case 'l':
corr_level = CORR_LEVEL_LOW;
break;
case 'm':
corr_level = CORR_LEVEL_MEDIUM;
break;
case 'h':
corr_level = CORR_LEVEL_HIGH;
break;
default:
printf("Invalid correlation level!\n");
}
}
break;
case 'i':
for(i=0; i < atoi(optarg); i++){
chest_type[i] = atoi(argv[optind++]);
}
i=0;
do {
chest_type[i>>1] = atoi(&optarg[i]);
i+=2;
} while (optarg[i-1] == ',');
break;
case 'k':
......@@ -514,7 +505,7 @@ int main(int argc, char **argv)
break;
case 't':
eff_tp_check = (float)atoi(optarg);
eff_tp_check = atof(optarg);
break;
/*
......@@ -597,16 +588,20 @@ int main(int argc, char **argv)
case 'T':
enable_ptrs=1;
for(i=0; i < atoi(optarg); i++){
ptrs_arg[i] = atoi(argv[optind++]);
}
i=0;
do {
ptrs_arg[i>>1] = atoi(&optarg[i]);
i+=2;
} while (optarg[i-1] == ',');
break;
case 'U':
modify_dmrs = 1;
for(i=0; i < atoi(optarg); i++){
dmrs_arg[i] = atoi(argv[optind++]);
}
i=0;
do {
dmrs_arg[i>>1] = atoi(&optarg[i]);
i+=2;
} while (optarg[i-1] == ',');
break;
case 'Q':
......@@ -626,11 +621,12 @@ int main(int argc, char **argv)
//printf("-d Use TDD\n");
printf("-d Introduce delay in terms of number of samples\n");
printf("-f Number of frames to simulate\n");
printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
printf("-g Channel model configuration. Arguments list: Number of arguments = 2, {Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300}, {Correlation: [l] Low, [m] Medium, [h] High}, e.g. -g A,l\n");
printf("-h This message\n");
printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 2 1 0\n");
printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 1,0\n");
//printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-m MCS value\n");
printf("-n Number of trials to simulate\n");
printf("-o ldpc offload flag\n");
......@@ -654,10 +650,9 @@ int main(int argc, char **argv)
printf("-O oversampling factor (1,2,4,8,16)\n");
printf("-R Maximum number of available resorce blocks (N_RB_DL)\n");
printf("-t Acceptable effective throughput (in percentage)\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-P Print ULSCH performances\n");
printf("-T Enable PTRS, arguments list: Number of arguments=2 L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
printf("-U Change DMRS Config, arguments list: Number of arguments=4, DMRS Mapping Type{0=A,1=B}, DMRS AddPos{0:3}, DMRS Config Type{1,2}, Number of CDM groups without data{1,2,3} e.g. -U 4 0 2 0 1 \n");
printf("-T Enable PTRS, arguments list: Number of arguments=2 L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 0,2 \n");
printf("-U Change DMRS Config, arguments list: Number of arguments=4, DMRS Mapping Type{0=A,1=B}, DMRS AddPos{0:3}, DMRS Config Type{1,2}, Number of CDM groups without data{1,2,3} e.g. -U 0,2,0,1 \n");
printf("-Q If -F used, read parameters from file\n");
printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
printf("-W Num of layer for PUSCH\n");
......@@ -690,12 +685,16 @@ int main(int argc, char **argv)
LOG_I( PHY,"++++++++++++++++++++++++++++++++++++++++++++++%i+++++++++++++++++++++++++++++++++++++++++",loglvl);
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
UE2gNB = new_channel_desc_scm(n_tx,
n_rx, channel_model,
sampling_frequency/1e6,
tx_bandwidth,
DS_TDL,
0, 0, 0, 0);
DS_TDL,
corr_level,
0,
0,
0,
0);
if (UE2gNB == NULL) {
printf("Problem generating channel model. Exiting.\n");
......@@ -1006,7 +1005,6 @@ int main(int argc, char **argv)
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
snrRun = 0;
int n_errs = 0;
int read_errors=0;
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
......@@ -1057,7 +1055,8 @@ int main(int argc, char **argv)
mod_order = nr_get_Qm_ul(Imcs, mcs_table);
code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
}
int ret = 1;
uint32_t errors_scrambling[4][100];
int n_errors[4][100];
int round_trials[4][100];
......@@ -1069,8 +1068,9 @@ int main(int argc, char **argv)
memset(round_trials, 0, sizeof(int)*4*100);
memset(blerStats, 0, sizeof(double)*4*100);
memset(berStats, 0, sizeof(double)*4*100);
memset(snrStats, 0, sizeof(double)*100);
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
memset(snrStats, 0, sizeof(double) * 100);
for (SNR = snr0; SNR <= snr1; SNR += snr_step) {
varArray_t *table_rx=initVarArray(1000,sizeof(double));
int error_flag = 0;
n_false_positive = 0;
......@@ -1313,42 +1313,12 @@ int main(int argc, char **argv)
}
}
// The multipath_channel() function calculates a channel matrix with only 1's. So the channel rank is 1, and we
// cannot use multi-layer. To solve this issue, for now we use the H_awgn_mimo matrix for multi-layer.
if (precod_nbr_layers == 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);
}
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 {
double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
{0.2, 1.0, 0.2, 0.1}, //rx 1
{0.1, 0.2, 1.0, 0.2}, //rx 2
{0.05, 0.1, 0.2, 1.0}}; //rx 3
for (i=0; i<slot_length; i++) {
for (ap = 0; ap < frame_parms->nb_antennas_rx; ap++) {
// sum up signals from different Tx antennas
r_re[ap][i] = 0;
r_im[ap][i] = 0;
for (int aa=0; aa<n_tx; aa++) {
r_re[ap][i] += s_re[aa][i]*H_awgn_mimo[ap][aa];
r_im[ap][i] += s_im[aa][i]*H_awgn_mimo[ap][aa];
}
}
}
}
for (i=0; i<slot_length; i++) {
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
rxdata[ap][slot_offset+i+delay].r = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
rxdata[ap][slot_offset+i+delay].i = (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, &rxdata[ap][slot_offset].r, &rxdata[ap][slot_offset].i);
}
}
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
}
add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, frame_parms->nb_antennas_rx);
} /*End input_fd */
......@@ -1633,12 +1603,12 @@ int main(int argc, char **argv)
printf("*************\n");
printf("PUSCH test OK\n");
printf("*************\n");
ret = 0;
break;
}
snrStats[snrRun] = SNR;
snrRun++;
n_errs = n_errors[0][snrRun];
} // SNR loop
printf("\n");
......@@ -1687,5 +1657,5 @@ int main(int argc, char **argv)
if (scg_fd)
fclose(scg_fd);
return (n_errs);
return ret;
}
......@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "nfapi_nr_interface_scf.h"
#include "PHY/TOOLS/tools_defs.h"
#include "SIMULATION/RF/rf.h"
#include "sim.h"
......@@ -31,7 +32,6 @@
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
{
random_channel(desc,0);
return(1);
}
......@@ -145,6 +145,31 @@ void multipath_channel(channel_desc_t *desc,
}
#else
void add_noise(c16_t **rxdata,
const double **r_re,
const double **r_im,
const double sigma,
const int length,
const int slot_offset,
const double ts,
const int delay,
const uint16_t pdu_bit_map,
const uint8_t nb_antennas_rx)
{
for (int i = 0; i < length; i++) {
for (int ap = 0; ap < nb_antennas_rx; ap++) {
c16_t *rxd = &rxdata[ap][slot_offset + i + delay];
rxd->r = r_re[ap][i] + sqrt(sigma / 2) * gaussdouble(0.0, 1.0); // convert to fixed point
rxd->i = 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, &rxdata[ap][slot_offset + i + delay].r, &rxdata[ap][slot_offset + i + delay].i);
}
}
}
}
void multipath_channel(channel_desc_t *desc,
double *tx_sig_re[NB_ANTENNAS_TX],
double *tx_sig_im[NB_ANTENNAS_TX],
......@@ -163,7 +188,8 @@ void multipath_channel(channel_desc_t *desc,
dd = abs(desc->channel_offset);
#ifdef DEBUG_CH
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",
keep_channel, path_loss, desc->path_loss_dB, desc->nb_rx, desc->nb_tx, dd, desc->channel_length);
#endif
if (keep_channel) {
......@@ -173,12 +199,9 @@ void multipath_channel(channel_desc_t *desc,
}
#ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
printf("ch[%i] = (%f, %f)\n", l, desc->ch[0][l].r, desc->ch[0][l].i);
}
printf("\n");
#endif
for (i=0; i<((int)length-dd); i++) {
......@@ -200,7 +223,8 @@ void multipath_channel(channel_desc_t *desc,
rx_tmp.i += (tx.i * desc->ch[ii+(j*desc->nb_rx)][l].r) + (tx.r * desc->ch[ii+(j*desc->nb_rx)][l].i);
if (i==0 && log_channel == 1) {
printf("channel[%d][%d][%d] = %f dB (%e,%e)\n",ii,j,l,10*log10(pow(desc->ch[ii+(j*desc->nb_rx)][l].r,2.0)+pow(desc->ch[ii+(j*desc->nb_rx)][l].i,2.0)),
printf("channel[%d][%d][%d] = %f dB \t(%e, %e)\n",
ii, j, l, 10*log10(pow(desc->ch[ii+(j*desc->nb_rx)][l].r,2.0)+pow(desc->ch[ii+(j*desc->nb_rx)][l].i,2.0)),
desc->ch[ii+(j*desc->nb_rx)][l].r,
desc->ch[ii+(j*desc->nb_rx)][l].i);
}
......@@ -209,9 +233,10 @@ void multipath_channel(channel_desc_t *desc,
rx_sig_re[ii][i+dd] = rx_tmp.r*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.i*path_loss;
#ifdef DEBUG_CHANNEL
#ifdef DEBUG_CH
if ((i%32)==0) {
printf("rx aa %d: %p %p %f,%f => %e,%e\n",ii,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("rx aa %d: %f, %f => %e, %e\n",
ii, rx_tmp.r, rx_tmp.i, rx_sig_re[ii][i-dd], rx_sig_im[ii][i-dd]);
}
#endif
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
......
......@@ -36,6 +36,7 @@
//#define DEBUG_CH
//#define DEBUG_CH_POWER
#include "assertions.h"
......@@ -183,156 +184,17 @@ static double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.
static 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};
static 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};
static 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
};
static 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
};
static 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
};
// TS 38.104 - Table G.2.1.1-2, delays normalized based on TR 38.901 - eq. 7.7-1
static double tdl_a_delays[] = {0, 0.3333, 0.5000, 0.6667, 0.8333, 1.6667, 2.1667, 2.5000, 3.5000, 4.5000, 5.0000, 9.6667};
static double tdl_a_amps_dB[] = {-15.5, 0.0, -5.1, -5.1, -9.6, -8.2, -13.1, -11.5, -11.0, -16.2, -16.6, -26.2};
static 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
};
static 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
};
// TS 38.104 - Table G.2.1.1-3, delays normalized based on TR 38.901 - eq. 7.7-1
static double tdl_b_delays[] = {0.0000, 0.1000, 0.2000, 0.3000, 0.3500, 0.4500, 0.5500, 1.2000, 1.7000, 2.4500, 3.3000, 4.8000};
static double tdl_b_amps_dB[] = {0.0, -2.2, -0.6, -0.6, -0.3, -1.2, -5.9, -2.2, -0.8, -6.3, -7.5, -7.1};
static 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
};
// TS 38.104 - Table G.2.1.1-4, delays normalized based on TR 38.901 - eq. 7.7-1
static double tdl_c_delays[] = {0.0000, 0.2167, 0.2333, 0.6333, 0.6500, 0.6667, 0.8000, 1.0833, 1.7333, 3.4833, 5.0333, 8.6500};
static double tdl_c_amps_dB[] = {-6.9, 0.0, -7.7, -2.5, -2.4, -9.9, -8.0, -6.6, -7.1, -13.0, -14.2, -16.0};
static double tdl_d_delays[] = {//0,
0,
......@@ -514,6 +376,7 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
chan_desc->ch = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
chan_desc->chF = (struct complexd **) malloc(nb_tx*nb_rx*sizeof(struct complexd *));
chan_desc->a = (struct complexd **) malloc(chan_desc->nb_taps*sizeof(struct complexd *));
chan_desc->ricean_factor = 1.0;
for (int i = 0; i<nb_tx*nb_rx; i++)
chan_desc->ch[i] = (struct complexd *) malloc(chan_desc->channel_length * sizeof(struct complexd));
......@@ -524,41 +387,146 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS
for (int i = 0; i<chan_desc->nb_taps; i++)
chan_desc->a[i] = (struct complexd *) malloc(nb_tx*nb_rx * sizeof(struct complexd));
chan_desc->R_sqrt = (struct complexd **) malloc(tdl_pathsby3*sizeof(struct complexd **));
if (nb_tx==2 && nb_rx==2) {
for (int i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complexd *) &R22_sqrt[i][0];
} else if (nb_tx==2 && nb_rx==1) {
for (int i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complexd *) &R21_sqrt[i][0];
} else if (nb_tx==1 && nb_rx==2) {
for (int i = 0; i<(tdl_pathsby3); i++)
chan_desc->R_sqrt[i] = (struct complexd *) &R12_sqrt[i][0];
int matrix_size = nb_tx*nb_rx;
double *correlation_matrix[matrix_size];
if (chan_desc->corr_level!=CORR_LEVEL_LOW) {
if (nb_rx==1 && nb_tx==2) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R12_medium_high[row];
}
} else if (nb_rx==1 && nb_tx==4) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R14_medium_high[row];
}
} else if (nb_rx==1 && nb_tx==8) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R18_medium_high[row];
}
} else if (nb_rx==2 && nb_tx==2 && chan_desc->corr_level==CORR_LEVEL_MEDIUM) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R22_medium[row];
}
} else if (nb_rx==2 && nb_tx==4 && chan_desc->corr_level==CORR_LEVEL_MEDIUM) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R24_medium[row];
}
} else if (nb_rx==4 && nb_tx==4 && chan_desc->corr_level==CORR_LEVEL_MEDIUM) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R44_medium[row];
}
} else if (nb_rx==2 && nb_tx==2 && chan_desc->corr_level==CORR_LEVEL_HIGH) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R22_high[row];
}
} else if (nb_rx==2 && nb_tx==4 && chan_desc->corr_level==CORR_LEVEL_HIGH) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R24_high[row];
}
} else if (nb_rx==4 && nb_tx==4 && chan_desc->corr_level==CORR_LEVEL_HIGH) {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = R44_high[row];
}
} else {
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = NULL;
}
}
} else {
for (int i = 0; i<(tdl_pathsby3); i++) {
chan_desc->R_sqrt[i] = (struct complexd *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complexd));
for (int row = 0; row < matrix_size; row++) {
correlation_matrix[row] = NULL;
}
}
for (int j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].r = 1.0;
chan_desc->R_sqrt[i][j].i = 0.0;
chan_desc->R_sqrt = (struct complexd **) malloc(matrix_size*sizeof(struct complexd **));
for (int row = 0; row < matrix_size; row++) {
chan_desc->R_sqrt[row] = (struct complexd *) calloc(1, matrix_size*sizeof(struct complexd));
if (correlation_matrix[row] == NULL) {
// TS 38.104 - Table G.2.3.1.2-4: MIMO correlation matrices for low correlation
chan_desc->R_sqrt[row][row].r = 1.0;
} else {
for (int col = 0; col < matrix_size; col++) {
chan_desc->R_sqrt[row][col].r = correlation_matrix[row][col];
}
LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
}
}
}
double get_normalization_ch_factor(channel_desc_t *desc)
{
if (!(desc->channel_length > 1 && desc->modelid >= TDL_A && desc->modelid <= TDL_E)) {
return 1.0;
}
uint16_t N_average = 1000;
double accumulated_ch_power = 0;
struct complexd a[desc->nb_taps][desc->nb_tx * desc->nb_rx];
struct complexd anew[desc->nb_tx * desc->nb_rx];
struct complexd acorr[desc->nb_tx * desc->nb_rx];
for (int n = 1; n <= N_average; n++) {
for (int l = 0; l < (int)desc->nb_taps; l++) {
for (int aarx = 0; aarx < desc->nb_rx; aarx++) {
for (int aatx = 0; aatx < desc->nb_tx; aatx++) {
anew[aarx + (aatx * desc->nb_rx)].r = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussdouble(0.0, 1.0);
anew[aarx + (aatx * desc->nb_rx)].i = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussdouble(0.0, 1.0);
if ((l == 0) && (desc->ricean_factor != 1.0)) {
anew[aarx + (aatx * desc->nb_rx)].r += sqrt((1.0 - desc->ricean_factor) / 2);
anew[aarx + (aatx * desc->nb_rx)].i += sqrt((1.0 - desc->ricean_factor) / 2);
}
} // for (int aatx = 0; aatx < desc->nb_tx; aatx++)
} // for (int aarx = 0; aarx < desc->nb_rx; aarx++)
// Apply correlation matrix
bzero(acorr, desc->nb_tx * desc->nb_rx * sizeof(struct complexd));
for (int aatx = 0; aatx < desc->nb_tx; aatx++) {
for (int aarx = 0; aarx < desc->nb_rx; aarx++) {
cblas_zaxpy(desc->nb_tx * desc->nb_rx,
(void *)&anew[aarx + (aatx * desc->nb_rx)],
(void *)desc->R_sqrt[aarx + (aatx * desc->nb_rx)],
1,
(void *)acorr,
1);
} // for (int aarx = 0; aarx < desc->nb_rx; aarx++)
} // for (int aatx = 0; aatx < desc->nb_tx; aatx++)
cblas_zcopy(desc->nb_tx * desc->nb_rx, (void *)acorr, 1, (void *)a[l], 1);
} // for (int l = 0; l < (int)desc->nb_taps; l++)
for (int aarx = 0; aarx < desc->nb_rx; aarx++) {
for (int aatx = 0; aatx < desc->nb_tx; aatx++) {
for (int k = 0; k < (int)desc->channel_length; k++) {
double ch_r = 0.0;
double ch_i = 0.0;
double s = 0.0;
for (int l = 0; l < desc->nb_taps; l++) {
if ((k - (desc->delays[l] * desc->sampling_rate) - desc->channel_offset) == 0) {
s = 1.0;
} else {
s = sin(M_PI * (k - (desc->delays[l] * desc->sampling_rate) - desc->channel_offset)) /
(M_PI * (k - (desc->delays[l] * desc->sampling_rate) - desc->channel_offset));
}
ch_r += s * a[l][aarx + (aatx * desc->nb_rx)].r;
ch_i += s * a[l][aarx + (aatx * desc->nb_rx)].i;
} // for (int l = 0; l < desc->nb_taps; l++)
accumulated_ch_power += (ch_r * ch_r + ch_i * ch_i);
} // for (int k = 0; k < (int)desc->channel_length; k++)
} // for (int aatx = 0; aatx < desc->nb_tx; aatx++)
} // for (int aarx = 0; aarx < desc->nb_rx; aarx++)
}
return sqrt((N_average * desc->nb_tx * desc->nb_rx) / accumulated_ch_power);
}
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
double channel_bandwidth,
double DS_TDL,
const corr_level_t corr_level,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB,
float noise_power_dB) {
float noise_power_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
for(int i=0; i<max_chan; i++) {
......@@ -577,17 +545,19 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps;
struct complexd *R_sqrt_ptr2;
chan_desc->modelid = channel_model;
chan_desc->modelid = channel_model;
chan_desc->nb_tx = nb_tx;
chan_desc->nb_rx = nb_rx;
chan_desc->sampling_rate = sampling_rate;
chan_desc->channel_bandwidth = channel_bandwidth;
chan_desc->corr_level = corr_level;
chan_desc->forgetting_factor = forgetting_factor;
chan_desc->channel_offset = channel_offset;
chan_desc->path_loss_dB = path_loss_dB;
chan_desc->first_run = 1;
chan_desc->ip = 0.0;
chan_desc->ip = 0.0;
chan_desc->noise_power_dB = noise_power_dB;
chan_desc->normalization_ch_factor = 1.0;
LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
int tdl_paths=0;
double *tdl_amps_dB;
......@@ -1637,6 +1607,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
return(NULL);
}
chan_desc->normalization_ch_factor = get_normalization_ch_factor(chan_desc);
LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor);
for (i=0; i<chan_desc->nb_taps; i++)
......@@ -1705,6 +1677,11 @@ void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) {
cdesc->model_name=strdup(modelname);
}
#ifdef DEBUG_CH_POWER
double accumulated_ch_power = 0;
int ch_power_count = 0;
#endif
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
double s;
int i,k,l,aarx,aatx;
......@@ -1713,11 +1690,30 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
struct complexd phase, alpha, beta;
start_meas(&desc->random_channel);
// For AWGN channel, the received signal (Srx) is equal to transmitted signal (Stx) plus noise (N), i.e., Srx = Stx + N,
// therefore, the channel matrix is the identity matrix.
if (desc->modelid == AWGN) {
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx = 0; aatx < desc->nb_tx; aatx++) {
desc->ch[aarx+(aatx*desc->nb_rx)][0].r = aarx%desc->nb_tx == aatx ? 1.0 : 0.0;
desc->ch[aarx+(aatx*desc->nb_rx)][0].i = 0.0;
acorr[aarx+(aatx*desc->nb_rx)].r = desc->ch[aarx+(aatx*desc->nb_rx)][0].r;
acorr[aarx+(aatx*desc->nb_rx)].i = desc->ch[aarx+(aatx*desc->nb_rx)][0].i;
}
}
cblas_zcopy(desc->nb_tx*desc->nb_rx, (void *) acorr, 1, (void *) desc->a[0], 1);
stop_meas(&desc->random_channel);
desc->first_run = 0;
return 0;
}
bzero(acorr,desc->nb_tx*desc->nb_rx*sizeof(struct complexd));
for (i=0; i<(int)desc->nb_taps; i++) {
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx=0; aatx<desc->nb_tx; aatx++) {
anew[aarx+(aatx*desc->nb_rx)].r = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0);
anew[aarx+(aatx*desc->nb_rx)].i = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0);
anew[aarx + (aatx * desc->nb_rx)].r = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussdouble(0.0, 1.0) * desc->normalization_ch_factor;
anew[aarx + (aatx * desc->nb_rx)].i = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussdouble(0.0, 1.0) * desc->normalization_ch_factor;
if ((i==0) && (desc->ricean_factor != 1.0)) {
if (desc->random_aoa==1) {
......@@ -1727,10 +1723,10 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
// this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing.
// Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so
// that we can safely assume plane wave propagation.
phase.r = cos(M_PI*((aarx-aatx)*sin(desc->aoa)));
phase.i = sin(M_PI*((aarx-aatx)*sin(desc->aoa)));
anew[aarx+(aatx*desc->nb_rx)].r += phase.r * sqrt(1.0-desc->ricean_factor);
anew[aarx+(aatx*desc->nb_rx)].i += phase.i * sqrt(1.0-desc->ricean_factor);
phase.r = cos(M_PI * ((aarx - aatx) * sin(desc->aoa)));
phase.i = sin(M_PI * ((aarx - aatx) * sin(desc->aoa)));
anew[aarx + (aatx * desc->nb_rx)].r += phase.r * sqrt(1.0 - desc->ricean_factor) * desc->normalization_ch_factor;
anew[aarx + (aatx * desc->nb_rx)].i += phase.i * sqrt(1.0 - desc->ricean_factor) * desc->normalization_ch_factor;
}
#ifdef DEBUG_CH
......@@ -1751,8 +1747,21 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
*/
//apply correlation matrix
//compute acorr = R_sqrt[i] * anew
bzero(acorr,desc->nb_tx*desc->nb_rx*sizeof(struct complexd));
cblas_zaxpy(desc->nb_tx*desc->nb_rx, (void *) desc->R_sqrt[i/3], (void *) anew, 1, (void *) acorr, 1);
bzero(acorr, desc->nb_tx * desc->nb_rx * sizeof(struct complexd));
if (desc->modelid >= TDL_A && desc->modelid <= TDL_E) {
for (aatx = 0; aatx < desc->nb_tx; aatx++) {
for (aarx=0; aarx<desc->nb_rx; aarx++) {
cblas_zaxpy(desc->nb_tx*desc->nb_rx,
(void *) &anew[aarx+(aatx*desc->nb_rx)],
(void *) desc->R_sqrt[aarx+(aatx*desc->nb_rx)],
1,
(void *) acorr,
1);
}
}
} else {
cblas_zaxpy(desc->nb_tx*desc->nb_rx, (void *) desc->R_sqrt[i/3], (void *) anew, 1, (void *) acorr, 1);
}
/*
FIXME: Function cblas_zgemv has an undefined output (for the same input) after a second call in RHEL8 (acorr = nan)
......@@ -1831,14 +1840,26 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
// printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
} //nb_taps
#ifdef DEBUG_CH_POWER
accumulated_ch_power += (desc->ch[aarx + (aatx * desc->nb_rx)][k].r * desc->ch[aarx + (aatx * desc->nb_rx)][k].r +
desc->ch[aarx + (aatx * desc->nb_rx)][k].i * desc->ch[aarx + (aatx * desc->nb_rx)][k].i);
#endif
#ifdef DEBUG_CH
printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].r,desc->ch[aarx+(aatx*desc->nb_rx)][k].i);
#endif
} //channel_length
#ifdef DEBUG_CH_POWER
ch_power_count++;
#endif
}
} //aatx
} //aarx
#ifdef DEBUG_CH_POWER
printf("(%5i) Average channel power = %f\n", ch_power_count, accumulated_ch_power / ch_power_count);
#endif
stop_meas(&desc->interp_time);
}
......@@ -2090,10 +2111,17 @@ int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double
AssertFatal(0, "\n Choose a valid model type\n");
}
channel_desc_t *channeldesc_p = new_channel_desc_scm(nb_tx,nb_rx,modid,sampling_rate,channel_bandwidth,
*(channel_list.paramarray[i][pindex_DT].dblptr), *(channel_list.paramarray[i][pindex_FF].dblptr),
*(channel_list.paramarray[i][pindex_CO].iptr), *(channel_list.paramarray[i][pindex_PL].dblptr),
*(channel_list.paramarray[i][pindex_NP].dblptr) );
channel_desc_t *channeldesc_p = new_channel_desc_scm(nb_tx,
nb_rx,
modid,
sampling_rate,
channel_bandwidth,
*(channel_list.paramarray[i][pindex_DT].dblptr),
CORR_LEVEL_LOW,
*(channel_list.paramarray[i][pindex_FF].dblptr),
*(channel_list.paramarray[i][pindex_CO].iptr),
*(channel_list.paramarray[i][pindex_PL].dblptr),
*(channel_list.paramarray[i][pindex_NP].dblptr));
AssertFatal( (channeldesc_p!= NULL), "Could not allocate channel %s type %s \n",*(channel_list.paramarray[i][pindex_NAME].strptr), *(channel_list.paramarray[i][pindex_TYPE].strptr));
channeldesc_p->model_name = strdup(*(channel_list.paramarray[i][pindex_NAME].strptr));
LOG_I(OCM,"Model %s type %s allocated from config file, list %s\n",*(channel_list.paramarray[i][pindex_NAME].strptr),
......
......@@ -43,3 +43,97 @@ static double R12_sqrt[6][8] = {
{0.991912, 0.000000,0.041738, -0.119870,0.041738, 0.119870,0.991912, 0.000000},
{0.968169, 0.000000,0.216594, -0.125443,0.216594, 0.125443,0.968169, 0.000000},
};
// TS 38.104 - Table G.2.3.1.2-2: MIMO correlation matrices for high correlation
static double R22_high[4][4] = {
{1.0, 0.9, 0.9, 0.81},
{0.9, 1.0, 0.81, 0.9},
{0.9, 0.81, 1.0, 0.9},
{0.81, 0.9, 0.9, 1}
};
static double R24_high[8][8] = {
{1.0000, 0.9883, 0.9542, 0.8999, 0.8999, 0.8894, 0.8587, 0.8099},
{0.9883, 1.0000, 0.9883, 0.9542, 0.8894, 0.8999, 0.8894, 0.8587},
{0.9542, 0.9883, 1.0000, 0.9883, 0.8587, 0.8894, 0.8999, 0.8894},
{0.8999, 0.9542, 0.9883, 1.0000, 0.8099, 0.8587, 0.8894, 0.8999},
{0.8999, 0.8894, 0.8587, 0.8099, 1.0000, 0.9883, 0.9542, 0.8999},
{0.8894, 0.8999, 0.8894, 0.8587, 0.9883, 1.0000, 0.9883, 0.9542},
{0.8587, 0.8894, 0.8999, 0.8894, 0.9542, 0.9883, 1.0000, 0.9883},
{0.8099, 0.8587, 0.8894, 0.8999, 0.8999, 0.9542, 0.9883, 1.0000}
};
static double R44_high[16][16] = {
{1.0000, 0.9882, 0.9541, 0.8999, 0.9882, 0.9767, 0.9430, 0.8894, 0.9541, 0.9430, 0.9105, 0.8587, 0.8999, 0.8894, 0.8587, 0.8099},
{0.9882, 1.0000, 0.9882, 0.9541, 0.9767, 0.9882, 0.9767, 0.9430, 0.9430, 0.9541, 0.9430, 0.9105, 0.8894, 0.8999, 0.8894, 0.8587},
{0.9541, 0.9882, 1.0000, 0.9882, 0.9430, 0.9767, 0.9882, 0.9767, 0.9105, 0.9430, 0.9541, 0.9430, 0.8587, 0.8894, 0.8999, 0.8894},
{0.8999, 0.9541, 0.9882, 1.0000, 0.8894, 0.9430, 0.9767, 0.9882, 0.8587, 0.9105, 0.9430, 0.9541, 0.8099, 0.8587, 0.8894, 0.8999},
{0.9882, 0.9767, 0.9430, 0.8894, 1.0000, 0.9882, 0.9541, 0.8999, 0.9882, 0.9767, 0.9430, 0.8894, 0.9541, 0.9430, 0.9105, 0.8587},
{0.9767, 0.9882, 0.9767, 0.9430, 0.9882, 1.0000, 0.9882, 0.9541, 0.9767, 0.9882, 0.9767, 0.9430, 0.9430, 0.9541, 0.9430, 0.9105},
{0.9430, 0.9767, 0.9882, 0.9767, 0.9541, 0.9882, 1.0000, 0.9882, 0.9430, 0.9767, 0.9882, 0.9767, 0.9105, 0.9430, 0.9541, 0.9430},
{0.8894, 0.9430, 0.9767, 0.9882, 0.8999, 0.9541, 0.9882, 1.0000, 0.8894, 0.9430, 0.9767, 0.9882, 0.8587, 0.9105, 0.9430, 0.9541},
{0.9541, 0.9430, 0.9105, 0.8587, 0.9882, 0.9767, 0.9430, 0.8894, 1.0000, 0.9882, 0.9541, 0.8999, 0.9882, 0.9767, 0.9430, 0.8894},
{0.9430, 0.9541, 0.9430, 0.9105, 0.9767, 0.9882, 0.9767, 0.9430, 0.9882, 1.0000, 0.9882, 0.9541, 0.9767, 0.9882, 0.9767, 0.9430},
{0.9105, 0.9430, 0.9541, 0.9430, 0.9430, 0.9767, 0.9882, 0.9767, 0.9541, 0.9882, 1.0000, 0.9882, 0.9430, 0.9767, 0.9882, 0.9767},
{0.8587, 0.9105, 0.9430, 0.9541, 0.8894, 0.9430, 0.9767, 0.9882, 0.8999, 0.9541, 0.9882, 1.0000, 0.8894, 0.9430, 0.9767, 0.9882},
{0.8999, 0.8894, 0.8587, 0.8099, 0.9541, 0.9430, 0.9105, 0.8587, 0.9882, 0.9767, 0.9430, 0.8894, 1.0000, 0.9882, 0.9541, 0.8999},
{0.8894, 0.8999, 0.8894, 0.8587, 0.9430, 0.9541, 0.9430, 0.9105, 0.9767, 0.9882, 0.9767, 0.9430, 0.9882, 1.0000, 0.9882, 0.9541},
{0.8587, 0.8894, 0.8999, 0.8894, 0.9105, 0.9430, 0.9541, 0.9430, 0.9430, 0.9767, 0.9882, 0.9767, 0.9541, 0.9882, 1.0000, 0.9882},
{0.8099, 0.8587, 0.8894, 0.8999, 0.8587, 0.9105, 0.9430, 0.9541, 0.8894, 0.9430, 0.9767, 0.9882, 0.8999, 0.9541, 0.9882, 1.0000}
};
// TS 38.104 - Table G.2.3.1.2-3: MIMO correlation matrices for medium correlation
static double R22_medium[4][4] = {
{1.0000, 0.9000, 0.3000, 0.2700},
{0.9000, 1.0000, 0.2700, 0.3000},
{0.3000, 0.2700, 1.0000, 0.9000},
{0.2700, 0.3000, 0.9000, 1.0000}
};
static double R24_medium[8][8] = {
{1.0000, 0.9884, 0.9543, 0.9000, 0.3000, 0.2965, 0.2863, 0.2700},
{0.9884, 1.0000, 0.9884, 0.9543, 0.2965, 0.3000, 0.2965, 0.2863},
{0.9543, 0.9884, 1.0000, 0.9884, 0.2863, 0.2965, 0.3000, 0.2965},
{0.9000, 0.9543, 0.9884, 1.0000, 0.2700, 0.2863, 0.2965, 0.3000},
{0.3000, 0.2965, 0.2863, 0.2700, 1.0000, 0.9884, 0.9543, 0.9000},
{0.2965, 0.3000, 0.2965, 0.2863, 0.9884, 1.0000, 0.9884, 0.9543},
{0.2863, 0.2965, 0.3000, 0.2965, 0.9543, 0.9884, 1.0000, 0.9884},
{0.2700, 0.2863, 0.2965, 0.3000, 0.9000, 0.9543, 0.9884, 1.0000}
};
static double R44_medium[16][16] = {
{1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872, 0.5855, 0.5787, 0.5588, 0.5270, 0.3000, 0.2965, 0.2862, 0.2700},
{0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347, 0.5787, 0.5855, 0.5787, 0.5588, 0.2965, 0.3000, 0.2965, 0.2862},
{0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645, 0.5588, 0.5787, 0.5855, 0.5787, 0.2862, 0.2965, 0.3000, 0.2965},
{0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747, 0.5270, 0.5588, 0.5787, 0.5855, 0.2700, 0.2862, 0.2965, 0.3000},
{0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872, 0.5855, 0.5787, 0.5588, 0.5270},
{0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347, 0.5787, 0.5855, 0.5787, 0.5588},
{0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645, 0.5588, 0.5787, 0.5855, 0.5787},
{0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747, 0.5270, 0.5588, 0.5787, 0.5855},
{0.5855, 0.5787, 0.5588, 0.5270, 0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999, 0.8747, 0.8645, 0.8347, 0.7872},
{0.5787, 0.5855, 0.5787, 0.5588, 0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541, 0.8645, 0.8747, 0.8645, 0.8347},
{0.5588, 0.5787, 0.5855, 0.5787, 0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882, 0.8347, 0.8645, 0.8747, 0.8645},
{0.5270, 0.5588, 0.5787, 0.5855, 0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000, 0.7872, 0.8347, 0.8645, 0.8747},
{0.3000, 0.2965, 0.2862, 0.2700, 0.5855, 0.5787, 0.5588, 0.5270, 0.8747, 0.8645, 0.8347, 0.7872, 1.0000, 0.9882, 0.9541, 0.8999},
{0.2965, 0.3000, 0.2965, 0.2862, 0.5787, 0.5855, 0.5787, 0.5588, 0.8645, 0.8747, 0.8645, 0.8347, 0.9882, 1.0000, 0.9882, 0.9541},
{0.2862, 0.2965, 0.3000, 0.2965, 0.5588, 0.5787, 0.5855, 0.5787, 0.8347, 0.8645, 0.8747, 0.8645, 0.9541, 0.9882, 1.0000, 0.9882},
{0.2700, 0.2862, 0.2965, 0.3000, 0.5270, 0.5588, 0.5787, 0.5855, 0.7872, 0.8347, 0.8645, 0.8747, 0.8999, 0.9541, 0.9882, 1.0000}
};
// Matrices computed based on TS 38.104 - Tables G.2.3.1.1-3 and G.2.3.1.2-1
static double R12_medium_high[2][2] = {
{1.0, 0.9},
{0.9, 1.0}
};
static double R14_medium_high[4][4] = {
{1.000000, 0.988362, 0.954253, 0.900000},
{0.988362, 1.000000, 0.988362, 0.954253},
{0.954253, 0.988362, 1.000000, 0.988362},
{0.900000, 0.954253, 0.988362, 1.000000},
};
static double R18_medium_high[8][8] = {
{1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664, 0.925512, 0.900000},
{0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664, 0.925512},
{0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182, 0.947664},
{0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834, 0.966182},
{0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436, 0.980834},
{0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852, 0.991436},
{0.925512, 0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000, 0.997852},
{0.900000, 0.925512, 0.947664, 0.966182, 0.980834, 0.991436, 0.997852, 1.000000}
};
\ No newline at end of file
......@@ -50,6 +50,13 @@ typedef enum {
#define CHANMODEL_FREE_RSQRT_6 1<<1
#define CHANMODEL_FREE_RSQRT_NTAPS 1<<2
#define CHANMODEL_FREE_AMPS 1<<3
typedef enum {
CORR_LEVEL_LOW,
CORR_LEVEL_MEDIUM,
CORR_LEVEL_HIGH
} corr_level_t;
typedef struct {
///Number of tx antennas
uint8_t nb_tx;
......@@ -59,6 +66,8 @@ typedef struct {
uint8_t nb_taps;
///linear amplitudes of taps
double *amps;
///normalization channel factor
double normalization_ch_factor;
///Delays of the taps in mus. length(delays)=nb_taps. Has to be between 0 and Td.
double *delays;
///length of impulse response. should be set to 11+2*bw*t_max
......@@ -75,8 +84,10 @@ typedef struct {
double channel_bandwidth;
///System sampling rate in Msps.
double sampling_rate;
///Ricean factor of first tap wrt other taps (0..1, where 0 means AWGN and 1 means Rayleigh channel).
///Ricean factor, sqrt(1/(K+1)), of first tap wrt other taps (0..1, where 0 means AWGN and 1 means Rayleigh channel).
double ricean_factor;
///Correlation level of correlation channel matrix
corr_level_t corr_level;
///Angle of arrival of wavefront (in radians). For Ricean channel only. This assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so that we can safely assume plane wave propagation.
double aoa;
///If set to 1, aoa is randomized according to a uniform random distribution
......@@ -303,13 +314,14 @@ typedef struct {
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
double sampling_rate,
double channel_bandwidth,
double TDL_DS,
double DS_TDL,
const corr_level_t corr_level,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB,
float noise_power_dB);
float noise_power_dB);
channel_desc_t *find_channel_desc_fromname( char *modelname );
......@@ -338,6 +350,30 @@ void set_channeldesc_name(channel_desc_t *cdesc,char *modelname);
*/
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
/**
\brief Add AWGN noise and phase noise if enabled
\param rxdata output data with noise
\param r_re real part of input data without noise
\param r_im imaginary part of input data without noise
\param sigma noise power
\param length number of samples to apply the noise
\param slot_offset slot offset to start applying the noise
\param ts sampling time
\param delay introduce delay in terms of number of samples
\param pdu_bit_map bitmap indicating presence of optional PDUs
\param nb_antennas_rx number of receive antennas
*/
void add_noise(c16_t **rxdata,
const double **r_re,
const double **r_im,
const double sigma,
const int length,
const int slot_offset,
const double ts,
const int delay,
const uint16_t pdu_bit_map,
const uint8_t nb_antennas_rx);
/**\fn void multipath_channel(channel_desc_t *desc,
double tx_sig_re[NB_ANTENNAS_TX],
double tx_sig_im[NB_ANTENANS_TX],
......
......@@ -343,15 +343,15 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name,modelname)==0)) {
channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
channelmod,
t->sample_rate,
t->tx_bw,
30e-9, // TDL delay-spread parameter
t->chan_forgetfact, // forgetting_factor
t->chan_offset, // maybe used for TA
t->chan_pathloss,
t->noise_power_dB
); // path_loss in dB
channelmod,
t->sample_rate,
t->tx_bw,
30e-9, // TDL delay-spread parameter
CORR_LEVEL_LOW,
t->chan_forgetfact, // forgetting_factor
t->chan_offset, // maybe used for TA
t->chan_pathloss,
t->noise_power_dB); // path_loss in dB
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
set_channeldesc_name(newmodel,modelname);
random_channel(newmodel,false);
......
......@@ -352,31 +352,33 @@ void init_ocm(void) {
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
LOG_I(PHY,"Initializing channel descriptors (RU %d, UE %d) for N_RB_DL %d\n",ru_id,UE_id,
RC.ru[ru_id]->frame_parms->N_RB_DL);
sim.RU2UE[ru_id][UE_id][CC_id] =
new_channel_desc_scm(RC.ru[ru_id]->nb_tx,
PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_rx,
AWGN,
N_RB2sampling_rate(RC.ru[ru_id]->frame_parms->N_RB_DL),
N_RB2channel_bandwidth(RC.ru[ru_id]->frame_parms->N_RB_DL),
DS_TDL,
0.0,
0,
0,
0);
sim.RU2UE[ru_id][UE_id][CC_id] =
new_channel_desc_scm(RC.ru[ru_id]->nb_tx,
PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_rx,
AWGN,
N_RB2sampling_rate(RC.ru[ru_id]->frame_parms->N_RB_DL),
N_RB2channel_bandwidth(RC.ru[ru_id]->frame_parms->N_RB_DL),
DS_TDL,
CORR_LEVEL_LOW,
0.0,
0,
0,
0);
random_channel(sim.RU2UE[ru_id][UE_id][CC_id],0);
LOG_D(OCM,"[SIM] Initializing channel (%s) from UE %d to ru %d\n", "AWGN", UE_id, ru_id);
sim.UE2RU[UE_id][ru_id][CC_id] =
new_channel_desc_scm(PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_tx,
RC.ru[ru_id]->nb_rx,
AWGN,
N_RB2sampling_rate(RC.ru[ru_id]->frame_parms->N_RB_UL),
N_RB2channel_bandwidth(RC.ru[ru_id]->frame_parms->N_RB_UL),
DS_TDL,
0.0,
0,
0,
0);
new_channel_desc_scm(PHY_vars_UE_g[UE_id][CC_id]->frame_parms.nb_antennas_tx,
RC.ru[ru_id]->nb_rx,
AWGN,
N_RB2sampling_rate(RC.ru[ru_id]->frame_parms->N_RB_UL),
N_RB2channel_bandwidth(RC.ru[ru_id]->frame_parms->N_RB_UL),
DS_TDL,
CORR_LEVEL_LOW,
0.0,
0,
0,
0);
random_channel(sim.UE2RU[UE_id][ru_id][CC_id],0);
// to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.
//UE2RU[UE_id][ru_id] = RU2UE[ru_id][UE_id];
......
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