diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index b371f6af20..6ae75d71ae 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -212,7 +212,7 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build eNb-ethernet") {
timeout (time: 20, unit: 'MINUTES') {
- sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
+ sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
@@ -221,7 +221,7 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 20, unit: 'MINUTES') {
- sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
+ sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index dda71d2606..940bcd2852 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -252,8 +252,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
- NB_PATTERN_FILES=7
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--phy_simulators"
+ VM_MEMORY=4096
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
shift
@@ -330,8 +331,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
- NB_PATTERN_FILES=7
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--phy_simulators"
+ VM_MEMORY=4096
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
;;
diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh
index a6f4edace8..208bf06318 100755
--- a/ci-scripts/waitBuildOnVM.sh
+++ b/ci-scripts/waitBuildOnVM.sh
@@ -165,6 +165,10 @@ function check_on_vm_build {
fi
done
- if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi
+ if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]
+ then
+ echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES"
+ STATUS=-1
+ fi
}
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index c54c3e3322..2f66c6af34 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1065,12 +1065,12 @@
$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash
$OPENAIR_DIR/targets/bin/nr_pbchsim.Rel15
- -s-11 -S-10 -n1000 -R106
- -s-11 -S-10 -n10 -I -R106
- -s-11 -S-10 -n1000 -R217 -N10
- -s-11 -S-10 -n10 -I -R217 -N10
- -s-11 -S-10 -n1000 -R273 -N20
- -s-11 -S-10 -n10 -I -R273 -N20
+ -s0 -S1 -n1000 -R106
+ -s0 -S1 -n10 -I -R106
+ -s0 -S1 -n1000 -R217
+ -s0 -S1 -n10 -I -R217
+ -s0 -S1 -n1000 -R273
+ -s0 -S1 -n10 -I -R273
nr_pbchsim.test1 nr_pbchsim.test2
PBCH test OK
segmentation fault|assertion|exiting|fatal
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index f018e8c422..01ab01f0a7 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -696,7 +696,7 @@ function main() {
echo_info "Compiling unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
- simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim"
+ simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim"
for f in $simlist ; do
compilations \
phy_simulators $f \
diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h
index 2040faf4a2..0f316e7869 100644
--- a/openair1/PHY/CODING/coding_defs.h
+++ b/openair1/PHY/CODING/coding_defs.h
@@ -467,33 +467,26 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f);
-uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
- uint32_t Tbslbrm,
- uint8_t BG,
- uint16_t Z,
- uint32_t G,
- uint8_t *w,
- uint8_t *e,
- uint8_t C,
- uint8_t rvidx,
- uint8_t Qm,
- uint8_t Nl,
- uint8_t r);
+int nr_rate_matching_ldpc(uint8_t Ilbrm,
+ uint32_t Tbslbrm,
+ uint8_t BG,
+ uint16_t Z,
+ uint8_t *w,
+ uint8_t *e,
+ uint8_t C,
+ uint8_t rvidx,
+ uint32_t E);
int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
- uint32_t Tbslbrm,
- uint8_t BG,
- uint16_t Z,
- uint32_t G,
+ uint32_t Tbslbrm,
+ uint8_t BG,
+ uint16_t Z,
int16_t *w,
int16_t *soft_input,
uint8_t C,
uint8_t rvidx,
uint8_t clear,
- uint8_t Qm,
- uint8_t Nl,
- uint8_t r,
- uint32_t *E_out);
+ uint32_t E);
decoder_if_t phy_threegpplte_turbo_decoder;
decoder_if_t phy_threegpplte_turbo_decoder8;
diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c
index 01390f1f2f..0bce31630f 100644
--- a/openair1/PHY/CODING/nr_rate_matching.c
+++ b/openair1/PHY/CODING/nr_rate_matching.c
@@ -63,55 +63,39 @@ void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
}
-uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
- uint32_t Tbslbrm,
- uint8_t BG,
- uint16_t Z,
- uint32_t G,
- uint8_t *w,
- uint8_t *e,
- uint8_t C,
- uint8_t rvidx,
- uint8_t Qm,
- uint8_t Nl,
- uint8_t r)
+int nr_rate_matching_ldpc(uint8_t Ilbrm,
+ uint32_t Tbslbrm,
+ uint8_t BG,
+ uint16_t Z,
+ uint8_t *w,
+ uint8_t *e,
+ uint8_t C,
+ uint8_t rvidx,
+ uint32_t E)
{
- uint8_t Cprime;
- uint32_t Ncb,E,ind,k,Nref,N;
- //uint8_t *e2;
+ uint32_t Ncb,ind,k,Nref,N;
- AssertFatal(Nl>0,"Nl is 0\n");
- AssertFatal(Qm>0,"Qm is 0\n");
+ if (C==0) {
+ printf("nr_rate_matching: invalid parameters (C %d\n",C);
+ return -1;
+ }
//Bit selection
N = (BG==1)?(66*Z):(50*Z);
if (Ilbrm == 0)
- Ncb = N;
+ Ncb = N;
else {
Nref = 3*Tbslbrm/(2*C); //R_LBRM = 2/3
Ncb = min(N, Nref);
}
-#ifdef RM_DEBUG
- printf("nr_rate_matching: Ncb %d, rvidx %d, G %d, Qm %d, Nl%d, r %d\n",Ncb,rvidx, G, Qm,Nl,r);
-#endif
-
- Cprime = C; //assume CBGTI not present
-
- if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
- E = Nl*Qm*(G/(Nl*Qm*Cprime));
- else
- E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
-
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG
- printf("nr_rate_matching: E %d, k0 %d Cprime %d modcprime %d\n",E,ind, Cprime,((G/(Nl*Qm))%Cprime));
+ printf("nr_rate_matching_ldpc: E %d, k0 %d, Ncb %d, rvidx %d\n", E, ind, Ncb, rvidx);
#endif
- //e2 = e;
-
k=0;
for (; (ind0,"Nl is 0\n");
- AssertFatal(Qm>0,"Qm is 0\n");
-
//Bit selection
N = (BG==1)?(66*Z):(50*Z);
if (Ilbrm == 0)
- Ncb = N;
+ Ncb = N;
else {
Nref = (3*Tbslbrm/(2*C)); //R_LBRM = 2/3
Ncb = min(N, Nref);
}
- Cprime = C; //assume CBGTI not present
-
- if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
- E = Nl*Qm*(G/(Nl*Qm*Cprime));
- else
- E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
-
ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG
- printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, Ncb %d,rvidx %d, G %d, Qm %d, Nl%d, r %d\n",clear,E,Ncb,rvidx, G, Qm,Nl,r);
+ printf("nr_rate_matching_ldpc_rx: Clear %d, E %d, k0 %d, Ncb %d, rvidx %d\n", clear, E, ind, Ncb, rvidx);
#endif
if (clear==1)
memset(w,0,Ncb*sizeof(int16_t));
- soft_input2 = soft_input;
k=0;
for (; (indharq_processes[harq_pid]->K;
- //Kr_bytes = Kr>>3;
+ Kr_bytes = Kr>>3;
//printf("segment Z %d kb %d k %d Kr %d BG %d\n", *pz,kb,dlsch->harq_processes[harq_pid]->K,Kr,BG);
@@ -403,25 +403,24 @@ int nr_dlsch_encoding(unsigned char *a,
//start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING
- printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+ printf("rvidx in encoding = %d\n", rel15.redundancy_version);
#endif
- E = nr_rate_matching_ldpc(Ilbrm,
- Tbslbrm,
- BG,
- *pz,
- G,
- dlsch->harq_processes[harq_pid]->d[r],
- dlsch->harq_processes[harq_pid]->e+r_offset,
- dlsch->harq_processes[harq_pid]->C,
- rel15.redundancy_version,
- mod_order,
- rel15.nb_layers,
- r);
+ E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
+
+ nr_rate_matching_ldpc(Ilbrm,
+ Tbslbrm,
+ BG,
+ *pz,
+ dlsch->harq_processes[harq_pid]->d[r],
+ dlsch->harq_processes[harq_pid]->e+r_offset,
+ dlsch->harq_processes[harq_pid]->C,
+ rel15.redundancy_version,
+ E);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
- printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i], r_offset);
+ printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
#endif
//stop_meas(rm_stats);
@@ -432,18 +431,15 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->f+r_offset);
//stop_meas(i_stats);
- r_offset += E;
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
- printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r*r_offset], r_offset);
-#endif
-
-#ifdef DEBUG_DLSCH_CODING
+ printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
if (r==dlsch->harq_processes[harq_pid]->C-1)
- write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,r_offset,1,4);
-
+ write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,G,1,4);
#endif
+
+ r_offset += E;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
index 0b8ab56329..f8b7454067 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_tbs_tools.c
@@ -176,3 +176,18 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16
G = ((NR_NB_SC_PER_RB*nb_symb_sch)-(nb_re_dmrs*length_dmrs))*nb_rb*Qm*Nl;
return(G);
}
+
+uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r) {
+ uint32_t E;
+ uint8_t Cprime = C; //assume CBGTI not present
+
+ AssertFatal(Nl>0,"Nl is 0\n");
+ AssertFatal(Qm>0,"Qm is 0\n");
+
+ if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1)
+ E = Nl*Qm*(G/(Nl*Qm*Cprime));
+ else
+ E = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
+
+ return E;
+}
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index a90450b0a5..4e2d245bb9 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -298,7 +298,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
// generate pilot
- nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
+ nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns>>1][symbol], &pilot[0],2000,nb_rb_coreset);
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 67cb3783ef..5ea5416ea6 100755
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -821,8 +821,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
#ifdef NR_PDCCH_DCI_DEBUG
printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol);
- printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) \n",
- coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R);
+ printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n",
+ coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id);
#endif
//
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index 610b8305df..2888a59606 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -376,6 +376,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
for (r=0; rC; r++) {
//printf("start rx segment %d\n",r);
+ E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+
+#if UE_TIMING_TRACE
+ start_meas(dlsch_deinterleaving_stats);
+#endif
+ nr_deinterleaving_ldpc(E,
+ harq_process->Qm,
+ harq_process->w[r],
+ dlsch_llr+r_offset);
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+
+#if UE_TIMING_TRACE
+ stop_meas(dlsch_deinterleaving_stats);
+#endif
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
@@ -394,20 +410,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
#endif
if (nr_rate_matching_ldpc_rx(Ilbrm,
- Tbslbrm,
- p_decParams->BG,
- p_decParams->Z,
- G,
- harq_process->w[r],
- dlsch_llr+r_offset,
- harq_process->C,
- harq_process->rvidx,
- (harq_process->round==0)?1:0,
- harq_process->Qm,
- harq_process->Nl,
- r,
- &E)==-1) {
-
+ Tbslbrm,
+ p_decParams->BG,
+ p_decParams->Z,
+ harq_process->d[r],
+ harq_process->w[r],
+ harq_process->C,
+ harq_process->rvidx,
+ (harq_process->round==0)?1:0,
+ E)==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
@@ -419,27 +430,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
+
r_offset += E;
- //for (int i =0; i<16; i++)
- // printf("rx output ratematching w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
-
-#if UE_TIMING_TRACE
- start_meas(dlsch_deinterleaving_stats);
-#endif
- nr_deinterleaving_ldpc(E,
- harq_process->Qm,
- harq_process->d[r],
- harq_process->w[r]);
-
- //for (int i =0; i<16; i++)
- // printf("rx output interleaving d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
-
-#if UE_TIMING_TRACE
- stop_meas(dlsch_deinterleaving_stats);
-#endif
#ifdef DEBUG_DLSCH_DECODING
-
if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
@@ -979,6 +976,30 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+ E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+
+ /*
+ printf("Subblock deinterleaving, dlsch_llr %p, w %p\n",
+ dlsch_llr+r_offset,
+ &harq_process->w[r]);
+ */
+#if UE_TIMING_TRACE
+ start_meas(dlsch_deinterleaving_stats);
+#endif
+ nr_deinterleaving_ldpc(E,
+ harq_process->Qm,
+ harq_process->w[r],
+ dlsch_llr+r_offset);
+
+#ifdef DEBUG_DLSCH_DECODING
+ for (int i =0; i<16; i++)
+ printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+#endif
+
+#if UE_TIMING_TRACE
+ stop_meas(dlsch_deinterleaving_stats);
+#endif
+
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
@@ -995,23 +1016,16 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
harq_process->round);
#endif
-#ifdef DEBUG_DLSCH_DECODING
- printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
-#endif
if (nr_rate_matching_ldpc_rx(Ilbrm,
- Tbslbrm,
- p_decParams->BG,
- p_decParams->Z,
- G,
- harq_process->w[r],
- dlsch_llr+r_offset,
- harq_process->C,
- harq_process->rvidx,
- (harq_process->round==0)?1:0,
- harq_process->Qm,
- harq_process->Nl,
- r,
- &E)==-1) {
+ Tbslbrm,
+ p_decParams->BG,
+ p_decParams->Z,
+ harq_process->d[r],
+ harq_process->w[r],
+ harq_process->C,
+ harq_process->rvidx,
+ (harq_process->round==0)?1:0,
+ E)==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
@@ -1023,34 +1037,18 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
+
//r_offset += E;
//printf("main thread r_offset %d\n",r_offset);
#ifdef DEBUG_DLSCH_DECODING
for (int i =0; i<16; i++)
- printf("rx output ratematching w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+ printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
#endif
- /*
- printf("Subblock deinterleaving, d %p w %p\n",
- harq_process->d[r],
- harq_process->w);
- */
-#if UE_TIMING_TRACE
- start_meas(dlsch_deinterleaving_stats);
-#endif
- nr_deinterleaving_ldpc(E,
- harq_process->Qm,
- harq_process->d[r],
- harq_process->w[r]);
-#ifdef DEBUG_DLSCH_DECODING
- for (int i =0; i<16; i++)
- printf("rx output interleaving d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
-#endif
-
-#if UE_TIMING_TRACE
- stop_meas(dlsch_deinterleaving_stats);
-#endif
#ifdef DEBUG_DLSCH_DECODING
if (r==0) {
@@ -1526,6 +1524,23 @@ void *nr_dlsch_decoding_2thread0(void *arg)
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+ E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+
+#if UE_TIMING_TRACE
+ start_meas(dlsch_deinterleaving_stats);
+#endif
+ nr_deinterleaving_ldpc(E,
+ harq_process->Qm,
+ harq_process->w[r],
+ dlsch_llr+r_offset);
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+
+#if UE_TIMING_TRACE
+ stop_meas(dlsch_deinterleaving_stats);
+#endif
+
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
@@ -1542,23 +1557,16 @@ void *nr_dlsch_decoding_2thread0(void *arg)
harq_process->round);
#endif
-#ifdef DEBUG_DLSCH_DECODING
- printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
-#endif
if (nr_rate_matching_ldpc_rx(Ilbrm,
- Tbslbrm,
- p_decParams->BG,
- p_decParams->Z,
- G,
- harq_process->w[r],
- dlsch_llr+r_offset,
- harq_process->C,
- harq_process->rvidx,
- (harq_process->round==0)?1:0,
- harq_process->Qm,
- harq_process->Nl,
- r,
- &E)==-1) {
+ Tbslbrm,
+ p_decParams->BG,
+ p_decParams->Z,
+ harq_process->d[r],
+ harq_process->w[r],
+ harq_process->C,
+ harq_process->rvidx,
+ (harq_process->round==0)?1:0,
+ E)==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
@@ -1570,23 +1578,13 @@ void *nr_dlsch_decoding_2thread0(void *arg)
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
- //r_offset += E;
//for (int i =0; i<16; i++)
- // printf("rx output ratematching w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+ // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
+
+ //r_offset += E;
-#if UE_TIMING_TRACE
- start_meas(dlsch_deinterleaving_stats);
-#endif
- nr_deinterleaving_ldpc(E,
- harq_process->Qm,
- harq_process->d[r],
- harq_process->w[r]);
-#if UE_TIMING_TRACE
- stop_meas(dlsch_deinterleaving_stats);
-#endif
#ifdef DEBUG_DLSCH_DECODING
-
if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
@@ -2043,6 +2041,28 @@ void *nr_dlsch_decoding_2thread1(void *arg)
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl);
+ E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r);
+
+ /*
+ printf("Subblock deinterleaving, d %p w %p\n",
+ harq_process->d[r],
+ harq_process->w);
+ */
+#if UE_TIMING_TRACE
+ start_meas(dlsch_deinterleaving_stats);
+#endif
+ nr_deinterleaving_ldpc(E,
+ harq_process->Qm,
+ harq_process->w[r],
+ dlsch_llr+r_offset);
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
+
+#if UE_TIMING_TRACE
+ stop_meas(dlsch_deinterleaving_stats);
+#endif
+
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
@@ -2059,23 +2079,16 @@ void *nr_dlsch_decoding_2thread1(void *arg)
harq_process->round);
#endif
-#ifdef DEBUG_DLSCH_DECODING
- printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
-#endif
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
p_decParams->Z,
- G,
+ harq_process->d[r],
harq_process->w[r],
- dlsch_llr+r_offset,
harq_process->C,
harq_process->rvidx,
(harq_process->round==0)?1:0,
- harq_process->Qm,
- harq_process->Nl,
- r,
- &E)==-1) {
+ E)==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
@@ -2087,23 +2100,12 @@ void *nr_dlsch_decoding_2thread1(void *arg)
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
+
+ //for (int i =0; i<16; i++)
+ // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
+
//r_offset += E;
- /*
- printf("Subblock deinterleaving, d %p w %p\n",
- harq_process->d[r],
- harq_process->w);
- */
-#if UE_TIMING_TRACE
- start_meas(dlsch_deinterleaving_stats);
-#endif
- nr_deinterleaving_ldpc(E,
- harq_process->Qm,
- harq_process->d[r],
- harq_process->w[r]);
-#if UE_TIMING_TRACE
- stop_meas(dlsch_deinterleaving_stats);
-#endif
#ifdef DEBUG_DLSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index 4a6e6423f6..e5f079ebc3 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -39,6 +39,7 @@
//#include "SCHED/extern.h"
#include "common_lib.h"
+#include
#include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_nr.h"
@@ -56,6 +57,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int ret =-1;
+
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
ue->rx_offset);
@@ -65,6 +67,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode)
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
+
//symbol 1
nr_slot_fep(ue,
1,
@@ -143,6 +146,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
int32_t sync_pos, sync_pos_slot; // k_ssb, N_ssb_crb, sync_pos2,
int32_t metric_tdd_ncp=0;
uint8_t phase_tdd_ncp;
+ double im, re;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1;
@@ -183,14 +187,14 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
sync_pos = pss_synchro_nr(ue, NO_RATE_CHANGE);
sync_pos_slot = (fp->samples_per_subframe/fp->slots_per_subframe) - 10*(fp->ofdm_symbol_size + fp->nb_prefix_samples);
-
+
if (sync_pos >= fp->nb_prefix_samples){
ue->ssb_offset = sync_pos - fp->nb_prefix_samples;}
else{
ue->ssb_offset = sync_pos + (fp->samples_per_subframe * 10) - fp->nb_prefix_samples;}
- ue->rx_offset = ue->ssb_offset - sync_pos_slot;
-
+ ue->rx_offset = ue->ssb_offset - sync_pos_slot;
+
//write_output("rxdata1.m","rxd1",ue->common_vars.rxdata[0],10*fp->samples_per_subframe,1,1);
#ifdef DEBUG_INITIAL_SYNCH
@@ -198,6 +202,25 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
LOG_I(PHY,"sync_pos %d ssb_offset %d sync_pos_slot %d \n",sync_pos,ue->ssb_offset,sync_pos_slot);
#endif
+ // digital compensation of FFO for SSB symbols
+ if (ue->UE_fo_compensation){
+ double s_time = 1/(1.0e3*fp->samples_per_subframe); // sampling time
+ double off_angle = -2*M_PI*s_time*(ue->common_vars.freq_offset); // offset rotation angle compensation per sample
+
+ int start = ue->ssb_offset; // start for offset correction is at ssb_offset (pss time position)
+ int end = start + 4*(fp->ofdm_symbol_size + fp->nb_prefix_samples); // loop over samples in 4 symbols (ssb size), including prefix
+
+ for(int n=start; nnb_antennas_rx; ar++) {
+ re = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n]);
+ im = ((double)(((short *)ue->common_vars.rxdata[ar]))[2*n+1]);
+ ((short *)ue->common_vars.rxdata[ar])[2*n] = (short)(round(re*cos(n*off_angle) - im*sin(n*off_angle)));
+ ((short *)ue->common_vars.rxdata[ar])[2*n+1] = (short)(round(re*sin(n*off_angle) + im*cos(n*off_angle)));
+ }
+ }
+ }
+
+
/* check that SSS/PBCH block is continuous inside the received buffer */
if (sync_pos < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe - (NB_SYMBOLS_PBCH * fp->ofdm_symbol_size))) {
@@ -244,7 +267,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
ret = -1;
}
- /* Consider this is a false detection if the offset is > 1000 Hz */
+ /* Consider this is a false detection if the offset is > 1000 Hz
+ Not to be used now that offest estimation is in place
if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
{
ret=-1;
@@ -253,7 +277,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
#else
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
#endif
- }
+ }*/
if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters
@@ -329,13 +353,13 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
- openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
+ openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# else
LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
- openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
+ openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# endif
#endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
index 01481d3612..9b09a846bb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include "PHY/defs_nr_UE.h"
@@ -662,6 +663,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int synchro_position;
int **rxdata = NULL;
+ int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
#ifdef DBG_PSS_NR
@@ -705,7 +707,10 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
synchro_position = pss_search_time_nr(rxdata,
frame_parms,
- (int *)&PHY_vars_UE->common_vars.eNb_id);
+ fo_flag,
+ (int *)&PHY_vars_UE->common_vars.eNb_id,
+ (int *)&PHY_vars_UE->common_vars.freq_offset);
+
#if TEST_SYNCHRO_TIMING_PSS
@@ -751,6 +756,15 @@ static inline int64_t abs64(int64_t x)
return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
}
+static inline double angle64(int64_t x)
+{
+
+ double re=((int32_t*)&x)[0];
+ double im=((int32_t*)&x)[1];
+ return (atan2(im,re));
+}
+
+
/*******************************************************************
*
* NAME : pss_search_time_nr
@@ -805,12 +819,15 @@ static inline int64_t abs64(int64_t x)
int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms,
- int *eNB_id)
+ int fo_flag,
+ int *eNB_id,
+ int *f_off)
{
unsigned int n, ar, peak_position, pss_source;
int64_t peak_value;
int64_t result;
int64_t avg[NUMBER_PSS_SEQUENCE];
+ double ffo_est=0;
unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
@@ -831,7 +848,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
maxval = max(maxval,-primary_synchro_time_nr[1][i]);
maxval = max(maxval,primary_synchro_time_nr[2][i]);
maxval = max(maxval,-primary_synchro_time_nr[2][i]);
-
}
int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
@@ -859,7 +875,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
frame_parms->ofdm_symbol_size,
shift);
pss_corr_ue[pss_index][n] += abs64(result);
-
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
@@ -867,7 +882,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
}
}
-
+
/* calculate the absolute value of sync_corr[n] */
avg[pss_index]+=pss_corr_ue[pss_index][n];
if (pss_corr_ue[pss_index][n] > peak_value) {
@@ -882,11 +897,45 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
}
}
+ if (fo_flag){
+ // fractional frequency offser computation according to Cross-correlation Synchronization Algorithm Using PSS
+ // Shoujun Huang, Yongtao Su, Ying He and Shan Tang, "Joint time and frequency offset estimation in LTE downlink," 7th International Conference on Communications and Networking in China, 2012.
+
+ int64_t result1,result2;
+ // Computing cross-correlation at peak on half the symbol size for first half of data
+ result1 = dot_product64((short*)primary_synchro_time_nr[pss_source],
+ (short*) &(rxdata[0][peak_position]),
+ frame_parms->ofdm_symbol_size>>1,
+ shift);
+ // Computing cross-correlation at peak on half the symbol size for data shifted by half symbol size
+ // as it is real and complex it is necessary to shift by a value equal to symbol size to obtain such shift
+ result2 = dot_product64((short*)primary_synchro_time_nr[pss_source]+(frame_parms->ofdm_symbol_size),
+ (short*) &(rxdata[0][peak_position])+(frame_parms->ofdm_symbol_size),
+ frame_parms->ofdm_symbol_size>>1,
+ shift);
+
+ int64_t re1,re2,im1,im2;
+ re1=((int*) &result1)[0];
+ re2=((int*) &result2)[0];
+ im1=((int*) &result1)[1];
+ im2=((int*) &result2)[1];
+
+ // estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
+ ffo_est=atan2(re1*im2-re2*im1,re1*re2+im1*im2)/M_PI;
+
+#ifdef DBG_PSS_NR
+ printf("ffo %lf\n",ffo_est);
+#endif
+ }
+
+ // computing absolute value of frequency offset
+ *f_off = ffo_est*frame_parms->subcarrier_spacing;
+
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
*eNB_id = pss_source;
- LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]));
+ LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %llu (%d dB) avg %d dB, ffo %lf\n", pss_source, peak_position, (unsigned long long)peak_value, dB_fixed64(peak_value),dB_fixed64(avg[pss_source]),ffo_est);
if (peak_value < 5*avg[pss_source])
return(-1);
diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c
index 06546467b1..843a9605f1 100644
--- a/openair1/PHY/TOOLS/cdot_prod.c
+++ b/openair1/PHY/TOOLS/cdot_prod.c
@@ -180,14 +180,13 @@ int64_t dot_product64(int16_t *x,
for (n=0; n<(N>>2); n++) {
// printf("n=%d, x128=%p, y128=%p\n",n,x128,y128);
- // print_shorts("x",&x128[0]);
- // print_shorts("y",&y128[0]);
+ // print_shorts("x",&x128[0]);
+ // print_shorts("y",&y128[0]);
// this computes Re(z) = Re(x)*Re(y) + Im(x)*Im(y)
mmtmp1 = _mm_madd_epi16(x128[0],y128[0]);
// print_ints("retmp",&mmtmp1);
// mmtmp1 contains real part of 4 consecutive outputs (32-bit)
-
// shift and accumulate results
mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift);
mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1);
@@ -205,7 +204,6 @@ int64_t dot_product64(int16_t *x,
mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2);
//print_ints("imtmp",&mmtmp3);
// mmtmp3 contains imag part of 4 consecutive outputs (32-bit)
-
// shift and accumulate results
mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift);
mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3);
@@ -218,13 +216,10 @@ int64_t dot_product64(int16_t *x,
// this gives Re Re Im Im
mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im);
//print_ints("cumul1",&mmcumul);
-
// this gives Re Im Re Im
mmcumul = _mm_hadd_epi32(mmcumul,mmcumul);
-
//print_ints("cumul2",&mmcumul);
-
//mmcumul = _mm_srai_epi32(mmcumul,output_shift);
// extract the lower half
result = _mm_extract_epi64(mmcumul,0);
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 0100dd44c4..3dd16ff0da 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -498,10 +498,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
float **rxsig_t_dB;
float *time;
float *corr;
- /*
int16_t **chest_t;
int16_t **chest_f;
- */
int16_t *pdsch_llr;
int16_t *pdsch_comp;
//int16_t *pdsch_mag;
@@ -519,10 +517,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
int coded_bits_per_codeword = num_re*Qm;
int symbol, first_symbol,nb_re;
int nb_rb_pdsch =50;
+ float ymax=1;
+ float **chest_t_abs;
+ float Re,Im;
+ float *chest_f_abs;
+ float *freq;
+ static int overlay = 0;
/*
- float Re,Im,ymax=1;
- float **chest_t_abs, *chest_f_abs;
- float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
int mcs = 0;
unsigned char harq_pid = 0;
@@ -565,15 +566,15 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
*/
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
- /*
+
chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
for (arx=0; arxofdm_symbol_size,sizeof(float));
}
- chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
- */
+ chest_f_abs = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
+ freq = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
@@ -589,10 +590,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
time = calloc(samples_per_frame,sizeof(float));
corr = calloc(samples_per_frame,sizeof(float));
- /*
chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
- */
+
pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
@@ -628,29 +628,37 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
}
if (phy_vars_ue->is_synchronized==0) {
- for (ind=0;ind<3;ind++) {
- if (pss_corr_ue[ind]) {
- for (i=0; ichest_t,time,corr,samples_per_frame,"","","");
+ else
+ fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
+
+ overlay = 1;
}
-
- if (ind==0)
- fl_set_xyplot_data(form->chest_t,time,corr,samples_per_frame,"","","");
- else
- fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
}
- }
+ }
+ else {
+
+ if (overlay) { //there was a previous overlay
+ fl_clear_xyplot(form->chest_t);
+ overlay = 0;
}
- /*
- // Channel Impulse Response (still repeated format)
+ // Channel Impulse Response
if (chest_t != NULL) {
ymax = 0;
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
- chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]);
+ chest_t_abs[0][i] = (float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]);
+ time[i] = (float) i;
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
@@ -658,7 +666,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
}
-
+ /*
for (arx=1; arxofdm_symbol_size>>3); i++) {
@@ -672,11 +680,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
}
}
-
+ */
// Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
fl_set_xyplot_ybounds(form->chest_t,0,(double) ymax);
}
+ }
// Channel Frequency Response (includes 5 complex sample for filter)
if (chest_f != NULL) {
@@ -685,7 +694,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
for (atx=0; atxofdm_symbol_size; k++) {
freq[ind] = (float)ind;
Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
@@ -698,12 +707,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
}
// tx antenna 0
- fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
//fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
// fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
- fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+ //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
+ /*
for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
@@ -722,8 +732,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
}
+ */
}
- */
// PBCH LLRs
if (pbch_llr != NULL) {
@@ -735,10 +745,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
}
- if (phy_vars_ue->is_synchronized==1)
- first_symbol=5;
- else
- first_symbol=1;
+ first_symbol=1;
// PBCH I/Q of MF Output
if (pbch_comp!=NULL) {
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 3d56147c8e..2823a58f39 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -983,6 +983,8 @@ typedef struct {
int UE_scan;
/// \brief Indicator that UE should perform coarse scanning around carrier
int UE_scan_carrier;
+ /// \brief Indicator that UE should enable estimation and compensation of frequency offset
+ int UE_fo_compensation;
/// \brief Indicator that UE is synchronized to an eNB
int is_synchronized;
/// Data structure for UE process scheduling
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 7cbb70242e..a7f8ef6884 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -138,20 +138,22 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
- nr_generate_sss(gNB->d_sss, txdataF[0], AMP_OVER_2, ssb_start_symbol, cfg, fp);
+ nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp);
if (!(frame&7)){
LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured);
if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0;
}
- nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP_OVER_2, ssb_start_symbol, cfg, fp);
+
+ nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp);
+
nr_generate_pbch(&gNB->pbch,
gNB->nrPolar_params,
pbch_pdu,
gNB->nr_pbch_interleaver,
txdataF[0],
- AMP_OVER_2,
+ AMP,
ssb_start_symbol,
n_hf,Lmax,ssb_index,
frame, cfg, fp);
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 3eb0c319aa..3619625a1e 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -2781,8 +2781,6 @@ void nr_ue_measurement_procedures(
*/
eNB_id = 0;
-
-
LOG_D(PHY,"start adjust sync l = %d slot = %d no timing %d\n",l, slot, ue->no_timing_correction);
if (ue->no_timing_correction==0)
nr_adjust_synch_ue(&ue->frame_parms,
@@ -2791,7 +2789,6 @@ void nr_ue_measurement_procedures(
nr_tti_rx,
0,
16384);
-
}
@@ -5065,7 +5062,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
nr_slot_fep(ue,
l,
- nr_tti_rx,
+ nr_tti_rx<<1,
0,
0,
1,
@@ -5107,7 +5104,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
}
//set active for testing, to be removed
- ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 1;
+ ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
}
else
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index f71cb7d147..214a33fb73 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -87,11 +87,13 @@ int main(int argc, char **argv)
int i,aa;//,l;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
+ double cfo=0;
uint8_t snr1set=0;
int **txdata;
double **s_re,**s_im,**r_re,**r_im;
- //double iqim = 0.0;
- //unsigned char pbch_pdu[6];
+ double iqim = 0.0;
+ double ip =0.0;
+ unsigned char pbch_pdu[6];
// int sync_pos, sync_pos_slot;
// FILE *rx_frame_file;
FILE *output_fd = NULL;
@@ -146,7 +148,7 @@ int main(int argc, char **argv)
randominit(0);
- while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:dP:IL:")) != -1) {
+ while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:o:s:S:t:x:y:z:N:F:GR:dP:IL:")) != -1) {
switch (c) {
case 'f':
write_output_file=1;
@@ -212,6 +214,11 @@ int main(int argc, char **argv)
n_trials = atoi(optarg);
break;
+ case 'o':
+ cfo = atof(optarg);
+ msg("Setting CFO to %f Hz\n",cfo);
+ break;
+
case 's':
snr0 = atof(optarg);
msg("Setting SNR0 to %f\n",snr0);
@@ -325,6 +332,7 @@ int main(int argc, char **argv)
printf("-z Number of RX antennas used in UE\n");
printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
+ printf("-o Carrier frequency offset in Hz\n");
printf("-N Nid_cell\n");
printf("-R N_RB_DL\n");
printf("-O oversampling factor (1,2,4,8,16)\n");
@@ -356,30 +364,49 @@ int main(int argc, char **argv)
frame_parms->nb_antennas_rx = n_rx;
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = N_RB_DL;
+ frame_parms->Nid_cell = Nid_cell;
nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell);
phy_init_nr_gNB(gNB,0,0);
- double fs,bw;
+ double fs,bw,scs,eps;
if (mu == 1 && N_RB_DL == 217) {
fs = 122.88e6;
bw = 80e6;
+ scs = 30000;
}
else if (mu == 1 && N_RB_DL == 245) {
fs = 122.88e6;
bw = 90e6;
+ scs = 30000;
}
else if (mu == 1 && N_RB_DL == 273) {
fs = 122.88e6;
bw = 100e6;
+ scs = 30000;
}
else if (mu == 1 && N_RB_DL == 106) {
fs = 61.44e6;
bw = 40e6;
+ scs = 30000;
}
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
+ // cfo with respect to sub-carrier spacing
+ eps = cfo/scs;
+
+ // computation of integer and fractional FO to compare with estimation results
+ int IFO;
+ if(eps!=0.0){
+ printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000));
+ if (eps>0)
+ IFO=(int)(eps+0.5);
+ else
+ IFO=(int)(eps-0.5);
+ printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO);
+ }
+
gNB2UE = new_channel_desc_scm(n_tx,
n_rx,
channel_model,
@@ -435,6 +462,9 @@ int main(int argc, char **argv)
UE->perfect_ce = 0;
+ if(eps!=0.0)
+ UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation
+
if (init_nr_ue_signal(UE, 1, 0) != 0)
{
printf("Error at UE NR initialisation\n");
@@ -492,6 +522,7 @@ int main(int argc, char **argv)
// printf("txlev %d (%f)\n",txlev,10*log10(txlev));
+
for (i=0; inb_antennas_tx; aa++) {
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
@@ -510,11 +541,32 @@ int main(int argc, char **argv)
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
//AWGN
- sigma2_dB = 10*log10((double)txlev)-SNR;
+ sigma2_dB = 20*log10((double)AMP/4)-SNR;
sigma2 = pow(10,sigma2_dB/10);
- // printf("sigma2 %f (%f dB)\n",sigma2,sigma2_dB);
+ //printf("sigma2 %f (%f dB), tx_lev %f (%f dB)\n",sigma2,sigma2_dB,txlev,10*log10((double)txlev));
- for (i=0; isamples_per_subframe; i++) {
+ if(eps!=0.0)
+ rf_rx(r_re, // real part of txdata
+ r_im, // imag part of txdata
+ NULL, // interference real part
+ NULL, // interference imag part
+ 0, // interference power
+ frame_parms->nb_antennas_rx, // number of rx antennas
+ frame_length_complex_samples, // number of samples in frame
+ 1.0e9/fs, //sampling time (ns)
+ cfo, // frequency offset in Hz
+ 0.0, // drift (not implemented)
+ 0.0, // noise figure (not implemented)
+ 0.0, // rx gain in dB ?
+ 200, // 3rd order non-linearity in dB ?
+ &ip, // initial phase
+ 30.0e3, // phase noise cutoff in kHz
+ -500.0, // phase noise amplitude in dBc
+ 0.0, // IQ imbalance (dB),
+ 0.0); // IQ phase imbalance (rad)
+
+
+ for (i=0; inb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c
index e317fbd154..bff3453de0 100644
--- a/openair1/SIMULATION/RF/rf.c
+++ b/openair1/SIMULATION/RF/rf.c
@@ -107,10 +107,10 @@ void rf_rx(double **r_re,
exit(-1);
}
- if (fabs(f_off) > 10000.0) {
+/* if (fabs(f_off) > 10000.0) {
printf("rf.c: Illegal f_off %f\n",f_off);
exit(-1);
- }
+ }*/
if (fabs(drift) > 1000.0) {
printf("rf.c: Illegal drift %f\n",drift);
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index e302291a61..a0b07c4fbd 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -292,7 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
uint32_t number_of_search_space_per_slot=1;
uint32_t first_symbol_index=0;
- uint32_t search_space_duration=1; // element of search space
+ uint32_t search_space_duration=0; // element of search space
uint32_t coreset_duration; // element of coreset
coreset_duration = num_symbols * number_of_search_space_per_slot;
diff --git a/targets/RT/USER/nr-ue.c b/targets/RT/USER/nr-ue.c
index f06ae0864d..ce56bc95ff 100644
--- a/targets/RT/USER/nr-ue.c
+++ b/targets/RT/USER/nr-ue.c
@@ -444,6 +444,7 @@ static void *UE_thread_synch(void *arg) {
//write_output("txdata_sym.m", "txdata_sym", UE->common_vars.rxdata[0], (10*UE->frame_parms.samples_per_slot), 1, 1);
+ freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync
hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot;
printf("Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
hw_slot_offset,
@@ -457,16 +458,13 @@ static void *UE_thread_synch(void *arg) {
// rerun with new cell parameters and frequency-offset
for (i=0; irf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
- if (UE->UE_scan_carrier == 1) {
if (freq_offset >= 0)
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset);
else
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset);
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
- freq_offset=0;
- }
}
// reconfigure for potentially different bandwidth
@@ -602,7 +600,7 @@ static void *UE_thread_synch(void *arg) {
phy_scope_UE(form_ue[0],
PHY_vars_UE_g[0][0],
- 0,0,7);
+ 0,0,1);
}
#endif
diff --git a/targets/RT/USER/nr-uesoftmodem.c b/targets/RT/USER/nr-uesoftmodem.c
index 81f46d31b3..d3d660e7f5 100644
--- a/targets/RT/USER/nr-uesoftmodem.c
+++ b/targets/RT/USER/nr-uesoftmodem.c
@@ -130,6 +130,7 @@ static char *itti_dump_file = NULL;
int UE_scan = 0;
int UE_scan_carrier = 0;
+int UE_fo_compensation = 0;
runmode_t mode = normal_txrx;
FILE *input_fd=NULL;
@@ -978,6 +979,7 @@ int main( int argc, char **argv ) {
UE[CC_id]->UE_scan = UE_scan;
UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
+ UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
UE[CC_id]->mode = mode;
printf("UE[%d]->mode = %d\n",CC_id,mode);
diff --git a/targets/RT/USER/nr-uesoftmodem.h b/targets/RT/USER/nr-uesoftmodem.h
index 816e753086..7f96480b2b 100644
--- a/targets/RT/USER/nr-uesoftmodem.h
+++ b/targets/RT/USER/nr-uesoftmodem.h
@@ -55,6 +55,7 @@
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
+#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
@@ -135,6 +136,7 @@
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
+{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
{"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \
{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \