mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-18 15:10:29 +00:00
Compare commits
774 Commits
main
...
feature-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21bd734d05 | ||
|
|
163bbfdcb1 | ||
|
|
67f29660a5 | ||
|
|
7d5adc8856 | ||
|
|
428a6f3414 | ||
|
|
170587d68f | ||
|
|
ad3ce001e2 | ||
|
|
d3f31b2a74 | ||
|
|
6d030ea2fa | ||
|
|
a9faf533b4 | ||
|
|
0e04fba03d | ||
|
|
5cebe354c5 | ||
|
|
b37050ac6e | ||
|
|
304c92c639 | ||
|
|
4505e780c5 | ||
|
|
644422ebec | ||
|
|
f6fe86c653 | ||
|
|
fe7228daee | ||
|
|
2c226b08f4 | ||
|
|
2802418c34 | ||
|
|
2659dce8b8 | ||
|
|
9c02189e64 | ||
|
|
d0fa56b1de | ||
|
|
0fe98c25a2 | ||
|
|
a4e2c2b799 | ||
|
|
2124e43d3a | ||
|
|
fb6fa64bc7 | ||
|
|
5cd674483b | ||
|
|
2bed0352fd | ||
|
|
4f44a1026b | ||
|
|
dab905519b | ||
|
|
2b38c78588 | ||
|
|
12a23fb1ef | ||
|
|
ee71b0dd9b | ||
|
|
78267db68b | ||
|
|
0c0d88b201 | ||
|
|
7194a720c9 | ||
|
|
9ff4630071 | ||
|
|
9e27394ecc | ||
|
|
2399da33cb | ||
|
|
348ff98762 | ||
|
|
032d477481 | ||
|
|
a73e500ded | ||
|
|
7b75305e3c | ||
|
|
5761164a09 | ||
|
|
4053c0c3b2 | ||
|
|
cc33856ba8 | ||
|
|
14d3a9c0e5 | ||
|
|
e62119bea5 | ||
|
|
7f21567f83 | ||
|
|
2521e46593 | ||
|
|
527003492d | ||
|
|
d835f3387d | ||
|
|
630f8ac2b1 | ||
|
|
079ad360e0 | ||
|
|
bb15360a55 | ||
|
|
0a74c23c8a | ||
|
|
ed74875025 | ||
|
|
7cee46777f | ||
|
|
33b69bdf30 | ||
|
|
1ad8f254c2 | ||
|
|
045de837ab | ||
|
|
a119e84f92 | ||
|
|
983760e9a4 | ||
|
|
131db89dfc | ||
|
|
5944b212b2 | ||
|
|
7387721ecf | ||
|
|
f6bb869c0b | ||
|
|
169f42a365 | ||
|
|
6900f2bc88 | ||
|
|
e850a8ece7 | ||
|
|
aabd9c6c4e | ||
|
|
b69fa39577 | ||
|
|
b193ccf6ee | ||
|
|
0122749406 | ||
|
|
ae23942020 | ||
|
|
dc4f610245 | ||
|
|
3793edf686 | ||
|
|
4b0d4e38c4 | ||
|
|
28ad0eaacb | ||
|
|
9127577bf3 | ||
|
|
2e6fea604d | ||
|
|
f95c636a6b | ||
|
|
f7ab71763d | ||
|
|
dde6d61dd4 | ||
|
|
7b68c48618 | ||
|
|
250043655a | ||
|
|
97b3d1a5cd | ||
|
|
8adcf8368a | ||
|
|
f5e9c4ec36 | ||
|
|
e7a491415c | ||
|
|
0aec0d91c6 | ||
|
|
894c45eae5 | ||
|
|
e3747ea06b | ||
|
|
aed83c91de | ||
|
|
12c0f52fea | ||
|
|
0d9e548f39 | ||
|
|
80ad5df367 | ||
|
|
933ad3dcf4 | ||
|
|
8a8bacead9 | ||
|
|
e8d91d642e | ||
|
|
0cea80c8fa | ||
|
|
1afdc298e9 | ||
|
|
7c47420da7 | ||
|
|
b2b84caeb5 | ||
|
|
93e6bd26da | ||
|
|
0960aa3d00 | ||
|
|
ab899c3a08 | ||
|
|
da8d3037df | ||
|
|
8f79ae0ea7 | ||
|
|
689ecf5ae1 | ||
|
|
e36a2b483a | ||
|
|
1d99c8e695 | ||
|
|
b29f92c1d6 | ||
|
|
36190b1c7d | ||
|
|
ac58460b6e | ||
|
|
382b2c41e3 | ||
|
|
2d3f4f7310 | ||
|
|
9eccd6c11d | ||
|
|
85b48193d4 | ||
|
|
f71766c3ee | ||
|
|
e24edde2fd | ||
|
|
bc1227f9a0 | ||
|
|
539e5e89f3 | ||
|
|
4ffef42472 | ||
|
|
bb17287089 | ||
|
|
d7dae8fa91 | ||
|
|
b1d07fb3e0 | ||
|
|
7546b8ca1b | ||
|
|
0b55910c48 | ||
|
|
308cae752a | ||
|
|
45522ae86c | ||
|
|
5f37ab35b4 | ||
|
|
4e34462488 | ||
|
|
7b3191d1a6 | ||
|
|
1215444cae | ||
|
|
6e7160ac03 | ||
|
|
bea2ec5c3b | ||
|
|
f8f20827e9 | ||
|
|
59e10dc8da | ||
|
|
f2bc364b50 | ||
|
|
cc2c3b9123 | ||
|
|
43701ddbd6 | ||
|
|
dd801325d4 | ||
|
|
db2c03d31d | ||
|
|
d5165ae2bd | ||
|
|
9b317eacef | ||
|
|
cd4bc84bd8 | ||
|
|
b96df49e15 | ||
|
|
a531342054 | ||
|
|
2c3eb996a4 | ||
|
|
9a43678ed0 | ||
|
|
13ed1200b4 | ||
|
|
5ea828e149 | ||
|
|
426bc2f088 | ||
|
|
6f7889d162 | ||
|
|
83d40a9b7c | ||
|
|
df8f632ae3 | ||
|
|
23c8336a37 | ||
|
|
ac9e47ba68 | ||
|
|
43033e20b6 | ||
|
|
16e8154d71 | ||
|
|
9ba33d4dec | ||
|
|
a51c1f93b5 | ||
|
|
b6adb32989 | ||
|
|
236f7d56e5 | ||
|
|
6bca31c7e3 | ||
|
|
92ba8cb9d0 | ||
|
|
daad3da6eb | ||
|
|
21a820b061 | ||
|
|
72d0a4ff05 | ||
|
|
9228f12d92 | ||
|
|
09ecb8a33c | ||
|
|
36a02913de | ||
|
|
360d4b3a81 | ||
|
|
103e21a05c | ||
|
|
cf7c2fd373 | ||
|
|
ab1df8bbc4 | ||
|
|
1450e2fb9f | ||
|
|
38f7d772e6 | ||
|
|
3c753aec71 | ||
|
|
3b28264374 | ||
|
|
ba73075ccd | ||
|
|
3a0bccde30 | ||
|
|
fac44b15e8 | ||
|
|
25086576e5 | ||
|
|
c6498ccf58 | ||
|
|
d3f90a90fe | ||
|
|
276b2d5e0c | ||
|
|
e1b090cfaa | ||
|
|
9f6b7dc6b9 | ||
|
|
9354d4305b | ||
|
|
00d021c66b | ||
|
|
2ba71e748d | ||
|
|
a724c1febc | ||
|
|
fcfc7a90e8 | ||
|
|
7bf5f018a1 | ||
|
|
a5d0615048 | ||
|
|
b46077c22d | ||
|
|
9150dc8c50 | ||
|
|
3d5cfb6642 | ||
|
|
d56f2c8e12 | ||
|
|
6d736db22d | ||
|
|
436eb2d5a9 | ||
|
|
3ca4cb708c | ||
|
|
34b821433b | ||
|
|
17cbc4dbf4 | ||
|
|
26c2c0add8 | ||
|
|
61d434339e | ||
|
|
1fbf968676 | ||
|
|
2d96262d7c | ||
|
|
0c5d6a59e7 | ||
|
|
e5c4e0f3d3 | ||
|
|
f94a479829 | ||
|
|
03e869ee36 | ||
|
|
1e4f509805 | ||
|
|
e639e79220 | ||
|
|
085014f601 | ||
|
|
3934f2020e | ||
|
|
6f8b13c2ad | ||
|
|
c97d5d04ed | ||
|
|
1f49b73eac | ||
|
|
8ac68929bc | ||
|
|
44a98a85c5 | ||
|
|
5bf454c78b | ||
|
|
22944fb8c0 | ||
|
|
6c43cdf4dc | ||
|
|
bdc4a664ac | ||
|
|
a254545b7c | ||
|
|
486e9e2381 | ||
|
|
cc238a91e4 | ||
|
|
9b2fa3ca63 | ||
|
|
1c4bf40248 | ||
|
|
64f4d34c25 | ||
|
|
a9dcdcbbcb | ||
|
|
09c3597b46 | ||
|
|
54f49fd253 | ||
|
|
2f3ce42d3b | ||
|
|
851291ddc4 | ||
|
|
9f51b3f8b1 | ||
|
|
7d1f693ba1 | ||
|
|
af377945c3 | ||
|
|
9aa7d1c88f | ||
|
|
0217cd50de | ||
|
|
270c540c3c | ||
|
|
c4c93cc498 | ||
|
|
3c4ba50281 | ||
|
|
340531038c | ||
|
|
5c754f2300 | ||
|
|
6ded64f86d | ||
|
|
4c1b432718 | ||
|
|
1fbc7e080b | ||
|
|
68be6f83e6 | ||
|
|
c7e8002d8d | ||
|
|
3b16547374 | ||
|
|
a037987b47 | ||
|
|
d7795c9dff | ||
|
|
c587fe366d | ||
|
|
5031649c47 | ||
|
|
59ced82104 | ||
|
|
b8cd9ef167 | ||
|
|
02d49ed3b6 | ||
|
|
87e79e5eb8 | ||
|
|
a8e6bf9bd5 | ||
|
|
2bbfe501c2 | ||
|
|
1750f45708 | ||
|
|
acc6fb8508 | ||
|
|
edea5c5f65 | ||
|
|
40fcfdea8b | ||
|
|
4045874d74 | ||
|
|
999f5d67e3 | ||
|
|
bf5389936d | ||
|
|
3ecfead572 | ||
|
|
63b28d3610 | ||
|
|
f2974b431b | ||
|
|
7aa3bfaa54 | ||
|
|
d059c71754 | ||
|
|
8641d54f4d | ||
|
|
1e38cead39 | ||
|
|
7597a582f9 | ||
|
|
cfa37e7213 | ||
|
|
2162ba6d82 | ||
|
|
e3fd9f7f8c | ||
|
|
b6a018089b | ||
|
|
8506307ef0 | ||
|
|
3d5fa54a48 | ||
|
|
5de85671d8 | ||
|
|
6b6528cc94 | ||
|
|
4f2854f92c | ||
|
|
0e2a00655e | ||
|
|
d01cd03ad3 | ||
|
|
2ddb68754e | ||
|
|
4b3aa7233e | ||
|
|
1694e1b061 | ||
|
|
523f8f2139 | ||
|
|
8ba0f2f086 | ||
|
|
7815293443 | ||
|
|
e236794310 | ||
|
|
c128a5d9e2 | ||
|
|
719d7fb8be | ||
|
|
724e155a3a | ||
|
|
927e219553 | ||
|
|
badb6cb590 | ||
|
|
735b51a06b | ||
|
|
4ecb0401e0 | ||
|
|
65f09fecb8 | ||
|
|
b6016cfc49 | ||
|
|
5e1364f19d | ||
|
|
99fde7f7cb | ||
|
|
b56494855e | ||
|
|
d05f2b3add | ||
|
|
6af3d0a364 | ||
|
|
f902e27c43 | ||
|
|
7e172e348b | ||
|
|
cb456a23cc | ||
|
|
ac5444afd9 | ||
|
|
7e6f8ecfb3 | ||
|
|
697d72cd01 | ||
|
|
f57f4ce3fe | ||
|
|
aeaf4c87b5 | ||
|
|
f49df05456 | ||
|
|
5887541538 | ||
|
|
15777bbf0e | ||
|
|
efd99acacc | ||
|
|
709db95112 | ||
|
|
e59ac44c94 | ||
|
|
8e4c513805 | ||
|
|
55f1a6b4da | ||
|
|
72f40e6fb1 | ||
|
|
7508205f90 | ||
|
|
5c176c454a | ||
|
|
bd7f837f18 | ||
|
|
44c0c8d321 | ||
|
|
795c057d8c | ||
|
|
a39c310bd4 | ||
|
|
6b873e0f41 | ||
|
|
a71552d55d | ||
|
|
9b2a163ebb | ||
|
|
3feb0f472f | ||
|
|
b216c58526 | ||
|
|
7b5d8de65f | ||
|
|
0270b7b1fb | ||
|
|
ada380d9fd | ||
|
|
e721f6af04 | ||
|
|
f9e5c987a6 | ||
|
|
0c05e283e2 | ||
|
|
a81640a6df | ||
|
|
cfda6c7b1d | ||
|
|
d6072cb5d2 | ||
|
|
d5421a9c87 | ||
|
|
e6913e5d33 | ||
|
|
11ced194cd | ||
|
|
02b66061b1 | ||
|
|
94e5aaff88 | ||
|
|
47c9ded007 | ||
|
|
bfc7c1b361 | ||
|
|
0689040770 | ||
|
|
940abc3587 | ||
|
|
8c056ceefc | ||
|
|
1ab64d26aa | ||
|
|
5962824038 | ||
|
|
4035bdb71d | ||
|
|
298740b06c | ||
|
|
c7055b2cf9 | ||
|
|
23bdf1e32c | ||
|
|
dd374c7e03 | ||
|
|
7f074bcc22 | ||
|
|
fe7ee4d2fe | ||
|
|
e297ccfa26 | ||
|
|
2b1cafb509 | ||
|
|
e4536a093f | ||
|
|
eb03322545 | ||
|
|
1a3c8e5440 | ||
|
|
c65593d088 | ||
|
|
345f3056ff | ||
|
|
4f29c73bb6 | ||
|
|
4f486ce66b | ||
|
|
693d687d3f | ||
|
|
0eb2acb00b | ||
|
|
f0ea21476a | ||
|
|
6ccaaacaf0 | ||
|
|
4d257e1a99 | ||
|
|
f8af4c8b72 | ||
|
|
a772400ffa | ||
|
|
2d434033e0 | ||
|
|
0152e8ce38 | ||
|
|
4c17c9c62a | ||
|
|
7901ff998d | ||
|
|
ed9c35a170 | ||
|
|
e1e8c167de | ||
|
|
25614263ba | ||
|
|
c83df1b677 | ||
|
|
729cf143e0 | ||
|
|
6e6f9a53a1 | ||
|
|
cb32c7505e | ||
|
|
a77c1d3202 | ||
|
|
038e70b0c6 | ||
|
|
90c64f4cf8 | ||
|
|
139a33d644 | ||
|
|
e322bdb289 | ||
|
|
181e576698 | ||
|
|
0abcf3d9c4 | ||
|
|
8e5ea001b1 | ||
|
|
c11f6082a6 | ||
|
|
3b3866feee | ||
|
|
9daef4e587 | ||
|
|
c6b4f97d19 | ||
|
|
6c1f1a02bb | ||
|
|
d5f431a1fd | ||
|
|
94a296d79c | ||
|
|
5f64d2a1db | ||
|
|
11577f6b0b | ||
|
|
a1739a1175 | ||
|
|
6d4bd11903 | ||
|
|
88c0028757 | ||
|
|
5d6d25c972 | ||
|
|
9c45ee05bb | ||
|
|
7ba2517334 | ||
|
|
d36549f80a | ||
|
|
345b66c77f | ||
|
|
4510041aa6 | ||
|
|
d0f6174fea | ||
|
|
2706b1641e | ||
|
|
e95b40a997 | ||
|
|
daf3fb0e2c | ||
|
|
6f5ea27e09 | ||
|
|
726cebaa9d | ||
|
|
07d20ba121 | ||
|
|
bc7a404629 | ||
|
|
f5c4ccf479 | ||
|
|
fb118a76a8 | ||
|
|
7ae5abfbeb | ||
|
|
199680d24d | ||
|
|
a9bbf18d9f | ||
|
|
65e47c882f | ||
|
|
4ce795186b | ||
|
|
4d289b92cc | ||
|
|
7b9f53e9db | ||
|
|
7ecd593f6b | ||
|
|
f439095c6e | ||
|
|
190eaa1e42 | ||
|
|
8704f81025 | ||
|
|
4e73ef0c3b | ||
|
|
aba5098e30 | ||
|
|
b59b84e904 | ||
|
|
ea22da6e7a | ||
|
|
2f2bc2a5e8 | ||
|
|
3f88cc1fb1 | ||
|
|
2f9d8e759d | ||
|
|
f40b579a78 | ||
|
|
f1eb2e15d4 | ||
|
|
8b0409d349 | ||
|
|
e07f32f131 | ||
|
|
ce1613ad7c | ||
|
|
9ef3fdbc49 | ||
|
|
8edcd41a8d | ||
|
|
6569ea1a20 | ||
|
|
1616ed7727 | ||
|
|
8f632a7c69 | ||
|
|
15e82e4811 | ||
|
|
31cd31826d | ||
|
|
d104ef73b7 | ||
|
|
9e90b8f22c | ||
|
|
4fd78ce1e0 | ||
|
|
cbf57d7b3c | ||
|
|
47148e3f7d | ||
|
|
4a90091095 | ||
|
|
baa2e92562 | ||
|
|
e56f284347 | ||
|
|
12eed23f63 | ||
|
|
03617b9165 | ||
|
|
e23e863e0f | ||
|
|
3114060a38 | ||
|
|
7e17f8bd6a | ||
|
|
a82d897478 | ||
|
|
1e5c3c5707 | ||
|
|
a88a8dae8e | ||
|
|
63ebfff4d3 | ||
|
|
b04957b57c | ||
|
|
670f979f97 | ||
|
|
0126bd849b | ||
|
|
6abb1e362d | ||
|
|
14ec3e505d | ||
|
|
19d8ea2742 | ||
|
|
06d488bb23 | ||
|
|
51a72b8479 | ||
|
|
00c6a4bce5 | ||
|
|
d058e2a6ed | ||
|
|
19f532d450 | ||
|
|
a87e99ad69 | ||
|
|
db0ce84aa5 | ||
|
|
bbe806a870 | ||
|
|
b8935b7761 | ||
|
|
a77769d45b | ||
|
|
a634f14f74 | ||
|
|
bb89ae3aca | ||
|
|
de8aa24de5 | ||
|
|
2776ec78b0 | ||
|
|
d4b566ceb8 | ||
|
|
35324cfa12 | ||
|
|
6c27a40f09 | ||
|
|
c272bb2f7c | ||
|
|
7fdd7547be | ||
|
|
9e26621d4b | ||
|
|
7bda635e03 | ||
|
|
e5c6ee599c | ||
|
|
55d59e5f2a | ||
|
|
3eaebbca93 | ||
|
|
853776ef2f | ||
|
|
05a9c0e264 | ||
|
|
fdce62f799 | ||
|
|
5bae6dd6f3 | ||
|
|
3ae8f393f4 | ||
|
|
4d17364142 | ||
|
|
0e0526e367 | ||
|
|
faf38c7e56 | ||
|
|
08e97aa9c8 | ||
|
|
8238c40ce9 | ||
|
|
ed6aa9f505 | ||
|
|
0ced14a56d | ||
|
|
bb82697819 | ||
|
|
cf284d76f0 | ||
|
|
6f19524e95 | ||
|
|
628726caae | ||
|
|
4f58d66972 | ||
|
|
2b108cdded | ||
|
|
580f56c869 | ||
|
|
777074ff79 | ||
|
|
d820051397 | ||
|
|
5b1dfb8bc9 | ||
|
|
ec539fc6a5 | ||
|
|
c02650826d | ||
|
|
9790eb1adc | ||
|
|
35d6c4af98 | ||
|
|
da251e00b3 | ||
|
|
cce425baf7 | ||
|
|
87c69d2fe4 | ||
|
|
589cb2f43e | ||
|
|
99d1588670 | ||
|
|
0789759b85 | ||
|
|
d1e7dead00 | ||
|
|
95a0271779 | ||
|
|
bddcfc512f | ||
|
|
6b69e67f71 | ||
|
|
fb153cc792 | ||
|
|
d3d9325081 | ||
|
|
405edc8bd3 | ||
|
|
1cd71d1742 | ||
|
|
acdbb5bb8d | ||
|
|
47592d53aa | ||
|
|
c4f1812cc9 | ||
|
|
5d488fcbfe | ||
|
|
0a6322103c | ||
|
|
571677b948 | ||
|
|
c1931a60e7 | ||
|
|
06d07e3a4c | ||
|
|
dccbd9279a | ||
|
|
9c72064883 | ||
|
|
8d7df8d164 | ||
|
|
7c747e5ccd | ||
|
|
4973424468 | ||
|
|
719aec8b9a | ||
|
|
5b875ab25d | ||
|
|
2e0823a7ae | ||
|
|
d29b17a211 | ||
|
|
9408c3c0b0 | ||
|
|
a19f2e3254 | ||
|
|
729c4ef1de | ||
|
|
975f7e868a | ||
|
|
dd6dac1392 | ||
|
|
299ba03b84 | ||
|
|
0d86181a58 | ||
|
|
a3aae0dd9e | ||
|
|
6afebc0e41 | ||
|
|
1f9900ba61 | ||
|
|
8d164fe2aa | ||
|
|
4bdc6ac59f | ||
|
|
9daebabe60 | ||
|
|
3377f91b62 | ||
|
|
4caafc7292 | ||
|
|
a6bf3f4cb2 | ||
|
|
8df429224b | ||
|
|
6f7b434c49 | ||
|
|
754a39def5 | ||
|
|
e7d11fab4b | ||
|
|
10ef3751d7 | ||
|
|
79cc85a265 | ||
|
|
2a610cfef4 | ||
|
|
18fd38fa08 | ||
|
|
a2244ab32d | ||
|
|
b608e326ef | ||
|
|
8c5524e455 | ||
|
|
f05c195751 | ||
|
|
1bd68ef261 | ||
|
|
2b6c64c98c | ||
|
|
c1d157dc42 | ||
|
|
65698f6a8f | ||
|
|
e5899e2f74 | ||
|
|
370b1f4d79 | ||
|
|
c9b8bf475b | ||
|
|
1a6b464331 | ||
|
|
96ae9a915f | ||
|
|
a8e7927cde | ||
|
|
46181eca7d | ||
|
|
c1f6dbfb2f | ||
|
|
7090db60bc | ||
|
|
08100357f7 | ||
|
|
b15f1f1830 | ||
|
|
4f50fcce2a | ||
|
|
6e4ff32cc5 | ||
|
|
981f46039f | ||
|
|
f44d1ccfeb | ||
|
|
212f00fce7 | ||
|
|
4f6938839a | ||
|
|
2bab005799 | ||
|
|
296357fe1b | ||
|
|
20b6ee70eb | ||
|
|
68d4daf7d9 | ||
|
|
87c75ebccd | ||
|
|
d36079c914 | ||
|
|
882c4b34a2 | ||
|
|
7d9b3464a8 | ||
|
|
74ce2cf4be | ||
|
|
7f6e5c6fff | ||
|
|
35ebb0e045 | ||
|
|
2a4c789ba9 | ||
|
|
4549104238 | ||
|
|
40a9792fef | ||
|
|
13b8abc310 | ||
|
|
ff56eb3a5d | ||
|
|
cd2b80e6c2 | ||
|
|
2d4453648f | ||
|
|
2f7e7b9823 | ||
|
|
dbdf38133e | ||
|
|
79002c1190 | ||
|
|
9fd889dc3e | ||
|
|
2aa8a438f2 | ||
|
|
e4a7eda968 | ||
|
|
e6ae92ea17 | ||
|
|
aa653af57f | ||
|
|
0f63e94861 | ||
|
|
1302b48b92 | ||
|
|
8cc8ef123b | ||
|
|
6edd0bb2ca | ||
|
|
ee054770c4 | ||
|
|
b4f8857da3 | ||
|
|
5521e34360 | ||
|
|
12792eece7 | ||
|
|
e8d92cbddd | ||
|
|
7f392cdb24 | ||
|
|
e51cd863fe | ||
|
|
40263348f9 | ||
|
|
188a99ca51 | ||
|
|
cd16d7ce03 | ||
|
|
f1455f15a3 | ||
|
|
6a1ac14447 | ||
|
|
1396004ccc | ||
|
|
e2b4f80ac2 | ||
|
|
5bfd507915 | ||
|
|
ebaabde8c6 | ||
|
|
f1992a58f8 | ||
|
|
1e6c36d877 | ||
|
|
3186d45e71 | ||
|
|
b103ada542 | ||
|
|
e7f8b56b65 | ||
|
|
96efe9c03b | ||
|
|
0e0be91aa3 | ||
|
|
11cdf1610e | ||
|
|
85faedfcbe | ||
|
|
40b131be13 | ||
|
|
b37195ad1f | ||
|
|
1a40b36193 | ||
|
|
39aaf63a4e | ||
|
|
e2c88f91af | ||
|
|
d3899a21a6 | ||
|
|
a1b2d222dd | ||
|
|
f068fb4ef3 | ||
|
|
b3c0095f07 | ||
|
|
36b8bb1b5b | ||
|
|
a84ecd1468 | ||
|
|
55476b175f | ||
|
|
5e506bfab0 | ||
|
|
c5feda8613 | ||
|
|
503eba46ce | ||
|
|
28394b96af | ||
|
|
f03b309bc0 | ||
|
|
1c60147e86 | ||
|
|
ad9e0f5db0 | ||
|
|
208a682152 | ||
|
|
f2a1023d8e | ||
|
|
8b1138c89f | ||
|
|
274ea107ff | ||
|
|
bd0c5f6030 | ||
|
|
94808d4326 | ||
|
|
000142c3e3 | ||
|
|
104e532731 | ||
|
|
6fa460dd2d | ||
|
|
f34c9131d9 | ||
|
|
1a089a0d67 | ||
|
|
115a6d0384 | ||
|
|
92298de507 | ||
|
|
1f94285040 | ||
|
|
8507a3d281 | ||
|
|
076a8264c2 | ||
|
|
c623d90453 | ||
|
|
039442c1d4 | ||
|
|
6602bdeed8 | ||
|
|
d3674a25e1 | ||
|
|
ea1b995a75 | ||
|
|
24acc0e8b0 | ||
|
|
4f9aaa927e | ||
|
|
af6807d30b | ||
|
|
1fe40f312e | ||
|
|
bca775a594 | ||
|
|
91765a2c4d | ||
|
|
4a6f8a7dc7 | ||
|
|
698917bf1c | ||
|
|
e9a6efc9c9 | ||
|
|
82ba9b96f4 | ||
|
|
b2fedd793c | ||
|
|
0628d54480 | ||
|
|
0afec1e3dd | ||
|
|
1ce9f1fccb | ||
|
|
0ec806f5fe | ||
|
|
8e79241cbe | ||
|
|
1042db7317 | ||
|
|
c64362f8ec | ||
|
|
3bc433a5f8 | ||
|
|
845a226410 | ||
|
|
c8a787d22c | ||
|
|
559e8fdcd2 | ||
|
|
0f704894f4 | ||
|
|
5e5bc1a9e3 | ||
|
|
c912762144 | ||
|
|
394f0deb1b | ||
|
|
55e32f6e8c | ||
|
|
0d65f76d46 | ||
|
|
119be5d45b | ||
|
|
cb8760a44d | ||
|
|
9b11d0b593 | ||
|
|
301317eca6 | ||
|
|
a6af0d99ce | ||
|
|
956d9aa1d8 | ||
|
|
8663ee697e | ||
|
|
c67550e531 | ||
|
|
265b5c4d1b | ||
|
|
4542322bb4 | ||
|
|
558fccbba7 | ||
|
|
b85b5fe47a | ||
|
|
6d9ceaa712 | ||
|
|
5e5e487e4c | ||
|
|
3e27bed4f7 | ||
|
|
bdd12a3396 | ||
|
|
bfad636369 | ||
|
|
00a8df6f8f | ||
|
|
a1b81d9475 | ||
|
|
140fa111c4 | ||
|
|
ad32b6108e | ||
|
|
d3af4c4b8b | ||
|
|
22fe32645b | ||
|
|
71a8d19b7d | ||
|
|
3ed622afbd | ||
|
|
a7e6137408 | ||
|
|
581a9731d8 | ||
|
|
732b98d1ae | ||
|
|
fe27b81703 | ||
|
|
66c30b9e1d | ||
|
|
9db8db256a | ||
|
|
e785891fb1 | ||
|
|
f8fbd26b57 | ||
|
|
fa3a637b72 | ||
|
|
550ab5009b | ||
|
|
cabbb72c0f | ||
|
|
0ee70df312 |
@@ -168,7 +168,7 @@ class PhySim:
|
||||
|
||||
mySSH.close()
|
||||
#check build status and update HTML object
|
||||
lHTML = html.HTMLManagement()
|
||||
lHTML = cls_oai_html.HTMLManagement()
|
||||
lHTML=self.__CheckBuild_PhySim(htmlObj,constObj)
|
||||
return lHTML
|
||||
|
||||
@@ -186,6 +186,6 @@ class PhySim:
|
||||
mySSH.command(self.__workSpacePath+'ran_build/build/ldpctest ' + self.runargs + ' >> '+self.__runLogFile, '\$', 30)
|
||||
mySSH.close()
|
||||
#return updated HTML to main
|
||||
lHTML = html.HTMLManagement()
|
||||
lHTML = cls_oai_html.HTMLManagement()
|
||||
lHTML=self.__CheckResults_PhySim(htmlObj,constObj,testcase_id)
|
||||
return lHTML
|
||||
|
||||
@@ -21,8 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
@@ -32,7 +32,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
pdcch_ConfigSIB1 = (
|
||||
{
|
||||
|
||||
@@ -21,7 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -32,7 +32,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -21,7 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
|
||||
@@ -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 = (
|
||||
|
||||
@@ -36,7 +36,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -37,8 +37,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -38,8 +38,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -21,7 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
|
||||
@@ -21,7 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
|
||||
@@ -19,8 +19,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pusch_AntennaPorts = 2;
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
do_SRS = 1;
|
||||
|
||||
@@ -37,8 +37,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
do_SRS = 1;
|
||||
|
||||
@@ -37,7 +37,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pusch_AntennaPorts = 2;
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
do_SRS = 1;
|
||||
|
||||
@@ -37,7 +37,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
#pusch_TargetSNRx10 = 200;
|
||||
#pucch_TargetSNRx10 = 200;
|
||||
ul_prbblacklist = "51,52,53,54"
|
||||
|
||||
@@ -37,8 +37,7 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts_N1 = 2;
|
||||
pdsch_AntennaPorts_XP = 2;
|
||||
pusch_AntennaPorts = 2;
|
||||
#pusch_TargetSNRx10 = 200;
|
||||
#pucch_TargetSNRx10 = 200;
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
|
||||
@@ -20,7 +20,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
|
||||
@@ -32,7 +32,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
pdcch_ConfigSIB1 = (
|
||||
|
||||
@@ -32,9 +32,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
pusch_AntennaPorts = 1;
|
||||
sib1_tda = 15;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,8 +15,9 @@ Ref :
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
PUSCH decoding : 180.0
|
||||
DL & UL scheduling timing stats : 37.0
|
||||
#PUSCH decoding : 180.0
|
||||
PUSCH decoding : 240.0
|
||||
DL & UL scheduling timing : 37.0
|
||||
UL Indication : 38.0
|
||||
Threshold :
|
||||
feprx : 1.25
|
||||
@@ -28,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
|
||||
|
||||
@@ -383,17 +383,19 @@ class RANManagement():
|
||||
|
||||
|
||||
# If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB
|
||||
localEpcIpAddr = EPC.IPAddress
|
||||
localEpcUserName = EPC.UserName
|
||||
localEpcPassword = EPC.Password
|
||||
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
|
||||
eth_interface = 'any'
|
||||
fltr = 'sctp'
|
||||
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
|
||||
self.epcPcapFile = 'enb_' + self.testCase_id + '_s1log.pcap'
|
||||
mySSH.command('echo ' + localEpcPassword + ' | sudo -S rm -f /tmp/' + self.epcPcapFile , '\$', 5)
|
||||
mySSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + self.epcPcapFile + ' > /tmp/tshark.log 2>&1 &', localEpcUserName, 5)
|
||||
mySSH.close()
|
||||
if EPC.IPAddress != "none":
|
||||
localEpcIpAddr = EPC.IPAddress
|
||||
localEpcUserName = EPC.UserName
|
||||
localEpcPassword = EPC.Password
|
||||
mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword)
|
||||
eth_interface = 'any'
|
||||
fltr = 'sctp'
|
||||
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m')
|
||||
self.epcPcapFile = 'enb_' + self.testCase_id + '_s1log.pcap'
|
||||
mySSH.command('echo ' + localEpcPassword + ' | sudo -S rm -f /tmp/' + self.epcPcapFile , '\$', 5)
|
||||
mySSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + self.epcPcapFile + ' > /tmp/tshark.log 2>&1 &', localEpcUserName, 5)
|
||||
mySSH.close()
|
||||
|
||||
mySSH.open(lIpAddr, lUserName, lPassWord)
|
||||
mySSH.command('cd ' + lSourcePath, '\$', 5)
|
||||
# Initialize_eNB_args usually start with -O and followed by the location in repository
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<htmlTabRef>gNB-PHY-Test</htmlTabRef>
|
||||
<htmlTabName>Run-gNB-PHY-Test</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<repeatCount>3</repeatCount>
|
||||
<repeatCount>1</repeatCount>
|
||||
<TestCaseRequestedList>
|
||||
090101 000001 090109
|
||||
</TestCaseRequestedList>
|
||||
@@ -33,7 +33,7 @@
|
||||
<testCase id="090101">
|
||||
<class>Initialize_eNB</class>
|
||||
<desc>Initialize gNB USRP</desc>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
|
||||
<air_interface>NR</air_interface>
|
||||
<USRP_IPAddress>192.168.20.2</USRP_IPAddress>
|
||||
</testCase>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
@@ -1384,8 +1406,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 +1422,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 +1568,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 +1595,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 +1642,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
|
||||
@@ -1925,6 +1952,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
|
||||
@@ -2842,6 +2870,7 @@ target_link_libraries(ldpctest
|
||||
add_executable(nr_dlschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -2865,6 +2894,7 @@ target_link_libraries(nr_pbchsim
|
||||
add_executable(nr_pucchsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -2909,6 +2939,7 @@ target_link_libraries(nr_prachsim
|
||||
add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
@@ -3150,3 +3181,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)
|
||||
|
||||
@@ -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>
|
||||
@@ -1184,9 +1190,10 @@
|
||||
|
||||
<testCase id="015108">
|
||||
<class>execution</class>
|
||||
<desc>nr_ulschsim Test cases. (Test1: 106 PRB),
|
||||
(Test2: 217 PRB),
|
||||
(Test3: 273 PRB)</desc>
|
||||
<desc>nr_ulschsim Test cases. (Test1: 106 PRBs),
|
||||
(Test2: 217 PRBs),
|
||||
(Test3: 273 PRBs)
|
||||
(Test4: 106 PRBs 4-layer MIMO)</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>
|
||||
@@ -1195,8 +1202,9 @@
|
||||
<main_exec> $OPENAIR_DIR/targets/bin/nr_ulschsim.Rel15</main_exec>
|
||||
<main_exec_args>-R 106 -m9 -s13 -n100
|
||||
-R 217 -m15 -s15 -n100
|
||||
-R 273 -m19 -s20 -n100</main_exec_args>
|
||||
<tags>nr_ulschsim.test1 nr_ulschsim.test2 nr_ulschsim.test3</tags>
|
||||
-R 273 -m19 -s20 -n100
|
||||
-R 106 -m9 -s13 -n100 -y4 -z4 -W4</main_exec_args>
|
||||
<tags>nr_ulschsim.test1 nr_ulschsim.test2 nr_ulschsim.test3 nr_ulschsim.test4</tags>
|
||||
<search_expr_true>PUSCH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
@@ -1304,7 +1312,14 @@
|
||||
(Test12: SC-FDMA, 216 PRBs),
|
||||
(Test13: SC-FDMA, 273 PRBs),
|
||||
(Test14: SC-FDMA, 3 DMRS),
|
||||
(Test15: MCS 16 50 PRBs 2 RX_Antenna)</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>
|
||||
@@ -1316,18 +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 -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 -m16 -s10 -z2</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</tags>
|
||||
-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
|
||||
-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>
|
||||
@@ -1338,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>
|
||||
@@ -1351,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>
|
||||
|
||||
@@ -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
|
||||
@@ -436,6 +439,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 +452,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 +632,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 +722,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 +738,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
|
||||
|
||||
@@ -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 ;;
|
||||
@@ -623,7 +624,6 @@ check_install_additional_tools (){
|
||||
android-tools-adb \
|
||||
wvdial \
|
||||
sshpass \
|
||||
nscd \
|
||||
bc \
|
||||
ntp"
|
||||
elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
|
||||
@@ -648,7 +648,6 @@ check_install_additional_tools (){
|
||||
wvdial \
|
||||
numpy \
|
||||
sshpass \
|
||||
nscd \
|
||||
python2-paramiko \
|
||||
python-pyroute2 \
|
||||
python-netifaces \
|
||||
@@ -676,7 +675,6 @@ check_install_additional_tools (){
|
||||
wvdial \
|
||||
python-numpy \
|
||||
sshpass \
|
||||
nscd \
|
||||
python-paramiko \
|
||||
python-pyroute2 \
|
||||
python-netifaces \
|
||||
|
||||
@@ -9,7 +9,10 @@ All logging facility parameters are defined in the log_config section. Some para
|
||||
|:---:|:---:|:---:|:----|
|
||||
| `global_log_level` | `pre-defined string of char` | `info` | Allows printing of messages up to the specified level. Available levels, from lower to higher are `error`,`warn`,`analysis`,`info`,`debug`,`trace` |
|
||||
| `global_log_online` | `boolean` | 1 (=true) | If false, all console messages are discarded, whatever their level |
|
||||
| `global_log_options` | `list of pre-defined string of char` | | 5 options can be specified to trigger the information added in the header of the message: `nocolor`, disable color usage in log messages, usefull when redirecting logs to a file, where escape sequences used for color selection can be annoying, `level`, add a one letter level id in the message header (T,D,I,A,W,E for trace, debug, info, analysis, warning, error),`thread`, add the thread name in the message header, `thread_id`, adds the thread ID in the message header, `function`, adds the function name, `line_num`, adds the line number, `time` adds the time since process starts|
|
||||
| `global_log_options` | `list of pre-defined string of char` | | 8 options can be specified to trigger the information added in the header of the message: `nocolor`, disable color usage in log messages, usefull when redirecting logs to a file, where escape sequences used for color selection can be annoying, `level`, add a one letter level id in the message header (T,D,I,A,W,E for trace, debug, info, analysis, warning, error),`thread`, add the thread name in the message header, `thread_id`, adds the thread ID in the message header, `function`, adds the function name, `line_num`, adds the line number, `time` adds the time since process starts, `json` for formatting log lines as json.|
|
||||
| `global_log_rotation_time` | `uint_val` | 0 (=disabled) | Set the maximum elapsed time in seconds for triggering file rotation. |
|
||||
| `global_log_rotation_size` | `uint_val` | 0 (=disabled) | Set the maximum log size in MB for triggering logfile rotation. |
|
||||
|
||||
|
||||
### Component specific parameters
|
||||
| name | type | default | description |
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
#include "common/config/config_userapi.h"
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <errno.h>
|
||||
// main log variables
|
||||
|
||||
log_mem_cnt_t log_mem_d[2];
|
||||
@@ -73,14 +74,15 @@ mapping log_level_names[] = {
|
||||
};
|
||||
|
||||
mapping log_options[] = {
|
||||
{"nocolor", FLAG_NOCOLOR },
|
||||
{"level", FLAG_LEVEL },
|
||||
{"thread", FLAG_THREAD },
|
||||
{"line_num", FLAG_FILE_LINE },
|
||||
{"function", FLAG_FUNCT},
|
||||
{"time", FLAG_TIME},
|
||||
{"nocolor" , FLAG_NOCOLOR },
|
||||
{"level" , FLAG_LEVEL },
|
||||
{"thread" , FLAG_THREAD },
|
||||
{"line_num" , FLAG_FILE_LINE},
|
||||
{"function" , FLAG_FUNCT },
|
||||
{"time" , FLAG_TIME },
|
||||
{"thread_id", FLAG_THREAD_ID},
|
||||
{NULL,-1}
|
||||
{"json" , FLAG_JSON },
|
||||
{NULL , -1 }
|
||||
};
|
||||
|
||||
|
||||
@@ -89,7 +91,135 @@ mapping log_maskmap[] = LOG_MASKMAP_INIT;
|
||||
char *log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, LOG_GREEN, "", LOG_BLUE, LOG_CYBL}; /*!< \brief Optional start-format strings for highlighting */
|
||||
char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
||||
static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format,va_list args);
|
||||
static void log_rotate_setconf(unsigned int rotation_size, unsigned int time_rotation_frequency);
|
||||
static void log_rotate_file(log_component_t *c);
|
||||
static bool log_should_we_rotate(const log_component_t *c);
|
||||
/**
|
||||
* Formatting function that dumps into LOGBUFFER a line terminated message in json format. Multilines inputs are not handled.
|
||||
* The function will eat the ending '\n' from the input message data in case it is present.
|
||||
* The output includes the following fields:
|
||||
* - ThreadName: (optional)
|
||||
* - File:(optional)
|
||||
* - Func:(optional)
|
||||
* - Line:(optional)
|
||||
* - Date:(optional)
|
||||
* - ThreadId: (optional)
|
||||
* - ServiceName:(optional) name of the component generating the log, present if log level is less that OAILOG_TRACE
|
||||
* - Data: content of the log
|
||||
* @param[in] flag variable containing enablement of all the optional parameters. Possible values are expressed in log.h
|
||||
* @param[in] data content of the log
|
||||
*@return boolean value. true: LOGBUFFER contains the formatted string, false: error
|
||||
*/
|
||||
static bool
|
||||
log_formatter_json( char *logbuffer,
|
||||
size_t logbuffer_size,
|
||||
int flag,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *component,
|
||||
char level,
|
||||
const char *dataformat,
|
||||
va_list data)
|
||||
{
|
||||
if (logbuffer_size < 15)
|
||||
return false;
|
||||
|
||||
const char *endp = logbuffer + logbuffer_size - 15;
|
||||
char *begp = logbuffer;
|
||||
|
||||
*begp = '{';
|
||||
begp += 1;
|
||||
|
||||
if (level < OAILOG_TRACE) {
|
||||
if (flag & FLAG_THREAD) {
|
||||
char threadname[16]; // Max 16 chars as per man of pthread_getname_np()
|
||||
if (pthread_getname_np(pthread_self(), threadname, sizeof(threadname)) != 0)
|
||||
strcpy(threadname, "???");
|
||||
nprinted = snprintf(begp, avail, "ThreadName: \"%s\", ", threadname);
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
if (flag & FLAG_FILE_LINE)
|
||||
{
|
||||
nprinted = snprintf(begp, avail, "File: \"(%s)\", ", file);
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
if (flag & FLAG_FUNCT)
|
||||
{
|
||||
nprinted = snprintf(begp, avail, "Func: \"%s\", ", func);
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
if (flag & FLAG_FILE_LINE)
|
||||
{
|
||||
nprinted = snprintf(begp, avail, "Line: \"%d\", ", line);
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
|
||||
if (flag & FLAG_TIME)
|
||||
{
|
||||
struct timespec t;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &t) == -1)
|
||||
return false;
|
||||
nprinted = snprintf(begp, avail, "Date: \"%lu.%06lu\", ", t.tv_sec, t.tv_nsec / 1000);
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
if (flag & FLAG_THREAD_ID)
|
||||
{
|
||||
nprinted = snprintf(begp, avail, "ThreadId: \"%08lx\", ", syscall(__NR_gettid));
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
}
|
||||
nprinted = snprintf(begp, avail, "ServiceName: \"%s\", Data: \"", component);
|
||||
|
||||
} else {
|
||||
nprinted = snprintf(begp, avail, "Data: \"%s", "");
|
||||
}
|
||||
|
||||
if ((nprinted < 0) || ((size_t) nprinted > avail))
|
||||
return false;
|
||||
|
||||
avail -= nprinted;
|
||||
begp += nprinted;
|
||||
nprinted = vsnprintf(begp, avail, dataformat, data);
|
||||
|
||||
if (nprinted < 0)
|
||||
return false;
|
||||
|
||||
if ((size_t) nprinted > avail) {
|
||||
begp += avail - 1; // eating the '\0'
|
||||
|
||||
if (memcmp(begp-1, "\n", 1)==0)
|
||||
begp--;
|
||||
|
||||
return (snprintf(begp, 15, "%s", " (...trunc)\"}\n") < 0) ? false : true;
|
||||
}
|
||||
|
||||
begp += nprinted;
|
||||
|
||||
if (memcmp(begp-1, "\n", 1)==0)
|
||||
begp--;
|
||||
|
||||
avail -= nprinted;
|
||||
strcpy(begp, "\"}\n"); // no worries, we left room for 15 bytes; see at the beginning of this function
|
||||
return true;
|
||||
}
|
||||
|
||||
int write_file_matlab(const char *fname,
|
||||
const char *vname,
|
||||
@@ -266,21 +396,34 @@ int write_file_matlab(const char *fname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get log parameters from configuration file */
|
||||
void log_getconfig(log_t *g_log)
|
||||
/**
|
||||
* Get logging parameters from the configuration file and update 'g_log' structure with those values handling defaults.
|
||||
* Priority is given to global parameters.
|
||||
*
|
||||
* @return 0 success, !=0 failure
|
||||
*/
|
||||
static int
|
||||
log_getconfig(log_t *g_log)
|
||||
{
|
||||
char *gloglevel = NULL;
|
||||
int consolelog = 0;
|
||||
unsigned int rotationsize, rotationtime;
|
||||
paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC;
|
||||
paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS];
|
||||
paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS];
|
||||
paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)];
|
||||
paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)];
|
||||
/*
|
||||
* Retrieve values for parameters "global_log_level", "global_log_online", "global_log_options", "global_log_rotation_size", "global_log_rotation_time"
|
||||
* and put them in local variables respectively: 'gloglevel', 'consolelog', 'logparams_defaults[LOG_OPTIONS_IDX].strlistptr', 'rotationsize', 'rotationtime'.
|
||||
* It they are not present, use defaults. This is all specified in macro LOG_GLOBALPARAMS_DESC.
|
||||
* WARN: it basically silently discards the following option: 'global_log_infile'.
|
||||
*/
|
||||
int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX);
|
||||
|
||||
if (ret <0) {
|
||||
fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed");
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set LOG display options (enable/disable color, thread name, level ) */
|
||||
@@ -291,16 +434,20 @@ void log_getconfig(log_t *g_log)
|
||||
break;
|
||||
} else if (log_options[j+1].name == NULL) {
|
||||
fprintf(stderr,"Unknown log option: %s\n",logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i]);
|
||||
exit(-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* build the parameter array for setting per component log level and infile options */
|
||||
log_rotate_setconf(rotationsize, rotationtime);
|
||||
/*
|
||||
* Handle per component parameters level and sink file (%s_log_level" and "%s_log_infile" parameters).
|
||||
*/
|
||||
memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||
memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS);
|
||||
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
|
||||
// handle corner cases of unregistered log_components
|
||||
if(g_log->log_component[i].name == NULL) {
|
||||
g_log->log_component[i].name = malloc(16);
|
||||
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
|
||||
@@ -364,7 +511,7 @@ void log_getconfig(log_t *g_log)
|
||||
config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX);
|
||||
|
||||
if (config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX) > 0)
|
||||
exit(1);
|
||||
return 1;
|
||||
|
||||
/* set the debug mask according to the debug parameters values */
|
||||
for (int i=0; log_maskmap[i].name != NULL ; i++) {
|
||||
@@ -377,6 +524,7 @@ void log_getconfig(log_t *g_log)
|
||||
|
||||
/* log globally enabled/disabled */
|
||||
set_glog_onlinelog(consolelog);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int register_log_component(char *name,
|
||||
@@ -501,7 +649,8 @@ int logInit (void)
|
||||
g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name
|
||||
|
||||
g_log->filelog_name = "/tmp/openair.log";
|
||||
log_getconfig(g_log);
|
||||
if (log_getconfig(g_log))
|
||||
return 1;
|
||||
|
||||
// set all unused component items to 0, they are for non predefined components
|
||||
for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
@@ -629,7 +778,8 @@ void log_dump(int component,
|
||||
break;
|
||||
}
|
||||
|
||||
if (wbuf != NULL) {
|
||||
if (wbuf != NULL)
|
||||
{
|
||||
va_start(args, format);
|
||||
int pos=log_header(c, wbuf,MAX_LOG_TOTAL,"noFile","noFunc",0, OAILOG_INFO);
|
||||
pos+=vsprintf(wbuf+pos,format, args);
|
||||
@@ -674,11 +824,14 @@ int set_log(int component,
|
||||
|
||||
|
||||
|
||||
void set_glog(int level)
|
||||
int set_glog(int level)
|
||||
{
|
||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||
set_log(c, level);
|
||||
if (set_log(c, level))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_glog_onlinelog(int enable)
|
||||
@@ -694,17 +847,26 @@ void set_glog_onlinelog(int enable)
|
||||
}
|
||||
}
|
||||
}
|
||||
void set_glog_filelog(int enable)
|
||||
int set_glog_filelog(int enable)
|
||||
{
|
||||
static FILE *fptr;
|
||||
|
||||
if ( enable ) {
|
||||
static FILE *fptr;
|
||||
if ( enable ) {
|
||||
fptr = fopen(g_log->filelog_name,"w");
|
||||
|
||||
if (fptr == NULL) {
|
||||
printf ("Failure opening log file %s: %s\n", g_log->filelog_name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_log->global_logfile = 1;
|
||||
g_log->global_logfilep=fptr;
|
||||
|
||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||
close_component_filelog(c);
|
||||
g_log->log_component[c].stream = fptr;
|
||||
g_log->log_component[c].filelog = 1;
|
||||
if (!g_log->log_component[c].filelog) {// components that have been specified to have a different file sink via configuration will be spared.
|
||||
close_component_filelog(c);
|
||||
g_log->log_component[c].stream = fptr;
|
||||
g_log->log_component[c].filelog = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) {
|
||||
@@ -717,18 +879,32 @@ void set_glog_filelog(int enable)
|
||||
g_log->log_component[c].stream = stdout;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_component_filelog(int comp)
|
||||
{
|
||||
int set_component_filelog(int comp) {
|
||||
if (g_log->log_component[comp].filelog_name == NULL) {
|
||||
printf ("LOG API programming error for component %s: name of logfile is NULL. Probably an unregistered log_components. Discarding set_component_filelog() settings\n",
|
||||
g_log->log_component[comp].name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) {
|
||||
g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w");
|
||||
|
||||
if (g_log->log_component[comp].stream == NULL) {
|
||||
printf ("Failure opening log file %s for component %s: %s\n", g_log->log_component[comp].filelog_name, g_log->log_component[comp].name, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
g_log->log_component[comp].vprint = vfprintf;
|
||||
g_log->log_component[comp].print = fprintf;
|
||||
g_log->log_component[comp].filelog = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void close_component_filelog(int comp)
|
||||
{
|
||||
g_log->log_component[comp].filelog = 0;
|
||||
@@ -800,10 +976,12 @@ void logClean (void)
|
||||
int i;
|
||||
|
||||
if(isLogInitDone()) {
|
||||
LOG_UI(PHY,"\n");
|
||||
|
||||
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
close_component_filelog(i);
|
||||
if (!g_log->global_logfile) {
|
||||
for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++)
|
||||
close_component_filelog(i);
|
||||
} else {
|
||||
fclose(g_log->global_logfilep);
|
||||
g_log->global_logfilep = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -858,7 +1036,7 @@ const char logmem_log_level[NUM_LOG_LEVEL] = {
|
||||
[OAILOG_TRACE] = 'T',
|
||||
};
|
||||
|
||||
static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format,va_list args)
|
||||
static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format, va_list args)
|
||||
{
|
||||
//logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args)
|
||||
int len = 0;
|
||||
@@ -869,9 +1047,39 @@ static void log_output_memory(log_component_t *c, const char *file, const char *
|
||||
*/
|
||||
char log_buffer[MAX_LOG_TOTAL];
|
||||
|
||||
// make sure that for log trace the extra info is only printed once, reset when the level changes
|
||||
if (level < OAILOG_TRACE) {
|
||||
int n = log_header(c, log_buffer+len, MAX_LOG_TOTAL, file, func, line, level);
|
||||
if (g_log->flag & FLAG_JSON)
|
||||
{
|
||||
if (!((g_log->flag | c->flag) & FLAG_NOCOLOR))
|
||||
len = snprintf(log_buffer, MAX_LOG_TOTAL, "%s", log_level_highlight_start[level]);
|
||||
|
||||
|
||||
if (log_formatter_json( log_buffer + len,
|
||||
MAX_LOG_TOTAL - len,
|
||||
g_log->flag | c->flag,
|
||||
file,
|
||||
func,
|
||||
line,
|
||||
c->name,
|
||||
g_log->level2string[level],
|
||||
format,
|
||||
args) == false)
|
||||
return;
|
||||
|
||||
len = strlen(log_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure that for log trace the extra info is only printed once, reset when the level changes
|
||||
if (level < OAILOG_TRACE) {
|
||||
int n = log_header(c, log_buffer+len, MAX_LOG_TOTAL, file, func, line, level);
|
||||
if (n > 0) {
|
||||
len += n;
|
||||
if (len > MAX_LOG_TOTAL) {
|
||||
len = MAX_LOG_TOTAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
int n = vsnprintf(log_buffer+len, MAX_LOG_TOTAL-len, format, args);
|
||||
if (n > 0) {
|
||||
len += n;
|
||||
if (len > MAX_LOG_TOTAL) {
|
||||
@@ -879,13 +1087,7 @@ static void log_output_memory(log_component_t *c, const char *file, const char *
|
||||
}
|
||||
}
|
||||
}
|
||||
int n = vsnprintf(log_buffer+len, MAX_LOG_TOTAL-len, format, args);
|
||||
if (n > 0) {
|
||||
len += n;
|
||||
if (len > MAX_LOG_TOTAL) {
|
||||
len = MAX_LOG_TOTAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !((g_log->flag | c->flag) & FLAG_NOCOLOR) ) {
|
||||
int n = snprintf(log_buffer+len, MAX_LOG_TOTAL-len, "%s", log_level_highlight_end[level]);
|
||||
if (n > 0) {
|
||||
@@ -932,6 +1134,12 @@ static void log_output_memory(log_component_t *c, const char *file, const char *
|
||||
}
|
||||
}else{
|
||||
AssertFatal(len >= 0 && len <= MAX_LOG_TOTAL, "Bad len %d\n", len);
|
||||
|
||||
if (c->filelog && log_should_we_rotate(c)) {
|
||||
log_rotate_file(c);
|
||||
g_log->rotation_start_time = time(NULL);
|
||||
}
|
||||
|
||||
if (write(fileno(c->stream), log_buffer, len)) {};
|
||||
}
|
||||
}
|
||||
@@ -1017,6 +1225,137 @@ void close_log_mem(void){
|
||||
}
|
||||
}
|
||||
}
|
||||
/*--- LOG ROTATION functionality ----*/
|
||||
|
||||
/*
|
||||
* logic: when dumping to a file (see function write() in log_output_memory(), check for the actual size of the file against the configured value
|
||||
* if it is above the limit, call log_rotate_file()). Similar for elapsed time just if you rotate, you set the next rotation time on g->log->rotation_start_time
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set in the global g_log structure the values for rotation algorithm that will be applied to all log files.
|
||||
* This function should be called in logInit() after getting the options set in configuration file.
|
||||
*
|
||||
* @param rotation_size rotation_size in bytes
|
||||
* @param time_rotation_frequency in seconds
|
||||
*/
|
||||
static void
|
||||
log_rotate_setconf(unsigned int rotation_size, unsigned int time_rotation_frequency) {
|
||||
g_log->rotation_size = rotation_size * (1 << 20); // 1 MB = 1<<20
|
||||
g_log->rotation_time = time_rotation_frequency;
|
||||
g_log->rotation_start_time = time(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* assess rotation needs
|
||||
*
|
||||
* The need for rotation is assessed against time or size of the file, whichever comes first
|
||||
*
|
||||
* @return: true (to rotate), false(not to rotate)
|
||||
*/
|
||||
static bool
|
||||
log_should_we_rotate(const log_component_t *c) {
|
||||
/*
|
||||
* XXX-TODO: compute the performance impact on assessing the need for rotation (of course, computation has to be
|
||||
* done without the log_rotate_file()). If results are not good, optimize the algo (i.e. using a counter for time
|
||||
* or for size)
|
||||
*/
|
||||
if (g_log->rotation_size != 0) {
|
||||
struct stat filestat;
|
||||
(void)fstat(fileno(c->stream), &filestat);
|
||||
|
||||
if (filestat.st_size > g_log->rotation_size)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((g_log->rotation_time !=0) &&
|
||||
((time(NULL) - g_log->rotation_start_time) > g_log->rotation_time))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
#define LOG_MAXHISTORY_FNUM 5
|
||||
/**
|
||||
* Rotate the file referenced by log component c.
|
||||
* A pattern of historic files will be created following the example {tst.log-> tst-1.log->tst-2.log->...tst-LOG_MAXHISTORY_FNUM.log -> discard} to avoid
|
||||
* filling filesystem.
|
||||
*
|
||||
* @param c component that has its logging file to be rotated.
|
||||
*/
|
||||
static void
|
||||
log_rotate_file(log_component_t *c) {
|
||||
/*
|
||||
* Approach: starting from the latest file on the harddisk, rename the old one into the newone copying its content (i.e. latest is tst-3.log-> tst-4.log if
|
||||
* log_maxfilenum has not been reached), then close the stream associated (with fclose()) and open the file description of the new file copying the pointer
|
||||
* in glog struct and all/or in the (eventual) components
|
||||
* XXX: some parts of the code could be unified and make this function more compact
|
||||
*/
|
||||
char fname[1024], newfname[1024], basename[1000];
|
||||
|
||||
if ((g_log->global_logfile) &&(!c->filelog)) {
|
||||
// Update only global log file STREAM and all log components STREAM pointers given that log filename does not change.
|
||||
// WARN: g_log->filelog_name is a const char * even if not declared like that in, while c->filelog_name is malloced memory.
|
||||
char *basenamep = strrchr(g_log->filelog_name, '.');
|
||||
memcpy(basename, g_log->filelog_name, basenamep - g_log->filelog_name);
|
||||
memset(basename + (basenamep - g_log->filelog_name), '\0', 1);
|
||||
|
||||
for (int i=(LOG_MAXHISTORY_FNUM -1); i>0; i--) {
|
||||
(void)snprintf(fname, sizeof(fname), "%s-%d.log", basename, i);
|
||||
(void)snprintf(newfname, sizeof(newfname), "%s-%d.log", basename, i+1);
|
||||
struct stat stats;
|
||||
|
||||
if (stat(fname, &stats) == 0) {
|
||||
// file exists and it is the last file we could have. Discard it.
|
||||
if (i == (LOG_MAXHISTORY_FNUM -1))
|
||||
unlink(fname);
|
||||
else
|
||||
(void)rename(fname, newfname);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case of current global log file. Note that we do not handle below the case LOG_MAXHISTORY_FNUM=1 as will never
|
||||
* happen because this value is hardcoded for now.
|
||||
*/
|
||||
snprintf(newfname, sizeof(fname), "%s-1.log", basename);
|
||||
strncpy(fname, g_log->filelog_name, sizeof(fname) - 1);
|
||||
fname[sizeof(fname) - 1] = '\0';
|
||||
fclose(g_log->global_logfilep);
|
||||
rename(fname, newfname);
|
||||
g_log->global_logfilep = fopen(g_log->filelog_name, "w");
|
||||
|
||||
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++)
|
||||
g_log->log_component[i].stream = g_log->global_logfilep;
|
||||
} else {
|
||||
// per component logging
|
||||
char *basenamep = strrchr(c->filelog_name, '.');
|
||||
memcpy(basename, c->filelog_name, basenamep - c->filelog_name);
|
||||
memset(basename +(basenamep - c->filelog_name), '\0', 1);
|
||||
|
||||
for (int i=(LOG_MAXHISTORY_FNUM -1); i>0; i--) {
|
||||
snprintf(fname, sizeof(fname), "%s-%d.log", basename, i);
|
||||
snprintf(newfname, sizeof(newfname), "%s-%d.log", basename, i+1);
|
||||
struct stat stats;
|
||||
|
||||
if (stat(fname, &stats) == 0) {
|
||||
// file exists and it is the last file we could have. Discard it.
|
||||
if (i == (LOG_MAXHISTORY_FNUM -1))
|
||||
unlink(c->filelog_name);
|
||||
else
|
||||
rename(fname, newfname);
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(newfname, sizeof(fname), "%s-1.log", basename);
|
||||
strncpy(fname, c->filelog_name, sizeof(fname) -1);
|
||||
fname[sizeof(fname) - 1] = '\0';
|
||||
fclose(c->stream);
|
||||
rename(fname, newfname);
|
||||
c->stream = fopen(c->filelog_name, "w");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LOG_TEST
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ extern "C" {
|
||||
#define FLAG_FILE_LINE 0x0040
|
||||
#define FLAG_TIME 0x0100
|
||||
#define FLAG_THREAD_ID 0x0200
|
||||
#define FLAG_JSON 0x0400 /*!< \brief: activate formatting in json*/
|
||||
#define FLAG_INITIALIZED 0x8000
|
||||
|
||||
#define SET_LOG_OPTION(O) g_log->flag = (g_log->flag | O)
|
||||
@@ -267,7 +268,7 @@ typedef struct {
|
||||
int level;
|
||||
int savedlevel;
|
||||
int flag;
|
||||
int filelog;
|
||||
int filelog; // flag set to 1 when using a sink of type file, stdout if set to 0
|
||||
char *filelog_name;
|
||||
FILE *stream;
|
||||
log_vprint_func_t vprint;
|
||||
@@ -284,6 +285,11 @@ typedef struct {
|
||||
char *filelog_name;
|
||||
uint64_t debug_mask;
|
||||
uint64_t dump_mask;
|
||||
unsigned char global_logfile;
|
||||
FILE *global_logfilep;
|
||||
off_t rotation_size;// in bytes, 0 means disabled
|
||||
unsigned int rotation_time;// in seconds. 0 means disabled
|
||||
time_t rotation_start_time; // timestamp in seconds since Unix-Epoch
|
||||
} log_t;
|
||||
|
||||
|
||||
@@ -302,27 +308,44 @@ extern "C" {
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
# include "log_if.h"
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int logInit (void);
|
||||
void logTerm (void);
|
||||
int isLogInitDone (void);
|
||||
int register_log_component(char *name, char *fext,int compidx);
|
||||
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||
void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args );
|
||||
void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... );
|
||||
/**
|
||||
* set log level for log component and check also if the stream associated is open. If it is not, give priority to file sink
|
||||
* type of log stream
|
||||
* @return: 0(success), !=-0(failure)
|
||||
*/
|
||||
int set_log(int component, int level);
|
||||
void set_glog(int level);
|
||||
|
||||
/*
|
||||
* @return: 0(success), !=-0(failure)
|
||||
*/
|
||||
int set_glog(int level);
|
||||
void set_glog_onlinelog(int enable);
|
||||
void set_glog_filelog(int enable);
|
||||
void set_component_filelog(int comp);
|
||||
/**
|
||||
* Set sink logging type globally. Sinks are of 2 types: stdout or file. You choose among them using ENABLE parameter
|
||||
*
|
||||
* @param enable if param is != 0, all the logs will be redirected to a global file, else logs will be redirected to stdout
|
||||
* @return: 0(success), !=-0(failure)
|
||||
*/
|
||||
int set_glog_filelog(int enable);
|
||||
/*
|
||||
* @return: 0(success), !=-0(failure)
|
||||
*/
|
||||
int set_component_filelog(int comp);
|
||||
void close_component_filelog(int comp);
|
||||
void set_component_consolelog(int comp);
|
||||
void logTerm (void);
|
||||
void logClean (void);
|
||||
int map_str_to_int(mapping *map, const char *str);
|
||||
char *map_int_to_str(mapping *map, int val);
|
||||
void logClean (void);
|
||||
int is_newline( char *str, int size);
|
||||
|
||||
int register_log_component(char *name, char *fext, int compidx);
|
||||
|
||||
#define LOG_MEM_SIZE 100*1024*1024
|
||||
#define LOG_MEM_FILE "./logmem.log"
|
||||
void flush_mem_to_file(void);
|
||||
@@ -374,6 +397,8 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE "global_log_online"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_INFILE "global_log_infile"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS "global_log_options"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_ROT_SIZE "global_log_rotation_size"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_ROT_TIME "global_log_rotation_time"
|
||||
|
||||
#define LOG_CONFIG_LEVEL_FORMAT "%s_log_level"
|
||||
#define LOG_CONFIG_LOGFILE_FORMAT "%s_log_infile"
|
||||
@@ -393,14 +418,15 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
/* optname help paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define LOG_GLOBALPARAMS_DESC { \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[3].name, TYPE_STRING, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all components\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[3].name, TYPE_STRING, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0} \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_ROT_SIZE, "Log Rotation: maximum log size in MB for file rotation (0 to disable/default)\n", 0, uptr:&(rotationsize), defuintval:0, TYPE_UINT, 0},\
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_ROT_TIME, "Log Rotation: maximum elapsed time in seconds for file rotation (0 to disable/default)\n", 0, uptr:&(rotationtime), defuintval:0, TYPE_UINT, 0} \
|
||||
}
|
||||
|
||||
#define LOG_OPTIONS_IDX 2
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/** @defgroup _debugging debugging macros
|
||||
* @ingroup _macro
|
||||
|
||||
37
common/utils/LOG/logexample.conf
Normal file
37
common/utils/LOG/logexample.conf
Normal file
@@ -0,0 +1,37 @@
|
||||
/* vim settings :setf config
|
||||
*
|
||||
* This is a section of a generic configuration file for configuring log system. If you do not put this section, the program will log to stdout at INFO level.
|
||||
* The file adheres to the libconfig grammar format that you can find in https://hyperrealm.github.io/libconfig/libconfig_manual.html
|
||||
*/
|
||||
log_config :
|
||||
{
|
||||
|
||||
# Set the log level for all the components.
|
||||
global_log_level = "debug";
|
||||
|
||||
# set log level per component. If the corresponding '*_log_infile' is not present, it will check the 'global_log_level'
|
||||
# to decide where to log
|
||||
hw_log_level = "info";
|
||||
|
||||
# Activation of log redirection to file sink per component. By default it is deactivated.
|
||||
# Syntax: <component>_log_infile = boolean_val(0|1)
|
||||
# Example: hw_log_infile = 1
|
||||
|
||||
# Activation of stdout logs globally for all the components. By default it is deactivated.
|
||||
# If some components has log to file activated it will honour that component setting
|
||||
# Syntax: global_log_online = boolean_val(0|1)
|
||||
|
||||
# Log formatting options for printing, globally or per component. By default, the formatting includes the
|
||||
# component name and colors.
|
||||
# Syntax: global_log_options: list of attributes
|
||||
# where attributes can be: nocolor, level, thread, line_num, function, time, thread_id, json
|
||||
global_log_options = ("level","nocolor","time", "json");
|
||||
|
||||
# Set the maximum log size in MB for triggering logfile rotation. By default it is disabled.
|
||||
# Syntax: global_log_rotation_size: uint_val, 0 means disabled
|
||||
global_log_rotation_size = 1;
|
||||
|
||||
# Set the maximum elapsed time in seconds for triggering file rotation. By default it is disabled.
|
||||
# Syntax: global_log_rotation_time: uint_val, 0 means disabled
|
||||
global_log_rotation_time = 1;
|
||||
};
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -450,6 +450,7 @@ extern "C" {
|
||||
void itti_wait_tasks_end(void) {
|
||||
shutting_down = false;
|
||||
signal(SIGTERM, catch_sigterm);
|
||||
//signal(SIGINT, catch_sigterm);
|
||||
while (! shutting_down)
|
||||
{
|
||||
sleep(24 * 3600);
|
||||
|
||||
@@ -510,7 +510,7 @@ int process_command(char *buf) {
|
||||
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
|
||||
cmddata->prnt=client_printf;
|
||||
cmddata->debug=telnetparams.telnetdbg;
|
||||
cmddata->cmdbuff=cmdb ? strdup(cmdb) : NULL;
|
||||
cmddata->cmdbuff=strdup(cmdb);
|
||||
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
|
||||
} else {
|
||||
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
|
||||
@@ -845,39 +845,30 @@ int telnetsrv_autoinit(void) {
|
||||
* function at init time. the telnet server is delivered with a set of commands which
|
||||
* will be loaded or not depending on the telnet section of the config file
|
||||
*/
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
|
||||
{
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) {
|
||||
int i;
|
||||
notifiedFIFO_t *afifo=NULL;
|
||||
|
||||
if( modulename == NULL || var == NULL || cmd == NULL) {
|
||||
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i=0; i<TELNET_MAXCMD ; i++) {
|
||||
cmdparser_t *CmdParser = &telnetparams.CmdParsers[i];
|
||||
if (CmdParser->var == NULL) {
|
||||
strncpy(CmdParser->module, modulename, sizeof(CmdParser->module) - 1);
|
||||
CmdParser->cmd = cmd;
|
||||
CmdParser->var = var;
|
||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
||||
i, CmdParser->module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == TELNET_MAXCMD) {
|
||||
fprintf(stderr, "[TELNETSRV] TELNET_MAXCMD reached, cannot add new module %s\n", modulename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
notifiedFIFO_t *afifo = NULL;
|
||||
for (int k = 0; cmd[k].cmdfunc != NULL ; k++) {
|
||||
if (cmd[k].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(afifo);
|
||||
if (telnetparams.CmdParsers[i].var == NULL) {
|
||||
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
|
||||
telnetparams.CmdParsers[i].cmd = cmd;
|
||||
telnetparams.CmdParsers[i].var = var;
|
||||
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(afifo);
|
||||
}
|
||||
cmd->qptr = afifo;
|
||||
}
|
||||
cmd[k].qptr = afifo;
|
||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
||||
i,telnetparams.CmdParsers[i].module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ void measurcmd_display_macstats(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_macstats_ue(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_rlcstats(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_phycpu(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_phyta(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_maccpu(telnet_printfunc_t prnt);
|
||||
void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt);
|
||||
|
||||
@@ -65,7 +64,6 @@ static telnet_measurgroupdef_t nrUEmeasurgroups[] = {
|
||||
// {"ue", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}},
|
||||
// {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}},
|
||||
{"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}},
|
||||
{"phyta", GROUP_CPUSTATS, 0, measurcmd_display_phyta, {NULL}},
|
||||
// {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}},
|
||||
// {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}},
|
||||
};
|
||||
@@ -91,18 +89,6 @@ void measurcmd_display_phycpu(telnet_printfunc_t prnt) {
|
||||
PRINT_CPUMEAS_STATE,HDR);
|
||||
measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t));
|
||||
}
|
||||
void measurcmd_display_phyta(telnet_printfunc_t prnt)
|
||||
{
|
||||
PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0];
|
||||
prnt("%s PHY TA stats\n", HDR);
|
||||
prnt("N_TA_offset %d\n", UE->N_TA_offset);
|
||||
for (int i = 0; i < UE->n_connected_gNB; ++i) {
|
||||
NR_UL_TIME_ALIGNMENT_t *ta = &UE->ul_time_alignment[i];
|
||||
prnt("gNB %d TA command %d TA total %d TAG ID %d\n", i, ta->ta_command, ta->ta_total, ta->tag_id);
|
||||
}
|
||||
prnt("timing_advance %d (samples)\n", UE->timing_advance);
|
||||
}
|
||||
|
||||
/*
|
||||
void measurcmd_display_maccpu(telnet_printfunc_t prnt) {
|
||||
eNB_MAC_INST *macvars = RC.mac[eNB_id];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -332,6 +332,9 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
- evalution of RSRP report
|
||||
- evaluation of CQI report
|
||||
- MAC scheduling of SR reception
|
||||
- Bandwidth part (BWP) operation
|
||||
- Handle multiple dedicated BWPs
|
||||
- BWP switching through RRCReconfiguration method
|
||||
|
||||
**gNB RLC**
|
||||
- Send/Receive operations according to 38.322 Rel.16
|
||||
@@ -493,6 +496,8 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
- Configuration of fapi PDU according to DCI
|
||||
* Scheduler procedures for SRS transmission
|
||||
- Periodic SRS transmission
|
||||
* Bandwidth part (BWP) operation
|
||||
- Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration
|
||||
|
||||
|
||||
**UE RLC**
|
||||
|
||||
234
doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md
Normal file
234
doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md
Normal 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
|
||||
```
|
||||
251
doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md
Normal file
251
doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md
Normal 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
|
||||
```
|
||||
@@ -207,7 +207,24 @@ UE on machine 2:
|
||||
|
||||
`sudo ./nr-uesoftmodem --if_freq 2169080000 --if_freq_off -400000000`
|
||||
|
||||
# MIMO configuration
|
||||
|
||||
<table style="border-collapse: collapse; border: none;">
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<img src="./images/mimo_antenna_ports.png" alt="" border=3 height=100 width=300>
|
||||
</img>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This image shows an example of gNB 5G MIMO logical antenna port configuration. It has to be noted that logical antenna ports might not directly correspond to physical antenna ports and each logical antenna port might consist of a sub-array of antennas.
|
||||
|
||||
The basic element is a dual-polarized antenna, therefore the minimal DL MIMO setup with two logical antenna ports would consist of two cross-polarized antenna elements. In a single panel configuration, as the one in the picture, this element can be repeated vertiacally and/or horizontally to form an equi-spaced 1D or 2D array. The values N1 and N2 represent the number of antenna ports in the two dimensions and the supported configurations are specified in Section 5.2.2.2.1 of TS 38.214.
|
||||
|
||||
The DL logical antenna port configuration can be selected through configuration file. `pdsch_AntennaPorts_N1` can be used to set N1 parameter, `pdsch_AntennaPorts_N2` to set N2 and `pdsch_AntennaPorts_XP` to set the cross-polarization configuration (1 for single pol, 2 for cross-pol). To be noted that if XP is 1 but N1 and/or N2 are larger than 1, this would result in a non-standard configuration and the PMI selected would be the identity matrix regardless of CSI report. The default value for each of these parameters is 1.
|
||||
|
||||
# Additional links
|
||||
|
||||
[Selecting an alternative ldpc implementation at run time](../openair1/PHY/CODING/DOC/LDPCImplementation.md)
|
||||
|
||||
|
||||
51
doc/RUN_NR_multiple_BWPs.md
Normal file
51
doc/RUN_NR_multiple_BWPs.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Procedure to add dedicated Bandwidth part (BWP)
|
||||
|
||||
## Contributed by 5G Testbed IISc
|
||||
|
||||
### Developers: Abhijith A, Shruthi S
|
||||
|
||||
# Terminology #
|
||||
|
||||
## Bandwidth part (BWP) ##
|
||||
Bandwidth Part (BWP) is a set of contiguous Resource Blocks in the resource grid.
|
||||
|
||||
Parameters of a BWP are communicated to UE using RRC parameters: BWP-Downlink and BWP-Uplink.
|
||||
|
||||
A UE can be configured with a set of 4 BWPs in uplink (UL) and downlink (DL) direction (3GPP TS 38.331 Annex B.2 Description of BWP configuration options). But only 1 BWP can be active in UL and DL direction at a given time.
|
||||
|
||||
# Procedure to run multiple dedicated BWPs #
|
||||
|
||||
A maximum of 4 dedicated BWPs can be configured for a UE.
|
||||
|
||||
To configure multiple BWPs, add the following parameters to the gNB configuration file under "servingCellConfigDedicated":
|
||||
|
||||
## Setup of the Configuration files ##
|
||||
```
|
||||
firstActiveDownlinkBWP-Id = 1; #BWP-Id
|
||||
defaultDownlinkBWP-Id = 1; #BWP-Id
|
||||
firstActiveUplinkBWP-Id = 1; #BWP-Id
|
||||
```
|
||||
|
||||
Each dedicated BWP must have:
|
||||
```
|
||||
# BWP 1 Configuration
|
||||
dl_bwp-Id_1 = 1;
|
||||
dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_bwp1_subcarrierSpacing = 1;
|
||||
```
|
||||
|
||||
Find these parameters in this configuration file: "targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf"
|
||||
|
||||
# Testing gNB and UE in RF simulator
|
||||
|
||||
## gNB command:
|
||||
```
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --sa
|
||||
```
|
||||
|
||||
## UE command:
|
||||
```
|
||||
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --rfsim --sa --uicc0.imsi 208990000000001
|
||||
```
|
||||
31
doc/UL_MIMO.txt
Normal file
31
doc/UL_MIMO.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# how to build phy sim
|
||||
cd cmake_targets/
|
||||
sudo ./build_oai --phy_simulators -c
|
||||
|
||||
cd phy_simulators/build/
|
||||
# ULSCH sim
|
||||
# bit level validation
|
||||
# PUSCH encoding and decoding for 4 layers 2 CMD without data
|
||||
sudo ./nr_ulschsim -R 106 -m9 -s13 -n100 -y4 -z4 -W4
|
||||
|
||||
# UL sim
|
||||
# Uplink chain validation
|
||||
# PUSCH on UE side and gNB side,whole chain for PUSCH
|
||||
# No channel model on data domain signal
|
||||
# No cross-path connection
|
||||
# PMI = 0 is only unitary prcoding matrix
|
||||
sudo ./nr_ulsim -n100 -m9 -r106 -s13 -W4 -y4 -z4
|
||||
|
||||
# How to build rfsim
|
||||
sudo ./build_oai -c --gNB --nrUE -w SIMU
|
||||
|
||||
# How to run with rfsim
|
||||
# 4x4 RANK 4
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 4
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
# 4x4 RANK 2
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 2
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
|
||||
|
||||
|
||||
BIN
doc/images/mimo_antenna_ports.png
Normal file
BIN
doc/images/mimo_antenna_ports.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -21,8 +21,6 @@ gNBs =
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
|
||||
316
doc/tutorial_resources/docker-compose-basic-nrf.yaml
Normal file
316
doc/tutorial_resources/docker-compose-basic-nrf.yaml
Normal 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"
|
||||
312
doc/tutorial_resources/oai_db.sql
Normal file
312
doc/tutorial_resources/oai_db.sql
Normal 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 */;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -173,7 +173,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,12 +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 sample_rate %f 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->sample_rate);
|
||||
cfg->tx_freq[i],
|
||||
cfg->rx_freq[i],
|
||||
cfg->tune_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2052,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;
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
|
||||
#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
||||
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
|
||||
#define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n"
|
||||
|
||||
@@ -839,10 +839,10 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
|
||||
for (int inst = 0; inst < NB_RU; inst++) {
|
||||
kill_NR_RU_proc(inst);
|
||||
nr_phy_free_RU(RC.ru[inst]);
|
||||
}
|
||||
|
||||
free_lte_top();
|
||||
pthread_cond_destroy(&sync_cond);
|
||||
pthread_mutex_destroy(&sync_mutex);
|
||||
pthread_cond_destroy(&nfapi_sync_cond);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
|
||||
{"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||
{"l" , CONFIG_HLP_DLNL_PHYTEST,0, uptr:&target_dl_Nl, defintval:0, TYPE_UINT, 0}, \
|
||||
{"L" , CONFIG_HLP_ULNL_PHYTEST,0, uptr:&target_ul_Nl, defintval:0, TYPE_UINT, 0}, \
|
||||
{"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
|
||||
{"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \
|
||||
{"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \
|
||||
@@ -36,6 +37,7 @@
|
||||
extern threads_t threads;
|
||||
extern uint32_t target_dl_mcs;
|
||||
extern uint32_t target_dl_Nl;
|
||||
extern uint32_t target_ul_Nl;
|
||||
extern uint32_t target_ul_mcs;
|
||||
extern uint32_t target_dl_bw;
|
||||
extern uint32_t target_ul_bw;
|
||||
|
||||
@@ -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)
|
||||
@@ -613,7 +614,7 @@ void processSlotTX(void *arg) {
|
||||
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx);
|
||||
uint8_t gNB_id = 0;
|
||||
|
||||
LOG_D(PHY,"%d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type);
|
||||
LOG_D(PHY,"processSlotTX %d.%d => slot type %d\n",proc->frame_tx,proc->nr_slot_tx,tx_slot_type);
|
||||
if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
|
||||
|
||||
// trigger L2 to run ue_scheduler thru IF module
|
||||
@@ -713,7 +714,8 @@ void processSlotRX(void *arg) {
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(UE,
|
||||
proc->nr_slot_tx,
|
||||
&UE->frame_parms,1);
|
||||
&UE->frame_parms,
|
||||
UE->frame_parms.nb_antennas_tx);
|
||||
}
|
||||
|
||||
if (UE->UE_mode[gNB_id] > NOT_SYNCHED && UE->UE_mode[gNB_id] < PUSCH) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
64
ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt
Normal file
64
ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt
Normal 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
|
||||
@@ -10,7 +10,8 @@
|
||||
#define FAPI_NR_MAX_RA_OCCASION_PER_CSIRS 64
|
||||
// Constants Defined in 38.213
|
||||
#define FAPI_NR_MAX_CORESET_PER_BWP 3
|
||||
#define FAPI_NR_MAX_SS 10
|
||||
#define FAPI_NR_MAX_SS_PER_BWP 10
|
||||
#define FAPI_NR_MAX_SS FAPI_NR_MAX_SS_PER_BWP*NR_MAX_NUM_BWP
|
||||
|
||||
|
||||
/// RX_IND
|
||||
|
||||
@@ -308,6 +308,7 @@ typedef struct
|
||||
uint8_t transform_precoding;
|
||||
uint16_t data_scrambling_id;
|
||||
uint8_t nrOfLayers;
|
||||
uint8_t Tpmi;
|
||||
//DMRS
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t dmrs_config_type;
|
||||
@@ -433,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;
|
||||
@@ -477,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;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
@@ -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 |
Binary file not shown.
@@ -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:
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
865
openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc_avx512.h
Normal file
865
openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc_avx512.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
83
openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
Normal file
83
openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_init_mem.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user