diff --git a/ci-scripts/xml_files/ldpc_gpu_test.xml b/ci-scripts/xml_files/ldpc_gpu_test.xml index f129d6bd2b..bee9035c8b 100644 --- a/ci-scripts/xml_files/ldpc_gpu_test.xml +++ b/ci-scripts/xml_files/ldpc_gpu_test.xml @@ -25,7 +25,10 @@ test-ldpc-gpu Test-ldpc-GPU tasks - 000002 000003 000004 000005 000006 000007 000008 000009 000010 000011 000012 000013 000014 000015 000016 000017 000018 000019 000020 000021 + + 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 + @@ -188,6 +191,166 @@ -l 8448 -s10 -n100 -G 1 + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 1 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 1 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 100 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 100 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 193 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 193 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 500 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 500 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 561 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 561 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 600 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 600 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 641 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 641 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 2000 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 2000 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 3000 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 3000 -s10 -n100 -G 1 + + + + Run_Physim + Run LDPC Test with CPU + true + ldpctest + -l 3840 -s10 -n100 + + + + Run_Physim + Run LDPC Test with GPU + true + ldpctest + -l 3840 -s10 -n100 -G 1 + + diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 80f18e98a7..6d9d64bce2 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -66,16 +66,26 @@ - 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) + 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) ldpctest -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 - test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 + -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 + test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 BLER 0.000000 segmentation fault|assertion|exiting|fatal|differ 3 diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index 0fa81f360b..5912c9d0b4 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -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 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); } diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c index 95141e8845..b51712ed71 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c @@ -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; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index d64c32059c..29ea38232c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -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 #include -//#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_txnb_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_txnb_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_idnum_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; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index c61898e9bb..667c7146b0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -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 -//#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);