Commit bad87bd1 authored by Guy De Souza's avatar Guy De Souza

Merge remote-tracking branch 'origin/develop-nr' into nr_pdcch_updates

parents bb398adb f7583ef4
...@@ -212,7 +212,7 @@ pipeline { ...@@ -212,7 +212,7 @@ pipeline {
steps { steps {
gitlabCommitStatus(name: "Build eNb-ethernet") { gitlabCommitStatus(name: "Build eNb-ethernet") {
timeout (time: 20, unit: 'MINUTES') { 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 { ...@@ -221,7 +221,7 @@ pipeline {
steps { steps {
gitlabCommitStatus(name: "Build UE-ethernet") { gitlabCommitStatus(name: "Build UE-ethernet") {
timeout (time: 20, unit: 'MINUTES') { 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}"
} }
} }
} }
......
...@@ -94,14 +94,21 @@ function build_on_vm { ...@@ -94,14 +94,21 @@ function build_on_vm {
echo "############################################################" echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################" echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml
fi echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
release_vm_create_lock
else
echo "Waiting for VM to be started" echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME` VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR" echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
fi
echo "############################################################" echo "############################################################"
echo "Copying GIT repo into VM ($VM_NAME)" echo "Copying GIT repo into VM ($VM_NAME)"
......
...@@ -49,6 +49,35 @@ function create_usage { ...@@ -49,6 +49,35 @@ function create_usage {
echo "" echo ""
} }
function acquire_vm_create_lock {
local FlockFile="/tmp/vmclone.lck"
local unlocked="0"
touch ${FlockFile} 2>/dev/null
if [[ $? -ne 0 ]]
then
echo "Cannot access lock file ${FlockFile}"
exit 2
fi
while [ $unlocked -eq 0 ]
do
exec 5>${FlockFile}
flock -nx 5
if [[ $? -ne 0 ]]
then
echo "Another instance of VM creation is running"
sleep 10
else
unlocked="1"
fi
done
chmod 666 ${FlockFile} 2>/dev/null
}
function release_vm_create_lock {
local FlockFile="/tmp/vmclone.lck"
rm -Rf ${FlockFile}
}
function create_vm { function create_vm {
echo "############################################################" echo "############################################################"
echo "OAI CI VM script" echo "OAI CI VM script"
...@@ -60,10 +89,12 @@ function create_vm { ...@@ -60,10 +89,12 @@ function create_vm {
echo "############################################################" echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################" echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml
echo "Waiting for VM to be started" echo "Waiting for VM to be started"
uvt-kvm wait $VM_NAME --insecure uvt-kvm wait $VM_NAME --insecure
VM_IP_ADDR=`uvt-kvm ip $VM_NAME` VM_IP_ADDR=`uvt-kvm ip $VM_NAME`
echo "$VM_NAME has for IP addr = $VM_IP_ADDR" echo "$VM_NAME has for IP addr = $VM_IP_ADDR"
release_vm_create_lock
} }
...@@ -252,8 +252,9 @@ case $key in ...@@ -252,8 +252,9 @@ case $key in
VM_NAME=ci-phy-sim VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=7 NB_PATTERN_FILES=8
BUILD_OPTIONS="--phy_simulators" BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256] NBARGS=$[$NBARGS+256]
shift shift
...@@ -330,8 +331,9 @@ case $key in ...@@ -330,8 +331,9 @@ case $key in
VM_NAME=ci-phy-sim VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=7 NB_PATTERN_FILES=8
BUILD_OPTIONS="--phy_simulators" BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256] NBARGS=$[$NBARGS+256]
;; ;;
......
...@@ -441,10 +441,16 @@ function run_test_on_vm { ...@@ -441,10 +441,16 @@ function run_test_on_vm {
echo "############################################################" echo "############################################################"
echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base" echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################" echo "############################################################"
acquire_vm_create_lock
uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching
echo "Waiting for VM to be started"
uvt-kvm wait $EPC_VM_NAME --insecure
release_vm_create_lock
else
echo "Waiting for VM to be started"
uvt-kvm wait $EPC_VM_NAME --insecure
fi fi
uvt-kvm wait $EPC_VM_NAME --insecure
EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR" echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
......
...@@ -165,6 +165,10 @@ function check_on_vm_build { ...@@ -165,6 +165,10 @@ function check_on_vm_build {
fi fi
done 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
} }
...@@ -1057,26 +1057,65 @@ ...@@ -1057,26 +1057,65 @@
(Test2: PBCH and synchronization, 106PBR), (Test2: PBCH and synchronization, 106PBR),
(Test3: PBCH-only, 217 PRB), (Test3: PBCH-only, 217 PRB),
(Test4: PBCH and synchronization, 217 RPB), (Test4: PBCH and synchronization, 217 RPB),
(Test5: PBCH-only, 217 PRB), (Test5: PBCH-only, 273 PRB),
(Test6: PBCH and synchronization, 217 PRB)</desc> (Test6: PBCH and synchronization, 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog> <pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args> <compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args> <pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_pbchsim.Rel15</main_exec> <main_exec> $OPENAIR_DIR/targets/bin/nr_pbchsim.Rel15</main_exec>
<main_exec_args>-s-11 -S-10 -n1000 -R106 <main_exec_args>-s0 -S1 -n1000 -R106
-s-11 -S-10 -n10 -I -R106 -s0 -S1 -n10 -I -R106
-s-11 -S-10 -n1000 -R217 -N10 -s0 -S1 -n1000 -R217
-s-11 -S-10 -n10 -I -R217 -N10 -s0 -S1 -n10 -I -R217
-s-11 -S-10 -n1000 -R273 -N20 -s0 -S1 -n1000 -R273
-s-11 -S-10 -n10 -I -R273 -N20</main_exec_args> -s0 -S1 -n10 -I -R273</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2</tags> <tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6</tags>
<search_expr_true>PBCH test OK</search_expr_true> <search_expr_true>PBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns> <nruns>3</nruns>
</testCase> </testCase>
<testCase id="015105">
<class>execution</class>
<desc>nr_dlsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15</main_exec>
<main_exec_args>-n100 -R106
-n100 -R217
-n100 -R273</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3</tags>
<search_expr_true>PDCCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015106">
<class>execution</class>
<desc>nr_dlschsim Test cases. (Test1: 106 PRB),
(Test2: 217 PRB),
(Test3: 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/nr_dlschsim.Rel15</main_exec>
<main_exec_args>-R 106 -m9 -s13 -n100
-R 217 -m15 -s15 -n100
-R 273 -m19 -s20 -n100</main_exec_args>
<tags>nr_dlschsim.test1 nr_dlschsim.test2 nr_dlschsim.test3</tags>
<search_expr_true>PDSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015110"> <testCase id="015110">
<class>execution</class> <class>execution</class>
......
...@@ -696,7 +696,7 @@ function main() { ...@@ -696,7 +696,7 @@ function main() {
echo_info "Compiling unitary tests simulators" echo_info "Compiling unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim 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 for f in $simlist ; do
compilations \ compilations \
phy_simulators $f \ phy_simulators $f \
......
...@@ -467,33 +467,26 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f); ...@@ -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); 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, int nr_rate_matching_ldpc(uint8_t Ilbrm,
uint32_t Tbslbrm, uint32_t Tbslbrm,
uint8_t BG, uint8_t BG,
uint16_t Z, uint16_t Z,
uint32_t G,
uint8_t *w, uint8_t *w,
uint8_t *e, uint8_t *e,
uint8_t C, uint8_t C,
uint8_t rvidx, uint8_t rvidx,
uint8_t Qm, uint32_t E);
uint8_t Nl,
uint8_t r);
int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
uint32_t Tbslbrm, uint32_t Tbslbrm,
uint8_t BG, uint8_t BG,
uint16_t Z, uint16_t Z,
uint32_t G,
int16_t *w, int16_t *w,
int16_t *soft_input, int16_t *soft_input,
uint8_t C, uint8_t C,
uint8_t rvidx, uint8_t rvidx,
uint8_t clear, uint8_t clear,
uint8_t Qm, uint32_t E);
uint8_t Nl,
uint8_t r,
uint32_t *E_out);
decoder_if_t phy_threegpplte_turbo_decoder; decoder_if_t phy_threegpplte_turbo_decoder;
decoder_if_t phy_threegpplte_turbo_decoder8; decoder_if_t phy_threegpplte_turbo_decoder8;
......
...@@ -63,25 +63,22 @@ void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) ...@@ -63,25 +63,22 @@ 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, int nr_rate_matching_ldpc(uint8_t Ilbrm,
uint32_t Tbslbrm, uint32_t Tbslbrm,
uint8_t BG, uint8_t BG,
uint16_t Z, uint16_t Z,
uint32_t G,
uint8_t *w, uint8_t *w,
uint8_t *e, uint8_t *e,
uint8_t C, uint8_t C,
uint8_t rvidx, uint8_t rvidx,
uint8_t Qm, uint32_t E)
uint8_t Nl,
uint8_t r)
{ {
uint8_t Cprime; uint32_t Ncb,ind,k,Nref,N;
uint32_t Ncb,E,ind,k,Nref,N;
//uint8_t *e2;
AssertFatal(Nl>0,"Nl is 0\n"); if (C==0) {
AssertFatal(Qm>0,"Qm is 0\n"); printf("nr_rate_matching: invalid parameters (C %d\n",C);
return -1;
}
//Bit selection //Bit selection
N = (BG==1)?(66*Z):(50*Z); N = (BG==1)?(66*Z):(50*Z);
...@@ -93,25 +90,12 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm, ...@@ -93,25 +90,12 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
Ncb = min(N, Nref); 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; ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG #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 #endif
//e2 = e;
k=0; k=0;
for (; (ind<Ncb)&&(k<E); ind++) { for (; (ind<Ncb)&&(k<E); ind++) {
...@@ -120,7 +104,6 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm, ...@@ -120,7 +104,6 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]); printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif #endif
//if (w[ind] != NR_NULL) e2[k++]=w[ind];
if (w[ind] != NR_NULL) e[k++]=w[ind]; if (w[ind] != NR_NULL) e[k++]=w[ind];
} }
...@@ -131,47 +114,36 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm, ...@@ -131,47 +114,36 @@ uint32_t nr_rate_matching_ldpc(uint8_t Ilbrm,
printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]); printf("RM_TX k%d Ind: %d (%d)\n",k,ind,w[ind]);
#endif #endif
//if (w[ind] != NR_NULL) e2[k++]=w[ind];
if (w[ind] != NR_NULL) e[k++]=w[ind]; if (w[ind] != NR_NULL) e[k++]=w[ind];
} }
} }
return(E); return 0;
} }
int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
uint32_t Tbslbrm, uint32_t Tbslbrm,
uint8_t BG, uint8_t BG,
uint16_t Z, uint16_t Z,
uint32_t G,
int16_t *w, int16_t *w,
int16_t *soft_input, int16_t *soft_input,
uint8_t C, uint8_t C,
uint8_t rvidx, uint8_t rvidx,
uint8_t clear, uint8_t clear,
uint8_t Qm, uint32_t E)
uint8_t Nl,
uint8_t r,
uint32_t *E_out)
{ {
uint8_t Cprime; uint32_t Ncb,ind,k,Nref,N;
uint32_t Ncb,E,ind,k,Nref,N;
int16_t *soft_input2;
#ifdef RM_DEBUG #ifdef RM_DEBUG
int nulled=0; int nulled=0;
#endif #endif
if (C==0 || Qm==0 || Nl==0) { if (C==0) {
printf("nr_rate_matching: invalid parameters (C %d, Qm %d, Nl %d\n",C,Qm,Nl); printf("nr_rate_matching: invalid parameters (C %d\n",C);
return(-1); return -1;
} }
AssertFatal(Nl>0,"Nl is 0\n");
AssertFatal(Qm>0,"Qm is 0\n");
//Bit selection //Bit selection
N = (BG==1)?(66*Z):(50*Z); N = (BG==1)?(66*Z):(50*Z);
...@@ -182,28 +154,20 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, ...@@ -182,28 +154,20 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
Ncb = min(N, Nref); 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; ind = (index_k0[BG-1][rvidx]*Ncb/N)*Z;
#ifdef RM_DEBUG #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 #endif
if (clear==1) if (clear==1)
memset(w,0,Ncb*sizeof(int16_t)); memset(w,0,Ncb*sizeof(int16_t));
soft_input2 = soft_input;
k=0; k=0;
for (; (ind<Ncb)&&(k<E); ind++) { for (; (ind<Ncb)&&(k<E); ind++) {
if (soft_input2[ind] != NR_NULL) { if (soft_input[ind] != NR_NULL) {
w[ind] += soft_input2[k++]; w[ind] += soft_input[k++];
#ifdef RM_DEBUG #ifdef RM_DEBUG
printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]);
#endif #endif
...@@ -220,10 +184,10 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, ...@@ -220,10 +184,10 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
while(k<E) { while(k<E) {
for (ind=0; (ind<Ncb)&&(k<E); ind++) { for (ind=0; (ind<Ncb)&&(k<E); ind++) {
if (soft_input2[ind] != NR_NULL) { if (soft_input[ind] != NR_NULL) {
w[ind] += soft_input2[k++]; w[ind] += soft_input[k++];
#ifdef RM_DEBUG #ifdef RM_DEBUG
printf("RM_RX k%d Ind: %d (%d)(soft in %d)\n",k-1,ind,w[ind],soft_input2[k-1]); printf("RM_RX k%d Ind: %d (%d)(soft in %d)\n",k-1,ind,w[ind],soft_input[k-1]);
#endif #endif
} }
...@@ -237,7 +201,5 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm, ...@@ -237,7 +201,5 @@ int nr_rate_matching_ldpc_rx(uint8_t Ilbrm,
} }
} }
*E_out = E; return 0;
return(0);
} }
...@@ -56,11 +56,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -56,11 +56,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
unsigned int rx_offset; unsigned int rx_offset;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns]][0]; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[Ns]][0];
uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset;//+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB; uint16_t coreset_start_subcarrier = frame_parms->first_carrier_offset;//+((int)floor(frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB)+pdcch_vars->coreset[0].rb_offset)*NR_NB_SC_PER_RB;
uint16_t nb_rb_coreset = 24; uint16_t nb_rb_coreset = 0;
uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;//+516; uint16_t bwp_start_subcarrier = frame_parms->first_carrier_offset;//+516;
uint16_t nb_rb_pdsch = 50; uint16_t nb_rb_pdsch = 50;
uint8_t p=0; uint8_t p=0;
uint8_t l0 = 2; uint8_t l0 = pdcch_vars->coreset[0].duration;
uint64_t coreset_freq_dom = pdcch_vars->coreset[0].frequencyDomainResources;
for (int i = 0; i < 45; i++) {
if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> i) & 0x1) nb_rb_coreset++;
}
nb_rb_coreset = 6 * nb_rb_coreset;
//printf("corset duration %d nb_rb_coreset %d\n", l0, nb_rb_coreset);
void (*dft)(int16_t *,int16_t *, int); void (*dft)(int16_t *,int16_t *, int);
int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs int tmp_dft_in[8192] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
......
...@@ -137,7 +137,9 @@ int set_pss_nr(int ofdm_symbol_size); ...@@ -137,7 +137,9 @@ int set_pss_nr(int ofdm_symbol_size);
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change); int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change);
int pss_search_time_nr(int **rxdata, ///rx data in time domain int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int *eNB_id); int fo_flag,
int *eNB_id,
int *f_off);
#endif #endif
#undef EXTERN #undef EXTERN
......
...@@ -90,6 +90,8 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch, ...@@ -90,6 +90,8 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch,
@param nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs */ @param nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs */
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm, uint8_t Nl); uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm, uint8_t Nl);
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
......
...@@ -280,7 +280,7 @@ int nr_dlsch_encoding(unsigned char *a, ...@@ -280,7 +280,7 @@ int nr_dlsch_encoding(unsigned char *a,
uint32_t A, Z; uint32_t A, Z;
uint32_t *pz = &Z; uint32_t *pz = &Z;
uint8_t mod_order = rel15.modulation_order; uint8_t mod_order = rel15.modulation_order;
uint16_t Kr=0,r,r_offset=0;//Kr_bytes uint16_t Kr=0,r,r_offset=0,Kr_bytes;
uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t kb,BG=1; uint8_t kb,BG=1;
uint32_t E; uint32_t E;
...@@ -346,7 +346,7 @@ int nr_dlsch_encoding(unsigned char *a, ...@@ -346,7 +346,7 @@ int nr_dlsch_encoding(unsigned char *a,
} }
Kr = dlsch->harq_processes[harq_pid]->K; Kr = dlsch->harq_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); //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, ...@@ -403,25 +403,24 @@ int nr_dlsch_encoding(unsigned char *a,
//start_meas(rm_stats); //start_meas(rm_stats);
#ifdef DEBUG_DLSCH_CODING #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 #endif
E = nr_rate_matching_ldpc(Ilbrm, E = nr_get_E(G, dlsch->harq_processes[harq_pid]->C, mod_order, rel15.nb_layers, r);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm, Tbslbrm,
BG, BG,
*pz, *pz,
G,
dlsch->harq_processes[harq_pid]->d[r], dlsch->harq_processes[harq_pid]->d[r],
dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->e+r_offset,
dlsch->harq_processes[harq_pid]->C, dlsch->harq_processes[harq_pid]->C,
rel15.redundancy_version, rel15.redundancy_version,
mod_order, E);
rel15.nb_layers,
r);
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++) 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 #endif
//stop_meas(rm_stats); //stop_meas(rm_stats);
...@@ -432,18 +431,15 @@ int nr_dlsch_encoding(unsigned char *a, ...@@ -432,18 +431,15 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->f+r_offset); dlsch->harq_processes[harq_pid]->f+r_offset);
//stop_meas(i_stats); //stop_meas(i_stats);
r_offset += E;
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++) 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); printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
#endif
#ifdef DEBUG_DLSCH_CODING
if (r==dlsch->harq_processes[harq_pid]->C-1) 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 #endif
r_offset += E;
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
......
...@@ -176,3 +176,18 @@ uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16 ...@@ -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; G = ((NR_NB_SC_PER_RB*nb_symb_sch)-(nb_re_dmrs*length_dmrs))*nb_rb*Qm*Nl;
return(G); 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;
}
...@@ -821,8 +821,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, ...@@ -821,8 +821,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
#ifdef NR_PDCCH_DCI_DEBUG #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)-> 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", 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); coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id);
#endif #endif
// //
......
...@@ -376,6 +376,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -376,6 +376,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
for (r=0; r<harq_process->C; r++) { for (r=0; r<harq_process->C; r++) {
//printf("start rx segment %d\n",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 #if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats); start_meas(dlsch_rate_unmatching_stats);
...@@ -397,17 +413,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -397,17 +413,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
Tbslbrm, Tbslbrm,
p_decParams->BG, p_decParams->BG,
p_decParams->Z, p_decParams->Z,
G, harq_process->d[r],
harq_process->w[r], harq_process->w[r],
dlsch_llr+r_offset,
harq_process->C, harq_process->C,
harq_process->rvidx, harq_process->rvidx,
(harq_process->round==0)?1:0, (harq_process->round==0)?1:0,
harq_process->Qm, E)==-1) {
harq_process->Nl,
r,
&E)==-1) {
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -419,27 +430,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -419,27 +430,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
} }
r_offset += E;
//for (int i =0; i<16; i++) //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);
#if UE_TIMING_TRACE r_offset += E;
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 #ifdef DEBUG_DLSCH_DECODING
if (r==0) { if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,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); 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 ...@@ -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); 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 #if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats); start_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -995,23 +1016,16 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment ...@@ -995,23 +1016,16 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
harq_process->round); harq_process->round);
#endif #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, if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm, Tbslbrm,
p_decParams->BG, p_decParams->BG,
p_decParams->Z, p_decParams->Z,
G, harq_process->d[r],
harq_process->w[r], harq_process->w[r],
dlsch_llr+r_offset,
harq_process->C, harq_process->C,
harq_process->rvidx, harq_process->rvidx,
(harq_process->round==0)?1:0, (harq_process->round==0)?1:0,
harq_process->Qm, E)==-1) {
harq_process->Nl,
r,
&E)==-1) {
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -1023,34 +1037,18 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment ...@@ -1023,34 +1037,18 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #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; //r_offset += E;
//printf("main thread r_offset %d\n",r_offset); //printf("main thread r_offset %d\n",r_offset);
#ifdef DEBUG_DLSCH_DECODING #ifdef DEBUG_DLSCH_DECODING
for (int i =0; i<16; i++) 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 #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 #ifdef DEBUG_DLSCH_DECODING
if (r==0) { if (r==0) {
...@@ -1526,6 +1524,23 @@ void *nr_dlsch_decoding_2thread0(void *arg) ...@@ -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); 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 #if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats); start_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -1542,23 +1557,16 @@ void *nr_dlsch_decoding_2thread0(void *arg) ...@@ -1542,23 +1557,16 @@ void *nr_dlsch_decoding_2thread0(void *arg)
harq_process->round); harq_process->round);
#endif #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, if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm, Tbslbrm,
p_decParams->BG, p_decParams->BG,
p_decParams->Z, p_decParams->Z,
G, harq_process->d[r],
harq_process->w[r], harq_process->w[r],
dlsch_llr+r_offset,
harq_process->C, harq_process->C,
harq_process->rvidx, harq_process->rvidx,
(harq_process->round==0)?1:0, (harq_process->round==0)?1:0,
harq_process->Qm, E)==-1) {
harq_process->Nl,
r,
&E)==-1) {
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -1570,23 +1578,13 @@ void *nr_dlsch_decoding_2thread0(void *arg) ...@@ -1570,23 +1578,13 @@ void *nr_dlsch_decoding_2thread0(void *arg)
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
} }
//r_offset += E;
//for (int i =0; i<16; i++) //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);
#if UE_TIMING_TRACE //r_offset += E;
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
#ifdef DEBUG_DLSCH_DECODING
if (r==0) { if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,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); 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) ...@@ -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); 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 #if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats); start_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -2059,23 +2079,16 @@ void *nr_dlsch_decoding_2thread1(void *arg) ...@@ -2059,23 +2079,16 @@ void *nr_dlsch_decoding_2thread1(void *arg)
harq_process->round); harq_process->round);
#endif #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, if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm, Tbslbrm,
p_decParams->BG, p_decParams->BG,
p_decParams->Z, p_decParams->Z,
G, harq_process->d[r],
harq_process->w[r], harq_process->w[r],
dlsch_llr+r_offset,
harq_process->C, harq_process->C,
harq_process->rvidx, harq_process->rvidx,
(harq_process->round==0)?1:0, (harq_process->round==0)?1:0,
harq_process->Qm, E)==-1) {
harq_process->Nl,
r,
&E)==-1) {
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #endif
...@@ -2087,23 +2100,12 @@ void *nr_dlsch_decoding_2thread1(void *arg) ...@@ -2087,23 +2100,12 @@ void *nr_dlsch_decoding_2thread1(void *arg)
stop_meas(dlsch_rate_unmatching_stats); stop_meas(dlsch_rate_unmatching_stats);
#endif #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; //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 #ifdef DEBUG_DLSCH_DECODING
if (r==0) { if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
//#include "SCHED/extern.h" //#include "SCHED/extern.h"
#include "common_lib.h" #include "common_lib.h"
#include <math.h>
#include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/pss_nr.h"
#include "PHY/NR_REFSIG/sss_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) ...@@ -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; NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int ret =-1; int ret =-1;
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id, LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
ue->rx_offset); ue->rx_offset);
...@@ -65,6 +67,7 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -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; int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples; frame_parms->nb_prefix_samples0 = frame_parms->nb_prefix_samples;
//symbol 1 //symbol 1
nr_slot_fep(ue, nr_slot_fep(ue,
1, 1,
...@@ -143,6 +146,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -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 sync_pos, sync_pos_slot; // k_ssb, N_ssb_crb, sync_pos2,
int32_t metric_tdd_ncp=0; int32_t metric_tdd_ncp=0;
uint8_t phase_tdd_ncp; uint8_t phase_tdd_ncp;
double im, re;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
int ret=-1; int ret=-1;
...@@ -198,6 +202,25 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -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); LOG_I(PHY,"sync_pos %d ssb_offset %d sync_pos_slot %d \n",sync_pos,ue->ssb_offset,sync_pos_slot);
#endif #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; n<end; n++){
for (int ar=0; ar<fp->nb_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 */ /* 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))) { 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) ...@@ -244,7 +267,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
ret = -1; 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) ) if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
{ {
ret=-1; ret=-1;
...@@ -253,7 +277,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) ...@@ -253,7 +277,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
#else #else
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset); LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
#endif #endif
} }*/
if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters 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) ...@@ -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", printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id, ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx, 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); ue->common_vars.freq_offset);
# else # else
LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id, ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx, 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); ue->common_vars.freq_offset);
# endif # endif
#endif #endif
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <math.h>
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
...@@ -662,6 +663,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) ...@@ -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); NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int synchro_position; int synchro_position;
int **rxdata = NULL; int **rxdata = NULL;
int fo_flag = PHY_vars_UE->UE_fo_compensation; // flag to enable freq offset estimation and compensation
#ifdef DBG_PSS_NR #ifdef DBG_PSS_NR
...@@ -705,7 +707,10 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change) ...@@ -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, synchro_position = pss_search_time_nr(rxdata,
frame_parms, 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 #if TEST_SYNCHRO_TIMING_PSS
...@@ -751,6 +756,15 @@ static inline int64_t abs64(int64_t x) ...@@ -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])); 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 * NAME : pss_search_time_nr
...@@ -803,47 +817,28 @@ static inline int64_t abs64(int64_t x) ...@@ -803,47 +817,28 @@ static inline int64_t abs64(int64_t x)
#define DOT_PRODUCT_SCALING_SHIFT (17) #define DOT_PRODUCT_SCALING_SHIFT (17)
int max3(int64_t a, int64_t b, int64_t c) {
if (a>b) {
if (a>c) {
return(0);
}
else {
return(2);
}
}
else {
if (b>c) {
return(1);
}
else {
return(2);
}
}
}
int pss_search_time_nr(int **rxdata, ///rx data in time domain int pss_search_time_nr(int **rxdata, ///rx data in time domain
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int *eNB_id) int fo_flag,
int *eNB_id,
int *f_off)
{ {
uint8_t L_max = 4; unsigned int n, ar, peak_position, pss_source;
unsigned int m, n, ar, n_peaks=0; int64_t peak_value;
unsigned int peak_position[3*L_max], pss_source[3*L_max];
int64_t peak_value, threshold;
int64_t result; int64_t result;
int64_t avg[NUMBER_PSS_SEQUENCE]; int64_t avg[NUMBER_PSS_SEQUENCE];
uint8_t found_peak=0; 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 */ unsigned int length = (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); /* 1 frame for now, it should be 2 TODO_NR */
AssertFatal(length>0,"illegal length %d\n",length); AssertFatal(length>0,"illegal length %d\n",length);
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i); for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
for (int i=0;i<4;i++) {
peak_position[i] = length; //max possible value peak_value = 0;
pss_source[i] = 0; peak_position = 0;
} pss_source = 0;
int maxval=0; int maxval=0;
for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) { for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
...@@ -853,7 +848,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -853,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[1][i]);
maxval = max(maxval,primary_synchro_time_nr[2][i]); maxval = max(maxval,primary_synchro_time_nr[2][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); int shift = log2_approx(maxval);//*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*2);
...@@ -866,10 +860,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -866,10 +860,10 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
memset(pss_corr_ue[pss_index],0,length*sizeof(int64_t)); memset(pss_corr_ue[pss_index],0,length*sizeof(int64_t));
} }
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
for (n=0; n < length; n+=4) { // for (n=0; n < length; n+=4) { //
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
if ( n < (length - frame_parms->ofdm_symbol_size)) { if ( n < (length - frame_parms->ofdm_symbol_size)) {
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */ /* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */
...@@ -881,7 +875,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -881,7 +875,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
shift); shift);
pss_corr_ue[pss_index][n] += abs64(result); 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] += ((short*) &result)[0]; /* real part */
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */ //((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */ //((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
...@@ -892,40 +885,61 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -892,40 +885,61 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
/* calculate the absolute value of sync_corr[n] */ /* calculate the absolute value of sync_corr[n] */
avg[pss_index]+=pss_corr_ue[pss_index][n]; avg[pss_index]+=pss_corr_ue[pss_index][n];
} if (pss_corr_ue[pss_index][n] > peak_value) {
peak_value = pss_corr_ue[pss_index][n];
peak_position = n;
pss_source = pss_index;
avg[pss_index]/=(length/4); #ifdef DEBUG_PSS_NR
printf("pss_index %d: n %6d peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]);
#endif
}
}
} }
threshold = 10*avg[max3(avg[0],avg[1],avg[2])]; if (fo_flag){
peak_value = threshold; // 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.
for (n=0; n < length; n+=4) { 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);
m = max3(pss_corr_ue[0][n],pss_corr_ue[1][n],pss_corr_ue[2][n]); int64_t re1,re2,im1,im2;
re1=((int*) &result1)[0];
re2=((int*) &result2)[0];
im1=((int*) &result1)[1];
im2=((int*) &result2)[1];
if (pss_corr_ue[m][n] > peak_value) { // estimation of fractional frequency offset: angle[(result1)'*(result2)]/pi
peak_value = pss_corr_ue[m][n]; ffo_est=atan2(re1*im2-re2*im1,re1*re2+im1*im2)/M_PI;
peak_position[n_peaks] = n;
pss_source[n_peaks] = m;
found_peak = 1;
}
if ((peak_position[n_peaks]+4*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)<n) && #ifdef DBG_PSS_NR
(found_peak==1)) { printf("ffo %lf\n",ffo_est);
//#ifdef DEBUG_PSS_NR #endif
printf("peak %d found at pss_index %d, n %6d, peak_value %15llu\n", n_peaks, pss_source[n_peaks], peak_position[n_peaks], (unsigned long long)pss_corr_ue[ pss_source[n_peaks]][peak_position[n_peaks]]);
//#endif
peak_value = threshold;
found_peak = 0;
n_peaks++;
//if (n_peaks==L_max) break;
}
} }
*eNB_id = pss_source[0]; // 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, 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);
//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]));
#ifdef DBG_PSS_NR #ifdef DBG_PSS_NR
...@@ -942,6 +956,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain ...@@ -942,6 +956,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
#endif #endif
return(peak_position[0]); return(peak_position);
} }
...@@ -56,7 +56,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n ...@@ -56,7 +56,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n
int nr_tti_tx, int nr_tti_tx,
uint8_t *u, uint8_t *u,
uint8_t *v) { uint8_t *v) {
/* /*
* Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping
* The following variables are set by higher layers: * The following variables are set by higher layers:
* - PUCCH_GroupHopping: * - PUCCH_GroupHopping:
...@@ -75,43 +75,66 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n ...@@ -75,43 +75,66 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n
// Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled // Cell-Specific scrambling ID for group hoppping and sequence hopping if enabled
// Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10)) // Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) BIT STRING (SIZE (10))
uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!! uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!!
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
// initialization to be removed // initialization to be removed
PUCCH_GroupHopping=neither; PUCCH_GroupHopping=neither;
n_id=10; n_id=10;
printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%d, n_id=%d -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id); printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%d, n_id=%d -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id);
#endif #endif
uint8_t f_ss=0,f_gh=0; uint8_t f_ss=0,f_gh=0;
*u=0; *u=0;
*v=0; *v=0;
uint32_t c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v uint32_t c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v
uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
#ifdef DEBUG_NR_PUCCH_TX int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3);
int tmpShift =0;
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); printf("\t\t [nr_group_sequence_hopping] calculating u,v -> ");
#endif #endif
if (PUCCH_GroupHopping == neither){ // PUCCH_GroupHopping 'neither' if (PUCCH_GroupHopping == neither) { // PUCCH_GroupHopping 'neither'
f_ss = n_id%30; f_ss = n_id%30;
} }
if (PUCCH_GroupHopping == enable){ // PUCCH_GroupHopping 'enabled'
for (int m=0; m<8; m++){ if (PUCCH_GroupHopping == enable) { // PUCCH_GroupHopping 'enabled'
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!! for (int m=0; m<8; m++) {
while(minShift >= l) {
s = lte_gold_generic(&x1, &c_init, 0);
l = l+32;
} }
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>tmpShift)&1)));
minShift ++;
}
f_gh = f_gh%30; f_gh = f_gh%30;
f_ss = n_id%30; f_ss = n_id%30;
/* for (int m=0; m<8; m++){
f_gh = f_gh + ((1<<m)*((uint8_t)((s>>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!!
}
f_gh = f_gh%30;
f_ss = n_id%30;*/
} }
if (PUCCH_GroupHopping == disable){ // PUCCH_GroupHopping 'disabled'
if (PUCCH_GroupHopping == disable) { // PUCCH_GroupHopping 'disabled'
f_ss = n_id%30; f_ss = n_id%30;
*v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!! l = 32, minShift = (2*nr_tti_tx+n_hop);
while(minShift >= l) {
s = lte_gold_generic(&x1, &c_init, 0);
l = l+32;
} }
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
*v = (uint8_t)((s>>tmpShift)&1);
// *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!!
}
*u = (f_gh+f_ss)%30; *u = (f_gh+f_ss)%30;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("%d,%d\n",*u,*v); printf("%d,%d\n",*u,*v);
#endif #endif
} }
double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
...@@ -120,7 +143,7 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, ...@@ -120,7 +143,7 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
uint8_t lnormal, uint8_t lnormal,
uint8_t lprime, uint8_t lprime,
int nr_tti_tx) { int nr_tti_tx) {
/* /*
* Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping
* - n_id: higher-layer parameter hoppingId * - n_id: higher-layer parameter hoppingId
* - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config * - m0: provided by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift of PUCCH-F0-resource-config
...@@ -131,26 +154,36 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue, ...@@ -131,26 +154,36 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
// alpha_init initialized to 2*PI/12=0.5235987756 // alpha_init initialized to 2*PI/12=0.5235987756
double alpha = 0.5235987756; double alpha = 0.5235987756;
uint32_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs uint32_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX // initialization to be remo.ved
// initialization to be removed
c_init=10; c_init=10;
printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init); printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init);
#endif #endif
uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
uint8_t n_cs=0; uint8_t n_cs=0;
#ifdef DEBUG_NR_PUCCH_TX int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime);
printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%d -> ",c_init); int tmpShift =0;
#endif #ifdef DEBUG_NR_PUCCH_TX
for (int m=0; m<8; m++){ printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%d -> \n",c_init);
#endif
for (int m=0; m<8; m++) {
while(minShift >= l) {
s = lte_gold_generic(&x1, &c_init, 0);
l = l+32;
}
tmpShift = (minShift&((1<<5)-1)); //minShift%32;
minShift ++;
n_cs = n_cs+((1<<m)*((uint8_t)((s>>tmpShift)&1)));
// calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!) // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!)
n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1))); // n_cs = n_cs+((1<<m)*((uint8_t)((s>>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1)));
} }
alpha = (alpha * (double)((m0+mcs+n_cs)%12)); alpha = (alpha * (double)((m0+mcs+n_cs)%12));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("n_cs=%d -> %lf\n",n_cs,alpha); printf("n_cs=%d -> %lf\n",n_cs,alpha);
#endif #endif
return(alpha); return(alpha);
} }
void nr_generate_pucch0(PHY_VARS_NR_UE *ue, void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
...@@ -164,18 +197,16 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, ...@@ -164,18 +197,16 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
uint8_t nrofSymbols, uint8_t nrofSymbols,
uint8_t startingSymbolIndex, uint8_t startingSymbolIndex,
uint16_t startingPRB) { uint16_t startingPRB) {
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx); printf("\t [nr_generate_pucch0] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx);
#endif #endif
/* /*
* Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation
* *
*/ */
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation\n"); printf("\t [nr_generate_pucch0] sequence generation\n");
#endif #endif
/* /*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/ */
...@@ -187,13 +218,11 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, ...@@ -187,13 +218,11 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
//uint8_t lprime; //uint8_t lprime;
// mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME!
//uint8_t mcs; //uint8_t mcs;
/* /*
* in TS 38.213 Subclause 9.2.1 it is said that: * in TS 38.213 Subclause 9.2.1 it is said that:
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift
* is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/ */
/* /*
* Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to: * Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to:
* x(l*12+n) = r_u_v_alpha_delta(n) * x(l*12+n) = r_u_v_alpha_delta(n)
...@@ -207,70 +236,78 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, ...@@ -207,70 +236,78 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
// n_hop = 1 for second hop // n_hop = 1 for second hop
uint8_t n_hop = 0; uint8_t n_hop = 0;
//uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!! //uint8_t PUCCH_Frequency_Hopping; // from higher layers FIXME!!
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation: variable initialization for test\n"); printf("\t [nr_generate_pucch0] sequence generation: variable initialization for test\n");
#endif #endif
// x_n contains the sequence r_u_v_alpha_delta(n) // x_n contains the sequence r_u_v_alpha_delta(n)
int16_t x_n_re[24],x_n_im[24]; int16_t x_n_re[24],x_n_im[24];
// we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2 // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2
for (int l=0; l<nrofSymbols; l++){ for (int l=0; l<nrofSymbols; l++) {
// if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!! // if frequency hopping is enabled n_hop = 1 for second hop. Not sure frequency hopping concerns format 0. FIXME!!!
// if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1; // if ((PUCCH_Frequency_Hopping == 1)&&(l == (nrofSymbols-1))) n_hop = 1;
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx); alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l); printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u,v,alpha,l);
#endif #endif
for (int n=0; n<12; n++){
for (int n=0; n<12; n++) {
x_n_re[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) x_n_re[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha
x_n_im[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) x_n_im[(12*l)+n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
+ (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n",
u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]); u,v,alpha,l,n,x_n_re[(12*l)+n],x_n_im[(12*l)+n]);
#endif #endif
} }
} }
/* /*
* Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME!
*/ */
//int32_t *txptr; //int32_t *txptr;
uint32_t re_offset=0; uint32_t re_offset=0;
for (int l=0; l<nrofSymbols; l++) { for (int l=0; l<nrofSymbols; l++) {
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
} }
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
} }
if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
//txptr = &txdataF[0][re_offset]; //txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++){ for (int n=0; n<12; n++) {
if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
} }
((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15); ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)(((int32_t)(amp) * x_n_re[(12*l)+n])>>15);
((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15); ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)(((int32_t)(amp) * x_n_im[(12*l)+n])>>15);
//((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15; //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15;
//((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15; //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15;
//txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n]; //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
re_offset++; re_offset++;
} }
} }
...@@ -294,39 +331,43 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -294,39 +331,43 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
#endif #endif
/* /*
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
* *
*/ */
// complex-valued symbol d_re, d_im containing complex-valued symbol d(0): // complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
int16_t d_re=0, d_im=0; int16_t d_re=0, d_im=0;
if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
if (((payload&1)==0) && (((payload>>1)&1)==0)) { if (((payload&1)==0) && (((payload>>1)&1)==0)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==0) && (((payload>>1)&1)==1)) { if (((payload&1)==0) && (((payload>>1)&1)==1)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==1) && (((payload>>1)&1)==0)) { if (((payload&1)==1) && (((payload>>1)&1)==0)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==1) && (((payload>>1)&1)==1)) { if (((payload&1)==1) && (((payload>>1)&1)==1)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
} }
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
#endif
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
#endif
/* /*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/ */
...@@ -346,7 +387,6 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -346,7 +387,6 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift
* is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/ */
/* /*
* the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n)
*/ */
...@@ -363,37 +403,42 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -363,37 +403,42 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
// otherwise no intra-slot frequency hopping shall be assumed // otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
uint8_t intraSlotFrequencyHopping = 0; uint8_t intraSlotFrequencyHopping = 0;
if (startingPRB != startingPRB_intraSlotHopping){
if (startingPRB != startingPRB_intraSlotHopping) {
intraSlotFrequencyHopping=1; intraSlotFrequencyHopping=1;
} }
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping); printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping);
#endif #endif
/* /*
* Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources
*/ */
//int32_t *txptr; //int32_t *txptr;
uint32_t re_offset=0; uint32_t re_offset=0;
int i=0; int i=0;
#define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n #define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n
int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z]; int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z];
int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z]; int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z];
for (int l=0; l<nrofSymbols; l++) { for (int l=0; l<nrofSymbols; l++) {
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n", printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n",
l,lprime); l,lprime);
#endif #endif
// y_n contains the complex value d multiplied by the sequence r_u_v // y_n contains the complex value d multiplied by the sequence r_u_v
int16_t y_n_re[12],y_n_im[12]; int16_t y_n_re[12],y_n_im[12];
if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n",
n_hop,nr_tti_tx); n_hop,nr_tti_tx);
#endif #endif
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx); alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx);
for (int n=0; n<12; n++){
for (int n=0; n<12; n++) {
r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha
r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
...@@ -409,11 +454,12 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -409,11 +454,12 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
- (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
+ (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n)
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n",
u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]);
#endif #endif
} }
/* /*
* The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m) * The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m)
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
...@@ -439,67 +485,72 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -439,67 +485,72 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
uint8_t N_SF_mprime0_PUCCH_DMRS_1; uint8_t N_SF_mprime0_PUCCH_DMRS_1;
// mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping
uint8_t mprime = 0; uint8_t mprime = 0;
if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping disabled\n", printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping disabled\n",
intraSlotFrequencyHopping); intraSlotFrequencyHopping);
#endif #endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS)
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n",
w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1);
#endif #endif
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
for (int n=0; n<12 ; n++) {
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
} }
} }
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) {
for (int n=0; n<12 ; n++) {
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n",
mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
} }
} }
} }
if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping enabled\n", printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping enabled\n",
intraSlotFrequencyHopping); intraSlotFrequencyHopping);
#endif #endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n",
w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1);
#endif #endif
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){
for (mprime = 0; mprime<2; mprime++){ // mprime can get values {0,1} for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1}
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
for (int n=0; n<12 ; n++) {
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
...@@ -513,8 +564,9 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -513,8 +564,9 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
#endif #endif
} }
} }
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) {
for (int n=0; n<12 ; n++) {
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)
...@@ -528,57 +580,67 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue, ...@@ -528,57 +580,67 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
#endif #endif
} }
} }
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS)
} }
} }
} }
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
startingPRB = startingPRB + startingPRB_intraSlotHopping; startingPRB = startingPRB + startingPRB_intraSlotHopping;
} }
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
} }
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
} }
if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
//txptr = &txdataF[0][re_offset]; //txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++){ for (int n=0; n<12; n++) {
if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
} }
if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
re_offset++; re_offset++;
} }
if (l%2 == 1) i+=12; if (l%2 == 1) i+=12;
} }
} }
...@@ -602,39 +664,43 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -602,39 +664,43 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
#endif #endif
/* /*
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
* *
*/ */
// complex-valued symbol d_re, d_im containing complex-valued symbol d(0): // complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
int16_t d_re, d_im; int16_t d_re, d_im;
if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
if (((payload&1)==0) && (((payload>>1)&1)==0)) { if (((payload&1)==0) && (((payload>>1)&1)==0)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==0) && (((payload>>1)&1)==1)) { if (((payload&1)==0) && (((payload>>1)&1)==1)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==1) && (((payload>>1)&1)==0)) { if (((payload&1)==1) && (((payload>>1)&1)==0)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((payload&1)==1) && (((payload>>1)&1)==1)) { if (((payload&1)==1) && (((payload>>1)&1)==1)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
} }
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
#endif
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
#endif
/* /*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/ */
...@@ -654,7 +720,6 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -654,7 +720,6 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift
* is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/ */
/* /*
* the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n)
*/ */
...@@ -671,11 +736,12 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -671,11 +736,12 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
// otherwise no intra-slot frequency hopping shall be assumed // otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
uint8_t intraSlotFrequencyHopping = 0; uint8_t intraSlotFrequencyHopping = 0;
if (startingPRB != startingPRB_intraSlotHopping){
if (startingPRB != startingPRB_intraSlotHopping) {
intraSlotFrequencyHopping=1; intraSlotFrequencyHopping=1;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping); printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping);
#endif #endif
// n_hop = 1 for second hop; // n_hop = 1 for second hop;
// FIXME // FIXME
// When hopping will be activated we have to implement this function differently as PUCH signal generation depends on n_hop value for u,v calculation // When hopping will be activated we have to implement this function differently as PUCH signal generation depends on n_hop value for u,v calculation
...@@ -683,13 +749,14 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -683,13 +749,14 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
// y_n contains the complex value d multiplied by the sequence r_u_v // y_n contains the complex value d multiplied by the sequence r_u_v
int16_t y_n_re[12],y_n_im[12]; int16_t y_n_re[12],y_n_im[12];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n",
n_hop,nr_tti_tx); n_hop,nr_tti_tx);
#endif #endif
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,lnormal,lprime,nr_tti_tx); alpha = nr_cyclic_shift_hopping(ue,m0,mcs,lnormal,lprime,nr_tti_tx);
for (int n=0; n<12; n++){
for (int n=0; n<12; n++) {
r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha
r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
...@@ -702,11 +769,12 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -702,11 +769,12 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
// DM-RS sequence // DM-RS sequence
r_u_v_alpha_delta_re[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_re[n])>>15); r_u_v_alpha_delta_re[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_re[n])>>15);
r_u_v_alpha_delta_im[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_im[n])>>15); r_u_v_alpha_delta_im[n] = (int16_t)(((int32_t)amp*r_u_v_alpha_delta_im[n])>>15);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n",
u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]);
#endif #endif
} }
/* /*
* The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m) * The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m)
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
...@@ -736,124 +804,144 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -736,124 +804,144 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
uint8_t N_SF_mprime0_PUCCH_DMRS_1; uint8_t N_SF_mprime0_PUCCH_DMRS_1;
// mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping
uint8_t mprime = 0; uint8_t mprime = 0;
if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n",
intraSlotFrequencyHopping); intraSlotFrequencyHopping);
#endif #endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS)
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
for (int n=0; n<12 ; n++) {
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t\t z_pucch[%d] \t= ((%d \t* %d \t-%d \t* %d), (%d \t* %d \t+%d \t*%d)) = (%d,%d)\n", printf("\t\t z_pucch[%d] \t= ((%d \t* %d \t-%d \t* %d), (%d \t* %d \t+%d \t*%d)) = (%d,%d)\n",
(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
} }
} }
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) {
for (int n=0; n<12 ; n++) {
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t\t z_dm-rs[%d] = ((),()) =(%d,%d)\n", printf("\t\t z_dm-rs[%d] = ((),()) =(%d,%d)\n",
(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); (mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif #endif
} }
} }
} }
if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n", printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n",
intraSlotFrequencyHopping); intraSlotFrequencyHopping);
#endif #endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
for (mprime = 0; mprime<2; mprime++){ // mprime can get values {0,1}
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){ for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1}
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
for (int n=0; n<12 ; n++) {
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15));
} }
} }
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){ for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) {
for (int n=0; n<12 ; n++) {
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15) z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)); - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15) z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)); + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15));
} }
} }
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS)
} }
} }
/*
/*
* Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources
*/ */
int32_t *txptr; int32_t *txptr;
uint32_t re_offset; uint32_t re_offset;
int i=0; int i=0;
for (int l=0; l<nrofSymbols; l++) { for (int l=0; l<nrofSymbols; l++) {
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new PRB, FIXME!!! if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new PRB, FIXME!!!
startingPRB = startingPRB + startingPRB_intraSlotHopping; startingPRB = startingPRB + startingPRB_intraSlotHopping;
} }
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
} }
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
} }
if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
} }
txptr = &txdataF[0][re_offset]; txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++){
for (int n=0; n<12; n++) {
if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
} }
if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n]; ((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n]; ((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
re_offset++; re_offset++;
} }
if (l%2 == 1) i+=12; if (l%2 == 1) i+=12;
} }
} }
...@@ -861,7 +949,6 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, ...@@ -861,7 +949,6 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline)); inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) { inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) {
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
int i; int i;
uint8_t c; uint8_t c;
...@@ -869,20 +956,21 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id, ...@@ -869,20 +956,21 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,
//x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1)); //x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1));
x2 = ((rnti)<<15)+n_id; x2 = ((rnti)<<15)+n_id;
s = lte_gold_generic(&x1, &x2, 1); s = lte_gold_generic(&x1, &x2, 1);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%lx\n",s); printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%lx\n",s);
#endif #endif
for (i=0;i<M_bit;i++) {
for (i=0; i<M_bit; i++) {
c = (uint8_t)((s>>i)&1); c = (uint8_t)((s>>i)&1);
btilde[i] = (((B>>i)&1) ^ c); btilde[i] = (((B>>i)&1) ^ c);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
//printf("\t\t\t btilde[%d]=%lx from scrambled bit %d\n",i,btilde[i],((B>>i)&1)); //printf("\t\t\t btilde[%d]=%lx from scrambled bit %d\n",i,btilde[i],((B>>i)&1));
#endif #endif
} }
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
#endif
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
#endif
} }
void nr_uci_encoding(uint64_t payload, void nr_uci_encoding(uint64_t payload,
uint8_t nr_bit, uint8_t nr_bit,
...@@ -899,79 +987,90 @@ void nr_uci_encoding(uint64_t payload, ...@@ -899,79 +987,90 @@ void nr_uci_encoding(uint64_t payload,
* Implementing TS 38.212 Subclause 6.3.1.2 * Implementing TS 38.212 Subclause 6.3.1.2
* *
*/ */
// A is the payload size, to be provided in function call // A is the payload size, to be provided in function call
uint8_t A = nr_bit; uint8_t A = nr_bit;
// L is the CRC size // L is the CRC size
uint8_t L; uint8_t L;
// E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1 // E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
uint16_t E=0,E_init; uint16_t E=0,E_init;
if (fmt == pucch_format2_nr) E = 16*nrofSymbols*nrofPRB; if (fmt == pucch_format2_nr) E = 16*nrofSymbols*nrofPRB;
if (fmt == pucch_format3_nr){
if (fmt == pucch_format3_nr) {
E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12; E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
if (nrofSymbols == 4) { if (nrofSymbols == 4) {
E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)*nrofPRB):((E_init*(nrofSymbols-1)*nrofPRB)); E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)*nrofPRB):((E_init*(nrofSymbols-1)*nrofPRB));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 3 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E); printf("format 3 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E);
#endif #endif
} }
if (nrofSymbols > 4) { if (nrofSymbols > 4) {
E = E_init*(nrofSymbols-2)*nrofPRB; E = E_init*(nrofSymbols-2)*nrofPRB;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 3 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E); printf("format 3 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E);
#endif #endif
} }
if (nrofSymbols > 9) { if (nrofSymbols > 9) {
E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)*nrofPRB):((E_init*(nrofSymbols-4)*nrofPRB)); E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)*nrofPRB):((E_init*(nrofSymbols-4)*nrofPRB));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 3 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E); printf("format 3 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E);
#endif #endif
} }
} }
if (fmt == pucch_format4_nr){
if (fmt == pucch_format4_nr) {
E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12; E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
if (nrofSymbols == 4) { if (nrofSymbols == 4) {
E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)/n_SF_PUCCH_s):((E_init*(nrofSymbols-1)/n_SF_PUCCH_s)); E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)/n_SF_PUCCH_s):((E_init*(nrofSymbols-1)/n_SF_PUCCH_s));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 4 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E); printf("format 4 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E);
#endif #endif
} }
if (nrofSymbols > 4) { if (nrofSymbols > 4) {
E = E_init*(nrofSymbols-2)/n_SF_PUCCH_s; E = E_init*(nrofSymbols-2)/n_SF_PUCCH_s;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 4 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E); printf("format 4 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E);
#endif #endif
} }
if (nrofSymbols > 9) { if (nrofSymbols > 9) {
E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)/n_SF_PUCCH_s):((E_init*(nrofSymbols-4)/n_SF_PUCCH_s)); E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)/n_SF_PUCCH_s):((E_init*(nrofSymbols-4)/n_SF_PUCCH_s));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("format 4 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E); printf("format 4 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E);
#endif #endif
} }
} }
*M_bit = E; *M_bit = E;
int I_seg; int I_seg;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB); printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB);
#endif #endif
if (A<=11){ if (A<=11) {
// procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2) // procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2)
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3) // CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
} else if (A>=12){ } else if (A>=12) {
// procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1) // procedure in subclause 6.3.1.2.1 (UCI encoded by Polar code -> subclause 6.3.1.3.1)
if ((A>=360 && E>=1088)||(A>=1013)){ if ((A>=360 && E>=1088)||(A>=1013)) {
I_seg = 1; I_seg = 1;
} else { } else {
I_seg = 0; I_seg = 0;
} }
if (A>=20){
if (A>=20) {
// parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1) // parity bits (subclause 5.2.1) computed by setting L=11 and using generator polynomial gCRC11(D) (subclause 5.1)
L=11; L=11;
} else if (A<=19){ } else if (A<=19) {
// parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1) // parity bits (subclause 5.2.1) computed by setting L=6 and using generator polynomial gCRC6(D) (subclause 5.1)
L=6; L=6;
} }
// code block segmentation and CRC attachment is performed according to subclause 5.2.1 // code block segmentation and CRC attachment is performed according to subclause 5.2.1
// polar coding subclause 5.3.1 // polar coding subclause 5.3.1
} }
...@@ -990,15 +1089,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, ...@@ -990,15 +1089,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
uint8_t nrofPRB, uint8_t nrofPRB,
uint16_t startingPRB, uint16_t startingPRB,
uint8_t nr_bit) { uint8_t nr_bit) {
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%d and nr_bit=%d\n",nr_tti_tx, payload, nr_bit); printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%d and nr_bit=%d\n",nr_tti_tx, payload, nr_bit);
#endif #endif
// b is the block of bits transmitted on the physical channel after payload coding // b is the block of bits transmitted on the physical channel after payload coding
uint64_t b; uint64_t b;
// M_bit is the number of bits of block b (payload after encoding) // M_bit is the number of bits of block b (payload after encoding)
uint16_t M_bit; uint16_t M_bit;
nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b,&M_bit); nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b,&M_bit);
/* /*
* Implementing TS 38.211 * Implementing TS 38.211
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2) * Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
...@@ -1011,54 +1109,53 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, ...@@ -1011,54 +1109,53 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
* n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured
* n_id = N_ID_cell if higher layer parameter not configured * n_id = N_ID_cell if higher layer parameter not configured
*/ */
uint8_t *btilde = malloc(sizeof(int8_t)*M_bit); uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
// rnti is given by the C-RNTI // rnti is given by the C-RNTI
uint16_t rnti=crnti, n_id=0; uint16_t rnti=crnti, n_id=0;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch2] rnti = %d ,\n",rnti); printf("\t [nr_generate_pucch2] rnti = %d ,\n",rnti);
#endif #endif
/* /*
* Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2 * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2
*/ */
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde); nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
/* /*
* Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2 * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2
* btilde shall be modulated as described in subclause 5.1 using QPSK * btilde shall be modulated as described in subclause 5.1 using QPSK
* resulting in a block of complex-valued modulation symbols d(0),...,d(m_symbol) where m_symbol=M_bit/2 * resulting in a block of complex-valued modulation symbols d(0),...,d(m_symbol) where m_symbol=M_bit/2
*/ */
//#define ONE_OVER_SQRT2_S 23171 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
//#define ONE_OVER_SQRT2_S 23171 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
// complex-valued symbol d(0) // complex-valued symbol d(0)
int16_t *d_re = malloc(sizeof(int16_t)*M_bit); int16_t *d_re = malloc(sizeof(int16_t)*M_bit);
int16_t *d_im = malloc(sizeof(int16_t)*M_bit); int16_t *d_im = malloc(sizeof(int16_t)*M_bit);
uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1;
for (int i=0; i < m_symbol; i++){ // QPSK modulation subclause 5.1.3
for (int i=0; i < m_symbol; i++) { // QPSK modulation subclause 5.1.3
if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch2] modulation of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); printf("\t [nr_generate_pucch2] modulation of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]);
#endif #endif
} }
/* /*
* Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources * Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources
*/ */
...@@ -1067,58 +1164,76 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, ...@@ -1067,58 +1164,76 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
int i=0; int i=0;
int m=0; int m=0;
for (int l=0; l<nrofSymbols; l++) { for (int l=0; l<nrofSymbols; l++) {
x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*n_id) + 1)) + (2*n_id))%(1<<31); // c_init calculation according to TS38.211 subclause x2 = (((1<<17)*((14*nr_tti_tx) + (l+startingSymbolIndex) + 1)*((2*n_id) + 1)) + (2*n_id))%(1<<31); // c_init calculation according to TS38.211 subclause
s = lte_gold_generic(&x1, &x2, 1); s = lte_gold_generic(&x1, &x2, 1);
for (int rb=0; rb<nrofPRB; rb++){ m = 0;
for (int rb=0; rb<nrofPRB; rb++) {
//startingPRB = startingPRB + rb; //startingPRB = startingPRB + rb;
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
} }
if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1)));
} }
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
} }
if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6;
} }
if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
} }
//txptr = &txdataF[0][re_offset]; //txptr = &txdataF[0][re_offset];
int k=0; int k=0;
int kk=0; int kk=0;
for (int n=0; n<12; n++){
for (int n=0; n<12; n++) {
if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
} }
if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3
((int16_t *)&txdataF[0][re_offset])[0] = d_re[i+k]; ((int16_t *)&txdataF[0][re_offset])[0] = d_re[i+k];
((int16_t *)&txdataF[0][re_offset])[1] = d_im[i+k]; ((int16_t *)&txdataF[0][re_offset])[1] = d_im[i+k];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+k,re_offset, n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+k,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
k++; k++;
} }
if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2
((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>(2*m))&1)))))>>15); ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>(2*m))&1)))))>>15);
((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>((2*m)+1))&1)))))>>15); ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>((2*m)+1))&1)))))>>15);
m++; m++;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch2] (n=%d,i=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+kk,re_offset, n,i,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+kk,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
kk++; kk++;
} }
re_offset++; re_offset++;
} }
i+=8; i+=8;
if ((m&((1<<4)-1))==0) {
s = lte_gold_generic(&x1, &x2, 0);
m = 0;
}
} }
} }
} }
...@@ -1140,10 +1255,9 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1140,10 +1255,9 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
uint8_t nr_bit, uint8_t nr_bit,
uint8_t occ_length_format4, uint8_t occ_length_format4,
uint8_t occ_index_format4) { uint8_t occ_index_format4) {
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%d and nr_bit=%d\n", nr_tti_tx, payload, nr_bit); printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%d and nr_bit=%d\n", nr_tti_tx, payload, nr_bit);
#endif #endif
// b is the block of bits transmitted on the physical channel after payload coding // b is the block of bits transmitted on the physical channel after payload coding
uint64_t b; uint64_t b;
// M_bit is the number of bits of block b (payload after encoding) // M_bit is the number of bits of block b (payload after encoding)
...@@ -1156,19 +1270,21 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1156,19 +1270,21 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
// otherwise no intra-slot frequency hopping shall be assumed // otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
uint8_t intraSlotFrequencyHopping = 0; uint8_t intraSlotFrequencyHopping = 0;
if (startingPRB != startingPRB_intraSlotHopping){
if (startingPRB != startingPRB_intraSlotHopping) {
intraSlotFrequencyHopping=1; intraSlotFrequencyHopping=1;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping); printf("\t [nr_generate_pucch3_4] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping);
#endif #endif
} }
// add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!! // add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!!
uint8_t add_dmrs = 0; uint8_t add_dmrs = 0;
//nrofPRB = 2; // only for test purposes //nrofPRB = 2; // only for test purposes
if (fmt == pucch_format4_nr) nrofPRB = 1; if (fmt == pucch_format4_nr) nrofPRB = 1;
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit); nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit);
/* /*
* Implementing TS 38.211 * Implementing TS 38.211
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4) * Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
...@@ -1181,19 +1297,16 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1181,19 +1297,16 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
* n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured
* n_id = N_ID_cell if higher layer parameter not configured * n_id = N_ID_cell if higher layer parameter not configured
*/ */
uint8_t *btilde = malloc(sizeof(int8_t)*M_bit); uint8_t *btilde = malloc(sizeof(int8_t)*M_bit);
// rnti is given by the C-RNTI // rnti is given by the C-RNTI
uint16_t rnti=crnti, n_id=0; uint16_t rnti=crnti, n_id=0;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] rnti = %d ,\n",rnti); printf("\t [nr_generate_pucch3_4] rnti = %d ,\n",rnti);
#endif #endif
/* /*
* Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4 * Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4
*/ */
nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde); nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde);
/* /*
* Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4 * Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4
* *
...@@ -1204,53 +1317,64 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1204,53 +1317,64 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
int16_t *d_re = malloc(sizeof(int16_t)*M_bit); int16_t *d_re = malloc(sizeof(int16_t)*M_bit);
int16_t *d_im = malloc(sizeof(int16_t)*M_bit); int16_t *d_im = malloc(sizeof(int16_t)*M_bit);
uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1;
if (is_pi_over_2_bpsk_enabled == 0){
if (is_pi_over_2_bpsk_enabled == 0) {
// using QPSK if PUCCH format 3,4 and pi/2-BPSK is not configured, according to subclause 6.3.2.6.2 // using QPSK if PUCCH format 3,4 and pi/2-BPSK is not configured, according to subclause 6.3.2.6.2
for (int i=0; i < m_symbol; i++){ // QPSK modulation subclause 5.1.3 for (int i=0; i < m_symbol; i++) { // QPSK modulation subclause 5.1.3
if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] modulation QPSK of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); printf("\t [nr_generate_pucch3_4] modulation QPSK of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]);
#endif #endif
} }
} }
if (is_pi_over_2_bpsk_enabled == 1){
if (is_pi_over_2_bpsk_enabled == 1) {
// using PI/2-BPSK if PUCCH format 3,4 and pi/2-BPSK is configured, according to subclause 6.3.2.6.2 // using PI/2-BPSK if PUCCH format 3,4 and pi/2-BPSK is configured, according to subclause 6.3.2.6.2
m_symbol = M_bit; m_symbol = M_bit;
for (int i=0; i<m_symbol; i++){ // PI/2-BPSK modulation subclause 5.1.1
if (((btilde[i]&1)==0) && (i%2 == 0)){ for (int i=0; i<m_symbol; i++) { // PI/2-BPSK modulation subclause 5.1.1
if (((btilde[i]&1)==0) && (i%2 == 0)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[i]&1)==0) && (i%2 == 1)){
if (((btilde[i]&1)==0) && (i%2 == 1)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[i]&1)==1) && (i%2 == 0)){
if (((btilde[i]&1)==1) && (i%2 == 0)) {
d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
if (((btilde[i]&1)==1) && (i%2 == 1)){
if (((btilde[i]&1)==1) && (i%2 == 1)) {
d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
} }
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] modulation PI/2-BPSK of bit btilde(%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[i]&1),m_symbol,i,d_re[i],d_im[i]); printf("\t [nr_generate_pucch3_4] modulation PI/2-BPSK of bit btilde(%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[i]&1),m_symbol,i,d_re[i],d_im[i]);
#endif #endif
} }
} }
...@@ -1270,66 +1394,75 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1270,66 +1394,75 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
// k={0,..11} n={0,1,2,3} // k={0,..11} n={0,1,2,3}
// parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n // parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n
uint16_t table_6_3_2_6_3_1_Wn_Re[2][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, uint16_t table_6_3_2_6_3_1_Wn_Re[2][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1}}; {1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1}
};
// Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1)
// k={0,..11} n={0,1} // k={0,..11} n={0,1}
uint16_t table_6_3_2_6_3_1_Wn_Im[2][12] = {{0,0,0,0,0,0,0,0,0,0,0,0}, uint16_t table_6_3_2_6_3_1_Wn_Im[2][12] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}}; {0,0,0,0,0,0,0,0,0,0,0,0}
};
// Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2)
// k={0,..11} n={0,1,2.3} // k={0,..11} n={0,1,2.3}
uint16_t table_6_3_2_6_3_2_Wn_Re[4][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, uint16_t table_6_3_2_6_3_2_Wn_Re[4][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}, {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0},
{1, 1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1}, {1, 1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1},
{1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}}; {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}
};
// Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2)
// k={0,..11} n={0,1,2,3} // k={0,..11} n={0,1,2,3}
uint16_t table_6_3_2_6_3_2_Wn_Im[4][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, uint16_t table_6_3_2_6_3_2_Wn_Im[4][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0,-1,-1,-1, 0, 0, 0, 1, 1, 1}, {0, 0, 0,-1,-1,-1, 0, 0, 0, 1, 1, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 0, 0, 0,-1,-1,-1}}; {0, 0, 0, 1, 1, 1, 0, 0, 0,-1,-1,-1}
};
//uint8_t occ_Length = occ_length_format4; // higher layer parameter occ-Length //uint8_t occ_Length = occ_length_format4; // higher layer parameter occ-Length
uint8_t occ_Index = occ_index_format4; // higher layer parameter occ-Index uint8_t occ_Index = occ_index_format4; // higher layer parameter occ-Index
//occ_Index = 1; //only for testing purposes; to be removed FIXME!!!
if (fmt == pucch_format3_nr){ // no block-wise spreading for format 3 //occ_Index = 1; //only for testing purposes; to be removed FIXME!!!
if (fmt == pucch_format3_nr) { // no block-wise spreading for format 3
n_SF_PUCCH_s = 1; n_SF_PUCCH_s = 1;
for (int l=0; l < floor(m_symbol/(12*nrofPRB)); l++){
for (int k=0; k < (12*nrofPRB); k++){ for (int l=0; l < floor(m_symbol/(12*nrofPRB)); l++) {
for (int k=0; k < (12*nrofPRB); k++) {
y_n_re[l*(12*nrofPRB)+k] = d_re[l*(12*nrofPRB)+k]; y_n_re[l*(12*nrofPRB)+k] = d_re[l*(12*nrofPRB)+k];
y_n_im[l*(12*nrofPRB)+k] = d_im[l*(12*nrofPRB)+k]; y_n_im[l*(12*nrofPRB)+k] = d_im[l*(12*nrofPRB)+k];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] block-wise spreading for format 3 (no block-wise spreading): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", printf("\t [nr_generate_pucch3_4] block-wise spreading for format 3 (no block-wise spreading): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n",
l,k,l*(12*nrofPRB)+k,d_re[l*(12*nrofPRB)+k],d_im[l*(12*nrofPRB)+k]); l,k,l*(12*nrofPRB)+k,d_re[l*(12*nrofPRB)+k],d_im[l*(12*nrofPRB)+k]);
#endif #endif
} }
} }
} }
if (fmt == pucch_format4_nr){
if (fmt == pucch_format4_nr) {
nrofPRB = 1; nrofPRB = 1;
for (int l=0; l < floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++){
for (int k=0; k < (12*nrofPRB); k++){ for (int l=0; l < floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++) {
if (n_SF_PUCCH_s == 2){ for (int k=0; k < (12*nrofPRB); k++) {
if (n_SF_PUCCH_s == 2) {
y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k]) y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k])
- ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k])); - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k]));
y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k]) y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k])
+ ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k])); + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k]));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 2) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 2) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n",
occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]);
// printf("\t\t d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]); // printf("\t\t d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]);
// printf("\t\t d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]); // printf("\t\t d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]);
// printf("\t\t table_6_3_2_6_3_1_Wn_Re[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Re[occ_Index][k]); // printf("\t\t table_6_3_2_6_3_1_Wn_Re[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Re[occ_Index][k]);
// printf("\t\t table_6_3_2_6_3_1_Wn_Im[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Im[occ_Index][k]); // printf("\t\t table_6_3_2_6_3_1_Wn_Im[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Im[occ_Index][k]);
#endif #endif
} }
if (n_SF_PUCCH_s == 4){
if (n_SF_PUCCH_s == 4) {
y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k]) y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k])
- ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k])); - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k]));
y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k]) y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k])
+ ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k])); + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k]));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 4) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 4) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n",
occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]);
#endif #endif
} }
} }
} }
...@@ -1340,37 +1473,40 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1340,37 +1473,40 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
*/ */
int16_t *z_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s int16_t *z_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s
int16_t *z_im = malloc(sizeof(int16_t)*4*M_bit); int16_t *z_im = malloc(sizeof(int16_t)*4*M_bit);
#define M_PI 3.14159265358979323846 // pi #define M_PI 3.14159265358979323846 // pi
//int16_t inv_sqrt_nrofPRBs = (int16_t)round(32767/sqrt(12*nrofPRB)); //int16_t inv_sqrt_nrofPRBs = (int16_t)round(32767/sqrt(12*nrofPRB));
for (int l=0; l<floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++){ for (int l=0; l<floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++) {
for (int k=0; k<(12*nrofPRB); k++){ for (int k=0; k<(12*nrofPRB); k++) {
z_re[l*(12*nrofPRB)+k] = 0; z_re[l*(12*nrofPRB)+k] = 0;
z_im[l*(12*nrofPRB)+k] = 0; z_im[l*(12*nrofPRB)+k] = 0;
// int16_t z_re_tmp[240] = {0};
// int16_t z_im_tmp[240] = {0}; // int16_t z_re_tmp[240] = {0};
for (int m=0; m<(12*nrofPRB); m++){ // int16_t z_im_tmp[240] = {0};
for (int m=0; m<(12*nrofPRB); m++) {
//z_re[l*(12*nrofPRB)+k] = y_n_re[l*(12*nrofPRB)+m] * (int16_t)(round(32767*cos((2*M_PI*m*k)/(12*nrofPRB)))); //z_re[l*(12*nrofPRB)+k] = y_n_re[l*(12*nrofPRB)+m] * (int16_t)(round(32767*cos((2*M_PI*m*k)/(12*nrofPRB))));
// z_re_tmp[m] = (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) // z_re_tmp[m] = (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15)
// + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); // + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15);
// z_im_tmp[m] = (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) // z_im_tmp[m] = (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15)
// - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); // - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15);
z_re[l*(12*nrofPRB)+k] = z_re[l*(12*nrofPRB)+k] z_re[l*(12*nrofPRB)+k] = z_re[l*(12*nrofPRB)+k]
+ (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) + (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15)
+ (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15);
z_im[l*(12*nrofPRB)+k] = z_im[l*(12*nrofPRB)+k] z_im[l*(12*nrofPRB)+k] = z_im[l*(12*nrofPRB)+k]
+ (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) + (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15)
- (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
// printf("\t\t z_re_tmp[%d] = %d\n",m,z_re_tmp[m]); // printf("\t\t z_re_tmp[%d] = %d\n",m,z_re_tmp[m]);
// printf("\t\t z_im_tmp[%d] = %d\n",m,z_im_tmp[m]); // printf("\t\t z_im_tmp[%d] = %d\n",m,z_im_tmp[m]);
// printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k,m)=(%d,%d,%d)\tz(%d) = \t(%d, %d)\n", // printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k,m)=(%d,%d,%d)\tz(%d) = \t(%d, %d)\n",
// l,k,m,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); // l,k,m,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]);
#endif #endif
} }
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k)=(%d,%d)\tz(%d) = \t(%d, %d)\n", printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k)=(%d,%d)\tz(%d) = \t(%d, %d)\n",
l,k,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); l,k,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]);
#endif #endif
} }
} }
...@@ -1392,29 +1528,32 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1392,29 +1528,32 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
// m0 is the cyclic shift index calculated depending on the Orthogonal sequence index n, according to table 6.4.1.3.3.1-1 from TS 38.211 subclause 6.4.1.3.3.1 // m0 is the cyclic shift index calculated depending on the Orthogonal sequence index n, according to table 6.4.1.3.3.1-1 from TS 38.211 subclause 6.4.1.3.3.1
uint8_t m0; uint8_t m0;
uint8_t mcs=0; uint8_t mcs=0;
if (fmt == pucch_format3_nr) m0 = 0; if (fmt == pucch_format3_nr) m0 = 0;
if (fmt == pucch_format4_nr) { if (fmt == pucch_format4_nr) {
if (n_SF_PUCCH_s == 2) { if (n_SF_PUCCH_s == 2) {
m0 = (occ_Index == 0) ? 0 : 6; m0 = (occ_Index == 0) ? 0 : 6;
} }
if (n_SF_PUCCH_s == 4) { if (n_SF_PUCCH_s == 4) {
m0 = (occ_Index == 3) ? 9 : ((occ_Index == 2) ? 3 : ((occ_Index == 1) ? 6 : 0)); m0 = (occ_Index == 3) ? 9 : ((occ_Index == 2) ? 3 : ((occ_Index == 1) ? 6 : 0));
} }
} }
double alpha; double alpha;
uint8_t N_ZC = 12*nrofPRB; uint8_t N_ZC = 12*nrofPRB;
int16_t *r_u_v_base_re = malloc(sizeof(int16_t)*12*nrofPRB); int16_t *r_u_v_base_re = malloc(sizeof(int16_t)*12*nrofPRB);
int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB); int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB);
//int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB); //int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB);
//int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB); //int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB);
// Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS // Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS
//int32_t *txptr; //int32_t *txptr;
uint32_t re_offset=0; uint32_t re_offset=0;
//uint32_t x1, x2, s=0; //uint32_t x1, x2, s=0;
// intraSlotFrequencyHopping // intraSlotFrequencyHopping
// uint8_t intraSlotFrequencyHopping = 0; // uint8_t intraSlotFrequencyHopping = 0;
uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] ={ uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] = {
{(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4 {(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4
{1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5 {1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5
{0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 6 {0,1,0,0,1,0,0,0,0,0,0,0,0,0}, // PUCCH length = 6
...@@ -1428,124 +1567,139 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, ...@@ -1428,124 +1567,139 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
{0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14 {0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14
}; };
uint16_t k=0; uint16_t k=0;
for (int l=0; l<nrofSymbols; l++) {
for (int l=0; l<nrofSymbols; l++) {
if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
// Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33
if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
int i = 4; int i = 4;
while (list_of_prime_numbers[i] < (12*nrofPRB)) i++; while (list_of_prime_numbers[i] < (12*nrofPRB)) i++;
N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB) N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB)
double q_base = (N_ZC*(u+1))/31; double q_base = (N_ZC*(u+1))/31;
int8_t q = (uint8_t)floor(q_base + (1/2)); int8_t q = (uint8_t)floor(q_base + (1/2));
q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v); q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v);
for (int n=0; n<(12*nrofPRB); n++){
for (int n=0; n<(12*nrofPRB); n++) {
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n", printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif #endif
} }
} }
if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies
for (int n=0; n<(12*nrofPRB); n++){ for (int n=0; n<(12*nrofPRB); n++) {
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15); r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15); r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n", printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif #endif
} }
} }
if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies
for (int n=0; n<(12*nrofPRB); n++){ for (int n=0; n<(12*nrofPRB); n++) {
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15); r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15); r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n", printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif #endif
} }
} }
uint16_t j=0; uint16_t j=0;
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx); alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
for (int rb=0; rb<nrofPRB; rb++){
for (int rb=0; rb<nrofPRB; rb++) {
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
startingPRB = startingPRB + startingPRB_intraSlotHopping; startingPRB = startingPRB + startingPRB_intraSlotHopping;
} }
//startingPRB = startingPRB + rb; //startingPRB = startingPRB + rb;
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("1 "); printf("1 ");
#endif #endif
} }
if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1)));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("2 "); printf("2 ");
#endif #endif
} }
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("3 "); printf("3 ");
#endif #endif
} }
if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("4 "); printf("4 ");
#endif #endif
} }
if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("5 "); printf("5 ");
#endif #endif
} }
#ifdef DEBUG_NR_PUCCH_TX
#ifdef DEBUG_NR_PUCCH_TX
printf("re_offset=%d,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB)); printf("re_offset=%d,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB));
#endif #endif
//txptr = &txdataF[0][re_offset]; //txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++){ for (int n=0; n<12; n++) {
if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
} }
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3
((int16_t *)&txdataF[0][re_offset])[0] = z_re[n+k]; ((int16_t *)&txdataF[0][re_offset])[0] = z_re[n+k];
((int16_t *)&txdataF[0][re_offset])[1] = z_im[n+k]; ((int16_t *)&txdataF[0][re_offset])[1] = z_im[n+k];
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(z(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(z(l=%d,n=%d)=(%d,%d))\n",
l,rb,n,k,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+k,re_offset, l,rb,n,k,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+k,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2
((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15) ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)
- (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15)); - (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15));
((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15) ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15)
+ (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)); + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15));
#ifdef DEBUG_NR_PUCCH_TX #ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(r_u_v(l=%d,n=%d)=(%d,%d))\n", printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(r_u_v(l=%d,n=%d)=(%d,%d))\n",
l,rb,n,j,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+j,re_offset, l,rb,n,j,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+j,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif #endif
} }
re_offset++; re_offset++;
} }
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) k+=12; if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) k+=12;
if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) j+=12; if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) j+=12;
} }
} }
} }
...@@ -187,7 +187,6 @@ int64_t dot_product64(int16_t *x, ...@@ -187,7 +187,6 @@ int64_t dot_product64(int16_t *x,
mmtmp1 = _mm_madd_epi16(x128[0],y128[0]); mmtmp1 = _mm_madd_epi16(x128[0],y128[0]);
// print_ints("retmp",&mmtmp1); // print_ints("retmp",&mmtmp1);
// mmtmp1 contains real part of 4 consecutive outputs (32-bit) // mmtmp1 contains real part of 4 consecutive outputs (32-bit)
// shift and accumulate results // shift and accumulate results
mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift); mmtmp1 = _mm_srai_epi32(mmtmp1,output_shift);
mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1); mmcumul_re = _mm_add_epi32(mmcumul_re,mmtmp1);
...@@ -205,7 +204,6 @@ int64_t dot_product64(int16_t *x, ...@@ -205,7 +204,6 @@ int64_t dot_product64(int16_t *x,
mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2); mmtmp3 = _mm_madd_epi16(x128[0],mmtmp2);
//print_ints("imtmp",&mmtmp3); //print_ints("imtmp",&mmtmp3);
// mmtmp3 contains imag part of 4 consecutive outputs (32-bit) // mmtmp3 contains imag part of 4 consecutive outputs (32-bit)
// shift and accumulate results // shift and accumulate results
mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift); mmtmp3 = _mm_srai_epi32(mmtmp3,output_shift);
mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3); mmcumul_im = _mm_add_epi32(mmcumul_im,mmtmp3);
...@@ -218,13 +216,10 @@ int64_t dot_product64(int16_t *x, ...@@ -218,13 +216,10 @@ int64_t dot_product64(int16_t *x,
// this gives Re Re Im Im // this gives Re Re Im Im
mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im); mmcumul = _mm_hadd_epi32(mmcumul_re,mmcumul_im);
//print_ints("cumul1",&mmcumul); //print_ints("cumul1",&mmcumul);
// this gives Re Im Re Im // this gives Re Im Re Im
mmcumul = _mm_hadd_epi32(mmcumul,mmcumul); mmcumul = _mm_hadd_epi32(mmcumul,mmcumul);
//print_ints("cumul2",&mmcumul); //print_ints("cumul2",&mmcumul);
//mmcumul = _mm_srai_epi32(mmcumul,output_shift); //mmcumul = _mm_srai_epi32(mmcumul,output_shift);
// extract the lower half // extract the lower half
result = _mm_extract_epi64(mmcumul,0); result = _mm_extract_epi64(mmcumul,0);
......
...@@ -498,10 +498,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -498,10 +498,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
float **rxsig_t_dB; float **rxsig_t_dB;
float *time; float *time;
float *corr; float *corr;
/*
int16_t **chest_t; int16_t **chest_t;
int16_t **chest_f; int16_t **chest_f;
*/
int16_t *pdsch_llr; int16_t *pdsch_llr;
int16_t *pdsch_comp; int16_t *pdsch_comp;
//int16_t *pdsch_mag; //int16_t *pdsch_mag;
...@@ -519,10 +517,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -519,10 +517,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
int coded_bits_per_codeword = num_re*Qm; int coded_bits_per_codeword = num_re*Qm;
int symbol, first_symbol,nb_re; int symbol, first_symbol,nb_re;
int nb_rb_pdsch =50; 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 frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
int mcs = 0; int mcs = 0;
unsigned char harq_pid = 0; unsigned char harq_pid = 0;
...@@ -565,15 +566,15 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -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)); 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)); 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*)); chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) { for (arx=0; arx<nb_antennas_rx; arx++) {
chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float)); chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_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 llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float)); bit = malloc(coded_bits_per_codeword*sizeof(float));
...@@ -589,10 +590,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -589,10 +590,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
time = calloc(samples_per_frame,sizeof(float)); time = calloc(samples_per_frame,sizeof(float));
corr = 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_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]; 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_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]; pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
...@@ -639,18 +639,26 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -639,18 +639,26 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_data(form->chest_t,time,corr,samples_per_frame,"","",""); fl_set_xyplot_data(form->chest_t,time,corr,samples_per_frame,"","","");
else else
fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]); fl_add_xyplot_overlay(form->chest_t,ind,time,corr,samples_per_frame,rx_antenna_colors[ind]);
overlay = 1;
} }
} }
} }
else {
/* if (overlay) { //there was a previous overlay
// Channel Impulse Response (still repeated format) fl_clear_xyplot(form->chest_t);
overlay = 0;
}
// Channel Impulse Response
if (chest_t != NULL) { if (chest_t != NULL) {
ymax = 0; ymax = 0;
if (chest_t[0] !=NULL) { if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) { 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) if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i]; ymax = chest_t_abs[0][i];
...@@ -658,7 +666,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -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),"","",""); fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
} }
/*
for (arx=1; arx<nb_antennas_rx; arx++) { for (arx=1; arx<nb_antennas_rx; arx++) {
if (chest_t[arx] !=NULL) { if (chest_t[arx] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) { for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
...@@ -672,11 +680,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -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); fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
} }
} }
*/
// Avoid flickering effect // Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work... // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); // Does not always work...
fl_set_xyplot_ybounds(form->chest_t,0,(double) ymax); fl_set_xyplot_ybounds(form->chest_t,0,(double) ymax);
} }
}
// Channel Frequency Response (includes 5 complex sample for filter) // Channel Frequency Response (includes 5 complex sample for filter)
if (chest_f != NULL) { if (chest_f != NULL) {
...@@ -685,7 +694,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -685,7 +694,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
for (atx=0; atx<nb_antennas_tx; atx++) { for (atx=0; atx<nb_antennas_tx; atx++) {
for (arx=0; arx<nb_antennas_rx; arx++) { for (arx=0; arx<nb_antennas_rx; arx++) {
if (chest_f[(atx<<1)+arx] != NULL) { if (chest_f[(atx<<1)+arx] != NULL) {
for (k=0; k<nsymb_ce; k++) { for (k=0; k<frame_parms->ofdm_symbol_size; k++) {
freq[ind] = (float)ind; freq[ind] = (float)ind;
Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); Re = (float)(chest_f[(atx<<1)+arx][(2*k)]);
Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]);
...@@ -698,12 +707,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -698,12 +707,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
} }
// tx antenna 0 // 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*frame_parms->symbols_per_tti,2);
// fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,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_xgrid(form->chest_f,FL_GRID_MAJOR);
fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,frame_parms->ofdm_symbol_size,"","","");
/*
for (arx=1; arx<nb_antennas_rx; arx++) { for (arx=1; arx<nb_antennas_rx; arx++) {
fl_add_xyplot_overlay(form->chest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); fl_add_xyplot_overlay(form->chest_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, ...@@ -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]); 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 // PBCH LLRs
if (pbch_llr != NULL) { if (pbch_llr != NULL) {
...@@ -735,9 +745,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, ...@@ -735,9 +745,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","",""); 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 // PBCH I/Q of MF Output
......
...@@ -983,6 +983,8 @@ typedef struct { ...@@ -983,6 +983,8 @@ typedef struct {
int UE_scan; int UE_scan;
/// \brief Indicator that UE should perform coarse scanning around carrier /// \brief Indicator that UE should perform coarse scanning around carrier
int UE_scan_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 /// \brief Indicator that UE is synchronized to an eNB
int is_synchronized; int is_synchronized;
/// Data structure for UE process scheduling /// Data structure for UE process scheduling
......
...@@ -736,7 +736,7 @@ typedef struct { ...@@ -736,7 +736,7 @@ typedef struct {
-- Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2) -- Corresponds to L1 parameter 'HoppingID' (see 38.211, section 6.3.2.2)
hoppingId BIT STRING (SIZE (10)) OPTIONAL, -- Need R hoppingId BIT STRING (SIZE (10)) OPTIONAL, -- Need R
*/ */
uint16_t hoppingId; uint32_t hoppingId;
/* /*
-- Power control parameter P0 for PUCCH transmissions. Value in dBm. Only even values (step size 2) allowed. -- Power control parameter P0 for PUCCH transmissions. Value in dBm. Only even values (step size 2) allowed.
-- Corresponds to L1 parameter 'p0-nominal-pucch' (see 38.213, section 7.2) -- Corresponds to L1 parameter 'p0-nominal-pucch' (see 38.213, section 7.2)
......
File mode changed from 100644 to 100755
...@@ -138,20 +138,22 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { ...@@ -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); 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_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)){ if (!(frame&7)){
LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured); LOG_D(PHY,"%d.%d : pbch_configured %d\n",frame,slot,gNB->pbch_configured);
if (gNB->pbch_configured != 1)return; if (gNB->pbch_configured != 1)return;
gNB->pbch_configured = 0; 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, nr_generate_pbch(&gNB->pbch,
gNB->nrPolar_params, gNB->nrPolar_params,
pbch_pdu, pbch_pdu,
gNB->nr_pbch_interleaver, gNB->nr_pbch_interleaver,
txdataF[0], txdataF[0],
AMP_OVER_2, AMP,
ssb_start_symbol, ssb_start_symbol,
n_hf,Lmax,ssb_index, n_hf,Lmax,ssb_index,
frame, cfg, fp); frame, cfg, fp);
......
...@@ -48,11 +48,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -48,11 +48,13 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
/// component carrier id /// component carrier id
uint8_t cc_id = scheduled_response->CC_id; uint8_t cc_id = scheduled_response->CC_id;
uint32_t i; uint32_t i;
int slot = scheduled_response->slot;
uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot];
if(scheduled_response != NULL){ if(scheduled_response != NULL){
// Note: we have to handle the thread IDs for this. To be revisited completely. // Note: we have to handle the thread IDs for this. To be revisited completely.
NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[0][0]; NR_UE_PDCCH *pdcch_vars2 = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[0][0][0]; NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[0];
NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms; NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0]; PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
......
...@@ -2781,8 +2781,6 @@ void nr_ue_measurement_procedures( ...@@ -2781,8 +2781,6 @@ void nr_ue_measurement_procedures(
*/ */
eNB_id = 0; eNB_id = 0;
LOG_D(PHY,"start adjust sync l = %d slot = %d no timing %d\n",l, slot, ue->no_timing_correction); 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) if (ue->no_timing_correction==0)
nr_adjust_synch_ue(&ue->frame_parms, nr_adjust_synch_ue(&ue->frame_parms,
...@@ -2792,7 +2790,6 @@ void nr_ue_measurement_procedures( ...@@ -2792,7 +2790,6 @@ void nr_ue_measurement_procedures(
0, 0,
16384); 16384);
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
...@@ -4969,95 +4966,20 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -4969,95 +4966,20 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
int frame_rx = proc->frame_rx; int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx; int nr_tti_rx = proc->nr_tti_rx;
NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0];
uint16_t nb_symb_sch = 8; // to be updated by higher layer uint16_t nb_symb_sch = 8; // to be updated by higher layer
uint8_t nb_symb_pdcch =2; uint8_t nb_symb_pdcch = pdcch_vars->coreset[0].duration;
//proc->decoder_switch = 0;
//int counter_decoder = 0;
LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx); LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx);
uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1); uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
#if 0
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
#if T_TRACER
T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx));
T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_tti_rx), T_INT(0),
T_BUFFER(&ue->common_vars.rxdata[0][nr_tti_rx*ue->frame_parms.samples_per_subframe],
ue->frame_parms.samples_per_subframe * 4));
#endif
// start timers
//#ifdef UE_DEBUG_TRACE
LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx);
//#endif
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]);
start_meas(&ue->generic_stat);
#endif
if (do_pdcch_flag) {
// deactivate reception until we scan pdcch
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0])
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1])
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][1]->active = 0;
if (ue->dlsch_SI[eNB_id])
ue->dlsch_SI[eNB_id]->active = 0;
if (ue->dlsch_p[eNB_id])
ue->dlsch_p[eNB_id]->active = 0;
if (ue->dlsch_ra[eNB_id])
ue->dlsch_ra[eNB_id]->active = 0;
}
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[%s %d] Frame %d nr_tti_rx %d: Doing phy_procedures_UE_RX\n",
(r_type == multicast_relay) ? "RN/UE" : "UE",
ue->Mod_id,frame_rx, nr_tti_rx);
#endif
if (ue->frame_parms.Ncp == 0) { // normal prefix
pilot1 = 4;
} else { // extended prefix
pilot1 = 3;
}
/*
if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) == SF_S) { // S-subframe, do first 5 symbols only
l2 = 5;
} else */
{ // normal nr_tti_rx, last symbol to be processed is the first of the second slot
l2 = (ue->frame_parms.symbols_per_tti/2)-1;
}
int prev_nr_tti_rx = (nr_tti_rx - 1)<0? 9: (nr_tti_rx - 1);/*
if (nr_subframe_select(&ue->frame_parms,prev_nr_tti_rx) != SF_DL) {
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RX processing of symbols l=0...l2
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
l=0;
} else */
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
l=1;
}
LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
#endif
#ifdef NR_PDCCH_SCHED #ifdef NR_PDCCH_SCHED
//nr_gold_pdcch(ue,0, 2); nr_gold_pdcch(ue,0, 2);
//if (nr_tti_rx==1){ //if (nr_tti_rx==1){
LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
for (uint16_t l=0; l<nb_symb_pdcch; l++) { for (uint16_t l=0; l<nb_symb_pdcch; l++) {
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
...@@ -5088,16 +5010,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -5088,16 +5010,16 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
//} //}
#endif //NR_PDCCH_SCHED #endif //NR_PDCCH_SCHED
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
if (nr_tti_rx==1){ if (nr_tti_rx==1){
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
//to update from pdsch config //to update from pdsch config
nr_gold_pdsch(ue,nb_symb_pdcch,0, 1); nr_gold_pdsch(ue,nb_symb_pdcch,0, 1);
for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){ for (uint16_t m=nb_symb_pdcch;m<=(nb_symb_sch+nb_symb_pdcch-1) ; m++){
nr_slot_fep(ue, nr_slot_fep(ue,
m, //to be updated from higher layer m, //to be updated from higher layer
nr_tti_rx<<1, nr_tti_rx,
0, 0,
0, 0,
1, 1,
...@@ -5108,7 +5030,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -5108,7 +5030,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 //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 else
ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0; ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active = 0;
...@@ -5131,7 +5053,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -5131,7 +5053,6 @@ 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_PDSCH_PROC, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
} }
LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
// do procedures for SI-RNTI // do procedures for SI-RNTI
if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
...@@ -5173,62 +5094,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -5173,62 +5094,12 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
ue->frame_parms.symbols_per_tti>>1); ue->frame_parms.symbols_per_tti>>1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
} }
//#if 0
LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
/*if (nr_subframe_select(&ue->frame_parms,nr_tti_rx) != SF_S)*/
{ // do front-end processing for second slot, and first symbol of next nr_tti_rx
for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) {
#if UE_TIMING_TRACE
start_meas(&ue->ofdm_demod_stats);
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
/*nr_slot_fep(ue,
l,
1+(nr_tti_rx<<1),
0,
0,
0,
NR_PDSCH_EST);*/
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(&ue->ofdm_demod_stats);
#endif
//ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(nr_tti_rx<<1),abstraction_flag,mode);
} // for l=1..l2
// do first symbol of next downlink nr_tti_rx for channel estimation
int next_nr_tti_rx = (1+nr_tti_rx)%10;
/* if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL)*/
{
/*nr_slot_fep(ue,
0,
(next_nr_tti_rx<<1),
0,
0,
0,
NR_PDSCH_EST);*/
}
} // not an S-subframe
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat);
#if DISABLE_LOG_X
printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
#else
LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",nr_tti_rx,ue->generic_stat.p_time/(cpuf*1000.0));
#endif
#endif
//LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1))
{ {
LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
nr_slot_fep(ue, nr_slot_fep(ue,
(5+i), //mu=1 case B (5+i), //mu=1 case B
...@@ -5242,7 +5113,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN ...@@ -5242,7 +5113,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eN
} }
// do procedures for C-RNTI // do procedures for C-RNTI
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
......
...@@ -144,7 +144,7 @@ int main(int argc, char **argv) { ...@@ -144,7 +144,7 @@ int main(int argc, char **argv) {
//char input_val_str[50],input_val_str2[50]; //char input_val_str[50],input_val_str2[50];
//uint16_t NB_RB=25; //uint16_t NB_RB=25;
SCM_t channel_model = AWGN; //Rayleigh1_anticorr; SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
uint8_t N_RB_DL = 106, mu = 1; uint16_t N_RB_DL = 106, mu = 1;
unsigned char frame_type = 0; unsigned char frame_type = 0;
unsigned char pbch_phase = 0; unsigned char pbch_phase = 0;
int frame = 0, subframe = 0; int frame = 0, subframe = 0;
...@@ -362,7 +362,8 @@ int main(int argc, char **argv) { ...@@ -362,7 +362,8 @@ int main(int argc, char **argv) {
if (snr1set == 0) if (snr1set == 0)
snr1 = snr0 + 10; snr1 = snr0 + 10;
gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, 61.44e6, //N_RB2sampling_rate(N_RB_DL), 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), 40e6, //N_RB2channel_bandwidth(N_RB_DL),
0, 0, 0); 0, 0, 0);
...@@ -599,9 +600,11 @@ int main(int argc, char **argv) { ...@@ -599,9 +600,11 @@ int main(int argc, char **argv) {
(float) n_errors / (float) n_trials, (float) n_errors / (float) n_trials,
(float) n_false_positive / (float) n_trials); (float) n_false_positive / (float) n_trials);
if ((float) n_errors / (float) n_trials < target_error_rate) if ((float) n_errors / (float) n_trials < target_error_rate) {
printf("PDSCH test OK\n");
break; break;
} }
}
/*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
......
...@@ -154,7 +154,7 @@ int main(int argc, char **argv) ...@@ -154,7 +154,7 @@ int main(int argc, char **argv)
unsigned char frame_type = 0; unsigned char frame_type = 0;
unsigned char pbch_phase = 0; unsigned char pbch_phase = 0;
int frame=0,slot=0; int frame=0,slot=1;
int frame_length_complex_samples; int frame_length_complex_samples;
int frame_length_complex_samples_no_prefix; int frame_length_complex_samples_no_prefix;
int slot_length_complex_samples_no_prefix; int slot_length_complex_samples_no_prefix;
...@@ -543,18 +543,20 @@ int main(int argc, char **argv) ...@@ -543,18 +543,20 @@ int main(int argc, char **argv)
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
int tx_offset = slot*frame_parms->samples_per_slot;
//TODO: loop over slots //TODO: loop over slots
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
PHY_ofdm_mod(gNB->common_vars.txdataF[aa], PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
txdata[aa], &txdata[aa][tx_offset],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
12, 12,
frame_parms->nb_prefix_samples, frame_parms->nb_prefix_samples,
CYCLIC_PREFIX); CYCLIC_PREFIX);
} else { } else {
nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
txdata[aa], &txdata[aa][tx_offset],
14, 14,
frame_parms); frame_parms);
} }
......
...@@ -87,11 +87,13 @@ int main(int argc, char **argv) ...@@ -87,11 +87,13 @@ int main(int argc, char **argv)
int i,aa;//,l; int i,aa;//,l;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0;
uint8_t snr1set=0; uint8_t snr1set=0;
int **txdata; int **txdata;
double **s_re,**s_im,**r_re,**r_im; double **s_re,**s_im,**r_re,**r_im;
//double iqim = 0.0; double iqim = 0.0;
//unsigned char pbch_pdu[6]; double ip =0.0;
unsigned char pbch_pdu[6];
// int sync_pos, sync_pos_slot; // int sync_pos, sync_pos_slot;
// FILE *rx_frame_file; // FILE *rx_frame_file;
FILE *output_fd = NULL; FILE *output_fd = NULL;
...@@ -146,7 +148,7 @@ int main(int argc, char **argv) ...@@ -146,7 +148,7 @@ int main(int argc, char **argv)
randominit(0); 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) { switch (c) {
case 'f': case 'f':
write_output_file=1; write_output_file=1;
...@@ -212,6 +214,11 @@ int main(int argc, char **argv) ...@@ -212,6 +214,11 @@ int main(int argc, char **argv)
n_trials = atoi(optarg); n_trials = atoi(optarg);
break; break;
case 'o':
cfo = atof(optarg);
msg("Setting CFO to %f Hz\n",cfo);
break;
case 's': case 's':
snr0 = atof(optarg); snr0 = atof(optarg);
msg("Setting SNR0 to %f\n",snr0); msg("Setting SNR0 to %f\n",snr0);
...@@ -325,6 +332,7 @@ int main(int argc, char **argv) ...@@ -325,6 +332,7 @@ int main(int argc, char **argv)
printf("-z Number of RX antennas used in UE\n"); 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("-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("-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("-N Nid_cell\n");
printf("-R N_RB_DL\n"); printf("-R N_RB_DL\n");
printf("-O oversampling factor (1,2,4,8,16)\n"); printf("-O oversampling factor (1,2,4,8,16)\n");
...@@ -356,30 +364,49 @@ int main(int argc, char **argv) ...@@ -356,30 +364,49 @@ int main(int argc, char **argv)
frame_parms->nb_antennas_rx = n_rx; frame_parms->nb_antennas_rx = n_rx;
frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = 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); nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell);
phy_init_nr_gNB(gNB,0,0); phy_init_nr_gNB(gNB,0,0);
double fs,bw; double fs,bw,scs,eps;
if (mu == 1 && N_RB_DL == 217) { if (mu == 1 && N_RB_DL == 217) {
fs = 122.88e6; fs = 122.88e6;
bw = 80e6; bw = 80e6;
scs = 30000;
} }
else if (mu == 1 && N_RB_DL == 245) { else if (mu == 1 && N_RB_DL == 245) {
fs = 122.88e6; fs = 122.88e6;
bw = 90e6; bw = 90e6;
scs = 30000;
} }
else if (mu == 1 && N_RB_DL == 273) { else if (mu == 1 && N_RB_DL == 273) {
fs = 122.88e6; fs = 122.88e6;
bw = 100e6; bw = 100e6;
scs = 30000;
} }
else if (mu == 1 && N_RB_DL == 106) { else if (mu == 1 && N_RB_DL == 106) {
fs = 61.44e6; fs = 61.44e6;
bw = 40e6; bw = 40e6;
scs = 30000;
} }
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); 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, gNB2UE = new_channel_desc_scm(n_tx,
n_rx, n_rx,
channel_model, channel_model,
...@@ -435,6 +462,9 @@ int main(int argc, char **argv) ...@@ -435,6 +462,9 @@ int main(int argc, char **argv)
UE->perfect_ce = 0; 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) if (init_nr_ue_signal(UE, 1, 0) != 0)
{ {
printf("Error at UE NR initialisation\n"); printf("Error at UE NR initialisation\n");
...@@ -492,6 +522,7 @@ int main(int argc, char **argv) ...@@ -492,6 +522,7 @@ int main(int argc, char **argv)
// printf("txlev %d (%f)\n",txlev,10*log10(txlev)); // printf("txlev %d (%f)\n",txlev,10*log10(txlev));
for (i=0; i<frame_length_complex_samples; i++) { for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
...@@ -510,11 +541,32 @@ int main(int argc, char **argv) ...@@ -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); //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
//AWGN //AWGN
sigma2_dB = 10*log10((double)txlev)-SNR; sigma2_dB = 20*log10((double)AMP/4)-SNR;
sigma2 = pow(10,sigma2_dB/10); 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));
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; i<frame_parms->samples_per_subframe; i++) {
for (i=0; i<frame_length_complex_samples; i++) {
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
......
...@@ -96,3 +96,8 @@ target_link_libraries(pucch_uci_test ...@@ -96,3 +96,8 @@ target_link_libraries(pucch_uci_test
-Wl,--start-group UTIL SCHED_NR_UE_LIB PHY PHY_COMMON PHY_UE PHY_NR_UE -Wl,--end-group -Wl,--start-group UTIL SCHED_NR_UE_LIB PHY PHY_COMMON PHY_UE PHY_NR_UE -Wl,--end-group
pthread m ${ATLAS_LIBRARIES} pthread m ${ATLAS_LIBRARIES}
) )
add_executable(pucch_uci_generator_test ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c ${SRC_UNIT_TESTS} )
target_link_libraries(pucch_uci_generator_test
-Wl,--start-group UTIL SCHED_NR_UE_LIB PHY PHY_COMMON PHY_UE PHY_NR_UE -Wl,--end-group
pthread m ${ATLAS_LIBRARIES}
)
\ No newline at end of file
...@@ -192,11 +192,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) { retu ...@@ -192,11 +192,10 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) { retu
void * get_shlibmodule_fptr(char *modname, char *fname) { return(NULL) ; } void * get_shlibmodule_fptr(char *modname, char *fname) { return(NULL) ; }
void exit_fun(const char* s) /*void exit_fun (const char *s) {
{
VOID_PARAMETER s; VOID_PARAMETER s;
undefined_function(__FUNCTION__); undefined_function(__FUNCTION__);
} }*/
uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP,
uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe){ uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe){
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
/*************** LOCAL VARIABLES***********************************/ /*************** LOCAL VARIABLES***********************************/
static nfapi_config_request_t config_t; static nfapi_config_request_t config_t;
static nfapi_config_request_t* config =&config_t; static nfapi_config_request_t *config =&config_t;
/*************** FUNCTIONS ****************************************/ /*************** FUNCTIONS ****************************************/
...@@ -86,8 +86,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_eNB, uint8_t abstract ...@@ -86,8 +86,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_eNB, uint8_t abstract
* *
*********************************************************************/ *********************************************************************/
void phase_shift_samples(int16_t *samples, int length, int16_t phase_shift_re, int16_t phase_shift_im) void phase_shift_samples(int16_t *samples, int length, int16_t phase_shift_re, int16_t phase_shift_im) {
{
int16_t sample_re, sample_im; int16_t sample_re, sample_im;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
...@@ -112,22 +111,23 @@ void phase_shift_samples(int16_t *samples, int length, int16_t phase_shift_re, i ...@@ -112,22 +111,23 @@ void phase_shift_samples(int16_t *samples, int length, int16_t phase_shift_re, i
* *
*********************************************************************/ *********************************************************************/
void display_data(int pss_sequence_number, int16_t *rxdata, int position) void display_data(int pss_sequence_number, int16_t *rxdata, int position) {
{
#ifdef DEBUG_TEST_PSS #ifdef DEBUG_TEST_PSS
int16_t *pss_sequence[NUMBER_PSS_SEQUENCE] = {primary_synch0_time, primary_synch1_time, primary_synch2_time}; int16_t *pss_sequence[NUMBER_PSS_SEQUENCE] = {primary_synch0_time, primary_synch1_time, primary_synch2_time};
int16_t *pss_sequence_time = pss_sequence[pss_sequence_number]; int16_t *pss_sequence_time = pss_sequence[pss_sequence_number];
printf(" pss %6d data \n", pss_sequence_number); printf(" pss %6d data \n", pss_sequence_number);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (pss_sequence_number < NUMBER_PSS_SEQUENCE) { if (pss_sequence_number < NUMBER_PSS_SEQUENCE) {
printf("[i %6d] : %4d [i %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i], (i + position), rxdata[2*i + (position*2)], &(rxdata[2*i + (position*2)])); printf("[i %6d] : %4d [i %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i], (i + position), rxdata[2*i + (position*2)], &(rxdata[2*i + (position*2)]));
printf("[q %6d] : %4d [q %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i+1], (i + position), rxdata[2*i + 1 + (position*2)], &(rxdata[2*i + 1 + (position*2)])); printf("[q %6d] : %4d [q %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i+1], (i + position), rxdata[2*i + 1 + (position*2)], &(rxdata[2*i + 1 + (position*2)]));
} } else {
else {
printf("[i %6d] : Undef [i %6d] : %8i at address : %p \n", i, (i + position), rxdata[2*i + (position*2)], &(rxdata[2*i + (position*2)])); printf("[i %6d] : Undef [i %6d] : %8i at address : %p \n", i, (i + position), rxdata[2*i + (position*2)], &(rxdata[2*i + (position*2)]));
printf("[q %6d] : Undef [q %6d] : %8i at address : %p \n", i, (i + position), rxdata[2*i + 1 + (position*2)], &(rxdata[2*i + 1 + (position*2)])); printf("[q %6d] : Undef [q %6d] : %8i at address : %p \n", i, (i + position), rxdata[2*i + 1 + (position*2)], &(rxdata[2*i + 1 + (position*2)]));
} }
}nr_init_frame_parms }
nr_init_frame_parms
printf(" ... ... \n"); printf(" ... ... \n");
#else #else
(void) pss_sequence_number; (void) pss_sequence_number;
...@@ -149,11 +149,9 @@ void display_data(int pss_sequence_number, int16_t *rxdata, int position) ...@@ -149,11 +149,9 @@ void display_data(int pss_sequence_number, int16_t *rxdata, int position)
* *
*********************************************************************/ *********************************************************************/
void display_test_configuration_pss(int position, int pss_sequence_number) void display_test_configuration_pss(int position, int pss_sequence_number) {
{
const char next_test_text[] = "------------------------------------------------\n"; const char next_test_text[] = "------------------------------------------------\n";
const char test_text_pss[] = "Test nr pss with Nid2 %i at position %i \n"; const char test_text_pss[] = "Test nr pss with Nid2 %i at position %i \n";
printf(next_test_text); printf(next_test_text);
printf(test_text_pss, pss_sequence_number, position); printf(test_text_pss, pss_sequence_number, position);
} }
...@@ -171,8 +169,7 @@ void display_test_configuration_pss(int position, int pss_sequence_number) ...@@ -171,8 +169,7 @@ void display_test_configuration_pss(int position, int pss_sequence_number)
* *
*********************************************************************/ *********************************************************************/
void display_test_configuration_sss(int sss_sequence_number) void display_test_configuration_sss(int sss_sequence_number) {
{
const char test_text_sss[] = "Test nr sss with Nid1 %i \n"; const char test_text_sss[] = "Test nr sss with Nid1 %i \n";
printf(test_text_sss, sss_sequence_number); printf(test_text_sss, sss_sequence_number);
} }
...@@ -191,8 +188,7 @@ void display_test_configuration_sss(int sss_sequence_number) ...@@ -191,8 +188,7 @@ void display_test_configuration_sss(int sss_sequence_number)
* *
*********************************************************************/ *********************************************************************/
void undefined_function(const char *function) void undefined_function(const char *function) {
{
printf("%s undefined \n", function); printf("%s undefined \n", function);
printf("Warning: function \"%s\" has been replaced by an empty function for avoiding undefined function error at build \n", function); printf("Warning: function \"%s\" has been replaced by an empty function for avoiding undefined function error at build \n", function);
} }
...@@ -210,34 +206,22 @@ void undefined_function(const char *function) ...@@ -210,34 +206,22 @@ void undefined_function(const char *function)
*********************************************************************/ *********************************************************************/
int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode, int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, uint8_t N_RB_DL) unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, uint8_t N_RB_DL) {
{
(void) transmission_mode; (void) transmission_mode;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
int log_level = OAILOG_TRACE; int log_level = OAILOG_TRACE;
logInit(); logInit();
// enable these lines if you need debug info // enable these lines if you need debug info
//set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1); //set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
set_glog(log_level); set_glog(log_level);
#ifndef NR_UNIT_TEST #ifndef NR_UNIT_TEST
cpuf = get_cpu_freq_GHz(); cpuf = get_cpu_freq_GHz();
//LOG_I(PHY, "[CONFIG] Test of UE synchronisation \n");
LOG_I(PHY, "[CONFIG] Test of UE synchronisation \n");
set_component_filelog(USIM); // file located in /tmp/testSynchroue.txt set_component_filelog(USIM); // file located in /tmp/testSynchroue.txt
#endif #endif
//randominit(0); //randominit(0);
//set_taus_seed(0); //set_taus_seed(0);
printf("Start lte_param_init, frame_type %d, extended_prefix %d\n",frame_type,extended_prefix_flag); printf("Start lte_param_init, frame_type %d, extended_prefix %d\n",frame_type,extended_prefix_flag);
PHY_vars_UE = malloc(sizeof(PHY_VARS_NR_UE)); PHY_vars_UE = malloc(sizeof(PHY_VARS_NR_UE));
bzero(PHY_vars_UE, sizeof(PHY_VARS_NR_UE)); bzero(PHY_vars_UE, sizeof(PHY_VARS_NR_UE));
...@@ -245,7 +229,6 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission ...@@ -245,7 +229,6 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission
return(-1); return(-1);
frame_parms = &(PHY_vars_UE->frame_parms); frame_parms = &(PHY_vars_UE->frame_parms);
frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz
frame_parms->N_RB_UL = N_RB_DL; frame_parms->N_RB_UL = N_RB_DL;
frame_parms->Ncp = extended_prefix_flag; frame_parms->Ncp = extended_prefix_flag;
...@@ -257,33 +240,30 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission ...@@ -257,33 +240,30 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission
frame_parms->nb_antenna_ports_eNB = 1; frame_parms->nb_antenna_ports_eNB = 1;
frame_parms->threequarter_fs = 0; frame_parms->threequarter_fs = 0;
frame_parms->numerology_index = NUMEROLOGY_INDEX_MAX_NR; frame_parms->numerology_index = NUMEROLOGY_INDEX_MAX_NR;
int mu = 1;
nr_init_frame_parms_ue(frame_parms); int n_ssb_crb = 0;
int ssb_subcarrier_offset = 0;
nr_init_frame_parms_ue(frame_parms, mu, extended_prefix_flag, N_RB_DL, n_ssb_crb, ssb_subcarrier_offset);
PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + N_ID_2_NUMBER; /* set to unvalid value */ PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + N_ID_2_NUMBER; /* set to unvalid value */
//phy_init_nr_top(frame_parms); //phy_init_nr_top(frame_parms);
if (init_nr_ue_signal(PHY_vars_UE, 1, 0) != 0) if (init_nr_ue_signal(PHY_vars_UE, 1, 0) != 0) {
{
LOG_E(PHY,"Error at UE NR initialisation : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); LOG_E(PHY,"Error at UE NR initialisation : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
return (0); return (0);
} }
/* dummy initialisation of global structure PHY_vars_UE_g */ /* dummy initialisation of global structure PHY_vars_UE_g */
unsigned char NB_UE_INST=1; unsigned char NB_UE_INST=1;
PHY_vars_UE_g = (PHY_VARS_NR_UE ** *)calloc( NB_UE_INST, sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g = (PHY_VARS_NR_UE***)calloc( NB_UE_INST, sizeof(PHY_VARS_NR_UE**));
for (int UE_id=0; UE_id<NB_UE_INST; UE_id++) { for (int UE_id=0; UE_id<NB_UE_INST; UE_id++) {
PHY_vars_UE_g[UE_id] = (PHY_VARS_NR_UE**) calloc( MAX_NUM_CCs, sizeof(PHY_VARS_NR_UE*)); PHY_vars_UE_g[UE_id] = (PHY_VARS_NR_UE **) calloc( MAX_NUM_CCs, sizeof(PHY_VARS_NR_UE *));
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
//(frame_parms[CC_id])->nb_antennas_tx = 1; //(frame_parms[CC_id])->nb_antennas_tx = 1;
//(frame_parms[CC_id])->nb_antennas_rx = nb_antennas_rx_ue; //(frame_parms[CC_id])->nb_antennas_rx = nb_antennas_rx_ue;
// PHY_vars_UE_g[UE_id][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag); // PHY_vars_UE_g[UE_id][CC_id] = init_lte_UE(frame_parms[CC_id], UE_id,abstraction_flag);
PHY_vars_UE_g[UE_id][CC_id] = calloc(1, sizeof(PHY_VARS_NR_UE)); PHY_vars_UE_g[UE_id][CC_id] = calloc(1, sizeof(PHY_VARS_NR_UE));
PHY_vars_UE_g[UE_id][CC_id]->Mod_id=UE_id; PHY_vars_UE_g[UE_id][CC_id]->Mod_id=UE_id;
PHY_vars_UE_g[UE_id][CC_id]->CC_id=CC_id; PHY_vars_UE_g[UE_id][CC_id]->CC_id=CC_id;
...@@ -318,73 +298,66 @@ typedef enum { ...@@ -318,73 +298,66 @@ typedef enum {
#define FREQUENCY_15_MHZ (15360000L) #define FREQUENCY_15_MHZ (15360000L)
#define FREQUENCY (FREQUENCY_15_MHZ) /* to generate a frequency with a sampling of 30,72 MHz 5 gives 770 KHz, 20 gives 1,5 MHz, 40 gives 3 MHz */ #define FREQUENCY (FREQUENCY_15_MHZ) /* to generate a frequency with a sampling of 30,72 MHz 5 gives 770 KHz, 20 gives 1,5 MHz, 40 gives 3 MHz */
void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) {
{ NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int samples_for_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
int samples_for_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); int16_t random;
int16_t random; int16_t *data_p;
int16_t *data_p; random_data_format_t data_format = SINUSOIDAL_DATA;
random_data_format_t data_format = SINUSOIDAL_DATA;
/* reinitialise random for always getting same data */ /* reinitialise random for always getting same data */
srand(0); srand(0);
double n = 0; double n = 0;
for (int aa=0;aa<PHY_vars_UE->frame_parms.nb_antennas_rx;aa++) { for (int aa=0; aa<PHY_vars_UE->frame_parms.nb_antennas_rx; aa++) {
data_p = (int16_t *) &(PHY_vars_UE->common_vars.rxdata[aa][0]); data_p = (int16_t *) &(PHY_vars_UE->common_vars.rxdata[aa][0]);
int frequency_switch = samples_for_frame/LTE_NUMBER_OF_SUBFRAMES_PER_FRAME; int frequency_switch = samples_for_frame/LTE_NUMBER_OF_SUBFRAMES_PER_FRAME;
int frequency_step = 0; int frequency_step = 0;
double beat = (2*M_PI*FREQUENCY_15_MHZ)/(SAMPLING_RATE); double beat = (2*M_PI*FREQUENCY_15_MHZ)/(SAMPLING_RATE);
for (int i=0; i< samples_for_frame; i++) { for (int i=0; i< samples_for_frame; i++) {
switch(data_format) { switch(data_format) {
case ZERO_DATA: case ZERO_DATA: {
{
/* all data are forced to zero */ /* all data are forced to zero */
random = 0; random = 0;
break; break;
} }
case SINUSOIDAL_DATA:
{ case SINUSOIDAL_DATA: {
/* sinusoidal signal */ /* sinusoidal signal */
n = cos(beat*i); n = cos(beat*i);
random = n * (amp * SCALING_SINUSOIDAL_DATA); random = n * (amp * SCALING_SINUSOIDAL_DATA);
frequency_step++; frequency_step++;
if (frequency_step == frequency_switch) { if (frequency_step == frequency_switch) {
beat = beat/2; /* frequency is divided by 2 */ beat = beat/2; /* frequency is divided by 2 */
//printf("frequency %f at %d\n", (beat/2*M_PI), i); //printf("frequency %f at %d\n", (beat/2*M_PI), i);
frequency_step = 0; frequency_step = 0;
} }
//printf("%d : cos %d %d \n", i, n, random); //printf("%d : cos %d %d \n", i, n, random);
break; break;
} }
case RANDOM_DATA:
{ case RANDOM_DATA: {
/* random data can take any value between -SHRT_MAX and SHRT_MAX */ /* random data can take any value between -SHRT_MAX and SHRT_MAX */
/* in this case one can use maxim value for uint16 because there is no saturation */ /* in this case one can use maxim value for uint16 because there is no saturation */
#define SCALING_RANDOM_DATA (24) /* 48 is max value without decimation */ #define SCALING_RANDOM_DATA (24) /* 48 is max value without decimation */
#define RANDOM_MAX_AMP (amp * SCALING_RANDOM_DATA) #define RANDOM_MAX_AMP (amp * SCALING_RANDOM_DATA)
random = ((rand() % RANDOM_MAX_AMP) - RANDOM_MAX_AMP/2); random = ((rand() % RANDOM_MAX_AMP) - RANDOM_MAX_AMP/2);
break; break;
} }
case RANDOM_MAX_DATA:
{ case RANDOM_MAX_DATA: {
/* random data can take only two value (-RANDOM_MAX) or RANDOM_MAX */ /* random data can take only two value (-RANDOM_MAX) or RANDOM_MAX */
/* In this case saturation can occur with value of scaling_value greater than 23 */ /* In this case saturation can occur with value of scaling_value greater than 23 */
#define SCALING_RANDOM_MAX_DATA (8) #define SCALING_RANDOM_MAX_DATA (8)
#define RANDOM_VALUE (amp * SCALING_RANDOM_DATA) #define RANDOM_VALUE (amp * SCALING_RANDOM_DATA)
const int random_number[2] = {-1,+1}; const int random_number[2] = {-1,+1};
random = random_number[rand()%2] * RANDOM_VALUE; random = random_number[rand()%2] * RANDOM_VALUE;
break; break;
} }
default:
{ default: {
printf("Format of data is undefined \n"); printf("Format of data is undefined \n");
assert(0); assert(0);
break; break;
...@@ -393,12 +366,13 @@ random_data_format_t data_format = SINUSOIDAL_DATA; ...@@ -393,12 +366,13 @@ random_data_format_t data_format = SINUSOIDAL_DATA;
data_p[2*i] = random; data_p[2*i] = random;
data_p[2*i+1] = random; data_p[2*i+1] = random;
#if 0 #if 0
if (i < 10) { if (i < 10) {
printf("random %d \n", random); printf("random %d \n", random);
printf("data[%d] : %d %d at address %p \n", i, data_p[2*i], data_p[2*i+1], &data_p[2*i]); printf("data[%d] : %d %d at address %p \n", i, data_p[2*i], data_p[2*i+1], &data_p[2*i]);
} }
#endif #endif
} }
} }
...@@ -418,23 +392,22 @@ random_data_format_t data_format = SINUSOIDAL_DATA; ...@@ -418,23 +392,22 @@ random_data_format_t data_format = SINUSOIDAL_DATA;
* *
*********************************************************************/ *********************************************************************/
int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short *input_buffer) int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short *input_buffer) {
{
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int samples_for_frame = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe; /* both i and q */ int samples_for_frame = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe; /* both i and q */
for (int aa=0;aa<PHY_vars_UE->frame_parms.nb_antennas_rx;aa++) { for (int aa=0; aa<PHY_vars_UE->frame_parms.nb_antennas_rx; aa++) {
for (int i = 0; i < samples_for_frame; i++) { for (int i = 0; i < samples_for_frame; i++) {
((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[2*i] = input_buffer[2*i]; /* real part */ ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[2*i] = input_buffer[2*i]; /* real part */
((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[2*i+1] = input_buffer[2*i+1]; /* imaginary part */ ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[2*i+1] = input_buffer[2*i+1]; /* imaginary part */
} }
} }
/* check that sequence has been properly copied */ /* check that sequence has been properly copied */
for (int aa=0;aa<PHY_vars_UE->frame_parms.nb_antennas_rx;aa++) { for (int aa=0; aa<PHY_vars_UE->frame_parms.nb_antennas_rx; aa++) {
for (int i=0; i<samples_for_frame; i++) { for (int i=0; i<samples_for_frame; i++) {
if ((input_buffer[2*i] != ((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[2*i]) if ((input_buffer[2*i] != ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[2*i])
|| (input_buffer[2*i+1] != ((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[2*i+1])) { || (input_buffer[2*i+1] != ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[2*i+1])) {
printf("Sequence pss was not properly copied into received buffer at index %d \n", i); printf("Sequence pss was not properly copied into received buffer at index %d \n", i);
exit(-1); exit(-1);
} }
...@@ -466,15 +439,13 @@ int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short ...@@ -466,15 +439,13 @@ int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short
* *
*********************************************************************/ *********************************************************************/
int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) {
{
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int samples_for_frame = frame_parms->samples_per_frame; int samples_for_frame = frame_parms->samples_per_frame;
int16_t *pss_sequence_time; int16_t *pss_sequence_time;
if ((position_symbol > samples_for_frame) if ((position_symbol > samples_for_frame)
|| ((position_symbol + frame_parms->ofdm_symbol_size) > samples_for_frame)) || ((position_symbol + frame_parms->ofdm_symbol_size) > samples_for_frame)) {
{
printf("This pss sequence can not be fully written in the received window \n"); printf("This pss sequence can not be fully written in the received window \n");
return (-1); return (-1);
} }
...@@ -486,18 +457,18 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p ...@@ -486,18 +457,18 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p
pss_sequence_time = primary_synchro_time_nr[pss_sequence_number]; pss_sequence_time = primary_synchro_time_nr[pss_sequence_number];
for (int aa=0;aa<PHY_vars_UE->frame_parms.nb_antennas_rx;aa++) { for (int aa=0; aa<PHY_vars_UE->frame_parms.nb_antennas_rx; aa++) {
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i)] = pss_sequence_time[2*i]; /* real part */ ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i)] = pss_sequence_time[2*i]; /* real part */
((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i+1)] = pss_sequence_time[2*i+1]; /* imaginary part */ ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i+1)] = pss_sequence_time[2*i+1]; /* imaginary part */
} }
} }
/* check that sequence has been properly copied */ /* check that sequence has been properly copied */
for (int aa=0;aa<PHY_vars_UE->frame_parms.nb_antennas_rx;aa++) { for (int aa=0; aa<PHY_vars_UE->frame_parms.nb_antennas_rx; aa++) {
for (int i=0; i<(frame_parms->ofdm_symbol_size); i++) { for (int i=0; i<(frame_parms->ofdm_symbol_size); i++) {
if ((pss_sequence_time[2*i] != ((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i)]) if ((pss_sequence_time[2*i] != ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i)])
|| (pss_sequence_time[2*i+1] != ((int16_t*)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i+1)])) { || (pss_sequence_time[2*i+1] != ((int16_t *)PHY_vars_UE->common_vars.rxdata[aa])[(position_symbol*2) + (2*i+1)])) {
printf("Sequence pss was not properly copied into received buffer at index %d \n", i); printf("Sequence pss was not properly copied into received buffer at index %d \n", i);
exit(-1); exit(-1);
} }
...@@ -525,11 +496,9 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p ...@@ -525,11 +496,9 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p
* *
*********************************************************************/ *********************************************************************/
void set_sequence_pss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) void set_sequence_pss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) {
{
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
int samples_for_frame = frame_parms->samples_per_frame; int samples_for_frame = frame_parms->samples_per_frame;
/* initialise received ue data with random */ /* initialise received ue data with random */
set_random_rx_buffer(PHY_vars_UE, AMP); set_random_rx_buffer(PHY_vars_UE, AMP);
...@@ -543,6 +512,7 @@ void set_sequence_pss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_ ...@@ -543,6 +512,7 @@ void set_sequence_pss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_
printf("This position for pss sequence %d is not supported because it exceeds the frame length %d!\n", position_symbol, samples_for_frame); printf("This position for pss sequence %d is not supported because it exceeds the frame length %d!\n", position_symbol, samples_for_frame);
exit(0); exit(0);
} }
if (set_pss_in_rx_buffer(PHY_vars_UE, position_symbol, pss_sequence_number) != 0) if (set_pss_in_rx_buffer(PHY_vars_UE, position_symbol, pss_sequence_number) != 0)
printf("Warning: pss sequence can not be properly written into received buffer !\n"); printf("Warning: pss sequence can not be properly written into received buffer !\n");
} }
......
#include "../../unit_tests/src/pss_util_test.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/INIT/init_extern.h"
#include "PHY/phy_extern_nr_ue.h"
/*
#include "SCHED_NR_UE/defs.h"
#include "SCHED_NR/extern.h"
#include "SCHED_NR_UE/harq_nr.h"
*/
#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
/**************** define **************************************/
#define TST_GNB_ID_0 (0) /* first index of gNB */
#define TST_THREAD_ID (0)
int test_pucch_generators(PHY_VARS_NR_UE *ue) {
int gNB_id = TST_GNB_ID_0;
int thread_number = TST_THREAD_ID;
int TB_identifier = 0;
int v_return = 0;
pucch_format_nr_t format = pucch_format2_nr;
uint8_t starting_symbol_index;
uint8_t nb_symbols_total = 4;
uint16_t starting_prb = 0;; /* it can be considered as first hop on case of pucch hopping */
uint16_t second_hop = 0; /* second part for pucch for hopping */
uint8_t nb_of_prbs = 1;
switch (format) {
case pucch_format0_nr:
nb_symbols_total = 2;
nb_of_prbs = 1;
starting_symbol_index = 0;
break;
case pucch_format1_nr:
nb_symbols_total = 5;
nb_of_prbs = 1;
starting_symbol_index = 0;
break;
case pucch_format2_nr:
nb_symbols_total = 2;
nb_of_prbs = 16;
starting_symbol_index = 0;
break;
}
int m_0 = 0; /* format 0 only */
int m_CS = 0; /* for all format except for format 0 */
int index_additional_dmrs = I_PUCCH_NO_ADDITIONAL_DMRS;
int index_hopping = I_PUCCH_NO_HOPPING;
int time_domain_occ = 0;
int occ_length = 0;
int occ_Index = 0;
uint64_t pucch_payload = 0;
int tx_amp = 512;
int nr_tti_tx = 0;
int N_UCI = 0; /* size in bits for Uplink Control Information */
switch(format) {
case pucch_format0_nr: {
nr_generate_pucch0(ue,ue->common_vars.txdataF,
&ue->frame_parms,
&ue->pucch_config_dedicated_nr[gNB_id],
tx_amp,
nr_tti_tx,
(uint8_t)m_0,
(uint8_t)m_CS,
nb_symbols_total,
starting_symbol_index,
starting_prb);
break;
}
case pucch_format1_nr: {
nr_generate_pucch1(ue,ue->common_vars.txdataF,
&ue->frame_parms,
&ue->pucch_config_dedicated_nr[gNB_id],
pucch_payload,
tx_amp,
nr_tti_tx,
(uint8_t)m_0,
nb_symbols_total,
starting_symbol_index,
starting_prb,
second_hop,
(uint8_t)time_domain_occ,
(uint8_t)N_UCI);
break;
}
case pucch_format2_nr: {
nr_generate_pucch2(ue,
ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti,
ue->common_vars.txdataF,
&ue->frame_parms,
&ue->pucch_config_dedicated_nr[gNB_id],
pucch_payload,
tx_amp,
nr_tti_tx,
nb_symbols_total,
starting_symbol_index,
nb_of_prbs,
starting_prb,
(uint8_t)N_UCI);
break;
}
case pucch_format3_nr:
case pucch_format4_nr: {
nr_generate_pucch3_4(ue,
ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti,
ue->common_vars.txdataF,
&ue->frame_parms,
format,
&ue->pucch_config_dedicated_nr[gNB_id],
pucch_payload,
tx_amp,
nr_tti_tx,
nb_symbols_total,
starting_symbol_index,
nb_of_prbs,
starting_prb,
second_hop,
(uint8_t)N_UCI,
(uint8_t)occ_length,
(uint8_t)occ_Index);
break;
}
}
return (v_return);
}
int main(int argc, char *argv[]) {
uint8_t transmission_mode = 1;
uint8_t nb_antennas_tx = 1;
uint8_t nb_antennas_rx = 1;
uint8_t frame_type = FDD;
uint8_t N_RB_DL=106;
lte_prefix_type_t extended_prefix_flag = NORMAL;
int Nid_cell[] = {(3*1+3)};
VOID_PARAMETER argc;
VOID_PARAMETER argv;
printf(" PUCCH TEST \n");
printf("-----------\n");
if (init_test(nb_antennas_tx, nb_antennas_rx, transmission_mode, extended_prefix_flag, frame_type, Nid_cell[0], N_RB_DL) != 0) {
printf("Initialisation problem for test \n");
exit(-1);;
}
if (test_pucch_generators(PHY_vars_UE) != 0) {
printf("\nTest PUCCH is fail \n");
} else {
printf("\nTest PUCCH is pass \n");
}
free_context_synchro_nr();
return(0);
}
...@@ -107,10 +107,10 @@ void rf_rx(double **r_re, ...@@ -107,10 +107,10 @@ void rf_rx(double **r_re,
exit(-1); exit(-1);
} }
if (fabs(f_off) > 10000.0) { /* if (fabs(f_off) > 10000.0) {
printf("rf.c: Illegal f_off %f\n",f_off); printf("rf.c: Illegal f_off %f\n",f_off);
exit(-1); exit(-1);
} }*/
if (fabs(drift) > 1000.0) { if (fabs(drift) > 1000.0) {
printf("rf.c: Illegal drift %f\n",drift); printf("rf.c: Illegal drift %f\n",drift);
......
...@@ -437,7 +437,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, ...@@ -437,7 +437,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
/*if (slotP==2) /*if (slotP==2)
nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/ nr_schedule_css_dlsch_phytest(module_idP, frameP, slotP);*/
if (slotP==2) if (slotP==1)
nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP); nr_schedule_uss_dlsch_phytest(module_idP, frameP, slotP);
/* /*
......
...@@ -292,7 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) { ...@@ -292,7 +292,7 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) {
uint32_t number_of_search_space_per_slot=1; uint32_t number_of_search_space_per_slot=1;
uint32_t first_symbol_index=0; 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 uint32_t coreset_duration; // element of coreset
coreset_duration = num_symbols * number_of_search_space_per_slot; coreset_duration = num_symbols * number_of_search_space_per_slot;
......
...@@ -444,6 +444,7 @@ static void *UE_thread_synch(void *arg) { ...@@ -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); //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; 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", 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, hw_slot_offset,
...@@ -457,16 +458,13 @@ static void *UE_thread_synch(void *arg) { ...@@ -457,16 +458,13 @@ static void *UE_thread_synch(void *arg) {
// rerun with new cell parameters and frequency-offset // rerun with new cell parameters and frequency-offset
for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { for (i=0; i<openair0_cfg[UE->rf_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; 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) 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 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].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]; 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]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
freq_offset=0;
}
} }
// reconfigure for potentially different bandwidth // reconfigure for potentially different bandwidth
...@@ -602,7 +600,7 @@ static void *UE_thread_synch(void *arg) { ...@@ -602,7 +600,7 @@ static void *UE_thread_synch(void *arg) {
phy_scope_UE(form_ue[0], phy_scope_UE(form_ue[0],
PHY_vars_UE_g[0][0], PHY_vars_UE_g[0][0],
0,0,7); 0,0,1);
} }
#endif #endif
...@@ -693,6 +691,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { ...@@ -693,6 +691,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req; UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response); nr_ue_scheduled_response(&UE_mac->scheduled_response);
#ifdef UE_SLOT_PARALLELISATION #ifdef UE_SLOT_PARALLELISATION
...@@ -920,7 +919,7 @@ void *UE_thread(void *arg) { ...@@ -920,7 +919,7 @@ void *UE_thread(void *arg) {
if(thread_idx>=RX_NB_TH) if(thread_idx>=RX_NB_TH)
thread_idx = 0; thread_idx = 0;
printf("slot_nr %d nb slot frame %d\n",slot_nr, nb_slot_frame); //printf("slot_nr %d nb slot frame %d\n",slot_nr, nb_slot_frame);
slot_nr++; slot_nr++;
slot_nr %= nb_slot_frame; slot_nr %= nb_slot_frame;
...@@ -1110,6 +1109,7 @@ void *UE_thread(void *arg) { ...@@ -1110,6 +1109,7 @@ void *UE_thread(void *arg) {
NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0);
UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req; UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req;
UE_mac->scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&UE_mac->scheduled_response); nr_ue_scheduled_response(&UE_mac->scheduled_response);
//write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1); //write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1);
......
...@@ -130,6 +130,7 @@ static char *itti_dump_file = NULL; ...@@ -130,6 +130,7 @@ static char *itti_dump_file = NULL;
int UE_scan = 0; int UE_scan = 0;
int UE_scan_carrier = 0; int UE_scan_carrier = 0;
int UE_fo_compensation = 0;
runmode_t mode = normal_txrx; runmode_t mode = normal_txrx;
FILE *input_fd=NULL; FILE *input_fd=NULL;
...@@ -978,6 +979,7 @@ int main( int argc, char **argv ) { ...@@ -978,6 +979,7 @@ int main( int argc, char **argv ) {
UE[CC_id]->UE_scan = UE_scan; UE[CC_id]->UE_scan = UE_scan;
UE[CC_id]->UE_scan_carrier = UE_scan_carrier; UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
UE[CC_id]->UE_fo_compensation = UE_fo_compensation;
UE[CC_id]->mode = mode; UE[CC_id]->mode = mode;
printf("UE[%d]->mode = %d\n",CC_id,mode); printf("UE[%d]->mode = %d\n",CC_id,mode);
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n" #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_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\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_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_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" #define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
...@@ -135,6 +136,7 @@ ...@@ -135,6 +136,7 @@
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ {"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-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-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}, \ {"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}, \ {"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}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
......
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