diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e04fc535b..f9f55511a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -827,21 +827,13 @@ add_custom_target( nrLDPC_decoder_kernels_CL COMMAND gcc ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c -dD -DNRLDPC_KERNEL_SOURCE -E -o ${CMAKE_CURRENT_BINARY_DIR}/nrLDPC_decoder_kernels_CL.clc SOURCES ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c ) - -set(PHY_NR_CODINGIF - ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c; -) - -add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} ) -target_link_libraries(ldpc_orig PRIVATE ldpc_gen_HEADERS) -add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} ) -target_link_libraries(ldpc_optim PRIVATE ldpc_gen_HEADERS) -add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} ) -target_link_libraries(ldpc_optim8seg PRIVATE ldpc_gen_HEADERS) add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} ) target_link_libraries(ldpc_cl OpenCL) add_dependencies(ldpc_cl nrLDPC_decoder_kernels_CL) +set(PHY_NR_CODINGIF + ${OPENAIR1_DIR}/PHY/CODING/nrLDPC_load.c +) ############################################## # Base CUDA setting @@ -859,13 +851,6 @@ if (ENABLE_LDPC_CUDA) endif() endif() -add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) -target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS) - -add_library(ldpc_parityCheck MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} ) -target_compile_definitions(ldpc_parityCheck PUBLIC NR_LDPC_ENABLE_PARITY_CHECK) -target_link_libraries(ldpc_parityCheck PRIVATE ldpc_gen_HEADERS) - add_library(coding MODULE ${PHY_TURBOSRC} ) add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts_neon.c) @@ -2190,12 +2175,12 @@ add_executable(ldpctest ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/ldpctest.c ) -add_dependencies( ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc ldpc_parityCheck) +add_dependencies(ldpctest ldpc_orig ldpc_optim ldpc_optim8seg ldpc) if (ENABLE_LDPC_CUDA) add_dependencies(ldpctest ldpc_cuda) endif() target_link_libraries(ldpctest PRIVATE - -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON -Wl,--end-group m pthread dl shlib_loader ${T_LIB} ) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 12362105bd..034eb8a5e5 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -428,6 +428,9 @@ static void get_channel_model_mode(configmodule_interface_t *cfg) int NB_UE_INST = 1; configmodule_interface_t *uniqCfg = NULL; +// A global var to reduce the changes size +ldpc_interface_t ldpc_interface = {0}; + int main( int argc, char **argv ) { int set_exe_prio = 1; if (checkIfFedoraDistribution()) @@ -465,8 +468,8 @@ int main( int argc, char **argv ) { itti_init(TASK_MAX, tasks_info); init_opt() ; - load_nrLDPClib(NULL); - + load_LDPClib(NULL, &ldpc_interface); + if (ouput_vcd) { vcd_signal_dumper_init("/tmp/openair_dump_nrUE.vcd"); } diff --git a/openair1/PHY/CODING/TESTBENCH/ldpctest.c b/openair1/PHY/CODING/TESTBENCH/ldpctest.c index f8a49e2199..7a3d299139 100644 --- a/openair1/PHY/CODING/TESTBENCH/ldpctest.c +++ b/openair1/PHY/CODING/TESTBENCH/ldpctest.c @@ -42,6 +42,7 @@ #define NR_LDPC_PROFILER_DETAIL #define NR_LDPC_ENABLE_PARITY_CHECK +ldpc_interface_t ldpc_orig, ldpc_toCompare; // 4-bit quantizer int8_t quantize4bit(double D,double x) @@ -77,49 +78,48 @@ int8_t quantize8bit(double D,double x) } typedef struct { - double n_iter_mean[400]; - double n_iter_std[400]; - int n_iter_max[400]; - double snr[400]; - double ber[400]; - double bler[400]; + double n_iter_mean; + double n_iter_std; + int n_iter_max; + double snr; + double ber; + double bler; } n_iter_stats_t; -nrLDPC_encoderfunc_t encoder_orig; +typedef struct { + unsigned int errors; + unsigned int errors_bit; + double errors_bit_uncoded; + unsigned int crc_misses; + time_stats_t time_optim; + time_stats_t time_decoder; + n_iter_stats_t dec_iter; +} one_measurement_t; -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}; - -int test_ldpc(short max_iterations, - int nom_rate, - int denom_rate, - double SNR, - uint8_t qbits, - short block_length, - unsigned int ntrials, - int n_segments, - unsigned int *errors, - unsigned int *errors_bit, - double *errors_bit_uncoded, - unsigned int *crc_misses, - time_stats_t *time_optim, - time_stats_t *time_decoder, - n_iter_stats_t *dec_iter, - int nsnr) +one_measurement_t test_ldpc(short max_iterations, + int nom_rate, + int denom_rate, + double SNR, + unsigned char qbits, + short block_length, + 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; double n_iter_mean = 0; double n_iter_std = 0; int n_iter_max = 0; - unsigned int segment_bler = 0; double sigma; sigma = 1.0/sqrt(2*SNR); opp_enabled=1; //short test_input[block_length]; - uint8_t *test_input[MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};; - //short *c; //padded codeword + 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]; memset(estimated_output, 0, sizeof(estimated_output)); uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; @@ -128,11 +128,8 @@ int test_ldpc(short max_iterations, 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 no_punctured_columns,removed_bit; - int i1,Zc,Kb=0; + int i1, Kb = 0; int R_ind = 0; - //Table of possible lifting sizes - //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}; //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}; @@ -143,24 +140,17 @@ int test_ldpc(short max_iterations, int32_t n_iter = 0; - *errors=0; - *errors_bit=0; - *errors_bit_uncoded=0; - *crc_misses=0; - // generate input block for(int j=0;j3840) - { + if (block_length > 3840) { BG = 1; Kb = 22; - nrows = 46; //parity check bits - //ncols=22; //info bits - } - else if (block_length<=3840) - { + nrows = 46; // parity check bits + // ncols=22; //info bits + } else { BG = 2; - nrows = 42; //parity check bits - //ncols=10; // info bits - - if (block_length>640) + nrows = 42; // parity check bits + // ncols=10; // info bits + if (block_length > 640) Kb = 10; - else if (block_length>560) + else if (block_length > 560) Kb = 9; - else if (block_length>192) + else if (block_length > 192) Kb = 8; else Kb = 6; } - if (nom_rate == 1) - if (denom_rate == 5) - if (BG == 2) - R_ind = 0; - else - printf("Not supported"); - else if (denom_rate == 3) - R_ind = 1; - else if (denom_rate == 2) - //R_ind = 3; - printf("Not supported"); - else - printf("Not supported"); + bool error = false; + switch (nom_rate) { + case 1: + if (denom_rate == 5) + if (BG == 2) + R_ind = 0; + else + error = true; + else if (denom_rate == 3) + R_ind = 1; + else if (denom_rate == 2) + // R_ind = 3; + error = true; + else + error = true; + break; + case 2: + if (denom_rate == 5) + // R_ind = 2; + error = true; + else if (denom_rate == 3) + R_ind = 4; + else + error = true; + break; + case 22: + if (denom_rate == 25 && BG == 1) + R_ind = 7; + else + error = true; + break; + default: + error = true; + } - else if (nom_rate == 2) - if (denom_rate == 5) - //R_ind = 2; - printf("Not supported"); - else if (denom_rate == 3) - R_ind = 4; - else - printf("Not supported"); + if (error) { + printf("Not supported: nom_rate: %d, denom_rate: %d\n", nom_rate, denom_rate); + exit(1); + } - else if ((nom_rate == 22) && (denom_rate == 30)) - //R_ind = 5; - printf("Not supported"); - else if ((nom_rate == 22) && (denom_rate == 27)) - //R_ind = 6; - printf("Not supported"); - else if ((nom_rate == 22) && (denom_rate == 25)) - if (BG == 1) - R_ind = 7; - else - printf("Not supported"); - else - printf("Not supported"); - - //find minimum value in all sets of lifting size - Zc=0; - - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { + // 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}; + for (i1 = 0; i1 < 51; i1++) { + if (lift_size[i1] >= (double)block_length / Kb) { Zc = lift_size[i1]; - //printf("%d\n",Zc); 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); - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc; + const int no_punctured_columns = + (int)((nrows - 2) * Zc + block_length - block_length * (1 / ((float)nom_rate / (float)denom_rate))) / Zc; // printf("puncture:%d\n",no_punctured_columns); - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate)); - encoder_implemparams_t impp=INIT0_LDPCIMPLEMPARAMS; + const int removed_bit = + (nrows - no_punctured_columns - 2) * Zc + block_length - (int)(block_length / ((float)nom_rate / (float)denom_rate)); + printf("nrows: %d\n", nrows); + printf("no_punctured_columns: %d\n", no_punctured_columns); + printf("removed_bit: %d\n", removed_bit); + 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, .E = block_length, .BG = BG, .Kr = block_length, .K = block_length}; impp.gen_code = 2; + if (ntrials==0) - encoder_orig(test_input,channel_input, Zc, BG, block_length, BG, &impp); + ldpc_orig.LDPCencoder(test_input, channel_input, &impp); impp.gen_code=0; decode_abort_t dec_abort; init_abort(&dec_abort); - for (int trial=0; trial < ntrials; trial++) - { - segment_bler = 0; + for (int trial = 0; trial < ntrials; trial++) { + unsigned int segment_bler = 0; //// encoder start_meas(&time); - for(int j=0;j>(i&7); - uint8_t inputbit = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments - if (estoutputbit != inputbit) - *errors_bit = (*errors_bit) + 1; - } - - n_iter_mean += n_iter; - n_iter_std += pow(n_iter-1,2); - - if ( n_iter > n_iter_max ) - n_iter_max = n_iter; - - } // end segments - - if (segment_bler != 0) - *errors = (*errors) + 1; - + decParams[j].E = block_length; + 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); + stop_meas(&ret.time_decoder); + // count errors + if (memcmp(estimated_output[j], test_input[j], block_length / 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++; + } + + n_iter_mean += n_iter; + n_iter_std += pow(n_iter - 1, 2); + + if (n_iter > n_iter_max) + n_iter_max = n_iter; + + } // end segments + + if (segment_bler != 0) + ret.errors++; } + 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)); + ret.dec_iter.n_iter_max = n_iter_max - 1; - dec_iter->n_iter_mean[nsnr] = n_iter_mean/(double)ntrials/(double)n_segments - 1; - dec_iter->n_iter_std[nsnr] = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2)); - dec_iter->n_iter_max[nsnr] = n_iter_max -1; + ret.errors_bit_uncoded = ret.errors_bit_uncoded / (double)((Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit); - *errors_bit_uncoded = *errors_bit_uncoded / (double)((Kb+nrows-no_punctured_columns-2) * Zc-removed_bit); - - for(int j=0;j 1280, 2401 -> 2560 // default to check output inside ldpc, the NR version checks the outer CRC defined by 3GPP - char *ldpc_version = "_parityCheck"; + 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; @@ -446,25 +410,22 @@ int main(int argc, char *argv[]) int nom_rate=1; int denom_rate=3; - double SNR0=-2.0,SNR,SNR_lin; + 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, i1 = 0; + int c, i = 0; int n_trials = 1; double SNR_step = 0.1; randominit(0); int test_uncoded= 0; + n_iter_stats_t dec_iter[400] = {0}; - time_stats_t time_optim[10], time_decoder[10]; - n_iter_stats_t dec_iter; - - short BG=0,Zc,Kb=0; + short BG = 0, Zc; while ((c = getopt (argc, argv, "q:r:s:S:l:G:n:d:i:t:u:hv:")) != -1) - switch (c) - { + switch (c) { case 'q': qbits = atoi(optarg); break; @@ -509,29 +470,29 @@ int main(int argc, char *argv[]) test_uncoded = atoi(optarg); break; case 'v': - ldpc_version=strdup(optarg); + ldpc_version = strdup(optarg); break; 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("-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("-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"); - printf("-s SNR per information bit (EbNo) in dB, Default: -2\n"); - printf("-S Number of segments (Maximum: 8), Default: 1\n"); - 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"); - exit(1); - break; + 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("-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("-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"); + printf("-s SNR per information bit (EbNo) in dB, Default: -2\n"); + printf("-S Number of segments (Maximum: 8), Default: 1\n"); + 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"); + exit(1); + break; } //printf("the decoder supports BG2, Kb=10, Z=128 & 256\n"); //printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n"); @@ -539,48 +500,13 @@ int main(int argc, char *argv[]) printf("n_trials %d: \n", n_trials); printf("SNR0 %f: \n", SNR0); - load_nrLDPClib(ldpc_version); - load_nrLDPClib_ref("_orig", &encoder_orig); + load_LDPClib(ldpc_version, &ldpc_toCompare); + load_LDPClib("_orig", &ldpc_orig); //for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8) - - //determine number of bits in codeword - if (block_length>3840) - { - BG = 1; - Kb = 22; - //nrows=46; //parity check bits - //ncols=22; //info bits - } - else if (block_length<=3840) - { - BG = 2; - //nrows=42; //parity check bits - //ncols=10; // info bits - - if (block_length>640) - Kb = 10; - else if (block_length>560) - Kb = 9; - else if (block_length>192) - Kb = 8; - else - Kb = 6; - } - //find minimum value in all sets of lifting size Zc=0; - for (i1=0; i1 < 51; i1++) - { - if (lift_size[i1] >= (double) block_length/Kb) - { - Zc = lift_size[i1]; - //printf("%d\n",Zc); - break; - } - } - 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"); @@ -588,75 +514,72 @@ int main(int argc, char *argv[]) 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 (SNR=SNR0;SNRdiff/time_optim->trials/1000.0/get_cpu_freq_GHz()); - printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2))); - printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/get_cpu_freq_GHz()); + 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()); printf("\n"); - printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz()); - printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2))); - printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/get_cpu_freq_GHz()); + 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()); - 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)errors_bit/(double)n_trials/(double)block_length/(double)n_segments , - errors_bit_uncoded/(double)n_trials/(double)n_segments , - (double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(), - sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)), - (double)time_optim->max/1000.0/get_cpu_freq_GHz(), - (double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(), - sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)), - (double)time_decoder->max/1000.0/get_cpu_freq_GHz(), - dec_iter.n_iter_mean[i], - dec_iter.n_iter_std[i], - dec_iter.n_iter_max[i] - ); + 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, + 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(), + dec_iter[i].n_iter_mean, + dec_iter[i].n_iter_std, + dec_iter[i].n_iter_max); i=i+1; - if (decoded_errors[i-1] == 0) break; - + if (decoded_errors[i - 1] == 0) + break; } fclose(fd); - LOG_M("ldpctestStats.m","SNR",&dec_iter.snr[0],i,1,7); - LOG_MM("ldpctestStats.m","BLER",&dec_iter.bler[0],i,1,7); - LOG_MM("ldpctestStats.m","BER",&dec_iter.ber[0],i,1,7); - LOG_MM("ldpctestStats.m","meanIter",&dec_iter.n_iter_mean[0],i,1,7); + LOG_M("ldpctestStats.m", "SNR", &dec_iter[0].snr, i, 1, 7); + LOG_MM("ldpctestStats.m", "BLER", &dec_iter[0].bler, i, 1, 7); + LOG_MM("ldpctestStats.m", "BER", &dec_iter[0].ber, i, 1, 7); + LOG_MM("ldpctestStats.m", "meanIter", &dec_iter[0].n_iter_mean, i, 1, 7); loader_reset(); logTerm(); diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c index 5f56879eba..4ac8f4799e 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c @@ -133,14 +133,24 @@ #include "bnProc128/nrLDPC_bnProc_BG2_R23_128.h" #endif -//#define NR_LDPC_ENABLE_PARITY_CHECK //#define NR_LDPC_PROFILER_DETAIL(a) a #define NR_LDPC_PROFILER_DETAIL(a) +#include "openair1/PHY/CODING/nrLDPC_extern.h" + #ifdef NR_LDPC_DEBUG_MODE #include "nrLDPC_tools/nrLDPC_debug.h" #endif +// decoder interface +/** + \brief LDPC decoder API type definition + \param p_decParams LDPC decoder parameters + \param p_llr Input LLRs + \param p_llrOut Output vector + \param p_profiler LDPC profiler statistics +*/ + static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_out, uint32_t numLLR, @@ -148,13 +158,25 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_time_stats* p_profiler, decode_abort_t* ab); -void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { + +int32_t LDPCinit() +{ + return 0; } -int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, - int8_t* p_llr, - int8_t* p_out, - t_nrLDPC_time_stats* p_profiler, - decode_abort_t* ab) + +int32_t LDPCshutdown() +{ + return 0; +} + +int32_t LDPCdecoder(t_nrLDPC_dec_params* p_decParams, + uint8_t harq_pid, + uint8_t ulsch_id, + uint8_t C, + int8_t* p_llr, + int8_t* p_out, + t_nrLDPC_time_stats* p_profiler, + decode_abort_t* ab) { uint32_t numLLR; t_nrLDPC_lut lut; @@ -817,31 +839,30 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, #endif // Parity Check -#ifdef NR_LDPC_ENABLE_PARITY_CHECK - NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->cnProcPc)); - if (BG == 1) - pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); - else - pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z); - NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cnProcPc)); -#else - if (numIter > 2) { - int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; - int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; - nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); - if (outMode == nrLDPC_outMode_BIT) - nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); - else // if (outMode == nrLDPC_outMode_BITINT8) - nrLDPC_llr2bit(p_out, p_llrOut, numLLR); - if (check_crc((uint8_t*)p_out, p_decParams->block_length, p_decParams->crc_type)) { - LOG_D(PHY, "Segment CRC OK, exiting LDPC decoder\n"); - break; + if (!p_decParams->check_crc) { + NR_LDPC_PROFILER_DETAIL(start_meas(&p_profiler->cnProcPc)); + if (BG == 1) + pcRes = nrLDPC_cnProcPc_BG1(p_lut, cnProcBuf, cnProcBufRes, Z); + else + pcRes = nrLDPC_cnProcPc_BG2(p_lut, cnProcBuf, cnProcBufRes, Z); + NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->cnProcPc)); + } else { + if (numIter > 2) { + int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; + int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; + nrLDPC_llrRes2llrOut(p_lut, p_llrOut, llrRes, Z, BG); + if (outMode == nrLDPC_outMode_BIT) + nrLDPC_llr2bitPacked(p_out, p_llrOut, numLLR); + else // if (outMode == nrLDPC_outMode_BITINT8) + nrLDPC_llr2bit(p_out, p_llrOut, numLLR); + if (p_decParams->check_crc((uint8_t*)p_out, p_decParams->E, p_decParams->crc_type)) { + LOG_D(PHY, "Segment CRC OK, exiting LDPC decoder\n"); + break; + } } } -#endif } -#ifdef NR_LDPC_ENABLE_PARITY_CHECK - { + if (!p_decParams->check_crc) { int8_t llrOut[NR_LDPC_MAX_NUM_LLR] __attribute__((aligned(64))) = {0}; int8_t* p_llrOut = outMode == nrLDPC_outMode_LLRINT8 ? p_out : llrOut; // Assign results from processing buffer to output @@ -856,7 +877,6 @@ static inline uint32_t nrLDPC_decoder_core(int8_t* p_llr, nrLDPC_llr2bit(p_out, p_llrOut, numLLR); NR_LDPC_PROFILER_DETAIL(stop_meas(&p_profiler->llr2bit)); } -#endif return numIter; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c index 74b3dbb41b..4e219c2273 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_CL.c @@ -47,8 +47,7 @@ typedef struct{ #include #include #include -#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" -#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "assertions.h" #include "common/utils/LOG/log.h" @@ -135,9 +134,9 @@ void set_compact_BG(int Zc,short BG){ } printf("\nZc = %d BG = %d\n",Zc,BG); ocl.runtime[0].dev_h_compact1 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact1, NULL, (cl_int *)&rt); - AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact1 for platform %i \n" , (int)rt, 0); + AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact1 for platform %i \n" , (int)rt, 0); ocl.runtime[0].dev_h_compact2 = clCreateBuffer(ocl.runtime[0].context, CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY, memorySize_h_compact2, NULL, (cl_int *)&rt); - AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact2 for platform %i \n" , (int)rt, 0); + AssertFatal(rt == CL_SUCCESS, "Error %d creating buffer dev_h_compact2 for platform %i \n" , (int)rt, 0); h_element *h1; h_element *h2; switch(lift_index){ @@ -328,18 +327,23 @@ int ldpc_autoinit(void) { // called by the library loader return 0; } - -void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { - set_compact_BG(p_decParams->Z,p_decParams->BG); -// init_LLR_DMA(p_decParams, p_llr, p_out); +int32_t LDPCshutdown() +{ + return 0; } -int32_t nrLDPC_decod(t_nrLDPC_dec_params *p_decParams, - int8_t *p_llr, - int8_t *p_out, - t_nrLDPC_procBuf *p_procBuf, - t_nrLDPC_time_stats *time_decoder, - decode_abort_t *ab) +int32_t LDPCinit() +{ + // init_LLR_DMA(p_decParams, p_llr, p_out); + return 0; +} + +int32_t LDPCdecoder(t_nrLDPC_dec_params *p_decParams, + int8_t *p_llr, + int8_t *p_out, + t_nrLDPC_procBuf *p_procBuf, + t_nrLDPC_time_stats *time_decoder, + decode_abort_t *ab) { uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; @@ -362,12 +366,14 @@ int32_t nrLDPC_decod(t_nrLDPC_dec_params *p_decParams, int memorySize_llr = col * Zc * sizeof(char) * MC; // cudaCheck( cudaMemcpyToSymbol(dev_const_llr, p_llr, memorySize_llr_cuda) ); // cudaCheck( cudaMemcpyToSymbol(dev_llr, p_llr, memorySize_llr_cuda) ); - int rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_const_llr, CL_TRUE, 0, - memorySize_llr, p_llr, 0, NULL, NULL); - AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read only memory in pltf %i dev %i\n" , (int)rt, 0,0); + set_compact_BG(p_decParams->Z, p_decParams->BG); + + int rt = + clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_const_llr, CL_TRUE, 0, memorySize_llr, p_llr, 0, NULL, NULL); + AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read only memory in pltf %i dev %i\n" , (int)rt, 0,0); rt = clEnqueueWriteBuffer(ocl.runtime[0].queue[0], ocl.runtime[0].dev_llr, CL_TRUE, 0, memorySize_llr, p_llr, 0, NULL, NULL); - AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read-write memory in pltf %i dev %i\n" , (int)rt, 0,0); + AssertFatal(rt == CL_SUCCESS, "Error %d moving p_llr data to read-write memory in pltf %i dev %i\n" , (int)rt, 0,0); // Define CUDA kernel dimension // int blockSizeX = Zc; // dim3 dimGridKernel1(row, MC, 1); // dim of the thread blocks diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h index 981debf5c7..3679020149 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h @@ -85,10 +85,15 @@ typedef struct nrLDPC_dec_params { uint8_t BG; /**< Base graph */ uint16_t Z; /**< Lifting size */ uint8_t R; /**< Decoding rate: Format 15,13,... for code rates 1/5, 1/3,... */ + uint16_t F; /**< Filler bits */ + uint8_t Qm; /**< Modulation */ + uint8_t rv; uint8_t numMaxIter; /**< Maximum number of iterations */ int block_length; + int E; e_nrLDPC_outMode outMode; /**< Output format */ int crc_type; + int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type); } t_nrLDPC_dec_params; /** diff --git a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu index 4c678699b5..a3c3f06c2e 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu +++ b/openair1/PHY/CODING/nrLDPC_decoder_LYC/nrLDPC_decoder_LYC.cu @@ -524,15 +524,21 @@ int ldpc_autoinit(void) { // called by the library loader return 0; } -extern "C" -void nrLDPC_initcall(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) { - set_compact_BG(p_decParams->Z,p_decParams->BG); - init_LLR_DMA(p_decParams, p_llr, p_out); +extern "C" void LDPCinit(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out) +{ + set_compact_BG(p_decParams->Z, p_decParams->BG); + init_LLR_DMA(p_decParams, p_llr, p_out); } +extern "C" void LDPCshutdown() +{ +} -extern "C" -int32_t nrLDPC_decod(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out,t_nrLDPC_procBuf* p_procBuf, t_nrLDPC_time_stats *time_decoder) +extern "C" int32_t LDPCdecoder(t_nrLDPC_dec_params* p_decParams, + int8_t* p_llr, + int8_t* p_out, + t_nrLDPC_procBuf* p_procBuf, + t_nrLDPC_time_stats* time_decoder) { uint16_t Zc = p_decParams->Z; uint8_t BG = p_decParams->BG; diff --git a/openair1/PHY/CODING/nrLDPC_defs.h b/openair1/PHY/CODING/nrLDPC_defs.h index 70021b64a8..c9e5454087 100644 --- a/openair1/PHY/CODING/nrLDPC_defs.h +++ b/openair1/PHY/CODING/nrLDPC_defs.h @@ -47,7 +47,7 @@ typedef struct { time_stats_t *toutput; int Kr; uint32_t Kb; - uint32_t *Zc; + uint32_t Zc; void *harq; /// Encoder BG uint8_t BG; @@ -57,13 +57,16 @@ typedef struct { uint32_t K; /// Number of "Filler" bits uint32_t F; - /// LDPC-code outputs - uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS]; + /// Modulation order + uint8_t Qm; + uint32_t E; + unsigned int G; + // Redundancy version index + uint8_t rv; } encoder_implemparams_t; -#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL} -typedef void(*nrLDPC_initcallfunc_t)(t_nrLDPC_dec_params *p_decParams, int8_t *p_llr, int8_t *p_out); -typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t *); -//============================================================================================================================ + +typedef int32_t(LDPC_initfunc_t)(void); +typedef int32_t(LDPC_shutdownfunc_t)(void); // decoder interface /** \brief LDPC decoder API type definition @@ -73,7 +76,14 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho \param p_profiler LDPC profiler statistics */ -typedef int32_t (*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_time_stats *, decode_abort_t *ab); -typedef int32_t(*nrLDPC_dectopfunc_t)(void); +typedef int32_t(LDPC_decoderfunc_t)(t_nrLDPC_dec_params *p_decParams, + uint8_t harq_pid, + uint8_t ulsch_id, + uint8_t C, + int8_t *p_llr, + int8_t *p_out, + t_nrLDPC_time_stats *, + decode_abort_t *ab); +typedef int32_t(LDPC_encoderfunc_t)(uint8_t **, uint8_t **, encoder_implemparams_t *); #endif diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c index 1e1b3c156f..f6d065a75b 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder.c @@ -38,44 +38,29 @@ #include "defs.h" #include "assertions.h" #include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "ldpc_generate_coefficient.c" - -int ldpc_encoder_orig(uint8_t *test_input,uint8_t *channel_input,int Zc,int Kb,short block_length, short BG,uint8_t gen_code) +int LDPCencoder(unsigned char **inputArray, unsigned char **outputArray, encoder_implemparams_t *impp) { + const unsigned char *input = inputArray[0]; + // channel input is the output of this function! + unsigned char *output = outputArray[0]; + const int Zc = impp->Zc; + const int Kb = impp->Kb; + const short block_length = impp->K; + const short BG = impp->BG; + const uint8_t gen_code = impp->gen_code; uint8_t c[22*384]; //padded input, unpacked, max size - uint8_t d[68*384]; //coded output, unpacked, max size - uint8_t channel_temp,temp; - short *Gen_shift_values, *no_shift_values, *pointer_shift_values; - - short nrows = 46;//parity check bits - short ncols = 22;//info bits - + uint8_t d[68 * 384]; // coded output, unpacked, max size int i,i1,i2,i3,i4,i5,temp_prime,var; - int no_punctured_columns,removed_bit,rate=3; + int no_punctured_columns, removed_bit; int nind=0; int indlist[1000]; int indlist2[1000]; - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - - Gen_shift_values=choose_generator_matrix(BG,Zc); + const short *Gen_shift_values = choose_generator_matrix(BG, Zc); if (Gen_shift_values==NULL) { printf("ldpc_encoder_orig: could not find generator matrix\n"); return(-1); @@ -83,21 +68,14 @@ int ldpc_encoder_orig(uint8_t *test_input,uint8_t *channel_input,int Zc,int Kb,s //printf("ldpc_encoder_orig: BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); + AssertFatal(BG <= 2, "BG %d is not supported yet\n", BG); // load base graph of generator matrix - if (BG==1) - { - no_shift_values=(short *) no_shift_values_BG1; - pointer_shift_values=(short *) pointer_shift_values_BG1; - } - else if (BG==2) - { - no_shift_values=(short *) no_shift_values_BG2; - pointer_shift_values=(short *) pointer_shift_values_BG2; - } - else { - AssertFatal(0,"BG %d is not supported yet\n",BG); - } - + const short nrows = BG == 1 ? 46 : 42; + const short ncols = BG == 1 ? 22 : 10; + const short rate = BG == 1 ? 3 : 5; + const short *no_shift_values = BG == 1 ? no_shift_values_BG1 : no_shift_values_BG2; + const short *pointer_shift_values = BG == 1 ? pointer_shift_values_BG1 : pointer_shift_values_BG2; + no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*rate); //printf("%d\n",no_punctured_columns); @@ -108,9 +86,9 @@ int ldpc_encoder_orig(uint8_t *test_input,uint8_t *channel_input,int Zc,int Kb,s for (i=0; i>7&1; - c[i]=(test_input[i/8]&(128>>(i&7)))>>(7-(i&7)); + // c[i] = input[i/8]<<(i%8); + // c[i]=c[i]>>7&1; + c[i] = (input[i / 8] & (128 >> (i & 7))) >> (7 - (i & 7)); } // parity check part @@ -188,10 +166,9 @@ int ldpc_encoder_orig(uint8_t *test_input,uint8_t *channel_input,int Zc,int Kb,s fprintf(fd2," c2=&csimd[i2];\n"); fprintf(fd2," d2=&dsimd[i2];\n"); - for (i1=0; i1 < nrows; i1++) + for (i1 = 0; i1 < nrows; i1++) { - channel_temp=0; fprintf(fd,"\n//row: %d\n",i1); fprintf(fd2,"\n//row: %d\n",i1); fprintf(fd," d2[%d]=",(Zc*i1)>>shift); @@ -225,8 +202,7 @@ int ldpc_encoder_orig(uint8_t *test_input,uint8_t *channel_input,int Zc,int Kb,s fprintf(fd2,"c2[%d]",indlist2[i4]); for (i4=0;i4gen_code); + memcpy(&output[0], &c[2 * Zc], block_length - 2 * Zc); + memcpy(&output[block_length - 2 * Zc], &d[0], (nrows - no_punctured_columns) * Zc - removed_bit); + // memcpy(output,c,Kb*Zc*sizeof(unsigned char)); + return block_length - 2 * Zc + (nrows - no_punctured_columns) * Zc - removed_bit; } diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c deleted file mode 100644 index 1cdb75f459..0000000000 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder2.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*!\file ldpc_encoder2.c - * \brief Defines the optimized LDPC encoder - * \author Florian Kaltenberger, Raymond Knopp, Kien le Trung (Eurecom) - * \email openair_tech@eurecom.fr - * \date 27-03-2018 - * \version 1.0 - * \note - * \warning - */ - -#include -#include -#include -#include -#include -#include "assertions.h" -#include "common/utils/LOG/log.h" -#include "time_meas.h" -#include "defs.h" -#include "PHY/sse_intrin.h" - -#include "ldpc384_byte.c" -#include "ldpc352_byte.c" -#include "ldpc320_byte.c" -#include "ldpc288_byte.c" -#include "ldpc256_byte.c" -#include "ldpc240_byte.c" -#include "ldpc224_byte.c" -#include "ldpc208_byte.c" -#include "ldpc192_byte.c" -#include "ldpc176_byte.c" -#include "ldpc384_byte_128.c" -#include "ldpc352_byte_128.c" -#include "ldpc320_byte_128.c" -#include "ldpc288_byte_128.c" -#include "ldpc256_byte_128.c" -#include "ldpc224_byte_128.c" -#include "ldpc192_byte_128.c" -#include "ldpc_BG2_Zc384_byte.c" -#include "ldpc_BG2_Zc352_byte.c" -#include "ldpc_BG2_Zc320_byte.c" -#include "ldpc_BG2_Zc288_byte.c" -#include "ldpc_BG2_Zc256_byte.c" -#include "ldpc_BG2_Zc240_byte.c" -#include "ldpc_BG2_Zc224_byte.c" -#include "ldpc_BG2_Zc208_byte.c" -#include "ldpc_BG2_Zc192_byte.c" -#include "ldpc_BG2_Zc176_byte.c" -#include "ldpc_BG2_Zc160_byte.c" -#include "ldpc_BG2_Zc144_byte.c" -#include "ldpc_BG2_Zc128_byte.c" -#include "ldpc_BG2_Zc120_byte.c" -#include "ldpc_BG2_Zc112_byte.c" -#include "ldpc_BG2_Zc104_byte.c" -#include "ldpc_BG2_Zc96_byte.c" -#include "ldpc_BG2_Zc88_byte.c" -#include "ldpc_BG2_Zc80_byte.c" -#include "ldpc_BG2_Zc72_byte.c" - - - -void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb) -{ - - if (BG==1) - { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: break; - case 80: break; - case 88: break; - case 96: break; - case 104: break; - case 112: break; - case 120: break; - case 128: break; - case 144: break; - case 160: break; - case 176: ldpc176_byte(c,d); break; - case 192: ldpc192_byte(c,d); break; - case 208: ldpc208_byte(c,d); break; - case 224: ldpc224_byte(c,d); break; - case 240: ldpc240_byte(c,d); break; - case 256: ldpc256_byte(c,d); break; - case 288: ldpc288_byte(c,d); break; - case 320: ldpc320_byte(c,d); break; - case 352: ldpc352_byte(c,d); break; - case 384: ldpc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else if (BG==2) { - switch (Zc) - { - case 2: break; - case 3: break; - case 4: break; - case 5: break; - case 6: break; - case 7: break; - case 8: break; - case 9: break; - case 10: break; - case 11: break; - case 12: break; - case 13: break; - case 14: break; - case 15: break; - case 16: break; - case 18: break; - case 20: break; - case 22: break; - case 24: break; - case 26: break; - case 28: break; - case 30: break; - case 32: break; - case 36: break; - case 40: break; - case 44: break; - case 48: break; - case 52: break; - case 56: break; - case 60: break; - case 64: break; - case 72: ldpc_BG2_Zc72_byte(c,d); break; - case 80: ldpc_BG2_Zc80_byte(c,d); break; - case 88: ldpc_BG2_Zc88_byte(c,d); break; - case 96: ldpc_BG2_Zc96_byte(c,d); break; - case 104: ldpc_BG2_Zc104_byte(c,d); break; - case 112: ldpc_BG2_Zc112_byte(c,d); break; - case 120: ldpc_BG2_Zc120_byte(c,d); break; - case 128: ldpc_BG2_Zc128_byte(c,d); break; - case 144: ldpc_BG2_Zc144_byte(c,d); break; - case 160: ldpc_BG2_Zc160_byte(c,d); break; - case 176: ldpc_BG2_Zc176_byte(c,d); break; - case 192: ldpc_BG2_Zc192_byte(c,d); break; - case 208: ldpc_BG2_Zc208_byte(c,d); break; - case 224: ldpc_BG2_Zc224_byte(c,d); break; - case 240: ldpc_BG2_Zc240_byte(c,d); break; - case 256: ldpc_BG2_Zc256_byte(c,d); break; - case 288: ldpc_BG2_Zc288_byte(c,d); break; - case 320: ldpc_BG2_Zc320_byte(c,d); break; - case 352: ldpc_BG2_Zc352_byte(c,d); break; - case 384: ldpc_BG2_Zc384_byte(c,d); break; - default: AssertFatal(0,"BG %d Zc %d is not supported yet\n",BG,Zc); break; - } - } - else { - AssertFatal(0,"BG %d is not supported yet\n",BG); - } - -} - - -int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,int Zc,int Kb,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,rate=3; - int no_punctured_columns,removed_bit; - - int simd_size; - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - //BG=1; - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d\n",BG,Zc,Kb,block_length); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU %x %x %x %x\n",test_input[0],test_input[1],test_input[2],test_input[3]); -#endif - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - } - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1 8 bytes, pattern repeats. - simde__m256i zero256 = simde_mm256_setzero_si256(); - simde__m256i masks[8]; - register simde__m256i c256; - masks[0] = simde_mm256_set1_epi8(0x1); - masks[1] = simde_mm256_set1_epi8(0x2); - masks[2] = simde_mm256_set1_epi8(0x4); - masks[3] = simde_mm256_set1_epi8(0x8); - masks[4] = simde_mm256_set1_epi8(0x10); - masks[5] = simde_mm256_set1_epi8(0x20); - masks[6] = simde_mm256_set1_epi8(0x40); - masks[7] = simde_mm256_set1_epi8(0x80); - - AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments); - - //determine number of bits in codeword - //if (block_length>3840) - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - //else if (block_length<=3840) - else if (BG==2) - { - //BG=2; - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - // printf("%d\n",no_punctured_columns); - // printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#else - for (i=0; i>5; i++) { - c256 = simde_mm256_and_si256(simde_mm256_cmpeq_epi8(simde_mm256_andnot_si256(simde_mm256_shuffle_epi8(simde_mm256_set1_epi32(((uint32_t*)test_input[0])[i]), shufmask),andmask),zero256),masks[0]); - for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << j); - } - } -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - simde__m256i *c256p = (simde__m256i *)&c[2 * Zc]; - simde__m256i *d256p = (simde__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>j)&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - for (j=0; j>j)&1; - } - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - -int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput) -{ - - short nrows=0,ncols=0; - int i,i1,j,rate=3; - int no_punctured_columns,removed_bit; - //Table of possible lifting sizes - char temp; - int simd_size; - unsigned int macro_segment, macro_segment_end; - - - macro_segment = 8*macro_num; - macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments; - //macro_segment_end = macro_segment + (n_segments > 8 ? 8 : n_segments); - //printf("macro_segment: %d\n", macro_segment); - //printf("macro_segment_end: %d\n", macro_segment_end ); - - simde__m256i shufmask = simde_mm256_set_epi64x(0x0303030303030303, 0x0202020202020202, 0x0101010101010101, 0x0000000000000000); - simde__m256i andmask = simde_mm256_set1_epi64x(0x0102040810204080); // every 8 bits -> 8 bytes, pattern repeats. - simde__m256i zero256 = simde_mm256_setzero_si256(); - simde__m256i masks[8]; - register simde__m256i c256; - masks[0] = simde_mm256_set1_epi8(0x1); - masks[1] = simde_mm256_set1_epi8(0x2); - masks[2] = simde_mm256_set1_epi8(0x4); - masks[3] = simde_mm256_set1_epi8(0x8); - masks[4] = simde_mm256_set1_epi8(0x10); - masks[5] = simde_mm256_set1_epi8(0x20); - masks[6] = simde_mm256_set1_epi8(0x40); - masks[7] = simde_mm256_set1_epi8(0x80); - - //determine number of bits in codeword - if (BG==1) - { - nrows=46; //parity check bits - ncols=22; //info bits - rate=3; - } - else if (BG==2) - { - nrows=42; //parity check bits - ncols=10; // info bits - rate=5; - } - -#ifdef DEBUG_LDPC - LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments); - LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]); -#endif - - AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length); - - if ((Zc&31) > 0) simd_size = 16; - else simd_size = 32; - - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size - - unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c - - // calculate number of punctured bits - no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); - //printf("%d\n",no_punctured_columns); - //printf("%d\n",removed_bit); - // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); - - if(tinput != NULL) start_meas(tinput); -#if 0 - for (i=0; i>(i&7); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#else - for (i=0; i>5; i++) { - c256 = simde_mm256_and_si256(simde_mm256_cmpeq_epi8(simde_mm256_andnot_si256(simde_mm256_shuffle_epi8(simde_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]); - //for (j=1; j>5)<<5;i>(i&7)))>>(7-(i&7)); - //printf("c(%d,%d)=%d\n",j,i,temp); - c[i] |= (temp << (j-macro_segment)); - } - } -#endif - - if(tinput != NULL) stop_meas(tinput); - - if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) { - // extend matrix - if(tprep != NULL) start_meas(tprep); - for (i1=0; i1 < ncols; i1++) - { - memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char)); - } - for (i1=1;i1>5; - uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5; - simde__m256i *c256p = (simde__m256i *)&c[2 * Zc]; - simde__m256i *d256p = (simde__m256i *)&d[0]; - // if (((block_length-(2*Zc))&31)>0) l1++; - - for (i=0;i0) l2++; - - for (i1=0;i1>(j-macro_segment))&1; - for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++) - //for (j=0; j>(j-macro_segment))&1; - } - - if(toutput != NULL) stop_meas(toutput); - return 0; -} - diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c index bf1e6f3400..bf663e0204 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim.c @@ -37,15 +37,17 @@ #include "common/utils/LOG/log.h" #include "time_meas.h" #include "openair1/PHY/CODING/nrLDPC_defs.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "ldpc_encode_parity_check.c" #include "ldpc_generate_coefficient.c" - - -int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +int LDPCencoder(uint8_t **test_input, uint8_t **channel_input, encoder_implemparams_t *impp) { - - short nrows=0,ncols=0; + int Zc = impp->Zc; + int Kb = impp->Kb; + int block_length = impp->K; + int BG = impp->BG; + int nrows=0,ncols=0; int rate=3; int no_punctured_columns,removed_bit; @@ -79,17 +81,17 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc if ((Zc&31) > 0) simd_size = 16; else simd_size = 32; - unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size - unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size + uint8_t c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size + uint8_t d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size // calculate number of punctured bits no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc; - removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate); + removed_bit = (nrows - no_punctured_columns - 2) * Zc + block_length - block_length * rate; // printf("%d\n",no_punctured_columns); // printf("%d\n",removed_bit); // unpack input - memset(c,0,sizeof(unsigned char) * ncols * Zc); - memset(d,0,sizeof(unsigned char) * nrows * Zc); + memset(c, 0, sizeof(c)); + memset(d, 0, sizeof(d)); if(impp->tinput != NULL) start_meas(impp->tinput); for (int i=0; iZc; + int Kb = impp->Kb; + short block_length = impp->K; + short BG = impp->BG; short nrows=0,ncols=0; int i,i1,j,rate=3; diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c index 7bbe9dfa78..6b48fee6fa 100644 --- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c +++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_encoder_optim8segmulti.c @@ -38,15 +38,19 @@ #include "time_meas.h" #include "openair1/PHY/CODING/nrLDPC_defs.h" #include "PHY/sse_intrin.h" +#include "openair1/PHY/CODING/nrLDPC_extern.h" #include "ldpc_encode_parity_check.c" #include "ldpc_generate_coefficient.c" - -int nrLDPC_encod(unsigned char **input,unsigned char **output,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) +int LDPCencoder(uint8_t **input, uint8_t **output, encoder_implemparams_t *impp) { //set_log(PHY, 4); - + + int Zc = impp->Zc; + int Kb = impp->Kb; + short block_length = impp->K; + short BG = impp->BG; int nrows=0,ncols=0; int rate=3; diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h index b3c02105d8..82f587aa37 100644 --- a/openair1/PHY/CODING/nrLDPC_extern.h +++ b/openair1/PHY/CODING/nrLDPC_extern.h @@ -18,24 +18,29 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ +#ifndef _NRLDPC_EXTERN_H__ +#define _NRLDPC_EXTERN_H__ #include "openair1/PHY/CODING/nrLDPC_defs.h" -#ifdef LDPC_LOADER -nrLDPC_decoderfunc_t nrLDPC_decoder; -nrLDPC_encoderfunc_t nrLDPC_encoder; -nrLDPC_initcallfunc_t nrLDPC_initcall; -nrLDPC_dectopfunc_t top_testsuite; -#else +/* ldpc coder/decoder API*/ +typedef struct ldpc_interface_s { + LDPC_initfunc_t *LDPCinit; + LDPC_shutdownfunc_t *LDPCshutdown; + LDPC_decoderfunc_t *LDPCdecoder; + LDPC_encoderfunc_t *LDPCencoder; +} ldpc_interface_t; + +// Global var to limit the rework of the dirty legacy code +extern ldpc_interface_t ldpc_interface; + /* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */ -int load_nrLDPClib(char *version); -int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t *nrLDPC_encoder_ptr); // for ldpctest -/* ldpc coder/decoder functions, as loaded by load_nrLDPClib(). */ -extern nrLDPC_initcallfunc_t nrLDPC_initcall; +int load_LDPClib(char *version, ldpc_interface_t *); +int free_LDPClib(ldpc_interface_t *ldpc_interface); -extern nrLDPC_decoderfunc_t nrLDPC_decoder; -extern nrLDPC_encoderfunc_t nrLDPC_encoder; - -extern nrLDPC_dectopfunc_t top_testsuite; +LDPC_initfunc_t LDPCinit; +LDPC_shutdownfunc_t LDPCshutdown; +LDPC_decoderfunc_t LDPCdecoder; +LDPC_encoderfunc_t LDPCencoder; // inline functions: #endif diff --git a/openair1/PHY/CODING/nrLDPC_load.c b/openair1/PHY/CODING/nrLDPC_load.c index 20c4064a24..b80887c327 100644 --- a/openair1/PHY/CODING/nrLDPC_load.c +++ b/openair1/PHY/CODING/nrLDPC_load.c @@ -35,20 +35,16 @@ #include #include "assertions.h" #include "common/utils/LOG/log.h" -#define LDPC_LOADER #include "PHY/CODING/nrLDPC_extern.h" -#include "common/config/config_userapi.h" -#include "common/utils/load_module_shlib.h" - - -/* function description array, to be used when loading the encoding/decoding shared lib */ -static loader_shlibfunc_t shlib_fdesc[3]; +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" /* arguments used when called from phy simulators exec's which do not use the config module */ /* arg is used to initialize the config module so that the loader works as expected */ char *arg[64]={"ldpctest",NULL}; -int load_nrLDPClib(char *version) { +int load_LDPClib(char *version, ldpc_interface_t *itf) +{ char *ptr = (char *)config_get_if(); char libname[64] = "ldpc"; @@ -56,26 +52,25 @@ int load_nrLDPClib(char *version) { uniqCfg = load_configmodule(1, arg, CONFIG_ENABLECMDLINEONLY); logInit(); } - shlib_fdesc[0].fname = "nrLDPC_decod"; - shlib_fdesc[1].fname = "nrLDPC_encod"; - shlib_fdesc[2].fname = "nrLDPC_initcall"; + /* function description array, to be used when loading the encoding/decoding shared lib */ + loader_shlibfunc_t shlib_fdesc[] = {{.fname = "LDPCinit"}, + {.fname = "LDPCshutdown"}, + {.fname = "LDPCdecoder"}, + {.fname = "LDPCencoder"}}; int ret; ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), NULL); AssertFatal((ret >= 0), "Error loading ldpc decoder"); - nrLDPC_decoder = (nrLDPC_decoderfunc_t)shlib_fdesc[0].fptr; - nrLDPC_encoder = (nrLDPC_encoderfunc_t)shlib_fdesc[1].fptr; - nrLDPC_initcall = (nrLDPC_initcallfunc_t)shlib_fdesc[2].fptr; + itf->LDPCinit = (LDPC_initfunc_t *)shlib_fdesc[0].fptr; + itf->LDPCshutdown = (LDPC_shutdownfunc_t *)shlib_fdesc[1].fptr; + itf->LDPCdecoder = (LDPC_decoderfunc_t *)shlib_fdesc[2].fptr; + itf->LDPCencoder = (LDPC_encoderfunc_t *)shlib_fdesc[3].fptr; + + AssertFatal(itf->LDPCinit() == 0, "error starting LDPC library %s %s\n", libname, version); + return 0; } -int load_nrLDPClib_ref(char *libversion, nrLDPC_encoderfunc_t * nrLDPC_encoder_ptr) { - loader_shlibfunc_t shlib_encoder_fdesc; - - shlib_encoder_fdesc.fname = "nrLDPC_encod"; - int ret=load_module_version_shlib("ldpc",libversion,&shlib_encoder_fdesc,1,NULL); - AssertFatal( (ret >= 0),"Error loading ldpc encoder %s\n",(libversion==NULL)?"":libversion); - *nrLDPC_encoder_ptr = (nrLDPC_encoderfunc_t)shlib_encoder_fdesc.fptr; -return 0; +int free_LDPClib(ldpc_interface_t *ldpc_interface) +{ + return ldpc_interface->LDPCshutdown(); } - - diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 8d4493f821..f3fda0969f 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -501,6 +501,9 @@ int init_codebook_gNB(PHY_VARS_gNB *gNB) { return 0; } +// A global var to reduce the changes size +ldpc_interface_t ldpc_interface = {0}; + int phy_init_nr_gNB(PHY_VARS_gNB *gNB) { // shortcuts @@ -528,7 +531,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB) nr_init_fde(); // Init array for frequency equalization of transform precoding of PUSCH - load_nrLDPClib(NULL); + load_LDPClib(NULL, &ldpc_interface); gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 4521c08673..0779812a5f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -163,7 +163,6 @@ void ldpc8blocks(void *p) { encoder_implemparams_t *impp=(encoder_implemparams_t *) p; NR_DL_gNB_HARQ_t *harq = (NR_DL_gNB_HARQ_t *)impp->harq; - uint16_t Kr = impp->K; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; uint8_t mod_order = rel15->qamModOrder[0]; uint16_t nb_rb = rel15->rbSize; @@ -183,9 +182,10 @@ void ldpc8blocks(void *p) // nrLDPC_encoder output is in "d" // let's make this interface happy! uint8_t tmp[8][68 * 384]__attribute__((aligned(32))); + uint8_t *d[impp->n_segments]; for (int rr=impp->macro_num*8, i=0; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++,i++ ) - impp->d[rr]=tmp[i]; - nrLDPC_encoder(harq->c,impp->d,*impp->Zc, impp->Kb,Kr,impp->BG,impp); + d[rr] = tmp[i]; + ldpc_interface.LDPCencoder(harq->c, d, impp); // Compute where to place in output buffer that is concatenation of all segments uint32_t r_offset=0; for (int i=0; i < impp->macro_num*8; i++ ) @@ -193,7 +193,7 @@ void ldpc8blocks(void *p) for (int rr=impp->macro_num*8; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++ ) { if (impp->F>0) { // writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212 - memset(&impp->d[rr][Kr-impp->F-2*(*impp->Zc)], NR_NULL, impp->F); + memset(&d[rr][impp->K - impp->F - 2 * impp->Zc], NR_NULL, impp->F); } #ifdef DEBUG_DLSCH_CODING @@ -201,14 +201,18 @@ void ldpc8blocks(void *p) #endif uint32_t E = nr_get_E(G, impp->n_segments, mod_order, rel15->nrOfLayers, rr); //#ifdef DEBUG_DLSCH_CODING - LOG_D(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d,nrOfLayer %d)...\n", + LOG_D(NR_PHY, + "Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb " + "%d,nrOfLayer %d)...\n", rr, impp->n_segments, G, E, impp->F, - Kr-impp->F-2*(*impp->Zc), - mod_order,nb_rb,rel15->nrOfLayers); + impp->K - impp->F - 2 * impp->Zc, + mod_order, + nb_rb, + rel15->nrOfLayers); uint32_t Tbslbrm = rel15->maintenance_parms_v3.tbSizeLbrmBytes; @@ -216,27 +220,38 @@ void ldpc8blocks(void *p) bzero (e, E); nr_rate_matching_ldpc(Tbslbrm, impp->BG, - *impp->Zc, - impp->d[rr], + impp->Zc, + d[rr], e, impp->n_segments, impp->F, - Kr-impp->F-2*(*impp->Zc), + impp->K - impp->F - 2 * impp->Zc, rel15->rvIndex[0], E); - if (Kr-impp->F-2*(*impp->Zc)> E) { - LOG_E(PHY,"dlsch coding A %d Kr %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", - A,impp->K,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,(int)mod_order); - - LOG_E(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n", - rr, - impp->n_segments, - G, - E, - Kr, - impp->F, - Kr-impp->F-2*(*impp->Zc), - mod_order,nb_rb); + if (impp->K - impp->F - 2 * impp->Zc > E) { + LOG_E(PHY, + "dlsch coding A %d Kr %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n", + A, + impp->K, + G, + nb_rb, + nb_symb_sch, + nb_re_dmrs, + length_dmrs, + (int)mod_order); + + LOG_E(NR_PHY, + "Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, " + "nb_rb %d)...\n", + rr, + impp->n_segments, + G, + E, + impp->K, + impp->F, + impp->K - impp->F - 2 * impp->Zc, + mod_order, + nb_rb); } #ifdef DEBUG_DLSCH_CODING @@ -279,7 +294,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, impp.output=output; unsigned int crc=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; - impp.Zc = &harq->Z; + impp.Zc = harq->Z; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN); uint32_t A = rel15->TBSize[0]<<3; unsigned char *a=harq->pdu; @@ -335,14 +350,13 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, impp.BG = rel15->maintenance_parms_v3.ldpcBaseGraph; start_meas(dlsch_segmentation_stats); - impp.Kb = nr_segmentation(harq->b, harq->c, B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG); + impp.Kb = nr_segmentation(harq->b, harq->c, B, &impp.n_segments, &impp.K, &impp.Zc, &impp.F, impp.BG); stop_meas(dlsch_segmentation_stats); if (impp.n_segments>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) { LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", impp.n_segments, B); return(-1); } - for (int r=0; rd[r][0]; //channel_input[r] = &harq->d[r][0]; @@ -365,27 +379,26 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, impp.tinput = tinput; impp.tparity = tparity; impp.toutput = toutput; - - impp.harq=harq; + impp.harq = harq; notifiedFIFO_t nf; initNotifiedFIFO(&nf); - int nbJobs=0; - for(int j=0; j<(impp.n_segments/8+((impp.n_segments&7)==0 ? 0 : 1)); j++) { - notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(impp), j, &nf, ldpc8blocks); - encoder_implemparams_t* perJobImpp=(encoder_implemparams_t*)NotifiedFifoData(req); - *perJobImpp=impp; - perJobImpp->macro_num=j; + int nbJobs = 0; + for (int j = 0; j < (impp.n_segments / 8 + ((impp.n_segments & 7) == 0 ? 0 : 1)); j++) { + notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(impp), j, &nf, ldpc8blocks); + encoder_implemparams_t *perJobImpp = (encoder_implemparams_t *)NotifiedFifoData(req); + *perJobImpp = impp; + perJobImpp->macro_num = j; pushTpool(&gNB->threadPool, req); nbJobs++; } - while(nbJobs) { - notifiedFIFO_elt_t *req=pullTpool(&nf, &gNB->threadPool); + while (nbJobs) { + notifiedFIFO_elt_t *req = pullTpool(&nf, &gNB->threadPool); if (req == NULL) break; // Tpool has been stopped delNotifiedFIFO_elt(req); nbJobs--; - } + 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 9c513afecf..b43c67e6b9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -187,7 +187,7 @@ static void nr_processULSegment(void *arg) memset(ulsch_harq->c[r], 0, Kr_bytes); p_decoderParms->crc_type = crcType(ulsch_harq->C, A); - p_decoderParms->block_length = lenWithCrc(ulsch_harq->C, A); + p_decoderParms->E = p_decoderParms->block_length = lenWithCrc(ulsch_harq->C, A); // start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); // set first 2*Z_c bits to zeros @@ -215,7 +215,8 @@ static void nr_processULSegment(void *arg) ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// - rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode); + rdata->decodeIterations = + ldpc_interface.LDPCdecoder(p_decoderParms, 0, 0, 0, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode); if (rdata->decodeIterations <= p_decoderParms->numMaxIter) memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3); @@ -257,7 +258,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->processedSegments = 0; harq_process->TBS = pusch_pdu->pusch_data.tb_size; - t_nrLDPC_dec_params decParams = {0}; + t_nrLDPC_dec_params decParams = {.check_crc = check_crc}; decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph; const uint32_t A = (harq_process->TBS) << 3; NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 19f133ff9a..34affedf88 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -252,10 +252,10 @@ static void nr_processDLSegment(void *arg) } //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN); - p_decoderParms->block_length = lenWithCrc(harq_process->C, A); + p_decoderParms->E = p_decoderParms->block_length = lenWithCrc(harq_process->C, A); p_decoderParms->crc_type = crcType(harq_process->C, A); - nrLDPC_initcall(p_decoderParms, (int8_t *)&pl[0], LDPCoutput); - rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], LDPCoutput, &procTime, &harq_process->abort_decode); + rdata->decodeIterations = + ldpc_interface.LDPCdecoder(p_decoderParms, 0, 0, 0, l, LDPCoutput, &procTime, &harq_process->abort_decode); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT); if (rdata->decodeIterations <= dlsch->max_ldpc_iterations) @@ -281,7 +281,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint32_t ret,offset; uint32_t r,r_offset=0,Kr=8424,Kr_bytes; t_nrLDPC_dec_params decParams; - t_nrLDPC_dec_params *p_decParams = &decParams; + decParams.check_crc = check_crc; if (!harq_process) { LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n"); @@ -348,8 +348,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d Coderate %f\n", frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.mcs, dlsch->Nl, nb_symb_sch, nb_rb, dlsch->dlsch_config.qamModOrder, Coderate); - p_decParams->BG = get_BG(A, dlsch->dlsch_config.targetCodeRate); - unsigned int kc = p_decParams->BG == 2 ? 52 : 68; + decParams.BG = get_BG(A, dlsch->dlsch_config.targetCodeRate); + unsigned int kc = decParams.BG == 2 ? 52 : 68; if (harq_process->first_rx == 1) { // This is a new packet, so compute quantities regarding segmentation @@ -360,7 +360,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, &harq_process->K, &harq_process->Z, // [hna] Z is Zc &harq_process->F, - p_decParams->BG); + decParams.BG); if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) { LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, A); @@ -375,11 +375,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); - p_decParams->Z = harq_process->Z; - //printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); - //printf("coderate %f kc %d \n", Coderate, kc); - p_decParams->numMaxIter = dlsch->max_ldpc_iterations; - p_decParams->outMode= 0; + decParams.Z = harq_process->Z; + decParams.numMaxIter = dlsch->max_ldpc_iterations; + decParams.outMode = 0; r_offset = 0; uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl; //number of segments to be allocated @@ -396,7 +394,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); - Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" + Kr = harq_process->K; Kr_bytes = Kr>>3; offset = 0; notifiedFIFO_t nf; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 1c4d7c0fec..ca9d020c8e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -57,11 +57,10 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid]; uint16_t nb_rb = ulsch->pusch_pdu.rb_size; uint32_t A = tb_size << 3; - uint32_t *pz = &harq_process->Z; uint8_t mod_order = ulsch->pusch_pdu.qam_mod_order; - uint16_t Kr=0; - uint32_t r_offset=0; - uint32_t F=0; + uint16_t Kr = 0; + uint32_t r_offset = 0; + uint32_t F = 0; // target_code_rate is in 0.1 units float Coderate = (float) ulsch->pusch_pdu.target_code_rate / 10240.0f; @@ -72,9 +71,11 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, ulsch->pusch_pdu.nrOfLayers); LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G, mod_order, Coderate); - LOG_D(NR_PHY, "harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n", - harq_pid,harq_process->ndi,ulsch->pusch_pdu.pusch_data.new_data_indicator); - + LOG_D(NR_PHY, + "harq_pid %d harq_process->ndi %d, pusch_data.new_data_indicator %d\n", + harq_pid, + harq_process->ndi, + ulsch->pusch_pdu.pusch_data.new_data_indicator); if (harq_process->first_tx == 1 || harq_process->ndi != ulsch->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet #ifdef DEBUG_ULSCH_CODING @@ -140,7 +141,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, B, &harq_process->C, &harq_process->K, - pz, + &harq_process->Z, &harq_process->F, harq_process->BG); @@ -161,7 +162,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, ///////////////////////// c---->| LDCP coding |---->d ///////////////////////// /////////// - //printf("segment Z %d k %d Kr %d BG %d\n", *pz,harq_process->K,Kr,BG); + // printf("segment Z %d k %d Kr %d BG %d\n", harq_process->Z,harq_process->K,Kr,BG); //start_meas(te_stats); for (int r=0; rC; r++) { @@ -170,7 +171,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, printf("Encoder: B %d F %d \n", B, harq_process->F); printf("start ldpc encoder segment %d/%d\n",r,harq_process->C); printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); - for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){ + for (int cnt = 0; cnt < 22 * harq_process->Z / 8; cnt++) { printf("%d ", harq_process->c[r][cnt]); } printf("\n"); @@ -183,28 +184,30 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, //for (int i=0;i<68*384;i++) // printf("channel_input[%d]=%d\n",i,channel_input[i]); - /*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]); - for (int cnt =0 ; cnt < 66*(*pz); cnt ++){ - printf("%d \n", harq_process->d[0][cnt]); + /*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], + harq_process->d[0][4]); for (int cnt =0 ; cnt < 66*harq_process->Z; cnt ++){ printf("%d \n", harq_process->d[0][cnt]); } printf("\n");*/ - encoder_implemparams_t impp = { - .n_segments=harq_process->C, - .macro_num=0, - .tinput = NULL, - .tprep = NULL, - .tparity = NULL, - .toutput = NULL}; + encoder_implemparams_t impp = {.n_segments = harq_process->C, + .macro_num = 0, + .K = harq_process->K, + .Kb = Kb, + .Zc = harq_process->Z, + .BG = harq_process->BG, + .tinput = NULL, + .tprep = NULL, + .tparity = NULL, + .toutput = NULL}; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN); start_meas(&ue->ulsch_ldpc_encoding_stats); - for(int j = 0; j < (harq_process->C/8 + 1); j++) { + for (int j = 0; j < (harq_process->C / 8 + 1); j++) { impp.macro_num = j; - nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp); + impp.E = nr_get_E(G, harq_process->C, mod_order, ulsch->pusch_pdu.nrOfLayers, j); + impp.Kr = Kr; + ldpc_interface.LDPCencoder(harq_process->c, harq_process->d, &impp); } - stop_meas(&ue->ulsch_ldpc_encoding_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT); //stop_meas(te_stats); @@ -224,7 +227,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, for (int r=0; rC; r++) { // looping over C segments if (harq_process->F>0) { - for (int k=(Kr-F-2*(*pz)); kZ; k < Kr - 2 * harq_process->Z; k++) { harq_process->d[r][k] = NR_NULL; //if (k<(Kr-F+8)) //printf("r %d filler bits [%d] = %d \n", r,k, harq_process->d[r][k]); @@ -249,14 +252,15 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, start_meas(&ue->ulsch_rate_matching_stats); if (nr_rate_matching_ldpc(ulsch->pusch_pdu.tbslbrm, harq_process->BG, - *pz, + harq_process->Z, harq_process->d[r], - harq_process->e+r_offset, + harq_process->e + r_offset, harq_process->C, F, - Kr-F-2*(*pz), + Kr - F - 2 * harq_process->Z, ulsch->pusch_pdu.pusch_data.rv_index, - E) == -1) + E) + == -1) return -1; stop_meas(&ue->ulsch_rate_matching_stats); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 540fef1b38..6bd282c054 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -353,7 +353,7 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt(argc, argv, "f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) { + while ((c = getopt(argc, argv, "f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:c")) != -1) { switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -542,7 +542,30 @@ int main(int argc, char **argv) default: case 'h': - printf("%s -h(elp)\n", argv[0]); + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-L \n"); + //printf("-p Use extended prefix mode\n"); + //printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + //printf("-t Delay spread for multipath channel\n"); + printf("-g Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300, e.g. -g A\n"); + printf("-o Introduce delay in terms of number of samples\n"); + printf("-y Number of TX antennas used in gNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-x Num of layer for PDSCH\n"); + printf("-p Precoding matrix index\n"); + printf("-i Change channel estimation technique. Arguments list: Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}\n"); + //printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f raw file containing RRC configuration (generated by gNB)\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); printf("-a Start PRB for PDSCH\n"); printf("-b Number of PRB for PDSCH\n"); printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); @@ -1301,7 +1324,7 @@ int main(int argc, char **argv) free(UE->phy_sim_pdsch_dl_ch_estimates); free(UE->phy_sim_pdsch_dl_ch_estimates_ext); free(UE->phy_sim_dlsch_b); - + if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 70d592f019..8209088da8 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -789,7 +789,7 @@ int main(int argc, char *argv[]) ulsch_input_buffer[0] = 0x31; for (i = 1; i < TBS/8; i++) { - ulsch_input_buffer[i] = (unsigned char) uniformrandom(); + ulsch_input_buffer[i] = (uint8_t)rand(); } uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);