From aadc28257005676b35234347a76bb63f7f043f79 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 7 Feb 2019 13:05:35 +0100 Subject: [PATCH 01/21] [ulschsim] Initial version (copy of dlschsim) --- cmake_targets/CMakeLists.txt | 3 + cmake_targets/build_oai | 2 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 672 ++++++++++++++++++++++++++ 3 files changed, 676 insertions(+), 1 deletion(-) create mode 100644 openair1/SIMULATION/NR_PHY/ulschsim.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index af9c3edf68..949731a021 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2557,6 +2557,9 @@ add_executable(nr_dlsim ${T_SOURCE}) target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) +add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c ${T_SOURCE}) +target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) + foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 3bbc1ccb71..596ff978f1 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -691,7 +691,7 @@ function main() { echo_info "Compiling unitary tests simulators" # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim #simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" - simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim" + simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim" for f in $simlist ; do compilations \ phy_simulators $f \ diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c new file mode 100644 index 0000000000..2b36a03e61 --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -0,0 +1,672 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include + +#include "common/config/config_userapi.h" +#include "common/utils/LOG/log.h" +#include "common/ran_context.h" + +#include "SIMULATION/TOOLS/sim.h" +#include "SIMULATION/RF/rf.h" +#include "PHY/types.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_nr_UE.h" +#include "PHY/defs_gNB.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_mod_table.h" +#include "PHY/MODULATION/modulation_eNB.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "SCHED_NR/sched_nr.h" + +//#include "PHY/MODULATION/modulation_common.h" +//#include "common/config/config_load_configmodule.h" +//#include "UTIL/LISTS/list.h" +//#include "common/ran_context.h" + +//#define DEBUG_DLSCHSIM + +PHY_VARS_gNB *gNB; +PHY_VARS_NR_UE *UE; +RAN_CONTEXT_t RC; + +double cpuf; + +// dummy functions +int nfapi_mode = 0; +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { + return (0); +} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { + return (0); +} + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { + return (0); +} + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { + return (0); +} + +int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { + return (0); +} + +uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_earfcn) { + return (0); +} +int32_t get_uldl_offset(int eutra_bandP) { + return (0); +} + +NR_IF_Module_t * +NR_IF_Module_init(int Mod_id) { + return (NULL); +} + +void exit_function(const char *file, const char *function, const int line, + const char *s) { + const char *msg = s == NULL ? "no comment" : s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} + +// needed for some functions +PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; +uint16_t n_rnti = 0x1234; + +char quantize(double D, double x, unsigned char B) { + double qxd; + short maxlev; + qxd = floor(x / D); + maxlev = 1 << (B - 1); //(char)(pow(2,B-1)); + + //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); + + if (qxd <= -maxlev) + qxd = -maxlev; + else if (qxd >= maxlev) + qxd = maxlev - 1; + + return ((char) qxd); +} + +int main(int argc, char **argv) { + char c; + int i; //,j,l,aa; + double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0; + double snr_step = 0.1; + uint8_t snr1set = 0; + int **txdata; + double **s_re, **s_im, **r_re, **r_im; + // int sync_pos, sync_pos_slot; + // FILE *rx_frame_file; + FILE *output_fd = NULL; + uint8_t write_output_file = 0; + // int subframe_offset; + // char fname[40], vname[40]; + int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; + uint8_t transmission_mode = 1, n_tx = 1, n_rx = 1; + uint16_t Nid_cell = 0; + channel_desc_t *gNB2UE; + uint8_t extended_prefix_flag = 0; + int8_t interf1 = -21, interf2 = -21; + FILE *input_fd = NULL, *pbch_file_fd = NULL; + //char input_val_str[50],input_val_str2[50]; + //uint16_t NB_RB=25; + SCM_t channel_model = AWGN; //Rayleigh1_anticorr; + uint16_t N_RB_DL = 106, mu = 1; + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + int frame = 0, subframe = 0; + int frame_length_complex_samples; + //int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + //nfapi_nr_config_request_t *gNB_config; + uint8_t Kmimo = 0; + uint32_t Nsoft = 0; + double sigma; + unsigned char qbits = 8; + int ret; + //int run_initial_sync=0; + int loglvl = OAILOG_WARNING; + float target_error_rate = 0.01; + + uint16_t nb_symb_sch = 12; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; + + cpuf = get_cpu_freq_GHz(); + + if (load_configmodule(argc, argv) == 0) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + //logInit(); + randominit(0); + + while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:N:F:R:P:")) != -1) { + switch (c) { + case 'f': + write_output_file = 1; + output_fd = fopen(optarg, "w"); + + if (output_fd == NULL) { + printf("Error opening %s\n", optarg); + exit(-1); + } + + break; + + case 'd': + frame_type = 1; + break; + + case 'g': + switch ((char) *optarg) { + case 'A': + channel_model = SCM_A; + break; + + case 'B': + channel_model = SCM_B; + break; + + case 'C': + channel_model = SCM_C; + break; + + case 'D': + channel_model = SCM_D; + break; + + case 'E': + channel_model = EPA; + break; + + case 'F': + channel_model = EVA; + break; + + case 'G': + channel_model = ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + + break; + + case 'i': + interf1 = atoi(optarg); + break; + + case 'j': + interf2 = atoi(optarg); + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n", snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set = 1; + msg("Setting SNR1 to %f\n", snr1); + break; + + case 'p': + extended_prefix_flag = 1; + break; + + /* + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } + break; + */ + + case 'y': + n_tx = atoi(optarg); + + if ((n_tx == 0) || (n_tx > 2)) { + msg("Unsupported number of tx antennas %d\n", n_tx); + exit(-1); + } + + break; + + case 'z': + n_rx = atoi(optarg); + + if ((n_rx == 0) || (n_rx > 2)) { + msg("Unsupported number of rx antennas %d\n", n_rx); + exit(-1); + } + + break; + + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; + + case 'F': + input_fd = fopen(optarg, "r"); + + if (input_fd == NULL) { + printf("Problem with filename %s\n", optarg); + exit(-1); + } + + break; + + case 'P': + pbch_phase = atoi(optarg); + + if (pbch_phase > 3) + printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); + + break; + + case 'm': + Imcs = atoi(optarg); + break; + + case 'l': + nb_symb_sch = atoi(optarg); + break; + + case 'r': + nb_rb = atoi(optarg); + break; + + case 'x': + transmission_mode = atoi(optarg); + break; + + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -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("-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 [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\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 Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit(-1); + break; + } + } + + logInit(); + set_glog(loglvl); + T_stdout = 1; + + if (snr1set == 0) + snr1 = snr0 + 10; + + gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, + 61.44e6, //N_RB2sampling_rate(N_RB_DL), + 40e6, //N_RB2channel_bandwidth(N_RB_DL), + 0, 0, 0); + + if (gNB2UE == NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **)); + RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *)); + RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); + gNB = RC.gNB[0][0]; + //gNB_config = &gNB->gNB_config; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_DL; + frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + crcTableInit(); + nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell); + phy_init_nr_gNB(gNB, 0, 0); + //init_eNB_afterRU(); + frame_length_complex_samples = frame_parms->samples_per_subframe; + //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + s_re = malloc(2 * sizeof(double *)); + s_im = malloc(2 * sizeof(double *)); + r_re = malloc(2 * sizeof(double *)); + r_im = malloc(2 * sizeof(double *)); + txdata = malloc(2 * sizeof(int *)); + + for (i = 0; i < 2; i++) { + s_re[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(s_re[i], frame_length_complex_samples * sizeof(double)); + s_im[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(s_im[i], frame_length_complex_samples * sizeof(double)); + r_re[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(r_re[i], frame_length_complex_samples * sizeof(double)); + r_im[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(r_im[i], frame_length_complex_samples * sizeof(double)); + txdata[i] = malloc(frame_length_complex_samples * sizeof(int)); + bzero(r_re[i], frame_length_complex_samples * sizeof(int)); + } + + if (pbch_file_fd != NULL) { + load_pbch_desc(pbch_file_fd); + } + + /* for (int k=0; k<2; k++) { + // Create transport channel structures for 2 transport blocks (MIMO) + for (i=0; i<2; i++) { + gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config); + + if (!gNB->dlsch[k][i]) { + printf("Can't get eNB dlsch structures\n"); + exit(-1); + } + gNB->dlsch[k][i]->Nsoft = 10; + gNB->dlsch[k][i]->rnti = n_rnti+k; + } + }*/ + //configure UE + UE = malloc(sizeof(PHY_VARS_NR_UE)); + memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + + //phy_init_nr_top(frame_parms); + if (init_nr_ue_signal(UE, 1, 0) != 0) { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + + //nr_init_frame_parms_ue(&UE->frame_parms); + //init_nr_ue_transport(UE, 0); + for (int sf = 0; sf < 2; sf++) { + for (i = 0; i < 2; i++) { + UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo, 8, Nsoft, 5, N_RB_DL, + 0); + + if (!UE->dlsch[sf][0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); + } + + UE->dlsch[sf][0][i]->rnti = n_rnti; + } + } + + UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); + UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); + unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; + NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; + nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; + //time_stats_t *rm_stats, *te_stats, *i_stats; + uint8_t is_crnti = 0, llr8_flag = 0; + unsigned int TBS = 8424; + unsigned int available_bits; + uint8_t nb_re_dmrs = 6; + uint16_t length_dmrs = 1; + unsigned char mod_order; + uint8_t Nl = 1; + uint8_t rvidx = 0; + dlsch->rnti = 1; + /*dlsch->harq_processes[0]->mcs = Imcs; + dlsch->harq_processes[0]->rvidx = rvidx;*/ + //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], + // dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl); + mod_order = nr_get_Qm(Imcs, 1); + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); + TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); + printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order); + //dlsch->harq_ids[subframe]= 0; + rel15->n_prb = nb_rb; + rel15->nb_symbols = nb_symb_sch; + rel15->modulation_order = mod_order; + rel15->nb_layers = Nl; + rel15->nb_re_dmrs = nb_re_dmrs; + rel15->transport_block_size = TBS; + double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); + short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); + short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); + double errors_bit_uncoded = 0; + unsigned char *estimated_output; + unsigned char *estimated_output_bit; + unsigned char *test_input_bit; + unsigned int errors_bit = 0; + test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0]; + NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; + harq_process->mcs = Imcs; + harq_process->Nl = Nl; + harq_process->nb_rb = nb_rb; + harq_process->Qm = mod_order; + harq_process->rvidx = rvidx; + printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); + unsigned char *test_input; + test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); + + for (i = 0; i < TBS / 8; i++) + test_input[i] = (unsigned char) rand(); + + estimated_output = harq_process->b; + +#ifdef DEBUG_DLSCHSIM + for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); +#endif + + /*for (int i=0; i0x%08x\n",crc24c(test_input, 32)); + // generate signal + if (input_fd == NULL) { + nr_dlsch_encoding(test_input, subframe, dlsch, frame_parms); + } + + for (SNR = snr0; SNR < snr1; SNR += snr_step) { + n_errors = 0; + n_false_positive = 0; + + for (trial = 0; trial < n_trials; trial++) { + errors_bit_uncoded = 0; + for (i = 0; i < available_bits; i++) { +#ifdef DEBUG_CODER + if ((i&0xf)==0) + printf("\ne %d..%d: ",i,i+15); +#endif + + //if (i<16) + // printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); + if (dlsch->harq_processes[0]->f[i] == 0) + modulated_input[i] = 1.0; ///sqrt(2); //QPSK + else + modulated_input[i] = -1.0; ///sqrt(2); + + //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); + //SNR =10; + SNR_lin = pow(10, SNR / 10.0); + sigma = 1.0 / sqrt(2 * SNR_lin); + channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, + modulated_input[i] + sigma * gaussdouble(0.0, 1.0), + qbits); + //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); + //printf("llr[%d]=%d\n",i,channel_output_fixed[i]); + //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); + + //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits); + + //if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]); + + //Uncoded BER + if (channel_output_fixed[i] < 0) + channel_output_uncoded[i] = 1; //QPSK demod + else + channel_output_uncoded[i] = 0; + + if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i]) + errors_bit_uncoded = errors_bit_uncoded + 1; + } + + //if (errors_bit_uncoded>10) + //printf("errors bits uncoded %f\n", errors_bit_uncoded); +#ifdef DEBUG_CODER + printf("\n"); + exit(-1); +#endif + ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms, + dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch, + subframe, harq_pid, is_crnti, llr8_flag); + + if (ret > dlsch0_ue->max_ldpc_iterations) + n_errors++; + + //count errors + errors_bit = 0; + + for (i = 0; i < TBS; i++) { + estimated_output_bit[i] = (dlsch0_ue->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments + + if (estimated_output_bit[i] != test_input_bit[i]) { + errors_bit++; + //printf("estimated bits error occurs @%d ",i); + } + } + + if (errors_bit > 0) { + n_false_positive++; + if (n_trials == 1) + printf("errors_bit %d (trial %d)\n", errors_bit, trial); + } + } + + printf("SNR %f, BLER %f (false positive %f)\n", SNR, + (float) n_errors / (float) n_trials, + (float) n_false_positive / (float) n_trials); + + if ((float) n_errors / (float) n_trials < target_error_rate) { + printf("PDSCH test OK\n"); + break; + } + } + + /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/ + + //TODO: loop over slots + /*for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + 14, + frame_parms); + } + } + + LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); + + + for (i=0; inb_antennas_tx; aa++) { + r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + } + }*/ + + for (i = 0; i < 2; i++) { + printf("gNB %d\n", i); + free_gNB_dlsch(gNB->dlsch[0][i]); + printf("UE %d\n", i); + free_nr_ue_dlsch(UE->dlsch[0][0][i]); + } + + for (i = 0; i < 2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + free(txdata[i]); + } + + free(s_re); + free(s_im); + free(r_re); + free(r_im); + free(txdata); + + if (output_fd) + fclose(output_fd); + + if (input_fd) + fclose(input_fd); + + return (n_errors); +} + From ad402982fe6a0deccaa0a90d30943c6e259c611e Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 7 Feb 2019 13:11:10 +0100 Subject: [PATCH 02/21] [ulschsim] Add support fo perfect channel (no noise) Also print the uncoded error bits --- openair1/SIMULATION/NR_PHY/ulschsim.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 2b36a03e61..72d4050f89 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -483,7 +483,7 @@ int main(int argc, char **argv) { double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); - double errors_bit_uncoded = 0; + unsigned int errors_bit_uncoded = 0; unsigned char *estimated_output; unsigned char *estimated_output_bit; unsigned char *test_input_bit; @@ -543,9 +543,13 @@ int main(int argc, char **argv) { //SNR =10; SNR_lin = pow(10, SNR / 10.0); sigma = 1.0 / sqrt(2 * SNR_lin); +#if 1 channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, modulated_input[i] + sigma * gaussdouble(0.0, 1.0), qbits); +#else + channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits); +#endif //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); //printf("llr[%d]=%d\n",i,channel_output_fixed[i]); //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); @@ -565,7 +569,7 @@ int main(int argc, char **argv) { } //if (errors_bit_uncoded>10) - //printf("errors bits uncoded %f\n", errors_bit_uncoded); + printf("errors bits uncoded %u\n", errors_bit_uncoded); #ifdef DEBUG_CODER printf("\n"); exit(-1); From 009b195d57fe3b8337fe9da6e5010daa55264dc2 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Wed, 13 Feb 2019 12:46:44 +0100 Subject: [PATCH 03/21] Initializing and freeing NR_UE_ULSCH_t. Creating nr_ulsch_coding.c --- cmake_targets/CMakeLists.txt | 1 + openair1/PHY/INIT/nr_init_ue.c | 12 +- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 4 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +- .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 41 ++-- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 204 ++++++++++++++++++ openair1/PHY/defs_nr_UE.h | 4 +- openair1/SCHED_NR_UE/harq_nr.c | 12 +- openair1/SCHED_NR_UE/harq_nr.h | 8 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 12 +- .../NR_UE_PHY/unit_tests/src/harq_test.c | 6 +- 11 files changed, 272 insertions(+), 36 deletions(-) create mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 949731a021..674d441dd9 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1304,6 +1304,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index a150717e42..7a4cd9f446 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -361,8 +361,13 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, uint16_t max_harq_tx ) { + int num_of_threads,num_of_code_words; + PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx; + + for (num_of_threads=0;num_of_threadsulsch[eNB_id][num_of_threads][num_of_code_words]->Mlimit = max_harq_tx; } extern uint16_t beta_cqi[16]; @@ -923,11 +928,12 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) { AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]); + + AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NUMBER_OF_HARQ_PID_MAX, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); + LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]); } } - //AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); - ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 7415b36281..7191e5f48b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -69,7 +69,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) #endif if (dlsch->harq_processes[i]->b) { - free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); + free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES dlsch->harq_processes[i]->b = NULL; #ifdef DEBUG_DLSCH_FREE printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b); @@ -196,7 +196,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, for (r=0; rharq_processes[i]->c[r] = (uint8_t*)malloc16(8448); - dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); + dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output if (dlsch->harq_processes[i]->c[r]) { bzero(dlsch->harq_processes[i]->c[r],8448); } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 3c272b9c17..2b8e0258e6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -61,10 +61,10 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch); NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag); -void free_ue_ulsch(NR_UE_ULSCH_t *ulsch); +void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch); -NR_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag); +NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag); void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 0760c44b53..1f99da06c0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -110,20 +110,24 @@ typedef struct { uint32_t B; /// Length of ACK information (bits) uint8_t O_ACK; - /// Pointer to the payload - uint8_t *b; - /// Pointers to transport block segments - uint8_t *c[MAX_NUM_ULSCH_SEGMENTS]; /// Index of current HARQ round for this ULSCH uint8_t round; /// MCS format of this ULSCH uint8_t mcs; /// Redundancy-version of the current sub-frame uint8_t rvidx; - /// LDPC-code outputs - uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448]; - /// Interleaver outputs - uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448]; + /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8) + uint8_t *a; + /// Pointer to the payload + CRC + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17) + uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; // 66*Z_c is the maximum LDPC block length. We use 68 for internal manipulation of the buffer + /// Rate matching (Bit selection) outputs (TS 36.212 V15.4.0, Sec 5.4.2.1 p. 28) + uint8_t *e[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30) + uint8_t *f[MAX_NUM_NR_ULSCH_SEGMENTS]; /// Number of code segments uint32_t C; /// Number of bits in code segments @@ -168,6 +172,7 @@ typedef struct { // UL number of harq processes uint8_t number_harq_processes_for_pusch; #endif + /* /// Pointer to CQI data (+1 for 8 bits crc) uint8_t o[1+MAX_CQI_BYTES]; /// Length of CQI data (bits) @@ -180,22 +185,25 @@ typedef struct { uint8_t O_RI; /// Pointer to ACK uint8_t o_ACK[4]; + */ /// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37) uint8_t O_CQI_MIN; /// ACK/NAK Bundling flag uint8_t bundling; - /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) - uint8_t e[MAX_NUM_CHANNEL_BITS]; + /// Concatenated "g"-sequences (for definition see 36-212 V15.4.0 2018-12, p.31) + uint8_t g[MAX_NUM_NR_CHANNEL_BITS]; /// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) - uint8_t h[MAX_NUM_CHANNEL_BITS]; + uint8_t h[MAX_NUM_NR_CHANNEL_BITS]; /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14) - uint8_t b_tilde[MAX_NUM_CHANNEL_BITS]; + uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS]; /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14) - int32_t d[MAX_NUM_RE]; + int32_t d[MAX_NUM_NR_RE]; /// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15) - int32_t z[MAX_NUM_RE]; + int32_t z[MAX_NUM_NR_RE]; + /* /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) uint8_t q[MAX_CQI_PAYLOAD]; + /// coded and interleaved CQI bits uint8_t o_w[(MAX_CQI_BITS+8)*3]; /// coded CQI bits @@ -204,6 +212,7 @@ typedef struct { uint8_t q_ACK[MAX_ACK_PAYLOAD]; /// coded RI bits uint8_t q_RI[MAX_RI_PAYLOAD]; + */ /// beta_offset_cqi times 8 uint16_t beta_offset_cqi_times8; /// beta_offset_ri times 8 @@ -229,9 +238,9 @@ typedef struct { /// num active cba group uint8_t num_active_cba_groups; /// num dci found for cba - uint8_t num_cba_dci[10]; + //uint8_t num_cba_dci[10]; /// allocated CBA RNTI - uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; + //uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; /// UL max-harq-retransmission uint8_t Mlimit; } NR_UE_ULSCH_t; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c new file mode 100644 index 0000000000..8ad2a8ecb4 --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -0,0 +1,204 @@ +/* + * 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 PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +* \brief Top-level routines for coding the ULSCH transport channel as described in 38.212 V15.4 2018-12 +* \author Khalid Ahmed +* \date 2019 +* \version 0.1 +* \company Fraunhofer IIS +* \email: khalid.ahmed@iis.fraunhofer.de +* \note +* \warning +*/ + +#include "PHY/defs_UE.h" +#include "PHY/phy_extern_ue.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/coding_extern.h" +#include "PHY/CODING/lte_interleaver_inline.h" +#include "PHY/CODING/nrLDPC_encoder/defs.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + + + + + +void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) +{ + int i; + int r; + + if (ulsch) { +#ifdef DEBUG_ULSCH_FREE + printf("Freeing ulsch %p\n",ulsch); +#endif + + for (i=0; iharq_processes[i]) { + if (ulsch->harq_processes[i]->b) { + free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); + ulsch->harq_processes[i]->b = NULL; + } + for (r=0; rharq_processes[i]->c[r]) { + free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); + ulsch->harq_processes[i]->c[r] = NULL; + } + + if (ulsch->harq_processes[i]->d[r]) { + free16(ulsch->harq_processes[i]->d[r],68*384); + ulsch->harq_processes[i]->d[r] = NULL; + } + + if (ulsch->harq_processes[i]->e[r]) { + free16(ulsch->harq_processes[i]->e[r],68*384); + ulsch->harq_processes[i]->e[r] = NULL; + } + + if (ulsch->harq_processes[i]->f[r]) { + free16(ulsch->harq_processes[i]->f[r],68*384); + ulsch->harq_processes[i]->f[r] = NULL; + } + + } + + free16(ulsch->harq_processes[i],sizeof(NR_UL_UE_HARQ_t)); + ulsch->harq_processes[i] = NULL; + } + } + free16(ulsch,sizeof(NR_UE_ULSCH_t)); + ulsch = NULL; + } + +} + +NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag) +{ + + NR_UE_ULSCH_t *ulsch; + unsigned char exit_flag = 0,i,j,r; + unsigned char bw_scaling =1; + + switch (N_RB_UL) { + + case 106: + bw_scaling =2; + break; + + default: + bw_scaling =1; + break; + } + + ulsch = (NR_UE_ULSCH_t *)malloc16(sizeof(NR_UE_ULSCH_t)); + + if (ulsch) { + memset(ulsch,0,sizeof(NR_UE_ULSCH_t)); + + ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES; + ulsch->Mlimit = 4; // maximum harq retransmissions + + for (i=0; iharq_processes[i] = (NR_UL_UE_HARQ_t *)malloc16(sizeof(NR_UL_UE_HARQ_t)); + + // printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]); + if (ulsch->harq_processes[i]) { + memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t)); + ulsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->a = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + + if (ulsch->harq_processes[i]->a) { + bzero(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + } else { + printf("Can't allocate PDU\n"); + exit_flag=1; + } + + if (ulsch->harq_processes[i]->b) + memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + else { + LOG_E(PHY,"Can't get b\n"); + exit_flag=1; + } + + if (abstraction_flag==0) { + for (r=0; rharq_processes[i]->c[r] = (uint8_t*)malloc16(8448); + ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output + ulsch->harq_processes[i]->e[r] = (uint8_t*)malloc16(68*384); + ulsch->harq_processes[i]->f[r] = (uint8_t*)malloc16(68*384); + if (ulsch->harq_processes[i]->c[r]) { + bzero(ulsch->harq_processes[i]->c[r],8448); + } else { + printf("Can't get c\n"); + exit_flag=2; + } + if (ulsch->harq_processes[i]->d[r]) { + bzero(ulsch->harq_processes[i]->d[r],(68*384)); + } else { + printf("Can't get d\n"); + exit_flag=2; + } + if (ulsch->harq_processes[i]->e[r]) { + bzero(ulsch->harq_processes[i]->e[r],(68*384)); + } else { + printf("Can't get e\n"); + exit_flag=2; + } + if (ulsch->harq_processes[i]->f[r]) { + bzero(ulsch->harq_processes[i]->f[r],(68*384)); + } else { + printf("Can't get f\n"); + exit_flag=2; + } + } + } + + ulsch->harq_processes[i]->subframe_scheduling_flag = 0; + ulsch->harq_processes[i]->first_tx = 1; + } else { + LOG_E(PHY,"Can't get harq_p %d\n",i); + exit_flag=3; + } + } + + if ((abstraction_flag == 0) && (exit_flag==0)) { + for (i=0; i<8; i++) + for (j=0; j<96; j++) + for (r=0; rharq_processes[i]->d[r][j] = NR_NULL; + + return(ulsch); + } else if (abstraction_flag==1) + return(ulsch); + } + + LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t)); + free_nr_ue_ulsch(ulsch); + return(NULL); + + +} \ No newline at end of file diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index a3c404ba61..10bfa46338 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -1044,8 +1044,8 @@ typedef struct { NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads - NR_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX]; + NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads + NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index 23d828ec93..31dcfcacbe 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -150,7 +150,7 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i * *********************************************************************/ -void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch) +void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch) { NR_UE_ULSCH_t *ulsch; @@ -160,7 +160,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h memset(ulsch,0,sizeof(NR_UE_ULSCH_t)); - ue->ulsch[gNB_id] = ulsch; + ue->ulsch[thread_id][gNB_id][code_word_idx] = ulsch; } else { LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__); @@ -185,7 +185,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h } for (int slot_tx = 0; slot_tx < NR_MAX_SLOTS_PER_FRAME; slot_tx++) { - ue->ulsch[gNB_id]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES; + ue->ulsch[thread_id][gNB_id][code_word_idx]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES; } } @@ -202,9 +202,9 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h * *********************************************************************/ -void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id) +void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx) { - NR_UE_ULSCH_t *ulsch = ue->ulsch[gNB_id]; + NR_UE_ULSCH_t *ulsch = ue->ulsch[thread_id][gNB_id][code_word_idx]; for (int process_id = 0; process_id < ulsch->number_harq_processes_for_pusch; process_id++) { @@ -215,7 +215,7 @@ void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id) free16(ulsch, sizeof(NR_UE_ULSCH_t)); - ue->ulsch[gNB_id] = NULL; + ue->ulsch[thread_id][gNB_id][code_word_idx] = NULL; } /******************************************************************* diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h index 2d3e87ddab..ee6e8625b0 100644 --- a/openair1/SCHED_NR_UE/harq_nr.h +++ b/openair1/SCHED_NR_UE/harq_nr.h @@ -83,17 +83,21 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i /** \brief This function configures uplink HARQ context @param PHY_VARS_NR_UE ue context @param gNB_id gNodeB identifier + @param thread_id RXTX thread index + @param code_word_idx code word index @param number_harq_processes_pusch maximum number of uplink HARQ processes @returns none */ -void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch); +void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch); /** \brief This function releases uplink HARQ context @param PHY_VARS_NR_UE ue context @param gNB_id gNodeB identifier + @param thread_id RXTX thread index + @param code_word_idx code word index @returns none */ -void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id); +void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx); /** \brief This function stores slot for transmission in HARQ context @param ulsch uplink context diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 72d4050f89..951d969c51 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -144,7 +144,7 @@ int main(int argc, char **argv) { //char input_val_str[50],input_val_str2[50]; //uint16_t NB_RB=25; SCM_t channel_model = AWGN; //Rayleigh1_anticorr; - uint16_t N_RB_DL = 106, mu = 1; + uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; unsigned char frame_type = 0; unsigned char pbch_phase = 0; int frame = 0, subframe = 0; @@ -291,6 +291,7 @@ int main(int argc, char **argv) { case 'R': N_RB_DL = atoi(optarg); + N_RB_UL = N_RB_DL; break; case 'F': @@ -381,6 +382,7 @@ int main(int argc, char **argv) { frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; frame_parms->N_RB_DL = N_RB_DL; + frame_parms->N_RB_UL = N_RB_UL; frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; crcTableInit(); nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell); @@ -446,6 +448,13 @@ int main(int argc, char **argv) { exit(-1); } + UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0); + + if (!UE->ulsch[sf][0][i]) { + printf("Can't get ue ulsch structures\n"); + exit(-1); + } + UE->dlsch[sf][0][i]->rnti = n_rnti; } } @@ -649,6 +658,7 @@ int main(int argc, char **argv) { free_gNB_dlsch(gNB->dlsch[0][i]); printf("UE %d\n", i); free_nr_ue_dlsch(UE->dlsch[0][0][i]); + free_nr_ue_ulsch(UE->ulsch[0][0][i]); } for (i = 0; i < 2; i++) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c index ab99841668..05170e0bc9 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/harq_test.c @@ -54,6 +54,8 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue) { int gNB_id = 0; + int thread_number = 0; + int code_word_idx = 0; int harq_pid = 0; int ndi = 1; uint8_t rnti_type = _C_RNTI_; @@ -61,7 +63,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue) printf("\nHARQ Uplink \n"); - config_uplink_harq_process(phy_vars_ue , gNB_id, NR_DEFAULT_DLSCH_HARQ_PROCESSES); + config_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx, NR_DEFAULT_DLSCH_HARQ_PROCESSES); NR_UE_ULSCH_t *ulsch_harq = phy_vars_ue->ulsch[gNB_id]; @@ -91,7 +93,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue) } } - release_uplink_harq_process(phy_vars_ue , gNB_id); + release_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx); return 0; } From 3d3f49c5c0931c446ce7dfb17597f3ac4cc4c2e5 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Mon, 18 Feb 2019 15:15:44 +0100 Subject: [PATCH 04/21] nr_ulsch_encoding is implemented and tested --- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 13 +- .../NR_TRANSPORT/nr_transport_common_proto.h | 2 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 3 + .../PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 14 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 313 ++++++++++++++++-- openair1/SIMULATION/NR_PHY/ulschsim.c | 65 +++- 6 files changed, 358 insertions(+), 52 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 7191e5f48b..eb1bdb0508 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -272,7 +272,7 @@ int nr_dlsch_encoding(unsigned char *a, unsigned int G; unsigned int crc=1; - + int i; uint8_t harq_pid = dlsch->harq_ids[slot]; nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; @@ -302,7 +302,9 @@ int nr_dlsch_encoding(unsigned char *a, A = rel15.transport_block_size; G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers); + LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); + Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers); @@ -328,8 +330,13 @@ int nr_dlsch_encoding(unsigned char *a, dlsch->harq_processes[harq_pid]->B = A+24; // dlsch->harq_processes[harq_pid]->b = a; + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + //write_output("enc_b.m","enc_in0",&dlsch->harq_processes[harq_pid]->b[0],(A/8)+4,1,4); + //for(i=0;i<10;i++) + //printf("dlsch->harq_processes[harq_pid]->b %d\n", dlsch->harq_processes[harq_pid]->b[i]); + nr_segmentation(dlsch->harq_processes[harq_pid]->b, dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->B, @@ -351,6 +358,7 @@ int nr_dlsch_encoding(unsigned char *a, Kr = dlsch->harq_processes[harq_pid]->K; Kr_bytes = Kr>>3; + //write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); //printf("segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG); //start_meas(te_stats); @@ -388,6 +396,7 @@ int nr_dlsch_encoding(unsigned char *a, //stop_meas(te_stats); //printf("end ldpc encoder -- output\n"); + //write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); #ifdef DEBUG_DLSCH_CODING write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4); @@ -429,6 +438,7 @@ int nr_dlsch_encoding(unsigned char *a, rel15.redundancy_version, E); + #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); @@ -442,6 +452,7 @@ int nr_dlsch_encoding(unsigned char *a, dlsch->harq_processes[harq_pid]->f+r_offset); //stop_meas(i_stats); + #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index b075da4e97..14ba3de923 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -38,7 +38,7 @@ #define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) -#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) +#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB #define MAX_NUM_NR_RE (14*273*12) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 2b8e0258e6..d3e7dd0621 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1006,6 +1006,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); +int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, + NR_DL_FRAME_PARMS* frame_parms); + uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, int eNB_id, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 1f99da06c0..885039c592 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -102,6 +102,8 @@ typedef struct { uint16_t first_rb; /// Current Number of RBs uint16_t nb_rb; + /// number of layers + uint8_t Nl; /// Last TPC command uint8_t TPC; /// Transport block size @@ -117,17 +119,17 @@ typedef struct { /// Redundancy-version of the current sub-frame uint8_t rvidx; /// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8) - uint8_t *a; + unsigned char *a; /// Pointer to the payload + CRC uint8_t *b; /// Pointers to transport block segments uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC-code outputs + uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; /// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17) - uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; // 66*Z_c is the maximum LDPC block length. We use 68 for internal manipulation of the buffer - /// Rate matching (Bit selection) outputs (TS 36.212 V15.4.0, Sec 5.4.2.1 p. 28) - uint8_t *e[MAX_NUM_NR_ULSCH_SEGMENTS]; + uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); /// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30) - uint8_t *f[MAX_NUM_NR_ULSCH_SEGMENTS]; + uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32))); /// Number of code segments uint32_t C; /// Number of bits in code segments @@ -162,6 +164,8 @@ typedef struct { typedef struct { /// Current Number of Symbols uint8_t Nsymb_pusch; + /// number of DMRS resource elements + uint8_t nb_re_dmrs; /// SRS active flag uint8_t srs_active; //#if defined(UPGRADE_RAT_NR) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 8ad2a8ecb4..965627e4a8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -56,6 +56,11 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) for (i=0; iharq_processes[i]) { + + if (ulsch->harq_processes[i]->a) { + free16(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES); + ulsch->harq_processes[i]->a = NULL; + } if (ulsch->harq_processes[i]->b) { free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); ulsch->harq_processes[i]->b = NULL; @@ -71,16 +76,6 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) ulsch->harq_processes[i]->d[r] = NULL; } - if (ulsch->harq_processes[i]->e[r]) { - free16(ulsch->harq_processes[i]->e[r],68*384); - ulsch->harq_processes[i]->e[r] = NULL; - } - - if (ulsch->harq_processes[i]->f[r]) { - free16(ulsch->harq_processes[i]->f[r],68*384); - ulsch->harq_processes[i]->f[r] = NULL; - } - } free16(ulsch->harq_processes[i],sizeof(NR_UL_UE_HARQ_t)); @@ -119,6 +114,9 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES; ulsch->Mlimit = 4; // maximum harq retransmissions + //for (i=0; i<10; i++) + //ulsch->harq_ids[i] = 0; + for (i=0; iharq_processes[i] = (NR_UL_UE_HARQ_t *)malloc16(sizeof(NR_UL_UE_HARQ_t)); @@ -126,8 +124,8 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u // printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]); if (ulsch->harq_processes[i]) { memset(ulsch->harq_processes[i], 0, sizeof(NR_UL_UE_HARQ_t)); - ulsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); - ulsch->harq_processes[i]->a = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->a = (unsigned char*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); if (ulsch->harq_processes[i]->a) { bzero(ulsch->harq_processes[i]->a,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); @@ -137,7 +135,7 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u } if (ulsch->harq_processes[i]->b) - memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + bzero(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); else { LOG_E(PHY,"Can't get b\n"); exit_flag=1; @@ -148,8 +146,7 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u // account for filler in first segment and CRCs for multiple segment case ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448); ulsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output - ulsch->harq_processes[i]->e[r] = (uint8_t*)malloc16(68*384); - ulsch->harq_processes[i]->f[r] = (uint8_t*)malloc16(68*384); + if (ulsch->harq_processes[i]->c[r]) { bzero(ulsch->harq_processes[i]->c[r],8448); } else { @@ -162,18 +159,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u printf("Can't get d\n"); exit_flag=2; } - if (ulsch->harq_processes[i]->e[r]) { - bzero(ulsch->harq_processes[i]->e[r],(68*384)); - } else { - printf("Can't get e\n"); - exit_flag=2; - } - if (ulsch->harq_processes[i]->f[r]) { - bzero(ulsch->harq_processes[i]->f[r],(68*384)); - } else { - printf("Can't get f\n"); - exit_flag=2; - } } } @@ -185,15 +170,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u } } - if ((abstraction_flag == 0) && (exit_flag==0)) { - for (i=0; i<8; i++) - for (j=0; j<96; j++) - for (r=0; rharq_processes[i]->d[r][j] = NR_NULL; + if (exit_flag==0) { + for (i=0; iharq_processes[i]->round=0; + } return(ulsch); - } else if (abstraction_flag==1) - return(ulsch); + } } LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t)); @@ -201,4 +184,264 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u return(NULL); -} \ No newline at end of file +} + + + +int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, + NR_DL_FRAME_PARMS* frame_parms) +{ + +/////////////////////////parameters and variables declaration///////////////////////// +/////////// + + unsigned int G,crc; + uint8_t harq_pid; + NR_UL_UE_HARQ_t *harq_process; + uint16_t nb_rb ; + uint8_t nb_symb_sch ; + uint32_t A, Z; + uint32_t *pz; + uint8_t mod_order; + uint16_t Kr,r,r_offset,Kr_bytes; + uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; + uint8_t kb,BG; + uint32_t E; + uint8_t Ilbrm; + uint32_t Tbslbrm; + uint8_t nb_re_dmrs; + uint16_t length_dmrs; + int i; + +/////////// +/////////////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////parameters and variables initialization///////////////////////// +/////////// + + crc = 1; + harq_pid = 0; + harq_process = ulsch->harq_processes[harq_pid]; + nb_rb = harq_process->nb_rb; + nb_symb_sch = harq_process->nb_symbols; + A = harq_process->TBS; + pz = &Z; + mod_order = nr_get_Qm(harq_process->mcs,1); + Kr=0; + r_offset=0; + BG = 1; + Ilbrm = 0; + Tbslbrm = 950984; //max tbs + nb_re_dmrs = ulsch->nb_re_dmrs; + length_dmrs = 1; + +/////////// +///////////////////////////////////////////////////////////////////////////////////////// + + /* + uint8_t *channel_input[MAX_NUM_DLSCH_SEGMENTS]; //unsigned char + for(j=0;jNl); + LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); + printf("ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); + + Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); + + // if (harq_process->Ndi == 1) { // this is a new packet + if (harq_process->round == 0) { // this is a new packet +#ifdef DEBUG_DLSCH_CODING + printf("encoding thinks this is a new packet \n"); +#endif + +///////////////////////// a---->| add CRC |---->b ///////////////////////// +/////////// + /* + int i; + printf("dlsch (tx): \n"); + for (i=0;i<(A>>3);i++) + printf("%02x.",a[i]); + printf("\n"); + */ + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(harq_process->a,A)>>8; + harq_process->a[A>>3] = ((uint8_t*)&crc)[2]; + harq_process->a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + harq_process->a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + //printf("CRC %x (A %d)\n",crc,A); + //printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]); + + harq_process->B = A+24; + + memcpy(harq_process->b,harq_process->a,(A/8)+4); + + //write_output("ulsch_b.m","enc_in0",&harq_process->b[0],(A/8)+4,1,4); + //for(i=0;i<10;i++) + //printf("harq_process->b %d\n", harq_process->b[i]); + + + +/////////// +/////////////////////////////////////////////////////////////////////////// + +///////////////////////// b---->| block segmentation |---->c ///////////////////////// +/////////// + + nr_segmentation(harq_process->b, + harq_process->c, + harq_process->B, + &harq_process->C, + &harq_process->K, + pz, + &harq_process->F); + + kb = harq_process->K/(*pz); + if ( kb==22){ + BG = 1; + } + else{ + BG = 2; + } + + Kr = harq_process->K; + Kr_bytes = Kr>>3; + + write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4); + +/////////// +///////////////////////////////////////////////////////////////////////////////////// + + +///////////////////////// c---->| LDCP coding |---->d ///////////////////////// +/////////// + + //printf("segment Z %d kb %d k %d Kr %d BG %d\n", *pz,kb,harq_process->K,Kr,BG); + + //start_meas(te_stats); + for (r=0; rC; r++) { + d_tmp[r] = &harq_process->d[r][0]; + //channel_input[r] = &harq_process->d[r][0]; +#ifdef DEBUG_DLSCH_CODING + printf("Encoder: B %d F %d \n",harq_process->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 ++){ + printf("%d ", harq_process->c[r][cnt]); + } + printf("\n"); + +#endif + //ldpc_encoder_orig((unsigned char*)harq_process->c[r],harq_process->d[r],Kr,BG,0); + //ldpc_encoder_optim((unsigned char*)harq_process->c[r],(unsigned char*)&harq_process->d[r][0],Kr,BG,NULL,NULL,NULL,NULL); + } + + //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("\n");*/ + + //ldpc_encoder_optim_8seg(harq_process->c,d_tmp,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL); + + //stop_meas(te_stats); + //printf("end ldpc encoder -- output\n"); + //write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4); +#ifdef DEBUG_DLSCH_CODING + write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4); + write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4); +#endif + +/////////// +/////////////////////////////////////////////////////////////////////////////// + + } + + for (r=0; rC; r++) { // looping over C segments +#ifdef DEBUG_DLSCH_CODING + printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb); +#endif + + //start_meas(rm_stats); +#ifdef DEBUG_DLSCH_CODING + printf("rvidx in encoding = %d\n", harq_process->rvidx); +#endif + +///////////////////////// d---->| Rate matching bit selection |---->e ///////////////////////// +/////////// + + E = nr_get_E(G, harq_process->C, mod_order, harq_process->Nl, r); + + nr_rate_matching_ldpc(Ilbrm, + Tbslbrm, + BG, + *pz, + harq_process->d[r], + harq_process->e+r_offset, + harq_process->C, + harq_process->rvidx, + E); + + + +#ifdef DEBUG_DLSCH_CODING + for (int i =0; i<16; i++) + printf("output ratematching e[%d]= %d r_offset %d\n", i,harq_process->e[i+r_offset], r_offset); +#endif + +/////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + +///////////////////////// e---->| Rate matching bit interleaving |---->f ///////////////////////// +/////////// + + //stop_meas(rm_stats); + + //start_meas(i_stats); + nr_interleaving_ldpc(E, + mod_order, + harq_process->e+r_offset, + harq_process->f+r_offset); + //stop_meas(i_stats); + + +#ifdef DEBUG_DLSCH_CODING + for (int i =0; i<16; i++) + printf("output interleaving f[%d]= %d r_offset %d\n", i,harq_process->f[i+r_offset], r_offset); + + if (r==harq_process->C-1) + write_output("enc_output.m","enc",harq_process->f,G,1,4); +#endif + + r_offset += E; + +/////////// +/////////////////////////////////////////////////////////////////////////////////////////////// + + } + + memcpy(ulsch->g,harq_process->f,G>>3); // g is the concatenated code block + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); + + return(0); +} diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 951d969c51..80121b3d7f 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -122,7 +122,7 @@ char quantize(double D, double x, unsigned char B) { int main(int argc, char **argv) { char c; - int i; //,j,l,aa; + int i,sf; //,j,l,aa; double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0; double snr_step = 0.1; uint8_t snr1set = 0; @@ -438,7 +438,7 @@ int main(int argc, char **argv) { //nr_init_frame_parms_ue(&UE->frame_parms); //init_nr_ue_transport(UE, 0); - for (int sf = 0; sf < 2; sf++) { + for (sf = 0; sf < 2; sf++) { for (i = 0; i < 2; i++) { UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo, 8, Nsoft, 5, N_RB_DL, 0); @@ -464,6 +464,9 @@ int main(int argc, char **argv) { unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; + + NR_UE_ULSCH_t *ulsch = UE->ulsch[0][0][0]; + //time_stats_t *rm_stats, *te_stats, *i_stats; uint8_t is_crnti = 0, llr8_flag = 0; unsigned int TBS = 8424; @@ -474,6 +477,7 @@ int main(int argc, char **argv) { uint8_t Nl = 1; uint8_t rvidx = 0; dlsch->rnti = 1; + ulsch->nb_re_dmrs = nb_re_dmrs; //[adk] A HOT FIX until cearting nfapi_nr_ul_config_ulsch_pdu_rel15_t /*dlsch->harq_processes[0]->mcs = Imcs; dlsch->harq_processes[0]->rvidx = rvidx;*/ //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], @@ -497,9 +501,13 @@ int main(int argc, char **argv) { unsigned char *estimated_output_bit; unsigned char *test_input_bit; unsigned int errors_bit = 0; + test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0]; NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; harq_process->mcs = Imcs; @@ -516,6 +524,26 @@ int main(int argc, char **argv) { estimated_output = harq_process->b; + + /////////////////////////[adk] preparing UL harq_process parameters///////////////////////// + /////////// + NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch->harq_processes[harq_pid]; + + if (harq_process_ul_ue){ + + harq_process_ul_ue->mcs = Imcs; + harq_process_ul_ue->Nl = Nl; + harq_process_ul_ue->nb_rb = nb_rb; + harq_process_ul_ue->nb_symbols = nb_symb_sch; + harq_process_ul_ue->rvidx = rvidx; + harq_process_ul_ue->TBS = TBS; + harq_process_ul_ue->a = &test_input[0]; + + } + /////////// + //////////////////////////////////////////////////////////////////////////////////////////// + + #ifdef DEBUG_DLSCHSIM for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); #endif @@ -527,6 +555,7 @@ int main(int argc, char **argv) { // generate signal if (input_fd == NULL) { nr_dlsch_encoding(test_input, subframe, dlsch, frame_parms); + nr_ulsch_encoding(ulsch, frame_parms); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -540,10 +569,14 @@ int main(int argc, char **argv) { if ((i&0xf)==0) printf("\ne %d..%d: ",i,i+15); #endif + /* + if (i<16){ + printf("dlsch_encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); + printf("ulsch_encoder output f[%d] = %d\n",i,ulsch->harq_processes[0]->f[i]); - //if (i<16) - // printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); - if (dlsch->harq_processes[0]->f[i] == 0) + } + */ + if (ulsch->harq_processes[0]->f[i] == 0) modulated_input[i] = 1.0; ///sqrt(2); //QPSK else modulated_input[i] = -1.0; ///sqrt(2); @@ -594,7 +627,7 @@ int main(int argc, char **argv) { errors_bit = 0; for (i = 0; i < TBS; i++) { - estimated_output_bit[i] = (dlsch0_ue->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7); + estimated_output_bit[i] = (ulsch->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7); test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments if (estimated_output_bit[i] != test_input_bit[i]) { @@ -653,12 +686,24 @@ int main(int argc, char **argv) { } }*/ + for (i = 0; i < 2; i++) { + printf("gNB %d\n", i); - free_gNB_dlsch(gNB->dlsch[0][i]); - printf("UE %d\n", i); - free_nr_ue_dlsch(UE->dlsch[0][0][i]); - free_nr_ue_ulsch(UE->ulsch[0][0][i]); + + if (gNB->dlsch[0][i]) + free_gNB_dlsch(gNB->dlsch[0][i]); + + for (sf = 0; sf < 2; sf++) { + + printf("UE %d\n", i); + + if (UE->dlsch[sf][0][i]) + free_nr_ue_dlsch(UE->dlsch[sf][0][i]); + + if (UE->ulsch[sf][0][i]) + free_nr_ue_ulsch(UE->ulsch[sf][0][i]); + } } for (i = 0; i < 2; i++) { From ea2bc826f1b2650f547fd00eb81d006482452cf4 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Wed, 20 Feb 2019 17:20:39 +0100 Subject: [PATCH 05/21] minor clean ups --- cmake_targets/CMakeLists.txt | 5 ++++- openair1/PHY/CODING/crc_byte.c | 6 +++++- openair1/PHY/INIT/nr_init_ue.c | 5 ++--- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 8 +------- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 7 ------- openair1/PHY/defs_nr_common.h | 4 ++-- 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 674d441dd9..6ed11eebfa 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2558,7 +2558,10 @@ add_executable(nr_dlsim ${T_SOURCE}) target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) -add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c ${T_SOURCE}) +add_executable(nr_ulschsim + ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c + ${OPENAIR_DIR}/common/utils/backtrace.c + ${T_SOURCE}) target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl) diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index d728d6b9ad..5e0ebeb991 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -32,6 +32,7 @@ #include "coding_defs.h" +#include "assertions.h" /*ref 36-212 v8.6.0 , pp 8-9 */ /* the highest degree is set by default */ @@ -275,7 +276,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type) break; default: - crc_len=3; + AssertFatal(1,"Invalid crc_type \n"); } for (int i=0; i>24; break; + + default: + AssertFatal(1,"Invalid crc_type \n"); } if (crc == oldcrc) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7a4cd9f446..986d423034 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -925,9 +925,8 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) { for (i=0; idlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); - - LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]); + AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); + LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]); AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NUMBER_OF_HARQ_PID_MAX, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index eb1bdb0508..4e8c2d2ff5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -272,7 +272,6 @@ int nr_dlsch_encoding(unsigned char *a, unsigned int G; unsigned int crc=1; - int i; uint8_t harq_pid = dlsch->harq_ids[slot]; nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; uint16_t nb_rb = rel15.n_prb; @@ -333,10 +332,6 @@ int nr_dlsch_encoding(unsigned char *a, memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); - //write_output("enc_b.m","enc_in0",&dlsch->harq_processes[harq_pid]->b[0],(A/8)+4,1,4); - //for(i=0;i<10;i++) - //printf("dlsch->harq_processes[harq_pid]->b %d\n", dlsch->harq_processes[harq_pid]->b[i]); - nr_segmentation(dlsch->harq_processes[harq_pid]->b, dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->B, @@ -358,7 +353,6 @@ int nr_dlsch_encoding(unsigned char *a, Kr = dlsch->harq_processes[harq_pid]->K; Kr_bytes = Kr>>3; - //write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4); //printf("segment Z %d k %d Kr %d BG %d\n", *pz,dlsch->harq_processes[harq_pid]->K,Kr,BG); //start_meas(te_stats); @@ -466,5 +460,5 @@ int nr_dlsch_encoding(unsigned char *a, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - return(0); + return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 965627e4a8..6b17eff585 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -284,12 +284,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, memcpy(harq_process->b,harq_process->a,(A/8)+4); - //write_output("ulsch_b.m","enc_in0",&harq_process->b[0],(A/8)+4,1,4); - //for(i=0;i<10;i++) - //printf("harq_process->b %d\n", harq_process->b[i]); - - - /////////// /////////////////////////////////////////////////////////////////////////// @@ -315,7 +309,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Kr = harq_process->K; Kr_bytes = Kr>>3; - write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4); /////////// ///////////////////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 58a8833b18..21c1af5774 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -87,10 +87,10 @@ #define NR_MAX_CSET_DURATION 3 #define NR_MAX_NB_RBG 18 -#define NR_MAX_NB_LAYERS 8 +#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) #define NR_MAX_NB_CODEWORDS 2 #define NR_MAX_NB_HARQ_PROCESSES 16 -#define NR_MAX_PDSCH_ENCODED_LENGTH 950984 +#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) #define NR_MAX_PDSCH_TBS 3824 typedef enum { From a7fc22c807f16c42866a12d1cd47aa40b23ba406 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Tue, 26 Feb 2019 12:53:00 +0100 Subject: [PATCH 06/21] Adding harq_pid as an input to nr_ulsch_encoding --- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 18 +++++++++++++++++- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 5 ++--- openair1/SIMULATION/NR_PHY/ulschsim.c | 10 +++++++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index d3e7dd0621..3db43237a0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1007,7 +1007,23 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t llr8_flag); int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS* frame_parms); + NR_DL_FRAME_PARMS* frame_parms, + uint8_t harq_pid); + +/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 + @param[in] in Pointer to input bits + @param[in] size of input bits + @param[in] Nid cell id + @param[in] n_RNTI CRNTI + @param[out] out the scrambled bits +*/ + +void nr_pusch_codeword_scrambling(uint8_t *in, + uint16_t size, + uint32_t Nid, + uint32_t n_RNTI, + uint32_t* out); + uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 6b17eff585..4e46903ebf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -189,14 +189,14 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, u int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, - NR_DL_FRAME_PARMS* frame_parms) + NR_DL_FRAME_PARMS* frame_parms, + uint8_t harq_pid) { /////////////////////////parameters and variables declaration///////////////////////// /////////// unsigned int G,crc; - uint8_t harq_pid; NR_UL_UE_HARQ_t *harq_process; uint16_t nb_rb ; uint8_t nb_symb_sch ; @@ -221,7 +221,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// crc = 1; - harq_pid = 0; harq_process = ulsch->harq_processes[harq_pid]; nb_rb = harq_process->nb_rb; nb_symb_sch = harq_process->nb_symbols; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 80121b3d7f..de3bd2fe62 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -52,7 +52,7 @@ //#include "UTIL/LISTS/list.h" //#include "common/ran_context.h" -//#define DEBUG_DLSCHSIM +//#define DEBUG_ULSCHSIM PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; @@ -544,7 +544,7 @@ int main(int argc, char **argv) { //////////////////////////////////////////////////////////////////////////////////////////// -#ifdef DEBUG_DLSCHSIM +#ifdef DEBUG_ULSCHSIM for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); #endif @@ -553,9 +553,13 @@ int main(int argc, char **argv) { //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); // generate signal + + /////////////////////////[adk] ULSCH coding///////////////////////// + /////////// + if (input_fd == NULL) { nr_dlsch_encoding(test_input, subframe, dlsch, frame_parms); - nr_ulsch_encoding(ulsch, frame_parms); + nr_ulsch_encoding(ulsch, frame_parms, harq_pid); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { From 9947a6bccd3508ac75c50e360bcdf09a2590c7ff Mon Sep 17 00:00:00 2001 From: Ahmed Date: Fri, 1 Mar 2019 16:58:47 +0100 Subject: [PATCH 07/21] ULSCH decoding functionality at gNB side Added the following structs and enums in "defs_gNB.h" - NR_UL_gNB_HARQ_t - NR_gNB_ULSCH_t - NR_SCH_status_t added the following structs in "nfapi_nr_interface.h" - nfapi_nr_ul_config_ulsch_pdu - nfapi_nr_ul_config_ulsch_pdu_rel15_t - nfapi_nr_ul_srs_config_t - nr_pusch_freq_hopping_t added nr_ulsch.h for the ulsch decoding function declarations - free_gNB_ulsch - new_gNB_ulsch - nr_ulsch_decoding added nr_ulsch_decoding.c for the implementation of the ulsch decoding functions - free_gNB_ulsch - new_gNB_ulsch - nr_ulsch_decoding --- cmake_targets/CMakeLists.txt | 1 + .../nfapi/public_inc/nfapi_nr_interface.h | 41 ++ openair1/PHY/NR_TRANSPORT/nr_ulsch.h | 49 ++ openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 583 ++++++++++++++++++ openair1/PHY/defs_gNB.h | 195 +++++- 5 files changed, 860 insertions(+), 9 deletions(-) create mode 100644 openair1/PHY/NR_TRANSPORT/nr_ulsch.h create mode 100644 openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 6ed11eebfa..79f057c29e 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1275,6 +1275,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c + ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 94b7121998..b953a715ef 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -673,4 +673,45 @@ typedef struct { nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_nr_dl_config_request_t; + +typedef enum {nr_pusch_freq_hopping_disabled = 0 , + nr_pusch_freq_hopping_enabled = 1 + } nr_pusch_freq_hopping_t; + +typedef struct{ + uint8_t aperiodicSRS_ResourceTrigger; +} nfapi_nr_ul_srs_config_t; + +typedef struct { + uint8_t bandwidth_part_ind; + uint16_t number_rbs; + uint16_t start_rb; + uint8_t frame_offset; + uint16_t number_symbols; + uint16_t start_symbol; + nr_pusch_freq_hopping_t pusch_freq_hopping; + uint8_t mcs; + uint8_t Qm; + uint8_t ndi; + uint8_t rv; + uint8_t harq_process_nbr; + int8_t accumulated_delta_PUSCH; + int8_t absolute_delta_PUSCH; + uint8_t n_layers; + uint8_t tpmi; + uint8_t n_dmrs_cdm_groups; + uint8_t dmrs_ports[4]; + uint8_t n_front_load_symb; + nfapi_nr_ul_srs_config_t srs_config; + uint8_t csi_reportTriggerSize; + uint8_t maxCodeBlockGroupsPerTransportBlock; + uint8_t ptrs_dmrs_association_port; + uint8_t beta_offset_ind; +} nfapi_nr_ul_config_ulsch_pdu_rel15_t; + +typedef struct { + uint16_t rnti; + nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15; +} nfapi_nr_ul_config_ulsch_pdu; + #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h new file mode 100644 index 0000000000..77cc101679 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -0,0 +1,49 @@ +/* + * 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.0 (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 PHY/NR_TRANSPORT/nr_ulsch.h +* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB +* \author Ahmed Hussein +* \date 2019 +* \version 0.1 +* \company Fraunhofer IIS +* \email: ahmed.hussein@iis.fraunhofer.de +* \note +* \warning +*/ + +#include "PHY/defs_gNB.h" + +void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); + +NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag); + +uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, + uint8_t UE_id, + short *ulsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag); + diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c new file mode 100644 index 0000000000..1d72507de9 --- /dev/null +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -0,0 +1,583 @@ +/* + * 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.0 (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 PHY/NR_TRANSPORT/nr_ulsch_decoding.c +* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12 +* \author Ahmed Hussein +* \date 2019 +* \version 0.1 +* \company Fraunhofer IIS +* \email: ahmed.hussein@iis.fraunhofer.de +* \note +* \warning +*/ + + +// [from gNB coding] +#include "PHY/defs_gNB.h" +#include "PHY/phy_extern.h" +#include "PHY/CODING/coding_extern.h" +#include "PHY/CODING/coding_defs.h" +#include "PHY/CODING/lte_interleaver_inline.h" +#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +#include "PHY/NR_TRANSPORT/nr_ulsch.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "SCHED_NR/sched_nr.h" +#include "defs.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "common/utils/LOG/log.h" +#include +//#define DEBUG_ULSCH_DECODING + +#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 + +static uint64_t nb_total_decod =0; +static uint64_t nb_error_decod =0; + +//extern double cpuf; + +void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) +{ + + int i,r; + + if (ulsch) { + for (i=0; iharq_processes[i]) { + if (ulsch->harq_processes[i]->b) { + free16(ulsch->harq_processes[i]->b,MAX_NR_ULSCH_PAYLOAD_BYTES); + ulsch->harq_processes[i]->b = NULL; + } + for (r=0; rharq_processes[i]->c[r],(8448)*sizeof(uint8_t)); + ulsch->harq_processes[i]->c[r] = NULL; + } + for (r=0; rharq_processes[i]->d[r]) { + free16(ulsch->harq_processes[i]->d[r],(68*384)*sizeof(int16_t)); + ulsch->harq_processes[i]->d[r] = NULL; + } + } + for (r=0; r<(MAX_NUM_NR_ULSCH_SEGMENTS); r++) { + if (ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]){ + nrLDPC_free_mem(ulsch->harq_processes[i]->p_nrLDPC_procBuf[r]); + ulsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; + } + } + free16(ulsch->harq_processes[i],sizeof(NR_UL_gNB_HARQ_t)); + ulsch->harq_processes[i] = NULL; + } + } + free16(ulsch,sizeof(NR_gNB_ULSCH_t)); + ulsch = NULL; + } +} + + +NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag) +{ + + NR_gNB_ULSCH_t *ulsch; + uint8_t exit_flag = 0,i,r; + unsigned char bw_scaling =1; + + switch (N_RB_UL) { + case 106: + bw_scaling =2; + break; + + default: + bw_scaling =1; + break; + } + + ulsch = (NR_gNB_ULSCH_t *)malloc16(sizeof(NR_gNB_ULSCH_t)); + + if (ulsch) { + + memset(ulsch,0,sizeof(NR_gNB_ULSCH_t)); + + ulsch->max_ldpc_iterations = max_ldpc_iterations; + ulsch->Mlimit = 4; + + for (i=0; iharq_processes[i] = (NR_UL_gNB_HARQ_t *)malloc16(sizeof(NR_UL_gNB_HARQ_t)); + + if (ulsch->harq_processes[i]) { + + memset(ulsch->harq_processes[i],0,sizeof(NR_UL_gNB_HARQ_t)); + + ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + + if (ulsch->harq_processes[i]->b) + memset(ulsch->harq_processes[i]->b,0,MAX_NR_ULSCH_PAYLOAD_BYTES/bw_scaling); + else + exit_flag=3; + + if (abstraction_flag == 0) { + for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); + + ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448*sizeof(uint8_t)); + + if (ulsch->harq_processes[i]->c[r]) + memset(ulsch->harq_processes[i]->c[r],0,8448*sizeof(uint8_t)); + else + exit_flag=2; + + ulsch->harq_processes[i]->d[r] = (int16_t*)malloc16((68*384)*sizeof(int16_t)); + + if (ulsch->harq_processes[i]->d[r]) + memset(ulsch->harq_processes[i]->d[r],0,(68*384)*sizeof(int16_t)); + else + exit_flag=2; + } + } + } else { + exit_flag=1; + } + } + + if (exit_flag==0) + return(ulsch); + } + + printf("new_gNB_ulsch with size %zu: exit_flag = %u\n",sizeof(NR_UL_gNB_HARQ_t), exit_flag); + free_gNB_ulsch(ulsch); + + return(NULL); +} + + +uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, + uint8_t UE_id, + short *ulsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag) +{ + + uint32_t A,E; + uint32_t G; + uint32_t ret,offset; + int32_t no_iteration_ldpc; + uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; + uint8_t crc_type; + int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); + + + NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; + NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15; + + t_nrLDPC_dec_params decParams; + t_nrLDPC_dec_params* p_decParams = &decParams; + t_nrLDPC_time_stats procTime; + t_nrLDPC_time_stats* p_procTime = &procTime ; + t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf; + + int16_t z [68*384]; + int8_t l [68*384]; + int16_t inv_d [68*384]; + uint8_t kb, kc; + uint8_t Ilbrm = 0; + uint32_t Tbslbrm = 950984; + uint16_t nb_rb = 30; //to update + uint8_t nb_re_dmrs = 6; + uint16_t length_dmrs = 1; + + uint32_t i,j; + + __m128i *pv = (__m128i*)&z; + __m128i *pl = (__m128i*)&l; + + + if (!ulsch_llr) { + printf("ulsch_decoding.c: NULL ulsch_llr pointer\n"); + return(ulsch->max_ldpc_iterations); + } + + if (!harq_process) { + printf("ulsch_decoding.c: NULL harq_process pointer\n"); + return(ulsch->max_ldpc_iterations); + } + + if (!frame_parms) { + printf("ulsch_decoding.c: NULL frame_parms pointer\n"); + return(ulsch->max_ldpc_iterations); + } + + nb_rb = nfapi_ulsch_pdu_rel15->number_rbs; + + // harq_process->trials[nfapi_ulsch_pdu_rel15->round]++; + + harq_process->TBS = nr_compute_tbs(nfapi_ulsch_pdu_rel15->mcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->n_layers); + + A = harq_process->TBS; + ret = ulsch->max_ldpc_iterations; + + harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers); + G = harq_process->G; + + LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb); + + if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation + harq_process->B = A+24; + + // [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F) + nr_segmentation(NULL, + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F); + + p_decParams->Z = harq_process->Z; + +#ifdef DEBUG_ULSCH_DECODING + printf("ulsch decoding nr segmentation Z %d\n", p_decParams->Z); + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); +#endif + } + + kb = harq_process->K/harq_process->Z; + + if ( kb==22) { + p_decParams->BG = 1; + p_decParams->R = 13; + kc = 68; + } else { + p_decParams->BG = 2; + p_decParams->R = 13; + kc = 52; + } + + p_decParams->numMaxIter = ulsch->max_ldpc_iterations; + Kr = p_decParams->Z*kb; + p_decParams->outMode= 0; + + err_flag = 0; + r_offset = 0; + + unsigned char bw_scaling =1; + + switch (frame_parms->N_RB_UL) { + + case 106: + bw_scaling =2; + break; + + default: + bw_scaling =1; + break; + } + + if (harq_process->C > MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling) { + LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_ULSCH_SEGMENTS/bw_scaling); + return((1+ulsch->max_ldpc_iterations)); + } +#ifdef DEBUG_ULSCH_DECODING + printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); +#endif + + opp_enabled=1; + + Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" + Kr_bytes = Kr>>3; + + K_bytes_F = Kr_bytes-(harq_process->F>>3); + + Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers); + + for (r=0; rC; r++) { + + E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r); + +#if gNB_TIMING_TRACE + start_meas(ulsch_deinterleaving_stats); +#endif + + //////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////// nr_deinterleaving_ldpc /////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////// ulsch_llr =====> harq_process->e ////////////////////////////// + + nr_deinterleaving_ldpc(E, + nfapi_ulsch_pdu_rel15->Qm, + harq_process->e[r], + ulsch_llr+r_offset); + + //for (int i =0; i<16; i++) + // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + +#if gNB_TIMING_TRACE + stop_meas(ulsch_deinterleaving_stats); +#endif + +#if gNB_TIMING_TRACE + start_meas(ulsch_rate_unmatching_stats); +#endif + +#ifdef DEBUG_ULSCH_DECODING + LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + harq_pid,r, G, + Kr*3, + harq_process->TBS, + nfapi_ulsch_pdu_rel15->Qm, + nfapi_ulsch_pdu_rel15->number_rbs, + nfapi_ulsch_pdu_rel15->n_layers, + nfapi_ulsch_pdu_rel15->rv, + harq_process->round); +#endif + ////////////////////////////////////////////////////////////////////////////////////////// + + + ////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////// nr_rate_matching_ldpc_rx //////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + ///////////////////////// harq_process->e =====> harq_process->d ///////////////////////// + + if (nr_rate_matching_ldpc_rx(Ilbrm, + Tbslbrm, + p_decParams->BG, + p_decParams->Z, + harq_process->d[r], + harq_process->e[r], + harq_process->C, + nfapi_ulsch_pdu_rel15->rv, + (harq_process->round==0)?1:0, + E)==-1) { +#if gNB_TIMING_TRACE + stop_meas(ulsch_rate_unmatching_stats); +#endif + LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n"); + return(ulsch->max_ldpc_iterations); + } else { +#if gNB_TIMING_TRACE + stop_meas(ulsch_rate_unmatching_stats); +#endif + } + + r_offset += E; + +#ifdef DEBUG_ULSCH_DECODING + if (r==0) { + write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0); + write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); + } + + printf("decoder input(segment %d) :",r); + int i; + for (i=0;i<(3*8*Kr_bytes)+12;i++) + printf("%d : %d\n",i,harq_process->d[r][i]); + printf("\n"); +#endif + + + // printf("Clearing c, %p\n",harq_process->c[r]); + memset(harq_process->c[r],0,Kr_bytes); + + // printf("done\n"); + if (harq_process->C == 1) + crc_type = CRC24_A; + else + crc_type = CRC24_B; + + if (err_flag == 0) { + +#if gNB_TIMING_TRACE + start_meas(ulsch_turbo_decoding_stats); +#endif + + for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++) { + inv_d[cnt] = (1)*harq_process->d[r][cnt]; + } + + memset(pv,0,2*harq_process->Z*sizeof(int16_t)); + memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); + + for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } + + for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } + + for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) { + pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + + + ////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////// nrLDPC_decoder ///////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////// pl =====> llrProcBuf ////////////////////////////////// + + no_iteration_ldpc = nrLDPC_decoder(p_decParams, + (int8_t*)&pl[0], + llrProcBuf, + p_nrLDPC_procBuf[r], + p_procTime); + + if (check_crc(llrProcBuf,harq_process->B,harq_process->F,crc_type)) { + printf("CRC OK\n"); + ret = 2; + } else { + printf("CRC NOK\n"); + ret = 1+ulsch->max_ldpc_iterations; + } + + nb_total_decod++; + if (no_iteration_ldpc > ulsch->max_ldpc_iterations){ + nb_error_decod++; + } + + ret=no_iteration_ldpc; + + for (int m=0; m < Kr>>3; m ++) { + harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; + } + +#ifdef DEBUG_ULSCH_DECODING + //printf("output decoder %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 k=0;k>3;k++) + printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); + //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); +#endif + +#if gNB_TIMING_TRACE + stop_meas(ulsch_turbo_decoding_stats); +#endif + } + + if ((err_flag == 0) && (ret>=(1+ulsch->max_ldpc_iterations))) { + // a Code segment is in error so break; + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + err_flag = 1; + } + ////////////////////////////////////////////////////////////////////////////////////////// + } + + int32_t frame_rx_prev = frame; + int32_t tti_rx_prev = nr_tti_rx - 1; + if (tti_rx_prev < 0) { + frame_rx_prev--; + tti_rx_prev += 10*frame_parms->ttis_per_subframe; + } + frame_rx_prev = frame_rx_prev%1024; + + if (err_flag == 1) { + +#if gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); +#endif + + // harq_process->harq_ack.ack = 0; + // harq_process->harq_ack.harq_id = harq_pid; + // harq_process->harq_ack.send_harq_status = 1; + // harq_process->errors[harq_process->round]++; + harq_process->round++; + + if (harq_process->round >= ulsch->Mlimit) { + harq_process->status = SCH_IDLE; + harq_process->round = 0; + harq_process->handled = 0; + ulsch->harq_mask &= ~(1 << harq_pid); + } + + if(is_crnti) { + LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); + } + + harq_process->handled = 1; + return((1+ulsch->max_ldpc_iterations)); + + } else { + +#if gNB_DEBUG_TRACE + LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", + phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); +#endif + + harq_process->status = SCH_IDLE; + harq_process->round = 0; + // harq_process->handled = 0; + ulsch->harq_mask &= ~(1 << harq_pid); + // harq_process->harq_ack.ack = 1; + // harq_process->harq_ack.harq_id = harq_pid; + // harq_process->harq_ack.send_harq_status = 1; + + if(is_crnti) + { + LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + } + } + + // Reassembly of Transport block here + offset = 0; + Kr = harq_process->K; + Kr_bytes = Kr>>3; + + for (r=0; rC; r++) { + + memcpy(harq_process->b+offset, + harq_process->c[r], + Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + + offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); + +#ifdef DEBUG_ULSCH_DECODING + printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("copied %d bytes to b sequence (harq_pid %d)\n", + (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); + printf("b[0] = %x,c[%d] = %x\n", + harq_process->b[offset], + harq_process->F>>3, + harq_process->c[r]); +#endif + + } + + ulsch->last_iteration_cnt = ret; + + return(ret); +} \ No newline at end of file diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 10b99eb113..24be9688dc 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -38,6 +38,10 @@ #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +#include "PHY/impl_defs_top.h" +#include "PHY/defs_common.h" +#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" +#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB @@ -72,6 +76,7 @@ typedef struct { uint64_t dci_pdu[2]; } NR_gNB_DCI_ALLOC_t; + typedef struct { uint8_t num_dci; uint8_t num_pdsch_rnti; @@ -79,6 +84,14 @@ typedef struct { } NR_gNB_PDCCH; +typedef enum { + NR_SCH_IDLE, + NR_ACTIVE, + NR_CBA_ACTIVE, + NR_DISABLED +} NR_SCH_status_t; + + typedef struct { /// Nfapi DLSCH PDU nfapi_nr_dl_config_dlsch_pdu dlsch_pdu; @@ -114,7 +127,6 @@ typedef struct { typedef struct { - /// Pointers to 16 HARQ processes for the DLSCH NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES]; /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) @@ -160,6 +172,170 @@ typedef struct { } NR_gNB_DLSCH_t; +typedef struct { + /// Nfapi ULSCH PDU + nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; + /// Frame where current HARQ round was sent + uint32_t frame; + /// Subframe where current HARQ round was sent + uint32_t subframe; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// Last TPC command + uint8_t TPC; + /// MIMO mode for this DLSCH + MIMO_mode_t mimo_mode; + /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) + uint8_t dci_alloc; + /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI) + uint8_t rar_alloc; + /// Status Flag indicating for this ULSCH (idle,active,disabled) + NR_SCH_status_t status; + /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_scheduling_flag; + /// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator) + uint8_t subframe_cba_scheduling_flag; + /// PHICH active flag + uint8_t phich_active; + /// PHICH ACK + uint8_t phich_ACK; + /// First Allocated RB - previous scheduling. This is needed for PHICH generation which is done after a new scheduling + uint16_t previous_first_rb; + /// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around + uint8_t handled; + /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up) + // int calibration_flag; + /// delta_TF for power control + int32_t delta_TF; + + + /////////////////////// ulsch decoding /////////////////////// + /// Transport block size (This is A from 38.212 V15.4.0 section 5.1) + uint32_t TBS; + /// Pointer to the payload (38.212 V15.4.0 section 5.1) + uint8_t *b; + /// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1) + uint32_t B; + /// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2) + uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// Number of bits in each code block (38.212 V15.4.0 section 5.2.2) + uint32_t K; + /// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2) + uint32_t F; + /// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2) + uint32_t C; + /// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2) + int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC processing buffer + t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS]; + /// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1) + uint32_t Z; + /// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448]; + /// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1) + uint32_t E; + /// Number of soft channel bits after code block concatenation (38.212 V15.4.0 section 5.5) + uint32_t G; + ////////////////////////////////////////////////////////////// + + + /////////////////////////// DMRS ///////////////////////////// + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) + uint8_t n_DMRS; + /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) + uint8_t n_DMRS2; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling + /// This is needed for PHICH generation which + /// is done after a new scheduling + uint8_t previous_n_DMRS; + ////////////////////////////////////////////////////////////// + + + ///////////////////// UCI multiplexing /////////////////////// + /// CQI CRC status + uint8_t cqi_crc_status; + /// Pointer to CQI data + uint8_t o[MAX_CQI_BYTES]; + /// Format of CQI data + UCI_format_t uci_format; + /// Length of CQI data under RI=1 assumption(bits) + uint8_t Or1; + /// Length of CQI data under RI=2 assumption(bits) + uint8_t Or2; + /// Rank information + uint8_t o_RI[2]; + /// Length of rank information (bits) + uint8_t O_RI; + /// Pointer to ACK + uint8_t o_ACK[4]; + /// Length of ACK information (bits) + uint8_t O_ACK; + /// The value of DAI in DCI format 0 + uint8_t V_UL_DAI; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + int8_t q[MAX_CQI_PAYLOAD]; + /// number of coded CQI bits after interleaving + uint8_t o_RCC; + /// coded and interleaved CQI bits + int8_t o_w[(MAX_CQI_BITS+8)*3]; + /// coded CQI bits + int8_t o_d[96+((MAX_CQI_BITS+8)*3)]; + /// coded ACK bits + int16_t q_ACK[MAX_ACK_PAYLOAD]; + /// coded RI bits + int16_t q_RI[MAX_RI_PAYLOAD]; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; + ////////////////////////////////////////////////////////////// +} NR_UL_gNB_HARQ_t; + + +typedef struct { + /// Pointers to 16 HARQ processes for the ULSCH + NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; + /// Current HARQ process id + int harq_process_id[NR_MAX_SLOTS_PER_FRAME]; + /// HARQ process mask, indicates which processes are currently active + uint16_t harq_mask; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// Flag to indicate that gNB awaits UE Msg3 + uint8_t Msg3_active; + /// Flag to indicate that gNB should decode UE Msg3 + uint8_t Msg3_flag; + /// Subframe for Msg3 + uint8_t Msg3_subframe; + /// Frame for Msg3 + uint32_t Msg3_frame; + /// Allocated RNTI for this ULSCH + uint16_t rnti; + /// RNTI type + uint8_t rnti_type; + /// cyclic shift for DM RS + uint8_t cyclicShift; + /// for cooperative communication + uint8_t cooperation_flag; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Maximum number of LDPC iterations + uint8_t max_ldpc_iterations; + /// number of iterations used in last LDPC decoding + uint8_t last_iteration_cnt; + /// num active cba group + uint8_t num_active_cba_groups; + /// num active cba group + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; +} NR_gNB_ULSCH_t; + + typedef struct { /// \brief Pointers (dynamic) to the received data in the time domain. /// - first index: rx antenna [0..nb_antennas_rx[ @@ -394,17 +570,18 @@ typedef struct PHY_VARS_gNB_s { LTE_eNB_PHICH phich_vars[2]; NR_gNB_COMMON common_vars; - LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; - LTE_eNB_PRACH prach_vars; - NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams - LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA + LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX]; + LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX]; + LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX]; + LTE_eNB_PRACH prach_vars; + NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams + NR_gNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA + // LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_MCH; NR_gNB_DLSCH_t *dlsch_PCH; - LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX]; - LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX]; + LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX]; + LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX]; uint8_t pbch_configured; uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE From e5fd0fcd00328c50b10fbf118500f039857f9c7c Mon Sep 17 00:00:00 2001 From: Ahmed Date: Fri, 1 Mar 2019 17:42:06 +0100 Subject: [PATCH 08/21] added the ulsch decoding functions to ulschsim.c now ulschsim.c is uplink only with no downlink decoding functions or variables --- openair1/PHY/INIT/nr_init.c | 69 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 1207 +++++++++++++------------ 2 files changed, 646 insertions(+), 630 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 46e3010972..1a2382b526 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -33,6 +33,7 @@ #include "assertions.h" #include +#include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "SCHED_NR/fapi_nr_l1.h" @@ -77,12 +78,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char abstraction_flag) { // shortcuts NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; - nfapi_nr_config_request_t *cfg = &gNB->gNB_config; + nfapi_nr_config_request_t *cfg = &gNB->gNB_config; NR_gNB_COMMON *const common_vars = &gNB->common_vars; - LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; - LTE_eNB_SRS *const srs_vars = gNB->srs_vars; - LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars; + LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars; + LTE_eNB_SRS *const srs_vars = gNB->srs_vars; + LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars; + int i, UE_id; + LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__); gNB->total_dlsch_bitrate = 0; gNB->total_transmitted_bits = 0; @@ -110,7 +113,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, init_dfts(); // PBCH DMRS gold sequences generation nr_init_pbch_dmrs(gNB); - // Polar encoder init for PBCH //PDCCH DMRS init gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs; @@ -148,6 +150,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value); + /// Transport init necessary for NR synchro init_nr_transport(gNB); @@ -167,14 +170,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, gNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here. common_vars->rxdata = (int32_t **)NULL; - common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t *)); - common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *)); + common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); + common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*)); - for (i=0; i<15; i++) { - common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); - LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", - i,common_vars->txdataF[i], - fp->samples_per_frame_wCP*sizeof(int32_t)); + for (i=0;i<15;i++){ + common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); // [hna] samples_per_frame without CP + + LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n", + i,common_vars->txdataF[i], + fp->samples_per_frame_wCP*sizeof(int32_t)); } // Channel estimates for SRS @@ -417,6 +421,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { gNB_config->rf_config.ul_carrier_bandwidth.value, gNB_config->sch_config.physical_cell_id.value, fp->dl_CarrierFreq ); + nr_init_frame_parms(gNB_config, fp); if (RC.gNB[Mod_id][CC_id]->configured == 1) { @@ -436,6 +441,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { LOG_I(PHY, "Initialise nr transport\n"); for (i=0; idlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti); + gNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti); }*/ + + ///////////////////////// Initializing gNB ULSCH ///////////////////////// + LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); + + // ULSCH for RA + if(i==0) { + gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0); + + if (!gNB->ulsch[i][j]) { + LOG_E(PHY,"Can't get gNB ulsch structures\n"); + exit(-1); + } + } + + // ULSCH for data + gNB->ulsch[i+1][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0); + + if (!gNB->ulsch[i+1][j]) { + LOG_E(PHY,"Can't get gNB ulsch structures\n"); + exit(-1); + } + ////////////////////////////////////////////////////////////////////////// } - //LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); - //gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); - /*if (!gNB->ulsch[1+i]) { - LOG_E(PHY,"Can't get gNB ulsch structures\n"); - exit(-1); - }*/ // this is the transmission mode for the signalling channels // this will be overwritten with the real transmission mode by the RRC once the UE is connected //gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2; } - // ULSCH for RA - //gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); - /*if (!gNB->ulsch[0]) { - LOG_E(PHY,"Can't get gNB ulsch structures\n"); - exit(-1); - }*/ gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI); gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index de3bd2fe62..9b0c3562af 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -1,23 +1,23 @@ /* - * 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 - */ +* 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 +*/ #include #include @@ -32,6 +32,7 @@ #include "SIMULATION/TOOLS/sim.h" #include "SIMULATION/RF/rf.h" + #include "PHY/types.h" #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" @@ -43,6 +44,7 @@ #include "PHY/MODULATION/modulation_UE.h" #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" +#include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED_NR/sched_nr.h" @@ -63,41 +65,40 @@ double cpuf; // dummy functions int nfapi_mode = 0; int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { - return (0); + return (0); } int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { - return (0); + return (0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { - return (0); + return (0); } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { - return (0); + return (0); } int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { - return (0); + return (0); } uint32_t from_nrarfcn(int nr_bandP, uint32_t dl_earfcn) { - return (0); + return (0); } int32_t get_uldl_offset(int eutra_bandP) { - return (0); + return (0); } NR_IF_Module_t * NR_IF_Module_init(int Mod_id) { - return (NULL); + return (NULL); } -void exit_function(const char *file, const char *function, const int line, - const char *s) { - const char *msg = s == NULL ? "no comment" : s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); +void exit_function(const char *file, const char *function, const int line, const char *s) { + const char *msg = s == NULL ? "no comment" : s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); } // needed for some functions @@ -105,631 +106,631 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } }; uint16_t n_rnti = 0x1234; char quantize(double D, double x, unsigned char B) { - double qxd; - short maxlev; - qxd = floor(x / D); - maxlev = 1 << (B - 1); //(char)(pow(2,B-1)); + double qxd; + short maxlev; + qxd = floor(x / D); + maxlev = 1 << (B - 1); //(char)(pow(2,B-1)); - //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); + //printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev); - if (qxd <= -maxlev) - qxd = -maxlev; - else if (qxd >= maxlev) - qxd = maxlev - 1; + if (qxd <= -maxlev) + qxd = -maxlev; + else if (qxd >= maxlev) + qxd = maxlev - 1; - return ((char) qxd); + return ((char) qxd); } int main(int argc, char **argv) { - char c; - int i,sf; //,j,l,aa; - double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0; - double snr_step = 0.1; - uint8_t snr1set = 0; - int **txdata; - double **s_re, **s_im, **r_re, **r_im; - // int sync_pos, sync_pos_slot; - // FILE *rx_frame_file; - FILE *output_fd = NULL; - uint8_t write_output_file = 0; - // int subframe_offset; - // char fname[40], vname[40]; - int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; - uint8_t transmission_mode = 1, n_tx = 1, n_rx = 1; - uint16_t Nid_cell = 0; - channel_desc_t *gNB2UE; - uint8_t extended_prefix_flag = 0; - int8_t interf1 = -21, interf2 = -21; - FILE *input_fd = NULL, *pbch_file_fd = NULL; - //char input_val_str[50],input_val_str2[50]; - //uint16_t NB_RB=25; - SCM_t channel_model = AWGN; //Rayleigh1_anticorr; - uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; - unsigned char frame_type = 0; - unsigned char pbch_phase = 0; - int frame = 0, subframe = 0; - int frame_length_complex_samples; - //int frame_length_complex_samples_no_prefix; - NR_DL_FRAME_PARMS *frame_parms; - //nfapi_nr_config_request_t *gNB_config; - uint8_t Kmimo = 0; - uint32_t Nsoft = 0; - double sigma; - unsigned char qbits = 8; - int ret; - //int run_initial_sync=0; - int loglvl = OAILOG_WARNING; - float target_error_rate = 0.01; - - uint16_t nb_symb_sch = 12; - uint16_t nb_rb = 50; - uint8_t Imcs = 9; - - cpuf = get_cpu_freq_GHz(); - - if (load_configmodule(argc, argv) == 0) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - - //logInit(); - randominit(0); - - while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:N:F:R:P:")) != -1) { - switch (c) { - case 'f': - write_output_file = 1; - output_fd = fopen(optarg, "w"); - - if (output_fd == NULL) { - printf("Error opening %s\n", optarg); - exit(-1); - } - - break; - - case 'd': - frame_type = 1; - break; - - case 'g': - switch ((char) *optarg) { - case 'A': - channel_model = SCM_A; - break; - - case 'B': - channel_model = SCM_B; - break; - - case 'C': - channel_model = SCM_C; - break; - - case 'D': - channel_model = SCM_D; - break; - - case 'E': - channel_model = EPA; - break; - - case 'F': - channel_model = EVA; - break; - - case 'G': - channel_model = ETU; - break; - - default: - msg("Unsupported channel model!\n"); - exit(-1); - } - - break; - - case 'i': - interf1 = atoi(optarg); - break; - - case 'j': - interf2 = atoi(optarg); - break; - - case 'n': - n_trials = atoi(optarg); - break; - - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n", snr0); - break; - - case 'S': - snr1 = atof(optarg); - snr1set = 1; - msg("Setting SNR1 to %f\n", snr1); - break; - - case 'p': - extended_prefix_flag = 1; - break; - - /* - case 'r': - ricean_factor = pow(10,-.1*atof(optarg)); - if (ricean_factor>1) { - printf("Ricean factor must be between 0 and 1\n"); - exit(-1); - } - break; - */ - - case 'y': - n_tx = atoi(optarg); - - if ((n_tx == 0) || (n_tx > 2)) { - msg("Unsupported number of tx antennas %d\n", n_tx); - exit(-1); - } - - break; - - case 'z': - n_rx = atoi(optarg); - - if ((n_rx == 0) || (n_rx > 2)) { - msg("Unsupported number of rx antennas %d\n", n_rx); - exit(-1); - } - - break; - - case 'N': - Nid_cell = atoi(optarg); - break; - - case 'R': - N_RB_DL = atoi(optarg); - N_RB_UL = N_RB_DL; - break; - - case 'F': - input_fd = fopen(optarg, "r"); - - if (input_fd == NULL) { - printf("Problem with filename %s\n", optarg); - exit(-1); - } - - break; - - case 'P': - pbch_phase = atoi(optarg); - - if (pbch_phase > 3) - printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); - - break; - - case 'm': - Imcs = atoi(optarg); - break; - - case 'l': - nb_symb_sch = atoi(optarg); - break; - - case 'r': - nb_rb = atoi(optarg); - break; - - case 'x': - transmission_mode = atoi(optarg); - break; - - default: - case 'h': - printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -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("-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 [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Nid_cell\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 Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit(-1); - break; - } - } - - logInit(); - set_glog(loglvl); - T_stdout = 1; - - if (snr1set == 0) - snr1 = snr0 + 10; - - gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, - 61.44e6, //N_RB2sampling_rate(N_RB_DL), - 40e6, //N_RB2channel_bandwidth(N_RB_DL), - 0, 0, 0); - - if (gNB2UE == NULL) { - msg("Problem generating channel model. Exiting.\n"); - exit(-1); - } - - RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **)); - RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *)); - RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); - gNB = RC.gNB[0][0]; - //gNB_config = &gNB->gNB_config; - frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) - frame_parms->nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = n_rx; - frame_parms->N_RB_DL = N_RB_DL; - frame_parms->N_RB_UL = N_RB_UL; - frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; - crcTableInit(); - nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell); - phy_init_nr_gNB(gNB, 0, 0); - //init_eNB_afterRU(); - frame_length_complex_samples = frame_parms->samples_per_subframe; - //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; - s_re = malloc(2 * sizeof(double *)); - s_im = malloc(2 * sizeof(double *)); - r_re = malloc(2 * sizeof(double *)); - r_im = malloc(2 * sizeof(double *)); - txdata = malloc(2 * sizeof(int *)); - - for (i = 0; i < 2; i++) { - s_re[i] = malloc(frame_length_complex_samples * sizeof(double)); - bzero(s_re[i], frame_length_complex_samples * sizeof(double)); - s_im[i] = malloc(frame_length_complex_samples * sizeof(double)); - bzero(s_im[i], frame_length_complex_samples * sizeof(double)); - r_re[i] = malloc(frame_length_complex_samples * sizeof(double)); - bzero(r_re[i], frame_length_complex_samples * sizeof(double)); - r_im[i] = malloc(frame_length_complex_samples * sizeof(double)); - bzero(r_im[i], frame_length_complex_samples * sizeof(double)); - txdata[i] = malloc(frame_length_complex_samples * sizeof(int)); - bzero(r_re[i], frame_length_complex_samples * sizeof(int)); - } - - if (pbch_file_fd != NULL) { - load_pbch_desc(pbch_file_fd); - } - - /* for (int k=0; k<2; k++) { - // Create transport channel structures for 2 transport blocks (MIMO) - for (i=0; i<2; i++) { - gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config); - - if (!gNB->dlsch[k][i]) { - printf("Can't get eNB dlsch structures\n"); - exit(-1); - } - gNB->dlsch[k][i]->Nsoft = 10; - gNB->dlsch[k][i]->rnti = n_rnti+k; - } - }*/ - //configure UE - UE = malloc(sizeof(PHY_VARS_NR_UE)); - memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); - - //phy_init_nr_top(frame_parms); - if (init_nr_ue_signal(UE, 1, 0) != 0) { - printf("Error at UE NR initialisation\n"); - exit(-1); - } - - //nr_init_frame_parms_ue(&UE->frame_parms); - //init_nr_ue_transport(UE, 0); - for (sf = 0; sf < 2; sf++) { - for (i = 0; i < 2; i++) { - UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo, 8, Nsoft, 5, N_RB_DL, - 0); - - if (!UE->dlsch[sf][0][i]) { - printf("Can't get ue dlsch structures\n"); - exit(-1); - } - - UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0); - - if (!UE->ulsch[sf][0][i]) { - printf("Can't get ue ulsch structures\n"); - exit(-1); - } - - UE->dlsch[sf][0][i]->rnti = n_rnti; - } - } - - UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); - UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); - unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; - NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0]; - nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15; - - NR_UE_ULSCH_t *ulsch = UE->ulsch[0][0][0]; - - //time_stats_t *rm_stats, *te_stats, *i_stats; - uint8_t is_crnti = 0, llr8_flag = 0; - unsigned int TBS = 8424; - unsigned int available_bits; - uint8_t nb_re_dmrs = 6; - uint16_t length_dmrs = 1; - unsigned char mod_order; - uint8_t Nl = 1; - uint8_t rvidx = 0; - dlsch->rnti = 1; - ulsch->nb_re_dmrs = nb_re_dmrs; //[adk] A HOT FIX until cearting nfapi_nr_ul_config_ulsch_pdu_rel15_t - /*dlsch->harq_processes[0]->mcs = Imcs; - dlsch->harq_processes[0]->rvidx = rvidx;*/ - //printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe], - // dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl); - mod_order = nr_get_Qm(Imcs, 1); - available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); - printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order); - //dlsch->harq_ids[subframe]= 0; - rel15->n_prb = nb_rb; - rel15->nb_symbols = nb_symb_sch; - rel15->modulation_order = mod_order; - rel15->nb_layers = Nl; - rel15->nb_re_dmrs = nb_re_dmrs; - rel15->transport_block_size = TBS; - double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); - short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); - short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); - unsigned int errors_bit_uncoded = 0; - unsigned char *estimated_output; - unsigned char *estimated_output_bit; - unsigned char *test_input_bit; - unsigned int errors_bit = 0; - - test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - - estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - - estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - - NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0]; - NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid]; - harq_process->mcs = Imcs; - harq_process->Nl = Nl; - harq_process->nb_rb = nb_rb; - harq_process->Qm = mod_order; - harq_process->rvidx = rvidx; - printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); - unsigned char *test_input; - test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); - - for (i = 0; i < TBS / 8; i++) - test_input[i] = (unsigned char) rand(); - - estimated_output = harq_process->b; - - - /////////////////////////[adk] preparing UL harq_process parameters///////////////////////// - /////////// - NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch->harq_processes[harq_pid]; - - if (harq_process_ul_ue){ - - harq_process_ul_ue->mcs = Imcs; - harq_process_ul_ue->Nl = Nl; - harq_process_ul_ue->nb_rb = nb_rb; - harq_process_ul_ue->nb_symbols = nb_symb_sch; - harq_process_ul_ue->rvidx = rvidx; - harq_process_ul_ue->TBS = TBS; - harq_process_ul_ue->a = &test_input[0]; - - } - /////////// - //////////////////////////////////////////////////////////////////////////////////////////// + char c; + int i,sf; //,j,l,aa; + double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0; + double snr_step = 0.1; + uint8_t snr1set = 0; + int **txdata; + double **s_re, **s_im, **r_re, **r_im; + // int sync_pos, sync_pos_slot; + // FILE *rx_frame_file; + FILE *output_fd = NULL; + uint8_t write_output_file = 0; + // int subframe_offset; + // char fname[40], vname[40]; + int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; + uint8_t transmission_mode = 1, n_tx = 1, n_rx = 1; + uint16_t Nid_cell = 0; + channel_desc_t *gNB2UE; + uint8_t extended_prefix_flag = 0; + int8_t interf1 = -21, interf2 = -21; + FILE *input_fd = NULL, *pbch_file_fd = NULL; + //char input_val_str[50],input_val_str2[50]; + //uint16_t NB_RB=25; + SCM_t channel_model = AWGN; //Rayleigh1_anticorr; + uint8_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; + unsigned char frame_type = 0; + unsigned char pbch_phase = 0; + int frame = 0, subframe = 0; + int frame_length_complex_samples; + //int frame_length_complex_samples_no_prefix; + NR_DL_FRAME_PARMS *frame_parms; + //nfapi_nr_config_request_t *gNB_config; + // uint8_t Kmimo = 0; + uint32_t Nsoft = 0; + double sigma; + unsigned char qbits = 8; + int ret; + //int run_initial_sync=0; + int loglvl = OAILOG_WARNING; + float target_error_rate = 0.01; + + uint16_t nb_symb_sch = 12; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; + + cpuf = get_cpu_freq_GHz(); + + if (load_configmodule(argc, argv) == 0) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + //logInit(); + randominit(0); + + while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:N:F:R:P:")) != -1) { + switch (c) { + case 'f': + write_output_file = 1; + output_fd = fopen(optarg, "w"); + + if (output_fd == NULL) { + printf("Error opening %s\n", optarg); + exit(-1); + } + + break; + + case 'd': + frame_type = 1; + break; + + case 'g': + switch ((char) *optarg) { + case 'A': + channel_model = SCM_A; + break; + + case 'B': + channel_model = SCM_B; + break; + + case 'C': + channel_model = SCM_C; + break; + + case 'D': + channel_model = SCM_D; + break; + + case 'E': + channel_model = EPA; + break; + + case 'F': + channel_model = EVA; + break; + + case 'G': + channel_model = ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + + break; + + case 'i': + interf1 = atoi(optarg); + break; + + case 'j': + interf2 = atoi(optarg); + break; + + case 'n': + n_trials = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n", snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set = 1; + msg("Setting SNR1 to %f\n", snr1); + break; + + case 'p': + extended_prefix_flag = 1; + break; + + /* + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } + break; + */ + + case 'y': + n_tx = atoi(optarg); + + if ((n_tx == 0) || (n_tx > 2)) { + msg("Unsupported number of tx antennas %d\n", n_tx); + exit(-1); + } + + break; + + case 'z': + n_rx = atoi(optarg); + + if ((n_rx == 0) || (n_rx > 2)) { + msg("Unsupported number of rx antennas %d\n", n_rx); + exit(-1); + } + + break; + + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + N_RB_UL = N_RB_DL; + break; + + case 'F': + input_fd = fopen(optarg, "r"); + + if (input_fd == NULL) { + printf("Problem with filename %s\n", optarg); + exit(-1); + } + + break; + + case 'P': + pbch_phase = atoi(optarg); + + if (pbch_phase > 3) + printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase); + + break; + + case 'm': + Imcs = atoi(optarg); + break; + + case 'l': + nb_symb_sch = atoi(optarg); + break; + + case 'r': + nb_rb = atoi(optarg); + break; + + case 'x': + transmission_mode = atoi(optarg); + break; + + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -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("-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 [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\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 Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit(-1); + break; + } + } + + logInit(); + set_glog(loglvl); + T_stdout = 1; + + if (snr1set == 0) + snr1 = snr0 + 10; + + gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, 61.44e6, //N_RB2sampling_rate(N_RB_DL), + 40e6, //N_RB2channel_bandwidth(N_RB_DL), + 0, 0, 0); + + if (gNB2UE == NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **)); + RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *)); + RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB)); + gNB = RC.gNB[0][0]; + //gNB_config = &gNB->gNB_config; + + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_DL; + frame_parms->N_RB_UL = N_RB_UL; + frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + + crcTableInit(); + + nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell); + + phy_init_nr_gNB(gNB, 0, 0); + //init_eNB_afterRU(); + + frame_length_complex_samples = frame_parms->samples_per_subframe; + //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + s_re = malloc(2 * sizeof(double *)); + s_im = malloc(2 * sizeof(double *)); + r_re = malloc(2 * sizeof(double *)); + r_im = malloc(2 * sizeof(double *)); + txdata = malloc(2 * sizeof(int * )); + + for (i = 0; i < 2; i++) { + s_re[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(s_re[i], frame_length_complex_samples * sizeof(double)); + s_im[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(s_im[i], frame_length_complex_samples * sizeof(double)); + r_re[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(r_re[i], frame_length_complex_samples * sizeof(double)); + r_im[i] = malloc(frame_length_complex_samples * sizeof(double)); + bzero(r_im[i], frame_length_complex_samples * sizeof(double)); + txdata[i] = malloc(frame_length_complex_samples * sizeof(int)); + bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata + } + + if (pbch_file_fd != NULL) { + load_pbch_desc(pbch_file_fd); + } + + /* for (int k=0; k<2; k++) { + // Create transport channel structures for 2 transport blocks (MIMO) + for (i=0; i<2; i++) { + gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config); + + if (!gNB->dlsch[k][i]) { + printf("Can't get eNB dlsch structures\n"); + exit(-1); + } + gNB->dlsch[k][i]->Nsoft = 10; + gNB->dlsch[k][i]->rnti = n_rnti+k; + } + }*/ + //configure UE + UE = malloc(sizeof(PHY_VARS_NR_UE)); + memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + + //phy_init_nr_top(frame_parms); + if (init_nr_ue_signal(UE, 1, 0) != 0) { + printf("Error at UE NR initialisation\n"); + exit(-1); + } + + //nr_init_frame_parms_ue(&UE->frame_parms); + //init_nr_ue_transport(UE, 0); + for (sf = 0; sf < 2; sf++) { + for (i = 0; i < 2; i++) { + + UE->ulsch[sf][0][i] = new_nr_ue_ulsch(N_RB_UL, 8, 0); + + if (!UE->ulsch[sf][0][i]) { + printf("Can't get ue ulsch structures\n"); + exit(-1); + } + + } + } + + UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); + UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0); + + unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; + //time_stats_t *rm_stats, *te_stats, *i_stats; + uint8_t is_crnti = 0, llr8_flag = 0; + unsigned int TBS = 8424; + unsigned int available_bits; + uint8_t nb_re_dmrs = 6; + uint16_t length_dmrs = 1; + unsigned char mod_order; + uint8_t Nl = 1; + uint8_t rvidx = 0; + uint8_t UE_id = 1; + + NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; + nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15; + + NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0][0]; + + ulsch_ue->nb_re_dmrs = nb_re_dmrs; //[adk] A HOT FIX until cearting nfapi_nr_ul_config_ulsch_pdu_rel15_t + + mod_order = nr_get_Qm(Imcs, 1); + available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); + TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, Nl); + printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order); + + /////////// setting rel15_ul parameters /////////// + rel15_ul->number_rbs = nb_rb; + rel15_ul->number_symbols = nb_symb_sch; + rel15_ul->Qm = mod_order; + rel15_ul->mcs = Imcs; + rel15_ul->rv = rvidx; + rel15_ul->n_layers = Nl; + /////////////////////////////////////////////////// + + double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc + short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); + short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); + unsigned int errors_bit_uncoded = 0; + // unsigned char *estimated_output; + unsigned char *estimated_output_bit; + unsigned char *test_input_bit; + unsigned int errors_bit = 0; + + test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + // estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); + + unsigned char *test_input; + test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); + + for (i = 0; i < TBS / 8; i++) + test_input[i] = (unsigned char) rand(); + + // estimated_output = ulsch_gNB->harq_processes[harq_pid]->b; + + /////////////////////////[adk] preparing UL harq_process parameters///////////////////////// + /////////// + NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid]; + + if (harq_process_ul_ue) { + + harq_process_ul_ue->mcs = Imcs; + harq_process_ul_ue->Nl = Nl; + harq_process_ul_ue->nb_rb = nb_rb; + harq_process_ul_ue->nb_symbols = nb_symb_sch; + harq_process_ul_ue->rvidx = rvidx; + harq_process_ul_ue->TBS = TBS; + harq_process_ul_ue->a = &test_input[0]; + + } + /////////// + //////////////////////////////////////////////////////////////////////////////////////////// #ifdef DEBUG_ULSCHSIM - for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); + for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%d \n",test_input[i]); #endif - /*for (int i=0; i0x%08x\n",crc24c(test_input, 32)); - // generate signal + //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); + // generate signal - /////////////////////////[adk] ULSCH coding///////////////////////// - /////////// + /////////////////////////[adk] ULSCH coding///////////////////////// + /////////// - if (input_fd == NULL) { - nr_dlsch_encoding(test_input, subframe, dlsch, frame_parms); - nr_ulsch_encoding(ulsch, frame_parms, harq_pid); - } + if (input_fd == NULL) { + nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid); + } - for (SNR = snr0; SNR < snr1; SNR += snr_step) { - n_errors = 0; - n_false_positive = 0; + /////////// + //////////////////////////////////////////////////////////////////// + + + for (SNR = snr0; SNR < snr1; SNR += snr_step) { + n_errors = 0; + n_false_positive = 0; + + for (trial = 0; trial < n_trials; trial++) { + + errors_bit_uncoded = 0; + + for (i = 0; i < available_bits; i++) { - for (trial = 0; trial < n_trials; trial++) { - errors_bit_uncoded = 0; - for (i = 0; i < available_bits; i++) { #ifdef DEBUG_CODER - if ((i&0xf)==0) - printf("\ne %d..%d: ",i,i+15); + if ((i&0xf)==0) + printf("\ne %d..%d: ",i,i+15); #endif - /* - if (i<16){ - printf("dlsch_encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); - printf("ulsch_encoder output f[%d] = %d\n",i,ulsch->harq_processes[0]->f[i]); + /* + if (i<16){ + printf("dlsch_encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); + printf("ulsch_encoder output f[%d] = %d\n",i,ulsch_ue->harq_processes[0]->f[i]); + } + */ - } - */ - if (ulsch->harq_processes[0]->f[i] == 0) - modulated_input[i] = 1.0; ///sqrt(2); //QPSK - else - modulated_input[i] = -1.0; ///sqrt(2); + if (ulsch_ue->harq_processes[0]->f[i] == 0) + modulated_input[i] = 1.0; ///sqrt(2); //QPSK + else + modulated_input[i] = -1.0; ///sqrt(2); + + //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); + //SNR =10; - //if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]); - //SNR =10; - SNR_lin = pow(10, SNR / 10.0); - sigma = 1.0 / sqrt(2 * SNR_lin); + SNR_lin = pow(10, SNR / 10.0); + sigma = 1.0 / sqrt(2 * SNR_lin); #if 1 - channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, - modulated_input[i] + sigma * gaussdouble(0.0, 1.0), - qbits); + channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0, + modulated_input[i] + sigma * gaussdouble(0.0, 1.0), + qbits); #else - channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits); + channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits); #endif - //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); - //printf("llr[%d]=%d\n",i,channel_output_fixed[i]); - //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); + //channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0)); + //printf("llr[%d]=%d\n",i,channel_output_fixed[i]); + //printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]); - //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits); + //channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits); - //if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]); + //if (i<16) printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]); - //Uncoded BER - if (channel_output_fixed[i] < 0) - channel_output_uncoded[i] = 1; //QPSK demod - else - channel_output_uncoded[i] = 0; + //Uncoded BER + if (channel_output_fixed[i] < 0) + channel_output_uncoded[i] = 1; //QPSK demod + else + channel_output_uncoded[i] = 0; - if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i]) - errors_bit_uncoded = errors_bit_uncoded + 1; - } + if (channel_output_uncoded[i] != ulsch_ue->harq_processes[harq_pid]->f[i]) + errors_bit_uncoded = errors_bit_uncoded + 1; + } + + //if (errors_bit_uncoded>10) + printf("errors bits uncoded %u\n", errors_bit_uncoded); - //if (errors_bit_uncoded>10) - printf("errors bits uncoded %u\n", errors_bit_uncoded); #ifdef DEBUG_CODER - printf("\n"); - exit(-1); + printf("\n"); + exit(-1); #endif - ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms, - dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch, - subframe, harq_pid, is_crnti, llr8_flag); - if (ret > dlsch0_ue->max_ldpc_iterations) - n_errors++; + ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, + frame, nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag); - //count errors - errors_bit = 0; + if (ret > ulsch_gNB->max_ldpc_iterations) + n_errors++; - for (i = 0; i < TBS; i++) { - estimated_output_bit[i] = (ulsch->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7); - test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments + //count errors + errors_bit = 0; - if (estimated_output_bit[i] != test_input_bit[i]) { - errors_bit++; - //printf("estimated bits error occurs @%d ",i); - } - } + for (i = 0; i < TBS; i++) { + estimated_output_bit[i] = (ulsch_gNB->harq_processes[harq_pid]->b[i/8] & (1 << (i & 7))) >> (i & 7); + test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments - if (errors_bit > 0) { - n_false_positive++; - if (n_trials == 1) - printf("errors_bit %d (trial %d)\n", errors_bit, trial); - } - } + if (estimated_output_bit[i] != test_input_bit[i]) { + errors_bit++; + //printf("estimated bits error occurs @%d ",i); + } + } - printf("SNR %f, BLER %f (false positive %f)\n", SNR, - (float) n_errors / (float) n_trials, - (float) n_false_positive / (float) n_trials); + if (errors_bit > 0) { + n_false_positive++; + if (n_trials == 1) + printf("errors_bit %d (trial %d)\n", errors_bit, trial); + } + } + + printf("*****************************************\n"); + printf("SNR %f, BLER %f (false positive %f)\n", SNR, + (float) n_errors / (float) n_trials, + (float) n_false_positive / (float) n_trials); + printf("*****************************************\n"); - if ((float) n_errors / (float) n_trials < target_error_rate) { - printf("PDSCH test OK\n"); - break; - } - } + if ((float) n_errors / (float) n_trials < target_error_rate) + break; + } - /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/ + /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/ - //TODO: loop over slots - /*for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { - if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { - PHY_ofdm_mod(gNB->common_vars.txdataF[aa], - txdata[aa], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - } else { - nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], - txdata[aa], - 14, - frame_parms); - } - } + //TODO: loop over slots + /*for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { + if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { + PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { + nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + txdata[aa], + 14, + frame_parms); + } + } - LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); - if (gNB->frame_parms.nb_antennas_tx>1) - LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); + LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1); + if (gNB->frame_parms.nb_antennas_tx>1) + LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1); - for (i=0; inb_antennas_tx; aa++) { - r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); - r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); - } - }*/ + for (i=0; inb_antennas_tx; aa++) { + r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]); + r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); + } + }*/ + for (i = 0; i < 2; i++) { - for (i = 0; i < 2; i++) { + printf("----------------------\n"); + printf("freeing codeword %d\n", i); + printf("----------------------\n"); - printf("gNB %d\n", i); + printf("gNB ulsch[0][%d]\n", i); // [hna] ulsch[0] is for RA - if (gNB->dlsch[0][i]) - free_gNB_dlsch(gNB->dlsch[0][i]); + free_gNB_ulsch(gNB->ulsch[0][i]); - for (sf = 0; sf < 2; sf++) { + printf("gNB ulsch[%d][%d]\n",UE_id, i); - printf("UE %d\n", i); + free_gNB_ulsch(gNB->ulsch[UE_id][i]); - if (UE->dlsch[sf][0][i]) - free_nr_ue_dlsch(UE->dlsch[sf][0][i]); + for (sf = 0; sf < 2; sf++) { - if (UE->ulsch[sf][0][i]) - free_nr_ue_ulsch(UE->ulsch[sf][0][i]); - } - } + printf("UE ulsch[%d][0][%d]\n", sf, i); - for (i = 0; i < 2; i++) { - free(s_re[i]); - free(s_im[i]); - free(r_re[i]); - free(r_im[i]); - free(txdata[i]); - } + if (UE->ulsch[sf][0][i]) + free_nr_ue_ulsch(UE->ulsch[sf][0][i]); + } - free(s_re); - free(s_im); - free(r_re); - free(r_im); - free(txdata); + printf("\n"); + } - if (output_fd) - fclose(output_fd); + for (i = 0; i < 2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + free(txdata[i]); + } - if (input_fd) - fclose(input_fd); + free(s_re); + free(s_im); + free(r_re); + free(r_im); + free(txdata); - return (n_errors); + if (output_fd) + fclose(output_fd); + + if (input_fd) + fclose(input_fd); + + return (n_errors); } From bc53a0a77144772de29c7244b0eee5d7801d53f5 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Fri, 1 Mar 2019 17:48:51 +0100 Subject: [PATCH 09/21] indentation + some comments --- openair1/PHY/CODING/coding_defs.h | 2 +- openair1/PHY/CODING/nr_segmentation.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 5 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 1146 ++++++++--------- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 4 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 4 +- 6 files changed, 579 insertions(+), 584 deletions(-) diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 0f316e7869..0c1dbfae35 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -453,7 +453,7 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int B, unsigned int *C, unsigned int *K, - unsigned int *Zout, + unsigned int *Zout, unsigned int *F); uint32_t nr_compute_tbs(uint8_t mcs, diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 8d0cc9e7d3..421f440ec2 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -34,7 +34,7 @@ int32_t nr_segmentation(unsigned char *input_buffer, unsigned int B, unsigned int *C, unsigned int *K, - unsigned int *Zout, + unsigned int *Zout, // [hna] Zout is Zc unsigned int *F) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 4e8c2d2ff5..50e836fe58 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -195,6 +195,9 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo, if (abstraction_flag==0) { for (r=0; rharq_processes[i]->c[r] = (uint8_t*)malloc16(8448); dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output if (dlsch->harq_processes[i]->c[r]) { @@ -337,7 +340,7 @@ int nr_dlsch_encoding(unsigned char *a, dlsch->harq_processes[harq_pid]->B, &dlsch->harq_processes[harq_pid]->C, &dlsch->harq_processes[harq_pid]->K, - pz, + pz, // [hna] pz is Zc &dlsch->harq_processes[harq_pid]->F); F = dlsch->harq_processes[harq_pid]->F; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index def3a71754..7cc6dde893 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -76,11 +76,11 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch) } for (r=0; r<(MAX_NUM_NR_DLSCH_SEGMENTS); r++) { - if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]){ - nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]); - dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; - } - } + if (dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]){ + nrLDPC_free_mem(dlsch->harq_processes[i]->p_nrLDPC_procBuf[r]); + dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = NULL; + } + } free16(dlsch->harq_processes[i],sizeof(NR_DL_UE_HARQ_t)); dlsch->harq_processes[i] = NULL; @@ -143,7 +143,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint if (abstraction_flag == 0) { for (r=0; rharq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); + dlsch->harq_processes[i]->p_nrLDPC_procBuf[r] = nrLDPC_init_mem(); dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(1056); if (dlsch->harq_processes[i]->c[r]) @@ -192,7 +192,7 @@ void nr_dlsch_unscrambling(int16_t* llr, reset = 0; } if (((s>>(i&0x1f))&1)==1) - llr[i] = -llr[i]; + llr[i] = -llr[i]; } } @@ -203,7 +203,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, NR_UE_DLSCH_t *dlsch, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, - uint16_t nb_symb_sch, + uint16_t nb_symb_sch, uint8_t nr_tti_rx, uint8_t harq_pid, uint8_t is_crnti, @@ -247,7 +247,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0]; - if (!dlsch_llr) { + if (!dlsch_llr) { printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); return(dlsch->max_ldpc_iterations); } @@ -305,57 +305,59 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, // [hna] Z is Zc + &harq_process->F); + + p_decParams->Z = harq_process->Z; #ifdef DEBUG_DLSCH_DECODING printf("dlsch decoding nr segmentation Z %d\n", p_decParams->Z); - if (!frame%100) - printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); + if (!frame%100) + printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); #endif } - Coderate = (float) A /(float) G; - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - p_decParams->BG = 2; - if (Coderate < 0.3333){ - p_decParams->R = 15; - kc = 52; - } - else if (Coderate <0.6667){ - p_decParams->R = 13; - kc = 32; - } - else { - p_decParams->R = 23; - kc = 17; - } - } - else{ - p_decParams->BG = 1; - if (Coderate < 0.6667){ - p_decParams->R = 13; - kc = 68; - } - else if (Coderate <0.8889){ - p_decParams->R = 23; - kc = 35; - } - else { - p_decParams->R = 89; - kc = 27; - } - } - //printf("coderate %f kc %d \n", Coderate, kc); + Coderate = (float) A /(float) G; + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + { + p_decParams->BG = 2; + if (Coderate < 0.3333){ + p_decParams->R = 15; + kc = 52; + } + else if (Coderate <0.6667){ + p_decParams->R = 13; + kc = 32; + } + else { + p_decParams->R = 23; + kc = 17; + } + } + else{ + p_decParams->BG = 1; + if (Coderate < 0.6667){ + p_decParams->R = 13; + kc = 68; + } + else if (Coderate <0.8889){ + p_decParams->R = 23; + kc = 35; + } + else { + p_decParams->R = 89; + kc = 27; + } + } - p_decParams->numMaxIter = dlsch->max_ldpc_iterations; - p_decParams->outMode= 0; + //printf("coderate %f kc %d \n", Coderate, kc); + p_decParams->numMaxIter = dlsch->max_ldpc_iterations; + p_decParams->outMode= 0; err_flag = 0; r_offset = 0; @@ -363,27 +365,27 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, unsigned char bw_scaling =1; switch (frame_parms->N_RB_DL) { + case 106: + bw_scaling =2; + break; - case 106: - bw_scaling =2; - break; - - default: - bw_scaling =1; - break; + default: + bw_scaling =1; + break; } if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling) { LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling); return((1+dlsch->max_ldpc_iterations)); } + #ifdef DEBUG_DLSCH_DECODING printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); #endif opp_enabled=1; - Kr = harq_process->K; + Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" Kr_bytes = Kr>>3; K_bytes_F = Kr_bytes-(harq_process->F>>3); @@ -400,11 +402,11 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #endif nr_deinterleaving_ldpc(E, harq_process->Qm, - harq_process->w[r], + harq_process->w[r], // [hna] w is e dlsch_llr+r_offset); //for (int i =0; i<16; i++) - // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -441,31 +443,30 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #endif LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); return(dlsch->max_ldpc_iterations); - } else - { + } else { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif } //for (int i =0; i<16; i++) - // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); r_offset += E; #ifdef DEBUG_DLSCH_DECODING if (r==0) { - write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); + write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); + write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0); } printf("decoder input(segment %d) :",r); - int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) + int i; + for (i=0;i<(3*8*Kr_bytes)+12;i++) printf("%d : %d\n",i,harq_process->d[r][i]); - printf("\n"); + printf("\n"); #endif - // printf("Clearing c, %p\n",harq_process->c[r]); memset(harq_process->c[r],0,Kr_bytes); @@ -482,74 +483,70 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (err_flag == 0) { #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); #endif //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); //printf("harq process dr iteration %d\n", p_decParams->numMaxIter); + memset(pv,0,2*harq_process->Z*sizeof(int16_t)); + //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); + memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); - memset(pv,0,2*harq_process->Z*sizeof(int16_t)); - //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); - memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); + for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); + } - for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); - } + for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); + } - for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); - } - - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) - { - - pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); - - } + for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + { + pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + } - no_iteration_ldpc = nrLDPC_decoder(p_decParams, - (int8_t*)&pl[0], - llrProcBuf, + no_iteration_ldpc = nrLDPC_decoder(p_decParams, + (int8_t*)&pl[0], + llrProcBuf, p_nrLDPC_procBuf[r], p_procTime); - // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int - if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { - printf("Segment %d CRC OK\n",r); - ret = 2; - } - else { - printf("CRC NOK\n"); - ret = 1+dlsch->max_ldpc_iterations; - } - + // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int + if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { + printf("Segment %d CRC OK\n",r); + ret = 2; + } + else { + printf("CRC NOK\n"); + ret = 1+dlsch->max_ldpc_iterations; + } - nb_total_decod++; - if (no_iteration_ldpc > dlsch->max_ldpc_iterations){ - nb_error_decod++; - } + nb_total_decod++; + if (no_iteration_ldpc > dlsch->max_ldpc_iterations){ + nb_error_decod++; + } - ret=no_iteration_ldpc; + ret=no_iteration_ldpc; - //if (!nb_total_decod%10000){ - //printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); - //} - //else - //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); + //if (!nb_total_decod%10000){ + //printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + //} + //else + //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) - { - harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; - } + for (int m=0; m < Kr>>3; m ++) + { + harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; + } #ifdef DEBUG_DLSCH_DECODING //printf("output decoder %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 k=0;k>3;k++) - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); printf("no_iterations_ldpc %d (ret %d)\n",no_iteration_ldpc,ret); //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif @@ -664,18 +661,18 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #ifdef UE_DLSCH_PARALLELISATION uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, - UE_nr_rxtx_proc_t *proc, - int eNB_id, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag) + UE_nr_rxtx_proc_t *proc, + int eNB_id, + short *dlsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + NR_UE_DLSCH_t *dlsch, + NR_DL_UE_HARQ_t *harq_process, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag) { #if UE_TIMING_TRACE @@ -786,27 +783,28 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F); + + p_decParams->Z = harq_process->Z; } - kb = harq_process->K/harq_process->Z; - if ( kb==22){ - p_decParams->BG = 1; - p_decParams->R = 13; - kc = 68; - } - else{ - p_decParams->BG = 2; - p_decParams->R = 13; - kc = 52; - } + kb = harq_process->K/harq_process->Z; + if ( kb==22){ + p_decParams->BG = 1; + p_decParams->R = 13; + kc = 68; + } + else{ + p_decParams->BG = 2; + p_decParams->R = 13; + kc = 52; + } p_decParams->numMaxIter = 2; Kr = p_decParams->Z*kb; @@ -842,135 +840,133 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #endif opp_enabled=1; -if (harq_process->C>1) { // wakeup worker if more than 1 segment - if (pthread_mutex_lock(&proc->mutex_dlsch_td) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE dlsch td\n",phy_vars_ue->Mod_id ); - exit_fun("nothing to add"); - } + if (harq_process->C>1) { // wakeup worker if more than 1 segment + if (pthread_mutex_lock(&proc->mutex_dlsch_td) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE dlsch td\n",phy_vars_ue->Mod_id ); + exit_fun("nothing to add"); + } - /*Qm= harq_process->Qm; - Nl=harq_process->Nl; - r_thread = harq_process->C/2-1; - C= harq_process->C; + /*Qm= harq_process->Qm; + Nl=harq_process->Nl; + r_thread = harq_process->C/2-1; + C= harq_process->C; - Gp = G/Nl/Qm; - GpmodC = Gp%C; + Gp = G/Nl/Qm; + GpmodC = Gp%C; - if (r_thread < (C-(GpmodC))) - Er = Nl*Qm * (Gp/C); - else - Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); - printf("mthread Er %d\n", Er); + if (r_thread < (C-(GpmodC))) + Er = Nl*Qm * (Gp/C); + else + Er = Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + printf("mthread Er %d\n", Er); - printf("mthread instance_cnt_dlsch_td %d\n", proc->instance_cnt_dlsch_td);*/ + printf("mthread instance_cnt_dlsch_td %d\n", proc->instance_cnt_dlsch_td);*/ - proc->instance_cnt_dlsch_td++; - proc->eNB_id = eNB_id; - proc->harq_pid = harq_pid; - proc->llr8_flag = llr8_flag; - //proc->r[0] = 1; + proc->instance_cnt_dlsch_td++; + proc->eNB_id = eNB_id; + proc->harq_pid = harq_pid; + proc->llr8_flag = llr8_flag; + //proc->r[0] = 1; - if (proc->instance_cnt_dlsch_td == 0) - { - LOG_D(PHY,"unblock dlsch td processing thread blocked on instance_cnt_dlsch_td : %d \n", proc->instance_cnt_dlsch_td ); - if (pthread_cond_signal(&proc->cond_dlsch_td) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE dlsch td\n", phy_vars_ue->Mod_id); - exit_fun("nothing to add"); - } - if (pthread_mutex_unlock(&proc->mutex_dlsch_td) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id ); - exit_fun("nothing to add"); - } + if (proc->instance_cnt_dlsch_td == 0) + { + LOG_D(PHY,"unblock dlsch td processing thread blocked on instance_cnt_dlsch_td : %d \n", proc->instance_cnt_dlsch_td ); + if (pthread_cond_signal(&proc->cond_dlsch_td) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE dlsch td\n", phy_vars_ue->Mod_id); + exit_fun("nothing to add"); + } + if (pthread_mutex_unlock(&proc->mutex_dlsch_td) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id ); + exit_fun("nothing to add"); + } + } else + { + LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td); + if (proc->instance_cnt_dlsch_td > 4) + exit_fun("instance_cnt_dlsch_td > 4"); + } + //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_dlsch_td) ==0,""); - } else - { - LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td); - if (proc->instance_cnt_dlsch_td > 4) - exit_fun("instance_cnt_dlsch_td > 4"); - } - //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,""); - AssertFatal(pthread_mutex_unlock(&proc->mutex_dlsch_td) ==0,""); + if (harq_process->C>2) { + if (pthread_mutex_lock(&proc->mutex_dlsch_td1) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE dlsch td\n",phy_vars_ue->Mod_id ); + exit_fun("nothing to add"); + } - if (harq_process->C>2) { - if (pthread_mutex_lock(&proc->mutex_dlsch_td1) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE dlsch td\n",phy_vars_ue->Mod_id ); - exit_fun("nothing to add"); - } + proc->instance_cnt_dlsch_td1++; + proc->eNB_id = eNB_id; + proc->harq_pid = harq_pid; + proc->llr8_flag = llr8_flag; + // proc->Er = Er; - proc->instance_cnt_dlsch_td1++; - proc->eNB_id = eNB_id; - proc->harq_pid = harq_pid; - proc->llr8_flag = llr8_flag; - // proc->Er = Er; + if (proc->instance_cnt_dlsch_td1 == 0) + { + LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_dlsch_td : %d \n", proc->instance_cnt_dlsch_td1 ); + if (pthread_cond_signal(&proc->cond_dlsch_td1) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE dlsch td\n", phy_vars_ue->Mod_id); + exit_fun("nothing to add"); + } + if (pthread_mutex_unlock(&proc->mutex_dlsch_td1) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id ); + exit_fun("nothing to add"); + } + } else + { + LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread 1 busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td1); + if (proc->instance_cnt_dlsch_td1 > 4) + exit_fun("instance_cnt_dlsch_td1 > 4"); + } - if (proc->instance_cnt_dlsch_td1 == 0) - { - LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_dlsch_td : %d \n", proc->instance_cnt_dlsch_td1 ); - if (pthread_cond_signal(&proc->cond_dlsch_td1) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE dlsch td\n", phy_vars_ue->Mod_id); - exit_fun("nothing to add"); - } - if (pthread_mutex_unlock(&proc->mutex_dlsch_td1) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE dlsch td \n",phy_vars_ue->Mod_id ); - exit_fun("nothing to add"); - } + AssertFatal(pthread_mutex_unlock(&proc->mutex_dlsch_td1) ==0,""); - } else - { - LOG_E( PHY, "[SCHED][UE %d] UE dlsch td thread 1 busy (IC %d)!!\n", phy_vars_ue->Mod_id, proc->instance_cnt_dlsch_td1); - if (proc->instance_cnt_dlsch_td1 > 4) - exit_fun("instance_cnt_dlsch_td1 > 4"); - } + } + /* + if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { + printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td); + exit_fun( "error locking mutex_fep" ); + return -1; + } - AssertFatal(pthread_mutex_unlock(&proc->mutex_dlsch_td1) ==0,""); + if (proc->instance_cnt_td==0) { + printf("[UE] TD thread busy\n"); + exit_fun("TD thread busy"); + pthread_mutex_unlock( &proc->mutex_td ); + return -1; + } - } - /* - if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { - printf("[eNB] ERROR pthread_mutex_lock for TD thread (IC %d)\n", proc->instance_cnt_td); - exit_fun( "error locking mutex_fep" ); - return -1; - } + ++proc->instance_cnt_td; - if (proc->instance_cnt_td==0) { - printf("[UE] TD thread busy\n"); - exit_fun("TD thread busy"); - pthread_mutex_unlock( &proc->mutex_td ); - return -1; - } + proc->tdp.UE = phy_vars_ue; + proc->tdp.eNB_id = eNB_id; + proc->tdp.harq_pid = harq_pid; + proc->tdp.llr8_flag = llr8_flag; - ++proc->instance_cnt_td; - - proc->tdp.UE = phy_vars_ue; - proc->tdp.eNB_id = eNB_id; - proc->tdp.harq_pid = harq_pid; - proc->tdp.llr8_flag = llr8_flag; - - printf("----- 2thread llr flag %d tdp flag %d\n",llr8_flag, proc->tdp.llr8_flag); + printf("----- 2thread llr flag %d tdp flag %d\n",llr8_flag, proc->tdp.llr8_flag); - // wakeup worker to do second half segments - if (pthread_cond_signal(&proc->cond_td) != 0) { - printf("[UE] ERROR pthread_cond_signal for td thread exit\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return (1+dlsch->last_iteration_cnt); - } + // wakeup worker to do second half segments + if (pthread_cond_signal(&proc->cond_td) != 0) { + printf("[UE] ERROR pthread_cond_signal for td thread exit\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return (1+dlsch->last_iteration_cnt); + } - pthread_mutex_unlock( &proc->mutex_td );*/ + pthread_mutex_unlock( &proc->mutex_td );*/ - Cby2 = 1; //harq_process->C/2; - //proc->decoder_main_available = 1; - } - else { - Cby2 = 1; - } + Cby2 = 1; //harq_process->C/2; + //proc->decoder_main_available = 1; + } + else { + Cby2 = 1; + } - //for (r=0; rK; Kr_bytes = Kr>>3; @@ -1041,27 +1037,27 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment } //for (int i =0; i<16; i++) - // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); //r_offset += E; //printf("main thread r_offset %d\n",r_offset); #ifdef DEBUG_DLSCH_DECODING for (int i =0; i<16; i++) - printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); #endif #ifdef DEBUG_DLSCH_DECODING if (r==0) { - write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); + write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); + write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); } printf("decoder input(segment %d) :",r); for (int i=0;i<(3*8*Kr_bytes);i++) printf("%d : %d\n",i,harq_process->d[r][i]); - printf("\n"); + printf("\n"); #endif @@ -1082,98 +1078,94 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ - if (llr8_flag) { - AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", - Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - } + if (llr8_flag) { + AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", + Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); + } #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); #endif LOG_D(PHY,"mthread AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); - - for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ - inv_d[cnt] = (1)*harq_process->d[r][cnt]; - } - memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); - //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); - memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); + for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){ + inv_d[cnt] = (1)*harq_process->d[r][cnt]; + } + + memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); + //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); + memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); - for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) - { + for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + { + pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + } - pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + no_iteration_ldpc = nrLDPC_decoder(p_decParams, + (int8_t*)&pl[0], + llrProcBuf, + p_nrLDPC_procBuf, + p_procTime); - } + nb_total_decod++; + if (no_iteration_ldpc > 10){ + nb_error_decod++; + ret = 1+dlsch->max_ldpc_iterations; + } + else { + ret=2; + } - no_iteration_ldpc = nrLDPC_decoder(p_decParams, - (int8_t*)&pl[0], - llrProcBuf, - p_nrLDPC_procBuf, - p_procTime); + if (check_crc(llrProcBuf,harq_process->B,harq_process->F,crc_type)) { + printf("CRC OK\n"); + ret = 2; + } + else { + printf("CRC NOK\n"); + ret = 1+dlsch->max_ldpc_iterations; + } - nb_total_decod++; - if (no_iteration_ldpc > 10){ - nb_error_decod++; - ret = 1+dlsch->max_ldpc_iterations; - } - else { - ret=2; - } - - if (check_crc(llrProcBuf,harq_process->B,harq_process->F,crc_type)) { - printf("CRC OK\n"); - ret = 2; - } - else { - printf("CRC NOK\n"); - ret = 1+dlsch->max_ldpc_iterations; - } - - //if (!nb_total_decod%10000){ - printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); - //} + //if (!nb_total_decod%10000){ + printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); + //} - //else - //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); + //else + //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) - { - harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; - } + for (int m=0; m < Kr>>3; m ++) + { + harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; + } - /*for (int u=0; u < Kr>>3; u ++) - { - ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; - } + /*for (int u=0; u < Kr>>3; u ++) + { + ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; + } - printf("output unsigned ullrProcBuf \n"); + printf("output unsigned ullrProcBuf \n"); - for (int j=0; j < Kr>>3; j ++) - { + for (int j=0; j < Kr>>3; j ++) + { + printf(" %d \n", ullrProcBuf[j]); + } + printf(" \n");*/ + //printf("output channel decoder %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]); - printf(" %d \n", ullrProcBuf[j]); - - } - printf(" \n");*/ - //printf("output channel decoder %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]); - - //printf("output decoder %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]); + //printf("output decoder %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]); #ifdef DEBUG_DLSCH_DECODING - for (int k=0;k<32;k++) - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + for (int k=0;k<32;k++) + printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); #endif #if UE_TIMING_TRACE @@ -1252,40 +1244,40 @@ if (harq_process->C>1) { // wakeup worker if more than 1 segment */ uint32_t wait = 0; if (harq_process->C==2){ - while((proc->decoder_thread_available == 0) ) + while((proc->decoder_thread_available == 0) ) { usleep(1); wait++; } } else if ((harq_process->C==3) ){ - while((proc->decoder_thread_available == 0) || (proc->decoder_thread_available1 == 0)) - { - usleep(1); - wait++; - } + while((proc->decoder_thread_available == 0) || (proc->decoder_thread_available1 == 0)) + { + usleep(1); + wait++; + } } proc->decoder_main_available = 0; for (r=0; rC; r++) { - Kr = harq_process->K; //to check if same K in all segments - Kr_bytes = Kr>>3; + Kr = harq_process->K; //to check if same K in all segments + Kr_bytes = Kr>>3; - memcpy(harq_process->b+offset, - harq_process->c[r], - Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); - offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); + memcpy(harq_process->b+offset, + harq_process->c[r], + Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0)); + offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0)); #ifdef DEBUG_DLSCH_DECODING - printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); - printf("copied %d bytes to b sequence (harq_pid %d)\n", - (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); - printf("b[0] = %x,c[%d] = %x\n", - harq_process->b[offset], - harq_process->F>>3, - harq_process->c[r]); + printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes); + printf("copied %d bytes to b sequence (harq_pid %d)\n", + (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); + printf("b[0] = %x,c[%d] = %x\n", + harq_process->b[offset], + harq_process->F>>3, + harq_process->c[r]); #endif } @@ -1346,14 +1338,14 @@ void *nr_dlsch_decoding_2thread0(void *arg) char threadname[256]; sprintf(threadname,"UE_thread_dlsch_td_%d", proc->sub_frame_start); - cpu_set_t cpuset; + cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.dlsch_td_one != -1 ) - CPU_SET(threads.dlsch_td_one, &cpuset); + CPU_SET(threads.dlsch_td_one, &cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.dlsch_td_two != -1 ) - CPU_SET(threads.dlsch_td_two, &cpuset); + CPU_SET(threads.dlsch_td_two, &cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.dlsch_td_three != -1 ) - CPU_SET(threads.dlsch_td_three, &cpuset); + CPU_SET(threads.dlsch_td_three, &cpuset); @@ -1376,42 +1368,42 @@ void *nr_dlsch_decoding_2thread0(void *arg) init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, threadname); while (!oai_exit) { - //proc->decoder_thread_available = 1; - - if (pthread_mutex_lock(&proc->mutex_dlsch_td) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE dlsch td\n" ); - exit_fun("nothing to add"); - } - while (proc->instance_cnt_dlsch_td < 0) { - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_dlsch_td, &proc->mutex_dlsch_td ); - } - if (pthread_mutex_unlock(&proc->mutex_dlsch_td) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE dlsch_td \n" ); - exit_fun("nothing to add"); - } + //proc->decoder_thread_available = 1; + + if (pthread_mutex_lock(&proc->mutex_dlsch_td) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE dlsch td\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_dlsch_td < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_dlsch_td, &proc->mutex_dlsch_td ); + } + if (pthread_mutex_unlock(&proc->mutex_dlsch_td) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE dlsch_td \n" ); + exit_fun("nothing to add"); + } - uint32_t wait = 0; - while(proc->decoder_main_available == 0) - { - usleep(1); - wait++; - } + uint32_t wait = 0; + while(proc->decoder_main_available == 0) + { + usleep(1); + wait++; + } - //proc->decoder_thread_available = 0; - //PHY_VARS_NR_UE *phy_vars_ue = tdp->UE; - int eNB_id = proc->eNB_id; - int harq_pid = proc->harq_pid; - llr8_flag1 = proc->llr8_flag; - //r_offset = proc->Er; - //UE_rxtx_proc_t *proc = tdp->proc; - int frame = proc->frame_rx; - int subframe = proc->nr_tti_rx; - NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; - NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; - short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; - //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); - p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[1]; + //proc->decoder_thread_available = 0; + //PHY_VARS_NR_UE *phy_vars_ue = tdp->UE; + int eNB_id = proc->eNB_id; + int harq_pid = proc->harq_pid; + llr8_flag1 = proc->llr8_flag; + //r_offset = proc->Er; + //UE_rxtx_proc_t *proc = tdp->proc; + int frame = proc->frame_rx; + int subframe = proc->nr_tti_rx; + NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; + NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; + short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; + //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); + p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[1]; /* if (nb_rb > frame_parms->N_RB_DL) { @@ -1444,27 +1436,27 @@ void *nr_dlsch_decoding_2thread0(void *arg) harq_process->B = A+24; nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F); + p_decParams->Z = harq_process->Z; } kb = harq_process->K/harq_process->Z; - if ( kb==22){ - p_decParams->BG = 1; - p_decParams->R = 13; - kc = 68; - } - else{ - p_decParams->BG = 2; - p_decParams->R = 13; - kc = 52; - } + if ( kb==22){ + p_decParams->BG = 1; + p_decParams->R = 13; + kc = 68; + } + else{ + p_decParams->BG = 2; + p_decParams->R = 13; + kc = 52; + } p_decParams->numMaxIter = 2; Kr = p_decParams->Z*kb; @@ -1510,14 +1502,14 @@ void *nr_dlsch_decoding_2thread0(void *arg) Cprime = C; //assume CBGTI not present if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1) - r_offset = Nl*Qm*(G/(Nl*Qm*Cprime)); + r_offset = Nl*Qm*(G/(Nl*Qm*Cprime)); else - r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1); + r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1); - // printf("thread0 r_offset %d\n",r_offset); - + // printf("thread0 r_offset %d\n",r_offset); + //for (r=(harq_process->C/2); rC; r++) { - r=1; //(harq_process->C/2); + r=1; //(harq_process->C/2); Kr = harq_process->K; @@ -1537,7 +1529,7 @@ void *nr_dlsch_decoding_2thread0(void *arg) dlsch_llr+r_offset); //for (int i =0; i<16; i++) - // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -1582,7 +1574,7 @@ void *nr_dlsch_decoding_2thread0(void *arg) } //for (int i =0; i<16; i++) - // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); //r_offset += E; @@ -1616,10 +1608,10 @@ void *nr_dlsch_decoding_2thread0(void *arg) Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ - if (llr8_flag1) { - AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", - Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - } + if (llr8_flag1) { + AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", + Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); + } #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif @@ -1634,58 +1626,58 @@ void *nr_dlsch_decoding_2thread0(void *arg) memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) - { + for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + { - pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); - } + } - no_iteration_ldpc = nrLDPC_decoder(p_decParams, - (int8_t*)&pl[0], - llrProcBuf, + no_iteration_ldpc = nrLDPC_decoder(p_decParams, + (int8_t*)&pl[0], + llrProcBuf, p_nrLDPC_procBuf, - p_procTime); + p_procTime); - if (no_iteration_ldpc > 10) - printf("Error number of iteration LPDC %d\n", no_iteration_ldpc); - //else - //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); + if (no_iteration_ldpc > 10) + printf("Error number of iteration LPDC %d\n", no_iteration_ldpc); + //else + //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) - { - harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; - } + for (int m=0; m < Kr>>3; m ++) + { + harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; + } - /*for (int u=0; u < Kr>>3; u ++) - { - ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; - } + /*for (int u=0; u < Kr>>3; u ++) + { + ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; + } - printf("output unsigned ullrProcBuf \n"); + printf("output unsigned ullrProcBuf \n"); - for (int j=0; j < Kr>>3; j ++) - { + for (int j=0; j < Kr>>3; j ++) + { - printf(" %d \n", ullrProcBuf[j]); + printf(" %d \n", ullrProcBuf[j]); - } - printf(" \n");*/ -#ifdef DEBUG_DLSCH_DECODING - for (int k=0;k<2;k++) - printf("segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + } + printf(" \n");*/ +#ifdef DEBUG_DLSCH_DECODING + for (int k=0;k<2;k++) + printf("segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); #endif - + #if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); #endif @@ -1818,7 +1810,7 @@ void *nr_dlsch_decoding_2thread0(void *arg) #define FIFO_PRIORITY 39 void *nr_dlsch_decoding_2thread1(void *arg) { - static __thread int UE_dlsch_td_retval1; + static __thread int UE_dlsch_td_retval1; struct nr_rxtx_thread_data *rtd = arg; UE_nr_rxtx_proc_t *proc = rtd->proc; PHY_VARS_NR_UE *phy_vars_ue = rtd->UE; @@ -1860,14 +1852,14 @@ void *nr_dlsch_decoding_2thread1(void *arg) char threadname[256]; sprintf(threadname,"UE_thread_dlsch_td1_%d", proc->sub_frame_start); - cpu_set_t cpuset; + cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.dlsch_td_one != -1 ) - CPU_SET(threads.dlsch_td_one, &cpuset); + CPU_SET(threads.dlsch_td_one, &cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.dlsch_td_two != -1 ) - CPU_SET(threads.dlsch_td_two, &cpuset); + CPU_SET(threads.dlsch_td_two, &cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.dlsch_td_three != -1 ) - CPU_SET(threads.dlsch_td_three, &cpuset); + CPU_SET(threads.dlsch_td_three, &cpuset); @@ -1881,51 +1873,51 @@ void *nr_dlsch_decoding_2thread1(void *arg) uint32_t ret,offset; uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F; uint8_t crc_type; - uint8_t C,Cprime; + uint8_t C,Cprime; uint8_t Qm; - uint8_t Nl; + uint8_t Nl; //uint32_t Er; - init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, threadname); - printf("2thread1 oai_exit %d\n", oai_exit); - while (!oai_exit) { - if (pthread_mutex_lock(&proc->mutex_dlsch_td1) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE dlsch td\n" ); - exit_fun("nothing to add"); - } - while (proc->instance_cnt_dlsch_td1 < 0) { - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_dlsch_td1, &proc->mutex_dlsch_td1 ); - } - if (pthread_mutex_unlock(&proc->mutex_dlsch_td1) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE dlsch_td \n" ); - exit_fun("nothing to add"); - } + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, threadname); + printf("2thread1 oai_exit %d\n", oai_exit); + while (!oai_exit) { + if (pthread_mutex_lock(&proc->mutex_dlsch_td1) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE dlsch td\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_dlsch_td1 < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_dlsch_td1, &proc->mutex_dlsch_td1 ); + } + if (pthread_mutex_unlock(&proc->mutex_dlsch_td1) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE dlsch_td \n" ); + exit_fun("nothing to add"); + } - //printf("2thread1 main available %d\n", proc->decoder_main_available); + //printf("2thread1 main available %d\n", proc->decoder_main_available); - uint32_t wait = 0; - while(proc->decoder_main_available == 0) - { - usleep(1); - wait++; - } - - //proc->decoder_thread_available1 = 0; - //PHY_VARS_NR_UE *phy_vars_ue = tdp->UE; - int eNB_id = proc->eNB_id; - int harq_pid = proc->harq_pid; - llr8_flag1 = proc->llr8_flag; - //r_offset = proc->Er; - //UE_rxtx_proc_t *proc = tdp->proc; - int frame = proc->frame_rx; - int subframe = proc->nr_tti_rx; - NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; - NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; - short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; - //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); - //printf("2thread1 nr_tti_tx %d subframe %d SF thread id %d r_offset %d\n", proc->nr_tti_rx, subframe, phy_vars_ue->current_thread_id[subframe], r_offset); - p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[2]; + uint32_t wait = 0; + while(proc->decoder_main_available == 0) + { + usleep(1); + wait++; + } + + //proc->decoder_thread_available1 = 0; + //PHY_VARS_NR_UE *phy_vars_ue = tdp->UE; + int eNB_id = proc->eNB_id; + int harq_pid = proc->harq_pid; + llr8_flag1 = proc->llr8_flag; + //r_offset = proc->Er; + //UE_rxtx_proc_t *proc = tdp->proc; + int frame = proc->frame_rx; + int subframe = proc->nr_tti_rx; + NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]; + NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; + short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; + //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); + //printf("2thread1 nr_tti_tx %d subframe %d SF thread id %d r_offset %d\n", proc->nr_tti_rx, subframe, phy_vars_ue->current_thread_id[subframe], r_offset); + p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[2]; /* if (nb_rb > frame_parms->N_RB_DL) { @@ -1960,27 +1952,27 @@ void *nr_dlsch_decoding_2thread1(void *arg) // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; nr_segmentation(NULL, - NULL, - harq_process->B, - &harq_process->C, - &harq_process->K, - &harq_process->Z, - &harq_process->F); - p_decParams->Z = harq_process->Z; + NULL, + harq_process->B, + &harq_process->C, + &harq_process->K, + &harq_process->Z, + &harq_process->F); + p_decParams->Z = harq_process->Z; } kb = harq_process->K/harq_process->Z; - if ( kb==22){ - p_decParams->BG = 1; - p_decParams->R = 89; - kc = 68; - } - else{ - p_decParams->BG = 2; - p_decParams->R = 13; - kc = 52; - } + if ( kb==22){ + p_decParams->BG = 1; + p_decParams->R = 89; + kc = 68; + } + else{ + p_decParams->BG = 2; + p_decParams->R = 13; + kc = 52; + } p_decParams->numMaxIter = 2; Kr = p_decParams->Z*kb; @@ -2025,23 +2017,23 @@ void *nr_dlsch_decoding_2thread1(void *arg) Cprime = C; //assume CBGTI not present if (r <= Cprime - ((G/(Nl*Qm))%Cprime) - 1) - r_offset = Nl*Qm*(G/(Nl*Qm*Cprime)); + r_offset = Nl*Qm*(G/(Nl*Qm*Cprime)); else - r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1); + r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1); - //printf("sub thread r_offset %d\n", r_offset); + //printf("sub thread r_offset %d\n", r_offset); //for (r=(harq_process->C/2); rC; r++) { - r=2; //(harq_process->C/2); - r_offset = r*r_offset; - //printf("thread1 r=%d r_offset %d \n",r, r_offset); + r=2; //(harq_process->C/2); + r_offset = r*r_offset; + //printf("thread1 r=%d r_offset %d \n",r, r_offset); - Kr = harq_process->K; - Kr_bytes = Kr>>3; - K_bytes_F = Kr_bytes-(harq_process->F>>3); + Kr = harq_process->K; + Kr_bytes = Kr>>3; + K_bytes_F = Kr_bytes-(harq_process->F>>3); - Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); + Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); @@ -2059,7 +2051,7 @@ void *nr_dlsch_decoding_2thread1(void *arg) dlsch_llr+r_offset); //for (int i =0; i<16; i++) - // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); + // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -2082,15 +2074,15 @@ void *nr_dlsch_decoding_2thread1(void *arg) #endif if (nr_rate_matching_ldpc_rx(Ilbrm, - Tbslbrm, - p_decParams->BG, - p_decParams->Z, - harq_process->d[r], - harq_process->w[r], - harq_process->C, - harq_process->rvidx, - (harq_process->round==0)?1:0, - E)==-1) { + Tbslbrm, + p_decParams->BG, + p_decParams->Z, + harq_process->d[r], + harq_process->w[r], + harq_process->C, + harq_process->rvidx, + (harq_process->round==0)?1:0, + E)==-1) { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif @@ -2104,7 +2096,7 @@ void *nr_dlsch_decoding_2thread1(void *arg) } //for (int i =0; i<16; i++) - // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); + // printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset); //r_offset += E; @@ -2136,71 +2128,71 @@ void *nr_dlsch_decoding_2thread1(void *arg) Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations); */ - if (llr8_flag1) { - AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", - Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - } + if (llr8_flag1) { + AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", + Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); + } #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif // LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); - memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); + memset(pv,0,2*p_decParams->Z*sizeof(int16_t)); //memset(pl,0,2*p_decParams->Z*sizeof(int8_t)); - memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); + memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) - { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); - } + for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) + { + pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + } - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) - { + for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + { - pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); + pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); - } + } - no_iteration_ldpc = nrLDPC_decoder(p_decParams, - (int8_t*)&pl[0], - llrProcBuf, + no_iteration_ldpc = nrLDPC_decoder(p_decParams, + (int8_t*)&pl[0], + llrProcBuf, p_nrLDPC_procBuf, - p_procTime); + p_procTime); - if (no_iteration_ldpc > 10) - printf("Error number of iteration LPDC %d\n", no_iteration_ldpc); - //else - // printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); + if (no_iteration_ldpc > 10) + printf("Error number of iteration LPDC %d\n", no_iteration_ldpc); + //else + // printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) - { - harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; - } + for (int m=0; m < Kr>>3; m ++) + { + harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; + } - /*for (int u=0; u < Kr>>3; u ++) - { - ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; - } + /*for (int u=0; u < Kr>>3; u ++) + { + ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; + } - printf("output unsigned ullrProcBuf \n"); + printf("output unsigned ullrProcBuf \n"); - for (int j=0; j < Kr>>3; j ++) - { + for (int j=0; j < Kr>>3; j ++) + { - printf(" %d \n", ullrProcBuf[j]); + printf(" %d \n", ullrProcBuf[j]); - } - printf(" \n");*/ + } + printf(" \n");*/ #endif - //printf("output channel decoder %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]); + //printf("output channel decoder %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]); - //printf("output decoder %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]); + //printf("output decoder %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]); #if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); @@ -2239,7 +2231,7 @@ void *nr_dlsch_decoding_2thread1(void *arg) //printf("end 2thread1 proc->instance_cnt_dlsch_td1 %d\n", proc->instance_cnt_dlsch_td1); } - //printf("after 2thread1 after oai exit proc->instance_cnt_dlsch_td %d\n", proc->instance_cnt_dlsch_td1); + //printf("after 2thread1 after oai exit proc->instance_cnt_dlsch_td %d\n", proc->instance_cnt_dlsch_td1); // thread finished free(arg); return &UE_dlsch_td_retval1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 4e46903ebf..b4b7463e18 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -42,8 +42,6 @@ - - void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) { int i; @@ -88,6 +86,8 @@ void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch) } + + NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag) { diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 2b36a03e61..29c4fed74d 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -404,7 +404,7 @@ int main(int argc, char **argv) { r_im[i] = malloc(frame_length_complex_samples * sizeof(double)); bzero(r_im[i], frame_length_complex_samples * sizeof(double)); txdata[i] = malloc(frame_length_complex_samples * sizeof(int)); - bzero(r_re[i], frame_length_complex_samples * sizeof(int)); + bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata } if (pbch_file_fd != NULL) { @@ -480,7 +480,7 @@ int main(int argc, char **argv) { rel15->nb_layers = Nl; rel15->nb_re_dmrs = nb_re_dmrs; rel15->transport_block_size = TBS; - double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); + double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384); short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384); double errors_bit_uncoded = 0; From d7abeed6abbc61b63ba45dbbe7f49f825a51a7c2 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Wed, 6 Mar 2019 16:48:37 +0100 Subject: [PATCH 10/21] Applying LDPC code rate fix at nr_ulsch_encoding --- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index b4b7463e18..70a34f2c66 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -200,18 +200,19 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, NR_UL_UE_HARQ_t *harq_process; uint16_t nb_rb ; uint8_t nb_symb_sch ; - uint32_t A, Z; + uint32_t A, Z, F; uint32_t *pz; uint8_t mod_order; uint16_t Kr,r,r_offset,Kr_bytes; uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS]; - uint8_t kb,BG; + uint8_t BG; uint32_t E; uint8_t Ilbrm; uint32_t Tbslbrm; uint8_t nb_re_dmrs; uint16_t length_dmrs; int i; + float Coderate; /////////// /////////////////////////////////////////////////////////////////////////////////////// @@ -230,10 +231,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Kr=0; r_offset=0; BG = 1; + F=0; Ilbrm = 0; Tbslbrm = 950984; //max tbs nb_re_dmrs = ulsch->nb_re_dmrs; length_dmrs = 1; + Coderate = 0.0; /////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -251,7 +254,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl); - LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); + LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); printf("ulsch coding A %d G %d mod_order %d\n", A,G, mod_order); Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, harq_process->Nl); @@ -266,7 +269,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, /////////// /* int i; - printf("dlsch (tx): \n"); + printf("ulsch (tx): \n"); for (i=0;i<(A>>3);i++) printf("%02x.",a[i]); printf("\n"); @@ -297,13 +300,15 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, pz, &harq_process->F); - kb = harq_process->K/(*pz); - if ( kb==22){ - BG = 1; - } - else{ - BG = 2; - } + F = harq_process->F; + Coderate = (float) A /(float) G; + + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + BG = 2; + } + else{ + BG = 1; + } Kr = harq_process->K; Kr_bytes = Kr>>3; @@ -316,7 +321,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, ///////////////////////// c---->| LDCP coding |---->d ///////////////////////// /////////// - //printf("segment Z %d kb %d k %d Kr %d BG %d\n", *pz,kb,harq_process->K,Kr,BG); + //printf("segment Z %d k %d Kr %d BG %d\n", *pz,harq_process->K,Kr,BG); //start_meas(te_stats); for (r=0; rC; r++) { @@ -364,6 +369,15 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } for (r=0; rC; r++) { // looping over C segments + + if (harq_process->F>0) { + for (int k=(Kr-F-2*(*pz)); kd[r][k] = NR_NULL; + //if (k<(Kr-F+8)) + //printf("r %d filler bits [%d] = %d \n", r,k, harq_process->d[r][k]); + } + } + #ifdef DEBUG_DLSCH_CODING printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", r, From a1da7a2f9555965b7edf8bccd2422e4b1d73b384 Mon Sep 17 00:00:00 2001 From: Ahmed Hussein Date: Wed, 6 Mar 2019 18:32:20 +0100 Subject: [PATCH 11/21] Applying LDPC code fix at "nr_ulsch_decoding.c" (works for mcs 4 to 28) --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 72 +++++++++++++------ 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 1d72507de9..ace93e4ee3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -187,7 +187,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint32_t A,E; uint32_t G; uint32_t ret,offset; - int32_t no_iteration_ldpc; + int32_t no_iteration_ldpc, length_dec; uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; uint8_t crc_type; int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); @@ -206,12 +206,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, int16_t z [68*384]; int8_t l [68*384]; int16_t inv_d [68*384]; - uint8_t kb, kc; + uint8_t kc; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; //to update uint8_t nb_re_dmrs = 6; uint16_t length_dmrs = 1; + double Coderate = 0.0; uint32_t i,j; @@ -249,6 +250,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb); if (harq_process->round == 0) { + // This is a new packet, so compute quantities regarding segmentation harq_process->B = A+24; @@ -270,20 +272,43 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #endif } - kb = harq_process->K/harq_process->Z; + Coderate = (float) A /(float) G; - if ( kb==22) { - p_decParams->BG = 1; - p_decParams->R = 13; - kc = 68; - } else { + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ p_decParams->BG = 2; - p_decParams->R = 13; - kc = 52; + if (Coderate < 0.3333) { + p_decParams->R = 15; + kc = 52; + } + else if (Coderate <0.6667) { + p_decParams->R = 13; + kc = 32; + } + else { + p_decParams->R = 23; + kc = 17; + } + } else { + p_decParams->BG = 1; + if (Coderate < 0.6667) { + p_decParams->R = 13; + kc = 68; + } + else if (Coderate <0.8889) { + p_decParams->R = 23; + kc = 35; + } + else { + p_decParams->R = 89; + kc = 27; + } } + //printf("coderate %f kc %d \n", Coderate, kc); + + + p_decParams->numMaxIter = ulsch->max_ldpc_iterations; - Kr = p_decParams->Z*kb; p_decParams->outMode= 0; err_flag = 0; @@ -410,10 +435,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, memset(harq_process->c[r],0,Kr_bytes); // printf("done\n"); - if (harq_process->C == 1) + if (harq_process->C == 1) { crc_type = CRC24_A; - else + length_dec = harq_process->B; + } + else { crc_type = CRC24_B; + length_dec = (harq_process->B+24*harq_process->C)/harq_process->C; + } if (err_flag == 0) { @@ -421,19 +450,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, start_meas(ulsch_turbo_decoding_stats); #endif - for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++) { - inv_d[cnt] = (1)*harq_process->d[r][cnt]; - } + //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); + memset(pv,0,2*harq_process->Z*sizeof(int16_t)); memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t)); - for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F+((2*p_decParams->Z)>>3); i++, j++) { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) { + pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } - for (i=Kr_bytes+((2*p_decParams->Z)>>3),j=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) { - pv[i]= _mm_loadu_si128((__m128i*)(&inv_d[8*j])); + for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { + pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) { @@ -455,8 +483,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, p_nrLDPC_procBuf[r], p_procTime); - if (check_crc(llrProcBuf,harq_process->B,harq_process->F,crc_type)) { - printf("CRC OK\n"); + if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { + printf("Segment %d CRC OK\n",r); ret = 2; } else { printf("CRC NOK\n"); From af59ee996d742ce3bb50c982130374da210e6670 Mon Sep 17 00:00:00 2001 From: Khalid Ahmed Date: Wed, 13 Feb 2019 12:45:01 +0100 Subject: [PATCH 12/21] Add build directories to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1ed392ef06..61d9558916 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ cmake_targets/log/ cmake_targets/ran_build/ +cmake_targets/*/build/ targets/bin/ From 2d39da3b57fee88a477b1666c6fb2ed897316ad7 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 8 Mar 2019 17:12:23 +0100 Subject: [PATCH 13/21] inc no physim exectuables in CI script --- ci-scripts/oai-ci-vm-tool | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 940bcd2852..fd867b6661 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -252,7 +252,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=8 + NB_PATTERN_FILES=9 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=4096 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" @@ -331,7 +331,7 @@ case $key in VM_NAME=ci-phy-sim ARCHIVES_LOC=phy_sim LOG_PATTERN=.Rel15.txt - NB_PATTERN_FILES=8 + NB_PATTERN_FILES=9 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=4096 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" From afb40cf509507b96d7f245d2fe7ce91043e6b8c3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 18 Mar 2019 17:13:19 +0100 Subject: [PATCH 14/21] CI: trying to increase the RAM size on the phy-sim VM Signed-off-by: Raphael Defosseux --- ci-scripts/oai-ci-vm-tool | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index fd867b6661..1245d046ff 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -254,7 +254,7 @@ case $key in LOG_PATTERN=.Rel15.txt NB_PATTERN_FILES=9 BUILD_OPTIONS="--phy_simulators" - VM_MEMORY=4096 + VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" NBARGS=$[$NBARGS+256] shift @@ -333,7 +333,7 @@ case $key in LOG_PATTERN=.Rel15.txt NB_PATTERN_FILES=9 BUILD_OPTIONS="--phy_simulators" - VM_MEMORY=4096 + VM_MEMORY=8192 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" NBARGS=$[$NBARGS+256] ;; From d9c68d8b30aed4518be25a4bfcd1aa6c54a5dd4d Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 21 Mar 2019 14:15:26 +0100 Subject: [PATCH 15/21] new thread model --- cmake_targets/CMakeLists.txt | 7 +- common/utils/threadPool/Makefile | 8 + common/utils/threadPool/measurement_display.c | 61 ++ common/utils/threadPool/thread-pool.c | 219 +++++ common/utils/threadPool/thread-pool.h | 244 ++++++ common/utils/threadPool/thread-pool.md | 69 ++ executables/nr-ue.c | 803 +++++++++++++++++ executables/nr-uesoftmodem.c | 826 ++++++++++++++++++ executables/nr-uesoftmodem.h | 246 ++++++ .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 7 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 4 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 45 +- openair1/PHY/defs_nr_UE.h | 21 - openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 1 - openair1/SCHED_UE/phy_procedures_lte_ue.c | 6 +- openair2/LAYER2/NR_MAC_UE/mac.h | 8 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 8 +- targets/ARCH/COMMON/common_lib.h | 2 +- 21 files changed, 2502 insertions(+), 91 deletions(-) create mode 100644 common/utils/threadPool/Makefile create mode 100644 common/utils/threadPool/measurement_display.c create mode 100644 common/utils/threadPool/thread-pool.c create mode 100644 common/utils/threadPool/thread-pool.h create mode 100644 common/utils/threadPool/thread-pool.md create mode 100644 executables/nr-ue.c create mode 100644 executables/nr-uesoftmodem.c create mode 100644 executables/nr-uesoftmodem.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index af9c3edf68..3da38c4f5f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2425,11 +2425,10 @@ add_executable(nr-uesoftmodem ${rrc_h} ${s1ap_h} # ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/nr-ue.c - ${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${OPENAIR_DIR}/executables//nr-uesoftmodem.c + ${OPENAIR_DIR}/executables/nr-ue.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c -# ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile new file mode 100644 index 0000000000..6f0e884886 --- /dev/null +++ b/common/utils/threadPool/Makefile @@ -0,0 +1,8 @@ +all: measurement_display thread-pool-test + +measurement_display: measurement_display.c thread-pool.h + gcc measurement_display.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display + +thread-pool-test: thread-pool.c thread-pool.h + gcc -g thread-pool.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test + diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c new file mode 100644 index 0000000000..ac7beca1fe --- /dev/null +++ b/common/utils/threadPool/measurement_display.c @@ -0,0 +1,61 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#define __USE_GNU +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "thread-pool.h" + +#define SEP "\t" + +uint64_t cpuCyclesMicroSec; + +int main(int argc, char *argv[]) { + if(argc != 2) { + printf("Need one paramter: the trace Linux pipe (fifo)"); + exit(1); + } + + mkfifo(argv[1],0666); + int fd=open(argv[1], O_RDONLY); + + if ( fd == -1 ) { + perror("open read mode trace file:"); + exit(1); + } + + uint64_t deb=rdtsc(); + usleep(100000); + cpuCyclesMicroSec=(rdtsc()-deb)/100000; + printf("Cycles per µs: %lu\n",cpuCyclesMicroSec); + printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n"); + notifiedFIFO_elt_t doneRequest; + + while ( 1 ) { + if ( read(fd,&doneRequest, sizeof(doneRequest)) == sizeof(doneRequest)) { + printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n", + doneRequest.key, + (doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec, + (doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec, + (doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec + ); + } else { + printf("no measurements\n"); + sleep(1); + } + } +} diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c new file mode 100644 index 0000000000..ca050ea098 --- /dev/null +++ b/common/utils/threadPool/thread-pool.c @@ -0,0 +1,219 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +void displayList(notifiedFIFO_t *nf) { + int n=0; + notifiedFIFO_elt_t *ptr=nf->outF; + + while(ptr) { + printf("element: %d, key: %lu\n",++n,ptr->key); + ptr=ptr->next; + } + + printf("End of list: %d elements\n",n); +} + +static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) { + mutexlock(nf->lockF); + + while(!nf->outF) + condwait(nf->notifF, nf->lockF); + + notifiedFIFO_elt_t *ret=nf->outF; + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + // For abort feature + thr->runningOnKey=ret->key; + thr->abortFlag=false; + mutexunlock(nf->lockF); + return ret; +} + +void *one_thread(void *arg) { + struct one_thread *myThread=(struct one_thread *) arg; + struct thread_pool *tp=myThread->pool; + // configure the thread core assignment + // TBD: reserve the core for us exclusively + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(myThread->coreID, &cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + //Configure the thread scheduler policy for Linux + struct sched_param sparam= {0}; + sparam.sched_priority = sched_get_priority_max(SCHED_RR); + pthread_setschedparam(pthread_self(), SCHED_RR, &sparam); + // set the thread name for debugging + sprintf(myThread->name,"Tpool_%d",myThread->coreID); + pthread_setname_np(pthread_self(), myThread->name ); + + // Infinite loop to process requests + do { + notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread); + + if (tp->measurePerf) elt->startProcessingTime=rdtsc(); + + elt->processingFunc(NotifiedFifoData(elt)); + + if (tp->measurePerf) elt->endProcessingTime=rdtsc(); + + if (elt->reponseFifo) { + // Check if the job is still alive, else it has been aborted + mutexlock(tp->incomingFifo.lockF); + + if (myThread->abortFlag) + delNotifiedFIFO_elt(elt); + else + pushNotifiedFIFO(elt->reponseFifo, elt); + + mutexunlock(tp->incomingFifo.lockF); + } + } while (true); +} + +void initTpool(char *params,tpool_t *pool, bool performanceMeas) { + memset(pool,0,sizeof(*pool)); + char *measr=getenv("threadPoolMeasurements"); + pool->measurePerf=performanceMeas; + // force measurement if the output is defined + pool->measurePerf=measr!=NULL; + + if (measr) { + mkfifo(measr,0666); + AssertFatal(-1 != (pool->dummyTraceFd= + open(measr, O_RDONLY| O_NONBLOCK)),""); + AssertFatal(-1 != (pool->traceFd= + open(measr, O_WRONLY|O_APPEND|O_NOATIME|O_NONBLOCK)),""); + } else + pool->traceFd=-1; + + //Configure the thread scheduler policy for Linux + struct sched_param sparam= {0}; + sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1; + pthread_setschedparam(pthread_self(), SCHED_RR, &sparam); + pool->activated=true; + initNotifiedFIFO(&pool->incomingFifo); + char *saveptr, * curptr; + pool->nbThreads=0; + pool->restrictRNTI=false; + curptr=strtok_r(params,",",&saveptr); + + while ( curptr!=NULL ) { + if (curptr[0] == 'u' || curptr[0] == 'U') { + pool->restrictRNTI=true; + } else if ( curptr[0]>='0' && curptr[0]<='9' ) { + struct one_thread *tmp=pool->allthreads; + pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); + pool->allthreads->next=tmp; + printf("create a thread for core %d\n", atoi(curptr)); + pool->allthreads->coreID=atoi(curptr); + pool->allthreads->id=pool->nbThreads; + pool->allthreads->pool=pool; + pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads); + pool->nbThreads++; + } else if (curptr[0] == 'n' || curptr[0] == 'N') { + pool->activated=false; + } else + printf("Error in options for thread pool: %s\n",curptr); + + curptr=strtok_r(NULL,",",&saveptr); + } + + if (pool->activated && pool->nbThreads==0) { + printf("No servers created in the thread pool, exit\n"); + exit(1); + } +} + +#ifdef TEST_THREAD_POOL + +struct testData { + int id; + char txt[30]; +}; + +void processing(void *arg) { + struct testData *in=(struct testData *)arg; + printf("doing: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() ); + sprintf(in->txt,"Done by %ld, job %d", pthread_self(), in->id); + usleep(rand()%100); + printf("done: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() ); +} + +int main() { + notifiedFIFO_t myFifo; + initNotifiedFIFO(&myFifo); + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1234,NULL,NULL)); + + for(int i=10; i>1; i--) { + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1000+i,NULL,NULL)); + } + + displayList(&myFifo); + notifiedFIFO_elt_t *tmp=pullNotifiedFIFO(&myFifo); + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + tmp=pullNotifiedFIFO(&myFifo); + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + abortNotifiedFIFO(&myFifo,1005); + printf("aborted 1005\n"); + displayList(&myFifo); + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL)); + displayList(&myFifo); + abortNotifiedFIFO(&myFifo,12345678); + printf("aborted 12345678\n"); + displayList(&myFifo); + + do { + tmp=pollNotifiedFIFO(&myFifo); + + if (tmp) { + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + } else + printf("Empty list \n"); + } while(tmp); + + tpool_t pool; + char params[]="1,2,3,u"; + initTpool(params,&pool, true); + notifiedFIFO_t worker_back; + initNotifiedFIFO(&worker_back); + + for (int i=0; i <1000 ; i++) { + notifiedFIFO_elt_t *work=newNotifiedFIFO_elt(sizeof(struct testData), i, &worker_back, processing); + struct testData *x=(struct testData *)NotifiedFifoData(work); + x->id=i; + pushTpool(&pool, work); + } + + do { + tmp=pullTpool(&worker_back,&pool); + + if (tmp) { + struct testData *dd=NotifiedFifoData(tmp); + printf("Result: %s\n",dd->txt); + delNotifiedFIFO_elt(tmp); + } else + printf("Empty list \n"); + + abortTpool(&pool,510); + } while(tmp); + + return 0; +} +#endif diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h new file mode 100644 index 0000000000..6f34508c5a --- /dev/null +++ b/common/utils/threadPool/thread-pool.h @@ -0,0 +1,244 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#ifndef THREAD_POOL_H +#define THREAD_POOL_H +#include +#include +#include +#include +#include +#include + +#ifdef DEBUG + #define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +#else + #define THREADINIT PTHREAD_MUTEX_INITIALIZER +#endif +#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,""); +#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,""); +#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,""); +#define mutextrylock(mutex) pthread_mutex_trylock(&mutex) +#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,""); +#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,""); +#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); +#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); + +typedef struct notifiedFIFO_elt_s { + struct notifiedFIFO_elt_s *next; + uint64_t key; //To filter out elements + struct notifiedFIFO_s *reponseFifo; + void (*processingFunc)(void *); + bool malloced; + uint64_t creationTime; + uint64_t startProcessingTime; + uint64_t endProcessingTime; + uint64_t returnTime; + void *msgData; +} notifiedFIFO_elt_t; + +typedef struct notifiedFIFO_s { + notifiedFIFO_elt_t *outF; + notifiedFIFO_elt_t *inF; + pthread_mutex_t lockF; + pthread_cond_t notifF; +} notifiedFIFO_t; + +// You can use this allocator or use any piece of memory +static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, + uint64_t key, + notifiedFIFO_t *reponseFifo, + void (*processingFunc)(void *)) { + notifiedFIFO_elt_t *ret; + AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), ""); + ret->next=NULL; + ret->key=key; + ret->reponseFifo=reponseFifo; + ret->processingFunc=processingFunc; + // We set user data piece aligend 32 bytes to be able to process it with SIMD + ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32; + ret->malloced=true; + return ret; +} + +static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) { + return elt->msgData; +} + +static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) { + if (elt->malloced) { + elt->malloced=false; + free(elt); + } else + printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n"); + + //LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n"); +} + +static inline void initNotifiedFIFO(notifiedFIFO_t *nf) { + mutexinit(nf->lockF); + condinit (nf->notifF); + nf->inF=NULL; + nf->outF=NULL; + // No delete function: the creator has only to free the memory +} + +static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) { + mutexlock(nf->lockF); + msg->next=NULL; + + if (nf->outF == NULL) + nf->outF = msg; + + if (nf->inF) + nf->inF->next = msg; + + nf->inF = msg; + condbroadcast(nf->notifF); + mutexunlock(nf->lockF); +} + +static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) { + mutexlock(nf->lockF); + + while(!nf->outF) + condwait(nf->notifF, nf->lockF); + + notifiedFIFO_elt_t *ret=nf->outF; + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + mutexunlock(nf->lockF); + return ret; +} + +static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { + int tmp=mutextrylock(nf->lockF); + + if (tmp != 0 ) + return NULL; + + notifiedFIFO_elt_t *ret=nf->outF; + + if (ret!=NULL) + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + mutexunlock(nf->lockF); + return ret; +} + +// This function aborts all messages matching the key +// If the queue is used in thread pools, it doesn't cancels already running processing +// because the message has already been picked +static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { + mutexlock(nf->lockF); + notifiedFIFO_elt_t **start=&nf->outF; + + while(*start!=NULL) { + if ( (*start)->key == key ) { + notifiedFIFO_elt_t *request=*start; + *start=(*start)->next; + delNotifiedFIFO_elt(request); + } + + if (*start != NULL) + start=&(*start)->next; + } + + mutexunlock(nf->lockF); +} + +struct one_thread { + pthread_t threadID; + int id; + int coreID; + char name[256]; + uint64_t runningOnKey; + bool abortFlag; + struct thread_pool *pool; + struct one_thread *next; +}; + +typedef struct thread_pool { + int activated; + bool measurePerf; + int traceFd; + int dummyTraceFd; + uint64_t cpuCyclesMicroSec; + uint64_t startProcessingUE; + int nbThreads; + bool restrictRNTI; + notifiedFIFO_t incomingFifo; + struct one_thread *allthreads; +} tpool_t; + +static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { + if (t->measurePerf) msg->creationTime=rdtsc(); + + pushNotifiedFIFO(&t->incomingFifo, msg); +} + +static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { + notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo); + + if (t->measurePerf) + msg->returnTime=rdtsc(); + + if (t->traceFd) + if(write(t->traceFd, msg, sizeof(*msg))); + + return msg; +} + +static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { + notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo); + + if (msg == NULL) + return NULL; + + if (t->measurePerf) + msg->returnTime=rdtsc(); + + if (t->traceFd) + if(write(t->traceFd, msg, sizeof(*msg))); + + return msg; +} + +static inline void abortTpool(tpool_t *t, uint64_t key) { + notifiedFIFO_t *nf=&t->incomingFifo; + mutexlock(nf->lockF); + notifiedFIFO_elt_t **start=&nf->outF; + + while(*start!=NULL) { + if ( (*start)->key == key ) { + notifiedFIFO_elt_t *request=*start; + *start=(*start)->next; + delNotifiedFIFO_elt(request); + } + + if (*start != NULL) + start=&(*start)->next; + } + + struct one_thread *ptr=t->allthreads; + + while(ptr!=NULL) { + if (ptr->runningOnKey==key) + ptr->abortFlag=true; + + ptr=ptr->next; + } + + mutexunlock(nf->lockF); +} +void initTpool(char *params,tpool_t *pool, bool performanceMeas); + +#endif diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md new file mode 100644 index 0000000000..92cc21b975 --- /dev/null +++ b/common/utils/threadPool/thread-pool.md @@ -0,0 +1,69 @@ +# Thread pool + +The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. + +Each worker loop on pick from the same input queue jobs to do. +When a job is done, the worker sends a return if a return is defined. + +A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). + +All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. + +## license +Author: Laurent Thomas, Open cells project +The owner share the code usage to Openairsoftware alliance as per OSA license terms + +# jobs + +A job is a message (notifiedFIFO_elt_t): +next: internal FIFO chain, do not set it +key: a long int that the client can use to identify a message or a group of messages +responseFifo: if the client defines a response FIFO, the message will be posted back after processing +processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch +msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing +malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature + +The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. + +# Queues of jobs + +Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() +No delete function is required, the creator has only to free the data of type notifiedFIFO_t + +push_notifiedFIFO() add a job in the queue +pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking + +abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) + +# Thread pools + +## initialization +The clients can create one or more thread pools with init_tpool() +the params string structure: describes a list of cores, separated by "," that run a worker thread + +The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" + +## adding jobs +The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) + +If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. + +## abort + +A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. + +Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + +## Performance measurements + +A performance measurement is integrated: the pool will automacillay fill timestamps: + +* creationTime: time the request is push to the pool; +* startProcessingTime: time a worker start to run on the job +* endProcessingTime: time the worker finished the job +* returnTime: time the client reads the result + +if you set the environement variable: thread-pool-measurements to a valid file name +These measurements will be wrote to this Linux pipe. + +A tool to read the linux fifo and display it in ascii will be provided (TBD) diff --git a/executables/nr-ue.c b/executables/nr-ue.c new file mode 100644 index 0000000000..d45ee37d19 --- /dev/null +++ b/executables/nr-ue.c @@ -0,0 +1,803 @@ +/* + * 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.0 (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 lte-ue.c + * \brief threads and support functions for real-time LTE UE target + * \author R. Knopp, F. Kaltenberger, Navid Nikaein + * \date 2015 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr + * \note + * \warning + */ +#include "executables/nr-uesoftmodem.h" + +#include "LAYER2/NR_MAC_UE/mac.h" +//#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface_extern.h" + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "fapi_nr_ue_l1.h" +#include "PHY/phy_extern_nr_ue.h" +#include "PHY/INIT/phy_init.h" +#include "PHY/MODULATION/modulation_UE.h" +#include "LAYER2/NR_MAC_UE/mac_proto.h" +#include "RRC/NR_UE/rrc_proto.h" + +//#ifndef NO_RAT_NR +#include "SCHED_NR/phy_frame_config_nr.h" +//#endif +#include "SCHED_NR_UE/defs.h" + +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "T.h" + +#ifdef XFORMS + #include "PHY/TOOLS/nr_phy_scope.h" + + extern char do_forms; +#endif + + +extern double cpuf; +//static nfapi_nr_config_request_t config_t; +//static nfapi_nr_config_request_t* config =&config_t; + +/* + * NR SLOT PROCESSING SEQUENCE + * + * Processing occurs with following steps for connected mode: + * + * - Rx samples for a slot are received, + * - PDCCH processing (including DCI extraction for downlink and uplink), + * - PDSCH processing (including transport blocks decoding), + * - PUCCH/PUSCH (transmission of acknowledgements, CSI, ... or data). + * + * Time between reception of the slot and related transmission depends on UE processing performance. + * It is defined by the value NR_UE_CAPABILITY_SLOT_RX_TO_TX. + * + * In NR, network gives the duration between Rx slot and Tx slot in the DCI: + * - for reception of a PDSCH and its associated acknowledgment slot (with a PUCCH or a PUSCH), + * - for reception of an uplink grant and its associated PUSCH slot. + * + * So duration between reception and it associated transmission depends on its transmission slot given in the DCI. + * NR_UE_CAPABILITY_SLOT_RX_TO_TX means the minimum duration but higher duration can be given by the network because UE can support it. + * + * Slot k + * -------+------------+-------- + * Frame | Tx samples | + * Subframe | buffer | + * Slot n -------+------------+-------- + * ------ +------------+-------- | + * | Rx samples | | + * | buffer | | + * -------+------------+-------- | + * | | + * V | + * +------------+ | + * | PDCCH | | + * | processing | | + * +------------+ | + * | | | + * | v | + * | +------------+ | + * | | PDSCH | | + * | | processing | decoding result | + * | +------------+ -> ACK/NACK of PDSCH | + * | | | + * | v | + * | +-------------+------------+ | + * | | PUCCH/PUSCH | Tx samples | | + * | | processing | transfer | | + * | +-------------+------------+ | + * | | + * |/___________________________________________________________\| + * \ duration between reception and associated transmission / + * + * Remark: processing is done slot by slot, it can be distribute on different threads which are executed in parallel. + * This is an architecture optimization in order to cope with real time constraints. + * By example, for LTE, subframe processing is spread over 4 different threads. + * + */ + +#ifndef NO_RAT_NR + #define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX) /* for NR this will certainly depends to such UE capability which is not yet defined */ +#else + #define DURATION_RX_TO_TX (4) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */ +#endif + +#define FRAME_PERIOD 100000000ULL +#define DAQ_PERIOD 66667ULL +#define FIFO_PRIORITY 40 + +typedef enum { + pss=0, + pbch=1, + si=2 +} sync_mode_t; + + +int32_t **rxdata; +int32_t **txdata; + +#define KHz (1000UL) +#define MHz (1000*KHz) +typedef struct eutra_band_s { + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; +} eutra_band_t; + +typedef struct band_info_s { + int nbands; + eutra_band_t band_info[100]; +} band_info_t; + +band_info_t bands_to_scan; + +static const eutra_band_t eutra_bands[] = { + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, +}; + +PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag) + +{ + PHY_VARS_NR_UE *ue; + + if (frame_parms!=(NR_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in + ue = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); + memset(ue,0,sizeof(PHY_VARS_NR_UE)); + memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); + } else ue = PHY_vars_UE_g[UE_id][0]; + + ue->Mod_id = UE_id; + ue->mac_enabled = 1; + // initialize all signal buffers + init_nr_ue_signal(ue,1,abstraction_flag); + // intialize transport + init_nr_ue_transport(ue,abstraction_flag); + return(ue); +} + +/*! + * It performs band scanning and synchonization. + * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure. + */ + +typedef struct syncData_s { + PHY_VARS_NR_UE *UE; +} syncData_t; + +static void UE_synch(void *arg) { + syncData_t *syncD=(syncData_t *) arg; + int i, hw_slot_offset; + PHY_VARS_NR_UE *UE = syncD->UE; + int current_band = 0; + int current_offset = 0; + sync_mode_t sync_mode = pbch; + int CC_id = UE->CC_id; + int freq_offset=0; + UE->is_synchronized = 0; + + if (UE->UE_scan == 0) { + int ind; + + for ( ind=0; ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); + ind++) { + current_band = eutra_bands[ind].band; + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + + if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + + break; + } + } + + AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", + downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], + oai_exit, openair0_cfg[0].rx_num_channels); + + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + + if (uplink_frequency_offset[CC_id][i] != 0) // + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + else //FDD + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + } + + sync_mode = pbch; + } else { + current_band=0; + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + } + } + + LOG_W(PHY, "Starting sync detection\n"); + + switch (sync_mode) { + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + //lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz + + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } + + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } + + break; + + case pbch: + LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + + if (nr_initial_sync( UE, UE->mode ) == 0) { + freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_slot; + LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + hw_slot_offset, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + // rerun with new cell parameters and frequency-offset + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (freq_offset >= 0) + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset); + else + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset); + + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + } + + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } + + if (UE->mode != loop_through_memory) { + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + //UE->rfdevice.trx_stop_func(&UE->rfdevice); + // sleep(1); + //nr_init_frame_parms_ue(&UE->frame_parms); + /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + }*/ + } + + if (UE->UE_scan_carrier == 1) { + UE->UE_scan_carrier = 0; + } else { + UE->is_synchronized = 1; + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + freq_offset += 100; + + freq_offset *= -1; + LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier==1) + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + + if (UE->mode != loop_through_memory) + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + }// initial_sync=0 + + break; + + case si: + default: + break; + } + } +} + +void processSubframeRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { + // Process Rx data for one sub-frame + if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_DOWNLINK_SLOT) { + //clean previous FAPI MESSAGE + UE->rx_ind.number_pdus = 0; + UE->dci_ind.number_of_dcis = 0; + //clean previous FAPI MESSAGE + // call L2 for DL_CONFIG (DCI) + UE->dcireq.module_id = UE->Mod_id; + UE->dcireq.gNB_index = 0; + UE->dcireq.cc_id = 0; + UE->dcireq.frame = proc->frame_rx; + UE->dcireq.slot = proc->nr_tti_rx; + nr_ue_dcireq(&UE->dcireq); //to be replaced with function pointer later + NR_UE_MAC_INST_t *UE_mac = get_mac_inst(0); + UE_mac->scheduled_response.dl_config = &UE->dcireq.dl_config_req; + UE_mac->scheduled_response.slot = proc->nr_tti_rx; + nr_ue_scheduled_response(&UE_mac->scheduled_response); + //write_output("uerxdata_frame.m", "uerxdata_frame", UE->common_vars.rxdata[0], UE->frame_parms.samples_per_frame, 1, 1); + printf("Processing slot %d\n",proc->nr_tti_rx); +#ifdef UE_SLOT_PARALLELISATION + phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); +#else + phy_procedures_nrUE_RX( UE, proc, 0, 1, UE->mode); + // printf(">>> nr_ue_pdcch_procedures ended\n"); +#endif + } + + if (UE->mac_enabled==1) { + // trigger L2 to run ue_scheduler thru IF module + // [TODO] mapping right after NR initial sync + if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { + UE->ul_indication.module_id = 0; + UE->ul_indication.gNB_index = 0; + UE->ul_indication.cc_id = 0; + UE->ul_indication.frame = proc->frame_rx; + UE->ul_indication.slot = proc->nr_tti_rx; + UE->if_inst->ul_indication(&UE->ul_indication); + } + } +} + +/*! + * \brief This is the UE thread for RX subframe n and TX subframe n+4. + * This thread performs the phy_procedures_UE_RX() on every received slot. + * then, if TX is enabled it performs TX for n+4. + * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + +typedef struct processingData_s { + UE_nr_rxtx_proc_t proc; + PHY_VARS_NR_UE *UE; +} processingData_t; + +void UE_processing(void *arg) { + processingData_t *rxtxD=(processingData_t *) arg; + UE_nr_rxtx_proc_t *proc = &rxtxD->proc; + PHY_VARS_NR_UE *UE = rxtxD->UE; + processSubframeRX(UE, proc); + //printf(">>> mac ended\n"); + // Prepare the future Tx data +#if 0 +#ifndef NO_RAT_NR + + if (slot_select_nr(&UE->frame_parms, proc->frame_tx, proc->nr_tti_tx) & NR_UPLINK_SLOT) +#else + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) +#endif + if (UE->mode != loop_through_memory) + phy_procedures_nrUE_TX(UE,proc,0,0,UE->mode,no_relay); + + //phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); +#endif +#if 0 + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && + (UE->frame_parms.frame_type == TDD)) + if (UE->mode != loop_through_memory) + //phy_procedures_UE_S_TX(UE,0,0,no_relay); + updateTimes(current, &t3, 10000, timing_proc_name); + +#endif +} + +void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { + void *rxp[NB_ANTENNAS_RX]; + void *dummy_tx[UE->frame_parms.nb_antennas_tx]; + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); + + for(int x=0; x<10; x++) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = ((void *)&UE->common_vars.rxdata[i][0]) + 4*x*UE->frame_parms.samples_per_subframe; + + AssertFatal( UE->frame_parms.samples_per_subframe == + UE->rfdevice.trx_read_func(&UE->rfdevice, + timestamp, + rxp, + UE->frame_parms.samples_per_subframe, + UE->frame_parms.nb_antennas_rx), ""); + } + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + free(dummy_tx[i]); +} + +void trashFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { + void *dummy_tx[UE->frame_parms.nb_antennas_tx]; + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); + + void *dummy_rx[UE->frame_parms.nb_antennas_rx]; + + for (int i=0; iframe_parms.nb_antennas_rx; i++) + dummy_rx[i]=malloc16(UE->frame_parms.samples_per_subframe*4); + + for (int sf=0; sfrfdevice.trx_read_func(&UE->rfdevice, + timestamp, + dummy_rx, + UE->frame_parms.samples_per_subframe, + UE->frame_parms.nb_antennas_rx); + } + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + free(dummy_tx[i]); + + for (int i=0; iframe_parms.nb_antennas_rx; i++) + free(dummy_rx[i]); +} + +void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + void *dummy_tx[UE->frame_parms.nb_antennas_tx]; + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + dummy_tx[i]=malloc16_clear(UE->frame_parms.samples_per_subframe*4); + + for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) { + int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ; + AssertFatal(unitTransfer == + UE->rfdevice.trx_read_func(&UE->rfdevice, + timestamp, + (void **)UE->common_vars.rxdata, + unitTransfer, + UE->frame_parms.nb_antennas_rx),""); + } + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + free(dummy_tx[i]); + } +} + +int computeSamplesShift(PHY_VARS_NR_UE *UE) { + if ( getenv("RFSIMULATOR") != 0) { + LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset); + //UE->rx_offset_diff=0; + return 0; + } + + // compute TO compensation that should be applied for this frame + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_slot && + UE->rx_offset > 0 ) + return -1 ; + + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_slot && + UE->rx_offset < 10*UE->frame_parms.samples_per_slot ) + return 1; + + return 0; +} + +void *UE_thread(void *arg) { + PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; + // int tx_enabled = 0; + openair0_timestamp timestamp; + void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + int start_rx_stream = 0; + const uint16_t table_sf_slot[20] = {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9}; + AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); + UE->rfdevice.host_type = RAU_HOST; + AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); + notifiedFIFO_t nf; + initNotifiedFIFO(&nf); + bool syncRunning=false; + notifiedFIFO_elt_t *syncMsg=newNotifiedFIFO_elt(sizeof(syncData_t),0,&nf,UE_synch); + syncData_t *syncD=(syncData_t *)NotifiedFifoData(syncMsg); + syncD->UE=UE; + int nbSlotProcessing=0; + int thread_idx=0; + notifiedFIFO_elt_t *processingMsg[RX_NB_TH]; + + for (int i=0; iUE=UE; + } + + const int nb_slot_frame = 10*UE->frame_parms.slots_per_subframe; + int absolute_slot=-1; + + while (!oai_exit) { + if (!syncD->UE->is_synchronized) { + if (syncRunning) { + notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool); + + if (res) { + syncRunning=false; + } else + trashFrame(UE, ×tamp); + } else { + readFrame(UE, ×tamp); + pushTpool(Tpool, syncMsg); + syncRunning=true; + } + + continue; + } + + if (start_rx_stream==0) { + start_rx_stream=1; + syncInFrame(UE, ×tamp); + UE->rx_offset=0; + UE->time_sync_cell=0; + //printf("first stream frame rx %d\n",UE->proc.proc_rxtx[0].frame_rx); + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + continue; + } + + absolute_slot++; + thread_idx = absolute_slot % RX_NB_TH; + int slot_nr=absolute_slot % nb_slot_frame; + UE_nr_rxtx_proc_t *proc=&(((processingData_t *)NotifiedFifoData(processingMsg[thread_idx]))->proc); + // update thread index for received subframe + proc->nr_tti_rx= slot_nr; + UE->current_thread_id[slot_nr] = thread_idx; + proc->subframe_rx=table_sf_slot[slot_nr]; + proc->nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; + proc->subframe_tx=proc->nr_tti_rx; + proc->frame_rx = ( absolute_slot/nb_slot_frame ) % MAX_FRAME_NUMBER; + proc->frame_tx = ( (absolute_slot + DURATION_RX_TO_TX) /nb_slot_frame ) % MAX_FRAME_NUMBER; + LOG_D(PHY,"Process slot %d thread Idx %d \n", slot_nr, thread_idx); + + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + slot_nr*UE->frame_parms.samples_per_slot]; + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + txp[i] = (void *)&UE->common_vars.txdata[i][proc->nr_tti_tx*UE->frame_parms.samples_per_slot]; + + int readBlockSize, writeBlockSize; + + if (slot_nr<(nb_slot_frame - 1)) { + readBlockSize=UE->frame_parms.samples_per_slot; + writeBlockSize=UE->frame_parms.samples_per_slot; + } else { + UE->rx_offset_diff = computeSamplesShift(UE); + readBlockSize=UE->frame_parms.samples_per_slot - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_slot - + UE->rx_offset_diff; + } + + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_slot) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + + if( slot_nr==(nb_slot_frame-1)) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + else + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + + proc->timestamp_tx = timestamp+ + (DURATION_RX_TO_TX*UE->frame_parms.samples_per_slot)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + + if (getenv("RFSIMULATOR")) { + // FixMe: Wait previous thread is done, because race conditions seems too bad + // in case of actual RF board, the overlap between threads mitigate the issue + while (!tryPullTpool(&nf, Tpool)) { + nbSlotProcessing--; + usleep(200); + } + } + + while (nbSlotProcessing >= RX_NB_TH && !tryPullTpool(&nf, Tpool)) { + nbSlotProcessing--; + usleep(200); + } + + pushTpool(Tpool, processingMsg[thread_idx]); + } // while !oai_exit + + return NULL; +} + +void init_UE(int nb_inst) { + int inst; + NR_UE_MAC_INST_t *mac_inst; + pthread_t threads[nb_inst]; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + struct sched_param sched; + sched.sched_priority = sched_get_priority_max(SCHED_RR)-1; + pthread_attr_setschedparam(&attr, &sched); + + for (inst=0; inst < nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; + //PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; + LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); + PHY_vars_UE_g[inst][0] = init_nr_ue_vars(NULL,inst,0); + PHY_VARS_NR_UE *UE = PHY_vars_UE_g[inst][0]; + AssertFatal((UE->if_inst = nr_ue_if_module_init(inst)) != NULL, "can not initial IF module\n"); + nr_l3_init_ue(); + nr_l2_init_ue(); + mac_inst = get_mac_inst(0); + mac_inst->if_module = UE->if_inst; + UE->if_inst->scheduled_response = nr_ue_scheduled_response; + UE->if_inst->phy_config_request = nr_ue_phy_config_request; + LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); + //init_UE_threads(inst); + //UE = PHY_vars_UE_g[inst][0]; + AssertFatal(0 == pthread_create(&threads[inst], + &attr, + UE_thread, + (void *)UE), ""); + } + + printf("UE threads created by %ld\n", gettid()); +} + diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c new file mode 100644 index 0000000000..5384e0835d --- /dev/null +++ b/executables/nr-uesoftmodem.c @@ -0,0 +1,826 @@ +/* + * 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 + */ + + +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include + +#include "T.h" +#include "assertions.h" +#include "PHY/types.h" +#include "PHY/defs_nr_UE.h" +#include "common/ran_context.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "../../ARCH/COMMON/common_lib.h" +#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" + +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "PHY/phy_vars_nr_ue.h" +#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "SCHED/sched_common_vars.h" +#include "PHY/MODULATION/modulation_vars.h" +//#include "../../SIMU/USER/init_lte.h" + +#include "LAYER2/MAC/mac_vars.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_vars.h" +#include "PHY_INTERFACE/phy_interface_vars.h" + +#ifdef SMBV +#include "PHY/TOOLS/smbv.h" +unsigned short config_frames[4] = {2,9,11,13}; +#endif +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +//#include "PHY/TOOLS/time_meas.h" + +#ifndef OPENAIR2 + #include "UTIL/OTG/otg_vars.h" +#endif + +#include "intertask_interface.h" +#include "create_tasks.h" + +#include "PHY/INIT/phy_init.h" +#include "system.h" +#include +#include +#include +#include +#include + +#ifdef XFORMS +#include + +/* Callbacks, globals and object handlers */ + +extern void reset_stats( FL_OBJECT *, long ); + +/* Forms and Objects */ + +typedef struct { + FL_FORM *stats_form; + void *vdata; + char *cdata; + long ldata; + FL_OBJECT *stats_text; + FL_OBJECT *stats_button; +} FD_stats_form; + +extern FD_stats_form *create_form_stats_form( void ); + +#include "PHY/TOOLS/nr_phy_scope.h" +//#include "stats.h" +// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) +// at eNB 0, an UL scope for every UE +FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; +//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; +char title[255]; +//unsigned char scope_enb_num_ue = 2; +static pthread_t forms_thread; //xforms +#endif //XFORMS +#include + +RAN_CONTEXT_t RC; +volatile int start_eNB = 0; +volatile int start_UE = 0; +volatile int oai_exit = 0; + +static clock_source_t clock_source = internal; +int single_thread_flag=1; + +int threequarter_fs=0; + +uint32_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +extern int16_t nr_dlsch_demod_shift; + +int UE_scan = 0; +int UE_scan_carrier = 0; +int UE_fo_compensation = 0; +runmode_t mode = normal_txrx; +openair0_config_t openair0_cfg[MAX_CARDS]; + +#if MAX_NUM_CCs == 1 +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}}; +#else +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; +#endif + +double rx_gain_off = 0.0; + +double sample_rate=30.72e6; +double bw = 10.0e6; + +static int tx_max_power[MAX_NUM_CCs] = {0}; + +char rf_config_file[1024]; + +int chain_offset=0; +int phy_test = 0; +uint8_t usim_test = 0; + +uint8_t dci_Format = 0; +uint8_t agregation_Level =0xFF; + +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; + +char ref[128] = "internal"; +char channels[128] = "0"; + +char *parallel_config = NULL; +char *worker_config = NULL; + +static THREAD_STRUCT thread_struct; +void set_parallel_conf(char *parallel_conf) { + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + + printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) { + if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; + + printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) { + return thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) { + return thread_struct.worker_conf; +} +int rx_input_level_dBm; + +//static int online_log_messages=0; + +#ifdef XFORMS + extern int otg_enabled; + int do_forms=0; +#else + int otg_enabled; +#endif +//int number_of_cards = 1; + +static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; +static nfapi_nr_config_request_t *config[MAX_NUM_CCs]; +int16_t node_synch_ref[MAX_NUM_CCs]; + +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +uint32_t timing_advance = 0; +uint8_t exit_missed_slots=1; +uint64_t num_missed_slots=0; // counter for the number of missed slots + + +int transmission_mode=1; +int numerology = 0; + +/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */ +//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD; +/* struct for ethernet specific parameters given in eNB conf file */ +//eth_params_t *eth_params; + +double cpuf; + +char uecap_xer[1024],uecap_xer_in=0; + +int oaisim_flag=0; +int emulate_rf = 0; + +tpool_t *Tpool; + +char *usrp_args=NULL; +char *usrp_clksrc=NULL; + +/* forward declarations */ +void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); + + +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + +/*---------------------BMC: timespec helpers -----------------------------*/ + +struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; +struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + +struct timespec clock_difftime(struct timespec start, struct timespec end) { + struct timespec temp; + + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + + return temp; +} + +void print_difftimes(void) { + LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); +} + +void exit_function(const char *file, const char *function, const int line, const char *s) { + int CC_id; + + if (s != NULL) { + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); + } + + oai_exit = 1; + + if (PHY_vars_UE_g && PHY_vars_UE_g[0]) { + for(CC_id=0; CC_idrfdevice.trx_end_func) + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } + } + + sleep(1); //allow lte-softmodem threads to exit first + itti_terminate_tasks (TASK_UNKNOWN); +} + +#ifdef XFORMS + + +void reset_stats(FL_OBJECT *button, long arg) { + //int i,j,k; + /*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0]; + + for (i=0; idlsch[i][0]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; + } + + phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; + + for (j=0; julsch[i]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0; + phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0; + } + } + + phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; + phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; + phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; + }*/ +} + +static void *scope_thread(void *arg) { + struct sched_param sched_param; + sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; + sched_setscheduler(0, SCHED_FIFO,&sched_param); + printf("Scope thread has priority %d\n",sched_param.sched_priority); + //wait the modem is runnign + sleep(5); + + while (!oai_exit) { + phy_scope_UE(form_ue[0], + PHY_vars_UE_g[0][0], + 0,0,1); + usleep(100*1000); + } + + pthread_exit((void *)arg); +} +#endif + +void init_scope(void) { +#ifdef XFORMS + int ret; + int fl_argc=1; + + if (do_forms==1) { + char *name="5G-UE-scope"; + fl_initialize (&fl_argc, &name, NULL, 0, 0); + int UE_id = 0; + form_ue[UE_id] = create_lte_phy_scope_ue(); + sprintf (title, "NR DL SCOPE UE"); + fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); + + printf("Scope thread created, ret=%d\n",ret); + } + +#endif +} + + +#if defined(ENABLE_ITTI) +void *l2l1_task(void *arg) { + MessageDef *message_p = NULL; + int result; + itti_set_task_real_time(TASK_L2L1); + itti_mark_task_ready(TASK_L2L1); + + do { + // Wait for a message + itti_receive_msg (TASK_L2L1, &message_p); + + switch (ITTI_MSG_ID(message_p)) { + case TERMINATE_MESSAGE: + oai_exit=1; + itti_exit_task (); + break; + + case ACTIVATE_MESSAGE: + start_UE = 1; + break; + + case DEACTIVATE_MESSAGE: + start_UE = 0; + break; + + case MESSAGE_TEST: + LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while(!oai_exit); + + return NULL; +} +#endif + +int16_t dlsch_demod_shift; + +static void get_options(void) { + int CC_id; + int tddflag=0, nonbiotflag; + char *loopfile=NULL; + int dumpframe=0; + uint32_t online_log_messages; + uint32_t glog_level, glog_verbosity; + uint32_t start_telnetsrv=0; + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if (strlen(in_path) > 0) { + opt_type = OPT_PCAP; + opt_enabled=1; + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + + if (strlen(in_ip) > 0) { + opt_enabled=1; + opt_type = OPT_WIRESHARK; + printf("Enabling OPT for wireshark for local interface"); + } + + config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); + + if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + set_glog_onlinelog(online_log_messages); + } + + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + set_glog(glog_level); + } + + if (start_telnetsrv) { + load_module_shlib("telnetsrv",NULL,0,NULL); + } + + paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; + paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; + config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); + config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; + + if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; + + if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; + + if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; + + if (dumpframe > 0) mode = rx_dump_frame; + + for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; + } + + UE_scan=0; + + if (tddflag > 0) { + for (CC_id=0; CC_idframe_type = TDD; + } + + /*if (frame_parms[0]->N_RB_DL !=0) { + if ( frame_parms[0]->N_RB_DL < 6 ) { + frame_parms[0]->N_RB_DL = 6; + printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 100 ) { + frame_parms[0]->N_RB_DL = 100; + printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { + frame_parms[0]->N_RB_DL = 50; + printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { + frame_parms[0]->N_RB_DL = 25; + printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + } + UE_scan = 0; + frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; + for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; + frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; + } + }*/ + + for (CC_id=1; CC_idsubframe_config.numerology_index_mu.value =1; + config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD + config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL + config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; + config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; + config[CC_id]->sch_config.physical_cell_id.value = 0; + frame_parms[CC_id]->frame_type = FDD; + frame_parms[CC_id]->tdd_config = 3; + //frame_parms[CC_id]->tdd_config_S = 0; + frame_parms[CC_id]->N_RB_DL = 106; + frame_parms[CC_id]->N_RB_UL = 106; + frame_parms[CC_id]->Ncp = NORMAL; + //frame_parms[CC_id]->Ncp_UL = NORMAL; + frame_parms[CC_id]->Nid_cell = 0; + //frame_parms[CC_id]->num_MBSFN_config = 0; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; + frame_parms[CC_id]->nb_antennas_tx = 1; + frame_parms[CC_id]->nb_antennas_rx = 1; + //frame_parms[CC_id]->nushift = 0; + ///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; + //frame_parms[CC_id]->phich_config_common.phich_duration = normal; + // UL RS Config + /*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0 + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; + + frame_parms[CC_id]->pusch_config_common.n_SB = 1; + frame_parms[CC_id]->pusch_config_common.hoppingMode = 0; + frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0; + frame_parms[CC_id]->pusch_config_common.enable64QAM = 0; + + frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/ + // NR: Init to legacy LTE 20Mhz params + frame_parms[CC_id]->numerology_index = 0; + frame_parms[CC_id]->ttis_per_subframe = 1; + frame_parms[CC_id]->slots_per_tti = 2; + } +} + +void init_openair0(void) { + int card; + int i; + + for (card=0; cardN_RB_DL == 106) { + if (numerology==0) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=23.04e6; + openair0_cfg[card].samples_per_frame = 230400; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } else { + openair0_cfg[card].sample_rate=30.72e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } + } else if (numerology==1) { + openair0_cfg[card].sample_rate=61.44e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 20e6; + openair0_cfg[card].rx_bw = 20e6; + } else if (numerology==2) { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 40e6; + openair0_cfg[card].rx_bw = 40e6; + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + } else if(frame_parms[0]->N_RB_DL == 50) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + openair0_cfg[card].tx_bw = 5e6; + openair0_cfg[card].rx_bw = 5e6; + } else if (frame_parms[0]->N_RB_DL == 25) { + openair0_cfg[card].sample_rate=7.68e6; + openair0_cfg[card].samples_per_frame = 76800; + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; + } else if (frame_parms[0]->N_RB_DL == 6) { + openair0_cfg[card].sample_rate=1.92e6; + openair0_cfg[card].samples_per_frame = 19200; + openair0_cfg[card].tx_bw = 1.5e6; + openair0_cfg[card].rx_bw = 1.5e6; + } + + if (frame_parms[0]->frame_type==TDD) + openair0_cfg[card].duplex_mode = duplex_mode_TDD; + else //FDD + openair0_cfg[card].duplex_mode = duplex_mode_FDD; + + printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].Mod_id = 0; + openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + openair0_cfg[card].clock_source = clock_source; + openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); + openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + + for (i=0; i<4; i++) { + if (irx_total_gain_dB - rx_gain_off; + openair0_cfg[card].configFilename = rf_config_file; + printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", + card,i, openair0_cfg[card].tx_gain[i], + openair0_cfg[card].rx_gain[i], + openair0_cfg[card].tx_freq[i], + openair0_cfg[card].rx_freq[i]); + } + + if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; + + if (usrp_clksrc) { + if (strcmp(usrp_clksrc, "internal") == 0) { + openair0_cfg[card].clock_source = internal; + LOG_D(PHY, "USRP clock source set as internal\n"); + } else if (strcmp(usrp_clksrc, "external") == 0) { + openair0_cfg[card].clock_source = external; + LOG_D(PHY, "USRP clock source set as external\n"); + } else if (strcmp(usrp_clksrc, "gpsdo") == 0) { + openair0_cfg[card].clock_source = gpsdo; + LOG_D(PHY, "USRP clock source set as gpsdo\n"); + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source unknown ('%s'). defaulting to internal\n", usrp_clksrc); + } + } else { + openair0_cfg[card].clock_source = internal; + LOG_I(PHY, "USRP clock source not specified. defaulting to internal\n"); + } + } +} + + +int main( int argc, char **argv ) { + //uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + PHY_VARS_NR_UE *UE[MAX_NUM_CCs]; + start_background_system(); + + if ( load_configmodule(argc,argv) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); + set_default_frame_parms(frame_parms); + mode = normal_txrx; + memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS); + memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + // initialize logging + logInit(); + // get options and fill parameters from configuration file + get_options (); //Command-line options, enb_properties +#if T_TRACER + T_Config_Init(); +#endif + //randominit (0); + set_taus_seed (0); + tpool_t pool; + Tpool = &pool; + char params[]="1,2,3,u"; + initTpool(params, Tpool, false); + cpuf=get_cpu_freq_GHz(); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + + if (opt_type != OPT_NONE) { + if (init_opt(in_path, in_ip) == -1) + LOG_E(OPT,"failed to run OPT \n"); + } + +#ifdef PDCP_USE_NETLINK + netlink_init(); +#if defined(PDCP_USE_NETLINK_QUEUES) + pdcp_netlink_init(); +#endif +#endif +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + + // init the parameters + for (int CC_id=0; CC_idnb_antennas_tx = nb_antenna_tx; + frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); + } + + NB_UE_INST=1; + NB_INST=1; + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **)); + PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs); + + for (int CC_id=0; CC_idofdm_symbol_size); + nr_init_frame_parms_ue(frame_parms[CC_id],numerology,NORMAL,frame_parms[CC_id]->N_RB_DL,(frame_parms[CC_id]->N_RB_DL-20)>>1,0); + PHY_vars_UE_g[0][CC_id] = init_nr_ue_vars(frame_parms[CC_id], 0,abstraction_flag); + UE[CC_id] = PHY_vars_UE_g[0][CC_id]; + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + + if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode + for (int i=0; ipusch_config_dedicated[i] = malloc(sizeof(PUSCH_CONFIG_DEDICATED)); + //UE[CC_id]->scheduling_request_config[i] = malloc(sizeof(SCHEDULING_REQUEST_CONFIG)); + /*UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; + UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); + UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;*/ + } + } + + UE[CC_id]->UE_scan = UE_scan; + UE[CC_id]->UE_scan_carrier = UE_scan_carrier; + UE[CC_id]->UE_fo_compensation = UE_fo_compensation; + UE[CC_id]->mode = mode; + printf("UE[%d]->mode = %d\n",CC_id,mode); + + for (uint8_t i=0; imac_enabled == 1) + UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1234; + else + UE[CC_id]->pdcch_vars[i][0]->crnti = 0x1235; + } + + UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; + + if (frame_parms[CC_id]->frame_type==FDD) { + UE[CC_id]->N_TA_offset = 0; + } else { + if (frame_parms[CC_id]->N_RB_DL == 100) + UE[CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + UE[CC_id]->N_TA_offset = 624/4; + } + } + + // printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power)); + init_openair0(); + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); + mlockall(MCL_CURRENT | MCL_FUTURE); + init_scope(); + number_of_cards = 1; + + for(int CC_id=0; CC_idrf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; +#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) + PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance; +#else + PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160; +#endif + } + + // wait for end of program + printf("TYPE TO TERMINATE\n"); + init_UE(1); + + while(true) + sleep(3600); + + return 0; +} diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h new file mode 100644 index 0000000000..df6b2f7282 --- /dev/null +++ b/executables/nr-uesoftmodem.h @@ -0,0 +1,246 @@ +#ifndef NR_UESOFTMODEM_H +#define NR_UESOFTMODEM_H + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../ARCH/COMMON/common_lib.h" +#undef MALLOC +#include "assertions.h" +#include "PHY/types.h" +#include "PHY/defs_nr_UE.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#include + + +#if defined(ENABLE_ITTI) + #if defined(ENABLE_USE_MME) + #include "s1ap_eNB.h" + #ifdef PDCP_USE_NETLINK + #include "SIMULATION/ETH_TRANSPORT/proto.h" + #endif + #endif +#endif + +/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ +#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" +#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n" +#define CONFIG_HLP_CALUER "set UE RX calibration\n" +#define CONFIG_HLP_CALUERM "" +#define CONFIG_HLP_CALUERB "" +#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n" +#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n" +#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n" +#define CONFIG_HLP_UERXG "set UE RX gain\n" +#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n" +#define CONFIG_HLP_UETXG "set UE TX gain\n" +#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n" +#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n" +#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n" +#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n" +#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" +#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" +#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" +#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" +#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" +#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n" +#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" +#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" +#define CONFIG_HLP_TADV "Set timing_advance\n" +#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" +#define CONFIG_HLP_CHOFF "Channel id offset\n" +#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" +#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" +#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" +#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" +#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" +#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" +#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" +#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n" +#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n" +#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" +#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n" +#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n" +#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n" +#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" +#define CONFIG_HLP_TPORT "tracer port\n" +#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" +#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" + +#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n" +#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" +#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" +#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" + +#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" + +#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" +#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n" + +/***************************************************************************************************************************************/ +/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument + when calling config_get or config_getlist functions */ + + +/*------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters defining UE running mode */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_UEMODEPARAMS_DESC { \ + {"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + {"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + {"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + {"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + {"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + {"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + {"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \ + {"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \ + } +#define CMDLINE_CALIBUERX_IDX 0 +#define CMDLINE_CALIBUERXMED_IDX 1 +#define CMDLINE_CALIBUERXBYP_IDX 2 +#define CMDLINE_DEBUGUEPRACH_IDX 3 +#define CMDLINE_NOL2CONNECT_IDX 4 +#define CMDLINE_CALIBPRACHTX_IDX 5 +#define CMDLINE_MEMLOOP_IDX 6 +#define CMDLINE_DUMPMEMORY_IDX 7 +/*------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters specific to UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_UEPARAMS_DESC { \ + {"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ + {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ + {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ + {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \ + {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ + {"r" , CONFIG_HLP_PRB, 0, iptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT, 0}, \ + {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ + {"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \ + } + +#define DEFAULT_DLF 2680000000 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters common to eNodeB and UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_PARAMS_DESC { \ + {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ + {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ + {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ + {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ + {"external-clock", CONFIG_HLP_EXCCLK, PARAMFLAG_BOOL, uptr:&clock_source, defintval:0, TYPE_INT, 0}, \ + {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ + {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ + {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ + {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ + {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, iptr:&do_forms, defintval:0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ + {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ + {"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ + {"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ + {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ + {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ + {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ + {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ + {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ + {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ + {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ + } + +#define CONFIG_HLP_FLOG "Enable online log \n" +#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n" +#define CONFIG_HLP_LOGV "Set the global log verbosity \n" +#define CONFIG_HLP_TELN "Start embedded telnet server \n" +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters for LOG utility */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_LOGPARAMS_DESC { \ + {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ + {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ + {"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \ + {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ + } +#define CMDLINE_ONLINELOG_IDX 0 +#define CMDLINE_GLOGLEVEL_IDX 1 +#define CMDLINE_GLOGVERBO_IDX 2 +#define CMDLINE_STARTTELN_IDX 3 + + +extern int T_port; +extern int T_nowait; +extern int T_dont_fork; + + + +/***************************************************************************************************************************************/ + +extern pthread_cond_t sync_cond; +extern pthread_mutex_t sync_mutex; +extern int sync_var; + + +extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +extern int rx_input_level_dBm; +extern uint8_t exit_missed_slots; +extern uint64_t num_missed_slots; // counter for the number of missed slots + +extern int oaisim_flag; +extern volatile int oai_exit; + +extern openair0_config_t openair0_cfg[MAX_CARDS]; +extern pthread_cond_t sync_cond; +extern pthread_mutex_t sync_mutex; +extern int sync_var; +extern int transmission_mode; +extern double cpuf; + +#if defined(ENABLE_ITTI) + extern volatile int start_eNB; + extern volatile int start_UE; +#endif + +// In nr-ue.c +extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); +extern void fill_ue_band_info(void); +extern void init_UE(int); +extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name); +extern void reset_opp_meas(void); +extern void print_opp_meas(void); +void *UE_thread(void *arg); +PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag); +extern tpool_t *Tpool; +#endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index f1a3ef42ab..f3cd1a29f3 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -52,9 +52,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, ncoef = 32767 - coef; -//#ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset); -//#endif //DEBUG_PHY + LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset); // we only use channel estimates from tx antenna 0 here @@ -122,8 +120,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", - ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx, + LOG_D(PHY,"AbsSubframe %d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", subframe, ue->current_thread_id[subframe], diff, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index def3a71754..b6a28c81b0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -39,7 +39,7 @@ #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "SCHED_NR_UE/defs.h" #include "SIMULATION/TOOLS/sim.h" -#include "targets/RT/USER/nr-uesoftmodem.h" +#include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" //#define DEBUG_DLSCH_DECODING diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index ca0aa50d0e..3a7af2e6be 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -203,14 +203,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #endif } else { - LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx); + LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n",nr_tti_rx); return(-1); } beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; break; default: - LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx,type); + LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type); return(-1); break; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 02b3d57afe..23dda3fc24 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -122,11 +122,6 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode) // ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2]; // ue->pbch_vars[0]->decoded_output[2] = dummy; - for(int i=0; iproc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx; - } #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id); #endif @@ -292,9 +287,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) if (ue->UE_scan_carrier == 0) { #if UE_AUTOTEST_TRACE - LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", + LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n", ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, ue->rx_offset, ue->common_vars.freq_offset ); #endif @@ -305,30 +299,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) } -#if DISABLE_LOG_X - printf("[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, - 10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB, - 10*log10(ue->measurements.rssi), - ue->rx_total_gain_dB, - ue->measurements.n0_power_tot_dBm, - 10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB, - (10*log10(ue->measurements.rsrq[0]))); - - - printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n", - ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, - duplex_string[fp->frame_type], - prefix_string[fp->Ncp], - fp->Nid_cell, - fp->N_RB_DL, - fp->phich_config_common.phich_duration, - phich_string[fp->phich_config_common.phich_resource], - fp->nb_antenna_ports_eNB); -#else - LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, + LOG_I(PHY, "[UE %d] RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id, 10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB, 10*log10(ue->measurements.rssi), ue->rx_total_gain_dB, @@ -346,22 +317,12 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode) fp->phich_config_common.phich_duration, phich_string[fp->phich_config_common.phich_resource], fp->nb_antenna_ports_eNB);*/ -#endif #if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) -# if DISABLE_LOG_X - printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", + LOG_I(PHY, "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset, ue->common_vars.freq_offset); -# else - LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n", - ue->Mod_id, - ue->proc.proc_rxtx[0].frame_rx, - openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset, - ue->common_vars.freq_offset); -# endif #endif } else { #ifdef DEBUG_INITIAL_SYNC diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 95381ad560..9f1c8e096d 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -267,27 +267,6 @@ typedef struct { uint8_t CC_id; /// Last RX timestamp openair0_timestamp timestamp_rx; - /// pthread attributes for main UE thread - pthread_attr_t attr_ue; - /// scheduling parameters for main UE thread - struct sched_param sched_param_ue; - /// pthread descriptor main UE thread - pthread_t pthread_ue; - /// \brief Instance count for synch thread. - /// \internal This variable is protected by \ref mutex_synch. - int instance_cnt_synch; - /// pthread attributes for synch processing thread - pthread_attr_t attr_synch; - /// scheduling parameters for synch thread - struct sched_param sched_param_synch; - /// pthread descriptor synch thread - pthread_t pthread_synch; - /// condition variable for UE synch thread; - pthread_cond_t cond_synch; - /// mutex for UE synch thread - pthread_mutex_t mutex_synch; - /// set of scheduling variables RXn-TXnp4 threads - UE_nr_rxtx_proc_t proc_rxtx[RX_NB_TH]; } UE_nr_proc_t; typedef enum { diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index ca30ab1cec..7c17987980 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -232,7 +232,6 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ printf("half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit); printf("-------------------------------\n"); - PHY_vars_UE_g[0][0]->proc.proc_rxtx[0].frame_rx = phy_config->config_req.pbch_config.system_frame_number; } if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON){ diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index c9ea45f03b..3b24814951 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -36,7 +36,7 @@ #include "PHY/defs_UE.h" #include "PHY/phy_extern_ue.h" #include -#include "targets/RT/USER/lte-softmodem.h" +#include "executables/nr-uesoftmodem.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "SCHED_UE/sched_UE.h" @@ -5116,13 +5116,13 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if (msg_p != NULL) { switch (ITTI_MSG_ID(msg_p)) { case PHY_FIND_CELL_REQ: - LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + LOG_I(PHY, "[UE ] Received %s\n", ITTI_MSG_NAME (msg_p)); /* TODO process the message */ break; default: - LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) , ITTI_MSG_NAME (msg_p)); break; } diff --git a/openair2/LAYER2/NR_MAC_UE/mac.h b/openair2/LAYER2/NR_MAC_UE/mac.h index d0b6d4730d..fe8e91500a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac.h +++ b/openair2/LAYER2/NR_MAC_UE/mac.h @@ -43,10 +43,10 @@ /*!\brief UE layer 2 status */ typedef enum { - CONNECTION_OK = 0, - CONNECTION_LOST, - PHY_RESYNCH, - PHY_HO_PRACH + UE_CONNECTION_OK = 0, + UE_CONNECTION_LOST, + UE_PHY_RESYNCH, + UE_PHY_HO_PRACH } NR_UE_L2_STATE_t; typedef struct { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index f34000bc98..2379233776 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -30,8 +30,8 @@ * \warning */ -#ifndef __LAYER2_MAC_PROTO_H__ -#define __LAYER2_MAC_PROTO_H__ +#ifndef __LAYER2_MAC_UE_PROTO_H__ +#define __LAYER2_MAC_UE_PROTO_H__ #include "mac_defs.h" #include "mac.h" diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index e3dad2db70..7110a35331 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -686,7 +686,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler( mac->scheduled_response.dl_config = dl_config; - return CONNECTION_OK; + return UE_CONNECTION_OK; } ////////////// diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 840cb5b4cc..e391cc67b9 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -102,13 +102,13 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ 0, 0); // TODO check tx/rx frame/slot is need for NR version switch(ret){ - case CONNECTION_OK: + case UE_CONNECTION_OK: break; - case CONNECTION_LOST: + case UE_CONNECTION_LOST: break; - case PHY_RESYNCH: + case UE_PHY_RESYNCH: break; - case PHY_HO_PRACH: + case UE_PHY_HO_PRACH: break; default: break; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 685a628b26..d14b2457c9 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -424,7 +424,7 @@ extern "C" * \returns 0 in success */ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg); - +#define gettid() syscall(__NR_gettid) /*@}*/ #ifdef __cplusplus From 71bc14d0d909500924b99c37f579e03c34d85b74 Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 21 Mar 2019 14:33:25 +0100 Subject: [PATCH 16/21] new thread model - make affinity optional --- common/utils/threadPool/thread-pool.c | 51 ++++++++++++++++----------- executables/nr-ue.c | 14 -------- executables/nr-uesoftmodem.c | 2 +- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index ca050ea098..4cc56fc9b8 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include void displayList(notifiedFIFO_t *nf) { @@ -46,12 +48,16 @@ static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, void *one_thread(void *arg) { struct one_thread *myThread=(struct one_thread *) arg; struct thread_pool *tp=myThread->pool; + // configure the thread core assignment // TBD: reserve the core for us exclusively - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(myThread->coreID, &cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if ( myThread->coreID >= 0 && myThread->coreID < get_nprocs_conf()) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(myThread->coreID, &cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + } + //Configure the thread scheduler policy for Linux struct sched_param sparam= {0}; sparam.sched_priority = sched_get_priority_max(SCHED_RR); @@ -112,22 +118,27 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { curptr=strtok_r(params,",",&saveptr); while ( curptr!=NULL ) { - if (curptr[0] == 'u' || curptr[0] == 'U') { - pool->restrictRNTI=true; - } else if ( curptr[0]>='0' && curptr[0]<='9' ) { - struct one_thread *tmp=pool->allthreads; - pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); - pool->allthreads->next=tmp; - printf("create a thread for core %d\n", atoi(curptr)); - pool->allthreads->coreID=atoi(curptr); - pool->allthreads->id=pool->nbThreads; - pool->allthreads->pool=pool; - pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads); - pool->nbThreads++; - } else if (curptr[0] == 'n' || curptr[0] == 'N') { - pool->activated=false; - } else - printf("Error in options for thread pool: %s\n",curptr); + int c=toupper(curptr[0]); + + switch (c) { + case 'U': + pool->restrictRNTI=true; + break; + + case 'N': + pool->activated=false; + break; + + default: + pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); + pool->allthreads->next=pool->allthreads; + printf("create a thread for core %d\n", atoi(curptr)); + pool->allthreads->coreID=atoi(curptr); + pool->allthreads->id=pool->nbThreads; + pool->allthreads->pool=pool; + pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads); + pool->nbThreads++; + } curptr=strtok_r(NULL,",",&saveptr); } diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d45ee37d19..46dd2835d9 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -19,16 +19,6 @@ * contact@openairinterface.org */ -/*! \file lte-ue.c - * \brief threads and support functions for real-time LTE UE target - * \author R. Knopp, F. Kaltenberger, Navid Nikaein - * \date 2015 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr - * \note - * \warning - */ #include "executables/nr-uesoftmodem.h" #include "LAYER2/NR_MAC_UE/mac.h" @@ -141,10 +131,6 @@ typedef enum { si=2 } sync_mode_t; - -int32_t **rxdata; -int32_t **txdata; - #define KHz (1000UL) #define MHz (1000*KHz) typedef struct eutra_band_s { diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 5384e0835d..ed5ff7aa1d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -709,7 +709,7 @@ int main( int argc, char **argv ) { set_taus_seed (0); tpool_t pool; Tpool = &pool; - char params[]="1,2,3,u"; + char params[]="-1,-1,-1,-1"; initTpool(params, Tpool, false); cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); From 30e06d16ce5afb8e3719bbbafba96b3a2c23fcde Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 22 Mar 2019 14:03:27 +0100 Subject: [PATCH 17/21] revised doc --- common/utils/threadPool/thread-pool.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index 92cc21b975..2b6336fb60 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -11,7 +11,7 @@ All the thread pool functions are thread safe, nevertheless the working function ## license Author: Laurent Thomas, Open cells project -The owner share the code usage to Openairsoftware alliance as per OSA license terms +The owner share this piece code to Openairsoftware alliance as per OSA license terms # jobs @@ -41,6 +41,8 @@ abort_notifiedFIFO() allows the customer to delete all waiting jobs that match w The clients can create one or more thread pools with init_tpool() the params string structure: describes a list of cores, separated by "," that run a worker thread +If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" ## adding jobs @@ -66,4 +68,4 @@ A performance measurement is integrated: the pool will automacillay fill timesta if you set the environement variable: thread-pool-measurements to a valid file name These measurements will be wrote to this Linux pipe. -A tool to read the linux fifo and display it in ascii will be provided (TBD) +A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. From 40b52195fcc4b3dd9a2b192f4e366774bfc7a4e2 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 26 Mar 2019 16:16:34 +0100 Subject: [PATCH 18/21] redefining max number of UEs for memory allocation. Using the PHYSIM macro, different allocations are used for phy_simulators and real-time modem. --- .gitignore | 1 - cmake_targets/CMakeLists.txt | 2 +- openair2/LAYER2/MAC/mac_extern.h | 4 ---- openair2/RRC/LTE/rrc_extern.h | 6 ------ openair2/RRC/NR/nr_rrc_extern.h | 6 ------ targets/COMMON/openairinterface5g_limits.h | 9 ++++++++- 6 files changed, 9 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 61d9558916..2adc5d457c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ cmake_targets/log/ -cmake_targets/ran_build/ cmake_targets/*/build/ targets/bin/ diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 79f057c29e..7899c71a7b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -671,7 +671,7 @@ add_boolean_option(EXMIMO_IOT True "????") add_boolean_option(LOCALIZATION False "???") add_integer_option(MAX_NUM_CCs 1 "????") add_boolean_option(MU_RECEIVER False "????") -add_boolean_option(PHYSIM True "for L1 simulators (dlsim, ulsim, ...)") +add_boolean_option(PHYSIM False "for L1 simulators (dlsim, ulsim, ...)") add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim") add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim") add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator") diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index ca72882471..825756a095 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -58,11 +58,7 @@ extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES -#ifndef PHYSIM -#define NB_INST 1 -#else extern unsigned char NB_INST; -#endif extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; extern unsigned char NB_RN_INST; diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 59200fb9cc..68c805dffe 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -44,17 +44,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue; extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue; -#ifndef PHY_EMUL -#ifndef PHYSIM -//#define NB_INST 1 -#else extern unsigned char NB_INST; -#endif extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; extern unsigned short NODE_ID[1]; extern void* bigphys_malloc(int); -#endif //CONSTANTS diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 7509dfc727..a9af422f02 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -43,17 +43,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue; extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue; -#ifndef PHY_EMUL -#ifndef PHYSIM -//#define NB_INST 1 -#else extern unsigned char NB_INST; -#endif extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; extern unsigned short NODE_ID[1]; extern void* bigphys_malloc(int); -#endif //CONSTANTS diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index d44f0c5601..9645acf4dd 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -1,11 +1,12 @@ #ifndef OPENAIRINTERFACE5G_LIMITS_H_ #define OPENAIRINTERFACE5G_LIMITS_H_ -#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) +#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/ # define NUMBER_OF_eNB_MAX 1 # define NUMBER_OF_gNB_MAX 1 # define NUMBER_OF_RU_MAX 2 # define NUMBER_OF_NR_RU_MAX 2 +# ifndef PHYSIM # ifndef UE_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_NR_UE_MAX 16 @@ -17,6 +18,12 @@ # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif +# else +# define NUMBER_OF_UE_MAX 1 +# define NUMBER_OF_NR_UE_MAX 1 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# define NUMBER_OF_CONNECTED_gNB_MAX 1 +# endif #else # define NUMBER_OF_eNB_MAX 7 # define NUMBER_OF_gNB_MAX 7 From 4af9f321cfc030d6e0f8e25ccb65b604ec4abbb2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 27 Mar 2019 16:10:51 +0100 Subject: [PATCH 19/21] Fix multiple SSB support for PUSCH --- openair1/SIMULATION/NR_PHY/ulschsim.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 9b0c3562af..ca3860c5b0 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -146,7 +146,7 @@ int main(int argc, char **argv) { //char input_val_str[50],input_val_str2[50]; //uint16_t NB_RB=25; SCM_t channel_model = AWGN; //Rayleigh1_anticorr; - uint8_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; + uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; unsigned char frame_type = 0; unsigned char pbch_phase = 0; int frame = 0, subframe = 0; @@ -162,7 +162,7 @@ int main(int argc, char **argv) { //int run_initial_sync=0; int loglvl = OAILOG_WARNING; float target_error_rate = 0.01; - + uint64_t SSB_positions=0x01; uint16_t nb_symb_sch = 12; uint16_t nb_rb = 50; uint8_t Imcs = 9; @@ -176,7 +176,7 @@ int main(int argc, char **argv) { //logInit(); randominit(0); - while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:N:F:R:P:")) != -1) { + while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) { switch (c) { case 'f': write_output_file = 1; @@ -287,6 +287,10 @@ int main(int argc, char **argv) { break; + case 'M': + SSB_positions = atoi(optarg); + break; + case 'N': Nid_cell = atoi(optarg); break; @@ -346,6 +350,7 @@ int main(int argc, char **argv) { printf("-z Number of RX antennas used in UE\n"); printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-M Multiple SSB positions in burst\n"); printf("-N Nid_cell\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); @@ -365,7 +370,8 @@ int main(int argc, char **argv) { if (snr1set == 0) snr1 = snr0 + 10; - gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, 61.44e6, //N_RB2sampling_rate(N_RB_DL), + gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, + 61.44e6, //N_RB2sampling_rate(N_RB_DL), 40e6, //N_RB2channel_bandwidth(N_RB_DL), 0, 0, 0); @@ -389,7 +395,7 @@ int main(int argc, char **argv) { crcTableInit(); - nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell); + nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell, SSB_positions); phy_init_nr_gNB(gNB, 0, 0); //init_eNB_afterRU(); @@ -649,8 +655,10 @@ int main(int argc, char **argv) { (float) n_false_positive / (float) n_trials); printf("*****************************************\n"); - if ((float) n_errors / (float) n_trials < target_error_rate) + if ((float) n_errors / (float) n_trials < target_error_rate) { + printf("PUSCH test OK\n"); break; + } } /*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); From 19d9693c0449d4e6096c8eaa3b3da617d158f65f Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 28 Mar 2019 17:48:34 +0100 Subject: [PATCH 20/21] adding get_band to new nr-ue executable --- executables/nr-ue.c | 73 ++++-------------------------------- executables/nr-uesoftmodem.c | 5 +++ 2 files changed, 13 insertions(+), 65 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 46dd2835d9..402c379687 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -131,55 +131,6 @@ typedef enum { si=2 } sync_mode_t; -#define KHz (1000UL) -#define MHz (1000*KHz) -typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; -} eutra_band_t; - -typedef struct band_info_s { - int nbands; - eutra_band_t band_info[100]; -} band_info_t; - -band_info_t bands_to_scan; - -static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, -}; PHY_VARS_NR_UE *init_nr_ue_vars(NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, @@ -226,20 +177,8 @@ static void UE_synch(void *arg) { if (UE->UE_scan == 0) { int ind; - for ( ind=0; ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); - ind++) { - current_band = eutra_bands[ind].band; - LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - - if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - break; - } - } - - AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); + get_band(downlink_frequency[CC_id][0], &UE->frame_parms.eutra_band, &uplink_frequency_offset[CC_id][0], &UE->frame_parms.frame_type); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], oai_exit, openair0_cfg[0].rx_num_channels); @@ -259,7 +198,8 @@ static void UE_synch(void *arg) { sync_mode = pbch; } else { current_band=0; - + LOG_E(PHY,"Fixme!\n"); + /* for (i=0; irf_map.card].rx_num_channels; i++) { downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = @@ -269,11 +209,13 @@ static void UE_synch(void *arg) { downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; } + */ } LOG_W(PHY, "Starting sync detection\n"); switch (sync_mode) { + /* case pss: LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); //lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); @@ -302,7 +244,8 @@ static void UE_synch(void *arg) { } break; - + */ + case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ed5ff7aa1d..e6a97c8f28 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -535,6 +535,8 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; config[CC_id]->sch_config.physical_cell_id.value = 0; + + frame_parms[CC_id]->eutra_band = 78; frame_parms[CC_id]->frame_type = FDD; frame_parms[CC_id]->tdd_config = 3; //frame_parms[CC_id]->tdd_config_S = 0; @@ -736,6 +738,9 @@ int main( int argc, char **argv ) { frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); + + get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band, &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type); + } NB_UE_INST=1; From 8c5d67a8f3799fb33353b31fbd0e11cc6dcf94b6 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 28 Mar 2019 18:54:58 +0100 Subject: [PATCH 21/21] CI: fix long standing typo Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 6 +++--- ci-scripts/oai-ci-vm-tool | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 6ae75d71ae..b5c34d5b81 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -131,10 +131,10 @@ pipeline { } } - stage ("Start VM -- nu-ue-usrp") { + stage ("Start VM -- nr-ue-usrp") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -239,7 +239,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build nr-UE-usrp") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 1245d046ff..ed43e26729 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -39,7 +39,7 @@ function variant_usage { echo " --variant phy-sim OR -v3" echo " --variant cppcheck OR -v4" echo " --variant gnb-usrp OR -v5" - echo " --variant nu-ue-usrp OR -v6" + echo " --variant nr-ue-usrp OR -v6" echo " --variant enb-ethernet OR -v7" echo " --variant ue-ethernet OR -v8" } @@ -354,7 +354,7 @@ case $key in BUILD_OPTIONS="--gNB -w USRP" NBARGS=$[$NBARGS+256] ;; - nu-ue-usrp) + nr-ue-usrp) VM_NAME=ci-ue-nr-usrp ARCHIVES_LOC=nrue_usrp LOG_PATTERN=.Rel15.txt