Merge remote-tracking branch 'origin/nrLDPC_coding_improvements_3' into integration_2025_w08 (!3227)
fix(nrLDPC_coding): timers in DL encoding, fix(ldpctest): Confusion in sizes Main improvements: 1. fix(ldpctest): Confusion in sizes IMPORTANT: This fix makes that ldpctest now works with BG2 and K' != K! (Worth double checking with more cases than I did check with though) The variable block_length had an ambiguous role and was used as both K and Kprime. This was leading to arrays with wrong sizes and functions with wrong arguments. Now there is not anymore block_length but K and Kprime. Kprime can be set with the command line argument -l. There was also some problems with array allocation for segments with length not divisible by 8. A proper sizing with ((size_in_bits + 7) & ~7) / 8 was used. A proper masking of the last byte containing payload bits was also added to keep filler bits to 0 after random initialization. 2. fix(nrLDPC_coding): timers in DL encoding While timers were available for rate matching and interleaving in the new interface, these timers were not merged to rate matching and interleaving timers in nr_dlsch_coding.
This commit is contained in:
@@ -25,7 +25,10 @@
|
||||
<htmlTabRef>test-ldpc-gpu</htmlTabRef>
|
||||
<htmlTabName>Test-ldpc-GPU</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<TestCaseRequestedList>000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021</TestCaseRequestedList>
|
||||
<TestCaseRequestedList>
|
||||
000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021
|
||||
000022 000023 000024 000025 000026 000027 000028 000029 000030 000031 000032 000033 000034 000035 000036 000037 000038 000039 000040 000041
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="000002">
|
||||
@@ -188,6 +191,166 @@
|
||||
<physim_run_args>-l 8448 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000022">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 1 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000023">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 1 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000024">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 100 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000025">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 100 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000026">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 193 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000027">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 193 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000028">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 500 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000029">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 500 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000030">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 561 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000031">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 561 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000032">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 600 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000033">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 600 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000034">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 641 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000035">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 641 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000036">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 2000 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000037">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 2000 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000038">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 3000 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000039">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 3000 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000040">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with CPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 3840 -s10 -n100</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000041">
|
||||
<class>Run_Physim</class>
|
||||
<desc>Run LDPC Test with GPU</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<physim_test>ldpctest</physim_test>
|
||||
<physim_run_args>-l 3840 -s10 -n100 -G 1</physim_run_args>
|
||||
</testCase>
|
||||
|
||||
|
||||
|
||||
</testCaseList>
|
||||
|
||||
@@ -66,16 +66,26 @@
|
||||
</testCase>
|
||||
|
||||
<testCase id="ldpctest">
|
||||
<desc>ldpc Test cases. (Test1: block length = 3872),
|
||||
(Test2: block length = 4224),
|
||||
(Test3: block length = 4576),
|
||||
(Test4: block length = 4928),
|
||||
(Test5: block length = 5280),
|
||||
(Test6: block length = 5632),
|
||||
(Test7: block length = 6336),
|
||||
(Test8: block length = 7040),
|
||||
(Test9: block length = 7744),
|
||||
(Test10: block length = 8448)</desc>
|
||||
<desc>ldpc Test cases. (Test1: block length = 3872, BG1),
|
||||
(Test2: block length = 4224, BG1),
|
||||
(Test3: block length = 4576, BG1),
|
||||
(Test4: block length = 4928, BG1),
|
||||
(Test5: block length = 5280, BG1),
|
||||
(Test6: block length = 5632, BG1),
|
||||
(Test7: block length = 6336, BG1),
|
||||
(Test8: block length = 7040, BG1),
|
||||
(Test9: block length = 7744, BG1),
|
||||
(Test10: block length = 8448, BG1),
|
||||
(Test11: block length = 1, BG2),
|
||||
(Test12: block length = 100, BG2),
|
||||
(Test13: block length = 193, BG2),
|
||||
(Test14: block length = 500, BG2),
|
||||
(Test15: block length = 561, BG2),
|
||||
(Test16: block length = 600, BG2),
|
||||
(Test17: block length = 641, BG2),
|
||||
(Test18: block length = 2000, BG2),
|
||||
(Test19: block length = 3000, BG2),
|
||||
(Test20: block length = 3840, BG2)</desc>
|
||||
<main_exec>ldpctest</main_exec>
|
||||
<main_exec_args>-l3872 -s10 -n100
|
||||
-l4224 -s10 -n100
|
||||
@@ -87,9 +97,17 @@
|
||||
-l7040 -s10 -n100
|
||||
-l7744 -s10 -n100
|
||||
-l8448 -s10 -n100
|
||||
-l561 -s10 -n1
|
||||
-l500 -s10 -n1</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10</tags>
|
||||
-l1 -s10 -n100
|
||||
-l100 -s10 -n100
|
||||
-l193 -s10 -n100
|
||||
-l500 -s10 -n100
|
||||
-l561 -s10 -n100
|
||||
-l600 -s10 -n100
|
||||
-l641 -s10 -n100
|
||||
-l2000 -s10 -n100
|
||||
-l3000 -s10 -n100
|
||||
-l3840 -s10 -n100</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20</tags>
|
||||
<search_expr_true>BLER 0.000000</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal|differ</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
//#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
// #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.h"
|
||||
#include "openair1/PHY/defs_nr_common.h"
|
||||
#include "coding_unitary_defs.h"
|
||||
@@ -38,7 +38,7 @@
|
||||
#define MAX_BLOCK_LENGTH 8448
|
||||
|
||||
#ifndef malloc16
|
||||
# define malloc16(x) memalign(32,x)
|
||||
#define malloc16(x) memalign(32, x)
|
||||
#endif
|
||||
|
||||
#define NR_LDPC_PROFILER_DETAIL
|
||||
@@ -46,10 +46,10 @@
|
||||
ldpc_interface_t ldpc_orig, ldpc_toCompare;
|
||||
|
||||
// 4-bit quantizer
|
||||
int8_t quantize4bit(double D,double x)
|
||||
int8_t quantize4bit(double D, double x)
|
||||
{
|
||||
double qxd;
|
||||
qxd = floor(x/D);
|
||||
qxd = floor(x / D);
|
||||
// printf("x=%f,qxd=%f\n",x,qxd);
|
||||
|
||||
if (qxd <= -8)
|
||||
@@ -57,25 +57,25 @@ int8_t quantize4bit(double D,double x)
|
||||
else if (qxd > 7)
|
||||
qxd = 7;
|
||||
|
||||
return((int8_t)qxd);
|
||||
return ((int8_t)qxd);
|
||||
}
|
||||
|
||||
int8_t quantize8bit(double D,double x)
|
||||
int8_t quantize8bit(double D, double x)
|
||||
{
|
||||
double qxd;
|
||||
//int8_t maxlev;
|
||||
qxd = floor(x/D);
|
||||
// int8_t maxlev;
|
||||
qxd = floor(x / D);
|
||||
|
||||
//maxlev = 1<<(B-1);
|
||||
// maxlev = 1<<(B-1);
|
||||
|
||||
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||
// printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||
|
||||
if (qxd <= -128)
|
||||
qxd = -128;
|
||||
else if (qxd >= 128)
|
||||
qxd = 127;
|
||||
|
||||
return((int8_t)qxd);
|
||||
return ((int8_t)qxd);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -102,61 +102,50 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
int denom_rate,
|
||||
double SNR,
|
||||
unsigned char qbits,
|
||||
short block_length,
|
||||
short Kprime,
|
||||
unsigned int ntrials,
|
||||
int n_segments)
|
||||
{
|
||||
one_measurement_t ret = {0};
|
||||
reset_meas(&ret.time_optim);
|
||||
reset_meas(&ret.time_decoder);
|
||||
//clock initiate
|
||||
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
|
||||
time_stats_t time, tinput,tprep,tparity,toutput;
|
||||
// clock initiate
|
||||
// time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
|
||||
time_stats_t time, tinput, tprep, tparity, toutput;
|
||||
double n_iter_mean = 0;
|
||||
double n_iter_std = 0;
|
||||
int n_iter_max = 0;
|
||||
|
||||
double sigma;
|
||||
sigma = 1.0/sqrt(2*SNR);
|
||||
sigma = 1.0 / sqrt(2 * SNR);
|
||||
cpu_meas_enabled = 1;
|
||||
//short test_input[block_length];
|
||||
uint8_t *test_input[MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS];
|
||||
uint8_t estimated_output[MAX_NUM_DLSCH_SEGMENTS][block_length];
|
||||
uint8_t estimated_output[MAX_NUM_DLSCH_SEGMENTS][Kprime];
|
||||
memset(estimated_output, 0, sizeof(estimated_output));
|
||||
uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS];
|
||||
uint8_t *channel_input_optim[MAX_NUM_DLSCH_SEGMENTS];
|
||||
//double channel_output[68 * 384];
|
||||
double modulated_input[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = { 0 };
|
||||
int8_t channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = { 0 };
|
||||
short BG=0,nrows=0;//,ncols;
|
||||
// double channel_output[68 * 384];
|
||||
double modulated_input[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = {0};
|
||||
int8_t channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS][68 * 384] = {0};
|
||||
short BG = 0, nrows = 0; //,ncols;
|
||||
int i1, Kb = 0;
|
||||
int R_ind = 0;
|
||||
//int n_segments=1;
|
||||
// int n_segments=1;
|
||||
int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
|
||||
//double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
|
||||
// double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
|
||||
|
||||
t_nrLDPC_dec_params decParams[MAX_NUM_DLSCH_SEGMENTS]={0};
|
||||
t_nrLDPC_dec_params decParams[MAX_NUM_DLSCH_SEGMENTS] = {0};
|
||||
|
||||
t_nrLDPC_time_stats decoder_profiler = {0};
|
||||
|
||||
int32_t n_iter = 0;
|
||||
|
||||
// generate input block
|
||||
for(int j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
test_input[j] = malloc16(block_length / 8);
|
||||
memset(test_input[j], 0, block_length / 8);
|
||||
channel_input[j] = malloc16(68 * 384);
|
||||
memset(channel_input[j], 0, 68 * 384);
|
||||
channel_input_optim[j] = malloc16(68 * 384);
|
||||
memset(channel_input_optim[j], 0, 68 * 384);
|
||||
}
|
||||
|
||||
reset_meas(&time);
|
||||
reset_meas(&tinput);
|
||||
reset_meas(&tprep);
|
||||
reset_meas(&tparity);
|
||||
reset_meas(&toutput);
|
||||
//Reset Decoder profiles
|
||||
// Reset Decoder profiles
|
||||
reset_meas(&decoder_profiler.llr2llrProcBuf);
|
||||
reset_meas(&decoder_profiler.llr2CnProcBuf);
|
||||
reset_meas(&decoder_profiler.cnProc);
|
||||
@@ -167,15 +156,10 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
reset_meas(&decoder_profiler.bn2cnProcBuf);
|
||||
reset_meas(&decoder_profiler.llrRes2llrOut);
|
||||
reset_meas(&decoder_profiler.llr2bit);
|
||||
//reset_meas(&decoder_profiler.total);
|
||||
// reset_meas(&decoder_profiler.total);
|
||||
|
||||
// Fill a input packet with random values
|
||||
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++)
|
||||
for (int i = 0; i < block_length / 8; i++)
|
||||
test_input[j][i] = (uint8_t)rand();
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (block_length > 3840) {
|
||||
// determine number of bits in codeword
|
||||
if (Kprime > 3840) {
|
||||
BG = 1;
|
||||
Kb = 22;
|
||||
nrows = 46; // parity check bits
|
||||
@@ -184,11 +168,11 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
BG = 2;
|
||||
nrows = 42; // parity check bits
|
||||
// ncols=10; // info bits
|
||||
if (block_length > 640)
|
||||
if (Kprime > 640)
|
||||
Kb = 10;
|
||||
else if (block_length > 560)
|
||||
else if (Kprime > 560)
|
||||
Kb = 9;
|
||||
else if (block_length > 192)
|
||||
else if (Kprime > 192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
@@ -237,21 +221,37 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
// find minimum value in all sets of lifting size
|
||||
int Zc = 0;
|
||||
const short lift_size[51] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20,
|
||||
22, 24, 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88,
|
||||
96, 104, 112, 120, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384};
|
||||
22, 24, 26, 28, 30, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88,
|
||||
96, 104, 112, 120, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384};
|
||||
for (i1 = 0; i1 < 51; i1++) {
|
||||
if (lift_size[i1] >= (double)block_length / Kb) {
|
||||
if (lift_size[i1] >= (double)Kprime / Kb) {
|
||||
Zc = lift_size[i1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length, BG, Zc, Kb);
|
||||
const int no_punctured_columns =
|
||||
(int)((nrows - 2) * Zc + block_length - block_length * (1 / ((float)nom_rate / (float)denom_rate))) / Zc;
|
||||
// K: Segment size = number of columns in the parity check matrix * lifting size (number of columns of the square parity check
|
||||
// sub-matrix)
|
||||
int K = 0;
|
||||
if (BG == 1) {
|
||||
K = 22 * Zc;
|
||||
} else if (BG == 2) {
|
||||
K = 10 * Zc;
|
||||
} else {
|
||||
printf("Not supported: BG: %d\n", BG);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("ldpc_test: codeword_length %d, n_segments %d, Kprime %d, BG %d, Zc %d, Kb %d\n",
|
||||
n_segments * K,
|
||||
n_segments,
|
||||
Kprime,
|
||||
BG,
|
||||
Zc,
|
||||
Kb);
|
||||
const int no_punctured_columns = (int)((nrows - 2) * Zc + K - K * (1 / ((float)nom_rate / (float)denom_rate))) / Zc;
|
||||
// printf("puncture:%d\n",no_punctured_columns);
|
||||
const int removed_bit =
|
||||
(nrows - no_punctured_columns - 2) * Zc + block_length - (int)(block_length / ((float)nom_rate / (float)denom_rate));
|
||||
const int removed_bit = (nrows - no_punctured_columns - 2) * Zc + K - (int)(K / ((float)nom_rate / (float)denom_rate));
|
||||
|
||||
printf("nrows: %d\n", nrows);
|
||||
printf("no_punctured_columns: %d\n", no_punctured_columns);
|
||||
@@ -259,12 +259,34 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
printf("To: %d\n", (Kb + nrows - no_punctured_columns) * Zc - removed_bit);
|
||||
printf("number of undecoded bits: %d\n", (Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit);
|
||||
|
||||
encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .K = block_length};
|
||||
// generate input block
|
||||
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++) {
|
||||
test_input[j] = malloc16(((K + 7) & ~7) / 8);
|
||||
memset(test_input[j], 0, ((K + 7) & ~7) / 8);
|
||||
channel_input[j] = malloc16(68 * 384);
|
||||
memset(channel_input[j], 0, 68 * 384);
|
||||
channel_input_optim[j] = malloc16(68 * 384);
|
||||
memset(channel_input_optim[j], 0, 68 * 384);
|
||||
}
|
||||
|
||||
// Fill input segments with random values
|
||||
for (int j = 0; j < MAX_NUM_DLSCH_SEGMENTS; j++) {
|
||||
int i = 0;
|
||||
for (i = 0; i < ((Kprime + 7) & ~7) / 8; i++)
|
||||
test_input[j][i] = (uint8_t)rand();
|
||||
// Mask the last byte in order to keep filler bits to 0
|
||||
if (Kprime % 8 != 0) {
|
||||
uint8_t last_byte_mask = (1 << (Kprime % 8)) - 1;
|
||||
test_input[j][i - 1] = test_input[j][i - 1] & last_byte_mask;
|
||||
}
|
||||
}
|
||||
|
||||
encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .K = K};
|
||||
impp.gen_code = 2;
|
||||
|
||||
if (ntrials==0)
|
||||
if (ntrials == 0)
|
||||
ldpc_orig.LDPCencoder(test_input, channel_input, &impp);
|
||||
impp.gen_code=0;
|
||||
impp.gen_code = 0;
|
||||
decode_abort_t dec_abort;
|
||||
init_abort(&dec_abort);
|
||||
for (int trial = 0; trial < ntrials; trial++) {
|
||||
@@ -286,11 +308,12 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
|
||||
if (ntrials == 1)
|
||||
for (int j = 0; j < n_segments; j++)
|
||||
for (int i = 0; i < block_length + (nrows - no_punctured_columns) * Zc - removed_bit; i++)
|
||||
for (int i = 0; i < K + (nrows - no_punctured_columns) * Zc - removed_bit; i++) {
|
||||
if (channel_input[j][i] != channel_input_optim[j][i]) {
|
||||
printf("differ in seg %d pos %d (%u,%u)\n", j, i, channel_input[j][i], channel_input_optim[j][i]);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < n_segments; j++) {
|
||||
for (int i = 2 * Zc; i < (Kb + nrows - no_punctured_columns) * Zc - removed_bit; i++) {
|
||||
@@ -314,47 +337,48 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CODER
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
decParams[j].BG = BG;
|
||||
decParams[j].Z = Zc;
|
||||
decParams[j].R = code_rate_vec[R_ind]; // 13;
|
||||
decParams[j].numMaxIter = max_iterations;
|
||||
decParams[j].outMode = nrLDPC_outMode_BIT;
|
||||
decParams[j].Kprime = block_length;
|
||||
ldpc_toCompare.LDPCinit();
|
||||
decParams[j].BG = BG;
|
||||
decParams[j].Z = Zc;
|
||||
decParams[j].R = code_rate_vec[R_ind]; // 13;
|
||||
decParams[j].numMaxIter = max_iterations;
|
||||
decParams[j].outMode = nrLDPC_outMode_BIT;
|
||||
decParams[j].Kprime = Kprime;
|
||||
ldpc_toCompare.LDPCinit();
|
||||
}
|
||||
for (int j = 0; j < n_segments; j++) {
|
||||
start_meas(&ret.time_decoder);
|
||||
set_abort(&dec_abort, false);
|
||||
|
||||
n_iter = ldpc_toCompare.LDPCdecoder(&decParams[j],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(int8_t *)channel_output_fixed[j],
|
||||
(int8_t *)estimated_output[j],
|
||||
&decoder_profiler,
|
||||
&dec_abort);
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(int8_t *)channel_output_fixed[j],
|
||||
(int8_t *)estimated_output[j],
|
||||
&decoder_profiler,
|
||||
&dec_abort);
|
||||
stop_meas(&ret.time_decoder);
|
||||
|
||||
// count errors
|
||||
if (memcmp(estimated_output[j], test_input[j], block_length / 8) != 0) {
|
||||
segment_bler++;
|
||||
if (memcmp(estimated_output[j], test_input[j], ((Kprime + 7) & ~7) / 8) != 0) {
|
||||
segment_bler++;
|
||||
}
|
||||
for (int i = 0; i < block_length; i++) {
|
||||
unsigned char estoutputbit = (estimated_output[j][i / 8] & (1 << (i & 7))) >> (i & 7);
|
||||
unsigned char inputbit = (test_input[j][i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||
if (estoutputbit != inputbit)
|
||||
ret.errors_bit++;
|
||||
for (int i = 0; i < Kprime; i++) {
|
||||
unsigned char estoutputbit = (estimated_output[j][i / 8] & (1 << (i & 7))) >> (i & 7);
|
||||
unsigned char inputbit = (test_input[j][i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||
if (estoutputbit != inputbit)
|
||||
ret.errors_bit++;
|
||||
}
|
||||
|
||||
n_iter_mean += n_iter;
|
||||
n_iter_std += pow(n_iter - 1, 2);
|
||||
|
||||
if (n_iter > n_iter_max)
|
||||
n_iter_max = n_iter;
|
||||
n_iter_max = n_iter;
|
||||
|
||||
} // end segments
|
||||
|
||||
@@ -364,7 +388,7 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
|
||||
ret.dec_iter.n_iter_mean = n_iter_mean / (double)ntrials / (double)n_segments - 1;
|
||||
ret.dec_iter.n_iter_std =
|
||||
sqrt(n_iter_std / (double)ntrials / (double)n_segments - pow(n_iter_mean / (double)ntrials / (double)n_segments - 1, 2));
|
||||
sqrt(n_iter_std / (double)ntrials / (double)n_segments - pow(n_iter_mean / (double)ntrials / (double)n_segments - 1, 2));
|
||||
ret.dec_iter.n_iter_max = n_iter_max - 1;
|
||||
|
||||
ret.errors_bit_uncoded = ret.errors_bit_uncoded / (double)((Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit);
|
||||
@@ -375,24 +399,24 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
free(channel_input_optim[j]);
|
||||
}
|
||||
|
||||
print_meas(&time,"ldpc_encoder",NULL,NULL);
|
||||
print_meas(&time, "ldpc_encoder", NULL, NULL);
|
||||
print_meas(&ret.time_optim, "ldpc_encoder_optim", NULL, NULL);
|
||||
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
|
||||
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
|
||||
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
|
||||
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
|
||||
print_meas(&tinput, "ldpc_encoder_optim(input)", NULL, NULL);
|
||||
print_meas(&tprep, "ldpc_encoder_optim(prep)", NULL, NULL);
|
||||
print_meas(&tparity, "ldpc_encoder_optim(parity)", NULL, NULL);
|
||||
print_meas(&toutput, "ldpc_encoder_optim(output)", NULL, NULL);
|
||||
printf("\n");
|
||||
print_meas(&ret.time_decoder, "ldpc_decoder", NULL, NULL);
|
||||
print_meas(&decoder_profiler.llr2llrProcBuf,"llr2llrProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2CnProcBuf,"llr2CnProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProc,"cnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProcPc,"cnProcPc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProc,"bnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProcPc,"bnProcPc(per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cn2bnProcBuf,"cn2bnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bn2cnProcBuf,"bn2cnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llrRes2llrOut,"llrRes2llrOut",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2bit,"llr2bit",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2llrProcBuf, "llr2llrProcBuf", NULL, NULL);
|
||||
print_meas(&decoder_profiler.llr2CnProcBuf, "llr2CnProcBuf", NULL, NULL);
|
||||
print_meas(&decoder_profiler.cnProc, "cnProc (per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.cnProcPc, "cnProcPc (per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.bnProc, "bnProc (per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.bnProcPc, "bnProcPc(per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.cn2bnProcBuf, "cn2bnProcBuf (per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.bn2cnProcBuf, "bn2cnProcBuf (per iteration)", NULL, NULL);
|
||||
print_meas(&decoder_profiler.llrRes2llrOut, "llrRes2llrOut", NULL, NULL);
|
||||
print_meas(&decoder_profiler.llr2bit, "llr2bit", NULL, NULL);
|
||||
printf("\n");
|
||||
|
||||
return ret;
|
||||
@@ -401,18 +425,18 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
short Kprime = 8448;
|
||||
// default to check output inside ldpc, the NR version checks the outer CRC defined by 3GPP
|
||||
char *ldpc_version = "";
|
||||
/* version of the ldpc decoder library to use (XXX suffix to use when loading libldpc_XXX.so */
|
||||
short max_iterations=5;
|
||||
int n_segments=1;
|
||||
//double rate=0.333;
|
||||
|
||||
int nom_rate=1;
|
||||
int denom_rate=3;
|
||||
double SNR0=-2.0;
|
||||
uint8_t qbits=8;
|
||||
short max_iterations = 5;
|
||||
int n_segments = 1;
|
||||
// double rate=0.333;
|
||||
|
||||
int nom_rate = 1;
|
||||
int denom_rate = 3;
|
||||
double SNR0 = -2.0;
|
||||
uint8_t qbits = 8;
|
||||
unsigned int decoded_errors[10000]; // initiate the size of matrix equivalent to size of SNR
|
||||
int c, i = 0;
|
||||
|
||||
@@ -420,7 +444,7 @@ int main(int argc, char *argv[])
|
||||
double SNR_step = 0.1;
|
||||
|
||||
randominit(0);
|
||||
int test_uncoded= 0;
|
||||
int test_uncoded = 0;
|
||||
n_iter_stats_t dec_iter[400] = {0};
|
||||
|
||||
short BG = 0, Zc;
|
||||
@@ -430,14 +454,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
logInit();
|
||||
|
||||
while ((c = getopt (argc, argv, "--:O:q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1) {
|
||||
|
||||
while ((c = getopt(argc, argv, "--:O:q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1) {
|
||||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
if (c == 1 || c == '-' || c == 'O')
|
||||
continue;
|
||||
|
||||
printf("handling optarg %c\n",c);
|
||||
printf("handling optarg %c\n", c);
|
||||
switch (c) {
|
||||
case 'q':
|
||||
qbits = atoi(optarg);
|
||||
@@ -452,11 +475,11 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
block_length = atoi(optarg);
|
||||
Kprime = atoi(optarg);
|
||||
break;
|
||||
|
||||
|
||||
case 'G':
|
||||
ldpc_version="_cuda";
|
||||
ldpc_version = "_cuda";
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
@@ -488,13 +511,13 @@ int main(int argc, char *argv[])
|
||||
case 'h':
|
||||
default:
|
||||
printf("CURRENTLY SUPPORTED CODE RATES: \n");
|
||||
printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
|
||||
printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
|
||||
printf("BG1 (K' > 3840): 1/3, 2/3, 22/25 (8/9) \n");
|
||||
printf("BG2 (K' <= 3840): 1/5, 1/3, 2/3 \n\n");
|
||||
printf("-h This message\n");
|
||||
printf("-q Quantization bits, Default: 8\n");
|
||||
printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
|
||||
printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
|
||||
printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
|
||||
printf("-l Length of payload bits in a segment (K' in 38.212-5.2.2), [1, 8448], Default: 8448\n");
|
||||
printf("-G give 1 to run cuda for LDPC, Default: 0\n");
|
||||
printf("-n Number of simulation trials, Default: 1\n");
|
||||
// printf("-M MCS2 for TB 2\n");
|
||||
@@ -503,30 +526,29 @@ int main(int argc, char *argv[])
|
||||
printf("-t SNR simulation step, Default: 0.1\n");
|
||||
printf("-i Max decoder iterations, Default: 5\n");
|
||||
printf("-u Set SNR per coded bit, Default: 0\n");
|
||||
printf("-v XXX Set ldpc shared library version. libldpc_XXX.so will be used \n");
|
||||
printf("-v _XXX Set ldpc shared library version. libldpc_XXX.so will be used \n");
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
|
||||
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
|
||||
printf("block length %d: \n", block_length);
|
||||
printf("block length %d: \n", Kprime);
|
||||
printf("n_trials %d: \n", n_trials);
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
load_LDPClib(ldpc_version, &ldpc_toCompare);
|
||||
load_LDPClib("_orig", &ldpc_orig);
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
// find minimum value in all sets of lifting size
|
||||
Zc = 0;
|
||||
|
||||
char fname[200];
|
||||
sprintf(fname,"ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, max_iterations);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
|
||||
sprintf(fname, "ldpctest_BG_%d_Zc_%d_rate_%d-%d_Kprime_%d_maxit_%d.txt", BG, Zc, nom_rate, denom_rate, Kprime, max_iterations);
|
||||
FILE *fd = fopen(fname, "w");
|
||||
AssertFatal(fd != NULL, "cannot open %s\n", fname);
|
||||
|
||||
fprintf(fd,"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\n");
|
||||
fprintf(fd,
|
||||
"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\n");
|
||||
|
||||
for (double SNR = SNR0; SNR < SNR0 + 20.0; SNR += SNR_step) {
|
||||
double SNR_lin;
|
||||
@@ -540,13 +562,14 @@ int main(int argc, char *argv[])
|
||||
denom_rate,
|
||||
SNR_lin, // noise standard deviation
|
||||
qbits,
|
||||
block_length, // block length bytes
|
||||
Kprime, // block length bytes
|
||||
n_trials,
|
||||
n_segments);
|
||||
|
||||
decoded_errors[i] = res.errors;
|
||||
dec_iter[i] = res.dec_iter;
|
||||
dec_iter[i].snr = SNR;
|
||||
dec_iter[i].ber = (float)res.errors_bit / (float)n_trials / (float)block_length / (double)n_segments;
|
||||
dec_iter[i].ber = (float)res.errors_bit / (float)n_trials / (float)Kprime / (double)n_segments;
|
||||
dec_iter[i].bler = (float)decoded_errors[i] / (float)n_trials;
|
||||
printf("SNR %f, BLER %f (%u/%d)\n", SNR, dec_iter[i].bler, decoded_errors[i], n_trials);
|
||||
printf("SNR %f, BER %f (%u/%d)\n", SNR, dec_iter[i].ber, decoded_errors[i], n_trials);
|
||||
@@ -559,33 +582,42 @@ int main(int argc, char *argv[])
|
||||
printf("SNR %f, Std iterations: %f\n", SNR, dec_iter[i].n_iter_std);
|
||||
printf("SNR %f, Max iterations: %d\n", SNR, dec_iter[i].n_iter_max);
|
||||
printf("\n");
|
||||
printf("Encoding time mean: %15.3f us\n",(double)res.time_optim.diff/res.time_optim.trials/1000.0/get_cpu_freq_GHz());
|
||||
printf("Encoding time std: %15.3f us\n",sqrt((double)res.time_optim.diff_square/res.time_optim.trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)res.time_optim.diff/res.time_optim.trials/1000.0/get_cpu_freq_GHz(),2)));
|
||||
printf("Encoding time max: %15.3f us\n",(double)res.time_optim.max/1000.0/get_cpu_freq_GHz());
|
||||
|
||||
double cpu_freq = get_cpu_freq_GHz();
|
||||
time_stats_t *t_optim = &res.time_optim;
|
||||
printf("Encoding time mean: %15.3f us\n", (double)t_optim->diff / t_optim->trials / 1000.0 / cpu_freq);
|
||||
printf("Encoding time std: %15.3f us\n",
|
||||
sqrt((double)t_optim->diff_square / t_optim->trials / pow(1000, 2) / pow(cpu_freq, 2)
|
||||
- pow((double)t_optim->diff / t_optim->trials / 1000.0 / cpu_freq, 2)));
|
||||
printf("Encoding time max: %15.3f us\n", (double)t_optim->max / 1000.0 / cpu_freq);
|
||||
printf("\n");
|
||||
printf("Decoding time mean: %15.3f us\n",(double)res.time_decoder.diff/res.time_decoder.trials/1000.0/get_cpu_freq_GHz());
|
||||
printf("Decoding time std: %15.3f us\n",sqrt((double)res.time_decoder.diff_square/res.time_decoder.trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)res.time_decoder.diff/res.time_decoder.trials/1000.0/get_cpu_freq_GHz(),2)));
|
||||
printf("Decoding time max: %15.3f us\n",(double)res.time_decoder.max/1000.0/get_cpu_freq_GHz());
|
||||
|
||||
time_stats_t *t_decoder = &res.time_decoder;
|
||||
printf("Decoding time mean: %15.3f us\n", (double)t_decoder->diff / t_decoder->trials / 1000.0 / cpu_freq);
|
||||
printf("Decoding time std: %15.3f us\n",
|
||||
sqrt((double)t_decoder->diff_square / t_decoder->trials / pow(1000, 2) / pow(cpu_freq, 2)
|
||||
- pow((double)t_decoder->diff / t_decoder->trials / 1000.0 / cpu_freq, 2)));
|
||||
printf("Decoding time max: %15.3f us\n", (double)t_decoder->max / 1000.0 / cpu_freq);
|
||||
|
||||
fprintf(fd,
|
||||
"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
|
||||
SNR,
|
||||
(double)decoded_errors[i] / (double)n_trials,
|
||||
(double)res.errors_bit / (double)n_trials / (double)block_length / (double)n_segments,
|
||||
(double)res.errors_bit / (double)n_trials / (double)Kprime / (double)n_segments,
|
||||
res.errors_bit_uncoded / (double)n_trials / (double)n_segments,
|
||||
(double)res.time_optim.diff / res.time_optim.trials / 1000.0 / get_cpu_freq_GHz(),
|
||||
sqrt((double)res.time_optim.diff_square / res.time_optim.trials / pow(1000, 2) / pow(get_cpu_freq_GHz(), 2)
|
||||
- pow((double)res.time_optim.diff / res.time_optim.trials / 1000.0 / get_cpu_freq_GHz(), 2)),
|
||||
(double)res.time_optim.max / 1000.0 / get_cpu_freq_GHz(),
|
||||
(double)res.time_decoder.diff / res.time_decoder.trials / 1000.0 / get_cpu_freq_GHz(),
|
||||
sqrt((double)res.time_decoder.diff_square / res.time_decoder.trials / pow(1000, 2) / pow(get_cpu_freq_GHz(), 2)
|
||||
- pow((double)res.time_decoder.diff / res.time_decoder.trials / 1000.0 / get_cpu_freq_GHz(), 2)),
|
||||
(double)res.time_decoder.max / 1000.0 / get_cpu_freq_GHz(),
|
||||
(double)t_optim->diff / t_optim->trials / 1000.0 / cpu_freq,
|
||||
sqrt((double)t_optim->diff_square / t_optim->trials / pow(1000, 2) / pow(cpu_freq, 2)
|
||||
- pow((double)t_optim->diff / t_optim->trials / 1000.0 / cpu_freq, 2)),
|
||||
(double)t_optim->max / 1000.0 / cpu_freq,
|
||||
(double)t_decoder->diff / t_decoder->trials / 1000.0 / cpu_freq,
|
||||
sqrt((double)t_decoder->diff_square / t_decoder->trials / pow(1000, 2) / pow(cpu_freq, 2)
|
||||
- pow((double)t_decoder->diff / t_decoder->trials / 1000.0 / cpu_freq, 2)),
|
||||
(double)t_decoder->max / 1000.0 / cpu_freq,
|
||||
dec_iter[i].n_iter_mean,
|
||||
dec_iter[i].n_iter_std,
|
||||
dec_iter[i].n_iter_max);
|
||||
|
||||
i=i+1;
|
||||
i = i + 1;
|
||||
if (decoded_errors[i - 1] == 0)
|
||||
break;
|
||||
}
|
||||
@@ -598,5 +630,5 @@ int main(int argc, char *argv[])
|
||||
loader_reset();
|
||||
logTerm();
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
+2
-2
@@ -49,7 +49,7 @@ typedef struct ldpc8blocks_args_s {
|
||||
encoder_implemparams_t impp;
|
||||
} ldpc8blocks_args_t;
|
||||
|
||||
static void ldpc8blocks_coding_segment(void *p)
|
||||
static void ldpc8blocks(void *p)
|
||||
{
|
||||
ldpc8blocks_args_t *args = (ldpc8blocks_args_t *)p;
|
||||
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = args->nrLDPC_TB_encoding_parameters;
|
||||
@@ -192,7 +192,7 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_
|
||||
perJobImpp->impp = impp;
|
||||
perJobImpp->nrLDPC_TB_encoding_parameters = nrLDPC_TB_encoding_parameters;
|
||||
|
||||
task_t t = {.func = ldpc8blocks_coding_segment, .args = perJobImpp};
|
||||
task_t t = {.func = ldpc8blocks, .args = perJobImpp};
|
||||
pushTpool(nrLDPC_slot_encoding_parameters->threadPool, t);
|
||||
}
|
||||
return n_seg;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_dlsch_coding_slot.c
|
||||
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
|
||||
*/
|
||||
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
@@ -39,17 +39,17 @@
|
||||
#include <syscall.h>
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
//#define DEBUG_DLSCH_CODING
|
||||
//#define DEBUG_DLSCH_FREE 1
|
||||
// #define DEBUG_DLSCH_CODING
|
||||
// #define DEBUG_DLSCH_FREE 1
|
||||
|
||||
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
|
||||
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers;
|
||||
int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
|
||||
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers;
|
||||
|
||||
if (N_RB != 273) {
|
||||
a_segments = a_segments*N_RB;
|
||||
a_segments = a_segments/273 +1;
|
||||
a_segments = a_segments * N_RB;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
|
||||
@@ -70,16 +70,16 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
|
||||
|
||||
NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
{
|
||||
int max_layers = (frame_parms->nb_antennas_tx<NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
|
||||
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated
|
||||
int max_layers = (frame_parms->nb_antennas_tx < NR_MAX_NB_LAYERS) ? frame_parms->nb_antennas_tx : NR_MAX_NB_LAYERS;
|
||||
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * max_layers; // number of segments to be allocated
|
||||
|
||||
if (N_RB != 273) {
|
||||
a_segments = a_segments*N_RB;
|
||||
a_segments = a_segments/273 +1;
|
||||
a_segments = a_segments * N_RB;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
|
||||
LOG_D(PHY,"Allocating %d segments (MAX %d, N_PRB %d)\n",a_segments,MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER,N_RB);
|
||||
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
|
||||
LOG_D(PHY, "Allocating %d segments (MAX %d, N_PRB %d)\n", a_segments, MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER, N_RB);
|
||||
uint32_t dlsch_bytes = a_segments * 1056; // allocated bytes per segment
|
||||
NR_gNB_DLSCH_t dlsch;
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
|
||||
@@ -88,7 +88,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
AssertFatal(harq->b, "cannot allocate memory for harq->b\n");
|
||||
bzero(harq->b, dlsch_bytes);
|
||||
|
||||
harq->c = (uint8_t **)malloc16(a_segments*sizeof(uint8_t *));
|
||||
harq->c = (uint8_t **)malloc16(a_segments * sizeof(uint8_t *));
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
// account for filler in first segment and CRCs for multiple segment case
|
||||
// [hna] 8448 is the maximum CB size in NR
|
||||
@@ -103,7 +103,7 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
AssertFatal(harq->f, "cannot allocate harq->f\n");
|
||||
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
|
||||
return(dlsch);
|
||||
return (dlsch);
|
||||
}
|
||||
|
||||
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
@@ -120,34 +120,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
time_stats_t *dlsch_interleaving_stats,
|
||||
time_stats_t *dlsch_segmentation_stats)
|
||||
{
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t TBs[msgTx->num_pdsch_slot];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters = {
|
||||
.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = msgTx->num_pdsch_slot,
|
||||
.threadPool = &gNB->threadPool,
|
||||
.tinput = tinput,
|
||||
.tprep = tprep,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs
|
||||
};
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = msgTx->num_pdsch_slot,
|
||||
.threadPool = &gNB->threadPool,
|
||||
.tinput = tinput,
|
||||
.tprep = tprep,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs};
|
||||
|
||||
int num_segments = 0;
|
||||
|
||||
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) {
|
||||
|
||||
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
|
||||
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
|
||||
unsigned int crc=1;
|
||||
unsigned int crc = 1;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
|
||||
uint32_t A = rel15->TBSize[0]<<3;
|
||||
unsigned char *a=harq->pdu;
|
||||
uint32_t A = rel15->TBSize[0] << 3;
|
||||
unsigned char *a = harq->pdu;
|
||||
if (rel15->rnti != SI_RNTI) {
|
||||
ws_trace_t tmp = {.nr = true,
|
||||
.direction = DIRECTION_DOWNLINK,
|
||||
@@ -175,38 +171,30 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
phy_stats->dlsch_stats.current_Qm = rel15->qamModOrder[0];
|
||||
}
|
||||
|
||||
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056;
|
||||
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers * 1056;
|
||||
int B;
|
||||
if (A > NR_MAX_PDSCH_TBS) {
|
||||
// Add 24-bit crc (polynomial A) to payload
|
||||
crc = crc24a(a,A)>>8;
|
||||
a[A>>3] = ((uint8_t *)&crc)[2];
|
||||
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
|
||||
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
crc = crc24a(a, A) >> 8;
|
||||
a[A >> 3] = ((uint8_t *)&crc)[2];
|
||||
a[1 + (A >> 3)] = ((uint8_t *)&crc)[1];
|
||||
a[2 + (A >> 3)] = ((uint8_t *)&crc)[0];
|
||||
// printf("CRC %x (A %d)\n",crc,A);
|
||||
// printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
B = A + 24;
|
||||
// harq->b = a;
|
||||
AssertFatal((A / 8) + 4 <= max_bytes,
|
||||
"A %d is too big (A/8+4 = %d > %d)\n",
|
||||
A,
|
||||
(A / 8) + 4,
|
||||
max_bytes);
|
||||
AssertFatal((A / 8) + 4 <= max_bytes, "A %d is too big (A/8+4 = %d > %d)\n", A, (A / 8) + 4, max_bytes);
|
||||
memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes?
|
||||
} else {
|
||||
// Add 16-bit crc (polynomial A) to payload
|
||||
crc = crc16(a,A)>>16;
|
||||
a[A>>3] = ((uint8_t *)&crc)[1];
|
||||
a[1+(A>>3)] = ((uint8_t *)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
|
||||
crc = crc16(a, A) >> 16;
|
||||
a[A >> 3] = ((uint8_t *)&crc)[1];
|
||||
a[1 + (A >> 3)] = ((uint8_t *)&crc)[0];
|
||||
// printf("CRC %x (A %d)\n",crc,A);
|
||||
// printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
|
||||
B = A + 16;
|
||||
// harq->b = a;
|
||||
AssertFatal((A / 8) + 3 <= max_bytes,
|
||||
"A %d is too big (A/8+3 = %d > %d)\n",
|
||||
A,
|
||||
(A / 8) + 3,
|
||||
max_bytes);
|
||||
AssertFatal((A / 8) + 3 <= max_bytes, "A %d is too big (A/8+3 = %d > %d)\n", A, (A / 8) + 3, max_bytes);
|
||||
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
|
||||
}
|
||||
|
||||
@@ -228,12 +216,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
TB_parameters->BG);
|
||||
stop_meas(dlsch_segmentation_stats);
|
||||
|
||||
if (TB_parameters->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) {
|
||||
if (TB_parameters->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B);
|
||||
return(-1);
|
||||
return (-1);
|
||||
}
|
||||
num_segments += TB_parameters->C;
|
||||
|
||||
}
|
||||
|
||||
nrLDPC_segment_encoding_parameters_t segments[num_segments];
|
||||
@@ -284,18 +271,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
segment_parameters->c = harq->c[r];
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G,
|
||||
TB_parameters->C,
|
||||
TB_parameters->Qm,
|
||||
rel15->nrOfLayers,
|
||||
r);
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, rel15->nrOfLayers, r);
|
||||
segment_parameters->output = &output[dlsch_offset + r_offset];
|
||||
r_offset += segment_parameters->E;
|
||||
|
||||
reset_meas(&segment_parameters->ts_interleave);
|
||||
reset_meas(&segment_parameters->ts_rate_match);
|
||||
reset_meas(&segment_parameters->ts_ldpc_encode);
|
||||
|
||||
}
|
||||
|
||||
segments_offset += TB_parameters->C;
|
||||
@@ -309,6 +291,16 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
|
||||
|
||||
for (int dlsch_id = 0; dlsch_id < msgTx->num_pdsch_slot; dlsch_id++) {
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[dlsch_id];
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
|
||||
merge_meas(dlsch_rate_matching_stats, &segment_parameters->ts_rate_match);
|
||||
// merge_meas(, &segment_parameters->ts_ldpc_encode);
|
||||
}
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_ulsch_decoding_slot.c
|
||||
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
|
||||
*/
|
||||
|
||||
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
|
||||
*/
|
||||
|
||||
// [from gNB coding]
|
||||
#include "PHY/defs_gNB.h"
|
||||
@@ -41,27 +40,26 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <syscall.h>
|
||||
//#define DEBUG_ULSCH_DECODING
|
||||
//#define gNB_DEBUG_TRACE
|
||||
// #define DEBUG_ULSCH_DECODING
|
||||
// #define gNB_DEBUG_TRACE
|
||||
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
//#define DEBUG_CRC
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000 // 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
// #define DEBUG_CRC
|
||||
#ifdef DEBUG_CRC
|
||||
#define PRINT_CRC_CHECK(a) a
|
||||
#else
|
||||
#define PRINT_CRC_CHECK(a)
|
||||
#endif
|
||||
|
||||
//extern double cpuf;
|
||||
// extern double cpuf;
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
|
||||
{
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS; // number of segments to be allocated
|
||||
|
||||
if (N_RB_UL != 273) {
|
||||
a_segments = a_segments*N_RB_UL;
|
||||
a_segments = a_segments/273 +1;
|
||||
a_segments = a_segments * N_RB_UL;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
|
||||
if (ulsch->harq_process) {
|
||||
@@ -83,12 +81,11 @@ void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
|
||||
|
||||
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
|
||||
{
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * NR_MAX_NB_LAYERS; // number of segments to be allocated
|
||||
|
||||
if (N_RB_UL != 273) {
|
||||
a_segments = a_segments*N_RB_UL;
|
||||
a_segments = a_segments/273 +1;
|
||||
a_segments = a_segments * N_RB_UL;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
|
||||
uint32_t ulsch_bytes = a_segments * 1056; // allocated bytes per segment
|
||||
@@ -110,7 +107,7 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
|
||||
}
|
||||
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
|
||||
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
|
||||
return(ulsch);
|
||||
return (ulsch);
|
||||
}
|
||||
|
||||
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
@@ -121,18 +118,15 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t *ULSCH_ids,
|
||||
int nb_pusch)
|
||||
{
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
|
||||
|
||||
nrLDPC_TB_decoding_parameters_t TBs[nb_pusch];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters = {
|
||||
.frame = frame,
|
||||
.slot = nr_tti_rx,
|
||||
.nb_TBs = nb_pusch,
|
||||
.threadPool = &phy_vars_gNB->threadPool,
|
||||
.TBs = TBs
|
||||
};
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters = {.frame = frame,
|
||||
.slot = nr_tti_rx,
|
||||
.nb_TBs = nb_pusch,
|
||||
.threadPool = &phy_vars_gNB->threadPool,
|
||||
.TBs = TBs};
|
||||
|
||||
int max_num_segments = 0;
|
||||
|
||||
@@ -154,17 +148,17 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
|
||||
// The harq_pid is not unique among the active HARQ processes in the instance so we use ULSCH_id instead
|
||||
TB_parameters->harq_unique_pid = ULSCH_id;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
TB_parameters->nb_rb = pusch_pdu->rb_size;
|
||||
TB_parameters->Qm = pusch_pdu->qam_mod_order;
|
||||
TB_parameters->mcs = pusch_pdu->mcs_index;
|
||||
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
|
||||
TB_parameters->processedSegments = &harq_process->processedSegments;
|
||||
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
||||
|
||||
|
||||
TB_parameters->BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
||||
TB_parameters->A = (harq_process->TBS) << 3;
|
||||
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
|
||||
@@ -181,7 +175,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t harq_pid = ulsch->harq_pid;
|
||||
LOG_D(PHY,
|
||||
"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
|
||||
@@ -197,7 +191,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
harq_process->round,
|
||||
harq_process->harq_to_be_cleared);
|
||||
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
@@ -211,40 +205,34 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
harq_process->K = TB_parameters->K;
|
||||
harq_process->Z = TB_parameters->Z;
|
||||
harq_process->F = TB_parameters->F;
|
||||
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers; // number of segments to be allocated
|
||||
if (TB_parameters->C > a_segments) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A);
|
||||
return(-1);
|
||||
return (-1);
|
||||
}
|
||||
if (TB_parameters->nb_rb != 273) {
|
||||
a_segments = a_segments*TB_parameters->nb_rb;
|
||||
a_segments = a_segments/273 +1;
|
||||
a_segments = a_segments * TB_parameters->nb_rb;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
if (TB_parameters->C > a_segments) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
LOG_E(PHY, "Illegal harq_process->C %d > %d\n", harq_process->C, a_segments);
|
||||
return -1;
|
||||
}
|
||||
max_num_segments = max(max_num_segments, TB_parameters->C);
|
||||
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("ulsch decoding nr segmentation Z %d\n", TB_parameters->Z);
|
||||
if (!frame % 100)
|
||||
printf("K %d C %d Z %d \n",
|
||||
TB_parameters->K,
|
||||
TB_parameters->C,
|
||||
TB_parameters->Z);
|
||||
printf("Segmentation: C %d, K %d\n",
|
||||
TB_parameters->C,
|
||||
TB_parameters->K);
|
||||
printf("K %d C %d Z %d \n", TB_parameters->K, TB_parameters->C, TB_parameters->Z);
|
||||
printf("Segmentation: C %d, K %d\n", TB_parameters->C, TB_parameters->K);
|
||||
#endif
|
||||
|
||||
|
||||
TB_parameters->max_ldpc_iterations = ulsch->max_ldpc_iterations;
|
||||
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
TB_parameters->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
|
||||
TB_parameters->abort_decode = &harq_process->abort_decode;
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
|
||||
}
|
||||
|
||||
nrLDPC_segment_decoding_parameters_t segments[nb_pusch][max_num_segments];
|
||||
@@ -267,11 +255,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint32_t r_offset = 0;
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G,
|
||||
TB_parameters->C,
|
||||
TB_parameters->Qm,
|
||||
TB_parameters->nb_layers,
|
||||
r);
|
||||
segment_parameters->E = nr_get_E(TB_parameters->G, TB_parameters->C, TB_parameters->Qm, TB_parameters->nb_layers, r);
|
||||
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
|
||||
segment_parameters->E,
|
||||
TB_parameters->BG,
|
||||
@@ -296,7 +280,6 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
harq_process->harq_to_be_cleared = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
@@ -314,7 +297,9 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB_parameters.segments[r];
|
||||
// Copy c to b in case of decoding success
|
||||
if (nrLDPC_segment_decoding_parameters.decodeSuccess) {
|
||||
memcpy(harq_process->b + offset, harq_process->c[r], (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
memcpy(harq_process->b + offset,
|
||||
harq_process->c[r],
|
||||
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
} else {
|
||||
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
|
||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||
|
||||
Reference in New Issue
Block a user