Commit 01431a0e authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/nrLDPC_coding_improvements_3' into...

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.
parents 76eb5c17 9dada89c
......@@ -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);
// 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();
// reset_meas(&decoder_profiler.total);
//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);
}
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment