From dd374c7e039ac13ec549a6f2f77688bb4bcdb173 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 25 Mar 2022 09:16:19 +0100 Subject: [PATCH] add more detailed statistics to nr_dlsim output --- executables/softmodem-common.h | 2 + openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 + openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 8 ++ openair1/PHY/defs_gNB.h | 2 + openair1/SIMULATION/NR_PHY/dlsim.c | 150 ++++++++++++-------- 5 files changed, 104 insertions(+), 62 deletions(-) diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 48ce73149f..a404cd6c69 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -204,6 +204,7 @@ extern int usrp_tx_thread; #define SOFTMODEM_NONBIOT_BIT (1<<2) #define SOFTMODEM_RFSIM_BIT (1<<10) #define SOFTMODEM_SIML1_BIT (1<<12) +#define SOFTMODEM_DLSIM_BIT (1<<13) #define SOFTMODEM_DOSCOPE_BIT (1<<15) #define SOFTMODEM_RECPLAY_BIT (1<<16) #define SOFTMODEM_TELNETCLT_BIT (1<<17) @@ -220,6 +221,7 @@ extern int usrp_tx_thread; #define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) #define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) #define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) +#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT) #define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT) #define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT) #define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 47d6c48373..c46879e39c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -38,6 +38,7 @@ #include "PHY/NR_REFSIG/ptrs_nr.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/nr/nr_common.h" +#include "executables/softmodem-common.h" //#define DEBUG_DLSCH //#define DEBUG_DLSCH_MAPPING @@ -147,6 +148,9 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, printf("\n"); #endif + if (IS_SOFTMODEM_DLSIM) + memcpy(harq->f, output, encoded_length); + /// scrambling start_meas(dlsch_scrambling_stats); for (int q=0; qNrOfCodewords; q++) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 229f59032e..95305a7b07 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -69,6 +69,10 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, free16(harq->b, a_segments * 1056); harq->b = NULL; } + if (harq->f) { + free16(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + harq->f = NULL; + } for (int r = 0; r < a_segments; r++) { free(harq->c[r]); harq->c[r] = NULL; @@ -177,6 +181,10 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, bzero(harq->c[r], 8448); } + harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + 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); } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9be2d0208d..1f4d2d33b7 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -96,6 +96,8 @@ typedef struct { uint32_t subframe; /// MIMO mode for this DLSCH MIMO_mode_t mimo_mode; + /// Interleaver outputs + uint8_t *f; /// LDPC lifting size uint32_t Z; } NR_DL_gNB_HARQ_t; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 494c4e8e1d..6aeb7a7afc 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -354,10 +354,13 @@ int main(int argc, char **argv) int i,aa;//,l; double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; uint8_t snr1set=0; - double roundStats[500] = {0}; - double blerStats[500] = {0}; - double berStats[500] = {0}; - double snrStats[500] = {0}; + uint32_t errors_scrambling[4][100] = {{0}}; + int n_errors[4][100] = {{0}}; + int round_trials[4][100] = {{0}}; + double roundStats[100] = {0}; + double blerStats[4][100] = {{0}}; + double berStats[4][100] = {{0}}; + double snrStats[100] = {0}; float effRate; //float psnr; float eff_tp_check = 0.7; @@ -375,7 +378,7 @@ int main(int argc, char **argv) //int freq_offset; // int subframe_offset; // char fname[40], vname[40]; - int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; + int trial, n_trials = 1, n_false_positive = 0; //int n_errors2, n_alamouti; uint8_t n_tx=1,n_rx=1; uint8_t round; @@ -703,6 +706,7 @@ int main(int argc, char **argv) get_softmodem_params()->phy_test = 1; get_softmodem_params()->do_ra = 0; + set_softmodem_optmask(SOFTMODEM_DLSIM_BIT); if (snr1set==0) snr1 = snr0+10; @@ -981,7 +985,6 @@ int main(int argc, char **argv) unsigned char *estimated_output_bit; unsigned char *test_input_bit; unsigned int errors_bit = 0; - uint32_t errors_scrambling = 0; initTpool("N", &(nrUE_params.Tpool), false); @@ -1019,6 +1022,7 @@ int main(int argc, char **argv) nr_ue_phy_config_request(&UE_mac->phy_config); //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels; snrRun = 0; + int n_errs = 0; gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); initTpool(gNBthreads, gNB->threadPool, true); @@ -1052,11 +1056,9 @@ int main(int argc, char **argv) clear_pdsch_stats(gNB); - n_errors = 0; effRate = 0; //n_errors2 = 0; //n_alamouti = 0; - errors_scrambling=0; n_false_positive = 0; if (n_trials== 1) num_rounds = 1; @@ -1088,6 +1090,7 @@ int main(int argc, char **argv) UE_harq_process->first_rx = 1; while ((roundack==0)) { + round_trials[round][snrRun]++; clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); @@ -1259,49 +1262,45 @@ int main(int argc, char **argv) dlsch_threads, NULL); + //---------------------------------------------------------- + //---------------------- count errors ---------------------- + //---------------------------------------------------------- + + if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >= + UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1) + n_errors[round][snrRun]++; + + NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id]; + int16_t *UE_llr = pdsch_vars[0]->llr[0]; + + TBS = UE_harq_process->TBS;//rel15->TBSize[0]; + uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); + uint16_t nb_rb = rel15->rbSize; + uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups; + uint8_t mod_order = rel15->qamModOrder[0]; + uint8_t nb_symb_sch = rel15->NrOfSymbols; + + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers); + if(pdu_bit_map & 0x1) { + available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2); + printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) ); + } + + for (i = 0; i < available_bits; i++) { + if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) || + ((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0))) + { + if(errors_scrambling[round][snrRun] == 0) { + LOG_D(PHY,"First bit in error in unscrambling = %d\n",i); + } + errors_scrambling[round][snrRun]++; + } + } + //printf("dlsim round %d ends\n",round); round++; } // round - //---------------------------------------------------------- - //---------------------- count errors ---------------------- - //---------------------------------------------------------- - - if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >= - UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1) - n_errors++; - - //NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id]; - //int16_t *UE_llr = pdsch_vars[0]->llr[0]; - - TBS = UE_harq_process->TBS;//rel15->TBSize[0]; - uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); - uint16_t nb_rb = rel15->rbSize; - uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*UE_harq_process->n_dmrs_cdm_groups : 4*UE_harq_process->n_dmrs_cdm_groups; - uint8_t mod_order = rel15->qamModOrder[0]; - uint8_t nb_symb_sch = rel15->NrOfSymbols; - - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers); - if(pdu_bit_map & 0x1) { - available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2); - LOG_D(PHY,"[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) ); - } - - /* - for (i = 0; i < available_bits; i++) { - - if(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) || - ((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0))) - { - if(errors_scrambling == 0) { - LOG_D(PHY,"\n"); - LOG_D(PHY,"First bit in error in unscrambling = %d\n",i); - } - errors_scrambling++; - } - - } - */ for (i = 0; i < TBS; i++) { estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7); @@ -1309,7 +1308,7 @@ int main(int argc, char **argv) if (estimated_output_bit[i] != test_input_bit[i]) { if(errors_bit == 0) - LOG_D(PHY,"First bit in error in decoding = %d (errors scrambling %d)\n",i,errors_scrambling); + LOG_D(PHY,"First bit in error in decoding = %d\n",i); errors_bit++; } @@ -1317,11 +1316,6 @@ int main(int argc, char **argv) //////////////////////////////////////////////////////////// - if (errors_scrambling > 0) { - if (n_trials == 1) - printf("errors_scrambling = %u/%u (trial %d)\n", errors_scrambling, available_bits,trial); - } - if (errors_bit > 0) { n_false_positive++; if (n_trials == 1) @@ -1331,18 +1325,48 @@ int main(int argc, char **argv) if (UE_harq_process->ack==1) effRate += ((float)TBS)/round; } // noise trials - blerStats[snrRun] = (float) n_errors / (float) n_trials; roundStats[snrRun]/=((float)n_trials); - berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials; + + blerStats[0][snrRun] = (double)n_errors[0][snrRun]/round_trials[0][snrRun]; + blerStats[1][snrRun] = (double)n_errors[1][snrRun]/round_trials[1][snrRun]; + blerStats[2][snrRun] = (double)n_errors[2][snrRun]/round_trials[2][snrRun]; + blerStats[3][snrRun] = (double)n_errors[3][snrRun]/round_trials[3][snrRun]; + + berStats[0][snrRun] = (double)errors_scrambling[0][snrRun]/available_bits/round_trials[0][snrRun]; + berStats[1][snrRun] = (double)errors_scrambling[1][snrRun]/available_bits/round_trials[1][snrRun]; + berStats[2][snrRun] = (double)errors_scrambling[2][snrRun]/available_bits/round_trials[2][snrRun]; + berStats[3][snrRun] = (double)errors_scrambling[3][snrRun]/available_bits/round_trials[3][snrRun]; + effRate /= n_trials; printf("*****************************************\n"); - printf("SNR %f, (false positive %f)\n", SNR, - (float) n_errors / (float) n_trials); - printf("*****************************************\n"); + printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n", + SNR, + n_errors[0][snrRun], round_trials[0][snrRun], + n_errors[1][snrRun], round_trials[1][snrRun], + n_errors[2][snrRun], round_trials[2][snrRun], + n_errors[3][snrRun], round_trials[3][snrRun], + n_false_positive, n_trials, + errors_scrambling[0][snrRun], available_bits*round_trials[0][snrRun], + errors_scrambling[1][snrRun], available_bits*round_trials[1][snrRun], + errors_scrambling[2][snrRun], available_bits*round_trials[2][snrRun], + errors_scrambling[3][snrRun], available_bits*round_trials[3][snrRun]); printf("\n"); dump_pdsch_stats(stdout,gNB); - printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", - SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS); + printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", + SNR, + blerStats[0][snrRun], + blerStats[1][snrRun], + blerStats[2][snrRun], + blerStats[3][snrRun], + berStats[0][snrRun], + berStats[1][snrRun], + berStats[2][snrRun], + berStats[3][snrRun], + roundStats[snrRun], + effRate, + effRate/TBS*100, + TBS); + printf("*****************************************\n"); printf("\n"); if (print_perf==1) { @@ -1402,6 +1426,7 @@ int main(int argc, char **argv) LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); if (UE->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); + LOG_M("rxF0.m","rxF0", UE->common_vars.common_vars_rx_data_per_thread[UE_proc.thread_id].rxdataF[0], frame_parms->samples_per_slot_wCP, 1, 1); LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1); write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0); @@ -1417,6 +1442,7 @@ int main(int argc, char **argv) snrStats[snrRun] = SNR; snrRun++; + n_errs = n_errors[0][snrRun]; } // NSR LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7); @@ -1460,8 +1486,8 @@ int main(int argc, char **argv) if (scg_fd) fclose(scg_fd); - return(n_errors); - + + return n_errs; }