diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c index 9d555c62fe..9c4ccf0679 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_modulation.c @@ -93,6 +93,11 @@ void dft_lte(int32_t *z,struct complex16 *input, int32_t Msc_PUSCH, uint8_t Nsym // printf("\n"); dft_size_idx_t dftsize = get_dft(Msc_PUSCH); + if (dftsize == DFT_SIZE_IDXTABLESIZE) { + LOG_E(PHY, "Internal error, not modulating the slot, Msc_PUSCH = %d\n", Msc_PUSCH); + return; + } + switch (Msc_PUSCH) { case 12: dft(dftsize, (int16_t *)dft_in0, (int16_t *)dft_out0, 0); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index f17e309a6d..9bc764fa35 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -589,20 +589,21 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, symbol, nb_re_pdsch); if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers - nr_dlsch_mmse(rx_size_symbol, - n_rx, - nl, - rxdataF_comp, - dl_ch_mag, - dl_ch_magb, - dl_ch_magr, - dl_ch_estimates_ext, - nb_rb_pdsch, - dlsch_config->qamModOrder, - *log2_maxh, - symbol, - nb_re_pdsch, - nvar); + if (nb_re_pdsch) + nr_dlsch_mmse(rx_size_symbol, + n_rx, + nl, + rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + dl_ch_estimates_ext, + nb_rb_pdsch, + dlsch_config->qamModOrder, + *log2_maxh, + symbol, + nb_re_pdsch, + nvar); } stop_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS); @@ -1333,50 +1334,6 @@ void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb) } } -/* Zero Forcing Rx function: nr_a_mult_b() - * Compute the complex Multiplication c=a*b - * - * */ -void nr_a_mult_b(c16_t *a, c16_t *b, c16_t *c, unsigned short nb_rb, unsigned char output_shift0) -{ - //This function is used to compute complex multiplications - short nr_conjugate[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; - unsigned short rb; - simde__m128i *a_128,*b_128, *c_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; - - a_128 = (simde__m128i *)a; - b_128 = (simde__m128i *)b; - - c_128 = (simde__m128i *)c; - - for (rb=0; rb<3*nb_rb; rb++) { - // the real part - mmtmpD0 = simde_mm_sign_epi16(a_128[0],*(simde__m128i*)&nr_conjugate[0]); - mmtmpD0 = simde_mm_madd_epi16(mmtmpD0,b_128[0]); //Re: (a_re*b_re - a_im*b_im) - - // the imag part - mmtmpD1 = simde_mm_shufflelo_epi16(a_128[0],SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1,SIMDE_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,b_128[0]);//Im: (x_im*y_re + x_re*y_im) - - mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - c_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3); - - /*printf("\n Computing mult \n"); - print_shorts("a:",(int16_t*)&a_128[0]); - print_shorts("b:",(int16_t*)&b_128[0]); - print_shorts("pack:",(int16_t*)&c_128[0]);*/ - - a_128+=1; - b_128+=1; - c_128+=1; - } -} - /* Zero Forcing Rx function: nr_element_sign() * Compute b=sign*a * @@ -1448,7 +1405,7 @@ static void nr_determin(int size, nb_rb, ((rtx & 1) == 1 ? -1 : 1) * ((ctx & 1) == 1 ? -1 : 1) * sign, shift0); - nr_a_mult_b(a44[ctx][rtx], outtemp, rtx == 0 ? ad_bc : outtemp1, nb_rb, shift0); + mult_complex_vectors(a44[ctx][rtx], outtemp, rtx == 0 ? ad_bc : outtemp1, sizeofArray(outtemp1), shift0); if (rtx != 0) nr_a_sum_b(ad_bc, outtemp1, nb_rb); @@ -1759,11 +1716,11 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, // printf("Computing r_%d c_%d\n",rtx,ctx); // print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*nl+rtx][0][0]); // print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*nl+rtx][0]); - nr_a_mult_b(inv_H_h_H[ctx][rtx], - (c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol), - outtemp, - nb_rb_0, - shift - (fp_flag == 1 ? 2 : 0)); + mult_complex_vectors(inv_H_h_H[ctx][rtx], + (c16_t *)(rxdataF_comp[ctx][0] + symbol * rx_size_symbol), + outtemp, + sizeofArray(outtemp), + shift - (fp_flag == 1 ? 2 : 0)); nr_a_sum_b(rxdataF_zforcing[rtx], outtemp, nb_rb_0); // a = a + b } #ifdef DEBUG_DLSCH_DEMOD diff --git a/openair1/PHY/TOOLS/tests/CMakeLists.txt b/openair1/PHY/TOOLS/tests/CMakeLists.txt index 9480af781f..f5bdf24421 100644 --- a/openair1/PHY/TOOLS/tests/CMakeLists.txt +++ b/openair1/PHY/TOOLS/tests/CMakeLists.txt @@ -16,8 +16,15 @@ add_dependencies(tests test_log2_approx) add_test(NAME test_log2_approx COMMAND ./test_log2_approx --gtest_filter=-log2_approx.complete) + add_executable(dft_test test_dft.c ../dfts_load.c) target_link_libraries(dft_test minimal_lib shlib_loader SIMU m) add_dependencies(tests dft_test) add_dependencies(dft_test dfts) # trigger build of dfts (shared lib for DFT) add_test(NAME dft_test COMMAND ./dft_test) + +add_executable(test_vector_op test_vector_op.cpp) +target_link_libraries(test_vector_op PRIVATE LOG minimal_lib) +add_dependencies(tests test_vector_op) +add_test(NAME test_vector_op + COMMAND test_vector_op) diff --git a/openair1/PHY/TOOLS/tests/benchmark_rotate_vector.cpp b/openair1/PHY/TOOLS/tests/benchmark_rotate_vector.cpp index 6f4ea89643..25f1756e76 100644 --- a/openair1/PHY/TOOLS/tests/benchmark_rotate_vector.cpp +++ b/openair1/PHY/TOOLS/tests/benchmark_rotate_vector.cpp @@ -45,7 +45,7 @@ static void BM_rotate_cpx_vector(benchmark::State &state) { int vector_size = state.range(0); auto input_complex_16 = generate_random_c16(vector_size); - auto input_alpha = generate_random_c16(vector_size); + auto input_alpha = generate_random_c16(1); AlignedVector512 output; output.resize(vector_size); int shift = 2; diff --git a/openair1/PHY/TOOLS/tests/test_vector_op.cpp b/openair1/PHY/TOOLS/tests/test_vector_op.cpp new file mode 100644 index 0000000000..6173c40e7e --- /dev/null +++ b/openair1/PHY/TOOLS/tests/test_vector_op.cpp @@ -0,0 +1,70 @@ +/* + * 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 +extern "C" { +#include "openair1/PHY/TOOLS/tools_defs.h" +struct configmodule_interface_s; +struct configmodule_interface_s *uniqCfg = NULL; +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + if (assert) { + abort(); + } else { + exit(EXIT_SUCCESS); + } +} +} +#include +#include "common/utils/LOG/log.h" +#include "openair1/PHY/TOOLS/phy_test_tools.hpp" + +int main() +{ + const int shift = 15; // it should always be 15 to keep int16 in same range + for (int vector_size = 1237; vector_size < 1237 + 8; vector_size++) { + auto input1 = generate_random_c16(vector_size); + auto input2 = generate_random_c16(vector_size); + AlignedVector512 output; + output.resize(vector_size); + mult_complex_vectors(input1.data(), input2.data(), output.data(), vector_size, shift); + for (int i = 0; i < vector_size; i++) { + c16_t res = c16mulShift(input1[i], input2[i], shift); + if (output[i].r != res.r || output[i].i != res.i) { + printf("Error at %d: (%d,%d) * (%d,%d) = (%d,%d) (should be (%d,%d))\n", + i, + input1[i].r, + input1[i].i, + input2[i].r, + input2[i].i, + output[i].r, + output[i].i, + res.r, + res.i); + return 1; + } + } + } + return 0; +} diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 58af33020a..41af6ba0a9 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -38,6 +38,7 @@ #include #include #include +#include "common/utils/LOG/log.h" #define simd_q15_t simde__m128i #define simdshort_q15_t simde__m64 @@ -90,7 +91,7 @@ extern "C" { int dim2; int dim3; int dim4; - uint8_t data[]; + uint8_t data[] __attribute__((aligned(32))); } fourDimArray_t; static inline fourDimArray_t *allocateFourDimArray(int elmtSz, int dim1, int dim2, int dim3, int dim4) @@ -357,6 +358,74 @@ static __attribute__((always_inline)) inline void multadd_real_four_symbols_vect simde_mm_storeu_si128((simd_q15_t *)y, y_128); } +// Multiply two vectors of complex int16 and take the most significant bits (shift by 15 in normal case) +// works only with little endian storage (for big endian, modify the srai/ssli at the end) +static __attribute__((always_inline)) inline void mult_complex_vectors(const c16_t *in1, + const c16_t *in2, + c16_t *out, + const int size, + const int shift) +{ + const simde__m256i complex_shuffle256 = simde_mm256_set_epi8(29, + 28, + 31, + 30, + 25, + 24, + 27, + 26, + 21, + 20, + 23, + 22, + 17, + 16, + 19, + 18, + 13, + 12, + 15, + 14, + 9, + 8, + 11, + 10, + 5, + 4, + 7, + 6, + 1, + 0, + 3, + 2); + const simde__m256i conj256 = simde_mm256_set_epi16(-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1); + int i; + // do 8 multiplications at a time + for (i = 0; i < size - 7; i += 8) { + const simde__m256i i1 = simde_mm256_loadu_epi32((simde__m256i *)(in1 + i)); + const simde__m256i i2 = simde_mm256_loadu_epi32((simde__m256i *)(in2 + i)); + const simde__m256i i2swap = simde_mm256_shuffle_epi8(i2, complex_shuffle256); + const simde__m256i i2conj = simde_mm256_sign_epi16(i2, conj256); + const simde__m256i re = simde_mm256_madd_epi16(i1, i2conj); + const simde__m256i im = simde_mm256_madd_epi16(i1, i2swap); + simde_mm256_storeu_si256( + (simde__m256i *)(out + i), + simde_mm256_blend_epi16(simde_mm256_srai_epi32(re, shift), simde_mm256_slli_epi32(im, 16 - shift), 0xAA)); + } + if (size - i > 4) { + const simde__m128i i1 = simde_mm_loadu_epi32((simde__m128i *)(in1 + i)); + const simde__m128i i2 = simde_mm_loadu_epi32((simde__m128i *)(in2 + i)); + const simde__m128i i2swap = simde_mm_shuffle_epi8(i2, *(simde__m128i *)&complex_shuffle256); + const simde__m128i i2conj = simde_mm_sign_epi16(i2, *(simde__m128i *)&conj256); + const simde__m128i re = simde_mm_madd_epi16(i1, i2conj); + const simde__m128i im = simde_mm_madd_epi16(i1, i2swap); + simde_mm_storeu_si128((simde__m128i *)(out + i), + simde_mm_blend_epi16(simde_mm_srai_epi32(re, shift), simde_mm_slli_epi32(im, 16 - shift), 0xAA)); + i += 4; + } + for (; i < size; i++) + out[i] = c16mulShift(in1[i], in2[i], shift); +} /*!\fn void multadd_complex_vector_real_scalar(int16_t *x,int16_t alpha,int16_t *y,uint8_t zero_flag,uint32_t N) This function performs componentwise multiplication and accumulation of a real scalar and a complex vector. @param x Vector input (Q1.15) in the format |Re0 Im0|Re1 Im 1| ... @@ -550,17 +619,15 @@ typedef enum dft_size_idx { case Sz: \ return DFT_##Sz; \ break; -static inline -dft_size_idx_t get_dft(int ofdm_symbol_size) +static inline dft_size_idx_t get_dft(int size) { - switch (ofdm_symbol_size) { + switch (size) { FOREACH_DFTSZ(FIND_ENUM) default: - printf("function get_dft : unsupported ofdm symbol size \n"); - assert(0); + LOG_E(UTIL, "function get_dft : unsupported DFT size %d\n", size); break; } - return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function; + return DFT_SIZE_IDXTABLESIZE; } #define SZ_iENUM(Sz) IDFT_##Sz, @@ -610,14 +677,12 @@ struct { return IDFT_##iSz; \ break; -static inline -idft_size_idx_t get_idft(int ofdm_symbol_size) +static inline idft_size_idx_t get_idft(int size) { - switch (ofdm_symbol_size) { + switch (size) { FOREACH_IDFTSZ(FIND_iENUM) default: - printf("function get_idft : unsupported ofdm symbol size \n"); - assert(0); + AssertFatal(false, "function get_idft : unsupported iDFT size %d\n", size); break; } return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function diff --git a/openair1/PHY/TOOLS/tools_extern.h b/openair1/PHY/TOOLS/tools_extern.h deleted file mode 100644 index 4690bba42e..0000000000 --- a/openair1/PHY/TOOLS/tools_extern.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index ef10837d2d..11a40fd69e 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -141,14 +141,13 @@ void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int1 int32_t *llr_32 = (int32_t *)llr; #ifndef USE_128BIT - simde__m256i xmm0, xmm1, xmm2; for (int i = 0; i < (nb_re >> 3); i++) { - xmm0 = *rxF; + simde__m256i xmm0 = simde_mm256_loadu_si256(rxF); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - xmm1 = simde_mm256_abs_epi16(xmm0); + simde__m256i xmm1 = simde_mm256_abs_epi16(xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 xmm1 = simde_mm256_subs_epi16(*ch_maga, xmm1); - xmm2 = simde_mm256_abs_epi16(xmm1); + simde__m256i xmm2 = simde_mm256_abs_epi16(xmm1); xmm2 = simde_mm256_subs_epi16(*ch_magb, xmm2); // xmm0 |1st 4th 7th 10th 13th 16th 19th 22ed| // xmm1 |2ed 5th 8th 11th 14th 17th 20th 23rd| diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 0e1864cad1..085317b0df 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -505,8 +505,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, dlsch0->Nl); const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16; - __attribute__((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx * dlsch0->Nl][pdsch_est_size]; - memset(pdsch_dl_ch_estimates, 0, sizeof(int32_t) * ue->frame_parms.nb_antennas_rx * dlsch0->Nl * pdsch_est_size); + fourDimArray_t *toFree = NULL; + allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch0->Nl, pdsch_est_size, false); c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot)); @@ -515,8 +515,14 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, memset(ptrs_re_per_slot, 0, sizeof(ptrs_re_per_slot)); const uint32_t rx_size_symbol = (dlsch[0].dlsch_config.number_rbs * NR_NB_SC_PER_RB + 15) & ~15; - __attribute__((aligned(32))) int32_t rxdataF_comp[dlsch[0].Nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT]; - memset(rxdataF_comp, 0, sizeof(rxdataF_comp)); + fourDimArray_t *toFree2 = NULL; + allocCast3D(rxdataF_comp, + int32_t, + toFree2, + dlsch[0].Nl, + ue->frame_parms.nb_antennas_rx, + rx_size_symbol * NR_SYMBOLS_PER_SLOT, + false); uint32_t nvar = 0; @@ -620,6 +626,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, return -1; } // CRNTI active stop_meas_nr_ue_phy(ue, RX_PDSCH_STATS); + free(toFree); + free(toFree2); } return 0; } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 9ab2de4215..6766b94ad1 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -858,15 +858,12 @@ int main(int argc, char **argv) UE_mac->if_module = nr_ue_if_module_init(0); unsigned int available_bits=0; - unsigned char *estimated_output_bit; - unsigned char *test_input_bit; + unsigned char *estimated_output_bit=NULL; + unsigned char *test_input_bit=NULL; unsigned int errors_bit = 0; initFloatingCoresTpool(dlsch_threads, &nrUE_params.Tpool, false, "UE-tpool"); - test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384); - // generate signal AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); @@ -905,13 +902,14 @@ int main(int argc, char **argv) gNB->msgDataTx = msgDataTx; // Buffers to store internal memory of slot process - int rx_size = (((14 * frame_parms->N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4; - UE->phy_sim_rxdataF = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, frame_parms->samples_per_slot_wCP * sizeof(int32_t)); + int rx_size = (((14 * UE->frame_parms.N_RB_DL * 12 * sizeof(int32_t)) + 15) >> 4) << 4; + UE->phy_sim_rxdataF = calloc(sizeof(int32_t *) * UE->frame_parms.nb_antennas_rx * g_nrOfLayers, + UE->frame_parms.samples_per_slot_wCP * sizeof(int32_t)); UE->phy_sim_pdsch_llr = calloc(1, (8 * (3 * 8 * 8448)) * sizeof(int16_t)); // Max length - UE->phy_sim_pdsch_rxdataF_ext = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); - UE->phy_sim_pdsch_rxdataF_comp = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); - UE->phy_sim_pdsch_dl_ch_estimates = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); - UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(sizeof(int32_t *) * frame_parms->nb_antennas_rx * g_nrOfLayers, rx_size); + UE->phy_sim_pdsch_rxdataF_ext = calloc(sizeof(int32_t *) * UE->frame_parms.nb_antennas_rx * g_nrOfLayers, rx_size); + UE->phy_sim_pdsch_rxdataF_comp = calloc(sizeof(int32_t *) * UE->frame_parms.nb_antennas_rx * g_nrOfLayers, rx_size); + UE->phy_sim_pdsch_dl_ch_estimates = calloc(sizeof(int32_t *) * UE->frame_parms.nb_antennas_rx * g_nrOfLayers, rx_size); + UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(sizeof(int32_t *) * UE->frame_parms.nb_antennas_rx * g_nrOfLayers, rx_size); int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated if (g_rbSize != 273) { a_segments = a_segments*g_rbSize; @@ -1118,7 +1116,17 @@ int main(int argc, char **argv) // Apply MIMO Channel multipath_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); - add_noise(UE->common_vars.rxdata, (const double **) r_re, (const double **) r_im, sigma2, slot_length, slot_offset, ts, delay, pdu_bit_map, 0x1, frame_parms->nb_antennas_rx); + add_noise(UE->common_vars.rxdata, + (const double **)r_re, + (const double **)r_im, + sigma2, + slot_length, + slot_offset, + ts, + delay, + pdu_bit_map, + 0x1, + UE->frame_parms.nb_antennas_rx); dl_config.sfn = frame; dl_config.slot = slot; ue_dci_configuration(UE_mac, &dl_config, frame, slot); @@ -1168,6 +1176,10 @@ int main(int argc, char **argv) round++; } // round + if (test_input_bit == NULL) { + test_input_bit = (unsigned char *)malloc16(sizeof(unsigned char) * TBS); + estimated_output_bit = (unsigned char *)malloc16(sizeof(unsigned char) * TBS); + } for (i = 0; i < TBS; i++) { estimated_output_bit[i] = (UE->phy_sim_dlsch_b[i/8] & (1 << (i & 7))) >> (i & 7); @@ -1226,10 +1238,11 @@ int main(int argc, char **argv) fprintf(csv_file,"%.2f,%.4f,%.2f,%u\n", roundStats, effRate, effRate / TBS * 100, TBS); } if (print_perf==1) { - printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, block %d)\n", + printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, C %d, block %d)\n", 1000 >> *scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex, + UE->dl_harq_processes[0][slot].C, msgDataTx->dlsch[0][0].harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0] << 3); printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx"); printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");