Compare commits

...

593 Commits

Author SHA1 Message Date
Flavien RJ
e3b4330e58 Fix LatSeq merge conflict with remote oai-eurecom 2022-09-20 08:31:24 +02:00
Flavien RJ
caee2d8279 latseq : fix patch 2022.w20 2022-09-15 11:58:46 +02:00
Flavien RJ
f2285cce40 Apply latseq patch 2022.w20 2022-09-15 09:18:27 +02:00
Flavien RJ
0ae4644f61 Merge branch 'latseq' into HEAD 2022-09-15 09:14:19 +02:00
laurent
fda7cf2121 merge develop 2022-06-30 16:26:51 +02:00
laurent
f1ffde5395 Merge branch 'develop' of https://gitlab.eurecom.fr/oai/openairinterface5g into latseq 2022-06-30 15:36:49 +02:00
Robert Schmidt
6d030ea2fa Merge branch 'integration_2022_wk25' into 'develop'
integration_2022_wk25

See merge request oai/openairinterface5g!1596

MR !1549: Remove ssb subcarrier offset from config file
MR !1589: Putting all CM code in one file
MR !1592: Support Fedora 36
MR !1492: Harmonization of PUCCH Resources
MR !1581: F1: Interoperability with Accelleran CU
MR !1599: nr rlc: minor: update tests
2022-06-26 15:56:56 +00:00
luis_pereira87
a9faf533b4 Fix SA with COTS UE in monolithic mode after merge 2022-06-24 14:51:38 +01:00
Robert Schmidt
0e04fba03d Fix build warnings 2022-06-23 16:18:50 +02:00
Robert Schmidt
5cebe354c5 Merge remote-tracking branch 'origin/bugfix-minor-update-nr-rlc-tests' into integration_2022_wk25 2022-06-23 14:14:37 +02:00
Robert Schmidt
b37050ac6e Merge remote-tracking branch 'origin/F1_interop_ACC_n78' into integration_2022_wk25 2022-06-23 14:09:33 +02:00
Robert Schmidt
304c92c639 Fixes in conversions.h 2022-06-23 13:51:36 +02:00
Cedric Roux
4505e780c5 nr rlc: minor: update tests
Behavior for ack/nack generation has changed not too long ago but the tests
were not checked and updated.
2022-06-23 11:44:01 +02:00
Robert Schmidt
644422ebec Merge remote-tracking branch 'origin/NR_PUCCH_RRC_Resources' into integration_2022_wk25 2022-06-22 17:20:38 +02:00
Robert Schmidt
f6fe86c653 Fix macros to avoid warnings 2022-06-21 19:24:49 +02:00
Robert Schmidt
fe7228daee Merge remote-tracking branch 'origin/support-fedora36' into integration_2022_wk25 2022-06-21 19:11:17 +02:00
Robert Schmidt
2c226b08f4 Merge remote-tracking branch 'origin/episys-channel-model-org' into integration_2022_wk25 2022-06-21 19:11:00 +02:00
Cedric Roux
2802418c34 remove debug printf 2022-06-21 16:43:54 +02:00
francescomani
2659dce8b8 removing flag init_UL_tti_req_ahead 2022-06-21 13:49:31 +02:00
Robert Schmidt
9c02189e64 Remove nr_bler_data from physims 2022-06-21 08:54:41 +02:00
Cedric Roux
d0fa56b1de compilation fix 2022-06-20 15:15:11 +02:00
Robert Schmidt
0fe98c25a2 Avoid RHEL_RELEASE_VERSION: not defined in Ubuntu 2022-06-20 13:34:54 +02:00
francescomani
a4e2c2b799 addressing review 2022-06-20 11:58:06 +02:00
Robert Schmidt
2124e43d3a Correctly use RHEL_RELEASE_CODE for Fedora and RHEL
This reverts commit 4f44a1026b.
2022-06-20 11:33:29 +02:00
francescomani
fb6fa64bc7 Merge remote-tracking branch 'origin/develop' into NR_remove_ssb_offset_from_configfile 2022-06-20 09:33:50 +02:00
Cedric Roux
5cd674483b Merge remote-tracking branch 'origin/develop' into F1_interop_ACC_n78 2022-06-19 18:41:27 +02:00
Cedric Roux
2bed0352fd f1: remove hardcoded value, set to what is in develop 2022-06-19 18:33:57 +02:00
Robert Schmidt
4f44a1026b Remove RHEL_RELEASE_CODE define 2022-06-19 18:02:08 +02:00
Robert Schmidt
dab905519b Remove nscd from additional packages
nscd (Name service cache daemon) is not needed for running OAI
2022-06-19 18:02:08 +02:00
Robert Schmidt
2b38c78588 Add fedora36 to supported distros 2022-06-19 18:02:08 +02:00
Robert Schmidt
12a23fb1ef Merge branch 'integration_2022_wk24' into 'develop'
integration_2022_wk24

See merge request oai/openairinterface5g!1591

MR !1382: Semi-automatic code generator for LDPC decoder for AVX2 and AVX512
MR !1521: 5G NR performance improvements for low SNR conditions
MR !1579: pthread_create, RT scheduler, and address sanitizer are incompatible in Ubuntu 18.04
MR !1588: small fix in csi configuration
MR !1583: Encoding/decoding CellGroup at MAC and fix RA with Msg3 carrying DCCH or DTCH messages
2022-06-18 13:57:58 +00:00
Robert Schmidt
ee71b0dd9b Lower error threshold for low SNR test in dlsim 2022-06-17 19:04:08 +02:00
luis_pereira87
78267db68b Revert "Update downlink MCS table" block of code to function nr_set_pdsch_semi_static to get downlink working again in NSA 2022-06-17 16:17:15 +01:00
Robert Schmidt
0c0d88b201 Better formatting for Consolidated Test Results 2022-06-17 12:17:54 +02:00
Robert Schmidt
7194a720c9 Increase 'low SNR' test's upper SNR threshold 2022-06-17 12:16:12 +02:00
Robert Schmidt
9ff4630071 Merge remote-tracking branch 'origin/NR_RRC_MAC_CellGroup' into integration_2022_wk24 2022-06-17 12:11:37 +02:00
luis_pereira87
9e27394ecc Reset feedback_slot and round values when resetting HARQ processes 2022-06-17 10:35:01 +01:00
Robert Schmidt
2399da33cb Merge remote-tracking branch 'origin/csi-multi-ues-fix' into integration_2022_wk24 2022-06-16 22:26:00 +02:00
Robert Schmidt
348ff98762 Merge remote-tracking branch 'origin/ubuntu_18_rt_add_san_incompatibility' into integration_2022_wk24 2022-06-16 22:25:46 +02:00
Robert Schmidt
032d477481 Merge remote-tracking branch 'origin/5g-nr-low-snr-performance' into integration_2022_wk24 2022-06-16 22:25:38 +02:00
Laurent Thomas
a73e500ded Add a warning for ubuntu 18.04 in build_oai 2022-06-16 21:42:46 +02:00
Melissa Elkadi
7b75305e3c pthread_create, RT scheduler, and address sanitizer are incompatible in Ubuntu 18.04
When we run with the RT scheduler and the address sanitizer in Ubuntu
18.04, pthread_create will hang and never create threads.  This adds
some explanatory text in CMakeLists.txt to explain about this issue.
2022-06-16 21:42:26 +02:00
Robert Schmidt
5761164a09 Build without AVX512 on asterix machine 2022-06-16 14:25:18 +02:00
Roberto Louro Magueta
4053c0c3b2 Revert log2_maxh in pusch_vars 2022-06-15 19:54:12 +01:00
luis_pereira87
cc33856ba8 Reset HARQ processes after RA when Msg3 carries a DCCH or DTCH message.
Reset ul_failure flag only after sending Msg4 otherwise gNB starts scheduling too early
2022-06-15 17:24:47 +01:00
Roberto Louro Magueta
14d3a9c0e5 Fixes after merge 2022-06-15 12:53:36 +01:00
Robert Schmidt
e62119bea5 Reintroduce nr_ulsim -I option after wrong merge 2022-06-15 13:53:22 +02:00
Roberto Louro Magueta
7f21567f83 Merge remote-tracking branch 'origin/develop' into 5g-nr-low-snr-performance
# Conflicts:
#	cmake_targets/autotests/test_case_list.xml
#	openair1/SIMULATION/NR_PHY/dlsim.c
#	openair1/SIMULATION/NR_PHY/ulsim.c
2022-06-15 11:17:06 +01:00
Cedric Roux
2521e46593 Merge remote-tracking branch 'origin/F1C_extensions_develop' into F1_interop_ACC_n78
Conflicts:
	openair2/F1AP/f1ap_du_interface_management.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
	openair2/LAYER2/NR_MAC_gNB/main.c
	openair2/RRC/NR/MESSAGES/asn1_msg.c
	openair2/RRC/NR/MESSAGES/asn1_msg.h
	openair2/RRC/NR/rrc_gNB.c
	openair3/ocp-gtpu/gtp_itf.cpp
2022-06-15 11:28:37 +02:00
luis_pereira87
527003492d Revert call to process_CellGroup function in rrc_mac_config_req_gNB to fix F1 user plane working 2022-06-15 09:34:55 +01:00
Robert Schmidt
d835f3387d Build without AVX512 on caracal to avoid compilation fail 2022-06-15 08:49:10 +02:00
Melissa Elkadi
630f8ac2b1 Putting all CM code in one file
This commit includes reorganization of
all of the SISO/MIMO channel modelling
support being moved into a single CM
file. Furthermore, it includes a bug
fix for the number of MCS simulation
tables (29 total, 0-28).
2022-06-14 12:52:01 -07:00
Karim Boutiba
079ad360e0 solve the conflict between cri-RSRP and cri-RI-PMI-CQI in the case of multiple UEs 2022-06-14 13:38:12 +00:00
Robert Schmidt
bb15360a55 Revert "CI: phySim container build: add SYS_PTRACE"
This reverts commit 0122749406.
2022-06-14 12:35:48 +02:00
Robert Schmidt
0a74c23c8a Disable Asan in LDPC decoder generator executables
The CI compiles the physims using Asan. This in turn compiles Asan into
the LDPC decoder generator files. Since they are run during build, there
are two options:

1) trigger the build using capability SYS_PTRACE to allow running asan
   when executing the generators.
2) disable asan in the generators.

The first option seems not feasible, as the compilation of the ldpctest
does not succeed (in fact, for a reason I don't understand, ninja seems
to trigger linking and is then blocked indefinitely). Therefore, this
commit simple disables asan in the generators.
2022-06-14 12:30:12 +02:00
luis_pereira87
ed74875025 Call rrc_mac_config_req_gNB function only when running nr-softmodem as a DU or in monolithic mode 2022-06-14 11:29:56 +01:00
luis_pereira87
7cee46777f Cosmetic changes 2022-06-13 23:20:37 +01:00
Cedric Roux
33b69bdf30 nr rlc: bugfix: use hard-coded mapping between drb ID and mac lcid
This will probably impact negatively the Accelleran interoperability
but the previous version is not correct and breaks the oai nr ue.

To be checked in a CU/DU scenario with Accelleran.
2022-06-13 18:28:07 +02:00
Cedric Roux
1ad8f254c2 Merge remote-tracking branch 'origin/develop' into F1_interop_ACC_n78 2022-06-13 16:59:59 +02:00
francescomani
045de837ab Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-06-13 10:25:05 +02:00
Raymond Knopp
a119e84f92 Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen 2022-06-13 09:44:51 +02:00
luis_pereira87
983760e9a4 Fix after merge with develop 2022-06-13 08:21:05 +01:00
luis_pereira87
131db89dfc Merge remote-tracking branch 'origin/develop' into NR_RRC_MAC_CellGroup
# Conflicts:
#	openair1/PHY/INIT/nr_init.c
#	openair2/LAYER2/NR_MAC_gNB/config.c
2022-06-13 08:19:39 +01:00
Robert Schmidt
5944b212b2 Merge branch 'integration_2022_wk23' into 'develop'
integration_2022_wk23

See merge request oai/openairinterface5g!1585

MR !1558: Add 5G SA end-to-end, step-by-step, tutorials for OAI CN5G, OAI gNB and COTS UE
MR !1578: Adding required LOG_As for EpiSci CI testing. (Proxy)
MR !1575: Fix msg3 retransmissions with OAI UE
MR !1577: Fix ULSCH timing measurements in RAN-gNB-nrUE-MONO-TDD-Band78-N300 and logging improvements
MR !1544: NR CORESET harmonization
MR !1287: PUSCH performance improvement
MR !1580: Aligning some internal memory to avoid segfaults
2022-06-13 07:02:11 +00:00
Raymond Knopp
7387721ecf Merge branch 'ldpc-decoder-codegen' of https://gitlab.eurecom.fr/oai/openairinterface5g into ldpc-decoder-codegen 2022-06-12 23:24:11 +02:00
Raymond Knopp
f6bb869c0b fixed AVX2 issue for cnProc code generator. Some cleanup in formatting and deleting unused files. 2022-06-12 23:23:07 +02:00
Robert Schmidt
169f42a365 Prevent #define name clash
The files openair1/PHY/CODING/nrLDPC_cnProc.h and
openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h have the same name,
and also the same include guard/define. This commit renames the define
in the latter to prevent this name clash.
2022-06-12 16:32:46 +02:00
Robert Schmidt
6900f2bc88 Add License to LDPC decoder generator files 2022-06-12 16:29:49 +02:00
luis_pereira87
e850a8ece7 Fix initial connection setup when there is Msg4 retransmissions and UE comes with a new RA with Msg3 carrying DCCH or DTCH message 2022-06-10 23:18:18 +01:00
Robert Schmidt
aabd9c6c4e nr_ulsim: Change thread-count command-line option to -C 2022-06-10 15:45:32 +02:00
Robert Schmidt
b69fa39577 Merge remote-tracking branch 'origin/alignment_fixes' into integration_2022_wk23 2022-06-10 13:52:50 +02:00
Robert Schmidt
b193ccf6ee Merge remote-tracking branch 'origin/develop' into 5g-nr-low-snr-performance 2022-06-10 13:50:47 +02:00
Robert Schmidt
0122749406 CI: phySim container build: add SYS_PTRACE
Physical simulators are built using address sanitizer. During the build
process, we use generators that are themselves built during the build
process. They are also asan, and we therefore need to give the
SYS_PTRACE capability during the build process to have them run
correctly.
2022-06-10 13:37:30 +02:00
Robert Schmidt
ae23942020 Compile container images without AVX512 for relocatability 2022-06-10 13:37:30 +02:00
Robert Schmidt
dc4f610245 Merge remote-tracking branch 'origin/ulsim-perf-testing' into integration_2022_wk23 2022-06-09 17:47:57 +02:00
Robert Schmidt
3793edf686 Merge remote-tracking branch 'origin/NR_coreset_harmonization' into integration_2022_wk23 2022-06-09 17:47:37 +02:00
Robert Schmidt
4b0d4e38c4 Merge remote-tracking branch 'origin/fix-test-caracal' into integration_2022_wk23 2022-06-09 17:46:54 +02:00
Robert Schmidt
28ad0eaacb Merge remote-tracking branch 'origin/NR_fix_msg3_rtx' into integration_2022_wk23 2022-06-09 17:46:45 +02:00
Robert Schmidt
9127577bf3 Merge remote-tracking branch 'origin/fixing_removed_LOG_As' into integration_2022_wk23 2022-06-09 17:46:36 +02:00
Robert Schmidt
2e6fea604d Merge remote-tracking branch 'origin/NR_SA_tutorials' into integration_2022_wk23 2022-06-09 17:46:27 +02:00
Sakthivel Velumani
f95c636a6b Improved help for ulsim 2022-06-09 20:07:23 +05:30
Robert Schmidt
f7ab71763d Remove old way of generating LDPC decoders 2022-06-09 15:03:13 +02:00
Robert Schmidt
dde6d61dd4 Dynamically create LDPC decoder headers when building ldpc libs 2022-06-09 15:03:13 +02:00
Robert Schmidt
7b68c48618 Make LDPC generator output directory prefix configurable 2022-06-09 15:03:13 +02:00
Robert Schmidt
250043655a Remove some variables from LDPC generated code to avoid warnings 2022-06-09 15:03:13 +02:00
Laurent THOMAS
97b3d1a5cd fix mutex not initialised in ul decoder 2022-06-09 15:03:13 +02:00
francescomani
8adcf8368a reverting activation of timer at transmission 2022-06-09 14:48:42 +02:00
francescomani
f5e9c4ec36 applying Robert's patch 2022-06-09 13:26:04 +02:00
luis_pereira87
e7a491415c Improvements on RRC passing CellGroup to MAC to get COTS UE working 2022-06-09 10:08:28 +01:00
francescomani
0aec0d91c6 temporary workaround for RRC passing CG to MAC (forced encoding of message at MAC) 2022-06-09 09:35:42 +01:00
Robert Schmidt
894c45eae5 Add comment to fix fill_mastercellGroupConfig() 2022-06-09 10:20:39 +02:00
Laurent THOMAS
e3747ea06b Fix small bugs in nrLDPC_tools, remain some warnings to fix 2022-06-09 10:01:45 +02:00
Robert Schmidt
aed83c91de Create header for LDPC bnProc BG2 files 2022-06-09 09:25:57 +02:00
Robert Schmidt
12c0f52fea Merge remote-tracking branch 'origin/develop' into F1_interop_ACC_n78 2022-06-08 19:45:17 +02:00
Sakthivel Velumani
0d9e548f39 Minor fixes in ulsim and dlsim 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
80ad5df367 Removed unused 256QAM table option 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
933ad3dcf4 Removed duplicate definition and other errors
left during rebase
2022-06-08 21:32:07 +05:30
Sakthivel Velumani
8a8bacead9 Set default cmd values in UE
It looked like the default command line option were not set in case the options were not passed. The right function was not called.
2022-06-08 21:32:07 +05:30
Sakthivel Velumani
e8d91d642e fixed nr_dlsim -q parameter bug 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
0cea80c8fa changing PUSCH dmrs symbol pos to 0 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
1afdc298e9 Interpolation chest default in UE 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
7c47420da7 Making interpolation ch estimation as default 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
b2b84caeb5 Made PRB averaging channel est as default
fixed indendation
updated ulsim CI test parameters
2022-06-08 21:32:07 +05:30
Sakthivel Velumani
93e6bd26da Made channel estimation techniques configurable 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
0960aa3d00 Updating ulsim CI test parameters 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
ab899c3a08 fix CI test parameters 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
da8d3037df fixed bugs in phy sims 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
8f79ae0ea7 A bug fix in DMRS averaging 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
689ecf5ae1 Enable additional DMRS symbol in UL 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
e36a2b483a Added 3GPP TS 38104 8.2.1.2-13 16QAM CI test cases 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
1d99c8e695 LDPC iterations as command line parameter 2022-06-08 21:32:07 +05:30
Sakthivel Velumani
b29f92c1d6 Add MCS table option to ulsim 2022-06-08 21:31:17 +05:30
Sakthivel Velumani
36190b1c7d Logging changes to ulsim 2022-06-08 21:31:17 +05:30
Sakthivel Velumani
ac58460b6e Time averaging PUSCH channel estimates 2022-06-08 21:31:17 +05:30
Sakthivel Velumani
382b2c41e3 Fixed ulsim to test 8 Rx antennas 2022-06-08 21:31:17 +05:30
Robert Schmidt
2d3f4f7310 Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen 2022-06-08 17:17:11 +02:00
Robert Schmidt
9eccd6c11d Correct caracal IP address 2022-06-08 17:06:47 +02:00
francescomani
85b48193d4 fix msg3 retransmissions with OAI UE 2022-06-08 16:45:30 +02:00
Cedric Roux
f71766c3ee Merge remote-tracking branch 'origin/develop' into F1_interop_ACC_n78
Conflicts:
	openair2/F1AP/f1ap_du_ue_context_management.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
	openair2/RRC/NR/MESSAGES/asn1_msg.h
	openair2/RRC/NR/rrc_gNB.c
	openair3/ocp-gtpu/gtp_itf.cpp

There were some important conflicts in openair3/ocp-gtpu/gtp_itf.cpp
I rewrote a bit the function Gtpv1uHandleGpdu(). It might have been
done wrongly.
To be tested and fixed if needed.

To redo the merge, if needed:
git checkout 9b2a163ebb
git merge 5ea828e149
2022-06-08 15:48:24 +02:00
francescomani
e24edde2fd remove commented code 2022-06-08 15:09:53 +02:00
francescomani
bc1227f9a0 Merge remote-tracking branch 'origin/develop' into NR_remove_ssb_offset_from_configfile 2022-06-08 14:52:47 +02:00
francescomani
539e5e89f3 Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-06-08 14:45:33 +02:00
francescomani
4ffef42472 Merge remote-tracking branch 'origin/develop' into NR_coreset_harmonization 2022-06-08 13:39:39 +02:00
Florian Kaltenberger
bb17287089 aligning some internal memory to avoid segfaults 2022-06-08 12:09:07 +02:00
Robert Schmidt
d7dae8fa91 Merge branch 'integration_2022_wk22' into 'develop'
integration_2022_wk22

See merge request oai/openairinterface5g!1576

MR !1501 fixes to support multiple pdu sessions (tested with 2 pdu sessions)
MR !1566 issue 545
MR !1569 bugfix in fill_searchSpaceZero
MR !1574 Repair LTE-M: Add missing parameter preambleTransMax_CE_rel13
MR !1496 PHY procedures at UE for CSI-RS
Increase LTE-2x2 ping thresholds to 60 ms to make tests pass (throughput seems to be fine)
2022-06-08 08:38:10 +00:00
Robert Schmidt
b1d07fb3e0 print_meas_log(): do not write beyond memory end 2022-06-07 17:41:21 +02:00
francescomani
7546b8ca1b fix dlsim compilation 2022-06-06 17:37:40 +02:00
francescomani
0b55910c48 possible fix in type setting of Y for coreset 2022-06-06 16:40:09 +02:00
luis_pereira87
308cae752a Update download link for the latest version of Open Cells SIM card programing tool uicc-v2.6 2022-06-06 14:13:58 +01:00
Robert Schmidt
45522ae86c [CI] Increase LTE-2x2 test ping thresholds to make test pass 2022-06-04 10:10:47 +02:00
Robert Schmidt
5f37ab35b4 Merge remote-tracking branch 'origin/develop-CSI' into integration_2022_wk22 2022-06-04 10:08:38 +02:00
Robert Schmidt
4e34462488 Merge remote-tracking branch 'origin/preambleTransMax_CE_rel13-in-configuration' into integration_2022_wk22 2022-06-04 10:08:31 +02:00
Robert Schmidt
7b3191d1a6 Merge remote-tracking branch 'origin/NR_SS0_config_fix' into integration_2022_wk22 2022-06-04 10:08:25 +02:00
Robert Schmidt
1215444cae Merge remote-tracking branch 'origin/fix-bug-545' into integration_2022_wk22 2022-06-04 10:08:17 +02:00
Robert Schmidt
6e7160ac03 Merge remote-tracking branch 'origin/multiple_pdu_MR' into integration_2022_wk22 2022-06-04 10:08:10 +02:00
Robert Schmidt
bea2ec5c3b Use snprintf() in dump_mac_stats() 2022-06-04 09:33:18 +02:00
Robert Schmidt
f8f20827e9 Rename DL&UL scheduling timing stats 2022-06-04 09:32:00 +02:00
Robert Schmidt
59e10dc8da Clean up MAC stats: don't show timing stats in console log, only file 2022-06-04 09:31:54 +02:00
Robert Schmidt
f2bc364b50 Drop periodic "Number of bad PUCCH" output 2022-06-04 09:29:20 +02:00
Melissa Elkadi
cc2c3b9123 Adding required LOG_As for EpiSci CI testing. (Proxy)
In commit 05c07c401f,
four of the LOG_A logs were demoted. These are required
for the L2 simulator proxy CI testbed.
2022-06-03 16:40:46 -07:00
Robert Schmidt
43701ddbd6 Phy-test scheduler: update MCS so it is shown in logs 2022-06-03 17:11:05 +02:00
Robert Schmidt
dd801325d4 Terminate LOG with newline 2022-06-03 17:10:03 +02:00
Robert Schmidt
db2c03d31d Do not abort ULSCH decoding in phy-test mode
For the RAN-gNB-nrUE-MONO-TDD-Band78-N300 test, in order to measure ULSCH
decoding times, we cannot abort ULSCH decoding on DTX.
2022-06-03 17:06:24 +02:00
Robert Schmidt
d5165ae2bd B210 tutorial: mention USB3 2022-06-03 12:50:44 +02:00
Robert Schmidt
9b317eacef Add instructions on how to tune Ethernet connection 2022-06-03 12:50:44 +02:00
KARIM BOUTIBA
cd4bc84bd8 small fix in nr_sdap_get_entity 2022-06-02 08:05:21 +00:00
francescomani
b96df49e15 postpone initialization of UL_tti_req_ahead to when sl_ahead is available 2022-06-01 17:09:08 +02:00
francescomani
a531342054 update ss and coreset after updating bwp 2022-06-01 12:35:31 +02:00
Roberto Louro Magueta
2c3eb996a4 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
#	openair2/LAYER2/NR_MAC_gNB/config.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
2022-06-01 11:06:49 +01:00
francescomani
9a43678ed0 Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-06-01 09:06:57 +02:00
francescomani
13ed1200b4 Merge remote-tracking branch 'origin/develop' into NR_coreset_harmonization 2022-06-01 08:45:35 +02:00
Robert Schmidt
5ea828e149 Merge branch 'integration_2022_wk21b' into 'develop'
integration_2022_wk21b

See merge request oai/openairinterface5g!1572

MR !1490 add support for 15 kHz SCS
MR !1525 Make USRP tune-offset configurable
MR !1550 remove UEid in MAC
2022-06-01 06:12:20 +00:00
Francesco Mani
426bc2f088 fix in get_ul_tda call for rtx 2022-05-31 09:36:39 +00:00
francescomani
6f7889d162 bugfix in mod_dmrs declaration 2022-05-30 18:02:08 +02:00
Raymond Knopp
83d40a9b7c Add missing parameter preambleTransMax_CE_rel13
To SIB2 and its passing to RRC. Parameter was read but not transfered
before. Basic LTE-M functionality should ok on develop branch with this
fix. Tested with uBlox SARA-R4 (QCOM chipset)
2022-05-30 16:19:35 +02:00
Robert Schmidt
df8f632ae3 Make sched_csirs common to all UEs 2022-05-30 14:52:50 +02:00
Robert Schmidt
23c8336a37 Fix warning 2022-05-30 14:50:55 +02:00
Robert Schmidt
ac9e47ba68 Merge remote-tracking branch 'origin/cleanup-2022-mai-UEid-management' into integration_2022_wk21b 2022-05-30 12:02:58 +02:00
Laurent THOMAS
43033e20b6 Avoid SEGV in nr_decode_pucch0() 2022-05-28 16:44:50 +02:00
Laurent THOMAS
16e8154d71 Handle full UL TTI Req list more gracefully 2022-05-28 16:44:50 +02:00
Laurent THOMAS
9ba33d4dec Correctly format code to avoid warnings/ambiguities 2022-05-28 16:44:49 +02:00
Laurent THOMAS
a51c1f93b5 Remove unused code 2022-05-28 16:37:47 +02:00
Robert Schmidt
b6adb32989 Delete commented code 2022-05-28 16:37:47 +02:00
Laurent THOMAS
236f7d56e5 Remove UEid in the MAC
After this commit, only the RNTI is used as an identifier in the MAC.
Further, it removes some module_id, but a lot of them remain (the goal
to remove all is still far from us)
2022-05-28 16:37:26 +02:00
rmagueta
6bca31c7e3 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
2022-05-27 10:18:13 +01:00
francescomani
92ba8cb9d0 Merge remote-tracking branch 'origin/develop' into NR_coreset_harmonization 2022-05-27 10:46:15 +02:00
Robert Schmidt
daad3da6eb Merge remote-tracking branch 'origin/usrp-tune-offset' into integration_2022_wk21b 2022-05-27 10:06:20 +02:00
Robert Schmidt
21a820b061 Merge remote-tracking branch 'origin/support-15-kHz-SCS' into integration_2022_wk21b 2022-05-27 10:05:57 +02:00
Robert Schmidt
72d0a4ff05 Merge branch 'integration_2022_wk21' into 'develop'
integration_2022_wk21

See merge request oai/openairinterface5g!1564
2022-05-27 07:49:38 +00:00
francescomani
9228f12d92 bugfix 2022-05-26 13:47:17 +02:00
francescomani
09ecb8a33c bugfix in fill_searchSpaceZero 2022-05-25 10:35:26 +02:00
Robert Schmidt
36a02913de Merge remote-tracking branch 'origin/usrp_x400_fixup' into integration_2022_wk21 2022-05-24 17:58:47 +02:00
Robert Schmidt
360d4b3a81 Merge remote-tracking branch 'origin/k2-slot0-fix' into integration_2022_wk21 2022-05-24 17:57:58 +02:00
Robert Schmidt
103e21a05c Merge remote-tracking branch 'origin/NR_removing_calculate_preferred_tda' into integration_2022_wk21 2022-05-24 17:56:38 +02:00
francescomani
cf7c2fd373 commenting out further call to decode sib1 after initial access 2022-05-24 15:10:53 +02:00
Roberto Louro Magueta
ab1df8bbc4 Revert CSI configuration from update_cellGroupConfig to fill_initial_SpCellConfig 2022-05-24 13:45:35 +01:00
laurent
1450e2fb9f issue 545 2022-05-24 13:29:05 +02:00
Florian Kaltenberger
38f7d772e6 small fix for USRP X410 2022-05-24 10:55:50 +02:00
francescomani
3c753aec71 fix in calling get_ul_tda 2022-05-23 18:41:10 +02:00
Robert Schmidt
3b28264374 Merge remote-tracking branch 'origin/fix-ra-on-frame-1023' into integration_2022_wk21 2022-05-23 17:18:39 +02:00
Robert Schmidt
ba73075ccd Merge remote-tracking branch 'origin/ul-dl-bler' into integration_2022_wk21 2022-05-23 17:17:47 +02:00
francescomani
3a0bccde30 fix for msg2 tda 2022-05-23 16:13:20 +02:00
francescomani
fac44b15e8 adding option for CSI slot 2022-05-23 16:13:20 +02:00
francescomani
25086576e5 simplyfying tda functions according to review 2022-05-23 16:07:10 +02:00
francescomani
c6498ccf58 addressing review 2022-05-23 16:07:10 +02:00
francescomani
d3f90a90fe removing calculate_preferred_ul_tda 2022-05-23 15:57:27 +02:00
francescomani
276b2d5e0c removing calculate_preferred_dl_tda 2022-05-23 15:48:29 +02:00
Robert Schmidt
e1b090cfaa Improve logging 2022-05-23 15:20:03 +02:00
Robert Schmidt
9f6b7dc6b9 Make USRP tune_offset configurable
UHD documentation: "A tune request instructs the implementation how to
tune the RF chain."

This commit makes this configurable, from nr-softmodem, nr-uesoftmodem,
lte-softmodem, and lte-uesoftmodem.
2022-05-23 15:20:03 +02:00
Robert Schmidt
9354d4305b Set k2=2 also in 5ms TDD periods
In the past, setting k2=2 for 5ms TDD periods resulted in increased ping
RTT and/or reestablishment requests. These problems do not appear
anymore, and we can allow k2=2.
2022-05-23 15:11:27 +02:00
Robert Schmidt
00d021c66b In TDD: enable slot 0
In the past, activation of slot 0 (i.e., after the switch UL->DL)
resulted in many retransmissions. This does not seem to be the case
anymore, and we can therefore activate slot 0 also in TDD.
2022-05-23 14:33:08 +02:00
francescomani
2ba71e748d using bwp id to configure coreset id 2022-05-23 13:39:56 +02:00
francescomani
a724c1febc starting timer for msg4 at transmission 2022-05-20 15:09:25 +02:00
francescomani
fcfc7a90e8 fix for asan assertion 2022-05-20 13:56:12 +02:00
Robert Schmidt
7bf5f018a1 Refactor DRB configuration in function 2022-05-19 18:40:54 +02:00
Robert Schmidt
a5d0615048 Harmonize SRB configuration in function 2022-05-19 18:28:55 +02:00
KARIM BOUTIBA
b46077c22d add multiple pdu session support (tested with 2 pdu sessions) 2022-05-19 18:28:55 +02:00
francescomani
9150dc8c50 applying review comment 2022-05-19 14:48:45 +02:00
Roberto Louro Magueta
3d5cfb6642 Update the spatialRelationInfoToAddModList for dedicated UL-BWPs 2022-05-18 17:00:05 +01:00
francescomani
d56f2c8e12 addressing review comments 2022-05-18 17:36:32 +02:00
francescomani
6d736db22d applying PUCCH harmonization to multiple BWP 2022-05-18 17:23:55 +02:00
Roberto Louro Magueta
436eb2d5a9 Fix PUCCH config in fill_default_uplinkBWP to consider the enabled CSI-RS 2022-05-18 16:05:38 +01:00
Robert Schmidt
3ca4cb708c Select UL MCS from BLER 2022-05-18 16:44:54 +02:00
Robert Schmidt
34b821433b Add UL BLER options and read from config 2022-05-18 16:44:54 +02:00
Robert Schmidt
17cbc4dbf4 Generalize get_mcs_from_bler() 2022-05-18 16:44:54 +02:00
Robert Schmidt
26c2c0add8 MAC stats: group UL&DL common stats 2022-05-18 16:44:54 +02:00
Robert Schmidt
61d434339e DL MCS: switch back to 9 on inactivity 2022-05-18 16:44:54 +02:00
Robert Schmidt
1fbf968676 Set DL MCS when receiving CQI report
- Introduce generic get_mcs_from_cqi() that gets MCS for a particular
  CQI
- Set MCS after receiving CQI
- Distinguish "global" max MCS from UE-measured max MCS
2022-05-18 16:44:53 +02:00
Roberto Louro Magueta
2d96262d7c Fix channel estimation based on CSI-RS 2022-05-18 14:31:13 +01:00
francescomani
0c5d6a59e7 Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-05-18 15:19:00 +02:00
Roberto Louro Magueta
e5c4e0f3d3 Address review comments 2022-05-18 12:59:24 +01:00
Roberto Louro Magueta
f94a479829 Fix warning after merge 2022-05-18 12:51:18 +01:00
francescomani
03e869ee36 applying harmonization function also to multiple BWP option 2022-05-18 11:54:15 +02:00
francescomani
1e4f509805 Merge remote-tracking branch 'origin/develop' into NR_coreset_harmonization 2022-05-18 11:41:07 +02:00
Thomas Schlichter
e639e79220 Merge remote-tracking branch 'origin/develop' into support-15-kHz-SCS 2022-05-18 10:51:19 +02:00
francescomani
085014f601 Merge remote-tracking branch 'origin/develop' into NR_remove_ssb_offset_from_configfile 2022-05-18 10:25:47 +02:00
Thomas Schlichter
3934f2020e slightly increase the target SNR for the nr_dlsim low SNR test to make the test more reliable 2022-05-18 09:54:59 +02:00
Thomas Schlichter
6f8b13c2ad fix nr_ulsim option "-i" has no further parameters 2022-05-18 09:50:37 +02:00
Thomas Schlichter
c97d5d04ed fixes from review 2022-05-18 09:35:01 +02:00
francescomani
1f49b73eac Merge remote-tracking branch 'origin/develop' into NR_dl_ul_fapi_improv 2022-05-18 08:55:40 +02:00
Roberto Louro Magueta
8ac68929bc Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/defs_nr_common.h
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/rrc_gNB_reconfig.c
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
2022-05-17 19:13:38 +01:00
Thomas Schlichter
44a98a85c5 Merge remote-tracking branch 'origin/develop' into 5g-nr-low-snr-performance 2022-05-17 17:38:59 +02:00
luis_pereira87
bdc4a664ac Add 5G SA end-to-end, step-by-step, tutorials for OAI CN5G, OAI gNB and COTS UE 2022-05-16 11:49:42 +01:00
laurent
a254545b7c fix ra bug 2022-05-16 09:31:29 +02:00
francescomani
c4c93cc498 Merge remote-tracking branch 'origin/develop' into NR_dl_ul_fapi_improv 2022-05-12 08:56:45 +02:00
Roberto Louro Magueta
5c754f2300 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
2022-05-11 14:19:33 +01:00
Robert Schmidt
68be6f83e6 randominit(): show used seed when using time() 2022-05-10 14:22:50 +02:00
francescomani
c7e8002d8d adding CI test with subcarrier offset in pbchsim 2022-05-10 11:43:44 +02:00
francescomani
3b16547374 fix in pbchsim 2022-05-10 09:13:52 +02:00
francescomani
a037987b47 remove ssb subcarrier offset from config file 2022-05-09 18:28:56 +02:00
francescomani
59ced82104 Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-05-06 17:02:22 +02:00
Roberto Louro Magueta
87e79e5eb8 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/LAYER2/NR_MAC_gNB/config.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/rrc_gNB_reconfig.c
#	targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
2022-05-06 11:32:36 +01:00
francescomani
2bbfe501c2 Merge remote-tracking branch 'origin/develop' into NR_coreset_harmonization 2022-05-06 12:02:00 +02:00
francescomani
1750f45708 additional fix for dmrs 2022-05-06 11:46:07 +02:00
francescomani
acc6fb8508 fixes for multi-symbol pdcch 2022-05-06 11:17:19 +02:00
francescomani
edea5c5f65 some more fixes for larger coresets 2022-05-05 17:23:12 +02:00
francescomani
40fcfdea8b additional fixes 2022-05-04 18:20:12 +02:00
francescomani
4045874d74 memory fixes 2022-05-04 16:56:23 +02:00
francescomani
999f5d67e3 bugfixes and improvements in handling dci candidates 2022-05-04 11:03:26 +02:00
Raymond Knopp
bf5389936d added deletion/creation of ldpc_gen_files directory and subdirectories 2022-05-03 22:09:46 +02:00
Raymond Knopp
3ecfead572 added script to generate ldpc decoder files 2022-05-03 22:03:19 +02:00
Raymond Knopp
63b28d3610 clean up (removal) of ldpc generated files on repository 2022-05-03 21:26:18 +02:00
Raymond Knopp
8506307ef0 Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen
Conflicts:
	cmake_targets/build_oai
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h
	openair1/PHY/NR_REFSIG/ptrs_nr.c
2022-05-02 22:41:48 +02:00
rmagueta
4b3aa7233e Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
2022-04-30 15:14:20 +01:00
Thomas Schlichter
7815293443 Merge remote-tracking branch 'origin/develop' into support-15-kHz-SCS 2022-04-29 10:15:15 +02:00
francescomani
b6016cfc49 Merge remote-tracking branch 'origin/develop' into NR_dl_ul_fapi_improv 2022-04-28 14:12:11 +02:00
francescomani
f902e27c43 updates on coreset harmonization 2022-04-27 16:24:05 +02:00
Thomas Schlichter
795c057d8c nr_dlsim: fix low-SNR performance by using DCI aggregation level 8 2022-04-19 11:32:47 +02:00
rmagueta
6b873e0f41 Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-04-18 10:26:46 +01:00
francescomani
a71552d55d harmonization of coreset configuration 2022-04-15 19:21:34 +02:00
matzakos
9b2a163ebb Add true reporting of RLC buffer availability in first DDD report from DU to CU 2022-04-15 10:36:31 +02:00
matzakos
3feb0f472f Add more proper parsing of NR-RAN gtp-u extension header 2022-04-15 10:35:39 +02:00
matzakos
b216c58526 Remove xml prints of F1AP messages 2022-04-15 10:34:53 +02:00
Raymond Knopp
e721f6af04 Merge remote-tracking branch 'origin/tdd25period_for_MR' into F1_interop_ACC_n78
Conflicts:
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
2022-04-14 11:14:36 +02:00
matzakos
f9e5c987a6 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-04-13 14:22:19 +02:00
matzakos
0c05e283e2 Remove warnings and unused code 2022-04-13 13:19:04 +02:00
rmagueta
a81640a6df Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/INIT/nr_init_ue.c
#	openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
#	openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
2022-04-13 10:21:09 +01:00
francescomani
cfda6c7b1d renaming SR config function 2022-04-13 10:58:28 +02:00
rmagueta
d6072cb5d2 Fix build after merge 2022-04-12 14:31:39 +01:00
rmagueta
d5421a9c87 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/INIT/nr_init.c
#	openair1/PHY/NR_REFSIG/nr_refsig.h
#	openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
#	openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
#	openair1/SCHED_NR/phy_procedures_nr_gNB.c
#	openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.h
2022-04-12 14:02:43 +01:00
francescomani
e6913e5d33 Merge remote-tracking branch 'origin/develop' into NR_dl_ul_fapi_improv 2022-04-12 10:41:20 +02:00
francescomani
11ced194cd Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-04-12 10:28:32 +02:00
Thomas Schlichter
94e5aaff88 Merge remote-tracking branch 'origin/develop' into 5g-nr-low-snr-performance 2022-04-12 09:51:47 +02:00
matzakos
47c9ded007 Use higher data type to store the length of UE capability RAT container 2022-04-11 19:53:36 +02:00
matzakos
bfc7c1b361 Remove bad return before unlocking mutex in pdcp UL indication 2022-04-11 19:35:05 +02:00
rmagueta
8c056ceefc Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-04-08 18:19:06 +01:00
Raymond Knopp
5962824038 Integrate true reporting of buffer availability of RLC(DU) towards the CU 2022-04-07 16:34:16 +02:00
Thomas Schlichter
4035bdb71d add autotest test case for nr_dlsim low SNR performance
performance is ~1.0dB worse than nr_ulsim because of unexpected bad PDCCH performance...
2022-04-07 12:20:33 +02:00
Thomas Schlichter
298740b06c add autotest test case for nr_ulsim low SNR performance 2022-04-07 12:12:20 +02:00
Thomas Schlichter
c7055b2cf9 nr_ulsim: set PUSCH detection threshold to -2.0 dB SNR 2022-04-07 12:08:26 +02:00
Thomas Schlichter
23bdf1e32c remove unused perfect_ce 2022-04-07 11:45:26 +02:00
Thomas Schlichter
dd374c7e03 add more detailed statistics to nr_dlsim output 2022-04-07 11:45:26 +02:00
Bo Zhao
7f074bcc22 Implement PDCCH channel estimation averaging over PRB (no interpolation) 2022-04-07 10:42:03 +02:00
Bo Zhao
fe7ee4d2fe Scaling LLR for different QAM schemes 2022-04-07 10:40:53 +02:00
Thomas Schlichter
e297ccfa26 Add nr_prachsim test case for 15 kHz SCS 2022-04-07 10:34:37 +02:00
rmagueta
4f29c73bb6 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair2/LAYER2/NR_MAC_gNB/config.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
2022-04-06 10:11:49 +01:00
matzakos
693d687d3f Restore nr_l1_helpers.h and dependencies 2022-04-06 10:57:36 +02:00
matzakos
0eb2acb00b F1 code cleanup before merge
-Remove commented out code, debug logs, some hardcodings, fix indentation
2022-04-06 10:43:09 +02:00
rmagueta
a772400ffa Fix memory leak 2022-04-04 13:14:18 +01:00
rmagueta
2d434033e0 Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-04-04 12:35:25 +01:00
francescomani
4c17c9c62a change SR slot in FDD to avoid assertion 2022-04-03 18:15:17 +02:00
francescomani
e1e8c167de Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-04-01 19:21:45 +02:00
rmagueta
25614263ba Fix build after merge 2022-04-01 16:15:58 +01:00
rmagueta
c83df1b677 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/INIT/nr_init_ue.c
#	openair2/GNB_APP/gnb_config.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.h
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
#	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf
2022-04-01 15:56:47 +01:00
Thomas Schlichter
729cf143e0 Merge remote-tracking branch 'origin/develop' into support-15-kHz-SCS 2022-04-01 10:28:11 +02:00
francescomani
6e6f9a53a1 Merge remote-tracking branch 'origin/develop' into NR_dl_ul_fapi_improv 2022-03-31 10:46:02 +02:00
francescomani
cb32c7505e tabulated values * 10 to simplify the code 2022-03-30 19:08:20 +02:00
Raymond Knopp
a77c1d3202 Trigger first DL Data Delivery status from DU to report the buffer availability to the CU
-After that no DL traffic is getting blocked at the Accelleran CU for low values of throughput
-Remaining to remove the hardcoded value of buffer availability and report the actual value from the DU.
2022-03-29 12:17:37 +02:00
matzakos
038e70b0c6 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-03-28 21:55:21 +02:00
matzakos
90c64f4cf8 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-03-28 21:20:49 +02:00
rmagueta
139a33d644 Remove multiple nr_gold_csi_rs initializations 2022-03-28 14:36:01 +01:00
rmagueta
e322bdb289 Fix warning after merge 2022-03-28 14:10:39 +01:00
rmagueta
181e576698 Fix warning after merge 2022-03-28 13:53:35 +01:00
rmagueta
0abcf3d9c4 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/INIT/nr_init.c
#	openair1/PHY/INIT/nr_init_ue.c
#	openair1/PHY/NR_REFSIG/nr_gold.c
#	openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
#	openair1/PHY/defs_nr_common.h
#	openair2/LAYER2/NR_MAC_gNB/config.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
2022-03-28 13:32:46 +01:00
francescomani
c6b4f97d19 coderate according to SCF and get tbs,qm,R only at MAC 2022-03-26 13:37:34 +01:00
Thomas Schlichter
88c0028757 Merge remote-tracking branch 'origin/develop' into support-15-kHz-SCS 2022-03-24 11:39:22 +01:00
rmagueta
199680d24d Address reviewer comments 2022-03-21 17:37:29 +00:00
rmagueta
7ecd593f6b Fix memory leaks 2022-03-18 17:55:53 +00:00
luis_pereira87
f439095c6e Fix bug after merge 2022-03-17 18:19:42 +00:00
rmagueta
190eaa1e42 Move CSI-RS configuration from fill_initial_SpCellConfig() to update_cellGroupConfig() 2022-03-17 16:36:50 +00:00
rmagueta
8704f81025 Remove duplicated code 2022-03-17 16:35:06 +00:00
matzakos
4e73ef0c3b Avoid exiting in case of PDPC receiving UL user-plane traffic before the DRB is established
-Happened occasionally in the CU/DU split scenario
2022-03-17 17:01:50 +01:00
matzakos
aba5098e30 Remove hardcoding of port numbers in handling of F1 UE context modification request 2022-03-17 17:01:01 +01:00
rmagueta
b59b84e904 Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-03-17 01:03:35 +00:00
rmagueta
ea22da6e7a Noise power estimation based on CSI-RS 2022-03-17 00:50:35 +00:00
rmagueta
2f2bc2a5e8 Merge remote-tracking branch 'origin/nr_csirs_rrc_harmonization' into develop-CSI
# Conflicts:
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/nr_rrc_config.c
#	openair2/RRC/NR/nr_rrc_config.h
#	openair2/RRC/NR/rrc_gNB_reconfig.c
2022-03-16 17:45:39 +00:00
rmagueta
3f88cc1fb1 Intermediate commit: move CSI configuration to a separate function 2022-03-16 17:19:36 +00:00
rmagueta
2f9d8e759d Memory optimization for procedures related to CSI-RS channel estimation 2022-03-16 15:21:55 +00:00
francescomani
f40b579a78 fix for phy-simulator issues 2022-03-16 15:13:50 +01:00
rmagueta
f1eb2e15d4 Channel estimation based on CSI-RS and interpolation at UE working for a gNB with 4 antenna ports 2022-03-16 13:03:31 +00:00
rmagueta
8b0409d349 Channel estimation based on CSI-RS and interpolation working for a gNB with 2 antenna ports 2022-03-16 01:34:23 +00:00
rmagueta
e07f32f131 Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-03-15 18:56:46 +00:00
rmagueta
ce1613ad7c Improvement in nr_get_csi_rs_signal() and nr_csi_rs_channel_estimation() to later be easier to extend to multiple ports 2022-03-15 18:55:50 +00:00
Thomas Schlichter
9ef3fdbc49 add autotests for nr_dlsim and nr_ulsim with 15 kHz SCS and 5 MHz BW 2022-03-15 09:45:36 +01:00
francescomani
8edcd41a8d fix for pucch0 that straddles DC carrier 2022-03-14 17:35:04 +01:00
Thomas Schlichter
6569ea1a20 fix use of uninitialized memory
found by valdgrind in nr_dlsim
2022-03-14 16:39:17 +01:00
Thomas Schlichter
1616ed7727 gNB: generalize rx_nr_prach_ru() and add support for mu==0 2022-03-14 16:39:17 +01:00
Thomas Schlichter
8f632a7c69 NR_UE: generalize generate_nr_prach() and add support for mu==0 2022-03-14 16:39:17 +01:00
Thomas Schlichter
15e82e4811 add support for mu==0 to nr_prachsim 2022-03-14 16:39:17 +01:00
Thomas Schlichter
31cd31826d move get_dft() and get_idft() from pss_nr.c to tools_defs.h 2022-03-14 16:39:17 +01:00
Thomas Schlichter
d104ef73b7 gNB: fix memory allocations for PUSCH in phy_init_nr_gNB() 2022-03-14 16:39:17 +01:00
Thomas Schlichter
9e90b8f22c remove unneeded global arrays ul_ch_ptrs_estimates, ul_ch_ptrs_estimates_ext, dl_ch_ptrs_estimates and dl_ch_ptrs_estimates_ext 2022-03-14 16:39:17 +01:00
Thomas Schlichter
4fd78ce1e0 small fixes for 15 kHz SCS 2022-03-14 16:39:17 +01:00
Thomas Schlichter
cbf57d7b3c Add configuration file for 15 kHz SCS, 5 MHz BW, band 66, FDD 2022-03-14 16:39:17 +01:00
Thomas Schlichter
47148e3f7d add NO_INTERP to nr_pdsch_channel_estimation() as it is in nr_pusch_channel_estimation() 2022-03-14 16:39:17 +01:00
Thomas Schlichter
4a90091095 fix init_timeshift_rotation() 2022-03-14 16:39:17 +01:00
Thomas Schlichter
baa2e92562 add support for 5 MHz (15 kHz SCS) and 10 MHz (30 kHz SCS) to nr_dlsim and nr_ulsim 2022-03-14 16:39:17 +01:00
rmagueta
e56f284347 Perform the channel interpolation for CSI-RS row 1 2022-03-14 15:29:10 +00:00
matzakos
12eed23f63 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-03-14 11:39:13 +01:00
francescomani
03617b9165 more general SR config for period and offset 2022-03-14 10:43:59 +01:00
Thomas Schlichter
7e17f8bd6a make nr_ulsim PASS condition depend on eff_tp_check, just as nr_dlsim already does 2022-03-14 09:45:38 +01:00
Thomas Schlichter
a82d897478 Merge remote-tracking branch 'origin/nr-ue-fixes' into support-15-kHz-SCS 2022-03-14 09:36:29 +01:00
Thomas Schlichter
1e5c3c5707 Merge remote-tracking branch 'origin/develop' into fix_nr_odd_prb 2022-03-14 09:35:17 +01:00
francescomani
a88a8dae8e config of pucch2 in rrcsetup 2022-03-11 12:27:00 +01:00
francescomani
63ebfff4d3 Merge remote-tracking branch 'origin/develop' into NR_PUCCH_RRC_Resources 2022-03-10 15:21:47 +01:00
rmagueta
670f979f97 Perform the average of LS estimates over time for CSI-RS at UE 2022-03-09 20:00:41 +00:00
rmagueta
0126bd849b Remove redundant info from nr_csi_rs_info_t 2022-03-09 19:18:30 +00:00
Raymond Knopp
6abb1e362d Merge remote-tracking branch 'origin/tdd25period_for_MR' into F1_interop_ACC
Conflicts:
	cmake_targets/CMakeLists.txt
	openair1/PHY/NR_TRANSPORT/pucch_rx.c
	openair1/SCHED_NR/fapi_nr_l1.c
	openair1/SIMULATION/NR_PHY/dlschsim.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
	openair2/LAYER2/NR_MAC_gNB/main.c
	openair2/RRC/NR/MESSAGES/asn1_msg.c
	openair2/RRC/NR/MESSAGES/asn1_msg.h
	openair2/RRC/NR/nr_rrc_proto.h
	openair2/RRC/NR/rrc_gNB.c
	openair3/ocp-gtpu/gtp_itf.cpp
	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
2022-03-09 19:16:23 +01:00
matzakos
14ec3e505d Fix decoding of UE-capabilities-RAT-container-list at the DU after receiving it from the CU 2022-03-09 19:08:15 +01:00
rmagueta
19d8ea2742 Minor optimizations 2022-03-09 17:59:32 +00:00
rmagueta
51a72b8479 LS channel estimation at UE based on CSI-RS 2022-03-09 15:07:23 +00:00
rmagueta
db0ce84aa5 Fix FAPI for CSI-RS pdu and associated procedures 2022-03-08 13:18:17 +00:00
rmagueta
bbe806a870 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/SIMULATION/NR_PHY/dlsim.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.h
#	openair2/RRC/NR/nr_rrc_config.c
#	openair2/RRC/NR/nr_rrc_config.h
#	openair2/RRC/NR/rrc_gNB.c
#	openair2/RRC/NR/rrc_gNB_nsa.c
2022-03-07 13:10:40 +00:00
rmagueta
a77769d45b Fix build after merge 2022-03-05 02:32:34 +00:00
rmagueta
a634f14f74 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c
#	openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
#	openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
2022-03-05 01:58:51 +00:00
luis_pereira87
bb89ae3aca Delete duplicated prototype function (update to develop implementation) 2022-03-05 01:42:26 +00:00
rmagueta
de8aa24de5 Get CSI-RS symbols from received signal at UE 2022-03-05 01:37:38 +00:00
Raymond Knopp
2776ec78b0 Add initial support for DL Data Delivery status reporting over NR-User plane protocol in gtp-u 2022-03-03 17:21:59 +01:00
Raymond Knopp
d4b566ceb8 Update ori.h for AW2S RU 2022-03-03 17:21:23 +01:00
rmagueta
35324cfa12 Call nr_generate_csi_rs at UE side too 2022-03-02 18:30:02 +00:00
rmagueta
6c27a40f09 Creation of nr_csi_rs_info_t 2022-03-02 16:30:54 +00:00
rmagueta
c272bb2f7c Generalization of the nr_generate_csi_rs function to be able to call it in gNB and UE 2022-03-02 15:23:15 +00:00
rmagueta
7fdd7547be Merge remote-tracking branch 'origin/develop' into develop-CSI 2022-03-02 13:14:09 +00:00
matzakos
e5c6ee599c Merge with latest updates of develop and fixes for F1
-Problem when parsing UE_RAT_container_list at the DU through UE context setup request
-Some debug logs added to be removed once this is fixed
2022-02-28 21:51:41 +01:00
matzakos
55d59e5f2a Merge remote-tracking branch 'origin/repair-f1-5g' into F1C_extensions_develop 2022-02-28 14:44:01 +01:00
Flavien RJ
4b90221622 Fix merge conflict latseq and develop branches 2022-02-24 17:30:17 +01:00
Flavien RJdM
3e0f8c73ad Merge remote-tracking branch 'oai-eurecom/develop' into latseq 2022-02-24 16:49:37 +01:00
rmagueta
3eaebbca93 CSI PDU received at PHY layer in new function nr_ue_csi_rs_procedures at UE 2022-02-23 20:23:34 +00:00
rmagueta
853776ef2f Implementation of FAPI procedures for CSI at UE 2022-02-23 19:32:20 +00:00
rmagueta
05a9c0e264 Fix in nr_ue_scheduler for CSI 2022-02-23 18:12:36 +00:00
rmagueta
fdce62f799 Add cyclic_prefix in csirs_config_pdu at UE 2022-02-23 18:05:45 +00:00
rmagueta
5bae6dd6f3 Add missing fiels in fapi_nr_dl_config_csirs_pdu_rel15_t 2022-02-23 16:11:13 +00:00
rmagueta
3ae8f393f4 Add logs in nr_generate_csi_rs 2022-02-23 15:05:02 +00:00
rmagueta
4d17364142 Fix build warnings 2022-02-23 14:16:58 +00:00
rmagueta
0e0526e367 Merge remote-tracking branch 'origin/develop' into develop-CSI
# Conflicts:
#	openair1/PHY/NR_TRANSPORT/nr_dlsch.c
#	openair1/SIMULATION/NR_PHY/dlsim.c
#	openair1/SIMULATION/NR_PHY/ulsim.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/RRC/NR/rrc_gNB_nsa.c
2022-02-23 13:51:31 +00:00
rmagueta
ed6aa9f505 Replace AssertFatal with a LOG in nr_get_csi_payload at UE 2022-02-22 20:09:58 +00:00
rmagueta
0ced14a56d Fix in nr_set_pdsch_semi_static 2022-02-22 20:02:15 +00:00
rmagueta
bb82697819 Fix segmentation fault at UE in nr_schedule_csi_for_im and nr_schedule_csirs_reception 2022-02-22 19:14:17 +00:00
rmagueta
cf284d76f0 Fix build after merge 2022-02-22 17:49:59 +00:00
rmagueta
6f19524e95 Merge remote-tracking branch 'origin/CSI-SA' into develop-CSI
# Conflicts:
#	openair1/PHY/NR_TRANSPORT/nr_dlsch.c
#	openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
#	openair1/SIMULATION/NR_PHY/dlsim.c
#	openair1/SIMULATION/NR_PHY/ulsim.c
#	openair2/LAYER2/NR_MAC_gNB/config.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
#	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/nr_rrc_proto.h
#	openair2/RRC/NR/rrc_gNB_nsa.c
#	openair2/RRC/NR/rrc_gNB_reconfig.c
2022-02-22 15:10:20 +00:00
rmagueta
628726caae Fix build after merge 2022-02-22 13:33:36 +00:00
rmagueta
4f58d66972 Merge remote-tracking branch 'origin/nr_csirs_rrc_harmonization' into develop-CSI
# Conflicts:
#	openair1/SIMULATION/NR_PHY/dlsim.c
#	openair1/SIMULATION/NR_PHY/ulsim.c
#	openair2/RRC/NR/MESSAGES/asn1_msg.c
#	openair2/RRC/NR/rrc_gNB_nsa.c
#	openair2/RRC/NR/rrc_gNB_reconfig.c
2022-02-22 13:14:12 +00:00
rmagueta
2b108cdded Merge remote-tracking branch 'origin/NR_UE_CSIRS_scheduling' into develop-CSI 2022-02-22 10:09:51 +00:00
rmagueta
580f56c869 Revert "Implementation of fill_default_csi_MeasConfig"
This reverts commit 777074ff79.
2022-02-22 10:08:39 +00:00
rmagueta
777074ff79 Implementation of fill_default_csi_MeasConfig 2022-02-21 20:23:27 +00:00
rmagueta
d820051397 Update config files 2022-02-21 17:46:02 +00:00
Raymond Knopp
c02650826d SIMD alignment of stack arrays in ptrs channel estimation. 2022-02-19 17:17:09 +01:00
Raymond Knopp
9790eb1adc Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen
Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/build_oai
	cmake_targets/phy_simulators
	cmake_targets/phy_simulators/CMakeLists.txt
2022-02-19 13:14:53 +01:00
Flavien RJ
fb7d473383 fix build_oai -I with develop branch 2022-02-16 18:59:26 +01:00
matzakos
fb153cc792 Merge remote-tracking branch 'origin/NR_SA_UID' into F1C_extensions_develop 2022-02-16 16:08:58 +01:00
matzakos
d3d9325081 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-02-16 16:08:34 +01:00
Raymond Knopp
dccbd9279a Some hardcoded values in F1AP for testing with Accelleran to be removed later 2022-02-09 11:05:23 +01:00
francescomani
8d7df8d164 rrc configuration for pucch power control 2022-02-07 19:28:51 +01:00
Flavien RJ
266cf75570 little fix of build_oai 2022-02-07 15:05:22 +01:00
Flavien RJ
47494c9950 Merge remote-tracking branch 'oai-eurecom/develop' into latseq 2022-02-07 15:04:59 +01:00
Flavien RJ
37abc70eee latseq : clean up for OAI merge request 2022-02-07 09:49:22 +01:00
Raymond Knopp
2e0823a7ae Change mapping between DRB id and channel id for interoperability with Accelleran CU
-Some hardcodings also added to be removed later
2022-02-01 14:03:42 +01:00
francescomani
d29b17a211 function to configure SR 2022-01-26 17:46:26 +01:00
francescomani
9408c3c0b0 function to set dl_DataToUL_ACK 2022-01-26 13:58:57 +01:00
matzakos
a19f2e3254 Merge remote-tracking branch 'origin/aw2s-n41' into F1_interop_ACC 2022-01-24 15:11:50 +01:00
francescomani
975f7e868a function to configure pucch resource set 1 (format2) 2022-01-21 19:15:50 +01:00
francescomani
dd6dac1392 function to configure pucch resource set 0 2022-01-21 16:16:02 +01:00
francescomani
299ba03b84 passing UECAP structure to RRC reconfiguration functions 2022-01-21 09:29:49 +01:00
francescomani
0d86181a58 using uid also in SA 2022-01-20 18:56:44 +01:00
Raymond Knopp
a3aae0dd9e made default nr_ulsim configuration not require root privileges (single-thread) 2022-01-20 12:35:13 +01:00
Raymond Knopp
6afebc0e41 Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen
Conflicts:
	openair1/SIMULATION/LTE_PHY/dlsim.c
	openair1/SIMULATION/LTE_PHY/ulsim.c
2022-01-20 07:51:29 +01:00
Raymond Knopp
1f9900ba61 LDPC decoder generator cleanup 2022-01-19 23:01:27 +01:00
Raymond Knopp
8d164fe2aa Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen 2022-01-19 20:06:08 +01:00
Raymond Knopp
4caafc7292 removal of lingering .o files in LDPC decoder generator directories. Merge conflict in CMakelists.txt 2022-01-19 11:25:34 +01:00
matzakos
e5899e2f74 Merge remote-tracking branch 'origin/develop' into F1C_extensions_develop 2022-01-17 13:19:45 +01:00
Raymond Knopp
7090db60bc Merge remote-tracking branch 'origin/physim-hotfix' into ldpc-decoder-codegen 2022-01-13 10:35:32 +01:00
Raymond Knopp
08100357f7 Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen 2022-01-13 09:51:08 +01:00
Raymond Knopp
f44d1ccfeb reduced memory requirements of dlsim,ulsim 2022-01-12 14:21:47 +01:00
Flavien RJ
3c56bfc638 Merge tag '2021.w51_c' into latseq-dev
Tx proc optim ;  oaiue x300 ; NR RRC harmonization: TDA for DL and UL
2022-01-06 13:00:06 +01:00
Raymond Knopp
7d9b3464a8 Merge branch 'ldpc-decoder-codegen' of https://gitlab.eurecom.fr/oai/openairinterface5g into ldpc-decoder-codegen
Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt
	openair1/PHY/CODING/nrLDPC_decoder.c
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_mPass.h_native_memcpy
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_bnProc/bnProc_gen_avx2
	openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/generator_bnProc_avx512/bnProc_gen_avx512
2022-01-05 14:55:13 +01:00
Raymond Knopp
74ce2cf4be to trigger CI 2022-01-05 01:27:42 +01:00
Raymond Knopp
40a9792fef build_oai flag to turn off AVX512 generation on machines that have it. Needed for caracal at EURECOM because of CUDA compiler which doesn't like the flag. Added creation of threadpool in nr_ulsim to test channel decoding parallelization on different high CPU count machines 2021-12-24 21:36:06 +01:00
Raymond Knopp
13b8abc310 Merge branch 'develop' into ldpc-decoder-codegen
Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/build_oai
	openair1/PHY/TOOLS/time_meas.h
2021-12-24 18:19:13 +01:00
Sy
cd2b80e6c2 some cleanup 2021-12-22 22:36:42 +01:00
Raymond Knopp
2d4453648f Correct how gtp-u extension header is parsed 2021-12-15 18:38:25 +01:00
Sy
5521e34360 my Internship project 2021-11-25 17:34:02 +01:00
Raymond Knopp
12792eece7 Modifications in the cellGroupConfig container content of F1 UE context response messages 2021-11-19 18:52:51 +01:00
matzakos
e8d92cbddd Merge remote-tracking branch 'origin/NR_F1C_F1U_extensions' into F1C_extensions_develop 2021-11-19 16:47:47 +01:00
Raymond Knopp
e51cd863fe Merge branch 'bler_txoptim' into F1C_extensions_develop
Conflicts:
	cmake_targets/CMakeLists.txt
	common/utils/nr/nr_common.c
	openair1/PHY/INIT/nr_parms.c
	openair1/PHY/NR_TRANSPORT/pucch_rx.c
	openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
	openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
	openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c
	openair1/SCHED_NR/fapi_nr_l1.c
	openair1/SCHED_NR/phy_procedures_nr_gNB.c
	openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
	openair1/SIMULATION/NR_PHY/dlschsim.c
	openair1/SIMULATION/NR_PHY/dlsim.c
	openair2/GNB_APP/gnb_config.c
	openair2/LAYER2/NR_MAC_UE/config_ue.c
	openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
	openair2/LAYER2/NR_MAC_gNB/main.c
	openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
	openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
	openair2/RRC/NR/L2_nr_interface.c
	openair2/RRC/NR/MESSAGES/asn1_msg.c
	openair2/RRC/NR/MESSAGES/asn1_msg.h
	openair2/RRC/NR/rrc_gNB_NGAP.c
	openair3/NAS/NR_UE/nr_nas_msg_sim.c
	openair3/NAS/NR_UE/nr_nas_msg_sim.h
	openair3/ocp-gtpu/gtp_itf.cpp
	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
	targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
2021-11-14 21:18:50 +01:00
matzakos
40263348f9 Merge with NR_F1C_F1U_extensions and resolve conflicts 2021-11-12 17:01:27 +01:00
matzakos
188a99ca51 Temporary dirty fix to not block SRB1 traffic once SRB2 is added
-This function will change completely after update with develop
2021-11-10 18:35:52 +01:00
matzakos
cd16d7ce03 Make the call to send DCCH SDU to RLC from RRC instead of F1AP 2021-11-10 18:35:05 +01:00
matzakos
f1455f15a3 Check whether RRC Setup is available before sending CBRA Msg4
-Required for the CU/DU split case if the RRC Setup arrives later than the first opportunity to transmit Msg4
-Next extension is to decouple RRCSetup from Msg4
2021-11-10 18:33:48 +01:00
matzakos
6a1ac14447 Include mandatory transaction ID field in F1 initial UL RRC message transfer 2021-11-10 18:31:08 +01:00
matzakos
e2b4f80ac2 Add sNSSAI configuration in F1 Setup request message to the CU
-Required for interoperability with Accelleran CU and OAI CN
-Currently hardcoded values, to be modified so that they are parsed from the DU config file
-After this modification Accelleran CU sends gNBCU configuration update
2021-11-05 10:38:46 +01:00
matzakos
b103ada542 Fix decoding of SIB1 RRC container at the processing function of F1 setup request at the CU
after modifications done at the encoded SIB1 message type included in the RRC container of F1 setup request at the DU
-Some cleanup required
2021-10-26 18:30:51 +02:00
matzakos
e7f8b56b65 Include NR_SIB1_t type in F1 setup req container instead of the whole NR_BCCH_DL_SCH_Message_t message
-Wireshark is not complaining after that
-Issue at decoding F1 Setup req at the CU due to the new encoding
-Keep the previous encoding as the default for now until the CU issue is fixed
-Fix PUCCH allocation for ACK/NAK issue appearing when DU runs without OAI CU
2021-10-26 13:11:50 +02:00
matzakos
96efe9c03b Enable rrc mac config from init NR SI for the DU case 2021-10-26 12:56:32 +02:00
matzakos
11cdf1610e Update F1AP UE context release command handling function for NR
-Include ITTI message to RRC to do the actual processing at RRC layer,
 as done for the other F1AP messages. Leave LTE processing as it was for now.
2021-10-20 19:00:51 +02:00
matzakos
85faedfcbe Add triggering of F1 UE Context release command
-Add also a temporary artificial trigger just to be able to test with OAI UE
-Comment out most of the part of the UE context release command handler function at the DU in order to separate properly the RRC from F1AP functionality later.
2021-10-18 18:32:57 +02:00
Flavien RJ
703bda8665 latseq : commit before push request pushing
latseq-dev branch to OAI repo
2021-10-15 09:29:06 +02:00
matzakos
40b131be13 Small corrections in F1AP UE context management messages and indentation fixes 2021-10-13 16:45:42 +02:00
matzakos
b37195ad1f Few updates on handling master cell group configuration updates coming from the DU 2021-10-13 14:36:38 +02:00
matzakos
1a40b36193 Use correct SCTP port number for F1AP according to standards 2021-10-12 19:38:19 +02:00
matzakos
39aaf63a4e Merge with branch NR_F1C_F1U_extensions 2021-10-11 17:56:28 +02:00
matzakos
e2c88f91af Trigger dedicated RRC Reconfiguration after processing F1 UE context modification response at RRC layer of the CU
-Successful user-plane traffic over F1-U upon completion of UE context modification procedures
2021-10-08 18:29:39 +02:00
matzakos
d3899a21a6 Add implementation of UE context modification response handler at F1AP layer of the CU 2021-10-08 13:37:46 +02:00
matzakos
a1b2d222dd Generation of UE context modification response at F1AP layer of the DU
-Fix some indentations
2021-10-08 10:31:53 +02:00
matzakos
f068fb4ef3 Add handling of UE context modification request at RRC layer of the DU and trigger UE context modification response
-Next step: Proper generation of UE context modification response at F1AP layer
2021-10-06 18:43:10 +02:00
matzakos
b3c0095f07 Add handler function for UE context modification request message at F1AP layer of the DU
-Fix indentation in UE context modification request message generation function at the CU
2021-10-05 17:24:16 +02:00
matzakos
36b8bb1b5b Trigger UE context modification request at the CU upon reception of PDU Session Resource setup request from the AMF
-F1 message successfully encoded at the CU (including SRB2, DRB and F1-U tunnel configuration) and received from the DU.
-Next steps: handling of UE context modification request at the DU and triggering the UE context setup response towards the CU.
2021-10-05 13:43:19 +02:00
Flavien RJ
60edb9a5b7 Merge tag '2021.w36' into latseq-dev
Bugfix nr rlc segmentation present in both NR RLC AM and NR RLC UM ;  T tracer  DLSCH DCI ; Fix computation of pointA in SIB1 ;  fix-physim-run-script-on-cluster ; fix nr-dlsim Test 21 (4x4 MIMO, 2 Layers)
2021-10-01 10:43:32 +02:00
matzakos
a84ecd1468 Merge with branch NR_F1C_F1U_extensions 2021-09-29 13:59:06 +02:00
matzakos
55476b175f Handle UE capabilities info at the DU received through UE context setup request
-Trigger UE context setup response at the DU and RRC Reconfiguration at the CU upon reception of UE context setup response.
-Pending: The DU should generate some updates on the master cell groupconfig based also on the received UE capabilities and add them in
 the UE context setup response message so that they can be included in the RRC Reconfiguration message sent from the CU. For the moment the
 corresponding function is empty.
-Next steps: trigger UE context modification procedures
2021-09-27 18:02:13 +02:00
matzakos
5e506bfab0 Trigger F1 UE context setup request from CU after reception of NR UE capabilities
-Include UE_Capability_RAT_container_list in UE context setup request so that it gets processed at the DU
-Next steps: DU should store and process the UE capabilities and generate updates in master cell group config
to be included in UE context setup response. Then upon reception of UE context setup response, the first RRC Reconfiguration
can be triggered at the CU with the updates on master cell group config.
2021-09-24 16:36:02 +02:00
Flavien RJ
9b064c1ab9 Merge tag '2021.w27' into latseq-dev
NR_gNB_initial_MIB_fix  ; x2_handle_sctp_shutdown
2021-07-15 12:23:22 +02:00
Flavien RJ
fcee3ceb41 latseq : centralize all scripts in one place 2021-06-16 09:05:47 +02:00
Flavien RJ
0ff491cb49 latseq : fix a warning on an incompatible size of array 2021-04-28 10:15:58 +02:00
flavien Ronteix--Jacquet dM
cb1aea9711 Merge branch 'develop' 2021.w09 into latseq-dev 2021-03-09 12:23:05 +01:00
flavien Ronteix--Jacquet dM
5606b0df7c Revert "soft-alter : create a branch for software alterated air interface"
This reverts commit 2e14dbb92b.
2021-02-09 20:59:16 +01:00
flavien Ronteix--Jacquet dM
2e14dbb92b soft-alter : create a branch for software alterated air interface 2021-02-09 20:58:37 +01:00
flavien Ronteix--Jacquet dM
6500e8077f latseq points : PHR 2021-02-02 11:20:12 +01:00
flavien Ronteix--Jacquet dM
cde95150c3 latseq points : long bsr 2021-01-25 19:45:51 +01:00
flavien Ronteix--Jacquet dM
5daa015e32 latseq points : nrb and rfi 2021-01-11 18:05:35 +01:00
flavien Ronteix--Jacquet dM
eb6ed6efbe latseq_points : a final version (without RLC UM) 2020-12-10 19:30:11 +01:00
flavien Ronteix--Jacquet dM
c7f93c90bc latseq_logs: logging system 2020-12-03 19:13:30 +01:00
flavien Ronteix--Jacquet dM
baa08960b3 latseq points : Add information points 2020-11-13 23:55:14 +01:00
flavien Ronteix--Jacquet dM
b98c6e1769 latseq : log rdtsc instead of gettimeofday
- add Synchronization points 'S'
- add script to convert rdtsc to gettimeofday using 'S'
- add call to conversion script to latseq_logs
2020-11-12 18:29:15 +01:00
flavien Ronteix--Jacquet dM
98a98485c1 latseq : log to ns instead of us 2020-11-04 17:23:48 +01:00
flavien Ronteix--Jacquet dM
7848214984 latseq tools and docs 2020-10-29 18:44:14 +01:00
flavien Ronteix--Jacquet dM
26f25dc943 latseq : fix flush error of fprintf 2020-10-29 18:43:29 +01:00
flavien Ronteix--Jacquet dM
3b6f8d584a latseq :
- cpu_freq in argument of init
- use local rdtsc
- fix time conversation
2020-10-29 18:42:52 +01:00
flavien Ronteix--Jacquet dM
2a36408c5b latseq points:
- add points in rlc_v2
- add points in gtp lib
- adapt points in mac layer
rlc_v2:
- add informations to RLC entity
2020-10-29 18:37:16 +01:00
flavien Ronteix--Jacquet dM
d22bb0c90f latseq :
- clean and release version of article
- add convert ring buffer by chunk
- validate test_latseq
2020-10-19 15:49:01 +02:00
flavien Ronteix--Jacquet dM
d39d476e62 latseq_logs : partial fix for infos yielding 2020-10-12 18:11:52 +02:00
flavien Ronteix--Jacquet dM
09995d5d8c latseq : hot fix, add a sleep to the thread 2020-10-07 18:28:25 +02:00
flavien Ronteix--Jacquet dM
e07c43a715 latseq : clean git repo 2020-09-18 11:35:05 +02:00
flavien Ronteix--Jacquet dM
42cfb03ca5 clear warnings 2020-09-17 10:21:19 +02:00
flavien Ronteix--Jacquet dM
c8b0c41871 latseq : patch before latseq publication 2020-09-17 10:20:52 +02:00
flavien Ronteix--Jacquet dM
2a658d1cdb NO-STABLE merge with main5G 2020-09-15 17:37:28 +02:00
flavien Ronteix--Jacquet dM
ca554e81c9 latseq_logs : fix Decimal, add progressbar and verbosity argument 2020-09-15 17:36:38 +02:00
flavien Ronteix--Jacquet dM
687d8cbf01 latseq : Add point of I-type for RLC am and um txbuffer 2020-09-14 18:44:22 +02:00
flavien Ronteix--Jacquet dM
138f67e342 latseq_logs : handle I-type traces 2020-09-14 13:11:15 +02:00
flavien Ronteix--Jacquet dM
b073fd22d4 Resolve merge conflict main5G-latseq-dev 2020-09-04 09:28:16 +02:00
flavien Ronteix--Jacquet dM
061dca80fe latseq : fix points 2020-09-04 09:23:22 +02:00
flavien Ronteix--Jacquet dM
cc40ca0721 Merge branch 'develop' (e31349256f) into latseq-dev 2020-09-01 12:55:24 +02:00
Raymond Knopp
c64362f8ec Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen
Conflicts:
	cmake_targets/CMakeLists.txt
	cmake_targets/build_oai
2020-08-27 07:22:10 +02:00
Raymond Knopp
3bc433a5f8 bugfix from type in last commit 2020-08-27 07:18:49 +02:00
flavien Ronteix--Jacquet dM
c53a4e49c1 latseq_stats : add interarrival 2020-08-20 12:22:14 +02:00
flavien Ronteix--Jacquet dM
1ebe01a9c1 latseq_stats : add throughput metric 2020-07-31 22:29:48 +02:00
flavien Ronteix--Jacquet dM
ef45e448c0 latseq_stats : matrix segment/journeys after filtering 2020-07-28 20:35:48 +02:00
flavien Ronteix--Jacquet dM
383de22fc8 latseq_p : measurements for rlc_v2. NOT DONE.
Not important since rlc_v1 works and we will switch to nr_rlc.
2020-07-15 11:23:06 +02:00
Sy
845a226410 optimized 5G NR LDPC decoder 2020-07-06 02:34:12 +02:00
flavien Ronteix--Jacquet dM
3e88f1cd77 latseq_logs : commit befor checking out 2020-07-03 18:44:25 +02:00
Sy
c8a787d22c optimized 5G NR LDPC decoder 2020-07-03 14:21:00 +02:00
Sy
559e8fdcd2 degradation of performance in BLER fixed | bnProc & bnProcPc unrolled | small improvement in times 2020-07-01 18:37:52 +02:00
Sy
0f704894f4 degradation of performance in BLER corrected | bnProc & bnProcPc unrolled 2020-07-01 14:12:53 +02:00
Sy
5e5bc1a9e3 Effective management of all values ​​of Z (lifting size) and all R (coding rate) for BG1 & BG2 |
some improvement in decoding time | (bnProcPc reduces 2x)
2020-06-27 02:07:13 +02:00
Sy
c912762144 bnProcPc and bnProc unrolled | BN Processing, small improvement in times at the expense of degraded performance in BLER , reordering of generated files 2020-06-19 23:45:02 +02:00
Sy
394f0deb1b bnProcPc and bnProc unrolled | BN treatment, small improvement in times at the expense of degraded performance in BLER , reordering of generated files 2020-06-19 23:38:37 +02:00
flavien Ronteix--Jacquet dM
b1eb810d9d latseq tools:
latseq_logs : output for latseqj fix of points' name
latseq_checker: add generation of reports of functional points in OAI code
2020-06-17 20:08:27 +02:00
flavien Ronteix--Jacquet dM
3234efec54 latseq : fix latseq point in RLC/ for experiments 2020-06-17 20:07:01 +02:00
flavien Ronteix--Jacquet dM
d2e4c33c7f Latseq : fix an error with filelog name memory 2020-06-15 19:26:22 +02:00
Raymond Knopp
55e32f6e8c removed unnecessary include files 2020-06-06 10:57:33 +02:00
Raymond Knopp
0d65f76d46 removed system includes that were put in the repository 2020-06-06 09:32:41 +02:00
Sy
119be5d45b Re-implementation of memcpy--> more faster | llr2cnProcBuf, cn2bnProcbuf, bn2cnProcBuf are optimized 2020-06-04 02:52:35 +02:00
Sy
cb8760a44d full version of the optimized 5NR LDPC decoder | AVX2 && AVX512 options 2020-06-03 22:57:13 +02:00
Sy
9b11d0b593 full version of the optimized 5NR LDPC decoder 2020-06-03 22:51:05 +02:00
Sy
301317eca6 full version of the optimized 5NR LDPC decoder 2020-06-03 19:04:20 +02:00
flavien Ronteix--Jacquet dM
c2cea21ae4 latseq tools:
- update README
-  stats parser
-  add script to convert json stream to a dsv stream
- change point yielder in latseq_logs
2020-06-03 17:37:20 +02:00
flavien Ronteix--Jacquet dM
6affc6a1d6 latseq : dynamic log filename 2020-06-03 17:33:29 +02:00
flavien Ronteix--Jacquet dM
1a60305799 latseq_stats : add -jd journeyx durations csv for plots 2020-06-02 18:18:52 +02:00
Raymond Knopp
a6af0d99ce minor fix for AVX2/AVX512 switch 2020-06-02 13:19:35 +02:00
matzakos
956d9aa1d8 added selection between AVX2 and AVX512 2020-06-02 12:06:38 +02:00
flavien Ronteix--Jacquet dM
7c6427b2e6 latseq_stats : output in csv 2020-06-01 14:48:14 +02:00
Raymond Knopp
8663ee697e chages in AVX512 code generator. Yields small improvement compared to AVX2, BLER performance is still degraded. 2020-06-01 14:40:11 +02:00
Sy
c67550e531 Test for AVX512 2020-05-29 15:23:22 +02:00
Sy
265b5c4d1b Test for AVX512 2020-05-29 15:19:52 +02:00
Sy
4542322bb4 TEST AVX512 2020-05-29 15:13:56 +02:00
Sy
558fccbba7 TEST AVX512 2020-05-29 15:07:54 +02:00
Sy
b85b5fe47a Test for avx512 2020-05-29 14:57:15 +02:00
Sy
6d9ceaa712 Test for AVX512 2020-05-29 13:51:38 +02:00
Sy
5e5e487e4c Test for avx512 2020-05-29 11:58:55 +02:00
Raymond Knopp
3e27bed4f7 updates to CMakelist.txt for AVX512 options 2020-05-28 12:23:33 +02:00
Sy
bdd12a3396 Testing for avx512 2020-05-27 13:41:57 +02:00
Sy
bfad636369 Testing for avx512 2020-05-26 16:50:32 +02:00
Sy
00a8df6f8f generated CN processing files according to the values of Z | version for AVX2 and AVX512| BG1 & BG2 2020-05-25 14:34:07 +02:00
Sy
a1b81d9475 generated files for CN processing according to the values of Z | version for AVX2 and AVX512 2020-05-23 22:07:22 +02:00
Sy
140fa111c4 file generated for CN processing according to the values of Z | version for AVX2 and AVX512 2020-05-23 21:39:17 +02:00
flavien Ronteix--Jacquet dM
64a39c5a11 Merge branch 'main5G' into latseq-dev 2020-05-20 10:08:00 +02:00
flavien Ronteix--Jacquet dM
4876af241c Merge remote-tracking branch 'origin/main5G' into latseq-dev 2020-05-19 15:56:39 +02:00
flavien Ronteix--Jacquet dM
2f62c6a403 latseq tools : some tests, comments and fixes 2020-05-19 12:14:37 +02:00
Sy
ad32b6108e use of avx2 & avx512 at CN processing level 2020-05-19 11:49:10 +02:00
Sy
d3af4c4b8b use of avx2 & avx512 at CN processinf level 2020-05-19 11:46:09 +02:00
flavien Ronteix--Jacquet dM
7fd29ce8bb latseq_logs : add csv output 2020-05-19 10:10:12 +02:00
flavien Ronteix--Jacquet dM
3a6a6d9b4d latseq_stats : repartition du temps de trajet par point en moyenne sur les séjours (par path) 2020-05-19 09:17:36 +02:00
Sy
22fe32645b use of avx512 & avx2 at CN processing level 2020-05-18 17:05:50 +02:00
Sy
71a8d19b7d use of avx2 & avx512 at CN Processing level 2020-05-18 13:58:44 +02:00
Sy
3ed622afbd use of avx512 at CN processing level 2020-05-18 11:50:12 +02:00
flavien Ronteix--Jacquet dM
3bc6d3b385 latseq_stats : debut du travail sur les stats journeys par point 2020-05-15 13:49:05 +02:00
Flavien RJdM
67dc05b35c latseq_app : Creation. Plotly + Flask. 2020-05-12 10:36:15 +02:00
flavien Ronteix--Jacquet dM
95c0d37f4a latseq tools : Full toolchain works. Readme for tools 2020-05-11 19:41:09 +02:00
flavien Ronteix--Jacquet dM
6556377a7e latseq_filter : latseq_filter component with an example 2020-05-11 13:07:38 +02:00
flavien Ronteix--Jacquet dM
cb7222d0d4 latseq_logs : match journey to a path 2020-05-11 13:06:59 +02:00
flavien Ronteix--Jacquet dM
3da0b6f6c6 latseq_stats : stats points 2020-05-11 13:06:38 +02:00
Raymond Knopp
a7e6137408 unrolled 2 BNs case in generator 2020-05-09 09:14:59 +02:00
Raymond Knopp
581a9731d8 removed one-level of unrolling in cnProc generator 2020-05-08 23:24:04 +02:00
Sy
732b98d1ae adding >> 5 to all lut_startAddrCnGroups 2020-05-08 17:40:45 +02:00
Sy
fe27b81703 adding >> 5 to all lut_startAddrCnGroups 2020-05-08 17:38:44 +02:00
Sy
66c30b9e1d adding >> 5 to all lut_startAddrCnGroups 2020-05-08 17:15:50 +02:00
Raymond Knopp
9db8db256a LUT memory access fix for code generator 2020-05-08 15:26:52 +02:00
Sy
e785891fb1 integration of the generated file (nrLDPC_cnProc_BG1_Z384_13 with the LDPC decoder at the base 2020-05-07 16:28:01 +02:00
flavien Ronteix--Jacquet dM
b929a7bfba latseq_logs:
- modularisation avec des sorties en json dans le stdout
- suppression de l'ancienne version de l'algo
- suppression de la classe de stats
latseq_stats:
- création de la classe de stat
- prend en charge le json dans le stdin pour les stat sur les journeys
2020-05-07 14:12:06 +02:00
flavien Ronteix--Jacquet dM
e65c78a932 latseq :
- Test TLS buffer occupancy... 32 latseq element is sufficent
- use of sdu size to connect rlc.tx.um--rlc.seg.um... not ideal
- split ip in ip.in and ip.out
2020-05-07 09:16:58 +02:00
Raymond Knopp
f8fbd26b57 more cleanup and testing 2020-05-04 13:18:47 +02:00
Raymond Knopp
fa3a637b72 cleanup of generator, added directory/file creation for output 2020-05-04 11:25:09 +02:00
flavien Ronteix--Jacquet dM
f40d6e08d5 latseq_log : Use time for search depth instead of number of packet 2020-05-04 11:03:30 +02:00
Raymond Knopp
550ab5009b fixed compilation of generator 2020-05-04 10:19:37 +02:00
Raymond Knopp
cabbb72c0f modifications to Makefile to include OPENAIR_HOME path and activate debugging symbols 2020-05-04 09:45:11 +02:00
Sy
0ee70df312 first commit 2020-05-02 23:35:18 +02:00
flavien Ronteix--Jacquet dM
e2a75a125b latseq_logs : rec_rebuild journey algorithm refactoring for a better
detection of segmentation in the case of concatenation
Use of a tree datastruct for the segmentation to explore
2020-04-30 12:33:38 +02:00
flavien Ronteix--Jacquet dM
fe9b97f5a0 latseq_logs : comments and minor fixes 2020-04-29 14:02:59 +02:00
flavien Ronteix--Jacquet dM
10824650e3 latseq_stats:
- add statistics computation for journeys' latency
- add statistics computation for points' latency
- add procedure to display basic statistics
2020-04-28 14:24:35 +02:00
flavien Ronteix--Jacquet dM
2dc3c0a6e0 latseq_logs :
- add stuffs to latseq_log's points attribute
- some fix for rebuild_journeys_recursively
- add pickle to store instance of latseq_log class
2020-04-28 14:23:05 +02:00
flavien Ronteix--Jacquet dM
f00db789fa latseq_logs : rebuild packet journey recursively.
Not totally finshed but looks good.
2020-04-24 23:33:58 +02:00
flavien Ronteix--Jacquet dM
b0d73f24f4 latseq_logs : rebuild allmost every journeys, except case where there is a measurement point betweet to path of the fork 2020-04-24 19:03:13 +02:00
flavien Ronteix--Jacquet dM
d68b88470c latseq : first version to rebuild path ! (not a final version of the algorithm...) 2020-04-23 14:56:11 +02:00
flavien Ronteix--Jacquet dM
670acb2738 latseq_checker : misc adds 2020-04-23 14:55:33 +02:00
flavien Ronteix--Jacquet dM
ef14b3e216 latseq : drb is no longer a global id 2020-04-23 14:55:02 +02:00
flavien Ronteix--Jacquet dM
a7367ae479 latseq_logs : rebuild_packet_journey almost ready 2020-04-22 15:31:04 +02:00
flavien Ronteix--Jacquet dM
270761022b latseq : divers clean 2020-04-22 15:30:36 +02:00
flavien Ronteix--Jacquet dM
efe6b87814 latseq : - BUG FIX pour log_measure4
- les dataid convergent...
2020-04-21 12:52:50 +02:00
flavien Ronteix--Jacquet dM
520961597c latseq : travail sur les points de mesures, notamment pdcp 2020-04-17 22:26:45 +02:00
flavien Ronteix--Jacquet dM
f0fbb77f29 latseq_logs : gestion du multibranche des points 2020-04-17 22:26:05 +02:00
flavien Ronteix--Jacquet dM
f31efd81a6 latseq_logs : objectification and parsing 2020-04-16 18:28:26 +02:00
flavien Ronteix--Jacquet dM
c432a3ecd7 latseq : ajout de la taille dans les points de mesures 2020-04-15 18:23:07 +02:00
flavien Ronteix--Jacquet dM
04b98d7656 After latseq_checker 2020-04-14 20:44:05 +02:00
flavien Ronteix--Jacquet dM
248f668865 latseq-tools : ajout script traitement de log 2020-04-10 22:51:44 +02:00
flavien Ronteix--Jacquet dM
a6b4555e74 latseq : latseq checker en version bash 2020-04-10 22:21:37 +02:00
flavien Ronteix--Jacquet dM
b2af014160 latseq : work on measurement points 2020-04-10 19:08:49 +02:00
flavien Ronteix--Jacquet dM
01f1e200af tools_latseq : ajout du dossier pour les outils latseq.
Creation du checker.
2020-04-09 13:29:59 +02:00
flavien Ronteix--Jacquet dM
63be7596ab test_latseq : ajout d'un test de charge sur le writer 2020-04-07 19:25:24 +02:00
flavien Ronteix--Jacquet dM
c025693894 latseq : Ajout de point et correction d'une erreur mémoire sur un free dans le logger 2020-04-07 19:24:46 +02:00
flavien Ronteix--Jacquet dM
2116edb940 latseq : premiers points de mesures conventionnels 2020-04-03 20:28:44 +02:00
flavien Ronteix--Jacquet dM
27bb00909a latseq : version fprintf 2020-04-03 20:27:52 +02:00
ferrieux
701ad23dbc Synchronously ABORT, you modafucka !!! 2020-04-02 01:46:01 +02:00
ferrieux
5d5dc5a02a Allow for NAT on S1U ($OAINAT) 2020-04-02 01:42:47 +02:00
flavien Ronteix--Jacquet dM
221930d2bd latseq
- intégration dans oai
- points de mesures de test
2020-03-26 19:07:27 +01:00
flavien Ronteix--Jacquet dM
aeb5641181 Merge branch 'split73' into latseq-dev 2020-03-26 16:09:21 +01:00
flavien Ronteix--Jacquet dM
e73a447060 latseq : fixes before split73 update and merge 2020-03-26 13:42:18 +01:00
flavien Ronteix--Jacquet dM
fb953b8d3f latseq : utilisation de l'expansion de macro plutôt que les fonctions variadiques
test_latseq : module de mesure du temps pris par log_measure()
2020-03-25 12:01:52 +01:00
flavien Ronteix--Jacquet dM
3dde316b22 test_latseq : mesure du temps 2020-03-23 17:43:25 +01:00
flavien Ronteix--Jacquet dM
9a6c794034 test_latseq : multithread functionnel 2020-03-20 12:23:31 +01:00
flavien Ronteix--Jacquet dM
cf9d524027 latseq : premiere version fonctionnelle par test_latseq a 2020-03-19 19:15:53 +01:00
ferrieux
e4d9bba825 Small bug in argv parsing 2020-03-18 22:21:06 +01:00
flavien Ronteix--Jacquet dM
8a13dcad72 latseq : test_latseq compile 2020-03-18 18:12:30 +01:00
flavien Ronteix--Jacquet dM
58478c9fcc Makefile cleanup 2020-03-18 17:07:25 +01:00
flavien Ronteix--Jacquet dM
a639140fb9 latseq : Creation du module de test de latseq, ne compile pas 2020-03-18 13:28:28 +01:00
flavien Ronteix--Jacquet dM
e20f10b1c8 latseq : some tests 2020-03-17 19:48:42 +01:00
flavien Ronteix--Jacquet dM
d7b85f69c5 latseq :
- use of global latseq veriable instead of ptr to allocate
-  add latseq_registry
- add latseq_thread_data
- add init_thread_for_latseq
2020-03-12 16:44:09 +01:00
flavien Ronteix--Jacquet dM
5116aa509a latseq : inline stuff 2020-03-11 19:05:32 +01:00
flavien Ronteix--Jacquet dM
17fab753c4 latseq : variadic function for log_measure 2020-03-11 11:32:36 +01:00
flavien Ronteix--Jacquet dM
91afd019fc latseq : new test point in dlsch_coding 2020-03-06 16:18:14 +01:00
flavien Ronteix--Jacquet dM
1412b1dc2a latseq : check g_latseq initialized
change filelog output
2020-03-06 11:49:42 +01:00
flavien Ronteix--Jacquet dM
c0f9af4955 latseq : - change log timestamp format to timeval
- lower priority on logger pthread
2020-03-05 19:13:21 +01:00
flavien Ronteix--Jacquet dM
d148bdd4d3 latseq : first compile without warnings/errors 2020-03-04 19:52:38 +01:00
flavien Ronteix--Jacquet dM
e78b0b12de latseq : First implem, not tested yet 2020-03-04 18:14:18 +01:00
flavien Ronteix--Jacquet dM
e98bf690ff NEW Latseq moved to latseq-dev 2020-03-04 07:39:41 +01:00
371 changed files with 148432 additions and 11913 deletions

20
.gitignore vendored
View File

@@ -9,9 +9,29 @@ cmake_targets/nas_sim_tools/build/
log/
lte_build_oai/
targets/bin/
core
*.lseq
*.lcheck
*.out
# object files
*.o
*.obj
*.orig
# vscode
.vscode
.vscode/launch.json
# python virtual env
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Tags for vim/global
GPATH

1
Makefile Normal file
View File

@@ -0,0 +1 @@
include ../Makefile

View File

@@ -21,8 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
servingCellConfigCommon = (
{
#spCellConfigCommon

View File

@@ -32,7 +32,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (
{

View File

@@ -21,7 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -32,7 +32,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -21,7 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -44,7 +44,6 @@ gNBs =
local_s_portd = 2152;
remote_s_portc = 500;
remote_s_portd = 2152;
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -36,7 +36,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -37,7 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;

View File

@@ -38,7 +38,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;

View File

@@ -21,7 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -21,7 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -19,7 +19,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"

View File

@@ -41,7 +41,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"
do_SRS = 1;

View File

@@ -37,7 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"

View File

@@ -37,7 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"
do_SRS = 1;

View File

@@ -37,7 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
#pusch_TargetSNRx10 = 200;
#pucch_TargetSNRx10 = 200;
ul_prbblacklist = "51,52,53,54"

View File

@@ -37,7 +37,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
#pusch_TargetSNRx10 = 200;

View File

@@ -21,7 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (
@@ -219,7 +218,7 @@ RUs = (
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.18.85";
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2";
}
);

View File

@@ -19,7 +19,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
servingCellConfigCommon = (
{

View File

@@ -20,7 +20,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -32,7 +32,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -32,9 +32,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
sib1_tda = 15;
min_rxtxtime = 6;

View File

@@ -0,0 +1,240 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2680000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.193.4.249";
ipv6 = "";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.193.4.248";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "10.193.4.248";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "10.193.4.248";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
#scheduler_mode = "fairRR";
#scheduler_mode = "default";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 120;
eNB_instances = [0];
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="warn";
global_log_verbosity ="high";
hw_log_level ="warn";
hw_log_verbosity ="high";
phy_log_level ="warn";
phy_log_verbosity ="high";
mac_log_level ="warn";
mac_log_verbosity ="high";
rlc_log_level ="warn";
rlc_log_verbosity ="high";
pdcp_log_level ="warn";
pdcp_log_verbosity ="high";
rrc_log_level ="warn";
rrc_log_verbosity ="high";
};

View File

@@ -0,0 +1,238 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB-Eurecom-LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_eNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2680000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -27;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -96;
pusch_alpha = "AL1";
pucch_p0_Nominal = -104;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "10.193.4.249";
ipv6 = "";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth1";
ENB_IPV4_ADDRESS_FOR_S1_MME = "10.193.4.248";
ENB_INTERFACE_NAME_FOR_S1U = "eth1";
ENB_IPV4_ADDRESS_FOR_S1U = "10.193.4.248";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "10.193.4.248";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 116;
eNB_instances = [0];
sdr_addrs = "type=x300";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_DISABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="warn";
global_log_verbosity ="high";
hw_log_level ="warn";
hw_log_verbosity ="high";
phy_log_level ="warn";
phy_log_verbosity ="high";
mac_log_level ="warn";
mac_log_verbosity ="high";
rlc_log_level ="warn";
rlc_log_verbosity ="high";
pdcp_log_level ="warn";
pdcp_log_verbosity ="high";
rrc_log_level ="warn";
rrc_log_verbosity ="high";
};

View File

@@ -16,7 +16,7 @@ Ref :
L1 Rx processing : 175.0
PUSCH inner-receiver : 100.0
PUSCH decoding : 180.0
DL & UL scheduling timing stats : 37.0
DL & UL scheduling timing : 37.0
UL Indication : 38.0
Threshold :
feprx : 1.25
@@ -28,5 +28,5 @@ Threshold :
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
DL & UL scheduling timing stats : 1.25
DL & UL scheduling timing : 1.25
UL Indication : 1.25

View File

@@ -17,7 +17,7 @@ Ref :
PUSCH inner-receiver : 100.0
#PUSCH decoding : 180.0
PUSCH decoding : 240.0
DL & UL scheduling timing stats : 37.0
DL & UL scheduling timing : 37.0
UL Indication : 38.0
Threshold :
feprx : 1.25
@@ -29,5 +29,5 @@ Threshold :
L1 Rx processing : 1.25
PUSCH inner-receiver : 1.25
PUSCH decoding : 1.25
DL & UL scheduling timing stats : 1.25
DL & UL scheduling timing : 1.25
UL Indication : 1.25

View File

@@ -529,14 +529,14 @@ class Dashboard:
mr_notes = editable_mr.notes.list(all=True)
body = '[Consolidated Test Results](https://oaitestdashboard.s3.eu-west-1.amazonaws.com/MR'+mr+'/index.html)\\\n'
body += 'Tested CommitID: ' + commit + '\\\n'
body += 'Tested CommitID: ' + commit
for i in range(0,n_tests):
jobname = args[4*i]
buildurl = args[4*i+1]
buildid = args[4*i+2]
status = args[4*i+3]
body += jobname+': **'+status+'** ([' + buildid + '](' + buildurl + '))\\\n'
body += '\\\n' + jobname + ': **'+status+'** ([' + buildid + '](' + buildurl + '))'
#create new note
mr_note = editable_mr.notes.create({

View File

@@ -25,7 +25,7 @@ gnb :
L1 Rx processing:
PUSCH inner-receiver:
PUSCH decoding:
DL & UL scheduling timing stats:
DL & UL scheduling timing:
UL Indication:
graph :
page1:
@@ -45,5 +45,5 @@ gnb :
page4:
rt.PUSCH inner-receiver:
rt.PUSCH decoding:
rt.DL & UL scheduling timing stats:
rt.DL & UL scheduling timing:
rt.UL Indication:

View File

@@ -32,7 +32,7 @@
<testCase id="000001">
<class>Build_eNB</class>
<desc>Build gNB</desc>
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<Build_eNB_args>-w USRP -c --gNB --ninja --noavx512</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>

View File

@@ -50,7 +50,7 @@
<testCase id="000002">
<class>Build_eNB</class>
<desc>Build gNB</desc>
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<Build_eNB_args>-w USRP -c --gNB --ninja --noavx512</Build_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<backgroundBuild>True</backgroundBuild>

View File

@@ -34,7 +34,7 @@
<mode>TesteNB</mode>
<class>Build_eNB</class>
<desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169</Build_eNB_args>
<Build_eNB_args>--gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169 --noavx512</Build_eNB_args>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>

View File

@@ -32,7 +32,7 @@
<testCase id="000001">
<class>Build_PhySim</class>
<desc>Build for physical simulator</desc>
<physim_build_args>--phy_simulators --ninja</physim_build_args>
<physim_build_args>--phy_simulators --ninja --noavx512</physim_build_args>
<forced_workspace_cleanup>FALSE</forced_workspace_cleanup>
</testCase>

View File

@@ -88,7 +88,7 @@
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>40</ping_rttavg_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050001">
<class>Ping</class>
@@ -96,7 +96,7 @@
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>40</ping_rttavg_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>

View File

@@ -88,7 +88,7 @@
<id>nrmodule2_quectel</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>40</ping_rttavg_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>
<testCase id="050003">
<class>Ping</class>
@@ -96,7 +96,7 @@
<id>nrmodule2_quectel</id>
<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>40</ping_rttavg_threshold>
<ping_rttavg_threshold>60</ping_rttavg_threshold>
</testCase>

View File

@@ -203,17 +203,23 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
if(EXISTS "/proc/cpuinfo")
file(STRINGS "/proc/cpuinfo" CPUINFO REGEX flags LIMIT_COUNT 1)
if (CPUINFO MATCHES "avx2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2")
message("NOAVX512 is ${NOAVX512}")
if (CPUINFO MATCHES "avx512bw" AND "${NOAVX512}" STREQUAL "False")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512 " )
set(COMPILATION_AVX2 "True")
else()
set(COMPILATION_AVX2 "False")
endif()
if (CPUINFO MATCHES "sse4_1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul")
endif()
if (CPUINFO MATCHES "ssse3")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3")
if (CPUINFO MATCHES "avx2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2")
set(COMPILATION_AVX2 "True")
else()
set(COMPILATION_AVX2 "False")
endif()
if (CPUINFO MATCHES "sse4_1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul")
endif()
if (CPUINFO MATCHES "ssse3")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3")
endif()
endif()
else()
Message("/proc/cpuinfo does not exit. We will use manual CPU flags")
@@ -224,11 +230,11 @@ set(C_FLAGS_PROCESSOR " ${C_FLAGS_PROCESSOR} ${CFLAGS_PROCESSOR_USER}")
Message("C_FLAGS_PROCESSOR is ${C_FLAGS_PROCESSOR}")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) )
Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ")
endif()
endif()
#if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
# if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) )
# Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ")
# endif()
#endif()
#
# add autotools definitions that were maybe used!
@@ -247,6 +253,22 @@ add_boolean_option(SANITIZE_ADDRESS False "enable the address sanitizer (ASan)")
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
# There seems to be some incompatibility with pthread_create and the RT scheduler, which
# results in pthread_create hanging.
#
# When we switch from Ubuntu 16.04 to 18.04, we found that running with the address sanitizer,
# the pthread_create function calls were not working. The inital thought was that we were
# trying to create a thread that was not-blocking and would eventually crash the machine during
# the run. After more debugging, we found that we would never even start the thread. We narrowed
# down the first two instances of pthread_create in the gNB and NR UE to be sctp_eNB_task and
# one_thread, respectively. We found that adding sleeps, and various other pauses to the threads
# had not effect. From there, we found that if we add an abort(); prior to the thread loop, we
# do not execute that. This indicated to us that the problem is not likely to be a non-blocking
# thread, but perhaps and issue with pthread_create itself. From there we begain to research the
# issue on the web. See: https://github.com/google/sanitizers/issues/1125
#
# Google searching indicates this appears to be a problem since at least 2018. This could be something
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -318,6 +340,7 @@ add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdo
add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace
add_boolean_option(PRINT_STATS False "This adds the possibility to see the status")
add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" )
add_boolean_option(LATSEQ False "Active Latency Sequence tools")
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_TIMING_TRACE False "Activate UE timing trace")
@@ -1180,6 +1203,7 @@ add_library(UTIL
${OPENAIR2_DIR}/UTIL/LISTS/list2.c
${OPENAIR_DIR}/common/utils/LOG/log.c
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c
${OPENAIR2_DIR}/UTIL/MATH/oml.c
${OPENAIR2_DIR}/UTIL/OPT/probe.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
@@ -1384,8 +1408,11 @@ set(PHY_NR_CODINGIF
)
add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} )
target_link_libraries(ldpc_orig PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} )
target_link_libraries(ldpc_optim PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} )
target_link_libraries(ldpc_optim8seg PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} )
target_link_libraries(ldpc_cl OpenCL)
add_dependencies(ldpc_cl nrLDPC_decoder_kernels_CL)
@@ -1397,6 +1424,7 @@ if (CUDA_FOUND)
endif (CUDA_FOUND)
add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS)
add_library(coding MODULE ${PHY_TURBOSRC} )
@@ -1542,9 +1570,10 @@ set(PHY_SRC_UE
set(PHY_NR_SRC_COMMON
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
)
set(PHY_NR_SRC
@@ -1568,7 +1597,6 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
@@ -1616,6 +1644,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/csi_rx.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
@@ -1694,6 +1723,7 @@ set(PHY_MEX_UE
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c
${OPENAIR_DIR}/common/utils/LOG/log.c
${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c
${OPENAIR_DIR}/common/utils/T/T.c
${OPENAIR_DIR}/common/utils/T/local_tracer.c
)
@@ -1925,6 +1955,7 @@ set (MAC_SRC_UE
set (MAC_NR_SRC_UE
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c
${NR_UE_MAC_DIR}/config_ue.c
${NR_UE_MAC_DIR}/mac_vars.c
${NR_UE_MAC_DIR}/main_ue_nr.c
@@ -3153,3 +3184,4 @@ ADD_CUSTOM_TARGET(oarf
)
include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt)
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)

View File

@@ -1062,7 +1062,8 @@
(Test3: PBCH-only, 217 PRB),
(Test4: PBCH and synchronization, 217 RPB),
(Test5: PBCH-only, 273 PRB),
(Test6: PBCH and synchronization, 273 PRB)</desc>
(Test6: PBCH and synchronization, 273 PRB),
(Test7: PBCH and synchronization, 106PBR, SSB SC OFFSET 6)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1074,8 +1075,9 @@
-s-11 -S-8 -n10 -R217
-s-11 -S-8 -n10 -o8000 -I -R217
-s-11 -S-8 -n10 -R273
-s-11 -S-8 -n10 -o8000 -I -R273</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6</tags>
-s-11 -S-8 -n10 -o8000 -I -R273
-s-11 -S-8 -n10 -R106 -O6</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6 nr_pbchsim.test7</tags>
<search_expr_true>PBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -1104,7 +1106,9 @@
(Test19: Mapping type A, 3 DMRS Symbols),
(Test20: Mapping type B, 4 DMRS Symbols),
(Test21: 4x4 MIMO, 1 Layer),
(Test22: 4x4 MIMO, 2 Layers)</desc>
(Test22: 4x4 MIMO, 2 Layers),
(Test23: 25 PRBs, 15 kHz SCS)
(Test24: MCS 0, low SNR performance)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1132,8 +1136,10 @@
-n100 -s2 -U 2 0 2
-n100 -s2 -U 2 1 3
-n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
-n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22</tags>
-n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4
-n100 -m0 -e0 -R25 -b25 -i 2 1 0
-n100 -e0 -t95 -S-1.0 -i 2 1 0</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23 nr_dlsim.test24</tags>
<search_expr_true>PDSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -1306,9 +1312,14 @@
(Test12: SC-FDMA, 216 PRBs),
(Test13: SC-FDMA, 273 PRBs),
(Test14: SC-FDMA, 3 DMRS),
(Test15: MCS 19 50 PRBs 2 RX_Antenna)
(Test16: MCS 9 106 PRBs MIMO 2 layers)
(Test17: MCS 9 106 PRBs MIMO 4 layers)</desc>
(Test15: MCS 19 50 PRBs 2 RX_Antenna),
(Test16: MCS 9 106 PRBs MIMO 2 layers),
(Test17: MCS 9 106 PRBs MIMO 4 layers),
(Test18: 25 PRBs, 15 kHz SCS),
(Test19: 3GPP G-FR1-A4-13 2 RX Antennas Requirements Test),
(Test20: 3GPP G-FR1-A4-13 4 RX Antennas Requirements Test),
(Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test),
(Test22: MCS 0, low SNR performance)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1320,20 +1331,24 @@
-n100 -m28 -s20
-n100 -m9 -R217 -r217 -s5
-n100 -m9 -R273 -r273 -s5
-n100 -s5 -U 2 0 1
-n100 -s5 -T 2 1 2 -U 2 0 2
-n100 -s5 -T 2 2 2 -U 2 1 2
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
-n100 -Z -s5
-n100 -s5 -U 4 0 1 1 1
-n100 -s5 -T 2 1 2 -U 4 0 2 1 1
-n100 -s5 -T 2 2 2 -U 4 1 2 1 1
-n100 -s5 -a4 -b8 -T 2 1 2 -U 4 1 3 1 1
-n100 -s5 -Z
-n100 -s5 -Z -r75
-n50 -s5 -Z -r216 -R217
-n50 -s5 -Z -r270 -R273
-n100 -s5 -Z -U 2 0 2
-n100 -s5 -Z -U 4 0 2 1 2
-n100 -m19 -s10 -S15 -z2
-n100 -m9 -r106 -s10 -W2 -y2 -z2
-n100 -m9 -r106 -s20 -W4 -y4 -z4</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17</tags>
-n100 -m9 -r106 -s20 -W4 -y4 -z4
-n100 -u0 -m0 -R25 -r25 -i 2 1 0
-m16 -r106 -s8.8 -S9.4 -z2 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s5.4 -S6 -z4 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-n100 -m0 -S -0.6 -i 2 1 0</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21 nr_ulsim.test22</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -1344,10 +1359,11 @@
<desc>nr_prachsim Test cases. (Test1: 30kHz SCS, 106 PRBs, Prach format A2),
(Test2: 30kHz SCS, 217 PRBs, Prach format A2),
(Test3: 30kHz SCS, 273 PRBs, Prach format A2),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test5: 120kHz SCS, 32 PRBs, Prach format A2),
(Test6: 120kHz SCS, 66 PRBs, Prach format A2),
(Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc>
(Test7: 120kHz SCS, 66 PRBs, High Speed Enabled),
(Test8: 15kHz SCS, 25 PRBs)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1357,11 +1373,12 @@
<main_exec_args>-a -s -30 -n 100 -p 63 -R 106
-a -s -30 -n 100 -p 63 -R 217
-a -s -30 -n 100 -p 63 -R 273
-a -s -30 -n 100 -p 63 -R 106 -c 4
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
-a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args>
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags>
-a -s -30 -n 100 -p 63 -R 106 -c 4
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
-a -s -30 -n 100 -R 66 -m 3 -c52 -H
-a -s -30 -n 100 -p 99 -R 25 -m 0</main_exec_args>
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7 nr_prachsim.test8</tags>
<search_expr_true>PRACH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>

View File

@@ -55,6 +55,7 @@ BUILD_COVERITY_SCAN=0
DISABLE_HARDWARE_DEPENDENCY="False"
CMAKE_BUILD_TYPE="RelWithDebInfo"
CMAKE_CMD="$CMAKE"
NOAVX512="False"
BUILD_ECLIPSE=0
NR="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope"
@@ -164,6 +165,8 @@ Options:
Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES or \"all\"
--usrp-recplay
Build for I/Q record-playback modes
--noavx512
Build without AVX512 if it is present on CPU
-k | --skip-shared-libraries
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
--ninja
@@ -392,6 +395,10 @@ function main() {
CMAKE_CMD="$CMAKE_CMD -DT_TRACER=False"
echo_info "Disabling the T tracer"
shift 1;;
--enable-latseq)
CMAKE_CMD="$CMAKE_CMD -DLATSEQ=True"
echo info "Enabling Latency Sequence measures"
shift 1;;
--disable-hardware-dependency)
echo_info "Disabling hardware dependency for compiling software"
DISABLE_HARDWARE_DEPENDENCY="True"
@@ -436,6 +443,10 @@ function main() {
fi
fi
shift 2;;
--noavx512)
NOAVX512="True"
echo_info "Disabling AVX512"
shift 1;;
-k | --skip-shared-libraries)
SKIP_SHARED_LIB_FLAG="True"
echo_info "Skipping build of shared libraries, rfsimulator and transport protocol libraries"
@@ -445,6 +456,7 @@ function main() {
MAKE_CMD=ninja
shift;;
--sanitize-address | -fsanitize=address)
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
shift;;
--ittiSIM)
@@ -624,6 +636,7 @@ function main() {
cd $DIR/$BUILD_DIR/build
if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi
if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi
CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\""
echo_info "running $CMAKE_CMD"
eval $CMAKE_CMD ../..
@@ -713,11 +726,11 @@ function main() {
# simlist="ldpctest"
for f in $simlist ; do
compilations \
ran_build $f \
$BUILD_DIR $f \
$f $dbin/$f.$REL
done
compilations \
ran_build coding \
$BUILD_DIR coding \
libcoding.so $dbin/libcoding.so
fi
@@ -729,7 +742,7 @@ function main() {
simlist="secu_knas_encrypt_eia1 secu_kenb aes128_ctr_encrypt aes128_ctr_decrypt secu_knas_encrypt_eea2 secu_knas secu_knas_encrypt_eea1 kdf aes128_cmac_encrypt secu_knas_encrypt_eia2"
for f in $simlist ; do
compilations \
ran_build test_$f \
$BUILD_DIR test_$f \
test_$f $dbin/test_$f.$REL
done
fi

View File

@@ -109,6 +109,7 @@ check_supported_distribution() {
"ubuntu18.04") return 0 ;;
"ubuntu16.04") return 0 ;;
"fedora35") return 0 ;;
"fedora36") return 0 ;;
"rhel7") return 0 ;;
"rhel7.6") return 0 ;;
"rhel7.7") return 0 ;;
@@ -216,6 +217,7 @@ compilations() {
if [ "$MAKE_CMD" != "" ]; then
$MAKE_CMD $2
else
if [ "$VERBOSE_COMPILE" == "1" ]; then
$COV_SCAN_PREFIX make -j`nproc` $2 VERBOSE=$VERBOSE_COMPILE
else
@@ -623,7 +625,6 @@ check_install_additional_tools (){
android-tools-adb \
wvdial \
sshpass \
nscd \
bc \
ntp"
elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
@@ -648,7 +649,6 @@ check_install_additional_tools (){
wvdial \
numpy \
sshpass \
nscd \
python2-paramiko \
python-pyroute2 \
python-netifaces \
@@ -676,7 +676,6 @@ check_install_additional_tools (){
wvdial \
python-numpy \
sshpass \
nscd \
python-paramiko \
python-pyroute2 \
python-netifaces \

264
common/utils/LATSEQ/README Normal file
View File

@@ -0,0 +1,264 @@
# LATency SEQuence analysis extension for OpenAirInterface
A tool for internal latency analysis in Base Station.
Code licenced under BSD-3. See more on https://github.com/Orange-OpenSource/LatSeq
Author : Flavien Ronteix--Jacquet (Orange Innovation), Alexandre Ferrieux (Orange Innovation)
Email : flavien.ronteixjacquet@orange.com, alexandre.ferrieux@orange.com
## Installation
- Put LatSeq extension source code in OAI code (https://gitlab.eurecom.fr/oai/openairinterface5g). We recommend to put it in the path common/utils/LATSEQ.
- In cmake_targets/CMakeLists.txt put `add_boolean_option(LATSEQ True "Active Latency Sequence tools")`. Also add Latseq to compiled source `set(UTIL_SRC... ${OPENAIR_DIR}/common/utils/LATSEQ/latseq.c`
- Put test/ in targets/TEST/LATSEQ/
- Verify installation of LatSeq with `make` in targets/TEST/LATSEQ
## Usage
0) Add init_latseq(appname) and close_latseq() in main Base Station thread at the start and end.
1) Add a new LatSeq measure point in the code with
#include "common/utils/LATSEQ/latseq.h"
#if LATSEQ
LATSEQ_P("D pdcp--rlc", "pdcp%d.rlc%d", 0, 1);
#endif
where first argument is the direction, the second the observed segment and the third argument is a string of data_identifier
1) Compile OAI code with cmake option LATSEQ at True
2) Run scanario for Uplink and Downlink
3) Process lseq traces to yield data do statistics with LatSeq tools
More in docs/Latseq.pdf
## LatSeq measurement module
For now, latseq is designed to be the more independant as possible : Means that it does not use oai LOG system (not register by logInit()) and the flag "LATSEQ" disable all lines related to latseq in the code (using #ifdef). In a second time, it could be conceivable to integrate more deeply latseq into oai code.
latseq_t, global structure for latseq embodied the latseq logging info. log_buffer is a circular buffer with 2 head index, i_write_head and i_read_head. this buffer of latseq_element_t is designed to bo mutex-less.
LATSEQ_P macro calls log_measure(). The idea is to have a low-footprint at logging explains why log_measure() should do a minimal amount of operations.
latseq_log_to_file() is the function run in the logger thread. It writes log_elements in the log file.
LATSEQ_P with direction of D (Downlink) or U (Uplink) observed the passage of a data.
LATSEQ_P with direction of I (Information) observed a scalar property at a point of code. e.g. buffer occupancy.
**We assume that**:
- All the point and latseq module run on the same machine (to don't have to synchronize clock of different machines)
- Clock give by asm rdtsc is same for all the CPU cores (constant_tsc enabled)
## TOOLS
Get scripts on https://github.com/Orange-OpenSource/LatSeq/tools
- rdtsctots : convert rdtsc timestamp to unix timestamp value
- latseq_logs : convert lseq log file into useful json file for statistics and visualization
- filter_Is.awk : filter contextual informations
- lseqj2any : generate waterfall to format gp or svg
- latseq_checker : verify constitency of Latseq points before compiling
- latseq_filter : filter output of latseq_logs
- latseq_stats : perform statistic
### latseq_checker
Checker to verify that points LATSEQ_P points are consistent.
Verify the number of argument, the emptiness, format...
ex. ./latseq_checker.sh /home/oai/
### rdtsctots
convert rdtsc value to unix timestamp value
ex. `./rdtsctots.py trace_raw.lseq > trace.lseq`
### latseq_logs
Proceeds LatSeq logs.
A *.lseq is required.
By default, builds the latseq_log object.
- Reads lseq file given in raw_input
- Cleans raw_input to inputs.
- Builds points structure and paths possible.
- Saves object related to the *.lseq files to a *.plk (pickle)
**Arguments**:
- "-h" : help
- "-C" : cleans pickle file associated to the log file and rebuild
- "-l" : required lseq file of fingerprints
- "-i" : request cleaned input measurements in the case of command line script
- "-r" returns the paths present in the log file as json.
```
{
"D": [
["ip", "pdcp.in",...],
...
],
"U": ...
}
``̀
- "-p" returns points structure as json.
Becareful, if journeys has not been rebuilt, then you do not have "duration" attibute which is used for statistics.
```
{
"layer1.point": {
"next": [layer2.point2,...],
"count": 5,
"dir": [0],
"duration": {
"journeys uid": 0.0115,
...
}
}
}
{
...
}
```
- "-j" returns journeys structure as json.
- Rebuilds journeys with rebuild_packets_journey method
- Builds out_journeys
```
{
"uid": 52,
"dir": 0,
"glob": {
"rnti": "54614",...
},
"set": [[1542, 1592409314.253678, "rlc.rx.am--pdcp.rx"],[...],...], # set of pointer to input entry
"set_ids": {
"drb": "1",...
},
"path": 0, # path according to direction and paths obtainable by -p
"completed": true,
"ts_in": 123.456,
"ts_out": 789.012
}
{
...
}
```
- "-m" returns metadata of information as list
```
20200423_143226.191801 rlc.am.txbuf occ1:drb1
20200423_143226.191802 rlc.am.txbuf occ2:drb1
...
20200423_143226.192000 rlc.um.txbuf occ15:drb2
```
- "-o" returns a latseq journey file line by line. redirects output to a file to have a *.lseqj for waterfall generation
```
#funcId ip pdcp.in pdcp.tx rlc.tx.um rlc.seg.um mac.mux mac.txreq phy.out.proc phy.in.proc mac.demux rlc.rx.um rlc.unseg.um pdcp.rx
20200423_143226.191801 D (len64) ip--pdcp.in.gtp uid0.rnti54614.drb1.gsn12
20200423_143226.191802 D (len64) pdcp.in--pdcp.tx uid0.rnti54614.drb1.gsn12.psn10
20200423_143226.191803 D (len66) pdcp.tx--rlc.tx.um uid0.rnti54614.drb1.psn10.lcid3.rsdu0
```
Requested json are printed in stdout line by line
Errors, Warnings, Informations are printed in stderr
Example of usage:
./latseq_logs.py -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -j -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -p -l ~/latseq.23042020.lseq 2>/dev/null
./latseq_logs.py -o -l ~/latseq.23042020.lseq > 23042020.lseqj 2>/dev/null
### latseq_filter
Applies a filter to a json stream.
It uses jq filters.
Help website to design jq filter : https://jqplay.org/
Takes a file with a filter or a filter as string in argument.
Example of usage:
./latseq_filter.sh journeys_downlinks_gsn.lfilter
cat journeys_downlinks_gsn.lfilter
> select(.["dir"] == 0 and .["set_ids"]["gsn"] == "18")
### latseq_stats
Performs statistics from json. Report json or print in stdout.
By default, reads on stdin. "-l" *.lseq will try to open a *.json associated.
By default, returns a json report on stdout.
Arguments:
- "-f" enables to choose format "json", "csv",...
- "-P" prints statistics formated by the latseq_stats module.
- "-sj" returns statistics on journeys
`̀``
{
"D": {
"size": 34,
"min": 0.19598,
"max": 1.187086,
"mean": 0.788976,
"stdev": 0.153623,
"quantiles": [0.694859, 0.699043, 0.834942, 0.838041, 0.955701]
}
`̀``
- "-sjpp" returns the shares of delay introduced by each point for each journeys by path.
```
{
"U02": { # Uplinks, path 0, point 2
"size": 4,
"min": 0,
"max": 0.7273,
"mean": 0.36239999999999994,
"stdev": 0.2915949673776967,
"quantiles": [
0.025005000000000003,
0.125025,
0.36114999999999997,
0.598525,
0.7015449999999999
]
}
}
```
- "-sp" returns statistics on points
```
{
"pdcp.rx": {
"dir": "U",
"size": 4,
"min": 0.01,
"max": 0.02,
"mean": 0.015,
"stdev": 0.005,
"quantiles": [0.012,...] # 5%, 25%, 50%, 75%, 95%
},
...
}
`̀``
- "-djd" returns data journeys' duration
`̀``
{
"00": { # first decimal indicates uplink/downlink followed by the journey unique id
"ts": 1587645146.191801,
"durations": 0.19598 # in ms
},
...
}
`̀``
Example of usage of the full toolchain for LatSeq Analysis Module
./latseq_logs.py -l ~/latseq.simple.lseq -j 2>/dev/null | ./latseq_filter.sh journeys_downlinks_gsn.lfilt | ./latseq_stats.py -sj --print
### lseqj2any
generate waterfall
cat uplink_burst.30102020_203233.lseqj | lseqj2any gp > uplink_burst.gp
## TEST_LATSEQ
in targets/TEST/LATSEQ test_latseq test different part of latseq module
- "h" : help menu
- "i" : test init and close latseq
- "a" : test init, capture 2 fingerprints and close
- "t" : same test as "a" but with 2 concurrent threads
- "m" : test measurement time to capture 1000000 fingerprints
- "n" : test measurement time to capture 1000 fingerprints with 1,2,3,5,10 data identifiers
- "w" : test writer speed for a simplified data collector

View File

@@ -0,0 +1,284 @@
/*
* Software Name : LatSeq
* Version: 1.0
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 Orange Labs
* SPDX-License-Identifier: BSD-3-Clause
*
* This software is distributed under the BSD 3-clause,
* the text of which is available at https://opensource.org/licenses/BSD-3-Clause
* or see the "license.txt" file for more details.
*
* Author: Flavien Ronteix--Jacquet
* Software description: LatSeq measurement part core
*/
#define _GNU_SOURCE // required for pthread_setname_np()
#include "latseq.h"
/*--- GLOBALS and EXTERNS ----------------------------------------------------*/
latseq_t g_latseq;
__thread latseq_thread_data_t tls_latseq = {
.th_latseq_id = 0
}; // need to be a thread local storage variable.
pthread_t logger_thread;
pthread_t fflusher_thread;
//double cpuf; //cpu frequency in MHz -> usec. Should be initialized in main.c
extern volatile int oai_exit; //oai is ended. Close latseq
/*--- UTILS FUNCTIONS --------------------------------------------------------*/
uint64_t get_cpu_freq_cycles(void)
{
uint64_t ts = l_rdtsc();
sleep(1);
return (l_rdtsc() - ts);
}
/*--- MAIN THREAD FUNCTIONS --------------------------------------------------*/
int init_latseq(const char * appname, uint64_t cpufreq)
{
// init members
g_latseq.is_running = 0;
//synchronise time and rdtsc
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
g_latseq.time_zero = (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
g_latseq.rdtsc_zero = l_rdtsc(); //check at compile time that constant_tsc is enabled in /proc/cpuinfo
if (cpufreq == 0) {
g_latseq.cpu_freq = get_cpu_freq_cycles();
} else {
g_latseq.cpu_freq = cpufreq;
}
// Open traces
char time_string[16];
strftime(time_string, sizeof (time_string), "%d%m%Y_%H%M%S", localtime(&ts.tv_sec));
g_latseq.filelog_name = (char *)malloc(LATSEQ_MAX_STR_SIZE);
sprintf(g_latseq.filelog_name, "%s.%s.lseq", appname, time_string);
//open logfile
g_latseq.outstream = fopen(g_latseq.filelog_name, "w");
if (g_latseq.outstream == NULL) {
g_latseq.is_running = 0;
printf("[LATSEQ] Error at opening log file\n");
return -1;
}
//write header
char hdr[] = "# LatSeq packet fingerprints\n# By Alexandre Ferrieux and Flavien Ronteix Jacquet\n# timestamp\tU/D\tsrc--dest\tlen:ctxtId:localId\n";
size_t ret = fwrite(hdr, sizeof(char), sizeof(hdr) - 1, g_latseq.outstream);
if (ret < 0) {
printf("[LATSEQ] Error at opening log file\n");
g_latseq.is_running = 0;
return -1;
}
fprintf(g_latseq.outstream, "%ld S rdtsc--gettimeofday %ld.%09ld\n", g_latseq.rdtsc_zero, ts.tv_sec, ts.tv_nsec);
fflush(g_latseq.outstream);
// init registry
g_latseq.local_log_buffers.read_ith_thread = 0;
g_latseq.local_log_buffers.nb_th = 0;
memset(&g_latseq.local_log_buffers.i_read_heads, 0, MAX_NB_THREAD * sizeof(unsigned int));
// init stat
g_latseq.stats.entry_counter = 0;
g_latseq.stats.bytes_counter = 0;
// init latseq_thread_t
tls_latseq.th_latseq_id = 0;
// init logger thread
g_latseq.is_running = 1;
return init_logger_latseq();
}
int init_logger_latseq(void)
{
// init thread to write buffer to file
if(pthread_create(&logger_thread, NULL, (void *) &latseq_log_to_file, NULL) > 0) {
printf("[LATSEQ] Error at starting data collector\n");
g_latseq.is_running = 0;
return -1;
}
// init thread to flush into file
pthread_create(&fflusher_thread, NULL, (void *) &fflush_latseq_periodically, NULL);
return g_latseq.is_running;
}
void latseq_print_stats(void)
{
printf("[LATSEQ] === stats ===\n");
printf("[LATSEQ] number of entry in log : %d\n", g_latseq.stats.entry_counter);
//printf("[LATSEQ] heads positions : %d (Write) : %d (Read)\n", g_latseq.i_write_head, g_latseq.i_read_head);
}
int close_latseq(void)
{
g_latseq.is_running = 0;
//Wait logger finish to write data
pthread_join(logger_thread, NULL);
//At this point, data_ids and points should be freed by the logger thread
free((char*) g_latseq.filelog_name);
if (fclose(g_latseq.outstream)){
fprintf(stderr, "[LATSEQ] error on closing %s\n", g_latseq.filelog_name);
exit(EXIT_FAILURE);
}
return 1;
}
/*--- INSTRUMENTED THREAD FUNCTIONS ------------------------------------------*/
int init_thread_for_latseq(void)
{
//Init tls_latseq for local thread
tls_latseq.i_write_head = 0; //local thread tls_latseq
//memset(tls_latseq.log_buffer, 0, sizeof(tls_latseq.log_buffer));
//Register thread in the registry
latseq_registry_t * reg = &g_latseq.local_log_buffers;
//Check if space left in registry
if (reg->nb_th >= MAX_NB_THREAD) {
g_latseq.is_running = 0;
fprintf(g_latseq.outstream, "Max instrumented thread MAX_NB_THREAD reached\n");
return -1;
}
reg->tls[reg->nb_th] = &tls_latseq;
reg->i_read_heads[reg->nb_th] = 0;
//Give id to the thread
reg->nb_th++;
tls_latseq.th_latseq_id = reg->nb_th;
return 0;
//TODO : No destroy function ? What happens when thread is stopped and data had not been written in the log file ?
}
/*--- DATA COLLECTOR THREAD FUNCTIONS ----------------------------------------*/
static int write_latseq_entry(void)
{
//reference to latseq_thread_data
latseq_thread_data_t * th = g_latseq.local_log_buffers.tls[g_latseq.local_log_buffers.read_ith_thread];
//read_head for this thread_data
unsigned int * i_read_head = &g_latseq.local_log_buffers.i_read_heads[g_latseq.local_log_buffers.read_ith_thread];
//reference to element to write
latseq_element_t * e = &th->log_buffer[(*i_read_head)%RING_BUFFER_SIZE];
char * tmps;
//Convert latseq_element to a string
tmps = calloc(LATSEQ_MAX_STR_SIZE, sizeof(char));
//Write the data identifier, e.g. do the vsprintf() here and not at measure()
//We put the first NB_DATA_IDENTIFIERS elements of array, even there are no NB_DATA_IDENTIFIERS element to write. sprintf will get the firsts...
sprintf(
tmps,
e->format,
e->data_id[0],
e->data_id[1],
e->data_id[2],
e->data_id[3],
e->data_id[4],
e->data_id[5],
e->data_id[6],
e->data_id[7],
e->data_id[8],
e->data_id[9]);
// Write into file
int ret = fprintf(g_latseq.outstream, "%ld %s %s\n",
e->ts,
e->point,
tmps);
if (ret < 0) {
g_latseq.is_running = 0;
fclose(g_latseq.outstream);
fprintf(stderr, "[LATSEQ] output log file cannot be written\n");
exit(EXIT_FAILURE);
}
#ifdef LATSEQ_DEBUG
fprintf(g_latseq.outstream, "# debug %ld.%06ld : log an entry (len %d) for %s\n", etv.tv_sec, etv.tv_usec, ret, e->point);
fprintf(g_latseq.outstream, "# info %ld.%06ld : buffer occupancy (%d / %d) for thread which embedded %s\n",etv.tv_sec, etv.tv_usec, OCCUPANCY((*(&th->i_write_head)%RING_BUFFER_SIZE), ((*i_read_head)%RING_BUFFER_SIZE)), RING_BUFFER_SIZE, e->point);
#endif
free(tmps);
// cleanup buffer element
e->ts = 0;
memset(e->data_id, 0, (sizeof(uint32_t) * e->len_id));
e->len_id = 0;
//Update read_head for the current read_ith_thread
//Update g_latseq.local_log_buffers.i_read_heads[g_latseq.local_log_buffers.read_ith_thread] head position
(*i_read_head)++;
return ret;
}
void latseq_log_to_file(void)
{
// pthread config
pthread_t thId = pthread_self();
//set name
pthread_setname_np(thId, "latseq_log_to_file");
//set priority
int prio_for_policy = 10;
pthread_setschedprio(thId, prio_for_policy);
latseq_registry_t * reg = &g_latseq.local_log_buffers;
int items_to_read = 0;
while (!oai_exit) { // run until oai is stopped
if (!g_latseq.is_running) { break; } //running flag is at 0, not running
//If no thread registered, continue and wait
if (reg->nb_th == 0) { usleep(1000); continue; }
//Select a thread to read with read_ith_thread.
// Using RR for now, WRR in near future according to occupancy
if (reg->read_ith_thread + 1 >= reg->nb_th) {
reg->read_ith_thread = 0;
} else {
reg->read_ith_thread++;
}
//If max occupancy reached for a local buffer
if (reg->tls[reg->read_ith_thread]->i_write_head < reg->i_read_heads[reg->read_ith_thread]) {
fprintf(g_latseq.outstream, "# Error\tring buffer of thread (%d) reach max occupancy of %d\n", reg->read_ith_thread, RING_BUFFER_SIZE);
}
items_to_read = CHUNK_SIZE_ITEMS;
// Write by chunk
while (reg->tls[reg->read_ith_thread]->i_write_head > reg->i_read_heads[reg->read_ith_thread] && items_to_read > 0 ) {
//printf("[debug] th %d : (%d)w (%d)r : (%d)items_to_read\n", reg->read_ith_thread, reg->tls[reg->read_ith_thread]->i_write_head, reg->i_read_heads[reg->read_ith_thread], items_to_read);
items_to_read--;
//Write pointed entry into log file
g_latseq.stats.bytes_counter += (uint32_t)write_latseq_entry();
g_latseq.stats.entry_counter++;
}
usleep(1);
} // while(!oai_exit)
//Write all remaining data
for (uint8_t i = 0; i < reg->nb_th; i++) {
reg->read_ith_thread = i;
while (reg->tls[reg->read_ith_thread]->i_write_head > reg->i_read_heads[reg->read_ith_thread])
{
g_latseq.stats.bytes_counter += (uint32_t)write_latseq_entry();
g_latseq.stats.entry_counter++;
}
}
//close_latseq(); // function to close latseq properly
//exit thread
pthread_exit(NULL);
}
void fflush_latseq_periodically(void)
{
struct timespec ts;
while(1){
sleep(1);
fflush(g_latseq.outstream);
clock_gettime(CLOCK_REALTIME, &ts);
fprintf(g_latseq.outstream, "%ld S rdtsc--gettimeofday %ld.%09ld\n", l_rdtsc(), ts.tv_sec, ts.tv_nsec);
}
pthread_exit(NULL);
}

View File

@@ -0,0 +1,409 @@
/*
* Software Name : LatSeq
* Version: 1.0
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 Orange Labs
* SPDX-License-Identifier: BSD-3-Clause
*
* This software is distributed under the BSD 3-clause,
* the text of which is available at https://opensource.org/licenses/BSD-3-Clause
* or see the "license.txt" file for more details.
*
* Author: Flavien Ronteix--Jacquet
* Software description: LatSeq measurement part core
*/
#ifndef __LATSEQ_H__
#define __LATSEQ_H__
/*--- INCLUDES ---------------------------------------------------------------*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdarg.h>
#include <time.h>
#include <stdint.h>
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <utils.h>
/*--- DEFINE -----------------------------------------------------------------*/
#define RING_BUFFER_SIZE 1024 // Number of fingerprints in Ring Buffer
#define NB_DATA_IDENTIFIERS 10 // to update according to distinct data identifier used in point
#define LATSEQ_MAX_STR_SIZE 128 // Length for filelog_name AND latseq fingerprint string size
#define CHUNK_SIZE_ITEMS 16 // Size of chunk of ring buffer to read at data collector. 1 correspoding to full RR, RING_BUFFER_SIZE read all buffer by passage
#define MAX_NB_THREAD 32 // Maximum number of instrumented threads expected
/*--- MACRO ------------------------------------------------------------------*/
#define LATSEQ_P3(p, f, i1) do {log_measure1(p, f, (uint32_t)i1); } while(0)
#define LATSEQ_P4(p, f, i1, i2) do {log_measure2(p, f, (uint32_t)i1, (uint32_t)i2); } while(0)
#define LATSEQ_P5(p, f, i1, i2, i3) do {log_measure3(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3); } while(0)
#define LATSEQ_P6(p, f, i1, i2, i3, i4) do {log_measure4(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4);} while(0)
#define LATSEQ_P7(p, f, i1, i2, i3, i4, i5) do {log_measure5(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5); } while(0)
#define LATSEQ_P8(p, f, i1, i2, i3, i4, i5, i6) do {log_measure6(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6); } while(0)
#define LATSEQ_P9(p, f, i1, i2, i3, i4, i5, i6, i7) do {log_measure7(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7); } while(0)
#define LATSEQ_P10(p, f, i1, i2, i3, i4, i5, i6, i7, i8) do {log_measure8(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8); } while(0)
#define LATSEQ_P11(p, f, i1, i2, i3, i4, i5, i6, i7, i8, i9) do {log_measure9(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8, (uint32_t)i9); } while(0)
#define LATSEQ_P12(p, f, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10) do {log_measure10(p, f, (uint32_t)i1, (uint32_t)i2, (uint32_t)i3, (uint32_t)i4, (uint32_t)i5, (uint32_t)i6, (uint32_t)i7, (uint32_t)i8, (uint32_t)i9, (uint32_t)i10); } while(0)
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,NAME,...) NAME
#define LATSEQ_P(...) GET_MACRO(__VA_ARGS__, LATSEQ_P12, LATSEQ_P11, LATSEQ_P10, LATSEQ_P9, LATSEQ_P8, LATSEQ_P7, LATSEQ_P6, LATSEQ_P5, LATSEQ_P4, LATSEQ_P3)(__VA_ARGS__)
#define OCCUPANCY(w, r) (w - r)
/*--- STRUCT -----------------------------------------------------------------*/
// A latseq element of the buffer
typedef struct latseq_element_t {
uint64_t ts; // timestamp of the measure
const char * point;
const char * format;
ushort len_id; // Number data identifiers
uint32_t data_id[NB_DATA_IDENTIFIERS]; // values for the data identifier. What is the best type ?
} latseq_element_t;
// Statistics structures for latseq
typedef struct latseq_stats_t {
uint32_t entry_counter;
uint32_t bytes_counter;
} latseq_stats_t;
//thread specific data struct
typedef struct latseq_thread_data_t {
uint8_t th_latseq_id; //Identifier of pthread for registry
latseq_element_t log_buffer[RING_BUFFER_SIZE]; //log buffer, structure mutex-less
unsigned int i_write_head; // position of writer in the log_buffer (main thread)
} latseq_thread_data_t;
//Registry of pointers to thread-specific struct latseq_data_thread
typedef struct latseq_registry_t {
uint8_t read_ith_thread;
uint8_t nb_th;
latseq_thread_data_t * tls[MAX_NB_THREAD];
unsigned int i_read_heads[MAX_NB_THREAD]; // position of reader in the ith log buffer (logger thread)
} latseq_registry_t;
// Global structure of LatSeq module
typedef struct latseq_t {
int is_running; //1 is running, 0 not running
char * filelog_name;
FILE * outstream; //Output descriptor
uint64_t time_zero; // time zero
uint64_t rdtsc_zero; //rdtsc zero
uint64_t cpu_freq; //cpu frequency
latseq_registry_t local_log_buffers; //Register of thread-specific buffers
latseq_stats_t stats; // stats of latseq instance
} latseq_t;
/*--- EXTERNS ----------------------------------------------------------------*/
extern latseq_t g_latseq; // global structure
extern __thread latseq_thread_data_t tls_latseq;
/*--- FUNCTIONS --------------------------------------------------------------*/
/** \fn int init_latseq(const char * appname);
* \brief init latency sequences module.
* \param appname app's name. The output file is appname.date_hour.lseq
* \param cpufreq. cpu frequency in cycles.
* \return -1 if error 1 otherwise
*/
int init_latseq(const char * appname, uint64_t cpufreq);
/** \fn init_logger_to_mem(void);
* \brief init thread logger
* \return -1 if error 1 otherwise
*/
int init_logger_latseq(void);
/** \fn init_thread_for_latseq(void);
* \brief init tls_latseq for local oai thread
* \return -1 if error, 0 otherwise
*/
int init_thread_for_latseq(void);
/** \fn l_rdtsc(void);
* \brief rdtsc wrapper
* \return time
*/
static __inline__ uint64_t l_rdtsc(void) {
uint32_t a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (((uint64_t)d)<<32) | ((uint64_t)a);
}
/** \fn get_cpu_freq_cycles(void);
* \brief Compute CPU clock in a 1 second experiment
* \return CPU clock in cycles
*/
uint64_t get_cpu_freq_cycles(void);
/*--- MEASUREMENTS -----------------------------------------------------------*/
/** \fn void log_measure(const char * point, const char *identifier);
* \brief function to log a new measure into buffer.
* From 1 to NB_DATA_IDENTIFIERS
* \param point name of the measurement point
* \param id identifier for the data pointed
* \todo measure latency introduced by this function
*/
static __inline__ void log_measure1(const char * point, const char *fmt, uint32_t i1)
{
//check if the oai thread is already registered
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
//get reference on new element
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 1;
e->data_id[0] = i1;
//Update head position
tls_latseq.i_write_head++;
}
static __inline__ void log_measure2(const char * point, const char *fmt, uint32_t i1, uint32_t i2)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 2;
e->data_id[0] = i1;
e->data_id[1] = i2;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure3(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 3;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure4(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 4;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure5(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 5;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure6(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 6;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure7(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 7;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure8(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 8;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure9(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8, uint32_t i9)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 9;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
e->data_id[8] = i9;
tls_latseq.i_write_head++;
}
static __inline__ void log_measure10(const char * point, const char *fmt, uint32_t i1, uint32_t i2, uint32_t i3, uint32_t i4, uint32_t i5, uint32_t i6, uint32_t i7, uint32_t i8, uint32_t i9, uint32_t i10)
{
if (tls_latseq.th_latseq_id == 0) {
//is not initialized yet
if (init_thread_for_latseq()) {
return;
}
}
latseq_element_t * e = &tls_latseq.log_buffer[tls_latseq.i_write_head%RING_BUFFER_SIZE];
e->ts = l_rdtsc();
e->point = point;
e->format = fmt;
e->len_id = 10;
e->data_id[0] = i1;
e->data_id[1] = i2;
e->data_id[2] = i3;
e->data_id[3] = i4;
e->data_id[4] = i5;
e->data_id[5] = i6;
e->data_id[6] = i7;
e->data_id[7] = i8;
e->data_id[8] = i9;
e->data_id[9] = i10;
tls_latseq.i_write_head++;
}
/** \fn static int write_latseq_entry(void);
* \brief private function to write an entry in the log file
*/
//static int write_latseq_entry(void);
/** \fn void log_to_file(void);
* \brief function to save buffer of logs into a file
*/
void latseq_log_to_file(void);
/** \fn void fflush_latseq_periodically(void);
* \brief flush periodically into fprintf
*/
void fflush_latseq_periodically(void);
/** \fn void latseq_print_stats(void);
* \brief print some stats about latseq
*/
void latseq_print_stats(void);
/** \fn int close_latseq(void);
* \brief finish latseq measurement if a latseq is running
* \return 0 if error 1 otherwise
*/
int close_latseq(void);
/*----------------------------------------------------------------------------*/
#endif

View File

@@ -37,6 +37,7 @@ typedef enum hashtable_return_code_e {
HASH_TABLE_KEY_ALREADY_EXISTS = 3,
HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
HASH_TABLE_SYSTEM_ERROR = 5,
HASH_TABLE_NONE = 6,
HASH_TABLE_CODE_MAX
} hashtable_rc_t;

View File

@@ -191,65 +191,17 @@ int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) {
return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275));
}
/// Target code rate tables indexed by Imcs
/* TS 38.214 table 5.1.3.1-1 - MCS index table 1 for PDSCH */
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948};
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs) {
/* TS 38.214 table 5.1.3.1-2 - MCS index table 2 for PDSCH */
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \
616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948};
/* TS 38.214 table 5.1.3.1-3 - MCS index table 3 for PDSCH */
uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \
378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772};
uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \
336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \
1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \
3104, 3240, 3368, 3496, 3624, 3752, 3824};
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 1:
return (((Imcs<10)||(Imcs==29))?2:((Imcs<17)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
break;
case 2:
return (((Imcs<5)||(Imcs==28))?2:((Imcs<11)||(Imcs==29))?4:((Imcs<20)||(Imcs==30))?6:((Imcs<28)||(Imcs==31))?8:-1);
break;
case 3:
return (((Imcs<15)||(Imcs==29))?2:((Imcs<21)||(Imcs==30))?4:((Imcs<29)||(Imcs==31))?6:-1);
break;
default:
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
return(0);
break;
}
}
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 1:
return (nr_target_code_rate_table1[Imcs]);
break;
case 2:
return (nr_target_code_rate_table2[Imcs]);
break;
case 3:
return (nr_target_code_rate_table3[Imcs]);
break;
default:
AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx);
return(0);
break;
int f; // interleaving function
if(R==0)
f = k;
else {
int c = k/R;
int r = k%R;
f = (r*C + c + n_shift)%(N_regs/L);
}
return f;
}
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
@@ -503,7 +455,6 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index) {
return i;
}
int get_subband_size(int NPRB,int size) {
// implements table 5.2.1.4-2 from 36.214
//

View File

@@ -57,7 +57,7 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) {
return(num_dmrs);
}
int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
int get_SLIV(uint8_t S, uint8_t L);
void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
@@ -69,12 +69,6 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart);
extern uint16_t nr_target_code_rate_table1[29];
extern uint16_t nr_target_code_rate_table2[28];
extern uint16_t nr_target_code_rate_table3[29];
extern uint16_t nr_tbs_table[93];
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
int get_subband_size(int NPRB,int size);
void SLIV2SL(int SLIV,int *S,int *L);
int get_dmrs_port(int nl, uint16_t dmrs_ports);

View File

@@ -80,7 +80,7 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
notifiedFIFO_t *reponseFifo,
void (*processingFunc)(void *)) {
notifiedFIFO_elt_t *ret;
AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), "");
AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) calloc(1, sizeof(notifiedFIFO_elt_t)+size+32)), "");
ret->next=NULL;
ret->key=key;
ret->reponseFifo=reponseFifo;

View File

@@ -111,13 +111,15 @@ void print_meas(time_stats_t *ts,
}
}
int print_meas_log(time_stats_t *ts,
const char *name,
time_stats_t *total_exec_time,
time_stats_t *sf_exec_time,
char *output)
size_t print_meas_log(time_stats_t *ts,
const char *name,
time_stats_t *total_exec_time,
time_stats_t *sf_exec_time,
char *output,
size_t outputlen)
{
int stroff = 0;
const char *begin = output;
const char *end = output + outputlen;
static int first_time = 0;
static double cpu_freq_GHz = 0.0;
@@ -128,30 +130,49 @@ int print_meas_log(time_stats_t *ts,
first_time=1;
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
stroff += sprintf(output, "%25s %25s %25s %25s %25s %6f\n","Name","Total","Per Trials", "Num Trials","CPU_F_GHz", cpu_freq_GHz);
output += snprintf(output,
end - output,
"%25s %25s %25s %25s %25s %6f\n",
"Name",
"Total",
"Per Trials",
"Num Trials",
"CPU_F_GHz",
cpu_freq_GHz);
else
stroff += sprintf(output+stroff, "%25s %25s %25s %20s %15s %6f\n","Name","Total","Average/Frame","Trials", "CPU_F_GHz", cpu_freq_GHz);
output += snprintf(output,
end - output,
"%25s %25s %25s %20s %15s %6f\n",
"Name",
"Total",
"Average/Frame",
"Trials",
"CPU_F_GHz",
cpu_freq_GHz);
}
if (ts->trials>0) {
//printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
stroff += sprintf(output+stroff, "%25s: %15.3f us; %15d; %15.3f us;\n",
name,
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
ts->trials,
ts->max/cpu_freq_GHz/1000.0);
output += snprintf(output,
end - output,
"%25s: %15.3f us; %15d; %15.3f us;\n",
name,
ts->diff / ts->trials / cpu_freq_GHz / 1000.0,
ts->trials,
ts->max / cpu_freq_GHz / 1000.0);
} else {
stroff += sprintf(output+stroff, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
name,
(ts->diff/cpu_freq_GHz/1000000.0),
((ts->diff/cpu_freq_GHz/1000000.0)/(total_exec_time->diff/cpu_freq_GHz/1000000.0))*100, // percentage
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
((ts->diff/ts->trials/cpu_freq_GHz/1000.0)/(sf_exec_time->diff/sf_exec_time->trials/cpu_freq_GHz/1000.0))*100, // percentage
ts->trials);
output += snprintf(output,
end - output,
"%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
name,
ts->diff / cpu_freq_GHz / 1000000.0,
((ts->diff / cpu_freq_GHz / 1000000.0) / (total_exec_time->diff / cpu_freq_GHz / 1000000.0))*100, // percentage
ts->diff / ts->trials / cpu_freq_GHz / 1000.0,
((ts->diff / ts->trials / cpu_freq_GHz / 1000.0) / (sf_exec_time->diff / sf_exec_time->trials / cpu_freq_GHz / 1000.0)) * 100, // percentage
ts->trials);
}
}
return stroff;
return output - begin;
}
double get_time_meas_us(time_stats_t *ts)

View File

@@ -83,7 +83,12 @@ static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name);
void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time);
int print_meas_log(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time, char *output);
size_t print_meas_log(time_stats_t *ts,
const char *name,
time_stats_t *total_exec_time,
time_stats_t *sf_exec_time,
char *output,
size_t outputlen);
double get_time_meas_us(time_stats_t *ts);
double get_cpu_freq_GHz(void);

View File

@@ -0,0 +1,234 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI 5G SA tutorial</font></b>
</td>
</tr>
</table>
**TABLE OF CONTENTS**
1. [Scenario](#1-scenario)
2. [OAI CN5G](#2-oai-cn5g)
1. [OAI CN5G pre-requisites](#21-oai-cn5g-pre-requisites)
2. [OAI CN5G Setup](#22-oai-cn5g-setup)
3. [OAI CN5G Configuration files](#23-oai-cn5g-configuration-files)
4. [SIM Card](#24-sim-card)
3. [OAI gNB](#3-oai-gnb)
1. [OAI gNB pre-requisites](#31-oai-gnb-pre-requisites)
2. [Build OAI gNB](#32-build-oai-gnb)
4. [Run OAI CN5G and OAI gNB with USRP B210](#4-run-oai-cn5g-and-oai-gnb-with-usrp-b210)
1. [Run OAI CN5G](#41-run-oai-cn5g)
2. [Run OAI gNB](#42-run-oai-gnb)
5. [Testing with QUECTEL RM500Q](#5-testing-with-quectel-rm500q)
1. [Setup QUECTEL](#51-setup-quectel)
2. [Ping test](#52-ping-test)
3. [Downlink iPerf test](#53-downlink-iperf-test)
# 1. Scenario
In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB and COTS UE.
Minimum hardware requirements:
- Laptop/Desktop/Server for OAI CN5G and OAI gNB
- Operating System: [Ubuntu 20.04.4 LTS](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso)
- CPU: 8 cores x86_64 @ 3.5 GHz
- RAM: 32 GB
- Laptop for UE
- Operating System: Microsoft Windows 10 x64
- CPU: 4 cores x86_64
- RAM: 8 GB
- Windows driver for Quectel MUST be equal or higher than version **2.2.4**
- [USRP B210](https://www.ettus.com/all-products/ub210-kit/)
- Quectel RM500Q
- Module, M.2 to USB adapter, antennas and SIM card
- Firmware version of Quectel MUST be equal or higher than **RM500QGLABR11A06M4G**
# 2. OAI CN5G
## 2.1 OAI CN5G pre-requisites
```bash
sudo apt install -y git net-tools putty
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y docker docker-ce
# Add your username to the docker group, otherwise you will have to run in sudo mode.
sudo usermod -a -G docker $(whoami)
reboot
# https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
sudo service docker restart
```
## 2.2 OAI CN5G Setup
```bash
# Git oai-cn5g-fed repository
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
cd ~/oai-cn5g-fed
git checkout master
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
docker pull oaisoftwarealliance/oai-amf:develop
docker pull oaisoftwarealliance/oai-nrf:develop
docker pull oaisoftwarealliance/oai-smf:develop
docker pull oaisoftwarealliance/oai-udr:develop
docker pull oaisoftwarealliance/oai-udm:develop
docker pull oaisoftwarealliance/oai-ausf:develop
docker pull oaisoftwarealliance/oai-upf-vpp:develop
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
docker pull oaisoftwarealliance/oai-nssf:develop
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
```
## 2.3 OAI CN5G Configuration files
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
- [oai_db.sql](tutorial_resources/oai_db.sql)
Change permissions on oai_db.sql to prevent mysql permission denied error:
```bash
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
```
## 2.4 SIM Card
Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz).
```bash
sudo ./program_uicc --adm 12345678 --imsi 208990000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate
```
# 3. OAI gNB
## 3.1 OAI gNB pre-requisites
### Build UHD from source
```bash
sudo apt install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-setuptools cmake build-essential
git clone https://github.com/EttusResearch/uhd.git ~/uhd
cd ~/uhd
git checkout v4.0.0.0
cd host
mkdir build
cd build
cmake ../
make -j 4
make test # This step is optional
sudo make install
sudo ldconfig
sudo uhd_images_downloader
```
## 3.2 Build OAI gNB
```bash
# Get openairinterface5g source code
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop
# Install dependencies in Ubuntu 20.04
cd ~/openairinterface5g
source oaienv
cd cmake_targets
./build_oai -I
# Build OAI gNB
cd ~/openairinterface5g
source oaienv
cd cmake_targets
./build_oai -w USRP --nrUE --gNB --build-lib all -c
```
# 4. Run OAI CN5G and OAI gNB with USRP B210
## 4.1 Run OAI CN5G
```bash
cd ~/oai-cn5g-fed/docker-compose
python3 core-network.py --type start-basic --fqdn yes --scenario 1
```
## 4.2 Run OAI gNB
```bash
cd ~/openairinterface5g
source oaienv
cd cmake_targets/ran_build/build
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --sa -E --continuous-tx
```
Make sure that during USRP initialization, it shows that USB 3 is used.
# 5. Testing with Quectel RM500Q
## 5.1 Setup Quectel
With [PuTTY](https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe), send the following AT commands to the module using a serial interface (ex: COM2) at 115200 bps:
```bash
# MUST be sent at least once everytime there is a firmware upgrade!
AT+QMBNCFG="Select","ROW_Commercial"
AT+QMBNCFG="AutoSel",0
AT+CFUN=1,1
AT+CGDCONT=1
AT+CGDCONT=2
AT+CGDCONT=3
AT+CGDCONT=1,"IP","oai"
# (Optional, debug only, AT commands) Activate PDP context, retrieve IP address and test with ping
AT+CGACT=1,1
AT+CGPADDR=1
AT+QPING=1,"openairinterface.org"
```
## 5.2 Ping test
- UE host
```bash
ping 192.168.70.135 -n 1000 -S 12.1.1.2
```
- CN5G host
```bash
docker exec -it oai-ext-dn ping 12.1.1.2
```
## 5.3 Downlink iPerf test
- UE host
- Download iPerf for Microsoft Windows from [here](https://iperf.fr/download/windows/iperf-2.0.9-win64.zip).
- Extract to Desktop and run with Command Prompt:
```bash
cd C:\Users\User\Desktop\iPerf\iperf-2.0.9-win64\iperf-2.0.9-win64
iperf -s -u -i 1 -B 12.1.1.2
```
- CN5G host
```bash
docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 125M -c 12.1.1.2
```

View File

@@ -0,0 +1,251 @@
<table style="border-collapse: collapse; border: none;">
<tr style="border-collapse: collapse; border: none;">
<td style="border-collapse: collapse; border: none;">
<a href="http://www.openairinterface.org/">
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
</img>
</a>
</td>
<td style="border-collapse: collapse; border: none; vertical-align: center;">
<b><font size = "5">OAI 5G SA tutorial</font></b>
</td>
</tr>
</table>
**TABLE OF CONTENTS**
1. [Scenario](#1-scenario)
2. [OAI CN5G](#2-oai-cn5g)
1. [OAI CN5G pre-requisites](#21-oai-cn5g-pre-requisites)
2. [OAI CN5G Setup](#22-oai-cn5g-setup)
3. [OAI CN5G Configuration files](#23-oai-cn5g-configuration-files)
4. [SIM Card](#24-sim-card)
3. [OAI gNB](#3-oai-gnb)
1. [OAI gNB pre-requisites](#31-oai-gnb-pre-requisites)
2. [Build OAI gNB](#32-build-oai-gnb)
3. [N300 Ethernet Tuning](#33-n300-ethernet-tuning)
4. [Run OAI CN5G and OAI gNB with USRP N300](#4-run-oai-cn5g-and-oai-gnb-with-usrp-n300)
1. [Run OAI CN5G](#41-run-oai-cn5g)
2. [Run OAI gNB](#42-run-oai-gnb)
5. [Testing with QUECTEL RM500Q](#5-testing-with-quectel-rm500q)
1. [Setup QUECTEL](#51-setup-quectel)
2. [Ping test](#52-ping-test)
3. [Downlink iPerf test](#53-downlink-iperf-test)
# 1. Scenario
In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB and COTS UE.
Minimum hardware requirements:
- Laptop/Desktop/Server for OAI CN5G and OAI gNB
- Operating System: [Ubuntu 20.04.4 LTS](https://releases.ubuntu.com/20.04.4/ubuntu-20.04.4-desktop-amd64.iso)
- CPU: 8 cores x86_64 @ 3.5 GHz
- RAM: 32 GB
- Laptop for UE
- Operating System: Microsoft Windows 10 x64
- CPU: 4 cores x86_64
- RAM: 8 GB
- Windows driver for Quectel MUST be equal or higher than version **2.2.4**
- [USRP N300](https://www.ettus.com/all-products/USRP-N300/): Please identify the network interface(s) on which the N300 is connected.
- Quectel RM500Q
- Module, M.2 to USB adapter, antennas and SIM card
- Firmware version of Quectel MUST be equal or higher than **RM500QGLABR11A06M4G**
# 2. OAI CN5G
## 2.1 OAI CN5G pre-requisites
```bash
sudo apt install -y git net-tools putty
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y docker docker-ce
# Add your username to the docker group, otherwise you will have to run in sudo mode.
sudo usermod -a -G docker $(whoami)
reboot
# https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net
sudo service docker restart
```
## 2.2 OAI CN5G Setup
```bash
# Git oai-cn5g-fed repository
git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed
cd ~/oai-cn5g-fed
git checkout master
./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop
docker pull oaisoftwarealliance/oai-amf:develop
docker pull oaisoftwarealliance/oai-nrf:develop
docker pull oaisoftwarealliance/oai-smf:develop
docker pull oaisoftwarealliance/oai-udr:develop
docker pull oaisoftwarealliance/oai-udm:develop
docker pull oaisoftwarealliance/oai-ausf:develop
docker pull oaisoftwarealliance/oai-upf-vpp:develop
docker pull oaisoftwarealliance/oai-spgwu-tiny:develop
docker pull oaisoftwarealliance/oai-nssf:develop
docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop
docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop
docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop
docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop
docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop
docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop
docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop
docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop
docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop
```
## 2.3 OAI CN5G Configuration files
Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose:
- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml)
- [oai_db.sql](tutorial_resources/oai_db.sql)
Change permissions on oai_db.sql to prevent mysql permission denied error:
```bash
chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql
```
## 2.4 SIM Card
Program SIM Card with [Open Cells Project](https://open-cells.com/) application [uicc-v2.6](https://open-cells.com/d5138782a8739209ec5760865b1e53b0/uicc-v2.6.tgz).
```bash
sudo ./program_uicc --adm 12345678 --imsi 208990000000001 --isdn 00000001 --acc 0001 --key fec86ba6eb707ed08905757b1bb44b8f --opc C42449363BBAD02B66D16BC975D77CC1 -spn "OpenAirInterface" --authenticate
```
# 3. OAI gNB
## 3.1 OAI gNB pre-requisites
### Build UHD from source
```bash
sudo apt install -y libboost-all-dev libusb-1.0-0-dev doxygen python3-docutils python3-mako python3-numpy python3-requests python3-ruamel.yaml python3-setuptools cmake build-essential
git clone https://github.com/EttusResearch/uhd.git ~/uhd
cd ~/uhd
git checkout v4.0.0.0
cd host
mkdir build
cd build
cmake ../
make -j 4
make test # This step is optional
sudo make install
sudo ldconfig
sudo uhd_images_downloader
```
## 3.2 Build OAI gNB
```bash
# Get openairinterface5g source code
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git ~/openairinterface5g
cd ~/openairinterface5g
git checkout develop
# Install dependencies in Ubuntu 20.04
cd ~/openairinterface5g
source oaienv
cd cmake_targets
./build_oai -I
# Build OAI gNB
cd ~/openairinterface5g
source oaienv
cd cmake_targets
./build_oai -w USRP --nrUE --gNB --build-lib all -c
```
## 3.3 N300 Ethernet Tuning
Please also refer to the official [USRP Host Performance Tuning Tips and Tricks](https://kb.ettus.com/USRP_Host_Performance_Tuning_Tips_and_Tricks) tuning guide.
The following steps are recommended. Please change the network interface(s) as required. Also, you should have 10Gbps interface(s): if you use two cables, you should have the XG interface. Refer to the [N300 Getting Started Guide](https://kb.ettus.com/USRP_N300/N310/N320/N321_Getting_Started_Guide) for more information.
* Use an MTU of 9000: how to change this depends on the network management tool. In the case of Network Manager, this can be done from the GUI.
* Increase the kernel socket buffer (also done by the USRP driver in OAI):
```
sysctl -w net.core.rmem_max=8388608
sysctl -w net.core.wmem_max=8388608
sysctl -w net.core.rmem_default=65536
sysctl -w net.core.wmem_default=65536
```
* Increase Ethernet Ring Buffers: `sudo ethtool -G <ifname> rx 4096 tx 4096`
* Disable hyper-threading in the BIOS
* Disable KPTI Protections for Spectre/Meltdown for more performance. **This is a security risk.** Add `mitigations=off nosmt` in your grub config and update grub.
# 4. Run OAI CN5G and OAI gNB with USRP N300
## 4.1 Run OAI CN5G
```bash
cd ~/oai-cn5g-fed/docker-compose
python3 core-network.py --type start-basic --fqdn yes --scenario 1
```
## 4.2 Run OAI gNB
```bash
cd ~/openairinterface5g
source oaienv
cd cmake_targets/ran_build/build
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf --sa --usrp-tx-thread-config 1
```
# 5. Testing with Quectel RM500Q
## 5.1 Setup Quectel
With [PuTTY](https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe), send the following AT commands to the module using a serial interface (ex: COM2) at 115200 bps:
```bash
# MUST be sent at least once everytime there is a firmware upgrade!
AT+QMBNCFG="Select","ROW_Commercial"
AT+QMBNCFG="AutoSel",0
AT+CFUN=1,1
AT+CGDCONT=1
AT+CGDCONT=2
AT+CGDCONT=3
AT+CGDCONT=1,"IP","oai"
# (Optional, debug only, AT commands) Activate PDP context, retrieve IP address and test with ping
AT+CGACT=1,1
AT+CGPADDR=1
AT+QPING=1,"openairinterface.org"
```
## 5.2 Ping test
- UE host
```bash
ping 192.168.70.135 -n 1000 -S 12.1.1.2
```
- CN5G host
```bash
docker exec -it oai-ext-dn ping 12.1.1.2
```
## 5.3 Downlink iPerf test
- UE host
- Download iPerf for Microsoft Windows from [here](https://iperf.fr/download/windows/iperf-2.0.9-win64.zip).
- Extract to Desktop and run with Command Prompt:
```bash
cd C:\Users\User\Desktop\iPerf\iperf-2.0.9-win64\iperf-2.0.9-win64
iperf -s -u -i 1 -B 12.1.1.2
```
- CN5G host
```bash
docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 200M -c 12.1.1.2
```

View File

@@ -21,8 +21,6 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
servingCellConfigCommon = (
{

View File

@@ -0,0 +1,316 @@
version: '3.8'
services:
mysql:
container_name: "mysql"
image: mysql:5.7
volumes:
- ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh
environment:
- TZ=Europe/Paris
- MYSQL_DATABASE=oai_db
- MYSQL_USER=test
- MYSQL_PASSWORD=test
- MYSQL_ROOT_PASSWORD=linux
healthcheck:
test: /bin/bash -c "/tmp/mysql-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
ipv4_address: 192.168.70.131
oai-udr:
container_name: oai-udr
image: oai-udr:develop
environment:
- TZ=Europe/Paris
- INSTANCE=0
- PID_DIRECTORY=/var/run
- UDR_INTERFACE_NAME_FOR_NUDR=eth0
- UDR_INTERFACE_PORT_FOR_NUDR=80
- UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080
- UDR_API_VERSION=v1
- MYSQL_IPV4_ADDRESS=192.168.70.131
- MYSQL_USER=test
- MYSQL_PASS=test
- MYSQL_DB=oai_db
- WAIT_MYSQL=120
depends_on:
- mysql
networks:
public_net:
ipv4_address: 192.168.70.136
volumes:
- ./udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
oai-udm:
container_name: oai-udm
image: oai-udm:develop
environment:
- TZ=Europe/Paris
- INSTANCE=0
- PID_DIRECTORY=/var/run
- UDM_NAME=OAI_UDM
- SBI_IF_NAME=eth0
- SBI_PORT=80
- UDM_VERSION_NB=v1
- USE_FQDN_DNS=yes
- UDR_IP_ADDRESS=192.168.70.136
- UDR_PORT=80
- UDR_VERSION_NB=v1
- UDR_FQDN=oai-udr
depends_on:
- oai-udr
networks:
public_net:
ipv4_address: 192.168.70.137
volumes:
- ./udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
oai-ausf:
container_name: oai-ausf
image: oai-ausf:develop
environment:
- TZ=Europe/Paris
- INSTANCE_ID=0
- PID_DIR=/var/run
- AUSF_NAME=OAI_AUSF
- SBI_IF_NAME=eth0
- SBI_PORT=80
- USE_FQDN_DNS=yes
- UDM_IP_ADDRESS=192.168.70.137
- UDM_PORT=80
- UDM_VERSION_NB=v1
- UDM_FQDN=oai-udm
depends_on:
- oai-udm
networks:
public_net:
ipv4_address: 192.168.70.138
volumes:
- ./ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
oai-nrf:
container_name: "oai-nrf"
image: oai-nrf:develop
environment:
- NRF_INTERFACE_NAME_FOR_SBI=eth0
- NRF_INTERFACE_PORT_FOR_SBI=80
- NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
- NRF_API_VERSION=v1
- INSTANCE=0
- PID_DIRECTORY=/var/run
networks:
public_net:
ipv4_address: 192.168.70.130
volumes:
- ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
oai-amf:
container_name: "oai-amf"
image: oai-amf:develop
environment:
- TZ=Europe/paris
- INSTANCE=0
- PID_DIRECTORY=/var/run
- MCC=208
- MNC=99
- REGION_ID=128
- AMF_SET_ID=1
- SERVED_GUAMI_MCC_0=208
- SERVED_GUAMI_MNC_0=99
- SERVED_GUAMI_REGION_ID_0=128
- SERVED_GUAMI_AMF_SET_ID_0=1
- SERVED_GUAMI_MCC_1=460
- SERVED_GUAMI_MNC_1=11
- SERVED_GUAMI_REGION_ID_1=10
- SERVED_GUAMI_AMF_SET_ID_1=1
- PLMN_SUPPORT_MCC=208
- PLMN_SUPPORT_MNC=99
- PLMN_SUPPORT_TAC=0x0001
- SST_0=1
- SD_0=1
- SST_1=1
- SD_1=12
- AMF_INTERFACE_NAME_FOR_NGAP=eth0
- AMF_INTERFACE_NAME_FOR_N11=eth0
- SMF_INSTANCE_ID_0=1
- SMF_FQDN_0=oai-smf
- SMF_IPV4_ADDR_0=192.168.70.133
- SMF_HTTP_VERSION_0=v1
- SELECTED_0=true
- SMF_INSTANCE_ID_1=2
- SMF_FQDN_1=oai-smf
- SMF_IPV4_ADDR_1=0.0.0.0
- SMF_HTTP_VERSION_1=v1
- SELECTED_1=false
- MYSQL_SERVER=192.168.70.131
- MYSQL_USER=root
- MYSQL_PASS=linux
- MYSQL_DB=oai_db
- OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3
- NRF_IPV4_ADDRESS=192.168.70.130
- NRF_PORT=80
- NF_REGISTRATION=yes
- SMF_SELECTION=yes
- USE_FQDN_DNS=yes
- EXTERNAL_AUSF=yes
- NRF_API_VERSION=v1
- NRF_FQDN=oai-nrf
- AUSF_IPV4_ADDRESS=192.168.70.138
- AUSF_PORT=80
- AUSF_API_VERSION=v1
- AUSF_FQDN=oai-ausf
depends_on:
- mysql
- oai-nrf
- oai-ausf
volumes:
- ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh"
interval: 10s
timeout: 15s
retries: 5
networks:
public_net:
ipv4_address: 192.168.70.132
oai-smf:
container_name: "oai-smf"
image: oai-smf:develop
environment:
- TZ=Europe/Paris
- INSTANCE=0
- PID_DIRECTORY=/var/run
- SMF_INTERFACE_NAME_FOR_N4=eth0
- SMF_INTERFACE_NAME_FOR_SBI=eth0
- SMF_INTERFACE_PORT_FOR_SBI=80
- SMF_INTERFACE_HTTP2_PORT_FOR_SBI=9090
- SMF_API_VERSION=v1
- DEFAULT_DNS_IPV4_ADDRESS=8.8.8.8
- DEFAULT_DNS_SEC_IPV4_ADDRESS=4.4.4.4
- AMF_IPV4_ADDRESS=192.168.70.132
- AMF_PORT=80
- AMF_API_VERSION=v1
- AMF_FQDN=oai-amf
- UDM_IPV4_ADDRESS=192.168.70.137
- UDM_PORT=80
- UDM_API_VERSION=v1
- UDM_FQDN=oai-udm
- UPF_IPV4_ADDRESS=192.168.70.134
- UPF_FQDN_0=oai-spgwu
- NRF_IPV4_ADDRESS=192.168.70.130
- NRF_PORT=80
- NRF_API_VERSION=v1
- USE_LOCAL_SUBSCRIPTION_INFO=yes
- NRF_FQDN=oai-nrf
- REGISTER_NRF=yes
- DISCOVER_UPF=yes
- USE_FQDN_DNS=yes
- DNN_RANGE1=12.1.1.2 - 12.1.1.128
- DNN_RANGE0=12.2.1.2 - 12.2.1.128
- DNN_NI1=oai
depends_on:
- oai-nrf
- oai-amf
volumes:
- ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
ipv4_address: 192.168.70.133
oai-spgwu:
container_name: "oai-spgwu"
image: oai-spgwu-tiny:develop
environment:
- TZ=Europe/Paris
- PID_DIRECTORY=/var/run
- SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0
- SGW_INTERFACE_NAME_FOR_SX=eth0
- PGW_INTERFACE_NAME_FOR_SGI=eth0
- NETWORK_UE_NAT_OPTION=yes
- NETWORK_UE_IP=12.1.1.0/24
- SPGWC0_IP_ADDRESS=192.168.70.133
- BYPASS_UL_PFCP_RULES=no
- MCC=208
- MNC=99
- MNC03=099
- TAC=1
- GW_ID=1
- REALM=openairinterface.org
- ENABLE_5G_FEATURES=yes
- REGISTER_NRF=yes
- USE_FQDN_NRF=no
- UPF_FQDN_5G=oai-spgwu
- NRF_IPV4_ADDRESS=192.168.70.130
- NRF_PORT=80
- NRF_API_VERSION=v1
- NRF_FQDN=oai-nrf
- NSSAI_SST_0=1
- NSSAI_SD_0=1
- DNN_0=oai
depends_on:
- oai-nrf
- oai-smf
cap_add:
- NET_ADMIN
- SYS_ADMIN
cap_drop:
- ALL
privileged: true
volumes:
- ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh
healthcheck:
test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh"
interval: 10s
timeout: 5s
retries: 5
networks:
public_net:
ipv4_address: 192.168.70.134
oai-ext-dn:
image: ubuntu:bionic
privileged: true
container_name: oai-ext-dn
entrypoint: /bin/bash -c \
"apt update; apt install -y iptables iproute2 iperf iperf3 iputils-ping;"\
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity"
depends_on:
- oai-spgwu
networks:
public_net:
ipv4_address: 192.168.70.135
networks:
public_net:
external:
name: demo-oai-public-net
# public_net:
# driver: bridge
# name: demo-oai-public-net
# ipam:
# config:
# - subnet: 192.168.70.128/26
# driver_opts:
# com.docker.network.bridge.name: "demo-oai"

View File

@@ -0,0 +1,312 @@
-- phpMyAdmin SQL Dump
-- version 5.1.0
-- https://www.phpmyadmin.net/
--
-- Host: 172.16.200.10:3306
-- Generation Time: Mar 22, 2021 at 10:31 AM
-- Server version: 5.7.33
-- PHP Version: 7.4.15
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `oai_db`
--
-- --------------------------------------------------------
--
-- Table structure for table `AccessAndMobilitySubscriptionData`
--
CREATE TABLE `AccessAndMobilitySubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`gpsis` json DEFAULT NULL,
`internalGroupIds` json DEFAULT NULL,
`sharedVnGroupDataIds` json DEFAULT NULL,
`subscribedUeAmbr` json DEFAULT NULL,
`nssai` json DEFAULT NULL,
`ratRestrictions` json DEFAULT NULL,
`forbiddenAreas` json DEFAULT NULL,
`serviceAreaRestriction` json DEFAULT NULL,
`coreNetworkTypeRestrictions` json DEFAULT NULL,
`rfspIndex` int(10) DEFAULT NULL,
`subsRegTimer` int(10) DEFAULT NULL,
`ueUsageType` int(10) DEFAULT NULL,
`mpsPriority` tinyint(1) DEFAULT NULL,
`mcsPriority` tinyint(1) DEFAULT NULL,
`activeTime` int(10) DEFAULT NULL,
`sorInfo` json DEFAULT NULL,
`sorInfoExpectInd` tinyint(1) DEFAULT NULL,
`sorafRetrieval` tinyint(1) DEFAULT NULL,
`sorUpdateIndicatorList` json DEFAULT NULL,
`upuInfo` json DEFAULT NULL,
`micoAllowed` tinyint(1) DEFAULT NULL,
`sharedAmDataIds` json DEFAULT NULL,
`odbPacketServices` json DEFAULT NULL,
`serviceGapTime` int(10) DEFAULT NULL,
`mdtUserConsent` json DEFAULT NULL,
`mdtConfiguration` json DEFAULT NULL,
`traceData` json DEFAULT NULL,
`cagData` json DEFAULT NULL,
`stnSr` varchar(50) DEFAULT NULL,
`cMsisdn` varchar(50) DEFAULT NULL,
`nbIoTUePriority` int(10) DEFAULT NULL,
`nssaiInclusionAllowed` tinyint(1) DEFAULT NULL,
`rgWirelineCharacteristics` varchar(50) DEFAULT NULL,
`ecRestrictionDataWb` json DEFAULT NULL,
`ecRestrictionDataNb` tinyint(1) DEFAULT NULL,
`expectedUeBehaviourList` json DEFAULT NULL,
`primaryRatRestrictions` json DEFAULT NULL,
`secondaryRatRestrictions` json DEFAULT NULL,
`edrxParametersList` json DEFAULT NULL,
`ptwParametersList` json DEFAULT NULL,
`iabOperationAllowed` tinyint(1) DEFAULT NULL,
`wirelineForbiddenAreas` json DEFAULT NULL,
`wirelineServiceAreaRestriction` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `Amf3GppAccessRegistration`
--
CREATE TABLE `Amf3GppAccessRegistration` (
`ueid` varchar(15) NOT NULL,
`amfInstanceId` varchar(50) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`purgeFlag` tinyint(1) DEFAULT NULL,
`pei` varchar(50) DEFAULT NULL,
`imsVoPs` json DEFAULT NULL,
`deregCallbackUri` varchar(50) NOT NULL,
`amfServiceNameDereg` json DEFAULT NULL,
`pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
`amfServiceNamePcscfRest` json DEFAULT NULL,
`initialRegistrationInd` tinyint(1) DEFAULT NULL,
`guami` json NOT NULL,
`backupAmfInfo` json DEFAULT NULL,
`drFlag` tinyint(1) DEFAULT NULL,
`ratType` json NOT NULL,
`urrpIndicator` tinyint(1) DEFAULT NULL,
`amfEeSubscriptionId` varchar(50) DEFAULT NULL,
`epsInterworkingInfo` json DEFAULT NULL,
`ueSrvccCapability` tinyint(1) DEFAULT NULL,
`registrationTime` varchar(50) DEFAULT NULL,
`vgmlcAddress` json DEFAULT NULL,
`contextInfo` json DEFAULT NULL,
`noEeSubscriptionInd` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `AuthenticationStatus`
--
CREATE TABLE `AuthenticationStatus` (
`ueid` varchar(20) NOT NULL,
`nfInstanceId` varchar(50) NOT NULL,
`success` tinyint(1) NOT NULL,
`timeStamp` varchar(50) NOT NULL,
`authType` varchar(25) NOT NULL,
`servingNetworkName` varchar(50) NOT NULL,
`authRemovalInd` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `AuthenticationSubscription`
--
CREATE TABLE `AuthenticationSubscription` (
`ueid` varchar(20) NOT NULL,
`authenticationMethod` varchar(25) NOT NULL,
`encPermanentKey` varchar(50) DEFAULT NULL,
`protectionParameterId` varchar(50) DEFAULT NULL,
`sequenceNumber` json DEFAULT NULL,
`authenticationManagementField` varchar(50) DEFAULT NULL,
`algorithmId` varchar(50) DEFAULT NULL,
`encOpcKey` varchar(50) DEFAULT NULL,
`encTopcKey` varchar(50) DEFAULT NULL,
`vectorGenerationInHss` tinyint(1) DEFAULT NULL,
`n5gcAuthMethod` varchar(15) DEFAULT NULL,
`rgAuthenticationInd` tinyint(1) DEFAULT NULL,
`supi` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `AuthenticationSubscription`
--
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('208950000000031', '5G_AKA', '0C0A34601D4F07677303652C0462535B', '0C0A34601D4F07677303652C0462535B', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '63bfa50ee6523365ff14c1f45f88737d', NULL, NULL, NULL, NULL, '208950000000031');
INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES
('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001');
-- --------------------------------------------------------
--
-- Table structure for table `SdmSubscriptions`
--
CREATE TABLE `SdmSubscriptions` (
`ueid` varchar(15) NOT NULL,
`subsId` int(10) UNSIGNED NOT NULL,
`nfInstanceId` varchar(50) NOT NULL,
`implicitUnsubscribe` tinyint(1) DEFAULT NULL,
`expires` varchar(50) DEFAULT NULL,
`callbackReference` varchar(50) NOT NULL,
`amfServiceName` json DEFAULT NULL,
`monitoredResourceUris` json NOT NULL,
`singleNssai` json DEFAULT NULL,
`dnn` varchar(50) DEFAULT NULL,
`subscriptionId` varchar(50) DEFAULT NULL,
`plmnId` json DEFAULT NULL,
`immediateReport` tinyint(1) DEFAULT NULL,
`report` json DEFAULT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`contextInfo` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `SessionManagementSubscriptionData`
--
CREATE TABLE `SessionManagementSubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`singleNssai` json NOT NULL,
`dnnConfigurations` json DEFAULT NULL,
`internalGroupIds` json DEFAULT NULL,
`sharedVnGroupDataIds` json DEFAULT NULL,
`sharedDnnConfigurationsId` varchar(50) DEFAULT NULL,
`odbPacketServices` json DEFAULT NULL,
`traceData` json DEFAULT NULL,
`sharedTraceDataId` varchar(50) DEFAULT NULL,
`expectedUeBehavioursList` json DEFAULT NULL,
`suggestedPacketNumDlList` json DEFAULT NULL,
`3gppChargingCharacteristics` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `SmfRegistrations`
--
CREATE TABLE `SmfRegistrations` (
`ueid` varchar(15) NOT NULL,
`subpduSessionId` int(10) NOT NULL,
`smfInstanceId` varchar(50) NOT NULL,
`smfSetId` varchar(50) DEFAULT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`pduSessionId` int(10) NOT NULL,
`singleNssai` json NOT NULL,
`dnn` varchar(50) DEFAULT NULL,
`emergencyServices` tinyint(1) DEFAULT NULL,
`pcscfRestorationCallbackUri` varchar(50) DEFAULT NULL,
`plmnId` json NOT NULL,
`pgwFqdn` varchar(50) DEFAULT NULL,
`epdgInd` tinyint(1) DEFAULT NULL,
`deregCallbackUri` varchar(50) DEFAULT NULL,
`registrationReason` json DEFAULT NULL,
`registrationTime` varchar(50) DEFAULT NULL,
`contextInfo` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `SmfSelectionSubscriptionData`
--
CREATE TABLE `SmfSelectionSubscriptionData` (
`ueid` varchar(15) NOT NULL,
`servingPlmnid` varchar(15) NOT NULL,
`supportedFeatures` varchar(50) DEFAULT NULL,
`subscribedSnssaiInfos` json DEFAULT NULL,
`sharedSnssaiInfosId` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `AccessAndMobilitySubscriptionData`
--
ALTER TABLE `AccessAndMobilitySubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- Indexes for table `Amf3GppAccessRegistration`
--
ALTER TABLE `Amf3GppAccessRegistration`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `AuthenticationStatus`
--
ALTER TABLE `AuthenticationStatus`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `AuthenticationSubscription`
--
ALTER TABLE `AuthenticationSubscription`
ADD PRIMARY KEY (`ueid`);
--
-- Indexes for table `SdmSubscriptions`
--
ALTER TABLE `SdmSubscriptions`
ADD PRIMARY KEY (`subsId`,`ueid`) USING BTREE;
--
-- Indexes for table `SessionManagementSubscriptionData`
--
ALTER TABLE `SessionManagementSubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- Indexes for table `SmfRegistrations`
--
ALTER TABLE `SmfRegistrations`
ADD PRIMARY KEY (`ueid`,`subpduSessionId`) USING BTREE;
--
-- Indexes for table `SmfSelectionSubscriptionData`
--
ALTER TABLE `SmfSelectionSubscriptionData`
ADD PRIMARY KEY (`ueid`,`servingPlmnid`) USING BTREE;
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `SdmSubscriptions`
--
ALTER TABLE `SdmSubscriptions`
MODIFY `subsId` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@@ -35,4 +35,4 @@ COPY . .
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci
./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512

View File

@@ -35,4 +35,4 @@ COPY . .
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci
./build_oai --eNB --gNB --RU --UE --nrUE --ninja --build-lib all -w USRP --verbose-ci --noavx512

View File

@@ -38,7 +38,7 @@ RUN yum install -y libasan
RUN /bin/sh oaienv && \
cd cmake_targets && \
mkdir -p log && \
./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address
./build_oai --phy_simulators --ninja --verbose-ci --sanitize-address --noavx512
#start from scratch for target executable
FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim

View File

@@ -64,6 +64,10 @@ static int DEFENBS[] = {0};
#include <openair2/LAYER2/MAC/mac_vars.h>
#include <openair2/RRC/LTE/rrc_vars.h>
#if LATSEQ
#include "common/utils/LATSEQ/latseq.h"
#endif
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
@@ -173,7 +177,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
}
for (int i=0; i<NUMBER_OF_ULSCH_MAX; i++) {
LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
LOG_D(PHY,"Allocating Transport Channel Buffers for ULSCH, UE %d\n",i);
AssertFatal((eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0)) != NULL,
"Can't get eNB ulsch structures\n");
// this is the transmission mode for the signalling channels
@@ -677,7 +681,7 @@ void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
exit_fun("Exiting IQ record/playback");
#else
//exit_fun( "problem receiving samples" );
LOG_E(PHY, "problem receiving samples");
LOG_E(PHY, "problem receiving samples\n");
#endif
}
@@ -689,6 +693,11 @@ void rx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
old_ts=timestamp_rx;
setAllfromTS(timestamp_rx, proc);
#if LATSEQ
LATSEQ_P("U phy.in.ant--phy.in.proc","len%d::fm%d.subfm%d", rxs, proc->frame_rx, proc->subframe_rx);
#endif
}
void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
@@ -734,6 +743,11 @@ void ocp_tx_rf(RU_t *ru, L1_rxtx_proc_t *proc) {
sf_extension = (sf_extension)&0xfffffffc;
#endif
#if LATSEQ
LATSEQ_P("D phy.out.proc--phy.out.ant","len%d::fm%d.subfm%d",siglen, proc->frame_tx, proc->subframe_tx);
#endif
for (i=0; i<ru->nb_tx; i++)
txp[i] = (void *)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension];
@@ -1154,7 +1168,9 @@ int main ( int argc, char **argv ) {
set_softmodem_sighandler();
cpuf=get_cpu_freq_GHz();
set_taus_seed (0);
#if LATSEQ
init_latseq("/tmp/main_ocp", (uint64_t)(cpuf*1000000000LL));
#endif
if (opp_enabled ==1)
reset_opp_meas();
@@ -1338,6 +1354,9 @@ int main ( int argc, char **argv ) {
oai_exit=1;
LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
// stop threads
#if LATSEQ
close_latseq(); //close before end of threads
#endif
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
if(IS_SOFTMODEM_DOSCOPE)

View File

@@ -304,32 +304,36 @@ void rx_func(void *param) {
);
#endif
}
static void dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output) {
int stroff = 0;
stroff += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output);
stroff += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output+stroff);
stroff += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output+stroff);
stroff += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output+stroff);
stroff += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output+stroff);
stroff += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output+stroff);
stroff += print_meas_log(&gNB->schedule_response_stats, "Schedule Response",NULL,NULL, output+stroff);
if (ru->feprx) stroff += print_meas_log(&ru->ofdm_demod_stats,"feprx",NULL,NULL, output+stroff);
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
const char *begin = output;
const char *end = output + outputlen;
output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->schedule_response_stats, "Schedule Response", NULL, NULL, output, end - output);
if (ru->feprx)
output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
if (ru->feptx_ofdm) {
stroff += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output+stroff);
stroff += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output+stroff);
stroff += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output+stroff);
stroff += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output+stroff);
output += print_meas_log(&ru->precoding_stats,"feptx_prec",NULL,NULL, output, end - output);
output += print_meas_log(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL, output, end - output);
output += print_meas_log(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL, output, end - output);
output += print_meas_log(&ru->ofdm_total_stats,"feptx_total",NULL,NULL, output, end - output);
}
if (ru->fh_north_asynch_in) stroff += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output+stroff);
if (ru->fh_north_asynch_in)
output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output);
stroff += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output+stroff);
output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output);
if (ru->fh_north_out) {
stroff += print_meas_log(&ru->compression,"compression",NULL,NULL, output+stroff);
stroff += print_meas_log(&ru->transport,"transport",NULL,NULL, output+stroff);
output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output);
output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output);
}
return output - begin;
}
void *nrL1_stats_thread(void *param) {
@@ -355,7 +359,7 @@ void *nrL1_stats_thread(void *param) {
dump_nr_I0_stats(fd,gNB);
dump_pdsch_stats(fd,gNB);
dump_pusch_stats(fd,gNB);
dump_L1_meas_stats(gNB, ru, output);
dump_L1_meas_stats(gNB, ru, output, L1STATSSTRLEN);
fprintf(fd,"%s\n",output);
fflush(fd);
fseek(fd,0,SEEK_SET);
@@ -380,7 +384,7 @@ void *tx_reorder_thread(void* param) {
if (resL1Reserve) {
resL1=resL1Reserve;
if (((processingData_L1tx_t *)NotifiedFifoData(resL1))->slot != next_tx_slot) {
LOG_E(PHY,"order mistake");
LOG_E(PHY,"order mistake\n");
resL1Reserve=NULL;
resL1 = pullTpool(gNB->L1_tx_out, gNB->threadPool);
}
@@ -600,7 +604,8 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
gNB->prach_energy_counter = 0;
gNB->prb_interpolation = get_softmodem_params()->prb_interpolation;
gNB->chest_time = get_softmodem_params()->chest_time;
gNB->chest_freq = get_softmodem_params()->chest_freq;
}

View File

@@ -719,10 +719,17 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb);
if(slot%(fp->slots_per_subframe/2))
siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
else
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
if (fp->slots_per_subframe == 1) {
if (txsymb <= 7)
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
else
siglen = 2 * (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 2) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
} else {
if(slot%(fp->slots_per_subframe/2))
siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
else
siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples);
}
//+ ru->end_of_burst_delay;
flags = 3; // end of burst
@@ -1049,11 +1056,12 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
cfg->tx_gain[i] = ru->att_tx;
cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
cfg->configFilename = rf_config_file;
LOG_I(PHY, "Channel %d: setting tx_gain offset %f, rx_gain offset %f, tx_freq %lu Hz, rx_freq %lu Hz\n",
LOG_I(PHY, "Channel %d: setting tx_gain offset %.0f, rx_gain offset %.0f, tx_freq %.0f Hz, rx_freq %.0f Hz, tune_offset %.0f Hz\n",
i, cfg->tx_gain[i],
cfg->rx_gain[i],
(unsigned long)cfg->tx_freq[i],
(unsigned long)cfg->rx_freq[i]);
cfg->tx_freq[i],
cfg->rx_freq[i],
cfg->tune_offset);
}
}
@@ -2051,6 +2059,8 @@ static void NRRCconfig_RU(void) {
RC.ru[j]->openair0_cfg.time_source = internal;
}
RC.ru[j]->openair0_cfg.tune_offset = get_softmodem_params()->tune_offset;
if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
RC.ru[j]->if_south = LOCAL_RF;

View File

@@ -61,6 +61,9 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#if LATSEQ
"common/utils/LATSEQ/latseq.h"
#endif
#include "intertask_interface.h"
@@ -651,7 +654,12 @@ int main( int argc, char **argv ) {
}
cpuf=get_cpu_freq_GHz();
#if LATSEQ
init_latseq("/tmp/nr_softmodem", (uint64_t)(cpuf*1000000000LL));
#endif
itti_init(TASK_MAX, tasks_info);
// initialize mscgen log after ITTI
init_opt();
if(PDCP_USE_NETLINK && !IS_SOFTMODEM_NOS1) {
@@ -823,6 +831,9 @@ int main( int argc, char **argv ) {
}
#endif*/
#if LATSEQ
close_latseq(); //close befire head of threads
#endif
printf("stopping MODEM threads\n");
// cleanup
stop_gNB(NB_gNB_INST);

View File

@@ -106,23 +106,24 @@ queue_t nr_rach_ind_queue;
static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
static int dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, int max_len)
static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
{
int stroff = 0;
stroff += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output);
stroff += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output + stroff);
stroff += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output + stroff);
return stroff;
const char *begin = output;
const char *end = output + max_len;
output += print_meas_log(&ue->phy_proc_tx, "L1 TX processing", NULL, NULL, output, end - output);
output += print_meas_log(&ue->ulsch_encoding_stats, "ULSCH encoding", NULL, NULL, output, end - output);
output += print_meas_log(&ue->phy_proc_rx[0], "L1 RX processing t0", NULL, NULL, output, end - output);
output += print_meas_log(&ue->phy_proc_rx[1], "L1 RX processing t1", NULL, NULL, output, end - output);
output += print_meas_log(&ue->ue_ul_indication_stats, "UL Indication", NULL, NULL, output, end - output);
output += print_meas_log(&ue->rx_pdsch_stats, "PDSCH receiver", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_decoding_stats[0], "PDSCH decoding t0", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_decoding_stats[1], "PDSCH decoding t1", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_deinterleaving_stats, " -> Deinterleive", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_rate_unmatching_stats, " -> Rate Unmatch", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_ldpc_decoding_stats, " -> LDPC Decode", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_unscrambling_stats, "PDSCH unscrambling", NULL, NULL, output, end - output);
output += print_meas_log(&ue->dlsch_rx_pdcch_stats, "PDCCH handling", NULL, NULL, output, end - output);
return output - begin;
}
static void *nrL1_UE_stats_thread(void *param)

View File

@@ -259,13 +259,11 @@ void init_tpools(uint8_t nun_dlsch_threads) {
}
static void get_options(void) {
nrUE_params.ofdm_offset_divisor = 8;
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_get(cmdline_params,numparams,NULL);
config_process_cmdline( cmdline_params,numparams,NULL);
if (vcdflag > 0)
ouput_vcd = 1;
}
@@ -317,8 +315,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset;
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation);
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, chest-freq %d\n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->chest_freq);
// Set FP variables
@@ -330,6 +328,7 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d, ssb_start_subcarrier %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs, fp->ssb_start_subcarrier);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations;
}
@@ -354,6 +353,7 @@ void init_openair0(void) {
openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
openair0_cfg[card].tune_offset = get_softmodem_params()->tune_offset;
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);

View File

@@ -7,10 +7,11 @@
#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed"
#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed"
#define CONFIG_HLP_IF_FREQ "IF frequency for RF, if needed\n"
#define CONFIG_HLP_IF_FREQ_OFF "UL IF frequency offset for RF, if needed\n"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
#define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -30,8 +31,9 @@
#define CMDLINE_NRUEPARAMS_DESC { \
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, u8ptr:&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:&nrUE_params.ofdm_offset_divisor, defuintval:8, TYPE_UINT32, 0}, \
{"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, u8ptr:&nrUE_params.max_ldpc_iterations, defuintval:5, TYPE_UINT8, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"uecap_file", CONFIG_HLP_UECAP_FILE, 0, strptr:(char **)&uecap_file, defstrval:"./uecap.xml", TYPE_STRING, 0}, \
@@ -67,7 +69,8 @@
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"if_freq" , CONFIG_HLP_IF_FREQ, 0, u64ptr:&(UE->if_freq), defuintval:0, TYPE_UINT64,0}, \
{"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, iptr:&(UE->if_freq_off), defuintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&(UE->chest_freq), defintval:0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&(UE->chest_time), defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
}
@@ -76,6 +79,7 @@ typedef struct {
uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
uint8_t max_ldpc_iterations; // number of maximum LDPC iterations
tpool_t Tpool; // thread pool
} nrUE_params_t;
extern uint64_t get_nrUE_optmask(void);

View File

@@ -60,6 +60,7 @@ extern "C"
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_TME "tells hardware to use a time reference (0:internal, 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_TUNE_OFFSET "LO tuning offset to use in Hz\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
@@ -71,7 +72,8 @@ extern "C"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n"
#define CONFIG_HLP_CHESTFREQ "Set channel estimation type in frequency domain. 0-Linear interpolation (default). 1-PRB based averaging of channel estimates in frequency. \n"
#define CONFIG_HLP_CHESTTIME "Set channel estimation type in time domain. 0-Symbols take estimates of the last preceding DMRS symbol (default). 1-Symbol based averaging of channel estimates in time. \n"
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
@@ -118,9 +120,11 @@ extern "C"
#define EMULATE_RF softmodem_params.emulate_rf
#define CLOCK_SOURCE softmodem_params.clock_source
#define TIMING_SOURCE softmodem_params.timing_source
#define TUNE_OFFSET softmodem_params.tune_offset
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define PRB_INTERPOLATION softmodem_params.prb_interpolation
#define CHEST_FREQ softmodem_params.chest_freq
#define CHEST_TIME softmodem_params.chest_time
#define NFAPI softmodem_params.nfapi
#define NSA softmodem_params.nsa
#define NODE_NUMBER softmodem_params.node_number
@@ -141,6 +145,7 @@ extern int usrp_tx_thread;
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"tune-offset", CONFIG_HLP_TUNE_OFFSET, 0, dblptr:&TUNE_OFFSET, defintval:0, TYPE_DOUBLE, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \
{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
@@ -157,10 +162,11 @@ extern int usrp_tx_thread;
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \
{"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
{"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \
@@ -203,6 +209,7 @@ extern int usrp_tx_thread;
#define SOFTMODEM_NONBIOT_BIT (1<<2)
#define SOFTMODEM_RFSIM_BIT (1<<10)
#define SOFTMODEM_SIML1_BIT (1<<12)
#define SOFTMODEM_DLSIM_BIT (1<<13)
#define SOFTMODEM_DOSCOPE_BIT (1<<15)
#define SOFTMODEM_RECPLAY_BIT (1<<16)
#define SOFTMODEM_TELNETCLT_BIT (1<<17)
@@ -219,6 +226,7 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
@@ -245,9 +253,12 @@ typedef struct {
int band;
uint32_t clock_source;
uint32_t timing_source;
double tune_offset;
int hw_timing_advance;
uint32_t send_dmrs_sync;
int prb_interpolation;
int use_256qam_table;
int chest_time;
int chest_freq;
uint8_t nfapi;
int nsa;
uint16_t node_number;

View File

@@ -0,0 +1,64 @@
SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX
-2.000000 1.000000 0.346185 0.258473 44.551218 31.688925 357.883903 217.655668 12.810778 326.852166 5.000000 0.000000 5
-1.900000 1.000000 0.345395 0.256275 40.787109 4.190954 65.926488 215.687102 4.300128 230.585721 5.000000 0.000000 5
-1.800000 1.000000 0.343100 0.253634 40.748628 3.912915 56.669470 215.314020 4.139156 227.806468 5.000000 0.000000 5
-1.700000 1.000000 0.341806 0.250634 40.550845 3.347808 56.032851 216.839001 5.959734 244.483352 5.000000 0.000000 5
-1.600000 1.000000 0.339245 0.248129 40.457158 3.735092 56.853508 215.747244 4.995522 242.867659 5.000000 0.000000 5
-1.500000 1.000000 0.337230 0.245763 41.178595 4.297429 56.265874 215.785600 4.151781 227.795995 5.000000 0.000000 5
-1.400000 1.000000 0.335131 0.243311 39.915221 2.739586 55.454917 216.866764 6.547848 251.528327 5.000000 0.000000 5
-1.300000 1.000000 0.333085 0.240664 40.119215 3.044973 55.978253 216.208443 4.459816 228.810686 5.000000 0.000000 5
-1.200000 1.000000 0.330664 0.238769 40.507713 2.998241 55.701876 215.868796 3.778455 226.049304 5.000000 0.000000 5
-1.100000 1.000000 0.329130 0.235812 41.038895 4.522472 56.760814 215.654663 4.746822 236.021980 5.000000 0.000000 5
-1.000000 1.000000 0.325980 0.233534 41.067622 4.626711 57.444142 215.260535 3.481966 225.512853 5.000000 0.000000 5
-0.900000 1.000000 0.323823 0.230863 40.683316 3.689159 56.208182 215.560917 5.180017 243.603452 5.000000 0.000000 5
-0.800000 1.000000 0.321004 0.228222 41.643513 4.717568 58.502452 215.630891 4.283475 238.574145 5.000000 0.000000 5
-0.700000 1.000000 0.317983 0.225520 41.214547 3.941824 56.054211 215.910346 4.375081 227.444626 5.000000 0.000000 5
-0.600000 1.000000 0.316243 0.222903 40.834442 4.370416 56.765508 215.153296 3.617927 226.280086 5.000000 0.000000 5
-0.500000 1.000000 0.312886 0.220473 40.178174 4.185502 64.657291 219.647151 4.454154 236.473446 5.000000 0.000000 5
-0.400000 1.000000 0.309757 0.217536 40.240385 3.172484 55.751563 217.761119 3.900779 228.757195 5.000000 0.000000 5
-0.300000 1.000000 0.305464 0.215229 40.852271 3.761739 56.158869 217.830497 4.087453 230.237764 5.000000 0.000000 5
-0.200000 1.000000 0.302919 0.212364 40.531166 3.688281 56.426841 217.657657 5.498697 253.516146 5.000000 0.000000 5
-0.100000 1.000000 0.298246 0.209310 41.058364 4.140510 59.959571 217.519279 4.087389 228.768313 5.000000 0.000000 5
0.000000 1.000000 0.294110 0.207107 40.436486 3.604369 55.788895 217.853044 4.012624 236.118036 5.000000 0.000000 5
0.100000 1.000000 0.288139 0.204033 40.603738 4.045866 57.560760 217.046816 4.583841 244.429411 5.000000 0.000000 5
0.200000 1.000000 0.285604 0.201954 40.494607 3.886199 59.431970 217.322824 4.080988 233.317513 5.000000 0.000000 5
0.300000 1.000000 0.278478 0.198929 40.311327 3.452837 56.124657 217.319394 4.434358 232.534720 5.000000 0.000000 5
0.400000 1.000000 0.270992 0.196299 40.649243 3.415612 56.204178 218.079445 4.990947 245.055337 5.000000 0.000000 5
0.500000 1.000000 0.263944 0.193661 40.464299 3.622703 56.602842 218.555364 3.936432 229.481159 5.000000 0.000000 5
0.600000 1.000000 0.256340 0.191194 40.200314 2.474984 53.432412 216.547260 3.695211 227.198078 5.000000 0.000000 5
0.700000 1.000000 0.251578 0.188606 40.111945 3.029821 54.900896 216.581752 4.247622 237.358365 5.000000 0.000000 5
0.800000 1.000000 0.234558 0.184742 39.533282 1.182169 42.753097 215.462335 2.960246 226.716604 5.000000 0.000000 5
0.900000 1.000000 0.225915 0.182691 39.851294 1.108193 42.180342 216.404194 4.450720 228.482353 5.000000 0.000000 5
1.000000 1.000000 0.216180 0.179994 40.721936 3.302539 56.032206 217.082196 4.599188 227.979232 5.000000 0.000000 5
1.100000 1.000000 0.203481 0.177332 41.006217 3.798207 56.014901 216.204345 4.292145 227.297386 5.000000 0.000000 5
1.200000 1.000000 0.188297 0.174121 40.739289 3.269948 56.653507 216.585873 6.250858 251.207034 5.000000 0.000000 5
1.300000 1.000000 0.172624 0.171622 41.215540 4.783342 55.692883 215.885639 3.629370 226.473280 5.000000 0.000000 5
1.400000 1.000000 0.156483 0.169110 40.289903 3.749338 56.290861 215.663761 4.176366 225.824735 5.000000 0.000000 5
1.500000 1.000000 0.136293 0.165692 42.208932 6.070189 69.182665 216.390504 4.816283 235.417446 5.000000 0.000000 5
1.600000 1.000000 0.125127 0.163325 40.890581 3.941185 56.491504 215.752348 4.426511 226.425984 5.000000 0.000000 5
1.700000 1.000000 0.104593 0.159971 41.263557 4.128935 57.062514 217.284932 5.311288 249.647163 5.000000 0.000000 5
1.800000 1.000000 0.091397 0.157460 40.273078 3.062810 55.546913 217.252505 6.331426 251.175692 5.000000 0.000000 5
1.900000 1.000000 0.078256 0.154628 40.407489 3.419342 56.316166 216.967648 4.712664 245.093313 5.000000 0.000000 5
2.000000 1.000000 0.065221 0.152571 40.660365 4.317854 57.537407 216.198346 4.991856 245.173269 5.000000 0.000000 5
2.100000 1.000000 0.053694 0.148885 40.355654 4.062614 60.051963 215.797667 4.447252 236.221454 5.000000 0.000000 5
2.200000 1.000000 0.042182 0.146229 40.613562 4.124655 56.201536 216.117304 4.060825 227.115987 5.000000 0.000000 5
2.300000 1.000000 0.034334 0.143612 40.465884 3.541452 55.067611 215.575953 4.891719 244.546802 5.000000 0.000000 5
2.400000 1.000000 0.026641 0.140869 41.074690 4.697458 61.619188 216.069185 4.700827 233.830937 5.000000 0.000000 5
2.500000 1.000000 0.019976 0.138112 40.766971 4.274128 58.871741 215.761570 5.633731 249.753931 5.000000 0.000000 5
2.600000 1.000000 0.012826 0.135122 40.559343 2.952804 54.017706 215.835161 4.039993 226.822103 5.000000 0.000000 5
2.700000 1.000000 0.010550 0.132915 40.985193 3.330639 55.013950 215.975836 4.240744 227.040703 5.000000 0.000000 5
2.800000 1.000000 0.007327 0.130133 39.778804 3.002485 56.610555 216.462786 7.082268 265.051418 5.000000 0.000000 5
2.900000 1.000000 0.004038 0.126763 40.327795 3.934211 55.515352 215.982666 4.626198 230.696124 5.000000 0.000000 5
3.000000 1.000000 0.003087 0.124336 40.337807 3.537021 55.101627 215.468662 4.177203 230.789145 5.000000 0.000000 5
3.100000 1.000000 0.001576 0.121689 39.812195 3.116738 55.422687 215.797778 4.091192 225.897780 5.000000 0.000000 5
3.200000 0.980000 0.001000 0.118928 39.853764 2.871322 56.405555 215.562722 4.187466 232.598421 5.000000 0.000000 5
3.300000 0.960000 0.000623 0.116065 40.440328 3.580650 56.738889 216.165848 4.735158 240.329999 5.000000 0.000000 5
3.400000 0.850000 0.000303 0.113505 40.974107 4.291544 56.280236 215.889562 4.448049 237.556780 5.000000 0.000000 5
3.500000 0.690000 0.000152 0.111010 41.508631 4.251791 56.198873 216.740295 4.889693 242.922934 5.000000 0.000000 5
3.600000 0.530000 0.000102 0.108493 40.065231 3.643794 57.120823 216.887338 5.242621 250.003843 5.000000 0.000000 5
3.700000 0.320000 0.000043 0.105612 40.462159 4.162383 56.782173 216.465615 3.846314 227.022697 5.000000 0.000000 5
3.800000 0.210000 0.000032 0.103084 42.192455 6.207380 64.648964 217.030913 4.482820 228.095918 5.000000 0.000000 5
3.900000 0.110000 0.000013 0.100391 40.640286 3.715782 55.922914 217.726055 4.553212 236.362804 5.000000 0.000000 5
4.000000 0.050000 0.000006 0.097518 40.437760 2.838308 54.764308 218.230040 4.309275 237.932625 5.000000 0.000000 5
4.100000 0.020000 0.000002 0.095436 41.347934 4.608500 64.182062 217.408836 4.385757 228.219627 5.000000 0.000000 5
4.200000 0.000000 0.000000 0.092396 40.782371 3.621708 55.984245 217.579878 4.102149 228.145363 5.000000 0.000000 5

View File

@@ -434,6 +434,9 @@ typedef struct {
uint8_t mcs;
uint8_t ndi;
uint8_t rv;
uint16_t targetCodeRate;
uint8_t qamModOrder;
uint32_t TBS;
uint8_t tb2_mcs;
uint8_t tb2_ndi;
uint8_t tb2_rv;
@@ -478,20 +481,20 @@ typedef struct {
typedef struct {
uint16_t bwp_size;//
uint16_t bwp_start;//
uint8_t subcarrier_spacing;//
uint8_t cyclic_prefix;//
uint16_t start_rb;
uint16_t nr_of_rbs;
uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
uint8_t symb_l1;//
uint8_t cdm_type;
uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
} fapi_nr_dl_config_csirs_pdu_rel15_t;

View File

@@ -925,32 +925,24 @@ typedef struct
} nfapi_nr_dlsch_pdu_t;
*/
//for csi-rs_pdu:
//table 3-39
typedef struct
{
uint16_t bwp_size;//
uint16_t bwp_start;//
uint8_t subcarrier_spacing;//
uint8_t cyclic_prefix;//
uint16_t start_rb;
uint16_t nr_of_rbs;
uint8_t csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
uint8_t row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
uint8_t symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
uint8_t symb_l1;//
uint8_t cdm_type;
uint8_t freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
//tx power info
uint8_t power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps
uint8_t power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
} nfapi_nr_dl_tti_csi_rs_pdu_rel15_t;
//for ssb_pdu:
typedef struct
{

View File

@@ -200,8 +200,6 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppW
static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
return(
push16(value->bwp_size, ppWritePackedMsg, end) &&
push16(value->bwp_start, ppWritePackedMsg, end) &&
push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
push16(value->start_rb, ppWritePackedMsg, end) &&
@@ -3663,8 +3661,6 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
return(
pull16(ppReadPackedMsg, &value->bwp_size, end) &&
pull16(ppReadPackedMsg, &value->bwp_start, end) &&
pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
pull16(ppReadPackedMsg, &value->start_rb, end) &&

View File

@@ -38,7 +38,6 @@
#define MAX_TURBO_ITERATIONS_MBSFN 8
#define MAX_TURBO_ITERATIONS max_turbo_iterations
#define MAX_LDPC_ITERATIONS 5
#define MAX_LDPC_ITERATIONS_MBSFN 4
#define LTE_NULL 2
@@ -469,18 +468,6 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int *F,
uint8_t BG);
/*!\fn uint32_t nr_compute_tbs
\brief This function returns the TBS in bits as per 6.1.4.2 of TS 38.214
*/
uint32_t nr_compute_tbs(uint16_t Qm,
uint16_t R,
uint16_t nb_rb,
uint16_t nb_symb_sch,
uint16_t nb_dmrs_prb,
uint16_t nb_rb_oh,
uint8_t tb_scaling,
uint8_t Nl);
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,960 +0,0 @@
%
% 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
%
\documentclass{article}
\usepackage[a4paper, total={6in, 8in}]{geometry}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{booktabs}
\usepackage{url}
\usepackage{tcolorbox}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations,shapes,backgrounds,patterns}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\definecolor{green}{RGB}{32,127,43}
\usetikzlibrary{calc}
\usepackage{listings}
\lstdefinestyle{customc}{
belowcaptionskip=1\baselineskip,
breaklines=true,
frame=L,
xleftmargin=\parindent,
language=C,
showstringspaces=false,
basicstyle=\footnotesize\ttfamily,
keywordstyle=\bfseries\color{green!40!black},
commentstyle=\itshape\color{purple!40!black},
identifierstyle=\color{blue},
stringstyle=\color{orange},
}
\lstset{escapechar=@,style=customc}
\title{NR LDPC Decoder}
\author{Sebastian Wagner (TCL)}
\date{\today}
\def\0{\mathbf{0}}
\def\b{\mathbf{b}}
\def\Bbb{\mathbb{B}}
\def\Bcal{\mathcal{B}}
\def\c{\mathbf{c}}
\def\C{\mathbf{C}}
\def\Cbb{\mathbb{C}}
\def\Ccal{\mathcal{C}}
\def\eqdef{\triangleq}
\def\g{\mathbf{g}}
\def\G{\mathbf{G}}
\def\Gcal{\mathcal{G}}
\def\h{\mathbf{h}}
\def\H{\mathbf{H}}
\def\Hbg{\mathbf{H}_\mathrm{BG}}
\def\Hbgo{\mathbf{H}_\mathrm{BG1}}
\def\Hbgt{\mathbf{H}_\mathrm{BG2}}
\def\I{\mathbf{I}}
\def\Kb{{K_b}}
\def\m{\mathbf{m}}
\def\Mb{{M_b}}
\def\Nb{{N_b}}
\def\Nbb{\mathbb{N}}
\def\n{\mathbf{n}}
\def\nr{{n_{\rm r}}}
\def\nt{{n_{\rm t}}}
\def\s{\mathbf{s}}
\def\SNR{\mathsf{SNR}}
\def\y{\mathbf{y}}
\def\z{\mathbf{z}}
\def\Z{\mathbf{Z}}
\def\Zc{{Z_c}}
\def\herm{\mathsf{H}}
\def\trans{\mathsf{T}}
\def\EE{\mathsf{E}}
\newcommand{\sgn}{\operatorname{sgn}}
\begin{document}
\maketitle
\begin{tikzpicture}[remember picture,overlay]
\node[anchor=north west,inner sep=0pt] at (current page.north west)
{\includegraphics[scale=0.5]{logo.png}};
\end{tikzpicture}
\begin{center}Currently Supported:\end{center}
\tcbox[center]{
\begin{tabular}{lll}
\toprule
\textbf{BG} & \textbf{Lifting Size Z} & \textbf{Code Rate R} \\
\midrule
1 & all & 1/3, 2/3, 8/9 \\
2 & all & 1/5, 1/3, 2/3 \\
\bottomrule
\end{tabular}
}
\paragraph{Version 1.0:}
\begin{itemize}
\item Initial version
\end{itemize}
\paragraph{Version 2.0:}
\begin{itemize}
\item Enhancements in message passing:
\begin{itemize}
\item LUTs replaced by smaller BG-specific parameters
\item Inefficient load/store replaced by circular memcpy
\end{itemize}
\item Bug fixes:
\begin{itemize}
\item Fixed bug in function \texttt{llr2CnProcBuf}
\item Corrected input LLR dynamic range in BLER simulations
\end{itemize}
\item Results:
\begin{itemize}
\item Size of LUTs reduced significantly (60MB to 200KB)
\item Siginifcantly enhances execution time (factor 3.5)
\item Improved BLER performance (all simulation results have been updated)
\end{itemize}
\end{itemize}
\newpage
\tableofcontents
\newpage
\section{Introduction}
\label{sec:introduction}
Low Density Parity Check (LDPC) codes have been developed by Gallager in 1963 \cite{gallager1962low}. They are linear error correcting codes that are capacity-achieving for large block length and are completely described by their Parity Check Matrix (PCM) $\H^{M\times N}$. The PCM $\H$ defines $M$ constraints on the codeword $\c$ of length $N$ such that
\begin{equation}
\label{eq:29}
\H\c = \0.
\end{equation}
The number of information bits $B$ that can be encoded with $\H$ is given by $B=N-M$. Hence the code rate $R$ of $\H$ reads
\begin{equation}
\label{eq:37}
R = \frac{B}{N} = 1-\frac{M}{N}.
\end{equation}
\subsection{LDPC in NR}
\label{sec:ldpc-nr}
NR uses quasi-cyclic (QC) Protograph LDPC codes, i.e. a smaller graph, called Base Graph (BG), is defined and utilized to construct the larger PCM. This has the advantage that the large PCM does not have to be stored in memory and allows for a more efficient implementation while maintaining good decoding properties.
Two BGs $\Hbg\in\Nbb^{\Mb\times \Nb}$ are defined in NR:
\begin{enumerate}
\item $\Hbgo\in\Nbb^{46\times 68}$
\item $\Hbgt\in\Nbb^{42\times 52}$
\end{enumerate}
where $\Nbb$ is the set of integers. For instance the first 3 rows and 13 columns of BG2 are given by
\setcounter{MaxMatrixCols}{30}
\begin{equation*}
\label{eq:33}
\Hbgt =
\begin{bmatrix}
9 & 117 & 204 & 26 & \emptyset & \emptyset & 189 & \emptyset & \emptyset & 205 & 0 & 0 & \emptyset & \emptyset \\
127 & \emptyset & \emptyset & 166 & 253 & 125 & 226 & 156 & 224 & 252 & \emptyset & 0 & 0 & \emptyset \\
81 & 114 & \emptyset & 44 & 52 & \emptyset & \emptyset & \emptyset & 240 & \emptyset & 1 & \emptyset & 0 & 0
\end{bmatrix}.
\end{equation*}
To obtain the PCM $\H$ from the BG $\Hbg$, each element $\Hbg(i,j)$ in the BG is replaced by a lifting matrix of size $\Zc\times \Zc$ according to
\begin{equation}
\label{eq:35}
\Hbg(i,j) =
\begin{cases}
\0 & \textrm{if}~ \Hbg(i,j)=\emptyset \\
\I_{P_{ij}} & \textrm{otherwise}
\end{cases}
\end{equation}
where $\I_{P_{ij}}$ is the identity matrix circularly shifted to the right by $P_{ij} = \Hbg(i,j)\mod \Zc$. Hence, the resulting PCM $\H$ will be of size $\Mb\Zc\times\Nb\Zc$.
The lifting size $\Zc$ depends on the number of bits to encode. To limit the complexity, a discrete set $\mathcal{Z}$ of possible values of $\Zc$ has been defined in \cite{3gpp2017_38212} and the optimal value $\Zc$ is calculated according to
\begin{equation}
\label{eq:36}
\Zc = \min_{\Z\in\mathcal{Z}}\left[Z\geq\frac{B}{\Nb}\right].
\end{equation}
The base rate of the two BGs is $1/3$ and $1/5$ for BG1 and BG2, respectively. That is, BG1 encodes $K=22\Zc$ bits and BG2 encodes $K=10\Zc$ bits. Note that the first 2 columns of BG 1 and 2 are always punctured, that is after encoding, the first $2\Zc$ bits are discarded and not transmitted.
For instance, consider $B=500$ information bits to encode using BG2, \eqref{eq:36} yields $\Zc=64$ hence $K=640$. Since $K>B$, $K-B=140$ filler bits are appended to the information bits. The PCM $\Hbgt$ is of size $2688\times 3328$ and the $640$ bits $\b$ are encoded according to \eqref{eq:29} at a rate $R \approx 0.192$. To achieve the higher base rate of $0.2$, the first $128$ are punctured, i.e. instead of transmitting all $3328$ bits, only $3200$ are transmitted resulting in the desired rate $R=640/3200=0.2$.
\subsection{LDPC Decoding}
\label{sec:ldpc-decoding}
The decoding of codeword $\c$ can be achieved via the classical message passing algorithm. This algorithm can be illustrated best using the Tanner graph of the PCM. The rows of the PCM are called check nodes (CN) since they represent the parity check equations. The parity check equation of each of these check nodes involves various bits in the codeword. Similarly, every column of the PCM corresponds to a bit and each bit is involved in several parity check equations. In the Tanner graph representation, the bits are called bit nodes (BN). Let's go back to the previous example of BG2 and assume $\Zc=2$, hence the first 3 rows and 13 columns of BG2 $\Hbgt$ read
\begin{equation*}
\label{eq:36}
\Hbgt =
\begin{bmatrix}
1 & 1 & 0 & 0 & \emptyset & \emptyset & 1 & \emptyset & \emptyset & 1 & 0 & 0 & \emptyset & \emptyset \\
1 & \emptyset & \emptyset & 0 & 1 & 1 & 0 & 0 & 0 & 0 & \emptyset & 0 & 0 & \emptyset \\
1 & 0 & \emptyset & 0 & 0 & \emptyset & \emptyset & \emptyset & 0 & \emptyset & 1 & \emptyset & 0 & 0
\end{bmatrix}.
\end{equation*}
Replacing the elements according to \eqref{eq:35}, we obtain the first 6 rows and 26 columns of the PCM as
\begin{equation*}
\label{eq:39}
\H =
\begin{bmatrix}
0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\
1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0\\
0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0\\
1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0\\
0 & 1 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 1 & 0\\
1 & 0 & 0 & 1 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 1 & 0 & 1
\end{bmatrix}.
\end{equation*}
The Tanner graph of the first 8 BNs is shown in Figure \ref{fig:tannergraph}.
\begin{figure}[ht]
\label{fig:tannergraph}
\centering
\def\ww{0.3cm}
\def\hh{0.3cm}
\tikzstyle{cnode}=[fill=white,rectangle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
\tikzstyle{vnode}=[fill=white,circle,draw=black,thick,inner sep=2pt, minimum height=\hh,minimum width=\ww, rounded corners=1pt,text width=\ww]
\tikzstyle{connector}=[<->,>=latex',semithick]
\begin{tikzpicture}
\tikzstyle{every node}=[node distance=1.5cm,text centered]
% Check nodes
\node[cnode, label=above:$v_0$] (v0) {};
\node[cnode, label=above:$v_1$, right of=v0] (v1) {};
\node[cnode, label=above:$v_2$, right of=v1] (v2) {};
% Variable nodes
\node[vnode, label=below:$c_3$, below of=v1, node distance=1.5cm] (c3) {};
\node[vnode, label=below:$c_2$, left of=c3, node distance=1.5cm] (c2) {};
\node[vnode, label=below:$c_1$, left of=c2, node distance=1.5cm] (c1) {};
\node[vnode, label=below:$c_0$, left of=c1, node distance=1.5cm] (c0) {};
\node[vnode, label=below:$c_4$, right of=c3, node distance=1.5cm] (c4) {};
\node[vnode, label=below:$c_5$, right of=c4, node distance=1.5cm] (c5) {};
\node[vnode, label=below:$c_6$, right of=c5, node distance=1.5cm] (c6) {};
% Draw edges
\draw (c0) edge[connector] (v1);
\draw (c1) edge[connector] (v0);
\draw (c1) edge[connector] (v2);
\draw (c2) edge[connector] (v1);
\draw (c3) edge[connector] (v0);
\draw (c4) edge[connector] (v0);
\draw (c4) edge[connector] (v2);
\draw (c5) edge[connector] (v1);
\draw (c6) edge[connector] (v0);
\draw (c6) edge[connector] (v2);
\end{tikzpicture}
\caption{Tanner graph for first 7 bits nodes and 3 check nodes from \eqref{eq:39}.}
\end{figure}
The message passing algorithm is an iterative algorithm where probabilities of the bits (being either 0 or 1) are exchanged between the BNs and CNs. After sufficient iterations, the probabilities will have either converged to either 0 or 1 and the parity check equations will be satisfied, at this point, the codeword has been decoded correctly.
\newpage
\section{LDPC Decoder Implementation}
\label{sec:ldpc-implementation}
The implementation on a general purpose processor (GPP) has to take advantage of potential instruction extension of the processor architecture. We focus on the Intel x86 instruction set architecture (ISA) and its advanced vector extension (AVX). In particular, we utilize AVX2 with its 256-bit single instruction multiple data (SIMD) format. In order to utilize AVX2 to speed up the processing at the CNs and BNs, the corresponding data has to be ordered/aligned in a specific way. The processing flow of the LDPC decoder is depicted in \ref{fig:ldpc_decoder_flow}.
\begin{figure}[ht]
\label{fig:ldpc_decoder_flow}
\centering
\def\ww{0.3cm}
\def\hh{0.3cm}
\tikzstyle{func}=[,draw=none]
\tikzstyle{connector}=[->,>=latex',semithick]
\begin{tikzpicture}
\tikzstyle{every node}=[node distance=2.5cm,text centered]
% Check nodes
% First iteration
\node[func] (llr2llrProcBuf) {\texttt{llr2llrProcBuf}};
\node[func, above of=llr2llrProcBuf] (llr2CnProcBuf) {\texttt{llr2CnProcBuf}};
\node[func, above right of=llr2CnProcBuf] (cnProc1) {\texttt{cnProc}};
\node[func, below right of=cnProc1] (cn2bnProcBuf1) {\texttt{cn2bnProcBuf}};
\node[func, below of=cn2bnProcBuf1] (bnProcPc1) {\texttt{bnProcPc}};
% Iterations
\node[func, right of=cnProc1, node distance=7cm] (cnProc) {\texttt{cnProc}};
\node[func, below right of=cnProc] (cn2bnProcBuf) {\texttt{cn2bnProcBuf}};
\node[func, below of=cn2bnProcBuf] (bnProcPc) {\texttt{bnProcPc}};
\node[func, below left of=cnProc] (bn2cnProcBuf) {\texttt{bn2cnProcBuf}};
\node[func, below of=bn2cnProcBuf] (bnProc) {\texttt{bnProc}};
% Post processing
\node[func, below of=bnProcPc] (llrRes2llrOut) {\texttt{llrRes2llrOut}};
\node[func, below of=llrRes2llrOut, node distance=1cm] (llr2bit) {\texttt{llr2bit}};
% Draw edges
\draw (llr2llrProcBuf) edge[connector] (llr2CnProcBuf);
\draw (llr2CnProcBuf) edge[connector] (cnProc1);
\draw (cnProc1) edge[connector] (cn2bnProcBuf1);
\draw (cn2bnProcBuf1) edge[connector] (bnProcPc1);
\draw (bnProcPc) edge[connector] (bnProc);
\draw (bnProc) edge[connector] (bn2cnProcBuf);
\draw (bn2cnProcBuf) edge[connector] node[above left] {\texttt{cnProcPc}} (cnProc);
\draw (cnProc) edge[connector] (cn2bnProcBuf);
\draw (cn2bnProcBuf) edge[connector] (bnProcPc);
\draw (bnProcPc1) edge[connector] (bnProc);
\draw (bnProcPc) edge[connector] node[left] {iterations done} (llrRes2llrOut);
\draw (llrRes2llrOut) edge[connector] (llr2bit);
% Boxes
\node[inner sep=0pt,above right of=cn2bnProcBuf1, node distance = 2.5cm] (ref) {};
\draw[fill=black,opacity=.2, rounded corners] (llr2llrProcBuf.south west) rectangle ($(ref) + (-.5cm,.5cm)$);
\draw[fill=black,opacity=.2, rounded corners] ($(ref) + (.5cm,.5cm)$) rectangle ($(bnProcPc.south east) + (.4cm,0)$);
\node[func, above of=cnProc1, node distance=.8cm] (iter1) {\textbf{First Iteration}};
\node[func, above of=cnProc , node distance=.8cm] (iterX) {\textbf{Subsequent Iterations}};
\end{tikzpicture}
\caption{LDPC Decoder processing flow.}
\end{figure}
The functions involved are described in more detail in Table \ref{tab:sum_func}.
\begin{table}[ht]
\centering
\begin{tabular}{ll}
\toprule
\textbf{Function} & \textbf{Description} \\
\midrule
\texttt{llr2llrProcBuf} & Copies input LLRs to LLR processing buffer \\
\texttt{llr2CnProcBuf} & Copies input LLRs to CN processing buffer \\
\texttt{cnProc} & Performs CN signal processing \\
\texttt{cnProcPc} & Performs parity check \\
\texttt{cn2bnProcBuf} & Copies the CN results to the BN processing buffer \\
\texttt{bnProcPc} & Performs BN processing for parity check and/or hard-decision \\
\texttt{bnProc} & Utilizes the results of \texttt{bnProcPc} to compute LLRs for CN processing \\
\texttt{bn2cnProcBuf} & Copies the BN results to the CN processing buffer \\
\texttt{llrRes2llrOut} & Copies the results of \texttt{bnProcPc} to output LLRs \\
\texttt{llr2bit} & Performs hard-decision on the output LLRs \\
\bottomrule
\end{tabular}
\caption{Summary of the LDPC decoder functions.}
\label{tab:sum_func}
\end{table}
The input LLRs are assumed to be 8-bit and aligned on 32 bytes. CN processing is carried out in 8-bit whereas BN processing is done in 16 bit. Subsequently, the processing tasks at the CNs and BNs are explained in more detail.
\newpage
\subsection{Check Node Processing}
\label{sec:check-node-proc}
Denote $q_{ij}$ the value from BN $j$ to CN $i$ and let $\Bcal_i$ be the set of connected BNs to the $i$th CN. Then, using the min-sum approximation, CN $i$ has to carry out the following operation for each connected BN.
\begin{equation}
\label{eq:40}
r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}|
\end{equation}
where $r_{ji}$ is the value returned to BN $j$ from CN $i$. There are $\Mb = \{46,42\}$ CNs in BG 1 and BG 2, respectively. Each of these CNs is connected to only a small number of BNs. The number of connected BNs to CN $i$ is $|\Bcal_i|$. In BG1 and BG2, $|\Bcal_i|=\{3,4,5,6,7,8,9,10,19\}$ and $|\Bcal_i|=\{3,4,5,6,8,10\}$, respectively. The following tables show the number of CNs $M_{|\Bcal_i|}$ that are connected to the same number of BNs.
\begin{table}[ht]
\centering
\begin{tabular}{llllllllll}
\toprule
$|\Bcal_i|$ & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 19 \\
\midrule
$M_{|\Bcal_i|}^\mathrm{BG1}$ & 1 & 5 &18 & 8 & 5 & 2 & 2 & 1 & 4 \\
$M_{|\Bcal_i|}^\mathrm{BG2}$ & 6 & 20 & 9 & 3 & 0 & 2 & 0 & 2 & 0 \\
\bottomrule
\end{tabular}
\caption{Ceck node groups for BG1 and BG2.}
\label{tab:checkNodeGroups}
\end{table}
It can be observed that each CN is at least connected to 3 BNs and there are 9 groups and 5 groups in BG1 and BG2, respectively. Denote the set of CN groups as $\Gcal$ and $M_k$ the number of CNs in group $k\in\Gcal$, e.g. for BG2 $M_4=20\Zc$. Each CN group will be processed separately. The CN processing buffer $p_C^k$ of group $k$ is defined as
\begin{equation}
\label{eq:44}
p_C^k = \{\underbrace{q_{11}q_{21}\dots q_{M_k 1}}_{\text 1. BN},\underbrace{q_{12}q_{22}\dots q_{M_k 2}}_{\text 2. BN},\dots,\underbrace{q_{12}q_{22}\dots q_{M_k k}}_{\text last BN}\}
\end{equation}
Hence, $|p_C^k| = kM_k$, e.g, $\Zc=128$, $|p_C^4| = 4\cdot 20\cdot 128 = 10240$.
\begin{lstlisting}[frame=single,caption={Example of CN processing for group 3 from \texttt{cnProc}.},label=code_cnproc] % Start your code-block
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
// =====================================================================
// Process group with 3 BNs
// Number of groups of 32 CNs for parallel processing
M = (lut_numCnInCnGroups[0]*Z)>>5;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 3
p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]];
p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
// Loop over every BN
for (j=0; j<3; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
sgn = _mm256_sign_epi8(*p_ones, ymm0);
min = _mm256_abs_epi8(ymm0);
// 32 CNs of second BN
ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
sgn = _mm256_sign_epi8(sgn, ymm0);
// Store result
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
p_cnProcBufResBit++;
}
}
}
\end{lstlisting}
Once all results of the check node processing $r_{ji}$ have been calculated, they are copied to the bit node processing buffer.
\subsection{Bit Node Processing}
\label{sec:bit-node-processing}
Denote $r_{ji}$ the value from CN $i$ to BN $j$ and let $\Ccal_j$ be the set of connected CNs to the $j$th BN. Each BN $j$ has to carry out the following operation for every connected CN $i\in\Ccal_j$.
\begin{equation}
\label{eq:46}
q_{ij} = \Lambda_j + \sum_{i'\in\Ccal_j\setminus i}r_{ji'}
\end{equation}
There are $\Nb = \{68,52\}$ BNs in BG 1 and BG 2, respectively. Each of these BNs is connected to only a small number of CNs. The number of connected CNs to BN $j$ is $|\Ccal_j|$. In BG1 and BG2, $|\Ccal_j|=\{1,4,7,8,9,10,11,12,28,30\}$ and $|\Ccal_j|=\{1,5,6,7,8,9,10,12,13,14,16,22,23\}$, respectively. The following tables show the number of BNs $K_{|\Ccal_j|}$ that are connected to the same number of CNs.
\begin{table}[ht]
\centering
\begin{tabular}{lllllllllllllllllll}
\toprule
$|\Ccal_j|$ & 1&4&5&6&7&8&9&10&11&12&13 & 14 & 15 & 16 & 22 & 23 &28&30 \\
\midrule
$K_{|\Ccal_j|}^\mathrm{BG1}$ & 42 & 1 & 1 & 2 & 4 & 3 & 1 & 4 & 3 & 4 & 1 & 0 & 0 & 0 & 0 & 0 & 1 & 1 \\
$K_{|\Ccal_j|}^\mathrm{BG2}$ & 38 & 0 & 2 & 1 & 1 & 1 & 2 & 1 & 0 & 1 & 1 & 1 & 0 & 1 & 1 & 1 & 0 & 0\\
\bottomrule
\end{tabular}
\caption{Bit node groups for BG1 and BG2 for base rates 1/3 and 1/5, respectively.}
\label{tab:bitNodeGroups}
\end{table}
The BNs that are connected to a single CN do not need to be considered in the BN processing since \eqref{eq:46} yields $q_{ij} = \Lambda_j$. It can be observed that the grouping is less compact, i.e. there are many groups with only a small number of elements.
Denote the set of BN groups as $\Bcal$ and $K_k$ the number of BNs in group $k\in\Bcal$, e.g. for BG2 $K_5=2\Zc$. Each BN group will be processed separately. The BN processing buffer $p_B^k$ of group $k$ is defined as
\begin{equation}
\label{eq:47}
p_B^k = \{\underbrace{r_{11}r_{21}\dots r_{K_k 1}}_{\text 1. CN},\underbrace{r_{12}r_{22}\dots r_{K_k 2}}_{\text 2. CN},\dots,\underbrace{r_{12}r_{22}\dots r_{K_k k}}_{\text last CN}\}
\end{equation}
Hence, $|p_B^k| = kK_k$, e.g, $\Zc=128$, $|p_B^5| = 5\cdot 2\cdot 128 = 1024$.
Depending on the code rate, some parity bits are not being transmitted. For instance, for BG2 with code rate $R = 1/3$ the last $20\Zc$ bits are discarded. Therefore, the last 20 columns or the last $20\Zc$ parity check equation are not required for decoding. This means that the BN groups shown in table \ref{tab:bitNodeGroups} are depending on the rate.
\begin{lstlisting}[frame=single,caption={Example of BN processing for group 3 from \texttt{bnProcPc}.},label=code_bnproc] % Start your code-block
// If elements in group move to next address
idxBnGroup++;
// Number of groups of 32 BNs for parallel processing
M = (lut_numBnInBnGroups[2]*Z)>>5;
// Set the offset to each CN within a group in terms of 16 Byte
cnOffsetInGroup = (lut_numBnInBnGroups[2]*NR_LDPC_ZMAX)>>4;
// Set pointers to start of group 3
p_bnProcBuf = (__m128i*) &bnProcBuf [lut_startAddrBnGroups [idxBnGroup]];
p_llrProcBuf = (__m128i*) &llrProcBuf [lut_startAddrBnGroupsLlr[idxBnGroup]];
p_llrRes = (__m256i*) &llrRes [lut_startAddrBnGroupsLlr[idxBnGroup]];
// Loop over BNs
for (i=0,j=0; i<M; i++,j+=2)
{
// First 16 LLRs of first CN
ymmRes0 = _mm256_cvtepi8_epi16(p_bnProcBuf[j]);
ymmRes1 = _mm256_cvtepi8_epi16(p_bnProcBuf[j+1]);
// Loop over CNs
for (k=1; k<3; k++)
{
ymm0 = _mm256_cvtepi8_epi16(p_bnProcBuf[k*cnOffsetInGroup + j]);
ymmRes0 = _mm256_adds_epi16(ymmRes0, ymm0);
ymm1 = _mm256_cvtepi8_epi16(p_bnProcBuf[k*cnOffsetInGroup + j+1]);
ymmRes1 = _mm256_adds_epi16(ymmRes1, ymm1);
}
// Add LLR from receiver input
ymm0 = _mm256_cvtepi8_epi16(p_llrProcBuf[j]);
ymmRes0 = _mm256_adds_epi16(ymmRes0, ymm0);
ymm1 = _mm256_cvtepi8_epi16(p_llrProcBuf[j+1]);
ymmRes1 = _mm256_adds_epi16(ymmRes1, ymm1);
// Pack results back to epi8
ymm0 = _mm256_packs_epi16(ymmRes0, ymmRes1);
// ymm0 = [ymmRes1[255:128] ymmRes0[255:128] ymmRes1[127:0] ymmRes0[127:0]]
// p_llrRes = [ymmRes1[255:128] ymmRes1[127:0] ymmRes0[255:128] ymmRes0[127:0]]
*p_llrRes = _mm256_permute4x64_epi64(ymm0, 0xD8);
// Next result
p_llrRes++;
}
}
\end{lstlisting}
The sum of the LLRs is carried out in 16 bit for accuracy and is then saturated to 8 bit for CN processing. Saturation after each addition results in significant loss of sensitivity for low code rates.
\subsection{Mapping to the Processing Buffers}
\label{sec:mapp-cn-proc}
For efficient processing with the AVX instructions, the data is required to be aligned in a certain manner. That is the reason why processing buffers have been introduced. The drawback is that the results of the processing need to copied every time to the processing buffer of the next task. However, the speed up in computation with AVX more than makes up for the time wasted in copying data. The copying is implemented as a circular memcpy because every edge in the BG is a circular shift of a $Z\times Z$ identity matrix. Hence, a circular mempcy consists of two regular memcpys each copying a part of the $Z$ values depending on the circular shift in the BG definition. The circular shifts are stored in \texttt{nrLDPC\_lut.h} in arrays \texttt{circShift\_BGX\_ZX\_CNGX}. In the specification there are only 8 sets of cirular shifts defined. However, the applied circular shift depends on $Z$, i.e. modulo $Z$. To avoid inefficient modulo operations in loops, we store the the circular shift values for every $Z$. Moreover, for convinience the arrays are already arranged depending on the CN group (CNG).
\newpage
\section{Performance Results}
\label{sec:performance-results}
In this section, the performance in terms of BLER and decoding latency of the current LDPC decoder implementation is verified.
\subsection{BLER Performance}
\label{sec:bler-performance}
In all simulations, we assume AWGN, QPSK modulation and 8-bit input LLRs, i.e. $-127$ until $+127$. The DLSCH coding procedure in 38.212 is used to encode/decode the TB and an error is declared if the TB CRC check failed. Results are averaged over at least $10\,000$ channel realizations.
The first set of simulations in Figure \ref{fig:bler-bg2-15} compares the current LDPC decoder implementation to the reference implementation developed by Kien. This reference implementation is called \textit{LDPC Ref} and uses the min-sum algorithm with 2 layers and 16 bit for processing. Our current optimized decoder implementation is referred to as \textit{LDPC OAI}. Moreover, reference results provided by Huawei are also shown.
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\tikzstyle{every pin}=[fill=white,draw=black]
\pgfplotsset{every axis legend/.append style={
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
% \pgfplotsset{every axis plot/.append style={smooth}}
\pgfplotsset{every axis/.append style={line width=0.5pt}}
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
grid={both}, xmin=-4, xmax=2, xtick={-4,-3.5,...,2}, ymin=0,
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
% HUAWEI merged BG2 2017-06-15
\addplot[black, solid] plot coordinates { (-3.91839,0.01) (-3.5567,0.0001) };
% 5 iterations
% LDPC Ref
\addplot[red, solid, mark=o] plot coordinates {(-1.250000,0.781300) (-1.000000,0.421000) (-0.750000,0.140400) (-0.500000,0.028900) (-0.250000,0.003300) (0.000000,0.000300) (0.250000,0.000000) (0.500000,0.000000)};
% LDPC OAI
\addplot[blue, solid, mark=square] plot coordinates {(-1.000000,0.693730) (-0.750000,0.370190) (-0.500000,0.137260) (-0.250000,0.038850) (0.000000,0.009740) (0.250000,0.002510) (0.500000,0.000730) (0.750000,0.000180) };
% Matlab layered min-sum with scaling factor 1
\addplot[green, solid, mark=triangle] plot coordinates {(-1.750000,0.709000) (-1.500000,0.360600) (-1.250000,0.105500) (-1.000000,0.015700) (-0.750000,0.001300) (-0.500000,0.000100) (-0.250000,0.000000) (0.000000,0.000000) };
% Matlab layered min-sum with scaling factor 0.8
%\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.982300) (-2.500000,0.882200) (-2.250000,0.573100) (-2.000000,0.214100) (-1.750000,0.041300) (-1.500000,0.003800) (-1.250000,0.000000) (-1.000000,0.000000) };
% 10 iterations
% Kien's 2-layer 16bit code
\addplot[red, solid, mark=o] plot coordinates { (-2.750000,0.915500) (-2.500000,0.576000) (-2.250000,0.165000) (-2.000000,0.017100) (-1.750000,0.000600) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
% LDPC OAI
\addplot[blue, solid, mark=square] plot coordinates { (-2.750000,0.997200) (-2.500000,0.955000) (-2.250000,0.710900) (-2.000000,0.270400) (-1.750000,0.042400) (-1.500000,0.002200) (-1.250000,0.000000) (-1.000000,0.000000)};
% Matlab layered min-sum with scaling factor 1
\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.942900) (-2.500000,0.723200) (-2.250000,0.362300) (-2.000000,0.098400) (-1.750000,0.014500) (-1.500000,0.001100) (-1.250000,0.000000) (-1.000000,0.000000) };
% Matlab layered min-sum with scaling factor 0.8
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.994300) (-3.500000,0.927200) (-3.250000,0.651100) (-3.000000,0.252000) (-2.750000,0.042500) (-2.500000,0.002700) (-2.250000,0.000000) (-2.000000,0.000000) (-1.750000,0.000000) (-1.500000,0.000000) };
% 20 iterations
% Kien's 2-layer 16bit code
\addplot[red, solid, mark=o] plot coordinates { (-2.750000,0.330300) (-2.500000,0.067800) (-2.250000,0.006000) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
% LDPC OAI
\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.337900) (-2.500000,0.058300) (-2.250000,0.004000) (-2.000000,0.000200) (-1.750000,0.000000) (-1.500000,0.000000) };
% Matlab layered min-sum with scaling factor 1
%\addplot[green, solid, mark=triangle] plot coordinates {(-2.750000,0.843200) (-2.500000,0.524600) (-2.250000,0.198100) (-2.000000,0.037300) (-1.750000,0.003200) (-1.500000,0.000000) };
% Matlab layered min-sum with scaling factor 0.8
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.872300) (-3.500000,0.544600) (-3.250000,0.186400) (-3.000000,0.027500) (-2.750000,0.001900) (-2.500000,0.000000) };
% Parity check 50 iterations
%\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.214600) (-2.500000,0.029200) (-2.250000,0.001500) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) };
\draw (axis cs:-3.3,0.1) node[fill=white,draw=black] (pint0) {20 iter};
\draw (axis cs:-2.3,0.01) node[draw,black,thick,ellipse,minimum height=0.3cm] (ell0) {}; \draw[black,thick] (pint0) -- (ell0);
\draw (axis cs:-1.2,0.0001) node[fill=white,draw=black] (pint1) {10 iter};
\draw (axis cs:-1.6,0.002) node[draw,black,thick,ellipse,minimum width=0.8cm] (ell1) {}; \draw[black,thick] (pint1) -- (ell1);
\draw (axis cs:1.3,0.2) node[fill=white,draw=black] (pint2) {5 iter};
\draw (axis cs:-0.4,0.01) node[draw,black,thick,ellipse,minimum width=2cm] (ell2) {}; \draw[black,thick] (pint2) -- (ell2);
\legend{ {Huawei 2017-06-15}\\
{LDPC Ref}\\
{LDPC OAI}\\
{MATLAB NMS SF=1}\\};
\end{semilogyaxis}
\end{tikzpicture}
\caption{BLER vs. SNR, BG2, Rate=1/5, \{5,10,20\} Iterations, B=1280.}
\label{fig:bler-bg2-15}
\end{figure}
From Figure \ref{fig:bler-bg2-15} it can be observed that the reference decoder outperforms the current implementation significantly for low to medium number of iterations. The reason is the implementation of 2 layers in the reference decoder, which results in faster convergence for punctured codes and hence requires less iterations to achieve a given BLER target. Note that there is a large performance loss of about 4 dB at BLER $10^{-2}$ between the Huawei reference and the current optimized decoder implementation with 5 iterations.
Moreover, there is a gap of about 1.5 dB between the results provided by Huawei and the current decoder with 20 iterations. The reason is the min-sum approximation algorithm used in both the reference decoder and the current implementation. The gap can be closed by using a tighter approximation like the min-sum with normalization or the lambda-min approach. Moreover, the gap closes for higher code rates which can be observed from Figure \ref{fig:bler-bg2-r23}. The gap is only about 0.6 dB for 50 iterations.
The Matlab results denoted \texttt{MATLAB NMS} are obtained with the function \texttt{nrLDPCDecode} provided by the MATLAB 5G Toolbox R2019b. The following options are provided to the function: \texttt{'Termination','max','Algorithm','Normalized min-sum','ScalingFactor',1}. Furthermore, the 8-bit input LLRs are adapted to fit the dynamic range of \texttt{nrLDPCDecode} which is shown in Listing \ref{ldpc_matlab}.
\begin{lstlisting}[frame=single,caption={Input adaptation for MATLAB LDPC Decoder},label=ldpc_matlab]
maxLLR = max(abs(softbits));
rxLLRs = round((softbits/maxLLR)*127);
// adjust range to fit tanh use in decoder code
softbits = rxLLRs/3.4;
\end{lstlisting}
A scaling factor (SF) of 1 has been chosen to compare the results more easily with the \textit{LDPC OAI} since the resulting check node processing is the same. However, the Matlab normelized min-sum algorithm uses layered processing and floating point operations. Thus, for the same number of iterations, the performance is significantly better than \textit{LDPC OAI}, especially for small a number of iterations.
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\tikzstyle{every pin}=[fill=white,draw=black]
\pgfplotsset{every axis legend/.append style={
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
% \pgfplotsset{every axis plot/.append style={smooth}}
\pgfplotsset{every axis/.append style={line width=0.5pt}}
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
grid={both}, xmin=3, xmax=6.5, xtick={3,3.5,...,6.5}, ymin=0,
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
% Kien's 2-layer 16bit code
%\addplot[red, solid] plot coordinates { (-2.750000,0.915500) (-2.500000,0.576000) (-2.250000,0.165000) (-2.000000,0.017100) (-1.750000,0.000600) (-1.500000,0.000000) (-1.250000,0.000000) (-1.000000,0.000000)};
% Huawei
\addplot[black, solid] plot coordinates { (3.28392,0.01) (3.73319,0.0001) };
% LDPC opt with 16bit BN processing
%\addplot[blue, solid, mark=square] plot coordinates {(4.000000,0.487500) (4.250000,0.163400) (4.500000,0.029800) (4.750000,0.002700) (5.000000,0.000100)};
\addplot[blue, solid, mark=square] plot coordinates {(5.000000,0.439600) (5.250000,0.185800) (5.500000,0.062100) (5.750000,0.015000) (6.000000,0.003900)};
%\addplot[blue, dashed, mark=triangle] plot coordinates {(4.000000,0.487500) (4.250000,0.163700) (4.500000,0.030000) (4.750000,0.002900) (5.000000,0.000100)};
%\addplot[blue, dashed, mark=square] plot coordinates {(3.000000,0.911600) (3.250000,0.614100) (3.500000,0.230100) (3.750000,0.036900) (4.000000,0.001100) (4.250000,0.000000) (4.500000,0.000000)};
\addplot[blue, dashed, mark=square] plot coordinates {(3.000000,0.900400) (3.250000,0.600000) (3.500000,0.216400) (3.750000,0.036000) (4.000000,0.002600) (4.250000,0.000000) };
\legend{ {Huawei 2017-06-15}\\
{LDPC OAI 5 iter}\\
{LDPC OAI 50 iter}\\};
\end{semilogyaxis}
\end{tikzpicture}
\caption{BLER vs. SNR, BG2, Rate=2/3, \{5,50\} Iterations, B=1280.}
\label{fig:bler-bg2-r23}
\end{figure}
In Figure \ref{fig:bler-bg2-15-2} we compare the performance of different algorithms using at most 50 iterations with early stopping if the parity check passes. The Matlab layered believe propagation (LBP) is used with unquantized input LLRs and performs the best since no approximation is done in the processing. Both NMS and offset min-sum (OMS) use a scaling factor and offset, respectively, that has been empirically found to perform best in this simulation setting. Theirs performance is very close to the BLP and OMS is slightly better than NMS. The performance of \textit{LDPC OAI} is more than 1 dB worse mainly because of the looser approximation. Moreover, the NMS algorithm with SF=1 performs worst probably because the SF is not optimized for the input LLRs. From the results in Figure \ref{fig:bler-bg2-15-2} we can conclude that the performance of the \textit{LDPC OAI} can be significantly improved by adopting an offset min-sum approximation improving the performance to within 0.3dB of the Huawei reference curve.
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\tikzstyle{every pin}=[fill=white,draw=black]
\pgfplotsset{every axis legend/.append style={
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
% \pgfplotsset{every axis plot/.append style={smooth}}
\pgfplotsset{every axis/.append style={line width=0.5pt}}
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
grid={both}, xmin=-4, xmax=-1, xtick={-4,-3.5,...,-1}, ymin=0,
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
% HUAWEI merged BG2 2017-06-15
\addplot[black, solid] plot coordinates { (-3.91839,0.01) (-3.5567,0.0001) };
% Parity check 50 iterations
\addplot[blue, solid, mark=square] plot coordinates {(-2.750000,0.214600) (-2.500000,0.029200) (-2.250000,0.001500) (-2.000000,0.000100) (-1.750000,0.000000) (-1.500000,0.000000) };
% Matlab layered believe propagation
\addplot[red, solid, mark=diamond] plot coordinates {(-4.500000,0.854200) (-4.250000,0.495800) (-4.000000,0.147700) (-3.750000,0.016100) (-3.500000,0.000800) (-3.250000,0.000200) (-3.000000,0.000000) };
% Matlab layered min-sum with scaling factor 1
\addplot[green, dashed, mark=triangle] plot coordinates {(-2.750000,0.830100) (-2.500000,0.497700) (-2.250000,0.165800) (-2.000000,0.024000) (-1.750000,0.001900) (-1.500000,0.000000) };
% Matlab layered min-sum with scaling factor 0.8
%\addplot[green, solid, mark=triangle] plot coordinates {(-3.750000,0.734800) (-3.500000,0.353800) (-3.250000,0.084300) (-3.000000,0.008000) (-2.750000,0.000400) };
\addplot[green, solid, mark=triangle] plot coordinates {(-4.500000,0.964400) (-4.250000,0.748200) (-4.000000,0.333600) (-3.750000,0.057700) (-3.500000,0.004400) (-3.250000,0.000400) };
% Matlab layered offset min-sum with offset 0.025
\addplot[brown, solid, mark=asterisk] plot coordinates {(-4.250000,0.688800) (-4.000000,0.253800) (-3.750000,0.035600) (-3.500000,0.002000) (-3.250000,0.000000) (-3.000000,0.000000) };
\legend{ {Huawei 2017-06-15}\\
{LDPC OAI}\\
{MATLAB LBP}\\
{MATLAB NMS SF=1}\\
{MATLAB NMS SF=0.65}\\
{MATLAB OMS OS=0.025}\\};
\end{semilogyaxis}
\end{tikzpicture}
\caption{BLER vs. SNR, BG2, Rate=1/5, max iterations = 50, B=1280.}
\label{fig:bler-bg2-15-2}
\end{figure}
Figure \ref{fig:bler-bg1-r89} shows the performance of BG1 with largest block size of $B=8448$ and highest code rate $R=8/9$. From Figure \ref{fig:bler-bg1-r89} it can be observed that the performance gap is only about 0.3 dB if 50 iterations are used. However, for 5 iterations there is still a significant performance loss of about 2.3 dB at BLER $10^{-2}$.
\begin{figure}[ht]
\centering
\begin{tikzpicture}
\tikzstyle{every pin}=[fill=white,draw=black]
\pgfplotsset{every axis legend/.append style={
cells={anchor=west}, at={(1.05,1)}, anchor=north west}}
% \pgfplotsset{every axis plot/.append style={smooth}}
\pgfplotsset{every axis/.append style={line width=0.5pt}}
\pgfplotsset{every axis/.append style={mark options=solid, mark size=2.5pt}}
\begin{semilogyaxis}[title={}, xlabel={$\SNR$ [dB]}, ylabel={BLER},
grid={both}, xmin=6, xmax=9, xtick={6,6.5,...,9}, ymin=0,
ymax=1,ytickten={-5,-4,-3,-2,-1,0},legend columns=1]
% Huawei
\addplot[black, solid] plot coordinates { (6.118717,0.01) (6.291449,0.0001) };
% LDPC opt 5 iter
%\addplot[blue, solid, mark=square] plot coordinates {(8.500000,0.350000) (8.750000,0.155100) (9.000000,0.062400) (9.250000,0.023000) (9.500000,0.008700) (9.750000,0.003500) (10.000000,0.000900) (10.250000,0.000300) };
\addplot[blue, solid, mark=square] plot coordinates {(7.500000,0.858900) (7.750000,0.449500) (8.000000,0.129700) (8.250000,0.025500) (8.500000,0.002300) (8.750000,0.000300) (9.000000,0.000000) };
% LDPC opt 50 iter
%\addplot[blue, dashed, mark=square] plot coordinates {(6.000000,0.705333) (6.100000,0.353367) (6.200000,0.102100) (6.300000,0.015133) (6.400000,0.000967) (6.500000,0.000000)};
\addplot[blue, dashed, mark=square] plot coordinates {(6.000000,0.970000) (6.100000,0.830800) (6.200000,0.527300) (6.300000,0.216900) (6.400000,0.045500) (6.500000,0.005600) (6.600000,0.000300) (6.700000,0.000000) (6.800000,0.000000) };
\legend{ {Huawei}\\
{LDPC OAI 5 iter}\\
{LDPC OAI 50 iter}\\};
\end{semilogyaxis}
\end{tikzpicture}
\caption{BLER vs. SNR, BG1, Rate=8/9 \{5,50\} Iterations, B=8448.}
\label{fig:bler-bg1-r89}
\end{figure}
\newpage
\subsection{Decoding Latency}
\label{sec:decoding-time}
This section provides results in terms of decoding latency. That is, the time it takes the decoder to to finish decoding for a given number of iterations. To measure the run time of the decoder we use the OAI tool \texttt{time\_meas.h}. The clock frequency is about 2.9 GHZ, decoder is run on a single core and the results are averaged over $10\,000$ blocks.
The results in Table \ref{tab:lat-bg2-r15} show the impact of the number of iterations on the decoding latency. It can be observed that the latency roughly doubles if the number of iterations are doubled.
\begin{table}[ht]
\centering
\begin{tabular}{lrrr}
\toprule
\textbf{Function} & \textbf{Time [$\mu s$] (5 it)} & \textbf{Time [$\mu s$] (10 it)} & \textbf{Time [$\mu s$] (20 it)}\\
\midrule
% \texttt{llr2llrProcBuf} & 1.1 & 1.1 & 1.1 \\
% \texttt{llr2CnProcBuf} & 12.4 & 12.0 & 12.0 \\
% \texttt{cnProc} & 11.7 & 22.1 & 43.5 \\
% \texttt{bnProcPc} & 6.6 & 12.1 & 23.8 \\
% \texttt{bnProc} & 4.2 & 8.1 & 16.2 \\
% \texttt{cn2bnProcBuf} & 61.3 & 118.3 & 234.9 \\
% \texttt{bn2cnProcBuf} & 38.1 & 82.5 & 172.3 \\
% \texttt{llrRes2llrOut} & 3.5 & 3.4 & 3.4 \\
% \texttt{llr2bit} & 0.2 & 0.1 & 0.1 \\
\texttt{llr2llrProcBuf} & 0.5 & 0.5 & 0.5 \\
\texttt{llr2CnProcBuf} & 5.0 & 4.8 & 4.9 \\
\texttt{cnProc} & 12.4 & 23.0 & 42.7 \\
\texttt{bnProcPc} & 8.4 & 14.8 & 27.0 \\
\texttt{bnProc} & 5.5 & 10.1 & 19.0 \\
\texttt{cn2bnProcBuf} & 14.9 & 24.4 & 44.0 \\
\texttt{bn2cnProcBuf} & 10.5 & 17.8 & 31.8 \\
\texttt{llrRes2llrOut} & 0.3 & 0.3 & 0.3 \\
\texttt{llr2bit} & 0.2 & 0.2 & 0.2 \\
\midrule
% \textbf{Total} & \textbf{139.4} & \textbf{260.3} & \textbf{508.4} \\
\textbf{Total} & \textbf{58.5} & \textbf{97.1} & \textbf{172.6} \\
\bottomrule
\end{tabular}
\caption{BG2, Z=128, R=1/5, B=1280, LDPC OAI}
\label{tab:lat-bg2-r15}
\end{table}
Table \ref{tab:lat-bg2-i5} shows the impact of the code rate on the latency for a given block size and 5 iterations. It can be observed that the performance gain from code rate 1/3 to 2/3 is about a factor 2.
\begin{table}[ht]
\centering
\begin{tabular}{lrrr}
\toprule
\textbf{Function} & \textbf{Time [$\mu s$] (R=1/5)} & \textbf{Time [$\mu s$] (R=1/3)} & \textbf{Time [$\mu s$] (R=2/3)}\\
\midrule
% \texttt{llr2llrProcBuf} & 3.2 & 2.9 & 2.6 \\
% \texttt{llr2CnProcBuf} & 36.5 & 25.4 & 14.8 \\
% \texttt{cnProc} & 33.6 & 25.2 & 13.3 \\
% \texttt{bnProcPc} & 17.6 & 10.2 & 4.5 \\
% \texttt{bnProc} & 8.5 & 5.4 & 2.5 \\
% \texttt{cn2bnProcBuf} & 175.3 & 110.6 & 50.7 \\
% \texttt{bn2cnProcBuf} & 106.6 & 71.2 & 36.1 \\
% \texttt{llrRes2llrOut} & 10.2 & 6.3 & 3.3 \\
% \texttt{llr2bit} & 0.4 & 0.2 & 0.1 \\
\texttt{llr2llrProcBuf} & 1.5 & 0.9 & 0.5 \\
\texttt{llr2CnProcBuf} & 6.0 & 4.1 & 2.2 \\
\texttt{cnProc} & 32.2 & 23.7 & 14.4 \\
\texttt{bnProcPc} & 21.2 & 12.1 & 5.5 \\
\texttt{bnProc} & 9.8 & 5.9 & 2.9 \\
\texttt{cn2bnProcBuf} & 23.3 & 13.9 & 6.8 \\
\texttt{bn2cnProcBuf} & 14.8 & 9.7 & 5.0 \\
\texttt{llrRes2llrOut} & 0.6 & 0.4 & 0.3 \\
\texttt{llr2bit} & 0.7 & 0.4 & 0.2 \\
\midrule
% \textbf{Total} & \textbf{392.4} & \textbf{258.0} & \textbf{128.2} \\
\textbf{Total} & \textbf{111.0} & \textbf{71.8} & \textbf{38.5} \\
\bottomrule
\end{tabular}
\caption{BG2, Z=384, B=3840, LDPC OAI, 5 iterations}
\label{tab:lat-bg2-i5}
\end{table}
Table \ref{tab:lat-bg1-i5} shows the results for BG1, larges block size and different code rates. The latency difference betwee code rate 1/3 and code rate 2/3 is less than half because upper left corner of the PCM is more dense than the rest of the PCM.
\begin{table}[ht]
\centering
\begin{tabular}{lrrr}
\toprule
\textbf{Function} & \textbf{Time [$\mu s$] (R=1/3)} & \textbf{Time [$\mu s$] (R=2/3)} & \textbf{Time [$\mu s$] (R=8/9)}\\
\midrule
% \texttt{llr2llrProcBuf} & 5.5 & 4.9 & 4.6 \\
% \texttt{llr2CnProcBuf} & 60.6 & 34.1 & 24.4 \\
% \texttt{cnProc} & 102.0 & 74.1 & 56.0 \\
% \texttt{bnProcPc} & 26.0 & 11.0 & 6.4 \\
% \texttt{bnProc} & 15.7 & 7.4 & 4.5 \\
% \texttt{cn2bnProcBuf} & 291.0 & 140.8 & 83.1 \\
% \texttt{bn2cnProcBuf} & 193.6 & 100.5 & 63.0 \\
% \texttt{llrRes2llrOut} & 13.3 & 6.9 & 5.2 \\
% \texttt{llr2bit} & 0.4 & 0.2 & 0.2 \\
\texttt{llr2llrProcBuf} & 2.1 & 1.2 & 0.9 \\
\texttt{llr2CnProcBuf} & 10.6 & 5.4 & 2.9 \\
\texttt{cnProc} & 89.8 & 66.3 & 50.0 \\
\texttt{bnProcPc} & 28.1 & 12.4 & 7.1 \\
\texttt{bnProc} & 17.1 & 8.1 & 4.8 \\
\texttt{cn2bnProcBuf} & 38.7 & 17.1 & 9.3 \\
\texttt{bn2cnProcBuf} & 25.6 & 12.7 & 7.2 \\
\texttt{llrRes2llrOut} & 0.8 & 0.4 & 0.3 \\
\texttt{llr2bit} & 0.9 & 0.4 & 0.3 \\
\midrule
% \textbf{Total} & \textbf{708.9} & \textbf{380.6} & \textbf{248.1}\\
\textbf{Total} & \textbf{214.6} & \textbf{124.6} & \textbf{83.6}\\
\bottomrule
\end{tabular}
\caption{BG1, Z=384, B=8448, LDPC OAI, 5 iterations}
\label{tab:lat-bg1-i5}
\end{table}
From the above results it can be observed that the data transfer between CNs and BNs takes up a significant amount of the run time. However, the performance gain due to AVX instructions in both CN and BN processing is significantly larger than the penalty incurred by the data transfers.
\section{Parity Check and Early Stopping Criteria}
It is often unnecessary to carry out the maximum number of iterations. After each iteration a parity check (PC) \eqref{eq:29} can be computed and if a valid code word is found the decoder can stop. This functionality has been implemented and the additional overhead is reasonable. The PC is carried out in the CN processing buffer and the calculation complexity itself is negligible. However, for the processing it is necessary to move the BN results to the CN buffer which takes time, the overall overhead is at most $10\%$ compared to an algorithm without early stopping criteria with the same number of iterations. The PC has to be activated via the define \texttt{NR\_LDPC\_ENABLE\_PARITY\_CHECK}.
\section{Conclusion}
\label{sec:conclusion}
The results in the previous sections show that the current optimized LDPC implementation full-fills the requirements in terms of decoding latency for low to medium number of iterations at the expense of a loss in BLER performance. To improve BLER performance, it is recommended to implement a layered algorithm and a min-sum algorithm with normalization. Further improvements upon the current implementation are detailed in the next section.
\newpage
\section{Future Work}
\label{sec:future-work}
The improvements upon the current LDPC decoder implementation can be divided into two categories:
\begin{enumerate}
\item Improved BLER performance
\item Reduced decoding latency
\end{enumerate}
\subsection{Improved BLER Performance}
\label{sec:impr-bler-perf}
The BLER performance can be improved by using a tighter approximation than the min-sum approximation. For instance, the min-sum algorithm can be improved by adding a correction factor in the CN processing . The min-sum approximation in \eqref{eq:40} is modified as
\begin{equation}
\label{eq:50}
r_{ji} = \prod_{j'\in\Bcal_i\setminus j}\sgn q_{ij'}\min_{j'\in\Bcal_i\setminus j} |q_{ij'}| + w(q_{ij'})
\end{equation}
The correction term $w(q_{ij'})$ is defined as
\begin{equation}
\label{eq:51}
w(q_{ij'}) =
\begin{cases}
c & \textrm{if}~ \\
-c & \textrm{if}~ \\
0 & \textrm{otherwise}
\end{cases}
\end{equation}
where the constant $c$ is of order $0.5$ typically.
\subsection{Reduced Decoding Latency}
\label{sec:reduc-decod-latency}
The following improvements will reduce the decoding latency:
\begin{itemize}
\item Adapt to AVX512
\item Optimization of CN processing
\item Implement 2/3-layers for faster convergence
\end{itemize}
\paragraph{AVX512:}
The computations in the CN and BN processing can be further accelerated by using AVX512 instructions. This improvement will speed-up the CN and BN processing by a approximately a factor of 2.
\paragraph{Optimization of CN Processing:}
It can be investigated if CN processing can be improved by computing two minima regardless of the number of BNs. Susequently, the (absolute) value fed back to the BN is one of those minima.
\paragraph{Layered processing:}
The LDPC code in NR always punctures the first 2 columns of the base graph. Hence, the decoder inserts LLRs with value 0 at their place and needs to retrieve those bits during the decoding process. Instead of computing all the parity equations and then passing the results to the BN processing, it is beneficial to first compute parity equations where at most one punctured BN is connected to that CN. If two punctured BNs are connected than according to \eqref{eq:40}, the result will be again 0. Thus in a first sub-iteration those parity equation are computed and the results are send to BN processing which calculates the results using only those rows in the PCM. In the second sub-iteration the remaining check equation are used.
The convergence of this layered approach is much fast since the bit can be retrieved more quickly while the decoding complexity remains the same. Therefore, for a fixed number of iterations the layered algorithm will have a significantly better performance.
\newpage
\bibliographystyle{IEEEtran}
\bibliography{./references}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

View File

@@ -1,105 +0,0 @@
%
% 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
%
@online{3gpp5gTimeline,
author = {3GPP},
title = {{3GPP 5G Timeline}},
year = 2016,
urldate = {2017-06-14},
url = {http://www.3gpp.org/images/articleimages/5g_timeline.jpg}
}
@techreport{3gppTR38913,
author = "{Technical Specification Group Radio Access Network}",
title = "{Study on Scenarios and Requirements for Next Generation Access Technologies}",
institution = "{3GPP TR 38.913 V14.2.0}",
month = mar,
year = 2017,
};
@techreport{iturM2038,
author = "{ITU-R}",
title = "{IMT Vision -- Framework and overall objectives of the future development of IMT for 2020 and beyond}",
institution = "{Radiocommunication Sector of ITU}",
month = sep,
year = 2015,
};
@techreport{3gpp2014seb,
author = "{Samsung, Nokia Networks}",
title = "{New SID Proposal: Study on Elevation Beamforming/Full-Dimension (FD) MIMO for LTE}",
institution = "3GPP",
month = sep,
year = 2014,
};
@techreport{3gpp2015fdm,
author = "{Technical Specification Group Radio Access Network}",
title = "{Study on elevation beamforming / Full-Dimension (FD) Multiple Input Multiple Output (MIMO) for LTE}",
institution = "3GPP TR 36.897 V13.0.0",
month = jun,
year = 2015,
};
@techreport{3gpp2008tsg,
author = "{Technical Specification Group Radio Access Network;
Evolved Universal Terrestrial Radio Access (E-UTRA)}",
title = "{Further advancements for E-UTRA physical layer aspects (Release 9)}",
institution = "{3GPP TR 36.814 V9.0.0}",
month = mar,
year = 2010,
};
@techreport{3gpp2011uer,
author = "{Technical Specification Group Radio Access Network;
Evolved Universal Terrestrial Radio Access (E-UTRA)}",
title = "{User Equipment (UE) Radio Transmission and Reception}",
institution = "{3GPP TR 36.101 V10.3.0}",
month = jun,
year = 2011,
};
@techreport{3gpp2009_36211,
author = "{3rd Generation Partnership Project}",
title = "{Physical Channels and Modulation (Release 8)}",
institution = "{3GPP TS 36.211 V8.6.0}",
month = mar,
year = 2009,
};
@techreport{3gpp2017_38212,
author = "{3rd Generation Partnership Project}",
title = "{Multiplexing and channel coding (Release 15)}",
institution = "{3GPP TS 38.212 V15.0.1}",
month = mar,
year = 2018,
};
@article{gallager1962low,
title={Low-density parity-check codes},
author={Gallager, Robert},
journal={IRE Transactions on information theory},
volume={8},
number={1},
pages={21--28},
year={1962},
publisher={IEEE}
}

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@
#ifndef __NR_LDPC_BNPROC__H__
#define __NR_LDPC_BNPROC__H__
#include <immintrin.h>
/**
\brief Performs first part of BN processing on the BN processing buffer and stores the results in the LLR results buffer.
At every BN, the sum of the returned LLRs from the connected CNs and the LLR of the receiver input is computed.

View File

@@ -1,3 +1,4 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -28,8 +29,8 @@
* \warning
*/
#ifndef __NR_LDPC_CNPROC__H__
#define __NR_LDPC_CNPROC__H__
#ifndef __NR_LDPC_DECODER_CNPROC__H__
#define __NR_LDPC_DECODER_CNPROC__H__
/**
\brief Performs CN processing for BG2 on the CN processing buffer and stores the results in the CN processing results buffer.
@@ -37,6 +38,13 @@
\param p_procBuf Pointer to processing buffers
\param Z Lifting size
*/
#ifdef __AVX512BW__
#include "nrLDPC_cnProc_avx512.h"
#else
static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
{
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
@@ -92,14 +100,14 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
ymm0 = pj0[i];
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
ymm0 = pj0[i];
sgn = _mm256_sign_epi8(*p_ones, ymm0);
min = _mm256_abs_epi8(ymm0);
// 32 CNs of second BN
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
ymm0 = pj1[i];
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
ymm0 = pj1[i];
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
sgn = _mm256_sign_epi8(sgn, ymm0);
@@ -107,7 +115,7 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
//*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
//p_cnProcBufResBit++;
p_cnProcBufResBit[i]=_mm256_sign_epi8(min, sgn);
p_cnProcBufResBit[i]=_mm256_sign_epi8(min, sgn);
}
}
}
@@ -364,6 +372,15 @@ static inline void nrLDPC_cnProc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
}
/**
\brief Performs CN processing for BG1 on the CN processing buffer and stores the results in the CN processing results buffer.
\param p_lut Pointer to decoder LUTs
\param Z Lifting size
*/
/**
\brief Performs CN processing for BG1 on the CN processing buffer and stores the results in the CN processing results buffer.
\param p_lut Pointer to decoder LUTs
@@ -431,6 +448,7 @@ static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
sgn = _mm256_sign_epi8(sgn, ymm0);
// Store result
min = _mm256_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
@@ -859,6 +877,7 @@ static inline void nrLDPC_cnProc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int
}
#endif
/**
\brief Performs parity check for BG1 on the CN processing buffer. Stops as soon as error is detected.
\param p_lut Pointer to decoder LUTs
@@ -1922,3 +1941,6 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu
}
#endif

View File

@@ -0,0 +1,865 @@
/*
* 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 nrLDPC_cnProc_avx512.h
* \brief Defines the functions for check node processing
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
* \date 30-09-2021
* \version 1.0
* \note
* \warning
*/
#ifndef __NR_LDPC_CNPROC__H__
#define __NR_LDPC_CNPROC__H__
#define conditional_negate(a,b,z) _mm512_mask_sub_epi8(a,_mm512_movepi8_mask(b),z,a)
static inline void nrLDPC_cnProc_BG2_AVX512(t_nrLDPC_lut* p_lut, int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z)
{
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
__m512i* p_cnProcBuf;
__m512i* p_cnProcBufRes;
// Number of CNs in Groups
uint32_t M;
uint32_t i;
uint32_t j;
uint32_t k;
// Offset to each bit within a group in terms of 32 Byte
uint32_t bitOffsetInGroup;
__m512i zmm0, min, sgn, zeros;
zeros = _mm512_setzero_si512();
// maxLLR = _mm512_set1_epi8((char)127);
__m512i* p_cnProcBufResBit;
const __m512i* p_ones = (__m512i*) ones512_epi8;
const __m512i* p_maxLLR = (__m512i*) maxLLR512_epi8;
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
// =====================================================================
// Process group with 3 BNs
if (lut_numCnInCnGroups[0] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 3
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
// Loop over every BN
for (j=0; j<3; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
__m512i *pj0 = &p_cnProcBuf[(lut_idxCnProcG3[j][0]/2)];
__m512i *pj1 = &p_cnProcBuf[(lut_idxCnProcG3[j][1]/2)];
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
zmm0 = pj0[i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// 32 CNs of second BN
// zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][1]/2) + i];
zmm0 = pj1[i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
//p_cnProcBufResBit[i]=_mm512_sign_epi8(min, sgn);
}
}
}
// =====================================================================
// Process group with 4 BNs
// Offset is 20*384/32 = 240
const uint16_t lut_idxCnProcG4[4][3] = {{240,480,720}, {0,480,720}, {0,240,720}, {0,240,480}};
if (lut_numCnInCnGroups[1] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 4
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<4; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<3; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 5 BNs
// Offset is 9*384/32 = 108
const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432},
{0,108,324,432}, {0,108,216,432}, {0,108,216,324}};
if (lut_numCnInCnGroups[2] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 5
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[2]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[2]];
// Loop over every BN
for (j=0; j<5; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<4; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 6 BNs
// Offset is 3*384/32 = 36
const uint16_t lut_idxCnProcG6[6][5] = {{36,72,108,144,180}, {0,72,108,144,180},
{0,36,108,144,180}, {0,36,72,144,180},
{0,36,72,108,180}, {0,36,72,108,144}};
if (lut_numCnInCnGroups[3] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 6
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[3]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[3]];
// Loop over every BN
for (j=0; j<6; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<5; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 8 BNs
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
if (lut_numCnInCnGroups[4] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 8
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[4]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[4]];
// Loop over every BN
for (j=0; j<8; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<7; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 10 BNs
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG10[10][9] = {{24,48,72,96,120,144,168,192,216}, {0,48,72,96,120,144,168,192,216},
{0,24,72,96,120,144,168,192,216}, {0,24,48,96,120,144,168,192,216},
{0,24,48,72,120,144,168,192,216}, {0,24,48,72,96,144,168,192,216},
{0,24,48,72,96,120,168,192,216}, {0,24,48,72,96,120,144,192,216},
{0,24,48,72,96,120,144,168,216}, {0,24,48,72,96,120,144,168,192}};
if (lut_numCnInCnGroups[5] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 10
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[5]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[5]];
// Loop over every BN
for (j=0; j<10; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<9; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
}
static inline void nrLDPC_cnProc_BG1_AVX512(t_nrLDPC_lut* p_lut, t_nrLDPC_procBuf* p_procBuf, uint16_t Z)
{
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
int8_t* cnProcBuf = p_procBuf->cnProcBuf;
int8_t* cnProcBufRes = p_procBuf->cnProcBufRes;
__m512i* p_cnProcBuf;
__m512i* p_cnProcBufRes;
// Number of CNs in Groups
uint32_t M;
uint32_t i;
uint32_t j;
uint32_t k;
// Offset to each bit within a group in terms of 32 Byte
uint32_t bitOffsetInGroup;
__m512i zmm0, min, sgn, zeros;
zeros = _mm512_setzero_si512();
// maxLLR = _mm512_set1_epi8((char)127);
__m512i* p_cnProcBufResBit;
const __m512i* p_ones = (__m512i*) ones512_epi8;
const __m512i* p_maxLLR = (__m512i*) maxLLR512_epi8;
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup (1*384/32)
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
// =====================================================================
// Process group with 3 BNs
if (lut_numCnInCnGroups[0] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 3
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[0]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
// Loop over every BN
for (j=0; j<3; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// 32 CNs of second BN
zmm0 = p_cnProcBuf[(lut_idxCnProcG3[j][1]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 4 BNs
// Offset is 5*384/32 = 60
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
if (lut_numCnInCnGroups[1] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 4
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[1]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<4; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<3; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG4[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 5 BNs
// Offset is 18*384/32 = 216
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
if (lut_numCnInCnGroups[2] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 5
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[2]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[2]];
// Loop over every BN
for (j=0; j<5; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<4; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG5[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 6 BNs
// Offset is 8*384/32 = 96
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
{0,96,288,384,480}, {0,96,192,384,480},
{0,96,192,288,480}, {0,96,192,288,384}};
if (lut_numCnInCnGroups[3] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 6
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[3]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[3]];
// Loop over every BN
for (j=0; j<6; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<5; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG6[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 7 BNs
// Offset is 5*384/32 = 60
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
{0,60,180,240,300,360}, {0,60,120,240,300,360},
{0,60,120,180,300,360}, {0,60,120,180,240,360},
{0,60,120,180,240,300}};
if (lut_numCnInCnGroups[4] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 7
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[4]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[4]];
// Loop over every BN
for (j=0; j<7; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG7[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<6; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG7[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 8 BNs
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
if (lut_numCnInCnGroups[5] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 8
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[5]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[5]];
// Loop over every BN
for (j=0; j<8; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<7; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG8[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 9 BNs
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
{0,24,48,72,96,120,144,168}};
if (lut_numCnInCnGroups[6] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[6]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 9
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[6]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[6]];
// Loop over every BN
for (j=0; j<9; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG9[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<8; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG9[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 10 BNs
// Offset is 1*384/32 = 12
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
if (lut_numCnInCnGroups[7] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[7]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 10
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[7]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[7]];
// Loop over every BN
for (j=0; j<10; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<9; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG10[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
// =====================================================================
// Process group with 19 BNs
// Offset is 4*384/32 = 12
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
if (lut_numCnInCnGroups[8] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
M = (lut_numCnInCnGroups[8]*Z + 63)>>6;
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>6;
// Set pointers to start of group 19
p_cnProcBuf = (__m512i*) &cnProcBuf [lut_startAddrCnGroups[8]];
p_cnProcBufRes = (__m512i*) &cnProcBufRes[lut_startAddrCnGroups[8]];
// Loop over every BN
for (j=0; j<19; j++)
{
// Set of results pointer to correct BN address
p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
for (i=0; i<M; i++)
{
// Abs and sign of 32 CNs (first BN)
zmm0 = p_cnProcBuf[(lut_idxCnProcG19[j][0]/2) + i];
sgn = _mm512_xor_si512(*p_ones, zmm0);
min = _mm512_abs_epi8(zmm0);
// Loop over BNs
for (k=1; k<18; k++)
{
zmm0 = p_cnProcBuf[(lut_idxCnProcG19[j][k]/2) + i];
min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
sgn = _mm512_xor_si512(sgn, zmm0);
}
// Store result
min = _mm512_min_epu8(min, *p_maxLLR); // 128 in epi8 is -127
*p_cnProcBufResBit = conditional_negate(min, sgn,zeros);
p_cnProcBufResBit++;
}
}
}
}
#endif

View File

@@ -1,3 +1,5 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -20,14 +22,8 @@
*/
/*!\file nrLDPC_decoder.c
* \brief Defines the LDPC decoder
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
* \date 30-09-2019
* \version 2.0
* \note
* \warning
*/
* \brief Defines thenrLDPC decoder
*/
#include <stdint.h>
#include <immintrin.h>
@@ -37,6 +33,83 @@
#include "nrLDPC_mPass.h"
#include "nrLDPC_cnProc.h"
#include "nrLDPC_bnProc.h"
#define UNROLL_CN_PROC 1
#define UNROLL_BN_PROC 1
#define UNROLL_BN_PROC_PC 1
#define UNROLL_BN2CN_PROC 1
/*----------------------------------------------------------------------
| cn processing files -->AVX512
/----------------------------------------------------------------------*/
//BG1-------------------------------------------------------------------
#ifdef __AVX512BW__
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R13_AVX512.h"
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R23_AVX512.h"
#include "cnProc_avx512/nrLDPC_cnProc_BG1_R89_AVX512.h"
//BG2-------------------------------------------------------------------
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R15_AVX512.h"
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R13_AVX512.h"
#include "cnProc_avx512/nrLDPC_cnProc_BG2_R23_AVX512.h"
#else
/*----------------------------------------------------------------------
| cn Processing files -->AVX2
/----------------------------------------------------------------------*/
//BG1------------------------------------------------------------------
#include "cnProc/nrLDPC_cnProc_BG1_R13_AVX2.h"
#include "cnProc/nrLDPC_cnProc_BG1_R23_AVX2.h"
#include "cnProc/nrLDPC_cnProc_BG1_R89_AVX2.h"
//BG2 --------------------------------------------------------------------
#include "cnProc/nrLDPC_cnProc_BG2_R15_AVX2.h"
#include "cnProc/nrLDPC_cnProc_BG2_R13_AVX2.h"
#include "cnProc/nrLDPC_cnProc_BG2_R23_AVX2.h"
#endif
/*----------------------------------------------------------------------
| bn Processing files -->AVX2
/----------------------------------------------------------------------*/
//bnProcPc-------------------------------------------------------------
//BG1------------------------------------------------------------------
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R13_AVX2.h"
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R23_AVX2.h"
#include "bnProcPc/nrLDPC_bnProcPc_BG1_R89_AVX2.h"
//BG2 --------------------------------------------------------------------
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R15_AVX2.h"
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R13_AVX2.h"
#include "bnProcPc/nrLDPC_bnProcPc_BG2_R23_AVX2.h"
//bnProc----------------------------------------------------------------
#ifdef __AVX512BW__
//BG1-------------------------------------------------------------------
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R13_AVX512.h"
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R23_AVX512.h"
#include "bnProc_avx512/nrLDPC_bnProc_BG1_R89_AVX512.h"
//BG2 --------------------------------------------------------------------
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R15_AVX512.h"
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R13_AVX512.h"
#include "bnProc_avx512/nrLDPC_bnProc_BG2_R23_AVX512.h"
#else
#include "bnProc/nrLDPC_bnProc_BG1_R13_AVX2.h"
#include "bnProc/nrLDPC_bnProc_BG1_R23_AVX2.h"
#include "bnProc/nrLDPC_bnProc_BG1_R89_AVX2.h"
//BG2 --------------------------------------------------------------------
#include "bnProc/nrLDPC_bnProc_BG2_R15_AVX2.h"
#include "bnProc/nrLDPC_bnProc_BG2_R13_AVX2.h"
#include "bnProc/nrLDPC_bnProc_BG2_R23_AVX2.h"
#endif
#define NR_LDPC_ENABLE_PARITY_CHECK
//#define NR_LDPC_PROFILER_DETAIL
@@ -66,28 +139,31 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_
}
/**
\brief Performs LDPC decoding of one code block
\brief PerformsnrLDPC decoding of one code block
\param p_llr Input LLRs
\param p_out Output vector
\param numLLR Number of LLRs
\param p_lut Pointer to decoder LUTs
\param p_decParams LDPC decoder parameters
\param p_profiler LDPC profiler statistics
\param p_decParamsnrLDPC decoder parameters
\param p_profilernrLDPC profiler statistics
*/
static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler)
{
uint16_t Z = p_decParams->Z;
uint8_t BG = p_decParams->BG;
uint8_t R = p_decParams->R; //Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */
uint8_t numMaxIter = p_decParams->numMaxIter;
e_nrLDPC_outMode outMode = p_decParams->outMode;
// int8_t* cnProcBuf= cnProcBuf;
// int8_t* cnProcBufRes= cnProcBufRes;
int8_t cnProcBuf[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32))) = {0};
int8_t llrRes[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))) = {0};
int8_t cnProcBuf[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
int8_t bnProcBuf[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(64))) = {0};
int8_t llrRes[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(64))) = {0};
// Minimum number of iterations is 1
// 0 iterations means hard-decision on input LLRs
uint32_t i = 1;
@@ -123,14 +199,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->llr2CnProcBuf);
#endif
if (BG == 1)
{
nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z);
}
else
{
nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z);
}
if (BG == 1) nrLDPC_llr2CnProcBuf_BG1(p_lut, p_llr, cnProcBuf, Z);
else nrLDPC_llr2CnProcBuf_BG2(p_lut, p_llr, cnProcBuf, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->llr2CnProcBuf);
#endif
@@ -146,13 +216,79 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->cnProc);
#endif
if (BG == 1)
{
if (BG==1) {
#ifndef UNROLL_CN_PROC
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
}
else
{
#else
switch (R)
{
case 13:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R23_AVX512(cnProcBuf,cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 89:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R89_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R89_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
}
#endif
} else {
#ifndef UNROLL_CN_PROC
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
#else
switch (R) {
case 15:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R15_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R15_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 13:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
}
#endif
}
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->cnProc);
@@ -166,14 +302,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->cn2bnProcBuf);
#endif
if (BG == 1)
{
nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
}
else
{
nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
}
if (BG == 1) nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
else nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->cn2bnProcBuf);
#endif
@@ -187,7 +317,51 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bnProcPc);
#endif
#ifndef UNROLL_BN_PROC_PC
nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
#else
if (BG==1) {
switch (R) {
case 13:
{
nrLDPC_bnProcPc_BG1_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
case 23:
{
nrLDPC_bnProcPc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
break;
}
case 89:
{
nrLDPC_bnProcPc_BG1_R89_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
break;
}
}
} else {
switch (R) {
case 15:
{
nrLDPC_bnProcPc_BG2_R15_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
break;
}
case 13:
{
nrLDPC_bnProcPc_BG2_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes,llrProcBuf, Z);
break;
}
case 23:
{
nrLDPC_bnProcPc_BG2_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
}
}
#endif
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bnProcPc);
#endif
@@ -200,7 +374,78 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bnProc);
#endif
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
if (BG==1) {
#ifndef UNROLL_BN_PROC
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
#else
switch (R) {
case 13:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 89:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R89_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R89_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
}
#endif
} else {
#ifndef UNROLL_BN2CN_PROC
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
#else
switch (R) {
case 15:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R15_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R15_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 13:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
}
#endif
}
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bnProc);
#endif
@@ -214,14 +459,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bn2cnProcBuf);
#endif
if (BG == 1)
{
nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
}
else
{
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
}
if (BG == 1) nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
else nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bn2cnProcBuf);
#endif
@@ -236,8 +475,7 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
// First iteration finished
while ( (i < numMaxIter) && (pcRes != 0) )
{
while ( (i < numMaxIter) && (pcRes != 0) ) {
// Increase iteration counter
i++;
@@ -245,13 +483,74 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->cnProc);
#endif
if (BG == 1)
{
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
}
else
{
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
if (BG==1) {
#ifndef UNROLL_CN_PROC
nrLDPC_cnProc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
#else
switch (R) {
case 13:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 89:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG1_R89_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG1_R89_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
}
#endif
} else {
#ifndef UNROLL_CN_PROC
nrLDPC_cnProc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
#else
switch (R) {
case 15:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R15_AVX512(cnProcBuf,cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R15_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 13:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R13_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R13_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_cnProc_BG2_R23_AVX512(cnProcBuf, cnProcBufRes, Z);
#else
nrLDPC_cnProc_BG2_R23_AVX2(cnProcBuf, cnProcBufRes, Z);
#endif
break;
}
}
#endif
}
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->cnProc);
@@ -265,14 +564,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->cn2bnProcBuf);
#endif
if (BG == 1)
{
nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
}
else
{
nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
}
if (BG == 1) nrLDPC_cn2bnProcBuf_BG1(p_lut, cnProcBufRes, bnProcBuf, Z);
else nrLDPC_cn2bnProcBuf_BG2(p_lut, cnProcBufRes, bnProcBuf, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->cn2bnProcBuf);
#endif
@@ -285,7 +578,49 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bnProcPc);
#endif
#ifndef UNROLL_BN_PROC_PC
nrLDPC_bnProcPc(p_lut, bnProcBuf, bnProcBufRes, llrProcBuf, llrRes, Z);
#else
if (BG==1) {
switch (R) {
case 13:
{
nrLDPC_bnProcPc_BG1_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
case 23:
{
nrLDPC_bnProcPc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
break;
}
case 89:
{
nrLDPC_bnProcPc_BG1_R89_AVX2(bnProcBuf,bnProcBufRes, llrRes, llrProcBuf, Z);
break;
}
}
} else {
switch (R)
{
case 15:
{
nrLDPC_bnProcPc_BG2_R15_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
case 13:
{
nrLDPC_bnProcPc_BG2_R13_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
case 23:
{
nrLDPC_bnProcPc_BG2_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, llrProcBuf, Z);
break;
}
}
}
#endif
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bnProcPc);
#endif
@@ -297,7 +632,75 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bnProc);
#endif
#ifndef UNROLL_BN_PROC
nrLDPC_bnProc(p_lut, bnProcBuf, bnProcBufRes, llrRes, Z);
#else
if (BG==1) {
switch (R) {
case 13:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R23_AVX2(bnProcBuf,bnProcBufRes,llrRes, Z);
#endif
break;
}
case 89:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG1_R89_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG1_R89_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
}
} else {
switch (R)
{
case 15:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R15_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R15_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 13:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R13_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R13_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
case 23:
{
#ifdef __AVX512BW__
nrLDPC_bnProc_BG2_R23_AVX512(bnProcBuf, bnProcBufRes,llrRes, Z);
#else
nrLDPC_bnProc_BG2_R23_AVX2(bnProcBuf, bnProcBufRes,llrRes, Z);
#endif
break;
}
}
}
#endif
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bnProc);
#endif
@@ -310,14 +713,8 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->bn2cnProcBuf);
#endif
if (BG == 1)
{
nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
}
else
{
nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
}
if (BG == 1) nrLDPC_bn2cnProcBuf_BG1(p_lut, bnProcBufRes, cnProcBuf, Z);
else nrLDPC_bn2cnProcBuf_BG2(p_lut, bnProcBufRes, cnProcBuf, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->bn2cnProcBuf);
#endif
@@ -326,60 +723,44 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_
nrLDPC_debug_writeBuffer2File(nrLDPC_buffers_CN_PROC, cnProcBuf);
#endif
// Parity Check
// Parity Check
#ifdef NR_LDPC_ENABLE_PARITY_CHECK
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->cnProcPc);
start_meas(&p_profiler->cnProcPc);
#endif
if (BG == 1)
{
pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
}
else
{
pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
}
if (BG == 1) pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z);
else pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->cnProcPc);
stop_meas(&p_profiler->cnProcPc);
#endif
#endif
}
// If maximum number of iterations reached an PC still fails increase number of iterations
// Thus, i > numMaxIter indicates that PC has failed
#ifdef NR_LDPC_ENABLE_PARITY_CHECK
if (pcRes != 0)
{
i++;
}
#endif
} // end while
// Last iteration
if (pcRes != 0) i++;
// Assign results from processing buffer to output
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->llrRes2llrOut);
start_meas(&p_profiler->llrRes2llrOut);
#endif
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->llrRes2llrOut);
stop_meas(&p_profiler->llrRes2llrOut);
#endif
// Hard-decision
#ifdef NR_LDPC_PROFILER_DETAIL
start_meas(&p_profiler->llr2bit);
start_meas(&p_profiler->llr2bit);
#endif
if (outMode == nrLDPC_outMode_BIT)
{
nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR);
}
else if (outMode == nrLDPC_outMode_BITINT8)
{
nrLDPC_llr2bit(p_out, p_llrOut, numLLR);
}
if (outMode == nrLDPC_outMode_BIT) nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR);
else //if (outMode == nrLDPC_outMode_BITINT8)
nrLDPC_llr2bit(p_out, p_llrOut, numLLR);
#ifdef NR_LDPC_PROFILER_DETAIL
stop_meas(&p_profiler->llr2bit);
#endif
return i;
}

View File

@@ -0,0 +1,83 @@
/*
* 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 nrLDPC_init_mem.h
* \brief Defines the function to initialize the LDPC decoder and sets correct LUTs.
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
* \date 07-12-2018
* \version 1.0
* \note
* \warning
*/
#ifndef __NR_LDPC_INIT_MEM__H__
#define __NR_LDPC_INIT_MEM__H__
#include <stdlib.h>
#include "nrLDPC_types.h"
/**
\brief Allocates 32 byte aligned memory and initializes to zero
\param size Input size in bytes
\return Pointer to memory
*/
static inline void* malloc32_clear(size_t size)
{
void* ptr = (void*) memalign(64, size+64);
memset(ptr, 0, size);
return ptr;
}
/**
\brief Allocates and initializes the internal decoder processing buffers
\param p_decParams Pointer to decoder parameters
\param p_lut Pointer to decoder LUTs
\return Number of LLR values
*/
static inline t_nrLDPC_procBuf* nrLDPC_init_mem(void)
{
t_nrLDPC_procBuf* p_procBuf = (t_nrLDPC_procBuf*) malloc32_clear(sizeof(t_nrLDPC_procBuf));
if (p_procBuf)
{
p_procBuf->cnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
p_procBuf->cnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_CN_PROC_BUF*sizeof(int8_t));
p_procBuf->bnProcBuf = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
p_procBuf->bnProcBufRes = (int8_t*) malloc32_clear(NR_LDPC_SIZE_BN_PROC_BUF*sizeof(int8_t));
p_procBuf->llrRes = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
p_procBuf->llrProcBuf = (int8_t*) malloc32_clear(NR_LDPC_MAX_NUM_LLR *sizeof(int8_t));
}
return(p_procBuf);
}
static inline void nrLDPC_free_mem(t_nrLDPC_procBuf* p_procBuf)
{
free(p_procBuf->cnProcBuf);
free(p_procBuf->cnProcBufRes);
free(p_procBuf->bnProcBuf);
free(p_procBuf->bnProcBufRes);
free(p_procBuf->llrRes);
free(p_procBuf->llrProcBuf);
free(p_procBuf);
}
#endif

View File

@@ -21,21 +21,16 @@
/*!\file nrLDPC_mPass.h
* \brief Defines the functions for message passing
* \author Sebastian Wagner (TCL Communications) Email: <mailto:sebastian.wagner@tcl.com>
* \date 30-09-2019
* \version 2.0
* \note
* \warning
*/
*
*/
#ifndef __NR_LDPC_MPASS__H__
#define __NR_LDPC_MPASS__H__
#include <string.h>
#include "nrLDPCdecoder_defs.h"
//#include <omp.h>
/**
\brief Circular memcpy
\brief Circular memcpy1
|<- rem->|<- circular shift ->|
(src) str2 = |--------xxxxxxxxxxxxxxxxxxxxx|
\_______________
@@ -46,6 +41,7 @@
\param Z Lifting size
\param cshift Circular shift
*/
static inline void *nrLDPC_inv_circ_memcpy(int8_t *str1, const int8_t *str2, uint16_t Z, uint16_t cshift)
{
uint16_t rem = Z - cshift;
@@ -169,6 +165,8 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX;
for (j=0; j<3; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[0] + j*bitOffsetInGroup];
@@ -200,8 +198,10 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
// =====================================================================
// CN group with 5 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX;
for (j=0; j<5; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
@@ -234,8 +234,10 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
// =====================================================================
// CN group with 7 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX;
for (j=0; j<7; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
@@ -253,6 +255,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX;
for (j=0; j<8; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[5] + j*bitOffsetInGroup];
@@ -302,6 +305,7 @@ static inline void nrLDPC_llr2CnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* llr, in
// =====================================================================
// CN group with 19 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX;
for (j=0; j<19; j++)
@@ -1007,18 +1011,18 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
// CN group with 4 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX;
for (j=0; j<3; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[1] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[1]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG4[j][i] + lut_bnPosBnProcBuf_CNG4[j][i]*Z;
nrLDPC_circ_memcpy(p_cnProcBuf, &bnProcBufRes[idxBn], Z, lut_circShift_CNG4[j][i]);
p_cnProcBuf += Z;
}
}
}
// =====================================================================
// CN group with 5 BNs
@@ -1027,6 +1031,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
for (j=0; j<4; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[2]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG5[j][i] + lut_bnPosBnProcBuf_CNG5[j][i]*Z;
@@ -1039,10 +1044,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
// CN group with 6 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX;
for (j=0; j<5; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[3] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[3]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG6[j][i] + lut_bnPosBnProcBuf_CNG6[j][i]*Z;
@@ -1055,11 +1061,12 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
// CN group with 7 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX;
for (j=0; j<6; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[4]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG7[j][i] + lut_bnPosBnProcBuf_CNG7[j][i]*Z;
@@ -1092,6 +1099,7 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
for (j=0; j<8; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[6] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[6]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG9[j][i] + lut_bnPosBnProcBuf_CNG9[j][i]*Z;
@@ -1104,10 +1112,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
// CN group with 10 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX;
for (j=0; j<9; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[7] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[7]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG10[j][i] + lut_bnPosBnProcBuf_CNG10[j][i]*Z;
@@ -1120,10 +1129,11 @@ static inline void nrLDPC_bn2cnProcBuf_BG1(t_nrLDPC_lut* p_lut, int8_t* bnProcBu
// CN group with 19 BNs
bitOffsetInGroup = lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX;
for (j=0; j<19; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[8] + j*bitOffsetInGroup];
for (i=0; i<lut_numCnInCnGroups[8]; i++)
{
idxBn = lut_startAddrBnProcBuf_CNG19[j][i] + lut_bnPosBnProcBuf_CNG19[j][i]*Z;
@@ -1172,3 +1182,7 @@ static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, int
}
#endif

View File

@@ -0,0 +1,19 @@
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc ldpc/generator_bnProc)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc_avx512 ldpc/generator_bnProc_avx512)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc ldpc/generator_cnProc)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc_avx512 ldpc/generator_cnProc_avx512)
# custom target to build all generators
add_custom_target(ldpc_generators)
add_dependencies(ldpc_generators
bnProc_gen_avx2
bnProc_gen_avx512
cnProc_gen_avx2
cnProc_gen_avx512)
add_library(ldpc_gen_HEADERS INTERFACE)
target_link_libraries(ldpc_gen_HEADERS INTERFACE
bnProc_gen_avx2_HEADERS
bnProc_gen_avx512_HEADERS
cnProc_gen_avx2_HEADERS
cnProc_gen_avx512_HEADERS)

View File

@@ -0,0 +1,36 @@
add_executable(bnProc_gen_avx2
bnProc_gen_BG1_avx2.c
bnProc_gen_BG2_avx2.c
bnProcPc_gen_BG1_avx2.c
bnProcPc_gen_BG2_avx2.c
main.c)
target_compile_options(bnProc_gen_avx2 PRIVATE -W -Wall -mavx2)
#set(bnProc_headers
# bnProc/nrLDPC_bnProc_BG1_R13_AVX2.h
# bnProc/nrLDPC_bnProc_BG1_R23_AVX2.h
# bnProc/nrLDPC_bnProc_BG1_R89_AVX2.h
# bnProc/rLDPC_bnProc_BG2_R13_AVX2.h
# bnProc/rLDPC_bnProc_BG2_R15_AVX2.h
# bnProc/rLDPC_bnProc_BG2_R23_AVX2.h)
#
#set(bnProcPc_headers
# bnProcPc/rLDPC_bnProcPc_BG1_R13_AVX2.h
# bnProcPc/rLDPC_bnProcPc_BG1_R23_AVX2.h
# bnProcPc/rLDPC_bnProcPc_BG1_R89_AVX2.h
# bnProcPc/rLDPC_bnProcPc_BG2_R13_AVX2.h
# bnProcPc/rLDPC_bnProcPc_BG2_R15_AVX2.h
# bnProcPc/rLDPC_bnProcPc_BG2_R23_AVX2.h)
add_custom_command(TARGET bnProc_gen_avx2 POST_BUILD
#OUTPUT ${bnProc_headers} ${bnProcPc_headers}
COMMAND ${CMAKE_COMMAND} -E make_directory bnProc
COMMAND ${CMAKE_COMMAND} -E make_directory bnProcPc
COMMAND bnProc_gen_avx2 .
DEPENDS bnProc_gen_avx2
COMMENT "Generating LDPC bnProc header files for AVX2"
)
add_library(bnProc_gen_avx2_HEADERS INTERFACE)
target_include_directories(bnProc_gen_avx2_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(bnProc_gen_avx2_HEADERS bnProc_gen_avx2)

View File

@@ -0,0 +1,55 @@
/*
* 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
*/
#include <stdio.h>
#include <stdint.h>
#define NB_R 3
void nrLDPC_bnProc_BG1_generator_AVX2(const char*, int);
void nrLDPC_bnProc_BG2_generator_AVX2(const char*, int);
void nrLDPC_bnProcPc_BG1_generator_AVX2(const char*, int);
void nrLDPC_bnProcPc_BG2_generator_AVX2(const char*, int);
const char *__asan_default_options()
{
/* don't do leak checking in nr_ulsim, creates problems in the CI */
return "detect_leaks=0";
}
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
return 1;
}
const char *dir = argv[1];
int R[NB_R]={0,1,2};
for(int i=0; i<NB_R;i++){
nrLDPC_bnProc_BG1_generator_AVX2(dir, R[i]);
nrLDPC_bnProc_BG2_generator_AVX2(dir, R[i]);
nrLDPC_bnProcPc_BG1_generator_AVX2(dir, R[i]);
nrLDPC_bnProcPc_BG2_generator_AVX2(dir, R[i]);
}
return(0);
}

View File

@@ -0,0 +1,36 @@
add_executable(bnProc_gen_avx512
bnProc_gen_BG1_avx512.c
bnProc_gen_BG2_avx512.c
bnProcPc_gen_BG1_avx512.c
bnProcPc_gen_BG2_avx512.c
main.c)
target_compile_options(bnProc_gen_avx512 PRIVATE -W -Wall -mavx2)
#set(bnProc_avx512_headers
# bnProc_avx512/rLDPC_bnProc_BG1_R13_AVX512.h
# bnProc_avx512/rLDPC_bnProc_BG1_R23_AVX512.h
# bnProc_avx512/rLDPC_bnProc_BG1_R89_AVX512.h
# bnProc_avx512/rLDPC_bnProc_BG2_R13_AVX512.h
# bnProc_avx512/rLDPC_bnProc_BG2_R15_AVX512.h
# bnProc_avx512/rLDPC_bnProc_BG2_R23_AVX512.h)
#
#set(bnProcPc_avx512_headers
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R13_AVX512.h
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R23_AVX512.h
# bnProcPc_avx512/rLDPC_bnProcPc_BG1_R89_AVX512.h
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R13_AVX512.h
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R15_AVX512.h
# bnProcPc_avx512/rLDPC_bnProcPc_BG2_R23_AVX512.h)
add_custom_command(TARGET bnProc_gen_avx512 POST_BUILD
#OUTPUT ${bnProc_avx512_headers} ${bnProcPc_avx512_headers}
COMMAND ${CMAKE_COMMAND} -E make_directory bnProc_avx512
COMMAND ${CMAKE_COMMAND} -E make_directory bnProcPc_avx512
COMMAND bnProc_gen_avx512 .
DEPENDS bnProc_gen_avx512
COMMENT "Generating LDPC bnProc header files for AVX512"
)
add_library(bnProc_gen_avx512_HEADERS INTERFACE)
target_include_directories(bnProc_gen_avx512_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(bnProc_gen_avx512_HEADERS bnProc_gen_avx512)

View File

@@ -0,0 +1,56 @@
/*
* 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
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define NB_R 3
void nrLDPC_bnProc_BG1_generator_AVX512(const char *, int);
void nrLDPC_bnProc_BG2_generator_AVX512(const char *, int);
void nrLDPC_bnProcPc_BG1_generator_AVX512(const char *, int);
void nrLDPC_bnProcPc_BG2_generator_AVX512(const char *, int);
const char *__asan_default_options()
{
/* don't do leak checking in nr_ulsim, creates problems in the CI */
return "detect_leaks=0";
}
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
return 1;
}
const char *dir = argv[1];
int R[NB_R]={0,1,2};
for(int i=0; i<NB_R;i++){
nrLDPC_bnProc_BG1_generator_AVX512(dir, R[i]);
nrLDPC_bnProc_BG2_generator_AVX512(dir, R[i]);
nrLDPC_bnProcPc_BG1_generator_AVX512(dir, R[i]);
nrLDPC_bnProcPc_BG2_generator_AVX512(dir, R[i]);
}
return(0);
}

View File

@@ -0,0 +1,25 @@
add_executable(cnProc_gen_avx2
cnProc_gen_BG1_avx2.c
cnProc_gen_BG2_avx2.c
main.c)
target_compile_options(cnProc_gen_avx2 PRIVATE -W -Wall -mavx2)
#set(cnProc_headers
# cnProc/rLDPC_cnProc_BG1_R13_AVX2.h
# cnProc/rLDPC_cnProc_BG1_R23_AVX2.h
# cnProc/rLDPC_cnProc_BG1_R89_AVX2.h
# cnProc/rLDPC_cnProc_BG2_R13_AVX2.h
# cnProc/rLDPC_cnProc_BG2_R15_AVX2.h
# cnProc/rLDPC_cnProc_BG2_R23_AVX2.h)
add_custom_command(TARGET cnProc_gen_avx2 POST_BUILD
#OUTPUT ${cnProc_headers}
COMMAND ${CMAKE_COMMAND} -E make_directory cnProc
COMMAND cnProc_gen_avx2 .
DEPENDS cnProc_gen_avx2
COMMENT "Generating LDPC cnProc header files for AVX2"
)
add_library(cnProc_gen_avx2_HEADERS INTERFACE)
target_include_directories(cnProc_gen_avx2_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(cnProc_gen_avx2_HEADERS cnProc_gen_avx2)

View File

@@ -0,0 +1,693 @@
/*
* 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
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "../../nrLDPCdecoder_defs.h"
void nrLDPC_cnProc_BG1_generator_AVX2(const char* dir, int R)
{
const char *ratestr[3]={"13","23","89"};
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
// system("mkdir -p ../ldpc_gen_files");
char fname[FILENAME_MAX+1];
snprintf(fname, sizeof(fname), "%s/cnProc/nrLDPC_cnProc_BG1_R%s_AVX2.h", dir, ratestr[R]);
FILE *fd=fopen(fname,"w");
if (fd == NULL) {
printf("Cannot create file %s\n", fname);
abort();
}
fprintf(fd,"#include <stdint.h>\n");
fprintf(fd,"#include <immintrin.h>\n");
fprintf(fd,"static inline void nrLDPC_cnProc_BG1_R%s_AVX2(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
const uint8_t* lut_numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1;
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13;
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23;
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89;
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
//__m256i* p_cnProcBuf;
//__m256i* p_cnProcBufRes;
// Number of CNs in Groups
//uint32_t M;
uint32_t j;
uint32_t k;
// Offset to each bit within a group in terms of 32 Byte
uint32_t bitOffsetInGroup;
//__m256i ymm0, min, sgn;
//__m256i* p_cnProcBufResBit;
// const __m256i* p_ones = (__m256i*) ones256_epi8;
// const __m256i* p_maxLLR = (__m256i*) maxLLR256_epi8;
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup (1*384/32)
// const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
// =====================================================================
// Process group with 3 BNs
fprintf(fd,"//Process group with 3 BNs\n");
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup (1*384/32)
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
fprintf(fd," __m256i ymm0, min, sgn,ones,maxLLR;\n");
fprintf(fd," ones = _mm256_set1_epi8((char)1);\n");
fprintf(fd," maxLLR = _mm256_set1_epi8((char)127);\n");
fprintf(fd," uint32_t M;\n");
if (lut_numCnInCnGroups[0] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[0] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 3
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[0]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[0]];
// Loop over every BN
for (j=0; j<3; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// 32 CNs of second BN
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 4 BNs
fprintf(fd,"//Process group with 4 BNs\n");
// Offset is 5*384/32 = 60
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
if (lut_numCnInCnGroups[1] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[1] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 4
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<4; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<3; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 5 BNs
fprintf(fd,"//Process group with 5 BNs\n");
// Offset is 18*384/32 = 216
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
if (lut_numCnInCnGroups[2] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[2] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 4
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<5; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<4; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 6 BNs
fprintf(fd,"//Process group with 6 BNs\n");
// Offset is 8*384/32 = 96
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
{0,96,288,384,480}, {0,96,192,384,480},
{0,96,192,288,480}, {0,96,192,288,384}};
if (lut_numCnInCnGroups[3] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[3] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 4
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<6; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<5; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 7 BNs
fprintf(fd,"//Process group with 7 BNs\n");
// Offset is 5*384/32 = 60
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
{0,60,180,240,300,360}, {0,60,120,240,300,360},
{0,60,120,180,300,360}, {0,60,120,180,240,360},
{0,60,120,180,240,300}};
if (lut_numCnInCnGroups[4] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[4] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 4
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<7; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG7[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<6; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG7[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 8 BNs
fprintf(fd,"//Process group with 8 BNs\n");
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
if (lut_numCnInCnGroups[5] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[5] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 4
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<8; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG8[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<7; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG8[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 9 BNs
fprintf(fd,"//Process group with 9 BNs\n");
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
{0,24,48,72,96,120,144,168}};
if (lut_numCnInCnGroups[6] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[6] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 9
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<9; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>5)+lut_idxCnProcG9[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<8; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>5)+lut_idxCnProcG9[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[6]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 10 BNs
fprintf(fd,"//Process group with 10 BNs\n");
// Offset is 1*384/32 = 12
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
if (lut_numCnInCnGroups[7] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, " M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[7] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 10
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<10; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>5)+lut_idxCnProcG10[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<9; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>5)+lut_idxCnProcG10[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[7]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 19 BNs
fprintf(fd,"//Process group with 19 BNs\n");
// Offset is 4*384/32 = 12
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
if (lut_numCnInCnGroups[8] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, " M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[8] );
// Set the offset to each bit within a group in terms of 32 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>5;
// Set pointers to start of group 19
//p_cnProcBuf = (__m256i*) &cnProcBuf [lut_startAddrCnGroups[1]];
//p_cnProcBufRes = (__m256i*) &cnProcBufRes[lut_startAddrCnGroups[1]];
// Loop over every BN
for (j=0; j<19; j++)
{
// Set of results pointer to correct BN address
//p_cnProcBufResBit = p_cnProcBufRes + (j*bitOffsetInGroup);
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>5)+lut_idxCnProcG19[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<18; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>5)+lut_idxCnProcG19[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[8]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
fprintf(fd,"}\n");
fclose(fd);
}//end of the function nrLDPC_cnProc_BG1

View File

@@ -0,0 +1,436 @@
/*
* 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
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "../../nrLDPCdecoder_defs.h"
#include "../../nrLDPC_types.h"
#include "../../nrLDPC_bnProc.h"
void nrLDPC_cnProc_BG2_generator_AVX2(const char* dir, int R)
{
const char *ratestr[3]={"15","13","23"};
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
// system("mkdir -p ldpc_gen_files/avx2");
char fname[FILENAME_MAX+1];
snprintf(fname, sizeof(fname), "%s/cnProc/nrLDPC_cnProc_BG2_R%s_AVX2.h", dir, ratestr[R]);
FILE *fd=fopen(fname,"w");
if (fd == NULL) {
printf("Cannot create file %s\n", fname);
abort();
}
fprintf(fd,"#include <stdint.h>\n");
fprintf(fd,"#include <immintrin.h>\n");
fprintf(fd,"static inline void nrLDPC_cnProc_BG2_R%s_AVX2(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
const uint8_t* lut_numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG2;
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R15;
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R13;
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG2_R23;
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
// Number of CNs in Groups
//uint32_t M;
uint32_t j;
uint32_t k;
// Offset to each bit within a group in terms of 32 byte
uint32_t bitOffsetInGroup;
// Offsets are in units of bitOffsetInGroup (1*384/32)
// const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
// =====================================================================
// Process group with 3 BNs
fprintf(fd,"//Process group with 3 BNs\n");
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup
const uint8_t lut_idxCnProcG3[3][2] = {{72,144}, {0,144}, {0,72}};
fprintf(fd," __m256i ymm0, min, sgn,ones,maxLLR;\n");
fprintf(fd," ones = _mm256_set1_epi8((char)1);\n");
fprintf(fd," maxLLR = _mm256_set1_epi8((char)127);\n");
fprintf(fd," uint32_t M;\n");
if (lut_numCnInCnGroups[0] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[0] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<3; j++)
{
fprintf(fd," for (int i=0;i<M;i+=2) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// 32 CNs of second BN
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][1] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][1]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[0]>>5)+(j*bitOffsetInGroup));
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>5)+lut_idxCnProcG3[j][0]+1);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 4 BNs
fprintf(fd,"//Process group with 4 BNs\n");
// Offset is 20*384/32 = 240
const uint16_t lut_idxCnProcG4[4][3] = {{240,480,720}, {0,480,720}, {0,240,720}, {0,240,480}};
if (lut_numCnInCnGroups[1] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[1] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<4; j++)
{
// Loop over CNs
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<3; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>5)+lut_idxCnProcG4[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[1]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 5 BNs
fprintf(fd,"//Process group with 5 BNs\n");
// Offset is 9*384/32 = 108
const uint16_t lut_idxCnProcG5[5][4] = {{108,216,324,432}, {0,216,324,432},
{0,108,324,432}, {0,108,216,432}, {0,108,216,324}};
if (lut_numCnInCnGroups[2] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd," M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[2] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<5; j++)
{
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<4; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>5)+lut_idxCnProcG5[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[2]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 6 BNs
fprintf(fd,"//Process group with 6 BNs\n");
// Offset is 3*384/32 = 36
const uint16_t lut_idxCnProcG6[6][5] = {{36,72,108,144,180}, {0,72,108,144,180},
{0,36,108,144,180}, {0,36,72,144,180},
{0,36,72,108,180}, {0,36,72,108,144}};
if (lut_numCnInCnGroups[3] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[3] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<6; j++)
{
// Loop over CNs
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<5; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>5)+lut_idxCnProcG6[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[3]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 8 BNs
fprintf(fd,"//Process group with 8 BNs\n");
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
if (lut_numCnInCnGroups[4] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[4] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<8; j++)
{
// Loop over CNs
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG8[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<7; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>5)+lut_idxCnProcG8[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[4]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 10 BNs
fprintf(fd,"//Process group with 10 BNs\n");
const uint8_t lut_idxCnProcG10[10][9] = {{24,48,72,96,120,144,168,192,216}, {0,48,72,96,120,144,168,192,216},
{0,24,72,96,120,144,168,192,216}, {0,24,48,96,120,144,168,192,216},
{0,24,48,72,120,144,168,192,216}, {0,24,48,72,96,144,168,192,216},
{0,24,48,72,96,120,168,192,216}, {0,24,48,72,96,120,144,192,216},
{0,24,48,72,96,120,144,168,216}, {0,24,48,72,96,120,144,168,192}};
if (lut_numCnInCnGroups[5] > 0)
{
// Number of groups of 32 CNs for parallel processing
// Ceil for values not divisible by 32
fprintf(fd, "M = (%d*Z + 31)>>5;\n",lut_numCnInCnGroups[5] );
// Set the offset to each bit within a group in terms of 32 byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX)>>5;
// Loop over every BN
for (j=0; j<10; j++)
{
// Loop over CNs
fprintf(fd," for (int i=0;i<M;i++) {\n");
// Abs and sign of 32 CNs (first BN)
// ymm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG10[j][0]);
// sgn = _mm256_sign_epi8(ones, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(ones, ymm0);\n");
// min = _mm256_abs_epi8(ymm0);
fprintf(fd," min = _mm256_abs_epi8(ymm0);\n");
// Loop over BNs
for (k=1; k<9; k++)
{
fprintf(fd," ymm0 = ((__m256i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>5)+lut_idxCnProcG10[j][k]);
// min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));
fprintf(fd," min = _mm256_min_epu8(min, _mm256_abs_epi8(ymm0));\n");
// sgn = _mm256_sign_epi8(sgn, ymm0);
fprintf(fd," sgn = _mm256_sign_epi8(sgn, ymm0);\n");
}
// Store result
// min = _mm256_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm256_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm256_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m256i*)cnProcBufRes)[%d+i] = _mm256_sign_epi8(min, sgn);\n",(lut_startAddrCnGroups[5]>>5)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
fprintf(fd,"}\n");
fclose(fd);
}//end of the function nrLDPC_cnProc_BG2

View File

@@ -0,0 +1,50 @@
/*
* 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
*/
#include <stdio.h>
#include <stdint.h>
#define NB_R 3
void nrLDPC_cnProc_BG1_generator_AVX2(const char*, int);
void nrLDPC_cnProc_BG2_generator_AVX2(const char*, int);
const char *__asan_default_options()
{
/* don't do leak checking in nr_ulsim, creates problems in the CI */
return "detect_leaks=0";
}
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: %s <output-dir>\n", argv[0]);
return 1;
}
const char *dir = argv[1];
int R[NB_R]={0,1,2};
for(int i=0; i<NB_R;i++) {
nrLDPC_cnProc_BG1_generator_AVX2(dir, R[i]);
nrLDPC_cnProc_BG2_generator_AVX2(dir, R[i]);
}
return(0);
}

View File

@@ -0,0 +1,25 @@
add_executable(cnProc_gen_avx512
cnProc_gen_BG1_avx512.c
cnProc_gen_BG2_avx512.c
main.c)
target_compile_options(cnProc_gen_avx512 PRIVATE -W -Wall -mavx2)
#set(cnProc_avx512_headers
# cnProc_avx512/nrLDPC_cnProc_BG1_R13_AVX512.h
# cnProc_avx512/nrLDPC_cnProc_BG1_R23_AVX512.h
# cnProc_avx512/nrLDPC_cnProc_BG1_R89_AVX512.h
# cnProc_avx512/nrLDPC_cnProc_BG2_R13_AVX512.h
# cnProc_avx512/nrLDPC_cnProc_BG2_R15_AVX512.h
# cnProc_avx512/nrLDPC_cnProc_BG2_R23_AVX512.h)
add_custom_command(TARGET cnProc_gen_avx512 POST_BUILD
#OUTPUT ${cnProc_avx512_headers}
COMMAND ${CMAKE_COMMAND} -E make_directory cnProc_avx512
COMMAND cnProc_gen_avx512 .
DEPENDS cnProc_gen_avx512
COMMENT "Generating LDPC cnProc header files for AVX512"
)
add_library(cnProc_gen_avx512_HEADERS INTERFACE)
target_include_directories(cnProc_gen_avx512_HEADERS INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(cnProc_gen_avx512_HEADERS cnProc_gen_avx512)

View File

@@ -0,0 +1,597 @@
/*
* 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
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "../../nrLDPCdecoder_defs.h"
void nrLDPC_cnProc_BG1_generator_AVX512(const char *dir, int R)
{
const char *ratestr[3]={"13","23","89"};
if (R<0 || R>2) {printf("Illegal R %d\n",R); abort();}
// system("mkdir -p ../ldpc_gen_files");
char fname[FILENAME_MAX+1];
snprintf(fname, sizeof(fname), "%s/cnProc_avx512/nrLDPC_cnProc_BG1_R%s_AVX512.h", dir, ratestr[R]);
FILE *fd=fopen(fname,"w");
if (fd == NULL) {
printf("Cannot create file %s\n", fname);
abort();
}
// fprintf(fd,"#include <stdint.h>\n");
// fprintf(fd,"#include <immintrin.h>\n");
fprintf(fd, "#define conditional_negate(a,b,z) _mm512_mask_sub_epi8(a,_mm512_movepi8_mask(b),z,a)\n");
fprintf(fd,"static inline void nrLDPC_cnProc_BG1_R%s_AVX512(int8_t* cnProcBuf, int8_t* cnProcBufRes, uint16_t Z) {\n",ratestr[R]);
const uint8_t* lut_numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = lut_startAddrCnGroups_BG1;
if (R==0) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R13;
else if (R==1) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R23;
else if (R==2) lut_numCnInCnGroups = lut_numCnInCnGroups_BG1_R89;
else { printf("aborting, illegal R %d\n",R); fclose(fd);abort();}
uint32_t j;
uint32_t k;
// Offset to each bit within a group in terms of 64 Byte
uint32_t bitOffsetInGroup;
fprintf(fd," uint32_t M, i;\n");
fprintf(fd," __m512i zmm0, min, sgn,zeros,maxLLR, ones;\n");
fprintf(fd," zeros = _mm512_setzero_si512();\n");
fprintf(fd," maxLLR = _mm512_set1_epi8((char)127);\n");
fprintf(fd," ones = _mm512_set1_epi8((char)1);\n");
// =====================================================================
// Process group with 3 BNs
fprintf(fd,"//Process group with 3 BNs\n");
// LUT with offsets for bits that need to be processed
// 1. bit proc requires LLRs of 2. and 3. bit, 2.bits of 1. and 3. etc.
// Offsets are in units of bitOffsetInGroup (1*384/32)12
// Offsets are in units of bitOffsetInGroup (1*384/32)12
const uint8_t lut_idxCnProcG3[3][2] = {{12,24}, {0,24}, {0,12}};
if (lut_numCnInCnGroups[0] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
//M = (lut_numCnInCnGroups[0]*Z + 63)>>6;
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[0] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[0]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<3; j++)
{
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// for (k=1; k<2; k++)
//{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[0]>>6)+lut_idxCnProcG3[j][1]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
// }
// Store result
// min = _mm512_min_epu8(min, *maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[0]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 4 BNs
fprintf(fd,"//Process group with 4 BNs\n");
// Offset is 5*384/32 = 30
const uint8_t lut_idxCnProcG4[4][3] = {{60,120,180}, {0,120,180}, {0,60,180}, {0,60,120}};
if (lut_numCnInCnGroups[1] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
//M = (lut_numCnInCnGroups[1]*Z + 63)>>6;
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[1] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[1]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<4; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<3; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[1]>>6)+lut_idxCnProcG4[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
// *p_cnProcBufResBit = _mm512_sign_epi8(min, sgn);
// p_cnProcBufResBit++;
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[1]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 5 BNs
fprintf(fd,"//Process group with 5 BNs\n");
// Offset is 18*384/32 = 216
const uint16_t lut_idxCnProcG5[5][4] = {{216,432,648,864}, {0,432,648,864},
{0,216,648,864}, {0,216,432,864}, {0,216,432,648}};
if (lut_numCnInCnGroups[2] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
//M = (lut_numCnInCnGroups[2]*Z + 63)>>6;
fprintf(fd," M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[2] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[2]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<5; j++)
{
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<4; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[2]>>6)+lut_idxCnProcG5[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[2]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 6 BNs
fprintf(fd,"//Process group with 6 BNs\n");
// Offset is 8*384/32 = 48
const uint16_t lut_idxCnProcG6[6][5] = {{96,192,288,384,480}, {0,192,288,384,480},
{0,96,288,384,480}, {0,96,192,384,480},
{0,96,192,288,480}, {0,96,192,288,384}};
if (lut_numCnInCnGroups[3] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
//M = (lut_numCnInCnGroups[3]*Z + 63)>>6;
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[3] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[3]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<6; j++)
{
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<5; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[3]>>6)+lut_idxCnProcG6[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[3]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 7 BNs
fprintf(fd,"//Process group with 7 BNs\n");
// Offset is 5*384/32 = 30
const uint16_t lut_idxCnProcG7[7][6] = {{60,120,180,240,300,360}, {0,120,180,240,300,360},
{0,60,180,240,300,360}, {0,60,120,240,300,360},
{0,60,120,180,300,360}, {0,60,120,180,240,360},
{0,60,120,180,240,300}};
if (lut_numCnInCnGroups[4] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
// M = (lut_numCnInCnGroups[4]*Z + 63)>>6;
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[4] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[4]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<7; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0= ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG7[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<6; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[4]>>6)+lut_idxCnProcG7[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[4]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 8 BNs
fprintf(fd,"//Process group with 8 BNs\n");
// Offset is 2*384/32 = 24
const uint8_t lut_idxCnProcG8[8][7] = {{24,48,72,96,120,144,168}, {0,48,72,96,120,144,168},
{0,24,72,96,120,144,168}, {0,24,48,96,120,144,168},
{0,24,48,72,120,144,168}, {0,24,48,72,96,144,168},
{0,24,48,72,96,120,168}, {0,24,48,72,96,120,144}};
if (lut_numCnInCnGroups[5] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
// M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[5] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[5]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<8; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG8[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<7; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[5]>>6)+lut_idxCnProcG8[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[5]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 9 BNs
fprintf(fd,"//Process group with 9 BNs\n");
// Offset is 2*384/32 = 12
const uint8_t lut_idxCnProcG9[9][8] = {{24,48,72,96,120,144,168,192}, {0,48,72,96,120,144,168,192},
{0,24,72,96,120,144,168,192}, {0,24,48,96,120,144,168,192},
{0,24,48,72,120,144,168,192}, {0,24,48,72,96,144,168,192},
{0,24,48,72,96,120,168,192}, {0,24,48,72,96,120,144,192},
{0,24,48,72,96,120,144,168}};
if (lut_numCnInCnGroups[6] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
// M = (lut_numCnInCnGroups[5]*Z + 63)>>6;
fprintf(fd, "M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[6] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[6]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<9; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>6)+lut_idxCnProcG9[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<8; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[6]>>6)+lut_idxCnProcG9[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[6]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 10 BNs
fprintf(fd,"//Process group with 10 BNs\n");
// Offset is 1*384/32 = 6
const uint8_t lut_idxCnProcG10[10][9] = {{12,24,36,48,60,72,84,96,108}, {0,24,36,48,60,72,84,96,108},
{0,12,36,48,60,72,84,96,108}, {0,12,24,48,60,72,84,96,108},
{0,12,24,36,60,72,84,96,108}, {0,12,24,36,48,72,84,96,108},
{0,12,24,36,48,60,84,96,108}, {0,12,24,36,48,60,72,96,108},
{0,12,24,36,48,60,72,84,108}, {0,12,24,36,48,60,72,84,96}};
if (lut_numCnInCnGroups[7] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
//M = (lut_numCnInCnGroups[7]*Z + 63)>>6;
fprintf(fd, " M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[7] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[7]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<10; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>6)+lut_idxCnProcG10[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<9; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[7]>>6)+lut_idxCnProcG10[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min,sgn,zeros);\n",(lut_startAddrCnGroups[7]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
// =====================================================================
// Process group with 19 BNs
fprintf(fd,"//Process group with 19 BNs\n");
// Offset is 4*384/32 = 24
const uint16_t lut_idxCnProcG19[19][18] = {{48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,192,240,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,240,288,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,288,336,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,336,384,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,384,432,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,432,480,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,480,528,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,528,576,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,576,624,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,624,672,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,672,720,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,720,768,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,768,816,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,816,864}, {0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,864},
{0,48,96,144,192,240,288,336,384,432,480,528,576,624,672,720,768,816}};
if (lut_numCnInCnGroups[8] > 0)
{
// Number of groups of 64 CNs for parallel processing
// Ceil for values not divisible by 64
// M = (lut_numCnInCnGroups[8]*Z + 63)>>6;
fprintf(fd, " M = (%d*Z + 63)>>6;\n",lut_numCnInCnGroups[8] );
// Set the offset to each bit within a group in terms of 64 Byte
bitOffsetInGroup = (lut_numCnInCnGroups_BG1_R13[8]*NR_LDPC_ZMAX)>>6;
// Loop over every BN
for (j=0; j<19; j++)
{
// Loop over CNs
// for (i=0; i<M; i++,iprime++)
// {
fprintf(fd," for (i=0;i<M;i++) {\n");
// Abs and sign of 64 CNs (first BN)
// zmm0 = p_cnProcBuf[lut_idxCnProcG3[j][0] + i];
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>6)+lut_idxCnProcG19[j][0]/2);
fprintf(fd," sgn = _mm512_xor_si512(ones, zmm0);\n");
fprintf(fd," min = _mm512_abs_epi8(zmm0);\n");
// Loop over BNs
for (k=1; k<18; k++)
{
fprintf(fd," zmm0 = ((__m512i*)cnProcBuf)[%d+i];\n",(lut_startAddrCnGroups[8]>>6)+lut_idxCnProcG19[j][k]/2);
// min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));
fprintf(fd," min = _mm512_min_epu8(min, _mm512_abs_epi8(zmm0));\n");
// sgn = _mm512_sign_epi8(*p_ones, zmm0);
fprintf(fd," sgn = _mm512_xor_si512(sgn, zmm0);\n");
}
// Store result
// min = _mm512_min_epu8(min, maxLLR); // 128 in epi8 is -127
fprintf(fd," min = _mm512_min_epu8(min, maxLLR);\n");
fprintf(fd," ((__m512i*)cnProcBufRes)[%d+i] = conditional_negate(min, sgn,zeros);\n",(lut_startAddrCnGroups[8]>>6)+(j*bitOffsetInGroup));
fprintf(fd," }\n");
}
}
fprintf(fd,"}\n");
fclose(fd);
}//end of the function nrLDPC_cnProc_BG1

Some files were not shown because too many files have changed in this diff Show More