Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
e2d82cd2
Commit
e2d82cd2
authored
Jul 19, 2018
by
tyhsu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
turbo decoder in gpu
parent
9927838e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
557 additions
and
898 deletions
+557
-898
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+104
-68
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+453
-830
No files found.
cmake_targets/CMakeLists.txt
View file @
e2d82cd2
#/*
# * 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.0 (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
# */
################################################################################
# OpenAirInterface
# Copyright(c) 1999 - 2014 Eurecom
#
# OpenAirInterface is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenAirInterface is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenAirInterface.The full GNU General Public License is
# included in this distribution in the file called "COPYING". If not,
# see <http://www.gnu.org/licenses/>.
#
# Contact Information
# OpenAirInterface Admin: openair_admin@eurecom.fr
# OpenAirInterface Tech : openair_tech@eurecom.fr
# OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
#
# Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
# Author: laurent THOMAS, Lionel GAUTHIER
###############################################################################
cmake_minimum_required
(
VERSION 2.8
)
##############################################
# Base CUDA setting
##############################################
find_package
(
CUDA
)
message
(
"cuda include
${
CUDA_INCLUDE_DIRS
}
"
)
message
(
"cud library
${
CUDA_LIBRARY_DIRS
}
"
)
add_definitions
(
"-L/usr/local/cuda/lib64"
)
SET
(
CUDA_NVCC_FLAGS
"
${
CUDA_NVCC_FLAGS
}
;-arch=sm_52;"
)
# Disable warnings for CUDA
SET
(
CUDA_NVCC_FLAGS
"
${
CUDA_NVCC_FLAGS
}
;-w;-O3"
)
SET
(
CUDA_VERBOSE_BUILD ON
)
SET
(
CUDA_HOST_COMPILER
"/usr/bin/g++"
)
SET
(
CUDA_SEPARABLE_COMPILATION ON
)
#############################################
# Base directories, compatible with legacy OAI building
################################################
...
...
@@ -174,13 +199,14 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU
# these changes are related to hardcoded path to include .h files
add_definitions
(
-DCMAKER
)
set
(
CMAKE_C_FLAGS_DEBUG
"
${
CMAKE_C_FLAGS
}
-g -DMALLOC_CHECK_=3"
)
set
(
CMAKE_C_FLAGS_RELWITHDEBINFO
"
${
CMAKE_C_FLAGS
}
-g -DMALLOC_CHECK_=3 -O
2
"
)
set
(
CMAKE_C_FLAGS_RELWITHDEBINFO
"
${
CMAKE_C_FLAGS
}
-g -DMALLOC_CHECK_=3 -O
3
"
)
set
(
GIT_BRANCH
"UNKNOWN"
)
set
(
GIT_COMMIT_HASH
"UNKNOWN"
)
set
(
GIT_COMMIT_DATE
"UNKNOWN"
)
find_package
(
Git
)
if
(
GIT_FOUND
)
message
(
"git found:
${
GIT_EXECUTABLE
}
"
)
...
...
@@ -256,7 +282,15 @@ if (${ENABLE_ITTI})
endif
(
${
ENABLE_ITTI
}
)
add_boolean_option
(
RTAI False
"Use RTAI"
)
if
(
${
RTAI
}
)
set
(
DEADLINE_SCHEDULER False
)
set
(
CPU_AFFINITY False
)
add_definitions
(
"-DENABLE_RTAI_CLOCK"
)
add_definitions
(
"-DCONFIG_RTAI_LXRT_INLINE"
)
include_directories
(
"/usr/realtime/include"
)
include_directories
(
"/usr/realtime/include/asm"
)
set
(
RTAI_SOURCE sched_dlsch.c sched_rx_pdsch.c rt_wrapper.c vcd_signal_dumper.c log.c
)
endif
(
${
RTAI
}
)
#############################
# ASN.1 grammar C code generation & dependancies
...
...
@@ -491,7 +525,7 @@ include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
#set (option_HWEXMIMOLIB_lib "-l ")
set
(
HWLIB_EXMIMO_SOURCE
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
#
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
add_library
(
oai_exmimodevif MODULE
${
HWLIB_EXMIMO_SOURCE
}
)
...
...
@@ -532,8 +566,8 @@ if (${RF_BOARD} STREQUAL "EXMIMO")
include_directories
(
"
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/"
)
include_directories
(
"
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/DEFS/"
)
set
(
HW_SOURCE
${
HW_SOURCE
}
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
)
#
${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c)
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
${
OPENAIR_TARGETS
}
/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
)
set
(
option_HW_lib
"-rdynamic -ldl"
)
elseif
(
${
RF_BOARD
}
STREQUAL
"OAI_USRP"
)
...
...
@@ -614,7 +648,6 @@ add_boolean_option(NAS_ADDRESS_FIX False "specific to oaisim: for nasmesh driver
add_boolean_option
(
NAS_NETLINK False
"???? Must be True to compile nasmesh driver without rtai"
)
add_boolean_option
(
OAISIM False
"specific to oaisim"
)
add_boolean_option
(
OAI_NW_DRIVER_USE_NETLINK True
"????"
)
add_boolean_option
(
USE_MME False
"this flag is used only one time in lte-softmodem.c"
)
add_list_string_option
(
PACKAGE_NAME
"NotDefined"
"As per attribute name"
)
add_boolean_option
(
MESSAGE_CHART_GENERATOR False
"For generating sequence diagrams"
)
...
...
@@ -838,10 +871,10 @@ include_directories("${OPENAIR_DIR}")
# Utilities Library
################
add_library
(
HASHTABLE
${
OPENAIR_DIR
}
/common/utils/hashtable/hashtable.c
${
OPENAIR_DIR
}
/common/utils/hashtable/obj_hashtable.c
${
OPENAIR_DIR
}
/common/utils/
collection/
hashtable/hashtable.c
${
OPENAIR_DIR
}
/common/utils/
collection/
hashtable/obj_hashtable.c
)
include_directories
(
${
OPENAIR_DIR
}
/common/utils/hashtable
)
include_directories
(
${
OPENAIR_DIR
}
/common/utils/
collection/
hashtable
)
if
(
MESSAGE_CHART_GENERATOR
)
add_library
(
MSC
...
...
@@ -869,16 +902,20 @@ set(UTIL_SRC
${
OPENAIR2_DIR
}
/UTIL/OCG/OCG_parse_filename.c
${
OPENAIR2_DIR
}
/UTIL/OCG/OCG_parse_XML.c
${
OPENAIR2_DIR
}
/UTIL/OCG/OCG_save_XML.c
${
OPENAIR2_DIR
}
/UTIL/OMG/client_traci_OMG.c
${
OPENAIR2_DIR
}
/UTIL/OMG/common.c
${
OPENAIR2_DIR
}
/UTIL/OMG/grid.c
${
OPENAIR2_DIR
}
/UTIL/OMG/id_manager.c
${
OPENAIR2_DIR
}
/UTIL/OMG/job.c
${
OPENAIR2_DIR
}
/UTIL/OMG/mobility_parser.c
${
OPENAIR2_DIR
}
/UTIL/OMG/omg.c
#
${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c
${
OPENAIR2_DIR
}
/UTIL/OMG/omg_hashtable.c
${
OPENAIR2_DIR
}
/UTIL/OMG/rwalk.c
${
OPENAIR2_DIR
}
/UTIL/OMG/rwp.c
${
OPENAIR2_DIR
}
/UTIL/OMG/socket_traci_OMG.c
${
OPENAIR2_DIR
}
/UTIL/OMG/static.c
${
OPENAIR2_DIR
}
/UTIL/OMG/steadystaterwp.c
${
OPENAIR2_DIR
}
/UTIL/OMG/storage_traci_OMG.c
${
OPENAIR2_DIR
}
/UTIL/OMG/trace.c
${
OPENAIR2_DIR
}
/UTIL/OMG/trace_hashtable.c
${
OPENAIR2_DIR
}
/UTIL/OPT/probe.c
...
...
@@ -891,15 +928,6 @@ set(UTIL_SRC
)
add_library
(
UTIL
${
UTIL_SRC
}
)
#set(OMG_SUMO_SRC
# ${OPENAIR2_DIR}/UTIL/OMG/client_traci_OMG.c
# ${OPENAIR2_DIR}/UTIL/OMG/id_manager.c
# ${OPENAIR2_DIR}/UTIL/OMG/sumo.c
# ${OPENAIR2_DIR}/UTIL/OMG/socket_traci_OMG.c
# ${OPENAIR2_DIR}/UTIL/OMG/storage_traci_OMG.c
# )
#add_library(OMG_SUMO ${OMG_SUMO_SRC})
set
(
SECU_OSA_SRC
${
OPENAIR2_DIR
}
/UTIL/OSA/osa_key_deriver.c
${
OPENAIR2_DIR
}
/UTIL/OSA/osa_rijndael.c
...
...
@@ -960,7 +988,6 @@ set(PHY_SRC
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/pucch.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/prach.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/pmch.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/pch.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/group_hopping.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/srs_modulation.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/drs_modulation.c
...
...
@@ -971,8 +998,6 @@ set(PHY_SRC
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/rar_tools.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/print_stats.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/initial_sync.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/if4_tools.c
${
OPENAIR1_DIR
}
/PHY/LTE_TRANSPORT/if5_tools.c
${
OPENAIR1_DIR
}
/PHY/MODULATION/ofdm_mod.c
${
OPENAIR1_DIR
}
/PHY/MODULATION/slot_fep.c
${
OPENAIR1_DIR
}
/PHY/MODULATION/slot_fep_mbsfn.c
...
...
@@ -1531,25 +1556,11 @@ endif()
pkg_search_module
(
NETTLE nettle
)
if
(
NOT
${
NETTLE_FOUND
}
)
message
(
FATAL_ERROR
"PACKAGE nettle not found: some targets will fail. Run build_oai -I again!
"
)
message
(
"PACKAGE nettle not found: some targets will fail
"
)
else
()
include_directories
(
${
NETTLE_INCLUDE_DIRS
}
)
endif
()
message
(
"NETTLE VERSION_INSTALLED =
${
NETTLE_VERSION
}
"
)
string
(
REGEX REPLACE
"([0-9]+).*"
"
\\
1"
NETTLE_VERSION_MAJOR
${
NETTLE_VERSION
}
)
string
(
REGEX REPLACE
"[0-9]+
\\
.([0-9]+).*"
"
\\
1"
NETTLE_VERSION_MINOR
${
NETTLE_VERSION
}
)
message
(
"NETTLE_VERSION_MAJOR =
${
NETTLE_VERSION_MAJOR
}
"
)
message
(
"NETTLE_VERSION_MINOR =
${
NETTLE_VERSION_MINOR
}
"
)
if
(
"
${
NETTLE_VERSION_MAJOR
}
"
STREQUAL
""
OR
"
${
NETTLE_VERSION_MINOR
}
"
STREQUAL
""
)
message
(
FATAL_ERROR
"The nettle version not detected properly. Try to run build_oai -I again"
)
endif
()
add_definitions
(
"-DNETTLE_VERSION_MAJOR=
${
NETTLE_VERSION_MAJOR
}
"
)
add_definitions
(
"-DNETTLE_VERSION_MINOR=
${
NETTLE_VERSION_MINOR
}
"
)
pkg_search_module
(
XPM xpm
)
if
(
NOT
${
XPM_FOUND
}
)
message
(
"PACKAGE xpm not found: some targets will fail"
)
...
...
@@ -1619,13 +1630,23 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
# lte-softmodem is both eNB and UE implementation
###################################################
add_executable
(
lte-softmodem
###################################################
# For CUDA library
###################################################
CUDA_ADD_LIBRARY
(
PUSCH_CU
${
OPENAIR1_DIR
}
/PHY/CUDA/LTE_TRANSPORT/turbo_rx_gpu.cu
#${OPENAIR1_DIR}/PHY/CUDA/INIT/init_cuda.cu
#${OPENAIR1_DIR}/PHY/CUDA/LTE_TRANSPORT/rx_pusch.cu
)
cuda_add_executable
(
lte-softmodem
${
rrc_h
}
${
s1ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/sched_dlsch.c
${
OPENAIR_TARGETS
}
/RT/USER/sched_rx_pdsch.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-enb.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
${
OPENAIR1_DIR
}
/SIMULATION/TOOLS/taus.c
${
OPENAIR_TARGETS
}
/SIMU/USER/init_lte.c
...
...
@@ -1642,11 +1663,28 @@ add_executable(lte-softmodem
${
T_SOURCE
}
)
###################################################
# For link cufft
###################################################
CUDA_ADD_CUFFT_TO_TARGET
(
lte-softmodem
)
CUDA_ADD_CUFFT_TO_TARGET
(
PUSCH_CU
)
target_link_libraries
(
lte-softmodem
#cudadevrt cudart
cuda boost_system
)
target_link_libraries
(
lte-softmodem -ldl
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2
${
MSC_LIB
}
${
RAL_LIB
}
${
NAS_UE_LIB
}
${
ITTI_LIB
}
${
MIH_LIB
}
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY
PUSCH_CU
LFDS L2
${
MSC_LIB
}
${
RAL_LIB
}
${
NAS_UE_LIB
}
${
ITTI_LIB
}
${
MIH_LIB
}
-Wl,--end-group
)
target_link_libraries
(
lte-softmodem
${
LIBXML2_LIBRARIES
}
cudart -L/usr/local/cuda/lib64
)
target_link_libraries
(
lte-softmodem
${
LIBXML2_LIBRARIES
}
cudadevrt -L/usr/local/cuda/lib64
)
target_link_libraries
(
lte-softmodem
${
LIBXML2_LIBRARIES
}
)
target_link_libraries
(
lte-softmodem pthread m
${
CONFIG_LIBRARIES
}
rt crypt
${
CRYPTO_LIBRARIES
}
${
OPENSSL_LIBRARIES
}
${
NETTLE_LIBRARIES
}
sctp
${
option_HW_lib
}
${
option_TP_lib
}
${
XFORMS_LIBRARIES
}
)
target_link_libraries
(
lte-softmodem
${
LIB_LMS_LIBRARIES
}
)
...
...
@@ -1658,9 +1696,10 @@ add_executable(lte-softmodem-nos1
${
rrc_h
}
${
s1ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/sched_dlsch.c
${
OPENAIR_TARGETS
}
/RT/USER/sched_rx_pdsch.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-enb.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-softmodem.c
${
OPENAIR1_DIR
}
/SIMULATION/TOOLS/taus.c
${
OPENAIR_TARGETS
}
/SIMU/USER/init_lte.c
...
...
@@ -1756,9 +1795,6 @@ add_executable(oaisim
${
s1ap_h
}
${
x2ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-enb.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/SIMU/USER/channel_sim.c
${
OPENAIR_TARGETS
}
/SIMU/USER/init_lte.c
${
OPENAIR_TARGETS
}
/SIMU/USER/oaisim_config.c
...
...
@@ -1769,6 +1805,7 @@ add_executable(oaisim
${
OPENAIR_TARGETS
}
/SIMU/USER/oaisim.c
${
OPENAIR2_DIR
}
/RRC/NAS/nas_config.c
${
OPENAIR2_DIR
}
/RRC/NAS/rb_config.c
${
OPENAIR2_DIR
}
/UTIL/OMG/sumo.c
${
OPENAIR3_DIR
}
/NAS/UE/nas_ue_task.c
${
GTPU_need_ITTI
}
${
OPENAIR_TARGETS
}
/COMMON/create_tasks.c
...
...
@@ -1801,9 +1838,6 @@ add_executable(oaisim_nos1
${
s1ap_h
}
${
x2ap_h
}
${
OPENAIR_BIN_DIR
}
/messages_xml.h
${
OPENAIR_TARGETS
}
/RT/USER/lte-ue.c
${
OPENAIR_TARGETS
}
/RT/USER/lte-enb.c
${
OPENAIR_TARGETS
}
/RT/USER/rt_wrapper.c
${
OPENAIR_TARGETS
}
/SIMU/USER/channel_sim.c
${
OPENAIR_TARGETS
}
/SIMU/USER/init_lte.c
${
OPENAIR_TARGETS
}
/SIMU/USER/oaisim_config.c
...
...
@@ -1814,6 +1848,7 @@ add_executable(oaisim_nos1
${
OPENAIR_TARGETS
}
/SIMU/USER/oaisim.c
${
OPENAIR2_DIR
}
/RRC/NAS/nas_config.c
${
OPENAIR2_DIR
}
/RRC/NAS/rb_config.c
${
OPENAIR2_DIR
}
/UTIL/OMG/sumo.c
${
OPENAIR_TARGETS
}
/COMMON/create_tasks.c
${
HW_SOURCE
}
${
TRANSPORT_SOURCE
}
...
...
@@ -1898,6 +1933,7 @@ foreach(myExe s1ap
aes128_cmac_encrypt
secu_knas_encrypt_eia2
)
add_executable
(
test_
${
myExe
}
${
OPENAIR3_DIR
}
/TEST/test_util.c
${
OPENAIR3_DIR
}
/TEST/test_
${
myExe
}
.c
)
target_link_libraries
(
test_
${
myExe
}
...
...
openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
View file @
e2d82cd2
/*
* 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.0 (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
*/
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/ulsch_decoding.c
* \brief Top-level routines for decoding the ULSCH transport channel from 36.212 V8.6 2009-03
...
...
@@ -31,7 +39,7 @@
*/
//#include "defs.h"
#include "PHY/CUDA/LTE_TRANSPORT/turbo_rx_gpu.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/extern.h"
...
...
@@ -119,7 +127,7 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin
ulsch
->
Mlimit
=
4
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
//
printf
("new_ue_ulsch: Harq process %d\n",i);
//
msg
("new_ue_ulsch: Harq process %d\n",i);
ulsch
->
harq_processes
[
i
]
=
(
LTE_UL_eNB_HARQ_t
*
)
malloc16
(
sizeof
(
LTE_UL_eNB_HARQ_t
));
if
(
ulsch
->
harq_processes
[
i
])
{
...
...
@@ -180,687 +188,60 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
ulsch
->
harq_processes
[
i
]
->
subframe_scheduling_flag
=
0
;
//ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
ulsch
->
harq_processes
[
i
]
->
phich_ACK
=
0
;
ulsch
->
harq_processes
[
i
]
->
round
=
0
;
}
}
}
}
uint8_t
extract_cqi_crc
(
uint8_t
*
cqi
,
uint8_t
CQI_LENGTH
)
{
uint8_t
crc
;
crc
=
cqi
[
CQI_LENGTH
>>
3
];
// printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7);
crc
=
(
crc
<<
(
CQI_LENGTH
&
0x7
));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7));
// printf("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]);
crc
|=
(
cqi
[
1
+
(
CQI_LENGTH
>>
3
)])
>>
(
8
-
(
CQI_LENGTH
&
0x7
));
// clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
// printf("crc : %x\n",crc);
return
(
crc
);
}
int
ulsch_decoding_data_2thread0
(
td_params
*
tdp
)
{
PHY_VARS_eNB
*
eNB
=
tdp
->
eNB
;
int
UE_id
=
tdp
->
UE_id
;
int
harq_pid
=
tdp
->
harq_pid
;
int
llr8_flag
=
tdp
->
llr8_flag
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
Q_m
=
get_Qm_ul
(
ulsch_harq
->
mcs
);
int
G
=
ulsch_harq
->
nb_rb
*
(
12
*
Q_m
)
*
ulsch_harq
->
Nsymb_pusch
;
uint32_t
E
;
uint32_t
Gp
,
GpmodC
,
Nl
=
1
;
uint32_t
C
=
ulsch_harq
->
C
;
uint8_t
(
*
tc
)(
int16_t
*
y
,
uint8_t
*
,
uint16_t
,
uint16_t
,
uint16_t
,
uint8_t
,
uint8_t
,
uint8_t
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
);
if
(
llr8_flag
==
0
)
tc
=
phy_threegpplte_turbo_decoder16
;
else
tc
=
phy_threegpplte_turbo_decoder8
;
// go through first half of segments to get r_offset
for
(
r
=
0
;
r
<
(
ulsch_harq
->
C
/
2
);
r
++
)
{
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
// This is stolen from rate-matching algorithm to get the value of E
Gp
=
G
/
Nl
/
Q_m
;
GpmodC
=
Gp
%
C
;
if
(
r
<
(
C
-
(
GpmodC
)))
E
=
Nl
*
Q_m
*
(
Gp
/
C
);
else
E
=
Nl
*
Q_m
*
((
GpmodC
==
0
?
0
:
1
)
+
(
Gp
/
C
));
r_offset
+=
E
;
if
(
r
==
0
)
{
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
// go through second half of segments
for
(;
r
<
(
ulsch_harq
->
C
);
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
get_Qm_ul
(
ulsch_harq
->
mcs
),
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
r_offset
+=
E
;
sub_block_deinterleaving_turbo
(
4
+
Kr
,
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
w
[
r
]);
if
(
ulsch_harq
->
C
==
1
)
crc_type
=
CRC24_A
;
else
crc_type
=
CRC24_B
;
ret
=
tc
(
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
c
[
r
],
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
ulsch
->
max_turbo_iterations
,
//MAX_TURBO_ITERATIONS,
crc_type
,
(
r
==
0
)
?
ulsch_harq
->
F
:
0
,
&
eNB
->
ulsch_tc_init_stats
,
&
eNB
->
ulsch_tc_alpha_stats
,
&
eNB
->
ulsch_tc_beta_stats
,
&
eNB
->
ulsch_tc_gamma_stats
,
&
eNB
->
ulsch_tc_ext_stats
,
&
eNB
->
ulsch_tc_intl1_stats
,
&
eNB
->
ulsch_tc_intl2_stats
);
// Reassembly of Transport block here
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
memcpy
(
ulsch_harq
->
b
+
offset
,
ulsch_harq
->
c
[
r
],
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
else
{
break
;
}
}
return
(
ret
);
}
extern
int
oai_exit
;
void
*
td_thread
(
void
*
param
)
{
PHY_VARS_eNB
*
eNB
=
((
td_params
*
)
param
)
->
eNB
;
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
while
(
!
oai_exit
)
{
if
(
wait_on_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
((
td_params
*
)
param
)
->
ret
=
ulsch_decoding_data_2thread0
((
td_params
*
)
param
);
if
(
release_thread
(
&
proc
->
mutex_td
,
&
proc
->
instance_cnt_td
,
"td thread"
)
<
0
)
break
;
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
NULL
);
}
}
return
(
NULL
);
}
int
ulsch_decoding_data_2thread
(
PHY_VARS_eNB
*
eNB
,
int
UE_id
,
int
harq_pid
,
int
llr8_flag
)
{
eNB_proc_t
*
proc
=
&
eNB
->
proc
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
Q_m
=
get_Qm_ul
(
ulsch_harq
->
mcs
);
int
G
=
ulsch_harq
->
nb_rb
*
(
12
*
Q_m
)
*
ulsch_harq
->
Nsymb_pusch
;
unsigned
int
E
;
int
Cby2
;
uint8_t
(
*
tc
)(
int16_t
*
y
,
uint8_t
*
,
uint16_t
,
uint16_t
,
uint16_t
,
uint8_t
,
uint8_t
,
uint8_t
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
);
struct
timespec
wait
;
wait
.
tv_sec
=
0
;
wait
.
tv_nsec
=
5000000L
;
if
(
llr8_flag
==
0
)
tc
=
phy_threegpplte_turbo_decoder16
;
else
tc
=
phy_threegpplte_turbo_decoder8
;
if
(
ulsch_harq
->
C
>
1
)
{
// wakeup worker if more than 1 segment
if
(
pthread_mutex_timedlock
(
&
proc
->
mutex_td
,
&
wait
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)
\n
"
,
proc
->
instance_cnt_td
);
exit_fun
(
"error locking mutex_fep"
);
return
-
1
;
}
if
(
proc
->
instance_cnt_td
==
0
)
{
printf
(
"[eNB] TD thread busy
\n
"
);
exit_fun
(
"TD thread busy"
);
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
return
-
1
;
}
++
proc
->
instance_cnt_td
;
proc
->
tdp
.
eNB
=
eNB
;
proc
->
tdp
.
UE_id
=
UE_id
;
proc
->
tdp
.
harq_pid
=
harq_pid
;
proc
->
tdp
.
llr8_flag
=
llr8_flag
;
// wakeup worker to do second half segments
if
(
pthread_cond_signal
(
&
proc
->
cond_td
)
!=
0
)
{
printf
(
"[eNB] ERROR pthread_cond_signal for td thread exit
\n
"
);
exit_fun
(
"ERROR pthread_cond_signal"
);
return
(
1
+
ulsch
->
max_turbo_iterations
);
}
pthread_mutex_unlock
(
&
proc
->
mutex_td
);
Cby2
=
ulsch_harq
->
C
/
2
;
}
else
{
Cby2
=
1
;
}
// go through first half of segments in main thread
for
(
r
=
0
;
r
<
Cby2
;
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
start_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
get_Qm_ul
(
ulsch_harq
->
mcs
),
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
stop_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
r_offset
+=
E
;
start_meas
(
&
eNB
->
ulsch_deinterleaving_stats
);
sub_block_deinterleaving_turbo
(
4
+
Kr
,
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
w
[
r
]);
stop_meas
(
&
eNB
->
ulsch_deinterleaving_stats
);
if
(
ulsch_harq
->
C
==
1
)
crc_type
=
CRC24_A
;
else
crc_type
=
CRC24_B
;
start_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
ret
=
tc
(
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
c
[
r
],
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
ulsch
->
max_turbo_iterations
,
//MAX_TURBO_ITERATIONS,
crc_type
,
(
r
==
0
)
?
ulsch_harq
->
F
:
0
,
&
eNB
->
ulsch_tc_init_stats
,
&
eNB
->
ulsch_tc_alpha_stats
,
&
eNB
->
ulsch_tc_beta_stats
,
&
eNB
->
ulsch_tc_gamma_stats
,
&
eNB
->
ulsch_tc_ext_stats
,
&
eNB
->
ulsch_tc_intl1_stats
,
&
eNB
->
ulsch_tc_intl2_stats
);
// Reassembly of Transport block here
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
r
==
0
)
{
memcpy
(
ulsch_harq
->
b
,
&
ulsch_harq
->
c
[
0
][(
ulsch_harq
->
F
>>
3
)],
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
memcpy
(
ulsch_harq
->
b
+
offset
,
ulsch_harq
->
c
[
r
],
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
else
{
break
;
}
stop_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
}
// wait for worker to finish
wait_on_busy_condition
(
&
proc
->
mutex_td
,
&
proc
->
cond_td
,
&
proc
->
instance_cnt_td
,
"td thread"
);
return
(
(
ret
>
proc
->
tdp
.
ret
)
?
ret
:
proc
->
tdp
.
ret
);
}
int
ulsch_decoding_data
(
PHY_VARS_eNB
*
eNB
,
int
UE_id
,
int
harq_pid
,
int
llr8_flag
)
{
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
iind
;
uint8_t
crc_type
;
int
offset
=
0
;
int
ret
=
1
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
LTE_UL_eNB_HARQ_t
*
ulsch_harq
=
ulsch
->
harq_processes
[
harq_pid
];
int
Q_m
=
get_Qm_ul
(
ulsch_harq
->
mcs
);
int
G
=
ulsch_harq
->
nb_rb
*
(
12
*
Q_m
)
*
ulsch_harq
->
Nsymb_pusch
;
unsigned
int
E
;
uint8_t
(
*
tc
)(
int16_t
*
y
,
uint8_t
*
,
uint16_t
,
uint16_t
,
uint16_t
,
uint8_t
,
uint8_t
,
uint8_t
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
);
if
(
llr8_flag
==
0
)
tc
=
phy_threegpplte_turbo_decoder16
;
else
tc
=
phy_threegpplte_turbo_decoder8
;
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
printf
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
start_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
get_Qm_ul
(
ulsch_harq
->
mcs
),
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
stop_meas
(
&
eNB
->
ulsch_rate_unmatching_stats
);
r_offset
+=
E
;
start_meas
(
&
eNB
->
ulsch_deinterleaving_stats
);
sub_block_deinterleaving_turbo
(
4
+
Kr
,
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
w
[
r
]);
stop_meas
(
&
eNB
->
ulsch_deinterleaving_stats
);
if
(
ulsch_harq
->
C
==
1
)
crc_type
=
CRC24_A
;
else
crc_type
=
CRC24_B
;
start_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
ret
=
tc
(
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
c
[
r
],
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
ulsch
->
max_turbo_iterations
,
//MAX_TURBO_ITERATIONS,
crc_type
,
(
r
==
0
)
?
ulsch_harq
->
F
:
0
,
&
eNB
->
ulsch_tc_init_stats
,
&
eNB
->
ulsch_tc_alpha_stats
,
&
eNB
->
ulsch_tc_beta_stats
,
&
eNB
->
ulsch_tc_gamma_stats
,
&
eNB
->
ulsch_tc_ext_stats
,
&
eNB
->
ulsch_tc_intl1_stats
,
&
eNB
->
ulsch_tc_intl2_stats
);
stop_meas
(
&
eNB
->
ulsch_turbo_decoding_stats
);
// Reassembly of Transport block here
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
r
==
0
)
{
memcpy
(
ulsch_harq
->
b
,
&
ulsch_harq
->
c
[
0
][(
ulsch_harq
->
F
>>
3
)],
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
memcpy
(
ulsch_harq
->
b
+
offset
,
ulsch_harq
->
c
[
r
],
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
}
else
{
break
;
ulsch
->
harq_processes
[
i
]
->
round
=
0
;
}
}
return
(
ret
);
}
}
static
inline
unsigned
int
lte_gold_unscram
(
unsigned
int
*
x1
,
unsigned
int
*
x2
,
unsigned
char
reset
)
__attribute__
((
always_inline
));
static
inline
unsigned
int
lte_gold_unscram
(
unsigned
int
*
x1
,
unsigned
int
*
x2
,
unsigned
char
reset
)
uint8_t
extract_cqi_crc
(
uint8_t
*
cqi
,
uint8_t
CQI_LENGTH
)
{
int
n
;
if
(
reset
)
{
*
x1
=
1
+
(
1
<<
31
);
*
x2
=*
x2
^
((
*
x2
^
(
*
x2
>>
1
)
^
(
*
x2
>>
2
)
^
(
*
x2
>>
3
))
<<
31
);
uint8_t
crc
;
// skip first 50 double words (1600 bits)
// printf("n=0 : x1 %x, x2 %x\n",x1,x2
);
for
(
n
=
1
;
n
<
50
;
n
++
)
{
*
x1
=
(
*
x1
>>
1
)
^
(
*
x1
>>
4
);
*
x1
=
*
x1
^
(
*
x1
<<
31
)
^
(
*
x1
<<
28
);
*
x2
=
(
*
x2
>>
1
)
^
(
*
x2
>>
2
)
^
(
*
x2
>>
3
)
^
(
*
x2
>>
4
);
*
x2
=
*
x2
^
(
*
x2
<<
31
)
^
(
*
x2
<<
30
)
^
(
*
x2
<<
29
)
^
(
*
x2
<<
28
);
}
}
crc
=
cqi
[
CQI_LENGTH
>>
3
];
// msg("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7
);
crc
=
(
crc
<<
(
CQI_LENGTH
&
0x7
));
// clear crc bits
// ((char *)cqi)[CQI_LENGTH>>3] &= 0xff>>(8-(CQI_LENGTH&0x7)
);
// msg("crc2: %x, cqi0 %x\n",crc,cqi[1+(CQI_LENGTH>>3)]
);
crc
|=
(
cqi
[
1
+
(
CQI_LENGTH
>>
3
)])
>>
(
8
-
(
CQI_LENGTH
&
0x7
)
);
// clear crc bits
//(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0;
*
x1
=
(
*
x1
>>
1
)
^
(
*
x1
>>
4
);
*
x1
=
*
x1
^
(
*
x1
<<
31
)
^
(
*
x1
<<
28
);
*
x2
=
(
*
x2
>>
1
)
^
(
*
x2
>>
2
)
^
(
*
x2
>>
3
)
^
(
*
x2
>>
4
);
*
x2
=
*
x2
^
(
*
x2
<<
31
)
^
(
*
x2
<<
30
)
^
(
*
x2
<<
29
)
^
(
*
x2
<<
28
);
return
(
*
x1
^*
x2
);
// printf("n=%d : c %x\n",n,x1^x2);
// printf("crc : %x\n",crc);
return
(
crc
);
}
unsigned
int
ulsch_decoding
(
PHY_VARS_eNB
*
eNB
,
eNB_rxtx_proc_t
*
proc
,
unsigned
int
ulsch_decoding
(
PHY_VARS_eNB
*
phy_vars_eNB
,
uint8_t
UE_id
,
uint8_t
sched_subframe
,
uint8_t
control_only_flag
,
uint8_t
Nbundled
,
uint8_t
llr8_flag
)
{
int16_t
*
ulsch_llr
=
eNB
->
pusch_vars
[
UE_id
]
->
llr
;
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
eNB
->
frame_parms
;
LTE_eNB_ULSCH_t
*
ulsch
=
eNB
->
ulsch
[
UE_id
];
int16_t
*
ulsch_llr
=
phy_vars_eNB
->
lte_eNB_
pusch_vars
[
UE_id
]
->
llr
;
LTE_DL_FRAME_PARMS
*
frame_parms
=
&
phy_vars_eNB
->
lte_
frame_parms
;
LTE_eNB_ULSCH_t
*
ulsch
=
phy_vars_eNB
->
ulsch_eNB
[
UE_id
];
uint8_t
harq_pid
;
unsigned
short
nb_rb
;
unsigned
int
A
;
unsigned
int
A
,
E
;
uint8_t
Q_m
;
unsigned
int
i
,
i2
,
q
,
j
,
j2
;
int
iprime
;
unsigned
int
ret
=
0
;
unsigned
int
ret
=
0
,
offset
;
unsigned
short
iind
;
// uint8_t dummy_channel_output[(3*8*block_length)+12];
int
r
,
Kr
;
unsigned
int
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
;
uint8_t
crc_type
;
uint8_t
*
columnset
;
unsigned
int
sumKr
=
0
;
unsigned
int
Qprime
,
L
,
G
,
Q_CQI
,
Q_RI
,
H
,
Hprime
,
Hpp
,
Cmux
,
Rmux_prime
,
O_RCC
;
...
...
@@ -871,19 +252,34 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
uint32_t
x1
,
x2
,
s
=
0
;
int16_t
ys
,
c
;
uint32_t
wACK_idx
;
int16_t
dummy_w
[
MAX_NUM_ULSCH_SEGMENTS
][
3
*
(
6144
+
64
)];
uint8_t
dummy_w_cc
[
3
*
(
MAX_CQI_BITS
+
8
+
32
)];
int16_t
y
[
6
*
14
*
1200
];
uint8_t
ytag
[
14
*
1200
];
// uint8_t ytag2[6*14*1200],*ytag2_ptr;
int16_t
cseq
[
6
*
14
*
1200
];
int
off
;
int
subframe
=
p
roc
->
subframe_rx
;
int
status
[
20
];
int
subframe
=
p
hy_vars_eNB
->
proc
[
sched_subframe
].
subframe_rx
;
LTE_UL_eNB_HARQ_t
*
ulsch_harq
;
uint8_t
(
*
tc
)(
int16_t
*
y
,
uint8_t
*
,
uint16_t
,
uint16_t
,
uint16_t
,
uint8_t
,
uint8_t
,
uint8_t
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
,
time_stats_t
*
);
harq_pid
=
subframe2harq_pid
(
frame_parms
,
proc
->
frame_rx
,
subframe
);
harq_pid
=
subframe2harq_pid
(
frame_parms
,
phy_vars_eNB
->
proc
[
sched_subframe
].
frame_rx
,
subframe
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
1
);
...
...
@@ -893,16 +289,17 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
if
(
harq_pid
==
255
)
{
LOG_E
(
PHY
,
"FATAL ERROR: illegal harq_pid, returning
\n
"
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
0
);
return
-
1
;
}
if
(
ulsch_harq
->
Nsymb_pusch
==
0
)
{
LOG_E
(
PHY
,
"FATAL ERROR: harq_pid %d, Nsymb 0!
\n
"
,
harq_pid
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
0
);
return
1
+
ulsch
->
max_turbo_iterations
;
}
if
(
llr8_flag
==
0
)
tc
=
phy_threegpplte_turbo_decoder16
;
else
tc
=
phy_threegpplte_turbo_decoder8
;
nb_rb
=
ulsch_harq
->
nb_rb
;
...
...
@@ -914,7 +311,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d
\n
"
,
msg
(
"ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d
\n
"
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
ulsch_harq
->
round
,
ulsch_harq
->
rvidx
,
...
...
@@ -954,7 +351,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
if
(
sumKr
==
0
)
{
LOG_N
(
PHY
,
"[eNB %d] ulsch_decoding.c: FATAL sumKr is 0!
\n
"
,
eNB
->
Mod_id
);
LOG_N
(
PHY
,
"[eNB %d] ulsch_decoding.c: FATAL sumKr is 0!
\n
"
,
phy_vars_
eNB
->
Mod_id
);
LOG_D
(
PHY
,
"ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d, subframe %d
\n
"
,
frame_parms
->
Nid_cell
,
ulsch
->
rnti
,
x2
,
harq_pid
,
...
...
@@ -1003,7 +400,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
// Q_ACK = Qprime * Q_m;
Qprime_ACK
=
Qprime
;
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d
\n
"
,
msg
(
"ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d
\n
"
,
Qprime_ACK
,
ulsch_harq
->
Msc_initial
,
ulsch_harq
->
Nsymb_initial
,
sumKr
);
#endif
...
...
@@ -1032,7 +429,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
Q_CQI
=
Q_m
*
Qprime
;
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d
\n
"
,
G
,
Q_RI
,
Q_CQI
,
L
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_ACK
);
msg
(
"ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d
\n
"
,
G
,
Q_RI
,
Q_CQI
,
L
,
ulsch_harq
->
Or1
,
ulsch_harq
->
O_ACK
);
#endif
G
=
G
-
Q_RI
-
Q_CQI
;
...
...
@@ -1045,56 +442,37 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
H
=
G
+
Q_CQI
;
Hprime
=
H
/
Q_m
;
// Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI
start_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
Hpp
=
Hprime
+
Qprime_RI
;
Cmux
=
ulsch_harq
->
Nsymb_pusch
;
// Rmux = Hpp*Q_m/Cmux;
Rmux_prime
=
Hpp
/
Cmux
;
// Clear "tag" interleaving matrix to allow for CQI/DATA identification
memset
(
ytag
,
0
,
Cmux
*
Rmux_prime
);
start_meas
(
&
phy_vars_eNB
->
ulsch_demultiplexing_stats
);
i
=
0
;
memset
(
y
,
LTE_NULL
,
Q_m
*
Hpp
);
// printf("before unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
// read in buffer and unscramble llrs for everything but placeholder bits
// llrs stored per symbol correspond to columns of interleaving matrix
s
=
lte_gold_
unscram
(
&
x1
,
&
x2
,
1
);
s
=
lte_gold_
generic
(
&
x1
,
&
x2
,
1
);
i2
=
0
;
for
(
i
=
0
;
i
<
((
Hpp
*
Q_m
)
>>
5
);
i
++
)
{
/*
for
(
j
=
0
;
j
<
32
;
j
++
)
{
cseq
[
i2
++
]
=
(
int16_t
)((((
s
>>
j
)
&
1
)
<<
1
)
-
1
);
}
*/
#if defined(__x86_64__) || defined(__i386__)
#ifndef __AVX2__
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
__m128i
*
)
cseq
)[
i2
++
]
=
((
__m128i
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
#else
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[
s
&
65535
];
((
__m256i
*
)
cseq
)[
i2
++
]
=
((
__m256i
*
)
unscrambling_lut
)[(
s
>>
16
)
&
65535
];
#endif
#elif defined(__arm__)
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
s
>>=
16
;
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[(
s
&
65535
)
<<
1
];
((
int16x8_t
*
)
cseq
)[
i2
++
]
=
((
int16x8_t
*
)
unscrambling_lut
)[
1
+
((
s
&
65535
)
<<
1
)];
#endif
s
=
lte_gold_unscram
(
&
x1
,
&
x2
,
0
);
}
s
=
lte_gold_generic
(
&
x1
,
&
x2
,
0
);
}
// printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]);
...
...
@@ -1133,6 +511,11 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
for
(
i
=
0
;
i
<
Qprime_ACK
;
i
++
)
{
r
=
Rmux_prime
-
1
-
(
i
>>
2
);
/*
for (q=0;q<Q_m;q++) {
ytag2[q+(Q_m*((r*Cmux) + columnset[j]))] = q_ACK[(q+(Q_m*i))%len_ACK];
}
*/
off
=
((
Rmux_prime
*
Q_m
*
columnset
[
j
])
+
(
r
*
Q_m
));
if
(
ulsch_harq
->
O_ACK
==
1
)
{
...
...
@@ -1147,7 +530,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d
\n
"
,
i
,
r
,
j
,
columnset
[
j
]);
msg
(
"ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d
\n
"
,
i
,
r
,
j
,
columnset
[
j
]);
#endif
j
=
(
j
+
3
)
&
3
;
}
...
...
@@ -1181,7 +564,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
i2
=
j
<<
2
;
for
(
r
=
0
;
r
<
Rmux_prime
;
r
++
)
{
/*
c
=
cseq
[
i
];
y
[
i2
++
]
=
c
*
ulsch_llr
[
i
++
];
c
=
cseq
[
i
];
...
...
@@ -1191,11 +573,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
c
=
cseq
[
i
];
y
[
i2
]
=
c
*
ulsch_llr
[
i
++
];
i2
=
(
i2
+
(
Cmux
<<
2
)
-
3
);
*/
// slightly more optimized version (equivalent to above) for 16QAM to improve computational performance
*
(
__m64
*
)
&
y
[
i2
]
=
_mm_sign_pi16
(
*
(
__m64
*
)
&
ulsch_llr
[
i
],
*
(
__m64
*
)
&
cseq
[
i
]);
i
+=
4
;
i2
+=
(
Cmux
<<
2
);
}
}
...
...
@@ -1226,7 +603,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
stop_meas
(
&
phy_vars_eNB
->
ulsch_demultiplexing_stats
);
if
(
i
!=
(
H
+
Q_RI
))
LOG_D
(
PHY
,
"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)
\n
"
,
i
,
H
+
Q_RI
);
...
...
@@ -1439,23 +816,34 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
j2
+=
Q_m
;
}
#if defined(__x86_64__)||defined(__i386__)
#ifndef __AVX2
for
(
iprime
=
0
;
iprime
<
G
;
iprime
+=
8
,
j2
+=
8
)
*
((
__m128i
*
)
&
ulsch_harq
->
e
[
iprime
])
=
*
((
__m128i
*
)
&
y
[
j2
]);
#else
for
(
iprime
=
0
;
iprime
<
G
;
iprime
+=
16
,
j2
+=
16
)
*
((
__m256i
*
)
&
ulsch_harq
->
e
[
iprime
])
=
*
((
__m256i
*
)
&
y
[
j2
]);
#endif
#elif defined(__arm__)
for
(
iprime
=
0
;
iprime
<
G
;
iprime
+=
8
,
j2
+=
8
)
*
((
int16x8_t
*
)
&
ulsch_harq
->
e
[
iprime
])
=
*
((
int16x8_t
*
)
&
y
[
j2
]);
#endif
// printf("after CQI0 c[%d] = %p\n",0,ulsch_harq->c[0]);
switch
(
Q_m
)
{
case
2
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
4
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
case
6
:
for
(
iprime
=
0
;
iprime
<
G
;)
{
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
ulsch_harq
->
e
[
iprime
++
]
=
y
[
j2
++
];
}
break
;
}
}
stop_meas
(
&
eNB
->
ulsch_demultiplexing_stats
);
// printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G);
// Do CQI/RI/HARQ-ACK Decoding first and pass to MAC
...
...
@@ -1524,7 +912,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
// RI
// rank 1
if
((
ulsch_harq
->
O_RI
==
1
)
&&
(
Qprime_RI
>
0
))
{
ulsch_harq
->
o_RI
[
0
]
=
((
ulsch_harq
->
q_RI
[
0
]
+
ulsch_harq
->
q_RI
[
Q_m
/
2
])
>
0
)
?
0
:
1
;
}
...
...
@@ -1576,23 +963,251 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
}
#ifdef DEBUG_ULSCH_DECODING
printf
(
"ulsch_decoding: Or1=%d
\n
"
,
ulsch_harq
->
Or1
);
msg
(
"ulsch_decoding: Or1=%d
\n
"
,
ulsch_harq
->
Or1
);
for
(
i
=
0
;
i
<
1
+
((
8
+
ulsch_harq
->
Or1
)
/
8
);
i
++
)
printf
(
"ulsch_decoding: O[%d] %d
\n
"
,
i
,
ulsch_harq
->
o
[
i
]);
msg
(
"ulsch_decoding: O[%d] %d
\n
"
,
i
,
ulsch_harq
->
o
[
i
]);
if
(
ulsch_harq
->
cqi_crc_status
==
1
)
printf
(
"RX CQI CRC OK (%x)
\n
"
,
extract_cqi_crc
(
o_flip
,
ulsch_harq
->
Or1
));
msg
(
"RX CQI CRC OK (%x)
\n
"
,
extract_cqi_crc
(
o_flip
,
ulsch_harq
->
Or1
));
else
msg
(
"RX CQI CRC NOT OK (%x)
\n
"
,
extract_cqi_crc
(
o_flip
,
ulsch_harq
->
Or1
));
#endif
}
// return(0);
// Do PUSCH Decoding
// stop_meas(&phy_vars_eNB->ulsch_demultiplexing_stats);
r_offset
=
0
;
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
// Get Turbo interleaver parameters
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
printf
(
"RX CQI CRC NOT OK (%x)
\n
"
,
extract_cqi_crc
(
o_flip
,
ulsch_harq
->
Or1
));
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
Kr_bytes
<=
64
)
iind
=
(
Kr_bytes
-
5
);
else
if
(
Kr_bytes
<=
128
)
iind
=
59
+
((
Kr_bytes
-
64
)
>>
1
);
else
if
(
Kr_bytes
<=
256
)
iind
=
91
+
((
Kr_bytes
-
128
)
>>
2
);
else
if
(
Kr_bytes
<=
768
)
iind
=
123
+
((
Kr_bytes
-
256
)
>>
3
);
else
{
LOG_E
(
PHY
,
"ulsch_decoding: Illegal codeword size %d!!!
\n
"
,
Kr_bytes
);
return
(
-
1
);
}
#ifdef DEBUG_ULSCH_DECODING
msg
(
"f1 %d, f2 %d, F %d
\n
"
,
f1f2mat_old
[
2
*
iind
],
f1f2mat_old
[
1
+
(
2
*
iind
)],(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#endif
memset
(
&
dummy_w
[
r
][
0
],
0
,
3
*
(
6144
+
64
)
*
sizeof
(
short
));
ulsch_harq
->
RTC
[
r
]
=
generate_dummy_w
(
4
+
(
Kr_bytes
*
8
),
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
(
r
==
0
)
?
ulsch_harq
->
F
:
0
);
#ifdef DEBUG_ULSCH_DECODING
msg
(
"Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...
\n
"
,
r
,
G
,
Kr
*
3
,
Q_m
,
nb_rb
,
ulsch_harq
->
Nl
);
#endif
start_meas
(
&
phy_vars_eNB
->
ulsch_rate_unmatching_stats
);
if
(
lte_rate_matching_turbo_rx
(
ulsch_harq
->
RTC
[
r
],
G
,
ulsch_harq
->
w
[
r
],
(
uint8_t
*
)
&
dummy_w
[
r
][
0
],
ulsch_harq
->
e
+
r_offset
,
ulsch_harq
->
C
,
NSOFT
,
0
,
//Uplink
1
,
ulsch_harq
->
rvidx
,
(
ulsch_harq
->
round
==
0
)
?
1
:
0
,
// clear
get_Qm_ul
(
ulsch_harq
->
mcs
),
1
,
r
,
&
E
)
==-
1
)
{
LOG_E
(
PHY
,
"ulsch_decoding.c: Problem in rate matching
\n
"
);
return
(
-
1
);
}
stop_meas
(
&
phy_vars_eNB
->
ulsch_rate_unmatching_stats
);
r_offset
+=
E
;
start_meas
(
&
phy_vars_eNB
->
ulsch_deinterleaving_stats
);
sub_block_deinterleaving_turbo
(
4
+
Kr
,
&
ulsch_harq
->
d
[
r
][
96
],
ulsch_harq
->
w
[
r
]);
stop_meas
(
&
phy_vars_eNB
->
ulsch_deinterleaving_stats
);
}
// turbo decoder gpu
if
(
ulsch_harq
->
C
==
1
)
crc_type
=
CRC24_A
;
else
crc_type
=
CRC24_B
;
short
*
d
[
16
];
unsigned
char
*
output_c
[
16
];
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
d
[
r
]
=
&
ulsch_harq
->
d
[
r
][
96
];
output_c
[
r
]
=
ulsch_harq
->
c
[
r
];
}
/*
static int write_cnt=0;
FILE* fp = fopen("/home/isip/Desktop/jmhu/oai_input","w+");
int kkk;
if(write_cnt==0)
{
for(r=0;r<ulsch_harq->C;r++)
{
fprintf(fp,"%d\n",Kr);
for(kkk=0;kkk<3*Kr+12;kkk++)
{
fprintf(fp,"%d",ulsch_harq->d[r][96+kkk]);
}
fprintf(fp,"\n");
}
}
fclose(fp);
*/
unsigned
char
ret_tmp
[
16
]
=
{
0
};
unsigned
char
f_tmp
[
2
];
f_tmp
[
0
]
=
ulsch_harq
->
F
;
f_tmp
[
1
]
=
0
;
ret
=
phy_threegpplte_turbo_decoder_gpu
(
d
,
output_c
,
ulsch_harq
->
C
,
Kr
,
f1f2mat_old
[
iind
*
2
],
f1f2mat_old
[(
iind
*
2
)
+
1
],
5
,
crc_type
,
f_tmp
,
ret_tmp
);
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
status
[
r
]
=
ret_tmp
[
r
];
}
/*
fp = fopen("/home/isip/Desktop/jmhu/oai_gpu_output","w+");
if(write_cnt==0)
{
for(r=0;r<ulsch_harq->C;r++)
{
fprintf(fp,"\n");
for(kkk=0;kkk<Kr/8;kkk++)
fprintf(fp,"%d",ulsch_harq->c[r][kkk]);
}
}
fclose(fp);
*/
/*
for (r=0; r<ulsch_harq->C; r++) {
// printf("c[%d] : %p\n",r,
// ulsch_harq->c[r]);
if (ulsch_harq->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
start_meas(&phy_vars_eNB->ulsch_turbo_decoding_stats);
ret = tc(&ulsch_harq->d[r][96],
ulsch_harq->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS,
crc_type,
(r==0) ? ulsch_harq->F : 0,
&phy_vars_eNB->ulsch_tc_init_stats,
&phy_vars_eNB->ulsch_tc_alpha_stats,
&phy_vars_eNB->ulsch_tc_beta_stats,
&phy_vars_eNB->ulsch_tc_gamma_stats,
&phy_vars_eNB->ulsch_tc_ext_stats,
&phy_vars_eNB->ulsch_tc_intl1_stats,
&phy_vars_eNB->ulsch_tc_intl2_stats);
stop_meas(&phy_vars_eNB->ulsch_turbo_decoding_stats);
status[r] = ret;
}
*/
/*
fp = fopen("/home/isip/Desktop/jmhu/oai_output","w+");
if(write_cnt==0)
{
for(r=0;r<ulsch_harq->C;r++)
{
fprintf(fp,"\n");
for(kkk=0;kkk<Kr/8;kkk++)
fprintf(fp,"%d",ulsch_harq->c[r][kkk]);
}
write_cnt++;
}
fclose(fp);
*/
// Reassembly of Transport block here
offset
=
0
;
ret
=
1
;
for
(
r
=
0
;
r
<
ulsch_harq
->
C
;
r
++
)
{
if
(
status
[
r
]
!=
(
1
+
ulsch
->
max_turbo_iterations
))
{
if
(
r
<
ulsch_harq
->
Cminus
)
Kr
=
ulsch_harq
->
Kminus
;
else
Kr
=
ulsch_harq
->
Kplus
;
Kr_bytes
=
Kr
>>
3
;
if
(
r
==
0
)
{
memcpy
(
ulsch_harq
->
b
,
&
ulsch_harq
->
c
[
0
][(
ulsch_harq
->
F
>>
3
)],
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
=
Kr_bytes
-
(
ulsch_harq
->
F
>>
3
)
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
);
}
else
{
memcpy
(
ulsch_harq
->
b
+
offset
,
ulsch_harq
->
c
[
r
],
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
offset
+=
(
Kr_bytes
-
((
ulsch_harq
->
C
>
1
)
?
3
:
0
));
}
// Do ULSCH Decoding for data portion
if
(
ret
!=
(
1
+
ulsch
->
max_turbo_iterations
))
ret
=
status
[
r
];
}
else
{
ret
=
1
+
ulsch
->
max_turbo_iterations
;
}
ret
=
eNB
->
td
(
eNB
,
UE_id
,
harq_pid
,
llr8_flag
);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0
+
harq_pid
,
0
);
...
...
@@ -1675,7 +1290,7 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
sinr_db1
=
sinr_dB
[
offset
*
2
];
sinr_db2
=
sinr_dB
[
offset
*
2
+
1
];
printf
(
"sinr_db1=%f
\n
,sinr_db2=%f
\n
"
,
sinr_db1
,
sinr_db2
);
msg
(
"sinr_db1=%f
\n
,sinr_db2=%f
\n
"
,
sinr_db1
,
sinr_db2
);
//rounding up for the table lookup
sinr_db1
*=
10
;
...
...
@@ -1929,7 +1544,7 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
sinr_eff
=
sinr_eff
*
beta2_dlsch_MI
[
TM
][
mcs
];
}
printf
(
"SINR_Eff = %e
\n
"
,
sinr_eff
);
msg
(
"SINR_Eff = %e
\n
"
,
sinr_eff
);
sinr_eff
*=
10
;
sinr_eff
=
floor
(
sinr_eff
);
...
...
@@ -1937,7 +1552,7 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
// sinr_eff += 1;
// }
sinr_eff
/=
10
;
printf
(
"sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
msg
(
"sinr_eff after rounding = %f
\n
"
,
sinr_eff
);
for
(
index
=
0
;
index
<
16
;
index
++
)
{
if
(
index
==
0
)
{
...
...
@@ -1955,10 +1570,10 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
#ifdef USER_MODE // need to be adapted for the emulation in the kernel space
if
(
uniformrandom
()
<
bler
)
{
printf
(
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
msg
(
"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
0
);
}
else
{
printf
(
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
msg
(
"abstraction_decoding successful (mcs=%d, sinr_eff=%f, bler=%f)
\n
"
,
mcs
,
sinr_eff
,
bler
);
return
(
1
);
}
...
...
@@ -1968,60 +1583,68 @@ int ulsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint8_t mcs,uint16_t nrb
#endif
uint32_t
ulsch_decoding_emul
(
PHY_VARS_eNB
*
eNB
,
eNB_rxtx_proc_t
*
proc
,
uint32_t
ulsch_decoding_emul
(
PHY_VARS_eNB
*
phy_vars_eNB
,
uint8_t
sched_subframe
,
uint8_t
UE_index
,
uint16_t
*
crnti
)
{
uint8_t
UE_id
;
uint16_t
rnti
;
int
subframe
=
p
roc
->
subframe_rx
;
int
subframe
=
p
hy_vars_eNB
->
proc
[
sched_subframe
].
subframe_rx
;
uint8_t
harq_pid
;
uint8_t
CC_id
=
eNB
->
CC_id
;
uint8_t
CC_id
=
phy_vars_
eNB
->
CC_id
;
harq_pid
=
subframe2harq_pid
(
&
eNB
->
frame_parms
,
proc
->
frame_rx
,
subframe
);
harq_pid
=
subframe2harq_pid
(
&
phy_vars_eNB
->
lte_frame_parms
,
phy_vars_eNB
->
proc
[
sched_subframe
].
frame_rx
,
subframe
);
rnti
=
eNB
->
ulsch
[
UE_index
]
->
rnti
;
rnti
=
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
rnti
;
#ifdef DEBUG_PHY
LOG_D
(
PHY
,
"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x
\n
"
,
eNB
->
Mod_id
,
subframe
,
UE_index
,
harq_pid
,
rnti
);
LOG_D
(
PHY
,
"[eNB %d] ulsch_decoding_emul : subframe %d UE_index %d harq_pid %d rnti %x
\n
"
,
phy_vars_
eNB
->
Mod_id
,
subframe
,
UE_index
,
harq_pid
,
rnti
);
#endif
for
(
UE_id
=
0
;
UE_id
<
NB_UE_INST
;
UE_id
++
)
{
if
(
rnti
==
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
pdcch_vars
[
0
]
->
crnti
)
if
(
rnti
==
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
lte_ue_
pdcch_vars
[
0
]
->
crnti
)
break
;
/*
msg("[PHY] EMUL eNB %d ulsch_decoding_emul : subframe ue id %d crnti %x nb ue %d\n",
phy_vars_eNB->Mod_id,
UE_id,
PHY_vars_UE_g[UE_id]->lte_ue_pdcch_vars[0]->crnti,
NB_UE_INST);
*/
}
if
(
UE_id
==
NB_UE_INST
)
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul: FATAL, didn't find UE with rnti %x (UE index %d)
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_index
);
return
(
1
+
eNB
->
ulsch
[
UE_id
]
->
max_turbo_iterations
);
phy_vars_
eNB
->
Mod_id
,
rnti
,
UE_index
);
return
(
1
+
phy_vars_eNB
->
ulsch_eNB
[
UE_id
]
->
max_turbo_iterations
);
}
else
{
LOG_D
(
PHY
,
"[eNB %d] Found UE with rnti %x => UE_id %d
\n
"
,
eNB
->
Mod_id
,
rnti
,
UE_id
);
LOG_D
(
PHY
,
"[eNB %d] Found UE with rnti %x => UE_id %d
\n
"
,
phy_vars_
eNB
->
Mod_id
,
rnti
,
UE_id
);
}
if
(
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
==
CBA_ACTIVE
)
{
if
(
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
_ue
[
0
]
->
harq_processes
[
harq_pid
]
->
status
==
CBA_ACTIVE
)
{
*
crnti
=
rnti
;
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
status
=
IDLE
;
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
_ue
[
0
]
->
harq_processes
[
harq_pid
]
->
status
=
IDLE
;
}
else
*
crnti
=
0x0
;
// Do abstraction here to determine if packet it in error
/* if (ulsch_abstraction_MIESM(
eNB->sinr_dB_eNB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch
[UE_id]->harq_processes[harq_pid]->first_rb) == 1)
/* if (ulsch_abstraction_MIESM(
phy_vars_eNB->sinr_dB_eNB,1, phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->mcs,phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->ulsch_eNB
[UE_id]->harq_processes[harq_pid]->first_rb) == 1)
flag = 1;
else flag = 0;*/
/*
//SINRdbPost = eNB->sinr_dB_eNB;
mcsPost =
eNB->ulsch
[UE_id]->harq_processes[harq_pid]->mcs,
nrbPost =
eNB->ulsch
[UE_id]->harq_processes[harq_pid]->nb_rb;
frbPost =
eNB->ulsch
[UE_id]->harq_processes[harq_pid]->first_rb;
//SINRdbPost =
phy_vars_
eNB->sinr_dB_eNB;
mcsPost =
phy_vars_eNB->ulsch_eNB
[UE_id]->harq_processes[harq_pid]->mcs,
nrbPost =
phy_vars_eNB->ulsch_eNB
[UE_id]->harq_processes[harq_pid]->nb_rb;
frbPost =
phy_vars_eNB->ulsch_eNB
[UE_id]->harq_processes[harq_pid]->first_rb;
if(nrbPost > 0)
{
SINRdbPost = eNB->sinr_dB_eNB;
SINRdbPost =
phy_vars_
eNB->sinr_dB_eNB;
ULflag1 = 1;
}
else
...
...
@@ -2031,7 +1654,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
}*/
//
// write_output("postprocSINR.m","SINReNB",eNB->sinr_dB,301,1,7);
// write_output("postprocSINR.m","SINReNB",
phy_vars_
eNB->sinr_dB,301,1,7);
//Yazdir buraya her frame icin 300 eNb
...
...
@@ -2040,51 +1663,51 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
// fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
// if (ulsch_abstraction(
eNB->sinr_dB,1, eNB->ulsch[UE_id]->harq_processes[harq_pid]->mcs,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch
[UE_id]->harq_processes[harq_pid]->first_rb) == 1) {
// if (ulsch_abstraction(
phy_vars_eNB->sinr_dB,1, phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->mcs,phy_vars_eNB->ulsch_eNB[UE_id]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->ulsch_eNB
[UE_id]->harq_processes[harq_pid]->first_rb) == 1) {
if
(
1
)
{
LOG_D
(
PHY
,
"ulsch_decoding_emul abstraction successful
\n
"
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
b
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
harq_processes
[
harq_pid
]
->
b
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
);
memcpy
(
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
b
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
_ue
[
0
]
->
harq_processes
[
harq_pid
]
->
b
,
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
TBS
>>
3
);
// get local ue's ack
if
((
UE_index
>=
oai_emulation
.
info
.
first_ue_local
)
||
(
UE_index
<
(
oai_emulation
.
info
.
first_ue_local
+
oai_emulation
.
info
.
nb_ue_local
)))
{
get_ack
(
&
eNB
->
frame_parms
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
dlsch
[
0
][
0
]
->
harq_ack
,
get_ack
(
&
phy_vars_eNB
->
lte_
frame_parms
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
dlsch
_ue
[
0
][
0
]
->
harq_ack
,
subframe
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
);
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
);
}
else
{
// get remote UEs' ack
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
0
];
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_ACK
[
1
];
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
o_ACK
[
0
];
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
]
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
o_ACK
[
1
];
}
// Do abstraction of PUSCH feedback
#ifdef DEBUG_PHY
LOG_D
(
PHY
,
"[eNB %d][EMUL] ue index %d UE_id %d: subframe %d : o_ACK (%d %d), cqi (val %d, len %d)
\n
"
,
eNB
->
Mod_id
,
UE_index
,
UE_id
,
subframe
,
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
],
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
],
((
HLC_subband_cqi_rank1_2A_5MHz
*
)
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
)
->
cqi1
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
);
phy_vars_eNB
->
Mod_id
,
UE_index
,
UE_id
,
subframe
,
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
0
],
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_ACK
[
1
],
((
HLC_subband_cqi_rank1_2A_5MHz
*
)
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
_ue
[
0
]
->
o
)
->
cqi1
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
_ue
[
0
]
->
O
);
#endif
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or1
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or2
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
O
;
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or1
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
O
;
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
Or2
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
O
;
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
uci_format
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
uci_format
;
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o
,
MAX_CQI_BYTES
);
memcpy
(
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_RI
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch
[
0
]
->
o_RI
,
2
);
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
uci_format
=
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
uci_format
;
memcpy
(
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
o
,
MAX_CQI_BYTES
);
memcpy
(
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
o_RI
,
PHY_vars_UE_g
[
UE_id
][
CC_id
]
->
ulsch_ue
[
0
]
->
o_RI
,
2
);
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
1
;
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
1
;
return
(
1
);
}
else
{
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d
\n
"
,
eNB
->
Mod_id
,
UE_index
);
LOG_W
(
PHY
,
"[eNB %d] ulsch_decoding_emul abstraction failed for UE %d
\n
"
,
phy_vars_
eNB
->
Mod_id
,
UE_index
);
eNB
->
ulsch
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
0
;
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
harq_processes
[
harq_pid
]
->
cqi_crc_status
=
0
;
// retransmission
return
(
1
+
eNB
->
ulsch
[
UE_index
]
->
max_turbo_iterations
);
return
(
1
+
phy_vars_eNB
->
ulsch_eNB
[
UE_index
]
->
max_turbo_iterations
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment