Commit ebcbad62 authored by Francesco Mani's avatar Francesco Mani

Merge branch 'develop-nr' into nr_segmentation_fixes

parents 053914d5 bc864d13
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
\ No newline at end of file
...@@ -44,7 +44,7 @@ pipeline { ...@@ -44,7 +44,7 @@ pipeline {
disableConcurrentBuilds() disableConcurrentBuilds()
timestamps() timestamps()
gitLabConnection('OAI GitLab') gitLabConnection('OAI GitLab')
gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"]) gitlabBuilds(builds: ["Build gNB-USRP", "Build nr-UE-USRP", "Build eNB-USRP", "Build basic-sim", "Build phy-sim", "Build eNB-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO", "Test-TDD-Band78-gNB-NR-UE"])
ansiColor('xterm') ansiColor('xterm')
} }
...@@ -131,8 +131,8 @@ pipeline { ...@@ -131,8 +131,8 @@ pipeline {
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password']
]) { ]) {
sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1"
sh "git checkout develop >> ../git_clone.log 2>&1"
} }
sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies"
sh "zip -r -qq flexran.zip ." sh "zip -r -qq flexran.zip ."
} }
} }
...@@ -578,6 +578,25 @@ pipeline { ...@@ -578,6 +578,25 @@ pipeline {
} }
} }
} }
stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") {
steps {
script {
triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU')
}
}
post {
always {
script {
finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
stage ("Test OAI UE - FDD - Band 20 - B200") { stage ("Test OAI UE - FDD - Band 20 - B200") {
steps { steps {
script { script {
......
...@@ -68,11 +68,12 @@ function build_on_vm { ...@@ -68,11 +68,12 @@ function build_on_vm {
then then
echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_MEMORY = $VM_MEMORY MBytes"
echo "VM_CPU = $VM_CPU" echo "VM_CPU = $VM_CPU"
echo "VM_DISK = $VM_DISK GBytes"
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 acquire_vm_create_lock
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --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
...@@ -179,8 +180,12 @@ function build_on_vm { ...@@ -179,8 +180,12 @@ function build_on_vm {
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS
echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS
echo "echo \"mkdir build\"" >> $VM_CMDS
echo "mkdir build" >> $VM_CMDS
echo "echo \"cd build\"" >> $VM_CMDS
echo "cd build" >> $VM_CMDS
echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS
echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS echo "$BUILD_OPTIONS > ../cmake_targets/log/rt_controller.Rel15.txt 2>&1" >> $VM_CMDS
fi fi
if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]]
then then
......
...@@ -85,12 +85,13 @@ function create_vm { ...@@ -85,12 +85,13 @@ function create_vm {
echo "VM_NAME = $VM_NAME" echo "VM_NAME = $VM_NAME"
echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_MEMORY = $VM_MEMORY MBytes"
echo "VM_CPU = $VM_CPU" echo "VM_CPU = $VM_CPU"
echo "VM_DISK = $VM_DISK GBytes"
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 acquire_vm_create_lock
uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --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
......
...@@ -128,6 +128,7 @@ class SSHConnection(): ...@@ -128,6 +128,7 @@ class SSHConnection():
self.Build_eNB_args = '' self.Build_eNB_args = ''
self.backgroundBuild = False self.backgroundBuild = False
self.backgroundBuildTestId = ['', '', ''] self.backgroundBuildTestId = ['', '', '']
self.Build_eNB_forced_workspace_cleanup = False
self.Initialize_eNB_args = '' self.Initialize_eNB_args = ''
self.air_interface = 'lte' self.air_interface = 'lte'
self.eNB_instance = '' self.eNB_instance = ''
...@@ -370,9 +371,16 @@ class SSHConnection(): ...@@ -370,9 +371,16 @@ class SSHConnection():
self.air_interface = 'nr' self.air_interface = 'nr'
else: else:
self.air_interface = 'lte' self.air_interface = 'lte'
if self.Build_eNB_forced_workspace_cleanup:
self.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15)
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None:
full_ran_repo_name = self.ranRepository
else:
full_ran_repo_name = self.ranRepository + '.git'
self.command('mkdir -p ' + lSourcePath, '\$', 5) self.command('mkdir -p ' + lSourcePath, '\$', 5)
self.command('cd ' + lSourcePath, '\$', 5) self.command('cd ' + lSourcePath, '\$', 5)
self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
# Raphael: here add a check if git clone or git fetch went smoothly # Raphael: here add a check if git clone or git fetch went smoothly
self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
self.command('git config user.name "OAI Jenkins"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5)
...@@ -537,7 +545,7 @@ class SSHConnection(): ...@@ -537,7 +545,7 @@ class SSHConnection():
ue_prefix = '' ue_prefix = ''
self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
self.command('cd ' + self.UESourceCodePath, '\$', 5) self.command('cd ' + self.UESourceCodePath, '\$', 5)
self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600)
# here add a check if git clone or git fetch went smoothly # here add a check if git clone or git fetch went smoothly
self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
self.command('git config user.name "OAI Jenkins"', '\$', 5) self.command('git config user.name "OAI Jenkins"', '\$', 5)
...@@ -4158,6 +4166,14 @@ def CheckClassValidity(action,id): ...@@ -4158,6 +4166,14 @@ def CheckClassValidity(action,id):
def GetParametersFromXML(action): def GetParametersFromXML(action):
if action == 'Build_eNB': if action == 'Build_eNB':
SSH.Build_eNB_args = test.findtext('Build_eNB_args') SSH.Build_eNB_args = test.findtext('Build_eNB_args')
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
if (forced_workspace_cleanup is None):
SSH.Build_eNB_forced_workspace_cleanup = False
else:
if re.match('true', forced_workspace_cleanup, re.IGNORECASE):
SSH.Build_eNB_forced_workspace_cleanup = True
else:
SSH.Build_eNB_forced_workspace_cleanup = False
SSH.eNB_instance = test.findtext('eNB_instance') SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None): if (SSH.eNB_instance is None):
SSH.eNB_instance = '0' SSH.eNB_instance = '0'
......
...@@ -52,7 +52,7 @@ function variant_usage { ...@@ -52,7 +52,7 @@ function variant_usage {
if [ "$1" = "full" ] if [ "$1" = "full" ]
then then
printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC" printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC"
printf " VM_MEMORY=%-15s VM_CPU=%-15s\n" "$VM_MEMORY" "$VM_CPU" printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK"
printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\"" printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\""
printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL" printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL"
fi fi
...@@ -185,6 +185,7 @@ function variant__v3__phy_sim { ...@@ -185,6 +185,7 @@ function variant__v3__phy_sim {
NB_PATTERN_FILES=12 NB_PATTERN_FILES=12
BUILD_OPTIONS="--phy_simulators" BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192 VM_MEMORY=8192
VM_DISK=20
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b"
} }
...@@ -196,11 +197,15 @@ function variant__v4__cppcheck { ...@@ -196,11 +197,15 @@ function variant__v4__cppcheck {
} }
function variant__v5__gnb_usrp { function variant__v5__gnb_usrp {
VM_MEMORY=8192
VM_CPU=8
NB_PATTERN_FILES=9 NB_PATTERN_FILES=9
BUILD_OPTIONS="--gNB -w USRP" BUILD_OPTIONS="--gNB -w USRP"
} }
function variant__v6__nr_ue_usrp { function variant__v6__nr_ue_usrp {
VM_MEMORY=4096
VM_CPU=4
NB_PATTERN_FILES=9 NB_PATTERN_FILES=9
BUILD_OPTIONS="--nrUE -w USRP" BUILD_OPTIONS="--nrUE -w USRP"
} }
...@@ -222,7 +227,7 @@ function variant__v8__ue_ethernet { ...@@ -222,7 +227,7 @@ function variant__v8__ue_ethernet {
function variant__v10__flexran_rtc { function variant__v10__flexran_rtc {
ARCHIVES_LOC=flexran ARCHIVES_LOC=flexran
NB_PATTERN_FILES=1 NB_PATTERN_FILES=1
BUILD_OPTIONS="cmake . && make -j2" BUILD_OPTIONS="cmake .. && make -j2"
VARIANT_INFO="non-OSA" VARIANT_INFO="non-OSA"
} }
...@@ -233,8 +238,8 @@ function variant__v20__l1_sim { ...@@ -233,8 +238,8 @@ function variant__v20__l1_sim {
} }
function variant__v21__rf_sim { function variant__v21__rf_sim {
ARCHIVES_LOC=rf_sim
RUN_OPTIONS="complex" RUN_OPTIONS="complex"
EXPERIMENTAL="true"
} }
function variant__v22__l2_sim { function variant__v22__l2_sim {
...@@ -272,6 +277,7 @@ function check_set_variant { ...@@ -272,6 +277,7 @@ function check_set_variant {
ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"} ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"}
VM_MEMORY=2048 VM_MEMORY=2048
VM_CPU=4 VM_CPU=4
VM_DISK=10
EXPERIMENTAL="" EXPERIMENTAL=""
NBARGS=$[$NBARGS+$VARIANT_OPTID] NBARGS=$[$NBARGS+$VARIANT_OPTID]
variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"} variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"}
...@@ -494,6 +500,7 @@ AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER ...@@ -494,6 +500,7 @@ AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER
# -V<xx> option. # -V<xx> option.
VM_NAME="" VM_NAME=""
VM_MEMORY=0 VM_MEMORY=0
VM_DISK=0
VM_CPU=0 VM_CPU=0
ARCHIVES_LOC="" ARCHIVES_LOC=""
LOG_PATTERN="" LOG_PATTERN=""
......
...@@ -97,14 +97,20 @@ function analyzeIperfFiles { ...@@ -97,14 +97,20 @@ function analyzeIperfFiles {
FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE`
if [ $FILE_COMPLETE -eq 0 ] if [ $FILE_COMPLETE -eq 0 ]
then then
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"`
FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'`
EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}else{printf "%.2f KBits/sec", br/1000}}'`
PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'`
PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'`
JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'`
PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'`
PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"`
if [[ $PERF_INT -lt 80 ]]
then
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
else
echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
fi
else else
EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"`
if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]]
...@@ -394,6 +400,126 @@ function report_test { ...@@ -394,6 +400,126 @@ function report_test {
echo " </div>" >> ./test_simulator_results.html echo " </div>" >> ./test_simulator_results.html
fi fi
ARCHIVES_LOC=archives/rf_sim/test
if [ -d $ARCHIVES_LOC ]
then
echo " <h3>5G NR RF Simulator Check</h3>" >> ./test_simulator_results.html
if [ -f $ARCHIVES_LOC/test_final_status.log ]
then
if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ]
then
echo " <div class=\"alert alert-success\">" >> ./test_simulator_results.html
echo " <strong>TEST was SUCCESSFUL <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
else
echo " <div class=\"alert alert-danger\">" >> ./test_simulator_results.html
echo " <strong>TEST was a FAILURE! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
else
echo " <div class=\"alert alert-danger\">" >> ./test_simulator_results.html
echo " <strong>COULD NOT DETERMINE TEST FINAL STATUS! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
echo " <button data-toggle=\"collapse\" data-target=\"#oai-rf-sim-test-details\">More details on 5G RF Simulator test results</button>" >> ./test_simulator_results.html
echo " <div id=\"oai-rf-sim-test-details\" class=\"collapse\">" >> ./test_simulator_results.html
echo " <table border = \"1\">" >> ./test_simulator_results.html
echo " <tr bgcolor = \"#33CCFF\" >" >> ./test_simulator_results.html
echo " <th>Log File Name</th>" >> ./test_simulator_results.html
echo " <th>Command</th>" >> ./test_simulator_results.html
echo " <th>Status</th>" >> ./test_simulator_results.html
echo " <th>Statistics</th>" >> ./test_simulator_results.html
echo " </tr>" >> ./test_simulator_results.html
EPC_CONFIGS=("noS1")
TRANS_MODES=("tdd")
BW_CASES=(106)
for CN_CONFIG in ${EPC_CONFIGS[@]}
do
for TMODE in ${TRANS_MODES[@]}
do
for BW in ${BW_CASES[@]}
do
echo " <tr bgcolor = \"#8FBC8F\" >" >> ./test_simulator_results.html
if [[ $CN_CONFIG =~ .*wS1.* ]]
then
echo " <td align = \"center\" colspan = 4 >Test with EPC (aka withS1): ${TMODE} -- ${BW}PRB </td>" >> ./test_simulator_results.html
else
echo " <td align = \"center\" colspan = 4 >Test without EPC (aka noS1): ${TMODE} -- ${BW}PRB </td>" >> ./test_simulator_results.html
fi
echo " </tr>" >> ./test_simulator_results.html
ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log
UE_LOG=`echo $ENB_LOG | sed -e "s#gnb#ue#"`
if [ -f $ENB_LOG ] && [ -f $UE_LOG ]
then
NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"`
NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"`
echo " <tr>" >> ./test_simulator_results.html
echo " <td>$NAME_ENB --- $NAME_UE</td>" >> ./test_simulator_results.html
echo " <td>N/A</td>" >> ./test_simulator_results.html
NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG`
NB_ENB_TUNNEL_UP=`egrep -c "Interface oaitun_enb1 successfuly configured" $ENB_LOG`
NB_UE_GOT_SYNC=`egrep -c "rfsimulator: Success" $UE_LOG`
NB_ENB_SYNCED_WITH_UE=`egrep -c "Initial sync: starting PBCH detection" $UE_LOG`
NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfuly configured" $UE_LOG`
if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
then
echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html
else
echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html
fi
echo " <td><pre>" >> ./test_simulator_results.html
if [ $NB_ENB_GOT_SYNC -gt 0 ]
then
echo "<font color = \"blue\">- gNB --> got sync</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- gNB NEVER got sync</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_ENB_TUNNEL_UP -gt 0 ]
then
echo "<font color = \"blue\">- gNB mounted oaitun_enb1 interface</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- gNB NEVER mounted oaitun_enb1 interface</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_UE_GOT_SYNC -gt 0 ]
then
echo "<font color = \"blue\">- NR UE --> got sync</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- NR UE NEVER got sync</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
then
echo "<font color = \"blue\">- NR UE attached to gNB</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- NR UE NEVER attached to eNB</b></font>" >> ./test_simulator_results.html
fi
if [ $NB_UE_TUNNEL_UP -gt 0 ]
then
echo "<font color = \"blue\">- NR UE mounted oaitun_ue1 interface</font>" >> ./test_simulator_results.html
else
echo "<font color = \"red\"><b>- NR UE NEVER mounted oaitun_ue1 interface</b></font>" >> ./test_simulator_results.html
fi
echo " </pre></td>" >> ./test_simulator_results.html
echo " </tr>" >> ./test_simulator_results.html
fi
#PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null`
#analyzePingFiles
IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null`
analyzeIperfFiles
#IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null`
#analyzeIperfFiles
done
done
done
echo " </table>" >> ./test_simulator_results.html
echo " </div>" >> ./test_simulator_results.html
fi
ARCHIVES_LOC=archives/l2_sim/test ARCHIVES_LOC=archives/l2_sim/test
if [ -d $ARCHIVES_LOC ] if [ -d $ARCHIVES_LOC ]
then then
......
This diff is collapsed.
...@@ -76,6 +76,8 @@ function wait_on_vm_build { ...@@ -76,6 +76,8 @@ function wait_on_vm_build {
echo "echo \"ps -aux | grep build \"" >> $VM_CMDS echo "echo \"ps -aux | grep build \"" >> $VM_CMDS
echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS
fi fi
echo "echo \"df -h\"" >> $VM_CMDS
echo "df -h" >> $VM_CMDS
ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
rm -f $VM_CMDS rm -f $VM_CMDS
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<class>Build_eNB</class> <class>Build_eNB</class>
<desc>Build gNB (USRP)</desc> <desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP</Build_eNB_args> <Build_eNB_args>--gNB -w USRP</Build_eNB_args>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase> </testCase>
</testCaseList> </testCaseList>
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>Build</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
</TestCaseRequestedList>
<TestCaseExclusionList>
</TestCaseExclusionList>
<testCase id="010101">
<class>Build_eNB</class>
<desc>Build Master eNB (USRP)</desc>
<Build_eNB_args>-w USRP -c --eNB</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
</testCaseList>
This diff is collapsed.
...@@ -1084,33 +1084,32 @@ ...@@ -1084,33 +1084,32 @@
(Test3: 273 PRB), (Test3: 273 PRB),
(Test4: 106 PRB 12 CSET-Offset), (Test4: 106 PRB 12 CSET-Offset),
(Test5: 217 PRB 48 CSET-Offset), (Test5: 217 PRB 48 CSET-Offset),
<!--(Test6: 106 PRB 25 PDSCH-Offset), (Test6: 106 PRB 25 PDSCH-Offset),
(Test7: 106 PRB 51 PDSCH-Offset), (Test7: 106 PRB 51 PDSCH-Offset),
(Test8: 217 PRB 100 PDSCH-PRBs), (Test8: 217 PRB 100 PDSCH-PRBs),
(Test9: 217 PRB 80 PDSCH-Offset), (Test9: 217 PRB 80 PDSCH-Offset),
(Test10: 217 PRB 100 PDSCH-PRBs 80 PDSCH-Offset), (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
(Test6: 106 PRB 0 MCS),--> (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28</desc>
(Test7: 273 PRB 28 MCS)</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_dlsim.Rel15</main_exec> <main_exec> $OPENAIR_DIR/targets/bin/nr_dlsim.Rel15</main_exec>
<main_exec_args>-n100 -R106 <main_exec_args>-n100 -R106 -b106
-n100 -R217 -n100 -R217 -b217
-n100 -R273 -n100 -R273 -b273
-n100 -R106 -o12 -n100 -R106 -o12
-n100 -R217 -o48 -n100 -R217 -o48
<!---n100 -R106 -a25 -n100 -R106 -a25
-n100 -R106 -a51 -n100 -R106 -a51
-n100 -R217 -b100 -n100 -R217 -b100
-n100 -R217 -a80 -n100 -R217 -a80
-n100 -R217 -a80 -b100 -n100 -R217 -a110 -b100
-n100 -R106 -e0--> -n100 -e28</main_exec_args>
-n100 -R273 -e28</main_exec_args> <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 <!--nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10-->nr_dlsim.test6 nr_dlsim.test7</tags> nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11</tags>
<search_expr_true>"PDCCH test OK" "PDSCH test OK"</search_expr_true> <search_expr_true>PDSCH 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>
...@@ -1240,19 +1239,23 @@ ...@@ -1240,19 +1239,23 @@
<testCase id="015111"> <testCase id="015111">
<class>execution</class> <class>execution</class>
<desc>nr_ulsim Test cases. (Test1: MCS 9), <desc>nr_ulsim Test cases. (Test1: MCS 9 106 PRBs),
(Test2: MCS 16), (Test2: MCS 16 50 PRBs),
(Test3: MCS 28)</desc> (Test3: MCS 28 50 PRBs),
(Test4: MCS 9 217 PRBs),
(Test5: MCS 9 273 PRBs)</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_ulsim.Rel15</main_exec> <main_exec> $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15</main_exec>
<main_exec_args>-f100 -m9 -s10 <main_exec_args>-f100 -m9 -r106 -s10
-f100 -m16 -s20 -f100 -m16 -s20
-f100 -m28 -s30</main_exec_args> -f100 -m28 -s30
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3</tags> -f100 -m9 -R217 -r217 -s10
-f100 -m9 -R273 -r273 -s10</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5</tags>
<search_expr_true>PUSCH test OK</search_expr_true> <search_expr_true>PUSCH 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>
......
...@@ -81,7 +81,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { ...@@ -81,7 +81,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
} }
if (*ptr == NULL) { if (*ptr == NULL) {
*ptr = malloc(length); *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch
if ( *ptr != NULL) { if ( *ptr != NULL) {
memset(*ptr,0,length); memset(*ptr,0,length);
...@@ -386,13 +386,12 @@ int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) { ...@@ -386,13 +386,12 @@ int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) {
status=1; status=1;
if (cfgoptions->numelt == 0 ) { if (cfgoptions->numelt == 0 ) {
config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *));
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1);
sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval);
printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr));
} else { } else {
sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); sprintf((char *)(cfgoptions->strptr), "%s",cfgoptions->defstrval);
printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)(cfgoptions->strptr));
} }
} }
......
...@@ -324,7 +324,9 @@ void log_getconfig(log_t *g_log) ...@@ -324,7 +324,9 @@ void log_getconfig(log_t *g_log)
config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX);
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX);
config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX);
if (config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX) > 0)
exit(1);
/* set the debug mask according to the debug parameters values */ /* set the debug mask according to the debug parameters values */
for (int i=0; log_maskmap[i].name != NULL ; i++) { for (int i=0; log_maskmap[i].name != NULL ; i++) {
...@@ -434,6 +436,10 @@ int logInit (void) ...@@ -434,6 +436,10 @@ int logInit (void)
register_log_component("ASN","log",ASN); register_log_component("ASN","log",ASN);
register_log_component("NFAPI_VNF","log",NFAPI_VNF); register_log_component("NFAPI_VNF","log",NFAPI_VNF);
register_log_component("NFAPI_PNF","log",NFAPI_PNF); register_log_component("NFAPI_PNF","log",NFAPI_PNF);
register_log_component("GNB_APP","log",GNB_APP);
register_log_component("NR_RRC","log",NR_RRC);
register_log_component("NR_MAC","log",NR_MAC);
register_log_component("NR_PHY","log",NR_PHY);
for (int i=0 ; log_level_names[i].name != NULL ; i++) for (int i=0 ; log_level_names[i].name != NULL ; i++)
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
......
...@@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = { ...@@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = {
"slot_number_TX0_gNB", "slot_number_TX0_gNB",
"slot_number_TX1_gNB", "slot_number_TX1_gNB",
"slot_number_RX0_gNB", "slot_number_RX0_gNB",
"slot_number_RX1_gNB" "slot_number_RX1_gNB",
"ru_tx_ofdm_mask"
}; };
const char* eurecomFunctionsNames[] = { const char* eurecomFunctionsNames[] = {
...@@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = { ...@@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = {
"phy_procedures_ru_feptx_ofdm7", "phy_procedures_ru_feptx_ofdm7",
"phy_procedures_ru_feptx_ofdm8", "phy_procedures_ru_feptx_ofdm8",
"phy_procedures_ru_feptx_ofdm9", "phy_procedures_ru_feptx_ofdm9",
"phy_procedures_ru_feptx_ofdm10",
"phy_procedures_ru_feptx_ofdm11",
"phy_procedures_ru_feptx_ofdm12",
"phy_procedures_ru_feptx_ofdm13",
"phy_procedures_ru_feptx_ofdm14",
"phy_procedures_ru_feptx_ofdm15",
"phy_procedures_ru_feptx_ofdm16",
"phy_procedures_ru_feptx_prec0", "phy_procedures_ru_feptx_prec0",
"phy_procedures_ru_feptx_prec1", "phy_procedures_ru_feptx_prec1",
"phy_procedures_ru_feptx_prec2", "phy_procedures_ru_feptx_prec2",
...@@ -502,6 +510,7 @@ const char* eurecomFunctionsNames[] = { ...@@ -502,6 +510,7 @@ const char* eurecomFunctionsNames[] = {
"pdcch_interleaving", "pdcch_interleaving",
"pdcch_tx", "pdcch_tx",
/*NR softmodem signal*/ /*NR softmodem signal*/
"wakeup_txfh",
"gNB_thread_rxtx0", "gNB_thread_rxtx0",
"gNB_thread_rxtx1" "gNB_thread_rxtx1"
}; };
......
...@@ -225,6 +225,7 @@ typedef enum { ...@@ -225,6 +225,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB,
VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK,
VCD_SIGNAL_DUMPER_VARIABLES_END VCD_SIGNAL_DUMPER_VARIABLES_END
...@@ -309,6 +310,13 @@ typedef enum { ...@@ -309,6 +310,13 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM10,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM11,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM12,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM13,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM14,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM15,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM16,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2,
...@@ -494,6 +502,7 @@ typedef enum { ...@@ -494,6 +502,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,
/*NR softmodem signal*/ /*NR softmodem signal*/
VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0,
VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1,
......
...@@ -73,10 +73,10 @@ typedef struct { ...@@ -73,10 +73,10 @@ typedef struct {
} T_cache_t; } T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */ /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS (237)//(232) #define VCD_NUM_FUNCTIONS (245)
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */ /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (185) #define VCD_NUM_VARIABLES (186)
/* first VCD function (to be kept up to date! see in T_messages.txt) */ /* first VCD function (to be kept up to date! see in T_messages.txt) */
#define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
......
...@@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB ...@@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB
GROUP = ALL:VCD:ENB:VCD_VARIABLE GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value FORMAT = ulong,value
VCD_NAME = slot_number_RX1_gNB VCD_NAME = slot_number_RX1_gNB
ID = VCD_VARIABLE_RU_TX_OFDM_MASK
DESC = VCD variable RU_TX_OFDM_MASK
GROUP = ALL:VCD:ENB:VCD_VARIABLE
FORMAT = ulong,value
VCD_NAME = ru_tx_ofdm_mask
#functions #functions
...@@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9 ...@@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9
GROUP = ALL:VCD:ENB:VCD_FUNCTION GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm9 VCD_NAME = phy_procedures_ru_feptx_ofdm9
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM10
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM10
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm10
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM11
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM11
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm11
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM12
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM12
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm12
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM13
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM13
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm13
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM14
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM14
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm14
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM15
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM15
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm15
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM16
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM16
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_procedures_ru_feptx_ofdm16
ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC
DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC
GROUP = ALL:VCD:ENB:VCD_FUNCTION GROUP = ALL:VCD:ENB:VCD_FUNCTION
...@@ -3230,6 +3270,11 @@ ID = VCD_FUNCTION_PDCCH_TX ...@@ -3230,6 +3270,11 @@ ID = VCD_FUNCTION_PDCCH_TX
VCD_NAME = pdcch_tx VCD_NAME = pdcch_tx
#function for gNB #function for gNB
ID = VCD_FUNCTION_WAKEUP_TXFH
DESC = VCD function WAKEUP_TXFH
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = wakeup_txfh
ID = VCD_FUNCTION_gNB_PROC_RXTX0 ID = VCD_FUNCTION_gNB_PROC_RXTX0
DESC = VCD function gNB_PROC_RXTX0 DESC = VCD function gNB_PROC_RXTX0
GROUP = ALL:VCD:ENB:VCD_FUNCTION GROUP = ALL:VCD:ENB:VCD_FUNCTION
......
...@@ -162,34 +162,6 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons ...@@ -162,34 +162,6 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons
return HASH_TABLE_KEY_NOT_EXISTS; return HASH_TABLE_KEY_NOT_EXISTS;
} }
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP)
//-------------------------------------------------------------------------------------------------------------------------------
{
hash_node_t *node = NULL;
unsigned int i = 0;
unsigned int num_elements = 0;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
if (hashtblP->nodes[i] != NULL) {
node=hashtblP->nodes[i];
while(node) {
num_elements += 1;
functP(node->key, node->data, parameterP);
node=node->next;
}
}
i += 1;
}
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ) hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP )
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
{ {
...@@ -266,7 +238,6 @@ hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t k ...@@ -266,7 +238,6 @@ hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t k
} }
hashtblP->nodes[hash]=node; hashtblP->nodes[hash]=node;
hashtblP->num_elements += 1;
return HASH_TABLE_OK; return HASH_TABLE_OK;
} }
//------------------------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------------------------
...@@ -295,7 +266,6 @@ hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t k ...@@ -295,7 +266,6 @@ hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t k
} }
free(node); free(node);
hashtblP->num_elements -= 1;
return HASH_TABLE_OK; return HASH_TABLE_OK;
} }
...@@ -335,47 +305,3 @@ hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_ ...@@ -335,47 +305,3 @@ hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_
*dataP = NULL; *dataP = NULL;
return HASH_TABLE_KEY_NOT_EXISTS; return HASH_TABLE_KEY_NOT_EXISTS;
} }
//-------------------------------------------------------------------------------------------------------------------------------
/*
* Resizing
* The number of elements in a hash table is not always known when creating the table.
* If the number of elements grows too large, it will seriously reduce the performance of most hash table operations.
* If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
* Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
* We create a temporary hash_table_t object (newtbl) to be used while building the new hashes.
* This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table.
* After that, we can just free the old table and copy the elements from newtbl to hashtbl.
*/
hashtable_rc_t hashtable_resize(hash_table_t *const hashtblP, const hash_size_t sizeP) {
hash_table_t newtbl;
hash_size_t n;
hash_node_t *node,*next;
if (hashtblP == NULL) {
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
newtbl.size = sizeP;
newtbl.hashfunc = hashtblP->hashfunc;
newtbl.num_elements = 0;
if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t *)))) return -1;
for(n=0; n<hashtblP->size; ++n) {
for(node=hashtblP->nodes[n]; node; node=next) {
next = node->next;
hashtable_insert(&newtbl, node->key, node->data);
// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
hashtable_remove(hashtblP, node->key);
}
}
free(hashtblP->nodes);
hashtblP->size=newtbl.size;
hashtblP->nodes=newtbl.nodes;
return HASH_TABLE_OK;
}
...@@ -49,7 +49,6 @@ typedef struct hash_node_s { ...@@ -49,7 +49,6 @@ typedef struct hash_node_s {
typedef struct hash_table_s { typedef struct hash_table_s {
hash_size_t size; hash_size_t size;
hash_size_t num_elements;
struct hash_node_s **nodes; struct hash_node_s **nodes;
hash_size_t (*hashfunc)(const hash_key_t); hash_size_t (*hashfunc)(const hash_key_t);
void (*freefunc)(void *); void (*freefunc)(void *);
...@@ -60,12 +59,10 @@ void hash_free_int_func(void *memoryP); ...@@ -60,12 +59,10 @@ void hash_free_int_func(void *memoryP);
hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *)); hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *));
hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl); hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl);
hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key); hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key);
hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void funct(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP);
hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ); hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP );
hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data); hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data);
hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key); hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key);
hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP); hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP);
hashtable_rc_t hashtable_resize (hash_table_t *const hashtbl, const hash_size_t size);
......
all: measurement_display thread-pool-test all:
measurement_display thread-pool-test
measurement_display: measurement_display.c thread-pool.h measurement_display:
gcc measurement_display.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display measurement_display.c thread-pool.h
gcc measurement_display.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o
measurement_display
thread-pool-test: thread-pool.c thread-pool.h thread-pool-test:
gcc -g thread-pool.c -I ${OPENAIR_DIR}/ -I ${OPENAIR_DIR}/common/utils/ -I. ${OPENAIR_DIR}/common/utils/backtrace.c -I ${OPENAIR_DIR}/openair2/COMMON ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/config/config_userapi.c ${OPENAIR_DIR}/common/config/config_load_configmodule.c ${OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test thread-pool.c thread-pool.h
gcc -g thread-pool.c -I $ {OPENAIR_DIR}/ -I $ {OPENAIR_DIR}/common/utils/ -I. $ {OPENAIR_DIR}/common/utils/backtrace.c -I $ {OPENAIR_DIR}/openair2/COMMON $ {OPENAIR_DIR}/common/utils/LOG/log.c $ {OPENAIR_DIR}/common/config/config_userapi.c
$ {OPENAIR_DIR}/common/config/config_load_configmodule.c $ {OPENAIR_DIR}/common/config/config_cmdline.c -lpthread -ldl -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test
...@@ -67,7 +67,7 @@ void *one_thread(void *arg) { ...@@ -67,7 +67,7 @@ void *one_thread(void *arg) {
delNotifiedFIFO_elt(elt); delNotifiedFIFO_elt(elt);
else else
pushNotifiedFIFO(elt->reponseFifo, elt); pushNotifiedFIFO(elt->reponseFifo, elt);
myThread->runningOnKey=-1;
mutexunlock(tp->incomingFifo.lockF); mutexunlock(tp->incomingFifo.lockF);
} }
} while (true); } while (true);
...@@ -95,7 +95,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { ...@@ -95,7 +95,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
pool->nbThreads=0; pool->nbThreads=0;
pool->restrictRNTI=false; pool->restrictRNTI=false;
curptr=strtok_r(params,",",&saveptr); curptr=strtok_r(params,",",&saveptr);
struct one_thread * ptr;
while ( curptr!=NULL ) { while ( curptr!=NULL ) {
int c=toupper(curptr[0]); int c=toupper(curptr[0]);
...@@ -109,8 +109,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { ...@@ -109,8 +109,9 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
break; break;
default: default:
ptr=pool->allthreads;
pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
pool->allthreads->next=pool->allthreads; pool->allthreads->next=ptr;
printf("create a thread for core %d\n", atoi(curptr)); printf("create a thread for core %d\n", atoi(curptr));
pool->allthreads->coreID=atoi(curptr); pool->allthreads->coreID=atoi(curptr);
pool->allthreads->id=pool->nbThreads; pool->allthreads->id=pool->nbThreads;
......
...@@ -150,8 +150,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { ...@@ -150,8 +150,9 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
// This function aborts all messages matching the key // This function aborts all messages matching the key
// If the queue is used in thread pools, it doesn't cancels already running processing // If the queue is used in thread pools, it doesn't cancels already running processing
// because the message has already been picked // because the message has already been picked
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { static inline int abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
mutexlock(nf->lockF); mutexlock(nf->lockF);
int nbDeleted=0;
notifiedFIFO_elt_t **start=&nf->outF; notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) { while(*start!=NULL) {
...@@ -159,13 +160,16 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { ...@@ -159,13 +160,16 @@ static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
notifiedFIFO_elt_t *request=*start; notifiedFIFO_elt_t *request=*start;
*start=(*start)->next; *start=(*start)->next;
delNotifiedFIFO_elt(request); delNotifiedFIFO_elt(request);
} nbDeleted++;
} else
if (*start != NULL)
start=&(*start)->next; start=&(*start)->next;
} }
if (nf->outF == NULL)
nf->inF=NULL;
mutexunlock(nf->lockF); mutexunlock(nf->lockF);
return nbDeleted;
} }
struct one_thread { struct one_thread {
...@@ -195,7 +199,20 @@ typedef struct thread_pool { ...@@ -195,7 +199,20 @@ typedef struct thread_pool {
static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
if (t->measurePerf) msg->creationTime=rdtsc(); if (t->measurePerf) msg->creationTime=rdtsc();
pushNotifiedFIFO(&t->incomingFifo, msg); if ( t->activated)
pushNotifiedFIFO(&t->incomingFifo, msg);
else {
if (t->measurePerf)
msg->startProcessingTime=rdtsc();
msg->processingFunc(NotifiedFifoData(msg));
if (t->measurePerf)
msg->endProcessingTime=rdtsc();
if (msg->reponseFifo)
pushNotifiedFIFO(msg->reponseFifo, msg);
}
} }
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
...@@ -225,7 +242,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo ...@@ -225,7 +242,8 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo
return msg; return msg;
} }
static inline void abortTpool(tpool_t *t, uint64_t key) { static inline int abortTpool(tpool_t *t, uint64_t key) {
int nbRemoved=0;
notifiedFIFO_t *nf=&t->incomingFifo; notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF); mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF; notifiedFIFO_elt_t **start=&nf->outF;
...@@ -235,22 +253,27 @@ static inline void abortTpool(tpool_t *t, uint64_t key) { ...@@ -235,22 +253,27 @@ static inline void abortTpool(tpool_t *t, uint64_t key) {
notifiedFIFO_elt_t *request=*start; notifiedFIFO_elt_t *request=*start;
*start=(*start)->next; *start=(*start)->next;
delNotifiedFIFO_elt(request); delNotifiedFIFO_elt(request);
} nbRemoved++;
} else
if (*start != NULL)
start=&(*start)->next; start=&(*start)->next;
} }
if (t->incomingFifo.outF==NULL)
t->incomingFifo.inF=NULL;
struct one_thread *ptr=t->allthreads; struct one_thread *ptr=t->allthreads;
while(ptr!=NULL) { while(ptr!=NULL) {
if (ptr->runningOnKey==key) if (ptr->runningOnKey==key) {
ptr->abortFlag=true; ptr->abortFlag=true;
nbRemoved++;
}
ptr=ptr->next; ptr=ptr->next;
} }
mutexunlock(nf->lockF); mutexunlock(nf->lockF);
return nbRemoved;
} }
void initTpool(char *params,tpool_t *pool, bool performanceMeas); void initTpool(char *params,tpool_t *pool, bool performanceMeas);
......
...@@ -3,69 +3,90 @@ ...@@ -3,69 +3,90 @@
The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores.
Each worker loop on pick from the same input queue jobs to do. Each worker loop on pick from the same input queue jobs to do.
When a job is done, the worker sends a return if a return is defined. When a job is done, the worker sends a return if a return is defined.
A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless).
All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client,
so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter.
## license ## license
Author: Laurent Thomas, Open cells project Author:
The owner share this piece code to Openairsoftware alliance as per OSA license terms Laurent Thomas, Open cells project
The owner share this piece code to Openairsoftware alliance as per OSA license terms
# jobs # jobs
A job is a message (notifiedFIFO_elt_t): A job is a message (notifiedFIFO_elt_t):
next: internal FIFO chain, do not set it next:
key: a long int that the client can use to identify a message or a group of messages internal FIFO chain, do not set it
responseFifo: if the client defines a response FIFO, the message will be posted back after processing key:
processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch a long int that the client can use to identify a message or a group of messages
msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing responseFifo:
malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature if the client defines a response FIFO, the message will be posted back after processing
processingFunc:
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. any funtion (type void processingFunc(void *)) that the worker will launch
msgData:
the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing
malloced:
a boolean that enable internal free in these cases:
no return Fifo or Abort feature
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
# Queues of jobs # Queues of jobs
Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() Queues are type of:
No delete function is required, the creator has only to free the data of type notifiedFIFO_t notifiedFIFO_t that must be initialized by init_notifiedFIFO()
No delete function is required, the creator has only to free the data of type notifiedFIFO_t
push_notifiedFIFO() add a job in the queue push_notifiedFIFO() add a job in the queue
pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking
abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition)
# Thread pools # Thread pools
## initialization ## initialization
The clients can create one or more thread pools with init_tpool() The clients can create one or more thread pools with init_tpool()
the params string structure: describes a list of cores, separated by "," that run a worker thread the params string structure:
describes a list of cores, separated by "," that run a worker thread
If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and
the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>" The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
## adding jobs ## adding jobs
The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job.
## abort ## abort
A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues.
Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
## Performance measurements ## Performance measurements
A performance measurement is integrated: the pool will automacillay fill timestamps: A performance measurement is integrated:
the pool will automacillay fill timestamps:
* creationTime:
time the request is push to the pool;
* creationTime: time the request is push to the pool; * startProcessingTime:
* startProcessingTime: time a worker start to run on the job time a worker start to run on the job
* endProcessingTime: time the worker finished the job * endProcessingTime:
* returnTime: time the client reads the result time the worker finished the job
* returnTime:
time the client reads the result
if you set the environement variable: thread-pool-measurements to a valid file name if you set the environement variable:
thread-pool-measurements to a valid file name
These measurements will be wrote to this Linux pipe. These measurements will be wrote to this Linux pipe.
A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. A tool to read the linux fifo and display it in ascii is provided:
see the local directory Makefile for this tool and to compile the thread pool unitary tests.
...@@ -194,11 +194,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t ...@@ -194,11 +194,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// UE-specific RX processing for subframe n // UE-specific RX processing for subframe n
if (nfapi_mode == 0 || nfapi_mode == 1) */ if (nfapi_mode == 0 || nfapi_mode == 1) */
if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD) {
nfapi_nr_ul_config_ulsch_pdu_rel15_t *ulsch_pdu_rel15 = &gNB->ulsch[1][0]->harq_processes[0]->ulsch_pdu.ulsch_pdu_rel15;
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx, ulsch_pdu_rel15->start_symbol, ulsch_pdu_rel15->start_symbol + ulsch_pdu_rel15->number_symbols);
}
pthread_mutex_lock(&gNB->UL_INFO_mutex); pthread_mutex_lock(&gNB->UL_INFO_mutex);
gNB->UL_INFO.frame = frame_rx; gNB->UL_INFO.frame = frame_rx;
gNB->UL_INFO.slot = slot_rx; gNB->UL_INFO.slot = slot_rx;
...@@ -217,6 +212,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t ...@@ -217,6 +212,9 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
if (oai_exit) return(-1); if (oai_exit) return(-1);
//if (slot_rx == NR_UPLINK_SLOT || gNB->frame_parms.frame_type == FDD)
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
} }
...@@ -292,6 +290,8 @@ static void *gNB_L1_thread_tx(void *param) { ...@@ -292,6 +290,8 @@ static void *gNB_L1_thread_tx(void *param) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx);
phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 );
pthread_mutex_lock( &L1_proc_tx->mutex ); pthread_mutex_lock( &L1_proc_tx->mutex );
L1_proc_tx->instance_cnt = -1; L1_proc_tx->instance_cnt = -1;
...@@ -303,6 +303,7 @@ static void *gNB_L1_thread_tx(void *param) { ...@@ -303,6 +303,7 @@ static void *gNB_L1_thread_tx(void *param) {
pthread_mutex_unlock(&L1_proc_tx->mutex); pthread_mutex_unlock(&L1_proc_tx->mutex);
wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
} }
...@@ -422,10 +423,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ...@@ -422,10 +423,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
// note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh");
AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n");
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
if (waitret == ETIMEDOUT) { if (waitret == ETIMEDOUT) {
...@@ -450,7 +451,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ...@@ -450,7 +451,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
ru = gNB->RU_list[i]; ru = gNB->RU_list[i];
ru_proc = &ru->proc; ru_proc = &ru->proc;
AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); //AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
if (ru_proc->instance_cnt_gNBs == 0) { if (ru_proc->instance_cnt_gNBs == 0) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
...@@ -458,7 +459,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ...@@ -458,7 +459,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
gNB->proc.RU_mask_tx = 0; gNB->proc.RU_mask_tx = 0;
AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); //AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0);
return(-1); return(-1);
...@@ -524,6 +525,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { ...@@ -524,6 +525,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
RU_proc_t *ru_proc=&ru->proc; RU_proc_t *ru_proc=&ru->proc;
int ret; int ret;
int i; int i;
struct timespec abstime;
int time_ns = 50000;
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
for (i=0;i<gNB->num_RU;i++) { for (i=0;i<gNB->num_RU;i++) {
...@@ -544,14 +547,22 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { ...@@ -544,14 +547,22 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
} }
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_nsec = abstime.tv_nsec + time_ns;
if (abstime.tv_nsec >= 1000*1000*1000) {
abstime.tv_nsec -= 1000*1000*1000;
abstime.tv_sec += 1;
}
// wake up TX for subframe n+sl_ahead // wake up TX for subframe n+sl_ahead
// lock the TX mutex and make sure the thread is ready // lock the TX mutex and make sure the thread is ready
AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret); AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
return(-1);
} }
++L1_proc->instance_cnt; ++L1_proc->instance_cnt;
...@@ -943,7 +954,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { ...@@ -943,7 +954,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_Schedule_response = nr_schedule_response;
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t));
//memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO));
LOG_I(PHY,"Setting indication lists\n"); LOG_I(PHY,"Setting indication lists\n");
gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list; gNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = gNB->rx_pdu_list;
gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list; gNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = gNB->crc_pdu_list;
...@@ -951,6 +963,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { ...@@ -951,6 +963,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list;
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list; gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;
gNB->prach_energy_counter = 0; gNB->prach_energy_counter = 0;
} }
} }
......
This diff is collapsed.
...@@ -106,7 +106,6 @@ int config_sync_var=-1; ...@@ -106,7 +106,6 @@ int config_sync_var=-1;
#endif #endif
volatile int oai_exit = 0; volatile int oai_exit = 0;
static clock_source_t clock_source = internal;
static int wait_for_sync = 0; static int wait_for_sync = 0;
unsigned int mmapped_dma=0; unsigned int mmapped_dma=0;
...@@ -924,6 +923,10 @@ init_opt(); ...@@ -924,6 +923,10 @@ init_opt();
# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif #endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if(IS_SOFTMODEM_NOS1)
init_pdcp();
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
if (RC.nb_nr_inst > 0) { if (RC.nb_nr_inst > 0) {
...@@ -942,9 +945,6 @@ init_opt(); ...@@ -942,9 +945,6 @@ init_opt();
flexran_agent_start(i); flexran_agent_start(i);
} }
if(IS_SOFTMODEM_NOS1)
init_pdcp();
// init UE_PF_PO and mutex lock // init UE_PF_PO and mutex lock
pthread_mutex_init(&ue_pf_po_mutex, NULL); pthread_mutex_init(&ue_pf_po_mutex, NULL);
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
...@@ -49,10 +48,12 @@ ...@@ -49,10 +48,12 @@
#define SOFTMODEM_NOS1_BIT (1<<0) #define SOFTMODEM_NOS1_BIT (1<<0)
#define SOFTMODEM_NOKRNMOD_BIT (1<<1) #define SOFTMODEM_NOKRNMOD_BIT (1<<1)
#define SOFTMODEM_RFSIM_BIT (1<<10)
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) #define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
extern uint64_t get_softmodem_optmask(void); extern uint64_t get_softmodem_optmask(void);
extern void get_common_options(void); extern void get_common_options(void);
......
...@@ -419,7 +419,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ...@@ -419,7 +419,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO,
0x1234, proc->frame_rx, 0x1234, proc->frame_rx,
proc->nr_tti_rx, 0); proc->nr_tti_rx, 0);
//pdcp_run(&ctxt); pdcp_run(&ctxt);
pdcp_fifo_flush_sdus(&ctxt); pdcp_fifo_flush_sdus(&ctxt);
} }
} }
...@@ -538,6 +538,9 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { ...@@ -538,6 +538,9 @@ void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
dummy_rx, dummy_rx,
UE->frame_parms.samples_per_subframe, UE->frame_parms.samples_per_subframe,
UE->frame_parms.nb_antennas_rx); UE->frame_parms.nb_antennas_rx);
if (IS_SOFTMODEM_RFSIM ) {
usleep(1000); // slow down, as would do actuall rf to let cpu for the synchro thread
}
} }
for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++) for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
......
...@@ -116,7 +116,7 @@ volatile int start_eNB = 0; ...@@ -116,7 +116,7 @@ volatile int start_eNB = 0;
volatile int start_UE = 0; volatile int start_UE = 0;
volatile int oai_exit = 0; volatile int oai_exit = 0;
static clock_source_t clock_source = internal; static clock_source_t clock_source = unset;
int single_thread_flag=1; int single_thread_flag=1;
static double snr_dB=20; static double snr_dB=20;
...@@ -521,14 +521,23 @@ void init_openair0(void) { ...@@ -521,14 +521,23 @@ void init_openair0(void) {
if (frame_parms[0]->threequarter_fs) { if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].sample_rate=92.16e6;
openair0_cfg[card].samples_per_frame = 921600; openair0_cfg[card].samples_per_frame = 921600;
openair0_cfg[card].tx_bw = 40e6;
openair0_cfg[card].rx_bw = 40e6;
} }
else { else {
openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800; openair0_cfg[card].samples_per_frame = 1228800;
openair0_cfg[card].tx_bw = 40e6; }
openair0_cfg[card].rx_bw = 40e6; } else {
LOG_E(PHY,"Unsupported numerology!\n");
exit(-1);
}
}else if(frame_parms[0]->N_RB_DL == 273) {
if (numerology==1) {
if (frame_parms[0]->threequarter_fs) {
AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n");
}
else {
openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800;
} }
} else { } else {
LOG_E(PHY,"Unsupported numerology!\n"); LOG_E(PHY,"Unsupported numerology!\n");
...@@ -539,32 +548,22 @@ void init_openair0(void) { ...@@ -539,32 +548,22 @@ void init_openair0(void) {
if (frame_parms[0]->threequarter_fs) { if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].sample_rate=23.04e6;
openair0_cfg[card].samples_per_frame = 230400; openair0_cfg[card].samples_per_frame = 230400;
openair0_cfg[card].tx_bw = 10e6;
openair0_cfg[card].rx_bw = 10e6;
} else { } else {
openair0_cfg[card].sample_rate=30.72e6; openair0_cfg[card].sample_rate=30.72e6;
openair0_cfg[card].samples_per_frame = 307200; openair0_cfg[card].samples_per_frame = 307200;
openair0_cfg[card].tx_bw = 10e6;
openair0_cfg[card].rx_bw = 10e6;
} }
} else if (numerology==1) { } else if (numerology==1) {
if (frame_parms[0]->threequarter_fs) { if (frame_parms[0]->threequarter_fs) {
openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].sample_rate=46.08e6;
openair0_cfg[card].samples_per_frame = 480800; openair0_cfg[card].samples_per_frame = 480800;
openair0_cfg[card].tx_bw = 20e6;
openair0_cfg[card].rx_bw = 20e6;
} }
else { else {
openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].sample_rate=61.44e6;
openair0_cfg[card].samples_per_frame = 614400; openair0_cfg[card].samples_per_frame = 614400;
openair0_cfg[card].tx_bw = 20e6;
openair0_cfg[card].rx_bw = 20e6;
} }
} else if (numerology==2) { } else if (numerology==2) {
openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].sample_rate=122.88e6;
openair0_cfg[card].samples_per_frame = 1228800; openair0_cfg[card].samples_per_frame = 1228800;
openair0_cfg[card].tx_bw = 40e6;
openair0_cfg[card].rx_bw = 40e6;
} else { } else {
LOG_E(PHY,"Unsupported numerology!\n"); LOG_E(PHY,"Unsupported numerology!\n");
exit(-1); exit(-1);
...@@ -572,18 +571,12 @@ void init_openair0(void) { ...@@ -572,18 +571,12 @@ void init_openair0(void) {
} else if(frame_parms[0]->N_RB_DL == 50) { } else if(frame_parms[0]->N_RB_DL == 50) {
openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].sample_rate=15.36e6;
openair0_cfg[card].samples_per_frame = 153600; openair0_cfg[card].samples_per_frame = 153600;
openair0_cfg[card].tx_bw = 5e6;
openair0_cfg[card].rx_bw = 5e6;
} else if (frame_parms[0]->N_RB_DL == 25) { } else if (frame_parms[0]->N_RB_DL == 25) {
openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].sample_rate=7.68e6;
openair0_cfg[card].samples_per_frame = 76800; openair0_cfg[card].samples_per_frame = 76800;
openair0_cfg[card].tx_bw = 2.5e6;
openair0_cfg[card].rx_bw = 2.5e6;
} else if (frame_parms[0]->N_RB_DL == 6) { } else if (frame_parms[0]->N_RB_DL == 6) {
openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].sample_rate=1.92e6;
openair0_cfg[card].samples_per_frame = 19200; openair0_cfg[card].samples_per_frame = 19200;
openair0_cfg[card].tx_bw = 1.5e6;
openair0_cfg[card].rx_bw = 1.5e6;
} }
else { else {
LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL);
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
{"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \
{"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ {"clock-source", CONFIG_HLP_EXCCLK, 0, iptr:&clock_source, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
......
This diff is collapsed.
...@@ -241,8 +241,8 @@ if (logFlag){ ...@@ -241,8 +241,8 @@ if (logFlag){
start_meas(&timeEncoder); start_meas(&timeEncoder);
if (decoder_int16==1) { if (decoder_int16==1) {
polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr); polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, 0, currentPtr);
//polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr); //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0,0,currentPtr);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) if (polarMessageType == 0)
polar_encoder(testInput, encoderOutput, currentPtr); polar_encoder(testInput, encoderOutput, currentPtr);
...@@ -278,7 +278,7 @@ if (logFlag){ ...@@ -278,7 +278,7 @@ if (logFlag){
start_meas(&timeDecoder); start_meas(&timeDecoder);
if (decoder_int16==1) { if (decoder_int16==1) {
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr); decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0, currentPtr);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) { if (polarMessageType == 0) {
decoderState = polar_decoder(channelOutput, decoderState = polar_decoder(channelOutput,
......
...@@ -46,7 +46,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh ...@@ -46,7 +46,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
short *Gen_shift_values=choose_generator_matrix(BG,Zc); short *Gen_shift_values=choose_generator_matrix(BG,Zc);
short *no_shift_values, *pointer_shift_values; short *no_shift_values, *pointer_shift_values;
int no_punctured_columns; int no_punctured_columns;
short nrows,ncols; short nrows,ncols,rate=3;
int i1,i2,i3,i4,i5,temp_prime; int i1,i2,i3,i4,i5,temp_prime;
unsigned char channel_temp,temp; unsigned char channel_temp,temp;
...@@ -56,6 +56,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh ...@@ -56,6 +56,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
pointer_shift_values=(short *) pointer_shift_values_BG1; pointer_shift_values=(short *) pointer_shift_values_BG1;
nrows=46; //parity check bits nrows=46; //parity check bits
ncols=22; //info bits ncols=22; //info bits
rate=3;
} }
else if (BG==2) else if (BG==2)
{ {
...@@ -63,6 +64,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh ...@@ -63,6 +64,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
pointer_shift_values=(short *) pointer_shift_values_BG2; pointer_shift_values=(short *) pointer_shift_values_BG2;
nrows=42; //parity check bits nrows=42; //parity check bits
ncols=10; //info bits ncols=10; //info bits
rate=5;
} }
else { else {
printf("problem with BG\n"); printf("problem with BG\n");
...@@ -70,7 +72,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh ...@@ -70,7 +72,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
} }
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
//printf("no_punctured_columns = %d\n",no_punctured_columns); //printf("no_punctured_columns = %d\n",no_punctured_columns);
......
...@@ -202,7 +202,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in ...@@ -202,7 +202,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in
{ {
short nrows=0,ncols=0; short nrows=0,ncols=0;
int i,i1; int i,i1,rate=3;
int no_punctured_columns,removed_bit; int no_punctured_columns,removed_bit;
int simd_size; int simd_size;
...@@ -214,6 +214,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in ...@@ -214,6 +214,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in
//BG=1; //BG=1;
nrows=46; //parity check bits nrows=46; //parity check bits
ncols=22; //info bits ncols=22; //info bits
rate=3;
} }
//else if (block_length<=3840) //else if (block_length<=3840)
else if (BG==2) else if (BG==2)
...@@ -221,6 +222,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in ...@@ -221,6 +222,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in
//BG=2; //BG=2;
nrows=42; //parity check bits nrows=42; //parity check bits
ncols=10; // info bits ncols=10; // info bits
rate=5;
} }
...@@ -239,8 +241,8 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in ...@@ -239,8 +241,8 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,in
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits // calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
// printf("%d\n",no_punctured_columns); // printf("%d\n",no_punctured_columns);
// printf("%d\n",removed_bit); // printf("%d\n",removed_bit);
// unpack input // unpack input
...@@ -297,7 +299,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i ...@@ -297,7 +299,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
{ {
short nrows=0,ncols=0; short nrows=0,ncols=0;
int i,i1,j; int i,i1,j,rate=3;
int no_punctured_columns,removed_bit; int no_punctured_columns,removed_bit;
char temp; char temp;
int simd_size; int simd_size;
...@@ -326,6 +328,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i ...@@ -326,6 +328,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
{ {
nrows=46; //parity check bits nrows=46; //parity check bits
ncols=22; //info bits ncols=22; //info bits
rate=3;
} }
//else if (block_length<=3840) //else if (block_length<=3840)
else if (BG==2) else if (BG==2)
...@@ -333,7 +336,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i ...@@ -333,7 +336,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
//BG=2; //BG=2;
nrows=42; //parity check bits nrows=42; //parity check bits
ncols=10; // info bits ncols=10; // info bits
rate=5;
} }
#ifdef DEBUG_LDPC #ifdef DEBUG_LDPC
...@@ -352,8 +356,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i ...@@ -352,8 +356,8 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits // calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
// printf("%d\n",no_punctured_columns); // printf("%d\n",no_punctured_columns);
// printf("%d\n",removed_bit); // printf("%d\n",removed_bit);
// unpack input // unpack input
...@@ -473,7 +477,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha ...@@ -473,7 +477,7 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
{ {
short nrows=0,ncols=0; short nrows=0,ncols=0;
int i,i1,j; int i,i1,j,rate=3;
int no_punctured_columns,removed_bit; int no_punctured_columns,removed_bit;
//Table of possible lifting sizes //Table of possible lifting sizes
char temp; char temp;
...@@ -509,11 +513,13 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha ...@@ -509,11 +513,13 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
{ {
nrows=46; //parity check bits nrows=46; //parity check bits
ncols=22; //info bits ncols=22; //info bits
rate=3;
} }
else if (BG==2) else if (BG==2)
{ {
nrows=42; //parity check bits nrows=42; //parity check bits
ncols=10; // info bits ncols=10; // info bits
rate=5;
} }
#ifdef DEBUG_LDPC #ifdef DEBUG_LDPC
...@@ -532,10 +538,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha ...@@ -532,10 +538,10 @@ int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **cha
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits // calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
// printf("%d\n",no_punctured_columns); //printf("%d\n",no_punctured_columns);
// printf("%d\n",removed_bit); //printf("%d\n",removed_bit);
// unpack input // unpack input
memset(c,0,sizeof(unsigned char) * ncols * Zc); memset(c,0,sizeof(unsigned char) * ncols * Zc);
memset(d,0,sizeof(unsigned char) * nrows * Zc); memset(d,0,sizeof(unsigned char) * nrows * Zc);
......
...@@ -373,7 +373,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int ...@@ -373,7 +373,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int
int i,i1,i2,i3,i4,i5,temp_prime,var; int i,i1,i2,i3,i4,i5,temp_prime,var;
int no_punctured_columns,removed_bit; int no_punctured_columns,removed_bit,rate=3;
int nind=0; int nind=0;
int indlist[1000]; int indlist[1000];
int indlist2[1000]; int indlist2[1000];
...@@ -384,6 +384,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int ...@@ -384,6 +384,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int
{ {
nrows=46; //parity check bits nrows=46; //parity check bits
ncols=22; //info bits ncols=22; //info bits
rate=3;
} }
//else if (block_length<=3840) //else if (block_length<=3840)
else if (BG==2) else if (BG==2)
...@@ -391,7 +392,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int ...@@ -391,7 +392,7 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int
//BG=2; //BG=2;
nrows=42; //parity check bits nrows=42; //parity check bits
ncols=10; // info bits ncols=10; // info bits
rate=5;
} }
Gen_shift_values=choose_generator_matrix(BG,Zc); Gen_shift_values=choose_generator_matrix(BG,Zc);
...@@ -417,8 +418,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int ...@@ -417,8 +418,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int
AssertFatal(0,"BG %d is not supported yet\n",BG); AssertFatal(0,"BG %d is not supported yet\n",BG);
} }
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc; no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate);
//printf("%d\n",no_punctured_columns); //printf("%d\n",no_punctured_columns);
//printf("%d\n",removed_bit); //printf("%d\n",removed_bit);
// unpack input // unpack input
......
...@@ -601,6 +601,7 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) { ...@@ -601,6 +601,7 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
uint32_t polar_decoder_int16(int16_t *input, uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out, uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams) const t_nrPolar_params *polarParams)
{ {
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
...@@ -650,28 +651,42 @@ uint32_t polar_decoder_int16(int16_t *input, ...@@ -650,28 +651,42 @@ uint32_t polar_decoder_int16(int16_t *input,
uint64_t Ar = 0; uint64_t Ar = 0;
AssertFatal(len<65,"A must be less than 65 bits\n"); AssertFatal(len<65,"A must be less than 65 bits\n");
// appending 24 ones before a0 for DCI as stated in 38.212 7.3.2
uint8_t offset = 0;
if (ones_flag) offset = 3;
if (len<=32) { if (len<=32) {
Ar = (uint32_t)(B[0]>>crclen); Ar = (uint32_t)(B[0]>>crclen);
uint8_t A32_flip[4]; uint8_t A32_flip[4+offset];
if (ones_flag) {
A32_flip[0] = 0xff;
A32_flip[1] = 0xff;
A32_flip[2] = 0xff;
}
uint32_t Aprime= (uint32_t)(Ar<<(32-len)); uint32_t Aprime= (uint32_t)(Ar<<(32-len));
A32_flip[0]=((uint8_t *)&Aprime)[3]; A32_flip[0+offset]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t *)&Aprime)[2]; A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t *)&Aprime)[1]; A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t *)&Aprime)[0]; A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A32_flip,len)>>8); crc = (uint64_t)(crc24c(A32_flip,8*offset+len)>>8);
} else if (len<=64) { } else if (len<=64) {
Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));; Ar = (B[0]>>crclen) | (B[1]<<(64-crclen));;
uint8_t A64_flip[8]; uint8_t A64_flip[8+offset];
uint64_t Aprime= (uint32_t)(Ar<<(64-len)); if (ones_flag) {
A64_flip[0]=((uint8_t *)&Aprime)[7]; A64_flip[0] = 0xff;
A64_flip[1]=((uint8_t *)&Aprime)[6]; A64_flip[1] = 0xff;
A64_flip[2]=((uint8_t *)&Aprime)[5]; A64_flip[2] = 0xff;
A64_flip[3]=((uint8_t *)&Aprime)[4]; }
A64_flip[4]=((uint8_t *)&Aprime)[3]; uint64_t Aprime= (uint64_t)(Ar<<(64-len));
A64_flip[5]=((uint8_t *)&Aprime)[2]; A64_flip[0+offset]=((uint8_t *)&Aprime)[7];
A64_flip[6]=((uint8_t *)&Aprime)[1]; A64_flip[1+offset]=((uint8_t *)&Aprime)[6];
A64_flip[7]=((uint8_t *)&Aprime)[0]; A64_flip[2+offset]=((uint8_t *)&Aprime)[5];
crc = (uint64_t)(crc24c(A64_flip,len)>>8); A64_flip[3+offset]=((uint8_t *)&Aprime)[4];
A64_flip[4+offset]=((uint8_t *)&Aprime)[3];
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
crc = (uint64_t)(crc24c(A64_flip,8*offset+len)>>8);
} }
#if 0 #if 0
......
...@@ -148,6 +148,7 @@ void polar_encoder_dci(uint32_t *in, ...@@ -148,6 +148,7 @@ void polar_encoder_dci(uint32_t *in,
void polar_encoder_fast(uint64_t *A, void polar_encoder_fast(uint64_t *A,
uint32_t *out, uint32_t *out,
int32_t crcmask, int32_t crcmask,
uint8_t ones_flag,
t_nrPolar_params *polarParams); t_nrPolar_params *polarParams);
int8_t polar_decoder(double *input, int8_t polar_decoder(double *input,
...@@ -157,6 +158,7 @@ int8_t polar_decoder(double *input, ...@@ -157,6 +158,7 @@ int8_t polar_decoder(double *input,
uint32_t polar_decoder_int16(int16_t *input, uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out, uint64_t *out,
uint8_t ones_flag,
const t_nrPolar_params *polarParams); const t_nrPolar_params *polarParams);
int8_t polar_decoder_dci(double *input, int8_t polar_decoder_dci(double *input,
......
...@@ -410,6 +410,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) { ...@@ -410,6 +410,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
void polar_encoder_fast(uint64_t *A, void polar_encoder_fast(uint64_t *A,
uint32_t *out, uint32_t *out,
int32_t crcmask, int32_t crcmask,
uint8_t ones_flag,
t_nrPolar_params *polarParams) { t_nrPolar_params *polarParams) {
AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K > 32, "K = %d < 33, is not supported yet\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K); AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
...@@ -421,6 +422,10 @@ void polar_encoder_fast(uint64_t *A, ...@@ -421,6 +422,10 @@ void polar_encoder_fast(uint64_t *A,
AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n"); AssertFatal(polarParams->crcParityBits == 24,"support for 24-bit crc only for now\n");
//int bitlen0=bitlen; //int bitlen0=bitlen;
uint64_t tcrc=0; uint64_t tcrc=0;
uint8_t offset = 0;
// appending 24 ones before a0 for DCI as stated in 38.212 7.3.2
if (ones_flag) offset = 3;
// A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1, // A bit string should be stored as 0, 0, ..., 0, a'_0, a'_1, ..., a'_A-1,
//???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A //???a'_{N-1} a'_{N-2} ... a'_{N-A} 0 .... 0, where N=64,128,192,..., N is smallest multiple of 64 greater than or equal to A
...@@ -428,38 +433,53 @@ void polar_encoder_fast(uint64_t *A, ...@@ -428,38 +433,53 @@ void polar_encoder_fast(uint64_t *A,
// First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH) // First flip A bitstring byte endian for CRC routines (optimized for DLSCH/ULSCH, not PBCH/PDCCH)
// CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH) // CRC reads in each byte in bit positions 7 down to 0, for PBCH/PDCCH we need to read in a_{A-1} down to a_{0}, A = length of bit string (e.g. 32 for PBCH)
if (bitlen<=32) { if (bitlen<=32) {
uint8_t A32_flip[4]; uint8_t A32_flip[4+offset];
if (ones_flag) {
A32_flip[0] = 0xff;
A32_flip[1] = 0xff;
A32_flip[2] = 0xff;
}
uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen)); uint32_t Aprime= (uint32_t)(((uint32_t)*A)<<(32-bitlen));
A32_flip[0]=((uint8_t *)&Aprime)[3]; A32_flip[0+offset]=((uint8_t *)&Aprime)[3];
A32_flip[1]=((uint8_t *)&Aprime)[2]; A32_flip[1+offset]=((uint8_t *)&Aprime)[2];
A32_flip[2]=((uint8_t *)&Aprime)[1]; A32_flip[2+offset]=((uint8_t *)&Aprime)[1];
A32_flip[3]=((uint8_t *)&Aprime)[0]; A32_flip[3+offset]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,bitlen)>>8))); tcrc = (uint64_t)((crcmask^(crc24c(A32_flip,8*offset+bitlen)>>8)));
} else if (bitlen<=64) { } else if (bitlen<=64) {
uint8_t A64_flip[8]; uint8_t A64_flip[8+offset];
uint64_t Aprime= (uint32_t)(((uint64_t)*A)<<(64-bitlen)); if (ones_flag) {
A64_flip[0]=((uint8_t *)&Aprime)[7]; A64_flip[0] = 0xff;
A64_flip[1]=((uint8_t *)&Aprime)[6]; A64_flip[1] = 0xff;
A64_flip[2]=((uint8_t *)&Aprime)[5]; A64_flip[2] = 0xff;
A64_flip[3]=((uint8_t *)&Aprime)[4]; }
A64_flip[4]=((uint8_t *)&Aprime)[3]; uint64_t Aprime= (uint64_t)(((uint64_t)*A)<<(64-bitlen));
A64_flip[5]=((uint8_t *)&Aprime)[2]; A64_flip[0+offset]=((uint8_t *)&Aprime)[7];
A64_flip[6]=((uint8_t *)&Aprime)[1]; A64_flip[1+offset]=((uint8_t *)&Aprime)[6];
A64_flip[7]=((uint8_t *)&Aprime)[0]; A64_flip[2+offset]=((uint8_t *)&Aprime)[5];
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,bitlen)>>8))); A64_flip[3+offset]=((uint8_t *)&Aprime)[4];
A64_flip[4+offset]=((uint8_t *)&Aprime)[3];
A64_flip[5+offset]=((uint8_t *)&Aprime)[2];
A64_flip[6+offset]=((uint8_t *)&Aprime)[1];
A64_flip[7+offset]=((uint8_t *)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A64_flip,8*offset+bitlen)>>8)));
} }
else if (bitlen<=128) { else if (bitlen<=128) {
uint8_t A128_flip[16]; uint8_t A128_flip[16+offset];
uint128_t Aprime= (uint32_t)(((uint128_t)*A)<<(128-bitlen)); if (ones_flag) {
A128_flip[0]=((uint8_t*)&Aprime)[15]; A128_flip[1]=((uint8_t*)&Aprime)[14]; A128_flip[0] = 0xff;
A128_flip[2]=((uint8_t*)&Aprime)[13]; A128_flip[3]=((uint8_t*)&Aprime)[12]; A128_flip[1] = 0xff;
A128_flip[4]=((uint8_t*)&Aprime)[11]; A128_flip[5]=((uint8_t*)&Aprime)[10]; A128_flip[2] = 0xff;
A128_flip[6] =((uint8_t*)&Aprime)[9]; A128_flip[7] =((uint8_t*)&Aprime)[8]; }
A128_flip[8] =((uint8_t*)&Aprime)[7]; A128_flip[9] =((uint8_t*)&Aprime)[6]; uint128_t Aprime= (uint128_t)(((uint128_t)*A)<<(128-bitlen));
A128_flip[10]=((uint8_t*)&Aprime)[5]; A128_flip[11]=((uint8_t*)&Aprime)[4]; A128_flip[0+offset]=((uint8_t*)&Aprime)[15]; A128_flip[1+offset]=((uint8_t*)&Aprime)[14];
A128_flip[12]=((uint8_t*)&Aprime)[3]; A128_flip[13]=((uint8_t*)&Aprime)[2]; A128_flip[2+offset]=((uint8_t*)&Aprime)[13]; A128_flip[3+offset]=((uint8_t*)&Aprime)[12];
A128_flip[14]=((uint8_t*)&Aprime)[1]; A128_flip[15]=((uint8_t*)&Aprime)[0]; A128_flip[4+offset]=((uint8_t*)&Aprime)[11]; A128_flip[5+offset]=((uint8_t*)&Aprime)[10];
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,bitlen)>>8))); A128_flip[6+offset] =((uint8_t*)&Aprime)[9]; A128_flip[7+offset] =((uint8_t*)&Aprime)[8];
A128_flip[8+offset] =((uint8_t*)&Aprime)[7]; A128_flip[9+offset] =((uint8_t*)&Aprime)[6];
A128_flip[10+offset]=((uint8_t*)&Aprime)[5]; A128_flip[11+offset]=((uint8_t*)&Aprime)[4];
A128_flip[12+offset]=((uint8_t*)&Aprime)[3]; A128_flip[13+offset]=((uint8_t*)&Aprime)[2];
A128_flip[14+offset]=((uint8_t*)&Aprime)[1]; A128_flip[15+offset]=((uint8_t*)&Aprime)[0];
tcrc = (uint64_t)((crcmask^(crc24c(A128_flip,8*offset+bitlen)>>8)));
} }
int n; int n;
...@@ -473,7 +493,6 @@ void polar_encoder_fast(uint64_t *A, ...@@ -473,7 +493,6 @@ void polar_encoder_fast(uint64_t *A,
//??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0 //??? b_{N'-1} b_{N'-2} ... b_{N'-A} b_{N'-A-1} ... b_{N'-A-Nparity} = a_{N-1} a_{N-2} ... a_{N-A} p_{N_parity-1} ... p_0
for (n=0; n<quadwlen; n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc; for (n=0; n<quadwlen; n++) if (n==0) B[n] = (A[n] << polarParams->crcParityBits) | tcrc;
else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits)); else B[n] = (A[n] << polarParams->crcParityBits) | (A[n-1]>>(64-polarParams->crcParityBits));
......
...@@ -484,29 +484,20 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { ...@@ -484,29 +484,20 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
} }
} }
for (i=0; i<NUMBER_OF_NR_UE_MAX; i++) { for (i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
for (j=0; j<2; j++) { for (j=0; j<2; j++) {
// ULSCH for RA
if(i==0) {
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
}
// ULSCH for data // ULSCH for data
gNB->ulsch[i+1][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0); gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
if (!gNB->ulsch[i+1][j]) { if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n"); LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1); exit(-1);
} }
/*
LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i); LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i);
// [hna] added here for RT implementation // [hna] added here for RT implementation
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
...@@ -526,13 +517,10 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { ...@@ -526,13 +517,10 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
rel15_ul->ulsch_pdu_rel15.rv = 0; rel15_ul->ulsch_pdu_rel15.rv = 0;
rel15_ul->ulsch_pdu_rel15.n_layers = 1; rel15_ul->ulsch_pdu_rel15.n_layers = 1;
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
*/
//////////////////////////////////////////////////////////////////////////
} }
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
} }
gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
......
...@@ -74,6 +74,10 @@ int nr_phy_init_RU(RU_t *ru) { ...@@ -74,6 +74,10 @@ int nr_phy_init_RU(RU_t *ru) {
} }
// allocate precoding input buffers (TX)
ru->common.txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
for(i=0; i< 15; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
// allocate IFFT input buffers (TX) // allocate IFFT input buffers (TX)
ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF,
...@@ -105,37 +109,33 @@ int nr_phy_init_RU(RU_t *ru) { ...@@ -105,37 +109,33 @@ int nr_phy_init_RU(RU_t *ru) {
RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX); RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX);
LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst); LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst);
for (i=0; i<RC.nb_nr_L1_inst; i++) { int beam_count = 0;
for (p=0;p<15;p++) { if (ru->nb_tx>1) {
if (p == 0|| p==5) { for (p=0;p<fp->Lmax;p++) {
ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); if ((fp->L_ssb >> p) & 0x01)
for (j=0; j<ru->nb_tx; j++) { beam_count++;
ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); }
// antenna ports 0-3 are mapped on antennas 0-3 AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx));
// antenna port 4 is mapped on antenna 0
// antenna ports 5-14 are mapped on all antennas int l_ind = 0;
if (((p<4) && (p==j)) || ((p==4) && (j==0))) { for (i=0; i<RC.nb_nr_L1_inst; i++) {
for (re=0; re<fp->ofdm_symbol_size; re++) for (p=0;p<fp->Lmax;p++) {
{ if ((fp->L_ssb >> p) & 0x01) {
ru->beam_weights[i][p][j][re] = 0x00007fff; ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*));
for (j=0; j<ru->nb_tx; j++) {
//LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
} for (re=0; re<fp->ofdm_symbol_size; re++)
} ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind];
else if (p>4) { //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j);
for (re=0; re<fp->ofdm_symbol_size; re++) l_ind++;
{ } // for j
ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; } // for p
//LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); }
} } //for i
} }
//LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t));
} // for (j=0
} // if (p<ru
} // for p
} //for i
} // !=IF5 } // !=IF5
ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP );
return(0); return(0);
...@@ -162,6 +162,10 @@ void nr_phy_free_RU(RU_t *ru) ...@@ -162,6 +162,10 @@ void nr_phy_free_RU(RU_t *ru)
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]);
free_and_zero(ru->common.rxdata_7_5kHz); free_and_zero(ru->common.rxdata_7_5kHz);
// free beamforming input buffers (TX)
for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]);
free_and_zero(ru->common.txdataF);
// free IFFT input buffers (TX) // free IFFT input buffers (TX)
for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]);
free_and_zero(ru->common.txdataF_BF); free_and_zero(ru->common.txdataF_BF);
...@@ -179,10 +183,8 @@ void nr_phy_free_RU(RU_t *ru) ...@@ -179,10 +183,8 @@ void nr_phy_free_RU(RU_t *ru)
for (i = 0; i < RC.nb_nr_L1_inst; i++) { for (i = 0; i < RC.nb_nr_L1_inst; i++) {
for (p = 0; p < 15; p++) { for (p = 0; p < 15; p++) {
if (p == 0 || p == 5) {
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
free_and_zero(ru->beam_weights[i][p]); free_and_zero(ru->beam_weights[i][p]);
}
} }
} }
} }
......
...@@ -79,30 +79,39 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f ...@@ -79,30 +79,39 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_f
return symbol; return symbol;
} }
int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot) int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame)
{ {
uint8_t n_hf; uint8_t n_hf;
uint16_t p,mu,hf_slots;
uint64_t ssb_map;
int rel_slot; int rel_slot;
mu = cfg->subframe_config.numerology_index_mu.value;
ssb_map = cfg->sch_config.ssb_scg_position_in_burst.value;
p = cfg->sch_config.ssb_periodicity.value;
n_hf = cfg->sch_config.half_frame_index.value; n_hf = cfg->sch_config.half_frame_index.value;
// if SSB periodicity is 5ms, they are transmitted in both half frames // if SSB periodicity is 5ms, they are transmitted in both half frames
if ( cfg->sch_config.ssb_periodicity.value == 5) { if ( (p>10) && (frame%(p/10)) )
if (slot<10) return 0;
else {
hf_slots = (10<<mu)>>1; // number of slots per half frame
// if SSB periodicity is 5ms, they are transmitted in both half frames
if ( p == 5) {
if (slot<hf_slots)
n_hf=0; n_hf=0;
else else
n_hf=1; n_hf=1;
} }
// to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be
rel_slot = (n_hf)? (slot-10) : slot; rel_slot = (n_hf)? (slot-hf_slots) : slot;
if(rel_slot<10 && rel_slot>=0)
return 1;
else
return 0;
return ( ((ssb_map >> rel_slot*2) & 0x01) || ((ssb_map >> (1+rel_slot*2)) & 0x01) );
}
} }
...@@ -266,15 +275,18 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, ...@@ -266,15 +275,18 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
// definition of Lmax according to ts 38.213 section 4.1 // definition of Lmax according to ts 38.213 section 4.1
if (fp->dl_CarrierFreq < 6e9){ if (fp->dl_CarrierFreq < 6e9) {
if(fp->frame_type && (fp->ssb_type==2)) if(fp->frame_type && (fp->ssb_type==2))
fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
else else
fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
} } else {
else
fp->Lmax = 64; fp->Lmax = 64;
}
fp->N_ssb = 0;
for (int p=0; p<fp->Lmax; p++)
fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
return 0; return 0;
} }
......
...@@ -378,7 +378,7 @@ void phy_config_request(PHY_Config_t *phy_config); ...@@ -378,7 +378,7 @@ void phy_config_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index); int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb, uint8_t half_frame_index);
int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot); int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame);
int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms(nfapi_nr_config_request_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "PHY/LTE_TRANSPORT/transport_eNB.h"
#include "modulation_eNB.h" #include "modulation_eNB.h"
#include "nr_modulation.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
int beam_precoding(int32_t **txdataF, int beam_precoding(int32_t **txdataF,
...@@ -135,3 +136,33 @@ int beam_precoding_one_eNB(int32_t **txdataF, ...@@ -135,3 +136,33 @@ int beam_precoding_one_eNB(int32_t **txdataF,
} }
return 0; return 0;
} }
int nr_beam_precoding(int32_t **txdataF,
int32_t **txdataF_BF,
NR_DL_FRAME_PARMS *frame_parms,
int32_t ***beam_weights,
int slot,
int symbol,
int aa,
int nb_antenna_ports)
{
uint8_t p;
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size));
for (p=0; p<nb_antenna_ports; p++) {
if ((frame_parms->L_ssb >> p) & 0x01) {
multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size],
(int16_t*)beam_weights[p][aa],
(int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],
0,
frame_parms->ofdm_symbol_size,
15);
}
}
return 0;
}
...@@ -93,4 +93,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, ...@@ -93,4 +93,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
*/ */
void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH); void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH);
int nr_beam_precoding(int32_t **txdataF,
int32_t **txdataF_BF,
NR_DL_FRAME_PARMS *frame_parms,
int32_t ***beam_weights,
int slot,
int symbol,
int aa,
int nb_antenna_ports
);
#endif #endif
...@@ -86,6 +86,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input ...@@ -86,6 +86,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input
) )
{ {
if(nb_symbols == 0) return;
short temp[4096*4] __attribute__((aligned(32))); short temp[4096*4] __attribute__((aligned(32)));
unsigned short i,j; unsigned short i,j;
short k; short k;
......
...@@ -37,14 +37,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -37,14 +37,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned short bwp_start_subcarrier, unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pusch) unsigned short nb_rb_pusch)
{ {
int pilot[1320] __attribute__((aligned(16))); int pilot[3280] __attribute__((aligned(16)));
unsigned char aarx; unsigned char aarx;
unsigned short k; unsigned short k;
unsigned int pilot_cnt; unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*ul_ch,*fl,*fm,*fr,*fml,*fmr,*fmm; int16_t ch[2],*pil,*rxF,*ul_ch;
int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh;
int ch_offset,symbol_offset, length_dmrs, UE_id = 0; int ch_offset,symbol_offset, length_dmrs, UE_id = 0;
unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config
int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(16))); int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(32)));
int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time;
#ifdef DEBUG_CH #ifdef DEBUG_CH
...@@ -82,6 +83,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -82,6 +83,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
fmm = filt8_mm0; fmm = filt8_mm0;
fml = filt8_m0; fml = filt8_m0;
fmr = filt8_mr0; fmr = filt8_mr0;
fdcl = filt8_dcl0;
fdcr = filt8_dcr0;
fdclh = filt8_dcl0_h;
fdcrh = filt8_dcr0_h;
break; break;
case 1: case 1:
...@@ -91,6 +96,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -91,6 +96,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
fmm = filt8_mm1; fmm = filt8_mm1;
fml = filt8_ml1; fml = filt8_ml1;
fmr = filt8_m1; fmr = filt8_m1;
fdcl = filt8_dcl1;
fdcr = filt8_dcr1;
fdclh = filt8_dcl1_h;
fdcrh = filt8_dcr1_h;
break; break;
default: default:
...@@ -119,12 +128,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -119,12 +128,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size)); memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
#ifdef DEBUG_PUSCH #ifdef DEBUG_PUSCH
printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_DL); printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset); printf("k %d, first_carrier %d\n",k,gNB->frame_parms.first_carrier_offset);
printf("rxF addr %p p %d\n", rxF,p); printf("rxF addr %p p %d\n", rxF,p);
printf("ul_ch addr %p nushift %d\n",ul_ch,nushift); printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
#endif #endif
//if ((gNB->frame_parms.N_RB_DL&1)==0) { //if ((gNB->frame_parms.N_RB_UL&1)==0) {
// Treat first 2 pilots specially (left edge) // Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
...@@ -140,7 +149,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -140,7 +149,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch, ul_ch,
8); 8);
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//for (int i= 0; i<8; i++) //for (int i= 0; i<8; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
...@@ -156,7 +165,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -156,7 +165,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch, ul_ch,
8); 8);
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch); //printf("ul_ch addr %p\n",ul_ch);
...@@ -175,7 +184,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -175,7 +184,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8; ul_ch+=8;
...@@ -193,7 +202,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -193,7 +202,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8); 8);
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
...@@ -206,7 +215,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -206,7 +215,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch, ul_ch,
8); 8);
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8; ul_ch+=8;
...@@ -227,7 +236,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -227,7 +236,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i)); //printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
...@@ -242,7 +251,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -242,7 +251,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
8); 8);
pil+=2; pil+=2;
re_offset = (re_offset+2)&(gNB->frame_parms.ofdm_symbol_size-1); re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8; ul_ch+=8;
...@@ -256,6 +265,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -256,6 +265,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch, ul_ch,
8); 8);
// check if PRB crosses DC and improve estimates around DC
if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) {
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier);
uint16_t idxPil = idxDC/2;
re_offset = k;
pil = (int16_t *)&pilot[0];
pil += (idxPil-2);
ul_ch += (idxDC-4);
ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10);
re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// for proper allignment of SIMD vectors
if((gNB->frame_parms.N_RB_UL&1)==0) {
multadd_real_vector_complex_scalar(fdcl,
ch,
ul_ch-4,
8);
pil += 4;
re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(fdcr,
ch,
ul_ch-4,
8);
} else {
multadd_real_vector_complex_scalar(fdclh,
ch,
ul_ch,
8);
pil += 4;
re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(fdcrh,
ch,
ul_ch,
8);
}
}
#ifdef DEBUG_PDSCH
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI+=2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
// Convert to time domain // Convert to time domain
memset(temp_in_ifft_0, 0, gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t)); memset(temp_in_ifft_0, 0, gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t));
memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t)); memcpy(temp_in_ifft_0, &ul_ch_estimates[aarx][symbol_offset], nb_rb_pusch * NR_NB_SC_PER_RB * sizeof(int32_t));
...@@ -322,4 +394,4 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -322,4 +394,4 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif #endif
return(0); return(0);
} }
\ No newline at end of file
...@@ -55,7 +55,7 @@ int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); ...@@ -55,7 +55,7 @@ int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit);
void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell);
void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell); void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell);
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position); uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
#undef EXTERN #undef EXTERN
......
...@@ -148,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, ...@@ -148,7 +148,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
//printf("x1 : %x, x2 : %x\n",x1,x2); //printf("x1 : %x, x2 : %x\n",x1,x2);
} }
for (n=0; n<52; n++) { for (n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
x1 = (x1>>1) ^ (x1>>4); x1 = (x1>>1) ^ (x1>>4);
x1 = x1 ^ (x1<<31) ^ (x1<<28); x1 = x1 ^ (x1<<31) ^ (x1<<28);
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4); x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
......
...@@ -155,7 +155,7 @@ void nr_pdcch_scrambling(uint32_t *in, ...@@ -155,7 +155,7 @@ void nr_pdcch_scrambling(uint32_t *in,
} }
} }
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc,
uint32_t **gold_pdcch_dmrs, uint32_t **gold_pdcch_dmrs,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
...@@ -168,8 +168,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -168,8 +168,6 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
nr_cce_t cce; nr_cce_t cce;
nr_reg_t reg; nr_reg_t reg;
nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE]; nr_reg_t reg_mapping_list[NR_MAX_PDCCH_AGG_LEVEL*NR_NB_REG_PER_CCE];
/*First iteration: single DCI*/
NR_gNB_DCI_ALLOC_t dci_alloc = pdcch_vars.dci_alloc[0];
nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params; nfapi_nr_dl_config_pdcch_parameters_rel15_t pdcch_params = dci_alloc.pdcch_params;
/*The coreset is initialised /*The coreset is initialised
...@@ -214,7 +212,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, ...@@ -214,7 +212,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)? uint16_t Nid = (pdcch_params.search_space_type == NFAPI_NR_SEARCH_SPACE_TYPE_UE_SPECIFIC)?
pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value; pdcch_params.scrambling_id : config.sch_config.physical_cell_id.value;
t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L); t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_alloc.size, dci_alloc.L);
polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti,currentPtr); polar_encoder_fast(dci_alloc.dci_pdu, encoder_output, pdcch_params.rnti, 1, currentPtr);
#ifdef DEBUG_CHANNEL_CODING #ifdef DEBUG_CHANNEL_CODING
printf("polar rnti %d\n",pdcch_params.rnti); printf("polar rnti %d\n",pdcch_params.rnti);
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
......
...@@ -30,7 +30,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, ...@@ -30,7 +30,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
uint16_t N_RB, uint16_t N_RB,
nfapi_nr_config_request_t *config); nfapi_nr_config_request_t *config);
uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars, uint8_t nr_generate_dci_top(NR_gNB_DCI_ALLOC_t dci_alloc,
uint32_t **gold_pdcch_dmrs, uint32_t **gold_pdcch_dmrs,
int32_t *txdataF, int32_t *txdataF,
int16_t amp, int16_t amp,
......
...@@ -90,6 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, ...@@ -90,6 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
uint8_t Qm = rel15->modulation_order; uint8_t Qm = rel15->modulation_order;
uint32_t encoded_length = nb_symbols*Qm; uint32_t encoded_length = nb_symbols*Qm;
/// CRC, coding, interleaving and rate matching /// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
start_meas(dlsch_encoding_stats); start_meas(dlsch_encoding_stats);
...@@ -206,7 +207,6 @@ for (int i=0; i<n_dmrs>>4; i++) { ...@@ -206,7 +207,6 @@ for (int i=0; i<n_dmrs>>4; i++) {
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n",
start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols); start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols);
#endif #endif
for (int ap=0; ap<rel15->nb_layers; ap++) { for (int ap=0; ap<rel15->nb_layers; ap++) {
// DMRS params for this ap // DMRS params for this ap
...@@ -221,6 +221,7 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); ...@@ -221,6 +221,7 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
#endif #endif
uint8_t k_prime=0; uint8_t k_prime=0;
uint16_t m=0, n=0, dmrs_idx=0, k=0; uint16_t m=0, n=0, dmrs_idx=0, k=0;
int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
dmrs_idx = rel15->start_prb*6; dmrs_idx = rel15->start_prb*6;
else else
...@@ -230,12 +231,12 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); ...@@ -230,12 +231,12 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol);
k = start_sc; k = start_sc;
for (int i=0; i<rel15->n_prb*NR_NB_SC_PER_RB; i++) { for (int i=0; i<rel15->n_prb*NR_NB_SC_PER_RB; i++) {
if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) { if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) {
((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING #ifdef DEBUG_DLSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif #endif
dmrs_idx++; dmrs_idx++;
k_prime++; k_prime++;
...@@ -245,12 +246,12 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_ ...@@ -245,12 +246,12 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_
else { else {
((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15; ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING #ifdef DEBUG_DLSCH_MAPPING
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif #endif
m++; m++;
} }
......
...@@ -314,7 +314,7 @@ int nr_dlsch_encoding(unsigned char *a, ...@@ -314,7 +314,7 @@ int nr_dlsch_encoding(unsigned char *a,
unsigned int G; unsigned int G;
unsigned int crc=1; unsigned int crc=1;
uint8_t harq_pid = dlsch->harq_ids[frame&2][slot]; uint8_t harq_pid = dlsch->harq_ids[frame%2][slot];
AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid); AssertFatal(harq_pid<8 && harq_pid>=0,"illegal harq_pid %d\b",harq_pid);
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
uint16_t nb_rb = rel15.n_prb; uint16_t nb_rb = rel15.n_prb;
......
...@@ -257,7 +257,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { ...@@ -257,7 +257,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
AssertFatal(gNB!=NULL,"gNB is null\n"); AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) { for (i=0; i<NUMBER_OF_NR_DLSCH_MAX; i++) {
AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i);
AssertFatal(gNB->dlsch[i]!=NULL,"gNB->dlsch[%d][0] is null\n",i); AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i);
LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index);
if ((gNB->dlsch[i][0]->harq_mask >0) && if ((gNB->dlsch[i][0]->harq_mask >0) &&
(gNB->dlsch[i][0]->rnti==rnti)) return i; (gNB->dlsch[i][0]->rnti==rnti)) return i;
...@@ -269,6 +269,26 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { ...@@ -269,6 +269,26 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
return first_free_index; return first_free_index;
} }
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) {
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(gNB!=NULL,"gNB is null\n");
for (i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
AssertFatal(gNB->ulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i);
AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i);
LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index);
if ((gNB->ulsch[i][0]->harq_mask >0) &&
(gNB->ulsch[i][0]->rnti==rnti)) return i;
else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
}
if (type == SEARCH_EXIST) return -1;
if (first_free_index != -1)
gNB->ulsch[first_free_index][0]->rnti = 0;
return first_free_index;
}
void nr_fill_dlsch(PHY_VARS_gNB *gNB, void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame, int frame,
int slot, int slot,
...@@ -290,3 +310,41 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, ...@@ -290,3 +310,41 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB,
} }
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu) {
int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
AssertFatal( (ulsch_id>=0) && (ulsch_id<NUMBER_OF_NR_ULSCH_MAX),
"illegal or no ulsch_id found!!! rnti %04x ulsch_id %d\n",ulsch_pdu->rnti,ulsch_id);
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0];
int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
ulsch->rnti = ulsch_pdu->rnti;
//ulsch->rnti_type;
ulsch->harq_mask |= 1<<harq_pid;
ulsch->harq_process_id[slot] = harq_pid;
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch->harq_processes[harq_pid]->ulsch_pdu;
LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid);
//FK this is still a bad hack. We need to replace the L1 FAPI structures with the new scf ones as well.
rel15_ul->rnti = ulsch_pdu->rnti;
rel15_ul->ulsch_pdu_rel15.start_rb = ulsch_pdu->rb_start;
rel15_ul->ulsch_pdu_rel15.number_rbs = ulsch_pdu->rb_size;
rel15_ul->ulsch_pdu_rel15.start_symbol = ulsch_pdu->start_symbol_index;
rel15_ul->ulsch_pdu_rel15.number_symbols = ulsch_pdu->nr_of_symbols;
rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; //where should this come from?
rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; //where should this come from?
rel15_ul->ulsch_pdu_rel15.Qm = ulsch_pdu->qam_mod_order;
rel15_ul->ulsch_pdu_rel15.mcs = ulsch_pdu->mcs_index;
rel15_ul->ulsch_pdu_rel15.rv = ulsch_pdu->pusch_data.rv_index;
rel15_ul->ulsch_pdu_rel15.n_layers = ulsch_pdu->nrOfLayers;
rel15_ul->ulsch_pdu_rel15.R = ulsch_pdu->target_code_rate;
}
...@@ -298,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -298,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i); a_reversed |= (((uint64_t)pbch->pbch_a_prime>>i)&1)<<(31-i);
/// CRC, coding and rate matching /// CRC, coding and rate matching
polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, polar_encoder_fast (&a_reversed, (uint32_t *)pbch->pbch_e, 0, 0,
nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL) nr_polar_params( NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL)
); );
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
......
...@@ -190,4 +190,19 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, ...@@ -190,4 +190,19 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
uint32_t nb_rb, uint32_t nb_rb,
uint32_t nb_re, uint32_t nb_re,
uint8_t symbol, uint8_t symbol,
uint8_t mod_order); uint8_t mod_order);
\ No newline at end of file
void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch,uint8_t N_RB_UL); void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
...@@ -79,4 +79,4 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, ...@@ -79,4 +79,4 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
int slot_rx, int slot_rx,
int UE_id, int UE_id,
uint8_t harq_pid); uint8_t harq_pid);
int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
...@@ -48,20 +48,22 @@ ...@@ -48,20 +48,22 @@
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include <syscall.h> #include <syscall.h>
//#define DEBUG_ULSCH_DECODING //#define DEBUG_ULSCH_DECODING
//#define gNB_DEBUG_TRACE
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
#define PRINT_CRC_CHECK //#define PRINT_CRC_CHECK
static uint64_t nb_total_decod =0; static uint64_t nb_total_decod =0;
static uint64_t nb_error_decod =0; static uint64_t nb_error_decod =0;
//extern double cpuf; //extern double cpuf;
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch,uint8_t N_RB_UL) void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
{ {
int i,r; int i,r;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
NR_gNB_ULSCH_t *ulsch = *ulschptr;
if (ulsch) { if (ulsch) {
if (N_RB_UL != 273) { if (N_RB_UL != 273) {
...@@ -105,7 +107,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch,uint8_t N_RB_UL) ...@@ -105,7 +107,7 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch,uint8_t N_RB_UL)
} }
} }
free16(ulsch,sizeof(NR_gNB_ULSCH_t)); free16(ulsch,sizeof(NR_gNB_ULSCH_t));
ulsch = NULL; *ulschptr = NULL;
} }
} }
...@@ -185,8 +187,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8 ...@@ -185,8 +187,8 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8
} }
printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag);
free_gNB_ulsch(ulsch,N_RB_UL); free_gNB_ulsch(&ulsch,N_RB_UL);
return(NULL); return(NULL);
} }
...@@ -288,6 +290,10 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) ...@@ -288,6 +290,10 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
} }
} }
#ifdef PRINT_CRC_CHECK
static uint32_t prnt_crc_cnt = 0;
#endif
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id, uint8_t UE_id,
short *ulsch_llr, short *ulsch_llr,
...@@ -307,7 +313,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -307,7 +313,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t crc_type; uint8_t crc_type;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][0]; #ifdef PRINT_CRC_CHECK
prnt_crc_cnt++;
#endif
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15; nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
...@@ -315,11 +326,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -315,11 +326,15 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
t_nrLDPC_dec_params* p_decParams = &decParams; t_nrLDPC_dec_params* p_decParams = &decParams;
t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats procTime;
t_nrLDPC_time_stats* p_procTime = &procTime ; t_nrLDPC_time_stats* p_procTime = &procTime ;
if (!harq_process) {
printf("ulsch_decoding.c: NULL harq_process pointer\n");
return (ulsch->max_ldpc_iterations + 1);
}
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
int16_t z [68*384]; int16_t z [68*384];
int8_t l [68*384]; int8_t l [68*384];
uint8_t kc; uint8_t kc=255;
uint8_t Ilbrm = 0; uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984; uint32_t Tbslbrm = 950984;
double Coderate = 0.0; double Coderate = 0.0;
...@@ -346,11 +361,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -346,11 +361,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
return (ulsch->max_ldpc_iterations + 1); return (ulsch->max_ldpc_iterations + 1);
} }
if (!harq_process) {
printf("ulsch_decoding.c: NULL harq_process pointer\n");
return (ulsch->max_ldpc_iterations + 1);
}
if (!frame_parms) { if (!frame_parms) {
printf("ulsch_decoding.c: NULL frame_parms pointer\n"); printf("ulsch_decoding.c: NULL frame_parms pointer\n");
return (ulsch->max_ldpc_iterations + 1); return (ulsch->max_ldpc_iterations + 1);
...@@ -533,7 +543,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -533,7 +543,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
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);
} }
printf("decoder input(segment %d) :",r); printf("decoder input(segment %u) :",r);
int i; int i;
for (i=0;i<(3*8*Kr_bytes)+12;i++) for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,harq_process->d[r][i]); printf("%d : %d\n",i,harq_process->d[r][i]);
...@@ -570,6 +580,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -570,6 +580,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
} }
AssertFatal(kc!=255,"");
for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
} }
...@@ -595,12 +606,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -595,12 +606,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
#ifdef PRINT_CRC_CHECK #ifdef PRINT_CRC_CHECK
LOG_I(PHY, "Segment %d CRC OK\n",r); //if (prnt_crc_cnt % 10 == 0)
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif #endif
ret = no_iteration_ldpc; ret = no_iteration_ldpc;
} else { } else {
#ifdef PRINT_CRC_CHECK #ifdef PRINT_CRC_CHECK
LOG_I(PHY, "CRC NOK\n"); //if (prnt_crc_cnt%10 == 0)
LOG_I(PHY, "CRC NOK\n");
#endif #endif
ret = ulsch->max_ldpc_iterations + 1; ret = ulsch->max_ldpc_iterations + 1;
} }
...@@ -619,7 +632,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -619,7 +632,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int k=0;k<A>>3;k++) for (int k=0;k<A>>3;k++)
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
#endif #endif
...@@ -646,9 +659,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -646,9 +659,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (err_flag == 1) { if (err_flag == 1) {
#if gNB_DEBUG_TRACE #ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n",
phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
#endif #endif
// harq_process->harq_ack.ack = 0; // harq_process->harq_ack.ack = 0;
...@@ -674,9 +687,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -674,9 +687,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
} else { } else {
#if gNB_DEBUG_TRACE #ifdef gNB_DEBUG_TRACE
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS);
#endif #endif
harq_process->status = SCH_IDLE; harq_process->status = SCH_IDLE;
...@@ -707,7 +720,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ...@@ -707,7 +720,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
#ifdef DEBUG_ULSCH_DECODING #ifdef DEBUG_ULSCH_DECODING
printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
printf("copied %d bytes to b sequence (harq_pid %d)\n", printf("copied %d bytes to b sequence (harq_pid %d)\n",
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
printf("b[0] = %x,c[%d] = %x\n", printf("b[0] = %x,c[%d] = %x\n",
......
...@@ -973,7 +973,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -973,7 +973,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
uint8_t first_symbol_flag, aarx, aatx, pilots; // pilots, a flag to indicate DMRS REs in current symbol uint8_t first_symbol_flag, aarx, aatx, pilots; // pilots, a flag to indicate DMRS REs in current symbol
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
uint32_t nb_re_pusch, bwp_start_subcarrier; uint32_t nb_re_pusch, bwp_start_subcarrier;
int avgs; int avgs;
int avg[4]; int avg[4];
...@@ -986,7 +986,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -986,7 +986,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
first_symbol_flag = 1; first_symbol_flag = 1;
} }
if (symbol == 2){ // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1) if (symbol == rel15_ul->start_symbol){ // [hna] here it is assumed that first carries 6 DMRS REs (dmrs-type 1)
nb_re_pusch = rel15_ul->number_rbs * 6; nb_re_pusch = rel15_ul->number_rbs * 6;
pilots = 1; pilots = 1;
} else { } else {
...@@ -1026,7 +1026,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -1026,7 +1026,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext,
frame_parms, frame_parms,
gNB->ulsch[UE_id+1], gNB->ulsch[UE_id],
symbol, symbol,
pilots, pilots,
rel15_ul->number_rbs); rel15_ul->number_rbs);
......
...@@ -123,6 +123,30 @@ short filt8_m0[8] = { ...@@ -123,6 +123,30 @@ short filt8_m0[8] = {
short filt8_mm0[8]= { short filt8_mm0[8]= {
0,0,0,8192,16384,8192,0,0}; 0,0,0,8192,16384,8192,0,0};
short filt8_dcma[8]= {
16384,12288,8192,4096,4096,0,0,0};
short filt8_dcmb[8]= {
0,4096,8192,4096,4096,0,0,0};
short filt8_dcmc[8]= {
0,0,0,4096,4096,8192,4096,0};
short filt8_dcmd[8]= {
0,0,0,4096,4096,8192,12288,16384};
short filt8_dcl0[8]= {
0,0,16384,12288,8192,4096,0,0};
short filt8_dcr0[8]= {
0,0,0,4096,8192,12288,16384,0};
short filt8_dcl0_h[8]= {
16384,12288,8192,4096,0,0,0,0};
short filt8_dcr0_h[8]= {
0,4096,8192,12288,16384,0,0,0};
short filt8_l1[8] = { short filt8_l1[8] = {
24576,16384,0,0,0,0,0,0}; 24576,16384,0,0,0,0,0,0};
...@@ -136,4 +160,16 @@ short filt8_m1[8] = { ...@@ -136,4 +160,16 @@ short filt8_m1[8] = {
0,0,8192,16384,8192,0,0,0}; 0,0,8192,16384,8192,0,0,0};
short filt8_mm1[8]= { short filt8_mm1[8]= {
0,0,0,0,8192,16384,8192,0}; 0,0,0,0,8192,16384,8192,0};
\ No newline at end of file
short filt8_dcl1[8]= {
0,0,0,16384,12288,8192,4096,0};
short filt8_dcr1[8]= {
0,0,0,0,4096,8192,12288,16384};
short filt8_dcl1_h[8]= {
0,16384,12288,8192,4096,0,0,0};
short filt8_dcr1_h[8]= {
0,0,4096,8192,12288,16384,0,0};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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