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
canghaiwuhen
OpenXG-RAN
Commits
1036f0ed
Commit
1036f0ed
authored
Sep 05, 2019
by
Hongzhi Wang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adding nr ue ldpc offload
parent
9881036c
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1250 additions
and
0 deletions
+1250
-0
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+16
-0
cmake_targets/build_oai
cmake_targets/build_oai
+8
-0
executables/nr-uesoftmodem.c
executables/nr-uesoftmodem.c
+152
-0
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding_ldpc_offload.c
...air1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding_ldpc_offload.c
+876
-0
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+12
-0
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+15
-0
targets/ARCH/LDPC_OFFLOAD/slib/ldpc_decoder_offload.h
targets/ARCH/LDPC_OFFLOAD/slib/ldpc_decoder_offload.h
+171
-0
targets/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload.so
targets/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload.so
+0
-0
targets/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload415.so.1.2.0
...RCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload415.so.1.2.0
+0
-0
No files found.
cmake_targets/CMakeLists.txt
View file @
1036f0ed
...
@@ -247,6 +247,7 @@ add_boolean_option(T_TRACER True "Activate the T tracer, a debugging
...
@@ -247,6 +247,7 @@ add_boolean_option(T_TRACER True "Activate the T tracer, a debugging
add_boolean_option
(
UE_AUTOTEST_TRACE False
"Activate UE autotest specific logs"
)
add_boolean_option
(
UE_AUTOTEST_TRACE False
"Activate UE autotest specific logs"
)
add_boolean_option
(
UE_DEBUG_TRACE False
"Activate UE debug trace"
)
add_boolean_option
(
UE_DEBUG_TRACE False
"Activate UE debug trace"
)
add_boolean_option
(
UE_TIMING_TRACE False
"Activate UE timing trace"
)
add_boolean_option
(
UE_TIMING_TRACE False
"Activate UE timing trace"
)
add_boolean_option
(
LDPC_FPGA_OFFLOAD False
"Activate UE LDPC trace"
)
add_boolean_option
(
DISABLE_LOG_X False
"Deactivate all LOG_* macros"
)
add_boolean_option
(
DISABLE_LOG_X False
"Deactivate all LOG_* macros"
)
add_boolean_option
(
USRP_REC_PLAY False
"Enable USRP record playback mode"
)
add_boolean_option
(
USRP_REC_PLAY False
"Enable USRP record playback mode"
)
add_boolean_option
(
UE_NAS_USE_TUN False
"Enable UE NAS TUN device instead of ue_ip.ko"
)
add_boolean_option
(
UE_NAS_USE_TUN False
"Enable UE NAS TUN device instead of ue_ip.ko"
)
...
@@ -1425,6 +1426,7 @@ set(PHY_SRC_UE
...
@@ -1425,6 +1426,7 @@ set(PHY_SRC_UE
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding_ldpc_offload.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
${
OPENAIR1_DIR
}
/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
${
OPENAIR1_DIR
}
/PHY/NR_TRANSPORT/nr_tbs_tools.c
${
OPENAIR1_DIR
}
/PHY/NR_TRANSPORT/nr_tbs_tools.c
${
OPENAIR1_DIR
}
/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${
OPENAIR1_DIR
}
/PHY/NR_TRANSPORT/nr_sch_dmrs.c
...
@@ -2549,6 +2551,20 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${C
...
@@ -2549,6 +2551,20 @@ target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${C
target_link_libraries
(
nr-uesoftmodem
${
LIB_LMS_LIBRARIES
}
)
target_link_libraries
(
nr-uesoftmodem
${
LIB_LMS_LIBRARIES
}
)
target_link_libraries
(
nr-uesoftmodem
${
T_LIB
}
)
target_link_libraries
(
nr-uesoftmodem
${
T_LIB
}
)
# LDPC Decoder Offload : SYRTEM
#####################################################
if
(
${
LDPC_FPGA_OFFLOAD
}
)
set
(
LDPC_OFFLOAD_DIR
${
OPENAIR_DIR
}
/targets/ARCH/LDPC_OFFLOAD/slib
)
include_directories
(
"
${
LDPC_OFFLOAD_DIR
}
"
)
LINK_DIRECTORIES
(
"
${
LDPC_OFFLOAD_DIR
}
"
)
set
(
LDPC_OFFLOAD_LIB
"ldpc_decoder_offload"
)
endif
(
${
LDPC_FPGA_OFFLOAD
}
)
if
(
${
LDPC_FPGA_OFFLOAD
}
)
message
(
"Linking LDPC_OFFLOAD lib"
)
target_link_libraries
(
nr-uesoftmodem
${
OPENAIR_TARGETS
}
/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload.so
)
endif
(
${
LDPC_FPGA_OFFLOAD
}
)
# nr-uesoftmodem-nos1
# nr-uesoftmodem-nos1
#######################################
#######################################
...
...
cmake_targets/build_oai
View file @
1036f0ed
...
@@ -64,6 +64,7 @@ CMAKE_CMD="$CMAKE"
...
@@ -64,6 +64,7 @@ CMAKE_CMD="$CMAKE"
UE_AUTOTEST_TRACE
=
"False"
UE_AUTOTEST_TRACE
=
"False"
UE_DEBUG_TRACE
=
"False"
UE_DEBUG_TRACE
=
"False"
UE_TIMING_TRACE
=
"False"
UE_TIMING_TRACE
=
"False"
LDPC_FPGA_OFFLOAD
=
"False"
USRP_REC_PLAY
=
"False"
USRP_REC_PLAY
=
"False"
BUILD_ECLIPSE
=
0
BUILD_ECLIPSE
=
0
NR
=
"False"
NR
=
"False"
...
@@ -143,6 +144,8 @@ Options
...
@@ -143,6 +144,8 @@ Options
Disables the T tracer.
Disables the T tracer.
--disable-hardware-dependency
--disable-hardware-dependency
Disable HW dependency during installation
Disable HW dependency during installation
--ldpc_fpga_offload
Enables LDPC decoding offload in FPGA.
--ue-autotest-trace
--ue-autotest-trace
Enable specific traces for UE autotest framework
Enable specific traces for UE autotest framework
--ue-trace
--ue-trace
...
@@ -332,6 +335,10 @@ function main() {
...
@@ -332,6 +335,10 @@ function main() {
echo_info
"Disabling hardware dependency for compiling software"
echo_info
"Disabling hardware dependency for compiling software"
DISABLE_HARDWARE_DEPENDENCY
=
"True"
DISABLE_HARDWARE_DEPENDENCY
=
"True"
shift
1
;;
shift
1
;;
--ldpc_fpga_offload
)
LDPC_FPGA_OFFLOAD
=
"True"
echo_info
"Enabling the usage of LDPC decoding offload in FPGA"
shift
1
;;
--ue-autotest-trace
)
--ue-autotest-trace
)
UE_AUTOTEST_TRACE
=
"True"
UE_AUTOTEST_TRACE
=
"True"
echo_info
"Enabling autotest specific trace for UE"
echo_info
"Enabling autotest specific trace for UE"
...
@@ -563,6 +570,7 @@ function main() {
...
@@ -563,6 +570,7 @@ function main() {
echo
"set ( UE_AUTOTEST_TRACE
$UE_AUTOTEST_TRACE
)"
>>
$cmake_file
echo
"set ( UE_AUTOTEST_TRACE
$UE_AUTOTEST_TRACE
)"
>>
$cmake_file
echo
"set ( UE_DEBUG_TRACE
$UE_DEBUG_TRACE
)"
>>
$cmake_file
echo
"set ( UE_DEBUG_TRACE
$UE_DEBUG_TRACE
)"
>>
$cmake_file
echo
"set ( UE_TIMING_TRACE
$UE_TIMING_TRACE
)"
>>
$cmake_file
echo
"set ( UE_TIMING_TRACE
$UE_TIMING_TRACE
)"
>>
$cmake_file
echo
"set ( LDPC_FPGA_OFFLOAD
$LDPC_FPGA_OFFLOAD
)"
>>
$cmake_file
echo
"set ( USRP_REC_PLAY
$USRP_REC_PLAY
)"
>>
$cmake_file
echo
"set ( USRP_REC_PLAY
$USRP_REC_PLAY
)"
>>
$cmake_file
echo
'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)'
>>
$cmake_file
echo
'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)'
>>
$cmake_file
cd
$DIR
/
$build_dir
/build
cd
$DIR
/
$build_dir
/build
...
...
executables/nr-uesoftmodem.c
View file @
1036f0ed
...
@@ -122,6 +122,59 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
...
@@ -122,6 +122,59 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern
int16_t
nr_dlsch_demod_shift
;
extern
int16_t
nr_dlsch_demod_shift
;
#if LDPC_FPGA_OFFLOAD
#include <dlfcn.h>
#include "ldpc_decoder_offload.h"
typedef
uint8_t
(
*
syr_ldpc_offload_initfunc_t
)(
void
);
typedef
uint8_t
(
*
syr_ldpc_offload_finifunc_t
)(
void
);
typedef
uint8_t
(
*
syr_ldpc_offload_decodefunc_t
)(
int16_t
*
y
,
uint8_t
*
decoded_bytes
,
uint16_t
n
,
uint16_t
interleaver_f1
,
uint16_t
interleaver_f2
,
uint8_t
max_iterations
,
uint8_t
crc_type
,
uint8_t
F
,
time_stats_t
*
init_stats
,
time_stats_t
*
alpha_stats
,
time_stats_t
*
beta_stats
,
time_stats_t
*
gamma_stats
,
time_stats_t
*
ext_stats
,
time_stats_t
*
intl1_stats
,
time_stats_t
*
intl2_stats
);
syr_ldpc_offload_initfunc_t
syr_init_funct
;
syr_ldpc_offload_finifunc_t
syr_fini_funct
;
//syr_ldpc_offload_decodefunc_t syr_ldpc_decode_funct;
typedef
session_t
(
*
threegpp_nr_ldpc_decode_start_t
)(
session_desc_t
*
session_desc
);
threegpp_nr_ldpc_decode_start_t
threegpp_nr_ldpc_decode_start_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_putq_t
)(
session_t
fd
,
int16_t
*
y_16bits
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint16_t
n
,
uint8_t
max_iterations
,
uint8_t
crc_type
);
threegpp_nr_ldpc_decode_putq_t
threegpp_nr_ldpc_decode_putq_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_getq_t
)(
session_t
fd
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint8_t
crc_type
,
uint8_t
*
crc_status
,
uint8_t
*
nb_iterations
);
threegpp_nr_ldpc_decode_getq_t
threegpp_nr_ldpc_decode_getq_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_stop_t
)(
session_t
fd
);
threegpp_nr_ldpc_decode_stop_t
threegpp_nr_ldpc_decode_stop_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_run_t
)(
session_t
fd
);
threegpp_nr_ldpc_decode_run_t
threegpp_nr_ldpc_decode_run_funct
;
#endif
int
UE_scan
=
0
;
int
UE_scan
=
0
;
int
UE_scan_carrier
=
0
;
int
UE_scan_carrier
=
0
;
int
UE_fo_compensation
=
0
;
int
UE_fo_compensation
=
0
;
...
@@ -789,6 +842,105 @@ int main( int argc, char **argv ) {
...
@@ -789,6 +842,105 @@ int main( int argc, char **argv ) {
#endif
#endif
}
}
#if LDPC_FPGA_OFFLOAD
void
*
syr_handle
=
NULL
;;
uint8_t
syr_ret
=
0
;
syr_handle
=
dlopen
(
"libldpc_decoder_offload.so"
,
RTLD_LAZY
);
if
(
!
syr_handle
)
{
fprintf
(
stderr
,
"Unable to locate libldpc_decoder_offload.so: HW device set to NONE_DEV.
\n
"
);
fprintf
(
stderr
,
"%s
\n
"
,
dlerror
());
exit_fun
(
"Error loading ldpc decoder offload device"
);
}
syr_init_funct
=
dlsym
(
syr_handle
,
"phy_threegppnr_ldpc_decoder_offload_init"
);
if
(
syr_init_funct
!=
NULL
)
{
syr_ret
=
syr_init_funct
();
if
(
syr_ret
<
0
)
{
fprintf
(
stderr
,
"%s %d:ldpc decoder offload device intialization failed %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit_fun
(
"Error loading ldpc decoder offload device"
);
}
}
else
{
fprintf
(
stderr
,
"%s %d:ldpc decoder offload device init function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit_fun
(
"Error ldpc decoder offload device init function not found"
);
}
syr_fini_funct
=
dlsym
(
syr_handle
,
"phy_threegppnr_ldpc_decoder_offload_fini"
);
if
(
syr_fini_funct
==
NULL
)
{
fprintf
(
stderr
,
"%s %d:ldpc decoder offload device fini function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit_fun
(
"Error ldpc decoder offload device fini function not found"
);
}
#if 0
syr_ldpc_decode_funct = dlsym(syr_handle,"phy_threegppnr_ldpc_decoder_offload");
if (syr_ldpc_decode_funct == NULL )
{
fprintf(stderr, "%s %d:ldpc decoder offload device decode function not found %s\n", __FILE__, __LINE__, dlerror());
exit_fun("Error ldpc decoder offload device decode function not found");
}
#endif
threegpp_nr_ldpc_decode_start_funct
=
dlsym
(
syr_handle
,
"threegpp_nr_ldpc_decode_start"
);
if
(
threegpp_nr_ldpc_decode_start_funct
==
NULL
)
{
printf
(
"%s %d:threegpp_nr_ldpc_decode_start function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit
(
-
1
);
}
threegpp_nr_ldpc_decode_putq_funct
=
dlsym
(
syr_handle
,
"threegpp_nr_ldpc_decode_putq"
);
if
(
threegpp_nr_ldpc_decode_putq_funct
==
NULL
)
{
printf
(
"%s %d:threegpp_nr_ldpc_decode_putq function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit
(
-
1
);
}
threegpp_nr_ldpc_decode_getq_funct
=
dlsym
(
syr_handle
,
"threegpp_nr_ldpc_decode_getq"
);
if
(
threegpp_nr_ldpc_decode_getq_funct
==
NULL
)
{
printf
(
"%s %d:threegpp_nr_ldpc_decode_getq function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit
(
-
1
);
}
threegpp_nr_ldpc_decode_stop_funct
=
dlsym
(
syr_handle
,
"threegpp_nr_ldpc_decode_stop"
);
if
(
threegpp_nr_ldpc_decode_stop_funct
==
NULL
)
{
printf
(
"%s %d:threegpp_nr_ldpc_decode_stop function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit
(
-
1
);
}
threegpp_nr_ldpc_decode_run_funct
=
dlsym
(
syr_handle
,
"threegpp_nr_ldpc_decode_run"
);
if
(
threegpp_nr_ldpc_decode_run_funct
==
NULL
)
{
printf
(
"%s %d:threegpp_nr_ldpc_decode_run function not found %s
\n
"
,
__FILE__
,
__LINE__
,
dlerror
());
exit
(
-
1
);
}
#if 0 // Test
int16_t y[8448]; // 22.Zc -> 22x128 x 3 LLR16bits -> 8448 int16_t
uint8_t decoded_bytes[352]; // 22.Zc bits -> 352 bytes
uint16_t n = 2816; // code_block size = 2816
memset(y, 0x7F, 8448 * sizeof(int16_t));
memset(decoded_bytes, 0, 352 * sizeof(uint8_t));
syr_ret = syr_ldpc_decode_funct(y, decoded_bytes, n, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (syr_ret < 0)
{
fprintf(stderr, "%s %d:ldpc decoder offload device intialization failed %s\n", __FILE__, __LINE__, dlerror());
exit_fun("Error loading ldpc decoder offload device");
}
#endif
#endif
// wait for end of program
// wait for end of program
printf
(
"TYPE <CTRL-C> TO TERMINATE
\n
"
);
printf
(
"TYPE <CTRL-C> TO TERMINATE
\n
"
);
init_NR_UE
(
1
);
init_NR_UE
(
1
);
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding_ldpc_offload.c
0 → 100644
View file @
1036f0ed
/*
* 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
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_decoding.c
* \brief Top-level routines for decoding LDPC-coded (DLSCH) transport channels from 38-212
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#include "common/utils/LOG/vcd_signal_dumper.h"
//#include "defs.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/phy_extern.h"
#include "PHY/CODING/coding_extern.h"
#include "SCHED_NR_UE/defs.h"
#include "SIMULATION/TOOLS/sim.h"
#include "executables/nr-uesoftmodem.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
//#include "PHY/CODING/nrLDPC_types.h"
//#define DEBUG_DLSCH_DECODING
#if LDPC_FPGA_OFFLOAD
static
uint64_t
nb_total_decod
=
0
;
static
uint64_t
nb_error_decod
=
0
;
uint64_t
total_decod
=
0
;
uint64_t
total_decod_error
=
0
;
uint64_t
total_decod_error_crc
=
0
;
uint64_t
total_decod_it
=
0
;
typedef
struct
ldpc_stat_per_subframe
{
uint64_t
ldpc_block_decod_count
;
uint64_t
ldpc_block_decod_error
;
uint64_t
ldpc_block_decod_error_crc
;
uint64_t
ldpc_block_decod_it
;
uint64_t
ldpc_block_decod_max_it
;
uint64_t
ldpc_tb_error_block_max
;
}
ldpc_stat_per_subframe_t
;
int
ldpc_stat_flag
=
0
;
ldpc_stat_per_subframe_t
g_ldpc_stat_per_subframe_array
[
10
];
//#define DLSIM_DECOD_CHECK
#ifdef DLSIM_DECOD_CHECK
extern
uint16_t
dlsch_coding_c
[
16
][
22
*
384
];
extern
uint8_t
dlsch_coding_d
[
16
][
96
+
(
22
*
384
*
3
)
+
12
];
extern
uint16_t
dlsch_decoding_d
[
16
][
96
+
(
22
*
384
*
3
)
+
12
];
void
debug_check_decoder_input_buff
(
uint32_t
Kr
,
uint32_t
Zc
,
uint32_t
r
,
LTE_DL_UE_HARQ_t
*
harq_process
);
#endif
#if LDPC_FPGA_OFFLOAD
#include <dlfcn.h>
#include "ldpc_decoder_offload.h"
typedef
session_t
(
*
threegpp_nr_ldpc_decode_start_t
)(
session_desc_t
*
session_desc
);
extern
threegpp_nr_ldpc_decode_start_t
threegpp_nr_ldpc_decode_start_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_putq_t
)(
session_t
fd
,
int16_t
*
y_16bits
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint16_t
n
,
uint8_t
max_iterations
,
uint8_t
crc_type
);
extern
threegpp_nr_ldpc_decode_putq_t
threegpp_nr_ldpc_decode_putq_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_getq_t
)(
session_t
fd
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint8_t
crc_type
,
uint8_t
*
crc_status
,
uint8_t
*
nb_iterations
);
extern
threegpp_nr_ldpc_decode_getq_t
threegpp_nr_ldpc_decode_getq_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_stop_t
)(
session_t
fd
);
extern
threegpp_nr_ldpc_decode_stop_t
threegpp_nr_ldpc_decode_stop_funct
;
typedef
int32_t
(
*
threegpp_nr_ldpc_decode_run_t
)(
session_t
fd
);
extern
threegpp_nr_ldpc_decode_run_t
threegpp_nr_ldpc_decode_run_funct
;
#endif
//#define DEBUG_LLR_STATS
#ifdef DEBUG_LLR_STATS
static
int16_t
llr_max
=
0
;
static
int16_t
llr_min
=
0
;
static
uint16_t
llr_cnt
=
0
;
static
double
llr_p_mean
=
0
.
0
;
static
double
llr_p_cnt
=
0
.
0
;
static
double
llr_n_mean
=
0
.
0
;
static
double
llr_n_cnt
=
0
.
0
;
static
double
llr_p_mean1
=
0
.
0
;
static
double
llr_p_cnt1
=
0
.
0
;
static
double
llr_n_mean1
=
0
.
0
;
static
double
llr_n_cnt1
=
0
.
0
;
static
void
debug_llr_stats
(
void
);
#endif
extern
double
cpuf
;
// static uint32_t dbg_counter = 0;
// static uint8_t current_sf = 0;
uint32_t
nr_dlsch_decoding_ldpc_offload
(
PHY_VARS_NR_UE
*
phy_vars_ue
,
short
*
dlsch_llr
,
NR_DL_FRAME_PARMS
*
frame_parms
,
NR_UE_DLSCH_t
*
dlsch
,
NR_DL_UE_HARQ_t
*
harq_process
,
uint32_t
frame
,
uint16_t
nb_symb_sch
,
uint8_t
nr_tti_rx
,
uint8_t
harq_pid
,
uint8_t
is_crnti
,
uint8_t
llr8_flag
)
{
#if UE_TIMING_TRACE
time_stats_t
*
dlsch_rate_unmatching_stats
=&
phy_vars_ue
->
dlsch_rate_unmatching_stats
;
time_stats_t
*
dlsch_turbo_decoding_stats
=&
phy_vars_ue
->
dlsch_turbo_decoding_stats
;
time_stats_t
*
dlsch_deinterleaving_stats
=&
phy_vars_ue
->
dlsch_deinterleaving_stats
;
#endif
uint8_t
no_iteration_ldpc
;
uint8_t
crc_status_ldpc
;
uint32_t
A
,
E
;
uint32_t
G
;
uint32_t
ret
,
offset
;
short
dummy_w
[
MAX_NUM_DLSCH_SEGMENTS
][
3
*
(
8448
+
64
)];
uint32_t
r
,
r_offset
=
0
,
Kr
,
Kr_bytes
,
err_flag
=
0
,
K_bytes_F
;
uint8_t
crc_type
;
t_nrLDPC_dec_params
decParams
;
t_nrLDPC_dec_params
*
p_decParams
=
&
decParams
;
uint8_t
kb
;
uint8_t
kc
;
uint8_t
Ilbrm
=
0
;
uint32_t
Tbslbrm
=
950984
;
uint16_t
nb_rb
=
30
;
double
Coderate
=
0
.
0
;
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
uint8_t
nb_re_dmrs
=
6
;
//(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4;
uint16_t
length_dmrs
=
1
;
//cfg->pdsch_config.dmrs_max_length.value;
uint8_t
iteration_max
;
session_t
ldpc_decoder_fd
;
session_desc_t
ldpc_decod_session_param
;
uint32_t
lpdc_decod_return
;
#ifndef __AVX2__
AssertFatal
(
0
,
"dlsch_decoding_ldpc_offload - platform not supported (no AVX2)
\n
"
);
#endif
if
(
!
dlsch_llr
)
{
printf
(
"dlsch_decoding.c: NULL dlsch_llr pointer
\n
"
);
return
(
dlsch
->
max_ldpc_iterations
);
}
if
(
!
harq_process
)
{
printf
(
"dlsch_decoding.c: NULL harq_process pointer
\n
"
);
return
(
dlsch
->
max_ldpc_iterations
);
}
if
(
!
frame_parms
)
{
printf
(
"dlsch_decoding.c: NULL frame_parms pointer
\n
"
);
return
(
dlsch
->
max_ldpc_iterations
);
}
/*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) {
printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx);
return(dlsch->max_ldpc_iterations);
}
if (dlsch->harq_ack[nr_tti_rx].ack != 2) {
LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
phy_vars_ue->Mod_id, nr_tti_rx, dlsch->harq_ack[nr_tti_rx].ack);
}
if (llr8_flag != 0) {
AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n",
harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
}*/
err_flag
=
0
;
iteration_max
=
0
;
r_offset
=
0
;
nb_rb
=
harq_process
->
nb_rb
;
harq_process
->
trials
[
harq_process
->
round
]
++
;
harq_process
->
TBS
=
nr_compute_tbs
(
harq_process
->
mcs
,
nb_rb
,
nb_symb_sch
,
nb_re_dmrs
,
length_dmrs
,
harq_process
->
Nl
);
A
=
harq_process
->
TBS
;
ret
=
dlsch
->
max_ldpc_iterations
;
harq_process
->
G
=
nr_get_G
(
nb_rb
,
nb_symb_sch
,
nb_re_dmrs
,
length_dmrs
,
harq_process
->
Qm
,
harq_process
->
Nl
);
G
=
harq_process
->
G
;
#ifdef DEBUG_DLSCH_DECODING
printf
(
"
\n
DLSCH Decoding, harq_pid %d DCINdi %d round %d
\n
"
,
harq_pid
,
harq_process
->
DCINdi
,
harq_process
->
round
);
#endif
if
(
harq_process
->
round
==
0
)
{
// printf("dlsch_decoding_ldpc_offload : Segmentation in (proc %d ) %d/%d \n",
// phy_vars_ue->current_thread_id[nr_tti_rx],
// frame,
// nr_tti_rx);
// fflush(stdout);
// This is a new packet, so compute quantities regarding segmentation
harq_process
->
B
=
A
+
24
;
nr_segmentation
(
NULL
,
NULL
,
harq_process
->
B
,
&
harq_process
->
C
,
&
harq_process
->
K
,
&
harq_process
->
Z
,
// [hna] Z is Zc
&
harq_process
->
F
);
}
p_decParams
->
Z
=
harq_process
->
Z
;
Coderate
=
(
float
)
A
/
(
float
)
G
;
if
((
A
<=
292
)
||
((
A
<=
3824
)
&&
(
Coderate
<=
0
.
6667
))
||
Coderate
<=
0
.
25
)
{
p_decParams
->
BG
=
2
;
if
(
Coderate
<
0
.
3333
){
p_decParams
->
R
=
15
;
kc
=
52
;
}
else
if
(
Coderate
<
0
.
6667
){
p_decParams
->
R
=
13
;
kc
=
32
;
}
else
{
p_decParams
->
R
=
23
;
kc
=
17
;
}
}
else
{
p_decParams
->
BG
=
1
;
if
(
Coderate
<
0
.
6667
){
p_decParams
->
R
=
13
;
kc
=
68
;
}
else
if
(
Coderate
<
0
.
8889
){
p_decParams
->
R
=
23
;
kc
=
35
;
}
else
{
p_decParams
->
R
=
89
;
kc
=
27
;
}
}
// Select CRC type
if
(
harq_process
->
C
==
1
)
crc_type
=
CRC24_A
;
else
crc_type
=
CRC24_B
;
p_decParams
->
numMaxIter
=
dlsch
->
max_ldpc_iterations
;
p_decParams
->
outMode
=
0
;
#ifdef DEBUG_DLSCH_DECODING
printf
(
"p_decParams Kplus=%d Z=%d BG=%d, R=%d, MaxIt.=%d
\n
"
,
harq_process
->
Kplus
,
harq_process
->
Z
,
p_decParams
->
BG
,
p_decParams
->
R
,
p_decParams
->
numMaxIter
);
#endif
ldpc_decod_session_param
.
proc_nb
=
phy_vars_ue
->
current_thread_id
[
nr_tti_rx
];
ldpc_decod_session_param
.
frame
=
frame
;
ldpc_decod_session_param
.
nr_tti_rx
=
nr_tti_rx
;
ldpc_decod_session_param
.
BG
=
p_decParams
->
BG
;
ldpc_decod_session_param
.
R
=
p_decParams
->
R
;
ldpc_decod_session_param
.
Zc
=
harq_process
->
Z
;
ldpc_decod_session_param
.
max_decoding_iterations
=
p_decParams
->
numMaxIter
;
ldpc_decod_session_param
.
C
=
harq_process
->
C
;
ldpc_decod_session_param
.
crc_type
=
crc_type
;
ldpc_decod_session_param
.
mcs
=
harq_process
->
mcs
;
ldpc_decoder_fd
=
threegpp_nr_ldpc_decode_start_funct
(
&
ldpc_decod_session_param
);
if
(
ldpc_decoder_fd
==
NULL
)
{
printf
(
"dlsch_decoding: Error getting FPGA decod session!!!
\n
"
);
harq_process
->
harq_ack
.
ack
=
0
;
harq_process
->
harq_ack
.
harq_id
=
harq_pid
;
harq_process
->
harq_ack
.
send_harq_status
=
1
;
harq_process
->
errors
[
harq_process
->
round
]
++
;
harq_process
->
round
++
;
// If we have reach harq max round or no mac (phytest mode) -> set harq process in idle mode
if
((
harq_process
->
round
>=
dlsch
->
Mdlharq
)
||
(
phy_vars_ue
->
mac_enabled
==
0
)
)
{
harq_process
->
status
=
SCH_IDLE
;
harq_process
->
round
=
0
;
}
if
(
is_crnti
)
{
LOG_D
(
PHY
,
"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
nr_tti_rx
,
harq_pid
,
harq_process
->
status
,
harq_process
->
round
,
dlsch
->
Mdlharq
,
harq_process
->
TBS
);
}
return
((
1
+
dlsch
->
max_ldpc_iterations
));
}
unsigned
char
bw_scaling
=
1
;
switch
(
frame_parms
->
N_RB_DL
)
{
case
106
:
bw_scaling
=
2
;
break
;
default:
bw_scaling
=
1
;
break
;
}
if
(
harq_process
->
C
>
MAX_NUM_DLSCH_SEGMENTS
/
bw_scaling
)
{
printf
(
"Illegal harq_process->C %d > %d
\n
"
,
harq_process
->
C
,
MAX_NUM_DLSCH_SEGMENTS
/
bw_scaling
);
return
(
(
1
+
dlsch
->
max_ldpc_iterations
)
);
}
#ifdef DEBUG_DLSCH_DECODING
printf
(
"Segmentation: C %d, K %d
\n
"
,
harq_process
->
C
,
harq_process
->
K
);
#endif
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* LOOP OVER SEGMENTS */
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
#if UE_TIMING_TRACE
opp_enabled
=
1
;
// enable openair performance monitor
#endif
Kr
=
harq_process
->
K
;
Kr_bytes
=
Kr
>>
3
;
K_bytes_F
=
Kr_bytes
-
(
harq_process
->
F
>>
3
);
Tbslbrm
=
nr_compute_tbs
(
28
,
nb_rb
,
frame_parms
->
symbols_per_slot
,
0
,
0
,
harq_process
->
Nl
);
for
(
r
=
0
;
r
<
harq_process
->
C
;
r
++
)
{
E
=
nr_get_E
(
G
,
harq_process
->
C
,
harq_process
->
Qm
,
harq_process
->
Nl
,
r
);
#if UE_TIMING_TRACE
start_meas
(
dlsch_deinterleaving_stats
);
#endif
nr_deinterleaving_ldpc
(
E
,
harq_process
->
Qm
,
harq_process
->
w
[
r
],
// [hna] w is e
dlsch_llr
+
r_offset
);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
#if UE_TIMING_TRACE
stop_meas
(
dlsch_deinterleaving_stats
);
#endif
#if UE_TIMING_TRACE
start_meas
(
dlsch_rate_unmatching_stats
);
#endif
#ifdef DEBUG_DLSCH_DECODING
LOG_D
(
PHY
,
"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...
\n
"
,
harq_pid
,
r
,
G
,
Kr
*
3
,
harq_process
->
TBS
,
harq_process
->
Qm
,
harq_process
->
nb_rb
,
harq_process
->
Nl
,
harq_process
->
rvidx
,
harq_process
->
round
);
#endif
if
(
nr_rate_matching_ldpc_rx
(
Ilbrm
,
Tbslbrm
,
p_decParams
->
BG
,
p_decParams
->
Z
,
harq_process
->
d
[
r
],
harq_process
->
w
[
r
],
harq_process
->
C
,
harq_process
->
rvidx
,
(
harq_process
->
round
==
0
)
?
1
:
0
,
E
)
==-
1
)
{
#if UE_TIMING_TRACE
stop_meas
(
dlsch_rate_unmatching_stats
);
#endif
LOG_E
(
PHY
,
"dlsch_decoding.c: Problem in rate_matching
\n
"
);
return
(
dlsch
->
max_ldpc_iterations
);
}
else
{
#if UE_TIMING_TRACE
stop_meas
(
dlsch_rate_unmatching_stats
);
#endif
}
//for (int i =0; i<16; i++)
// printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
r_offset
+=
E
;
#ifdef DEBUG_DLSCH_DECODING
if
(
r
==
0
)
{
write_output
(
"decoder_llr.m"
,
"decllr"
,
dlsch_llr
,
G
,
1
,
0
);
write_output
(
"decoder_in.m"
,
"dec"
,
&
harq_process
->
d
[
0
][
0
],(
3
*
8
*
Kr_bytes
)
+
12
,
1
,
0
);
}
printf
(
"decoder input(segment %d) :"
,
r
);
int
i
;
for
(
i
=
0
;
i
<
(
3
*
8
*
Kr_bytes
)
+
12
;
i
++
)
printf
(
"%d : %d
\n
"
,
i
,
harq_process
->
d
[
r
][
i
]);
printf
(
"
\n
"
);
#endif
// printf("Clearing c, %p\n",harq_process->c[r]);
memset
(
harq_process
->
c
[
r
],
0
,
Kr_bytes
);
/* CLEARING OUTPUT BUFFER */
/* ---------------------------------------------------------------------- */
memset
(
harq_process
->
c
[
r
],
0
,
Kr_bytes
);
/* Compute LLRs 16 statistics -> usefull for 8bits conversion dynamic */
#ifdef DEBUG_LLR_STATS
debug_llr_stats
();
#endif
/* DECODING PROCESS */
/* ---------------------------------------------------------------------- */
// LDPC Decoder
#ifdef DLSIM_DECOD_CHECK
debug_check_decoder_input_buff
(
Kr
,
harq_process
->
Z
,
r
,
harq_process
);
#endif
lpdc_decod_return
=
threegpp_nr_ldpc_decode_putq_funct
(
ldpc_decoder_fd
,
&
harq_process
->
d
[
r
],
harq_process
->
c
[
r
],
r
,
Kr
,
dlsch
->
max_ldpc_iterations
,
crc_type
);
if
(
lpdc_decod_return
){
printf
(
"dlsch_decoding_ldpc_offload putq FAILED %s() %s:%d
\n
"
,
__FUNCTION__
,
__FILE__
,
__LINE__
);
lpdc_decod_return
=
threegpp_nr_ldpc_decode_stop_funct
(
ldpc_decoder_fd
);
return
((
1
+
dlsch
->
max_ldpc_iterations
));
}
}
// r Segments LOOP
#if 1
lpdc_decod_return
=
threegpp_nr_ldpc_decode_run_funct
(
ldpc_decoder_fd
);
if
(
lpdc_decod_return
)
{
printf
(
"dlsch_decoding_ldpc_offload run FAILED %s() %s:%d !!!!!!!!!!
\n
"
,
__FUNCTION__
,
__FILE__
,
__LINE__
);
lpdc_decod_return
=
threegpp_nr_ldpc_decode_stop_funct
(
ldpc_decoder_fd
);
return
((
1
+
dlsch
->
max_ldpc_iterations
));
}
// Wait for decoding offload ending
for
(
r
=
0
;
r
<
harq_process
->
C
;
r
++
)
{
nb_total_decod
++
;
total_decod
++
;
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_count
++
;
// If no errors try to get next segment
// if ( ! err_flag )
// {
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LDPC_DECOD_GETQ0+(phy_vars_ue->current_thread_id[nr_tti_rx]), 1);
lpdc_decod_return
=
threegpp_nr_ldpc_decode_getq_funct
(
ldpc_decoder_fd
,
harq_process
->
c
[
r
],
r
,
crc_type
,
&
crc_status_ldpc
,
&
no_iteration_ldpc
);
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LDPC_DECOD_GETQ0+(phy_vars_ue->current_thread_id[nr_tti_rx]), 0);
total_decod_it
+=
no_iteration_ldpc
;
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_it
+=
no_iteration_ldpc
;
if
(
lpdc_decod_return
!=
LDPC_DECODER_OFFLOAD_OK
)
{
nb_error_decod
++
;
total_decod_error
++
;
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_error
++
;
err_flag
++
;
lpdc_decod_return
=
threegpp_nr_ldpc_decode_stop_funct
(
ldpc_decoder_fd
);
return
((
1
+
dlsch
->
max_ldpc_iterations
));
}
else
if
(
!
crc_status_ldpc
)
{
nb_error_decod
++
;
total_decod_error
++
;
total_decod_error_crc
++
;
err_flag
++
;
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_error
++
;
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_error_crc
++
;
// If CRC has failed it is likely that we will get max_iteration
iteration_max
=
(
1
+
dlsch
->
max_ldpc_iterations
);
LOG_W
(
PHY
,
"AbsSubframe %d.%d CRC failed, segment %d/%d
\n
"
,
frame
%
1024
,
nr_tti_rx
,
r
,
harq_process
->
C
-
1
);
}
else
{
if
(
iteration_max
<
no_iteration_ldpc
)
iteration_max
=
no_iteration_ldpc
;
}
if
(
!
(
total_decod
%
100000
))
{
ldpc_stat_flag
=
1
;
}
}
// r Segments LOOP
if
(
!
nr_tti_rx
&&
!
(
frame
%
1000
)
&&
ldpc_stat_flag
)
{
printf
(
"
\n
LDPC BLER %f (%.6f %%) error %ld total %ld
\n
"
,
(
float
)
nb_error_decod
/
(
float
)
nb_total_decod
,
(
float
)(
nb_error_decod
*
100
.
0
)
/
(
float
)
nb_total_decod
,
nb_error_decod
,
nb_total_decod
);
nb_error_decod
=
0
;
nb_total_decod
=
0
;
printf
(
"ldpc_decode_getq total=%ld err=%ld (%.6f %%) crc_err=%ld it=%ld mean it.=%ld
\n
"
,
total_decod
,
total_decod_error
,
(
float
)
total_decod_error
/
total_decod
*
100
,
total_decod_error_crc
,
total_decod_it
,
total_decod_it
/
total_decod
);
for
(
int
dbg_loop
=
0
;
dbg_loop
<
10
;
dbg_loop
++
)
{
printf
(
" ldpc_stat subfram=%d %.4ld/%ld (%.2f %%) crc_err=%4.4ld it=%2.2ld mean it.=%ld max it.=%ld max_iterationblock_err=%ld
\n
"
,
dbg_loop
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_error
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_count
,
(
float
)
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_error
/
(
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_count
+
1
)
*
100
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_error_crc
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_it
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_it
/
(
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_count
+
1
),
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_max_it
,
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_tb_error_block_max
);
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_count
=
0
;
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_error
=
0
;
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_error_crc
=
0
;
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_it
=
0
;
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_block_decod_max_it
=
0
;
g_ldpc_stat_per_subframe_array
[
dbg_loop
].
ldpc_tb_error_block_max
=
0
;
}
printf
(
"
\n
"
);
}
if
(
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_max_it
<
iteration_max
)
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_block_decod_max_it
=
iteration_max
;
if
(
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_tb_error_block_max
<
err_flag
)
g_ldpc_stat_per_subframe_array
[
nr_tti_rx
].
ldpc_tb_error_block_max
=
err_flag
;
lpdc_decod_return
=
threegpp_nr_ldpc_decode_stop_funct
(
ldpc_decoder_fd
);
#endif
// If we detect an error
if
(
err_flag
)
ret
=
(
1
+
dlsch
->
max_ldpc_iterations
);
else
ret
=
iteration_max
;
if
(
err_flag
||
ret
==
(
1
+
dlsch
->
max_ldpc_iterations
)
)
{
#if UE_DEBUG_TRACE
LOG_I
(
PHY
,
"[UE %d] DLSCH: 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
"
,
phy_vars_ue
->
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
);
#endif
harq_process
->
harq_ack
.
ack
=
0
;
harq_process
->
harq_ack
.
harq_id
=
harq_pid
;
harq_process
->
harq_ack
.
send_harq_status
=
1
;
harq_process
->
errors
[
harq_process
->
round
]
++
;
harq_process
->
round
++
;
// If we have reach harq max round or no mac (phytest mode) -> set harq process in idle mode
if
((
harq_process
->
round
>=
dlsch
->
Mdlharq
)
||
(
phy_vars_ue
->
mac_enabled
==
0
)
)
{
harq_process
->
status
=
SCH_IDLE
;
harq_process
->
round
=
0
;
}
if
(
is_crnti
)
{
LOG_D
(
PHY
,
"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
nr_tti_rx
,
harq_pid
,
harq_process
->
status
,
harq_process
->
round
,
dlsch
->
Mdlharq
,
harq_process
->
TBS
);
}
return
((
1
+
dlsch
->
max_ldpc_iterations
));
}
else
{
#if UE_DEBUG_TRACE
LOG_I
(
PHY
,
"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d
\n
"
,
phy_vars_ue
->
Mod_id
,
nr_tti_rx
,
harq_process
->
TBS
,
harq_process
->
mcs
,
harq_process
->
nb_rb
,
harq_process
->
round
);
#endif
harq_process
->
status
=
SCH_IDLE
;
harq_process
->
round
=
0
;
harq_process
->
harq_ack
.
ack
=
1
;
harq_process
->
harq_ack
.
harq_id
=
harq_pid
;
harq_process
->
harq_ack
.
send_harq_status
=
1
;
if
(
is_crnti
)
{
LOG_D
(
PHY
,
"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)
\n
"
,
phy_vars_ue
->
Mod_id
,
nr_tti_rx
,
harq_pid
,
harq_process
->
round
,
harq_process
->
TBS
);
}
}
// Reassembly of Transport block here
offset
=
0
;
Kr
=
harq_process
->
K
;
Kr_bytes
=
Kr
>>
3
;
for
(
r
=
0
;
r
<
harq_process
->
C
;
r
++
)
{
memcpy
(
harq_process
->
b
+
offset
,
harq_process
->
c
[
r
],
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_DLSCH_DECODING
printf
(
"Segment %d : Kr= %d bytes
\n
"
,
r
,
Kr_bytes
);
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
);
printf
(
"b[0] = %x,c[%d] = %x
\n
"
,
harq_process
->
b
[
offset
],
harq_process
->
F
>>
3
,
harq_process
->
c
[
r
]);
#endif
}
dlsch
->
last_iteration_cnt
=
ret
;
return
(
ret
);
}
#ifdef DEBUG_LLR_STATS
void
debug_llr_stats
(
void
)
{
// first LLR seems to be buggous, wait a little before compute statistics
if
(
llr_cnt
>
1024
)
{
llr_p_mean1
=
0
.
0
;
llr_p_cnt1
=
0
.
0
;
llr_n_mean1
=
0
.
0
;
llr_n_cnt1
=
0
.
0
;
for
(
int
i
=
0
;
i
<
Kr
*
3
;
i
++
)
{
if
(
harq_process
->
d
[
r
][
96
+
i
]
>
llr_max
)
llr_max
=
harq_process
->
d
[
r
][
96
+
i
];
if
(
harq_process
->
d
[
r
][
96
+
i
]
<
llr_min
)
llr_min
=
harq_process
->
d
[
r
][
96
+
i
];
if
(
harq_process
->
d
[
r
][
96
+
i
]
>
0
)
{
llr_p_mean1
+=
harq_process
->
d
[
r
][
96
+
i
];
llr_p_cnt1
+=
1
.
0
;
}
if
(
harq_process
->
d
[
r
][
96
+
i
]
<
0
)
{
llr_n_mean1
+=
harq_process
->
d
[
r
][
96
+
i
];
llr_n_cnt1
+=
1
.
0
;
}
}
llr_n_mean
+=
llr_n_mean1
;
llr_n_cnt
+=
llr_n_cnt1
;
llr_p_mean
+=
llr_p_mean1
;
llr_p_cnt
+=
llr_p_mean1
;
}
llr_cnt
++
;
if
(
!
(
llr_cnt
%
4096
)
)
{
printf
(
"LDPC decoding LLRmax=%d LLRmin=%d pLLRmean=%lf (cnt:%lf) nLLRmean=%lf (cnt:%lf) pLLRmean1=%lf (cnt1:%lf) nLLRmean1=%lf (cnt1:%lf)
\n
"
,
llr_max
,
llr_min
,
(
llr_p_mean
/
llr_p_cnt
),
llr_p_cnt
,
(
llr_n_mean
/
llr_n_cnt
),
llr_n_cnt
,
(
llr_p_mean1
/
llr_p_cnt1
),
llr_p_cnt1
,
(
llr_n_mean1
/
llr_n_cnt1
),
llr_n_cnt1
);
}
return
;
}
#endif
#ifdef DLSIM_DECOD_CHECK
static
uint32_t
failure_cnt
=
0
;
static
uint32_t
total_cnt
=
0
;
void
debug_check_decoder_input_buff
(
uint32_t
Kr
,
uint32_t
Zc
,
uint32_t
r
,
LTE_DL_UE_HARQ_t
*
harq_process
)
{
uint32_t
failure
=
0
;
uint32_t
poncture
=
0
;
uint32_t
failure_systematic
=
0
;
uint32_t
poncture_systematic
=
0
;
uint32_t
failure_parity89
=
0
;
uint32_t
poncture_parity89
=
0
;
uint32_t
failure_parity13
=
0
;
uint32_t
poncture_parity13
=
0
;
total_cnt
++
;
// LLR coded data
for
(
int
i
=
0
;
i
<
(
Kr
*
3
);
i
++
)
{
uint8_t
bit
=
((
uint16_t
*
)
harq_process
->
d
[
r
])[
96
+
i
]
&
0x8000
?
0
:
1
;
// Check for Poncturing
if
(
!
((
uint16_t
*
)
harq_process
->
d
[
r
])[
96
+
i
]){
poncture
++
;
if
(
i
<
Zc
*
20
)
poncture_systematic
++
;
else
if
(
i
<
Zc
*
25
)
poncture_parity89
++
;
else
{
//poncture_parity13++;
}
}
// Check for erronous position
if
((
bit
-
dlsch_coding_d
[
r
][
96
+
i
])
||
(
!
((
uint16_t
*
)
harq_process
->
d
[
r
])[
96
+
i
])
)
{
if
(
i
<
Zc
*
20
){
failure
++
;
failure_systematic
++
;
}
else
if
(
i
<
Zc
*
25
){
failure
++
;
failure_parity89
++
;
}
else
{
//failure++;
//failure_parity13++;
}
}
}
if
(
failure
)
{
failure_cnt
++
;
#if 1
printf
(
"!! SYRTEM failure_cnt = %d/%d - r=%d - failure=%d/%d sys=%d parity89=%d parity13=%d !!!
\n
"
,
failure_cnt
,
total_cnt
,
r
,
failure
,
Kr
*
3
,
failure_systematic
,
failure_parity89
,
failure_parity13
);
printf
(
"!! SYRTEM %d - r=%d - poncture=%d sys=%d parity89=%d parity13=%d !!!
\n
"
,
Kr
*
3
,
r
,
poncture
,
poncture_systematic
,
poncture_parity89
,
poncture_parity13
);
#endif
}
return
;
}
#endif
#endif // LDPC_FPGA_OFFLOAD
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
View file @
1036f0ed
...
@@ -1804,6 +1804,18 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
...
@@ -1804,6 +1804,18 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t
is_crnti
,
uint8_t
is_crnti
,
uint8_t
llr8_flag
);
uint8_t
llr8_flag
);
uint32_t
nr_dlsch_decoding_ldpc_offload
(
PHY_VARS_NR_UE
*
phy_vars_ue
,
short
*
dlsch_llr
,
NR_DL_FRAME_PARMS
*
frame_parms
,
NR_UE_DLSCH_t
*
dlsch
,
NR_DL_UE_HARQ_t
*
harq_process
,
uint32_t
frame
,
uint16_t
nb_symb_sch
,
uint8_t
nr_tti_rx
,
uint8_t
harq_pid
,
uint8_t
is_crnti
,
uint8_t
llr8_flag
);
int
nr_extract_dci_info
(
PHY_VARS_NR_UE
*
ue
,
int
nr_extract_dci_info
(
PHY_VARS_NR_UE
*
ue
,
uint8_t
eNB_id
,
uint8_t
eNB_id
,
lte_frame_type_t
frame_type
,
lte_frame_type_t
frame_type
,
...
...
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
1036f0ed
...
@@ -3673,6 +3673,20 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
...
@@ -3673,6 +3673,20 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>
256
?
1
:
0
);
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>
256
?
1
:
0
);
LOG_T
(
PHY
,
"UE_DLSCH_PARALLELISATION is defined, ret = %d
\n
"
,
ret
);
LOG_T
(
PHY
,
"UE_DLSCH_PARALLELISATION is defined, ret = %d
\n
"
,
ret
);
#else
#else
#if LDPC_FPGA_OFFLOAD
ret
=
nr_dlsch_decoding_ldpc_offload
(
ue
,
pdsch_vars
->
llr
[
0
],
&
ue
->
frame_parms
,
dlsch0
,
dlsch0
->
harq_processes
[
harq_pid
],
frame_rx
,
nb_symb_sch
,
nr_tti_rx
,
harq_pid
,
pdsch
==
PDSCH
?
1
:
0
,
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>
256
?
1
:
0
);
//printf("start cW0 dlsch decoding\n");
#else
ret
=
nr_dlsch_decoding
(
ue
,
ret
=
nr_dlsch_decoding
(
ue
,
pdsch_vars
->
llr
[
0
],
pdsch_vars
->
llr
[
0
],
&
ue
->
frame_parms
,
&
ue
->
frame_parms
,
...
@@ -3686,6 +3700,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
...
@@ -3686,6 +3700,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>
256
?
1
:
0
);
dlsch0
->
harq_processes
[
harq_pid
]
->
TBS
>
256
?
1
:
0
);
LOG_T
(
PHY
,
"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d
\n
"
,
ret
);
LOG_T
(
PHY
,
"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d
\n
"
,
ret
);
//printf("start cW0 dlsch decoding\n");
//printf("start cW0 dlsch decoding\n");
#endif
#endif
#endif
#if UE_TIMING_TRACE
#if UE_TIMING_TRACE
...
...
targets/ARCH/LDPC_OFFLOAD/slib/ldpc_decoder_offload.h
0 → 100644
View file @
1036f0ed
/* ============================================================================
*
* file ldpc_decoder_offload.h
* author B.ROBERT
* date Jan 10, 2018
*
* brief LDPC Decoder Offload interface header.
*
* Infos:
* - Project : syr_ldpc_offload_lib
* - Software :
* - CVS domain : syrtemplatform5g
* - CVS component :
*
* ============================================================================
* Statement of Ownership
* ----------------------
* Copyright (c) 2018-2019 SYRTEM S.a.r.l All Rights Reserved
*
* This software is furnished under licence and may be used and copied only
* in accordance with the terms of such license and with the inclusion of the
* above COPYRIGHT notice. This SOFTWARE or any other copies thereof may not
* be provided or otherwise made available to any other person. No title to
* and ownership of the SOFTWARE is hereby transferred.
*
* The information in this SOFTWARE is subject to change without notice and
* should not be constructed as a commitment by SYRTEM.
*
* SYRTEM assumes no responsability for the use or reliability of its SOFTWARE
* on equipment or platform not explicitly validated by SYRTEM.
*
* ============================================================================
* Reference documents :
* -------------------
*
* ==========================================================================*/
#ifndef __LDPC_DECODER_OFFLOAD_LIB_H__
#define __LDPC_DECODER_OFFLOAD_LIB_H__
#define LDPC_DECODER_OFFLOAD_OK (0)
#define LDPC_DECODER_OFFLOAD_ERROR (-1)
#define LDPC_DECODER_OFFLOAD_BAD_PARAMETER (-2)
#define LDPC_DECODER_OFFLOAD_PRECONDITION_NOT_MET (-3)
#define LDPC_DECODER_OFFLOAD_NOT_SUPPORTED (-4)
#define LDPC_DECODER_OFFLOAD_NO_CONTEXT (-5)
#define LDPC_DECODER_OFFLOAD_DEVICE_NOT_FOUND (-6)
#define LDPC_DECODER_OFFLOAD_CHANNEL_NOT_FOUND (-7)
#define LDPC_DECODER_OFFLOAD_BUFFER_NOT_CREATED (-8)
#define LDPC_DECODER_OFFLOAD_INITCFG_FAILED (-9)
#define LDPC_DECODER_OFFLOAD_SELF_TEST_FAILED (-10)
#define LDPC_DECODER_OFFLOAD_SYRIQ_INIT_FAILED (-11)
#define LDPC_DECODER_OFFLOAD_TH_INIT_FAILED (-12)
#define LDPC_DECODER_OFFLOAD_DECOD_REQ_NULL (-20)
#define LDPC_DECODER_OFFLOAD_ERROR_TIMEOUT (-30)
typedef
void
*
session_t
;
typedef
struct
session_desc_s
{
uint32_t
proc_nb
;
uint32_t
frame
;
uint32_t
nr_tti_rx
;
// ~ tti number
uint32_t
BG
;
uint32_t
R
;
uint8_t
coderate
;
// 0x01:BG1 8/9 27.Zc
// 0x2A:BG1 1/3 68.Zc,
// 0x43:BG2 2/3 17.Zc,
// 0x66:BG2 1/5 52.Zc,
uint32_t
Zc
;
// 128, 160, 224, 256, 384
uint8_t
max_decoding_iterations
;
uint32_t
C
;
uint8_t
crc_type
;
uint8_t
mcs
;
}
session_desc_t
;
typedef
enum
ldpc_msgtype_e
{
LDPC_DECODING_OFFLOAD_REQ
,
LDPC_DECODING_OFFLOAD_CONF
}
ldpc_msgtype_t
;
typedef
struct
decode_req_s
{
ldpc_msgtype_t
msg_type
;
uint32_t
proc_nb
;
uint32_t
r
;
// seg. index from 1 to 16 max
int16_t
*
data
;
// 16bit LLR buffer pointer
}
decode_req_t
;
typedef
struct
decode_conf_s
{
ldpc_msgtype_t
msg_type
;
uint32_t
proc_nb
;
uint32_t
segment_no
;
// from 1 to 16 max
uint32_t
crc24_check
;
uint32_t
nb_iterations
;
uint8_t
*
data
;
// Hard decoded bits buffer pointer
}
decode_conf_t
;
session_t
threegpp_nr_ldpc_decode_start
(
session_desc_t
*
session_desc
);
int32_t
threegpp_nr_ldpc_decode_putq
(
session_t
fd
,
int16_t
*
y_16bits
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint16_t
n
,
uint8_t
max_iterations
,
uint8_t
crc_type
);
int32_t
threegpp_nr_ldpc_decode_getq
(
session_t
fd
,
uint8_t
*
decoded_bytes
,
uint8_t
r
,
uint8_t
crc_type
,
uint8_t
*
crc_status
,
uint8_t
*
nb_iterations
);
int32_t
threegpp_nr_ldpc_decode_stop
(
session_t
fd
);
int32_t
threegpp_nr_ldpc_decode_run
(
session_t
fd
);
/*!
\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 16-bit
LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU)
@param y LLR input (16-bit precision)
@param decoded_bytes Pointer to decoded output
@param n number of coded bits (including tail bits)
@param max_iterations The maximum number of iterations to perform
@param interleaver_f1 F1 generator
@param interleaver_f2 F2 generator
@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8)
@param F Number of filler bits at start of packet
@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0)
*/
uint8_t
phy_threegppnr_ldpc_decoder_offload
(
int16_t
*
y
,
uint8_t
*
decoded_bytes
,
uint16_t
n
,
uint16_t
interleaver_f1
,
uint16_t
interleaver_f2
,
uint8_t
max_iterations
,
uint8_t
crc_type
,
uint8_t
F
,
time_stats_t
*
init_stats
,
time_stats_t
*
alpha_stats
,
time_stats_t
*
beta_stats
,
time_stats_t
*
gamma_stats
,
time_stats_t
*
ext_stats
,
time_stats_t
*
intl1_stats
,
time_stats_t
*
intl2_stats
);
uint8_t
phy_threegppnr_ldpc_decoder_offload_init
(
void
);
uint8_t
phy_threegppnr_ldpc_decoder_offload_fini
(
void
);
#endif // __LDPC_DECODER_OFFLOAD_LIB_H__
targets/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload.so
0 → 100644
View file @
1036f0ed
File added
targets/ARCH/LDPC_OFFLOAD/slib/libldpc_decoder_offload415.so.1.2.0
0 → 100644
View file @
1036f0ed
File added
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