From ec40b34b1dacef04ff0767f80d79a07ff25fd1fa Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 16 Aug 2024 16:34:43 +0200 Subject: [PATCH 1/6] initial cleanup --- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 148 ++++++-------- .../nr_dlsch_llr_computation.c | 192 +----------------- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 36 ---- 3 files changed, 64 insertions(+), 312 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 2529fdd38e..5ca3f3e203 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -31,9 +31,7 @@ */ #include "PHY/defs_gNB.h" -#include "PHY/defs_nr_common.h" #include "PHY/sse_intrin.h" -#include "PHY/impl_defs_top.h" #ifdef __aarch64__ #define USE_128BIT @@ -55,13 +53,10 @@ int16_t saturating_sub(int16_t a, int16_t b) //---------------------------------------------------------------------------------------------- // QPSK //---------------------------------------------------------------------------------------------- -void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol) +void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re, uint8_t symbol) { c16_t *rxF = (c16_t *)rxdataF_comp; - c16_t *llr32 = (c16_t *)ulsch_llr; + c16_t *llr32 = (c16_t *)llr; for (int i = 0; i < nb_re; i++) { llr32[i].r = rxF[i].r >> 3; llr32[i].i = rxF[i].i >> 3; @@ -72,11 +67,11 @@ void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp, // 16-QAM //---------------------------------------------------------------------------------------------- -void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsch_llr, uint32_t nb_re, uint8_t symbol) +void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re, uint8_t symbol) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; - simde__m256i *ch_mag = (simde__m256i *)ul_ch_mag; - int64_t *llr_64 = (int64_t *)ulsch_llr; + simde__m256i *ch_mag = (simde__m256i *)ch_mag_in; + int64_t *llr_64 = (int64_t *)llr; #ifndef USE_128BIT simde__m256i xmm0, xmm1, xmm2; @@ -110,7 +105,7 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsc simde__m128i *rxF_128 = (simde__m128i *)rxF_256; simde__m128i *ch_mag_128 = (simde__m128i *)ch_mag; - simde__m128i *ulsch_llr_128 = (simde__m128i *)llr_64; + simde__m128i *llr_128 = (simde__m128i *)llr_64; // Each iteration does 4 RE (gives 16 16bit-llrs) for (int i = 0; i < (nb_re >> 2); i++) { @@ -119,9 +114,9 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsc // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 xmm0 = simde_mm_subs_epi16(*ch_mag_128, xmm0); - ulsch_llr_128[0] = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs - ulsch_llr_128[1] = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs - ulsch_llr_128 += 2; + llr_128[0] = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs + llr_128[1] = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs + llr_128 += 2; rxF_128++; ch_mag_128++; } @@ -130,17 +125,17 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsc nb_re &= 0x3; int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ul_ch_mag_i16 = (int16_t *)ch_mag_128; - int16_t *ulsch_llr_i16 = (int16_t *)ulsch_llr_128; + int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; + int16_t *llr_i16 = (int16_t *)llr_128; for (uint i = 0U; i < nb_re; i++) { int16_t real = rxDataF_i16[2 * i]; int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; - ulsch_llr_i16[4 * i] = real; - ulsch_llr_i16[4 * i + 1] = imag; - ulsch_llr_i16[4 * i + 2] = saturating_sub(mag_real, abs(real)); - ulsch_llr_i16[4 * i + 3] = saturating_sub(mag_imag, abs(imag)); + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr_i16[4 * i] = real; + llr_i16[4 * i + 1] = imag; + llr_i16[4 * i + 2] = saturating_sub(mag_real, abs(real)); + llr_i16[4 * i + 3] = saturating_sub(mag_imag, abs(imag)); } } @@ -148,19 +143,14 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsc // 64-QAM //---------------------------------------------------------------------------------------------- -void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol) +void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re, uint8_t symbol) { simde__m256i *rxF = (simde__m256i *)rxdataF_comp; - simde__m256i *ch_maga = (simde__m256i *)ul_ch_mag; - simde__m256i *ch_magb = (simde__m256i *)ul_ch_magb; + simde__m256i *ch_maga = (simde__m256i *)ch_mag; + simde__m256i *ch_magb = (simde__m256i *)ch_mag2; - int32_t *llr_32 = (int32_t *)ulsch_llr; + int32_t *llr_32 = (int32_t *)llr; #ifndef USE_128BIT simde__m256i xmm0, xmm1, xmm2; @@ -244,40 +234,40 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, nb_re &= 0x3; int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ul_ch_mag_i16 = (int16_t *)ch_mag_128; - int16_t *ul_ch_magb_i16 = (int16_t *)ch_magb_128; + int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; + int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; int16_t *llr_i16 = (int16_t *)llr64; for (int i = 0; i < nb_re; i++) { int16_t real = rxDataF_i16[2 * i]; int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; llr_i16[6 * i] = real; llr_i16[6 * i + 1] = imag; llr_i16[6 * i + 2] = saturating_sub(mag_real, abs(real)); llr_i16[6 * i + 3] = saturating_sub(mag_imag, abs(imag)); - int16_t mag_realb = ul_ch_magb_i16[2 * i]; - int16_t mag_imagb = ul_ch_magb_i16[2 * i + 1]; + int16_t mag_realb = ch_magb_i16[2 * i]; + int16_t mag_imagb = ch_magb_i16[2 * i + 1]; llr_i16[6 * i + 4] = saturating_sub(mag_realb, abs(llr_i16[6 * i + 2])); llr_i16[6 * i + 5] = saturating_sub(mag_imagb, abs(llr_i16[6 * i + 3])); } simde_mm_empty(); } -void nr_ulsch_256qam_llr(int32_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int32_t *ul_ch_magc, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol) +void nr_256qam_llr(int32_t *rxdataF_comp, + int32_t *ch_mag, + int32_t *ch_mag2, + int32_t *ch_mag3, + int16_t *llr, + uint32_t nb_re, + uint8_t symbol) { simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; - simde__m256i *llr256 = (simde__m256i *)ulsch_llr; + simde__m256i *llr256 = (simde__m256i *)llr; - simde__m256i *ch_maga = (simde__m256i *)ul_ch_mag; - simde__m256i *ch_magb = (simde__m256i *)ul_ch_magb; - simde__m256i *ch_magc = (simde__m256i *)ul_ch_magc; + simde__m256i *ch_maga = (simde__m256i *)ch_mag; + simde__m256i *ch_magb = (simde__m256i *)ch_mag2; + simde__m256i *ch_magc = (simde__m256i *)ch_mag3; #ifndef USE_128BIT simde__m256i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; @@ -357,26 +347,26 @@ void nr_ulsch_256qam_llr(int32_t *rxdataF_comp, if (nb_re & 3) { for (int i = 0; i < (nb_re & 0x3); i++) { int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ul_ch_mag_i16 = (int16_t *)ch_maga_128; - int16_t *ul_ch_magb_i16 = (int16_t *)ch_magb_128; - int16_t *ul_ch_magc_i16 = (int16_t *)ch_magc_128; - int16_t *ulsch_llr_i16 = (int16_t *)llr_128; + int16_t *ch_mag_i16 = (int16_t *)ch_maga_128; + int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; + int16_t *ch_magc_i16 = (int16_t *)ch_magc_128; + int16_t *llr_i16 = (int16_t *)llr_128; int16_t real = rxDataF_i16[2 * i + 0]; int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; - ulsch_llr_i16[8 * i] = real; - ulsch_llr_i16[8 * i + 1] = imag; - ulsch_llr_i16[8 * i + 2] = saturating_sub(mag_real, abs(real)); - ulsch_llr_i16[8 * i + 3] = saturating_sub(mag_imag, abs(imag)); - int16_t magb_real = ul_ch_magb_i16[2 * i]; - int16_t magb_imag = ul_ch_magb_i16[2 * i + 1]; - ulsch_llr_i16[8 * i + 4] = saturating_sub(magb_real, abs(ulsch_llr_i16[8 * i + 2])); - ulsch_llr_i16[8 * i + 5] = saturating_sub(magb_imag, abs(ulsch_llr_i16[8 * i + 3])); - int16_t magc_real = ul_ch_magc_i16[2 * i]; - int16_t magc_imag = ul_ch_magc_i16[2 * i + 1]; - ulsch_llr_i16[8 * i + 6] = saturating_sub(magc_real, abs(ulsch_llr_i16[8 * i + 4])); - ulsch_llr_i16[8 * i + 7] = saturating_sub(magc_imag, abs(ulsch_llr_i16[8 * i + 5])); + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr_i16[8 * i] = real; + llr_i16[8 * i + 1] = imag; + llr_i16[8 * i + 2] = saturating_sub(mag_real, abs(real)); + llr_i16[8 * i + 3] = saturating_sub(mag_imag, abs(imag)); + int16_t magb_real = ch_magb_i16[2 * i]; + int16_t magb_imag = ch_magb_i16[2 * i + 1]; + llr_i16[8 * i + 4] = saturating_sub(magb_real, abs(llr_i16[8 * i + 2])); + llr_i16[8 * i + 5] = saturating_sub(magb_imag, abs(llr_i16[8 * i + 3])); + int16_t magc_real = ch_magc_i16[2 * i]; + int16_t magc_imag = ch_magc_i16[2 * i + 1]; + llr_i16[8 * i + 6] = saturating_sub(magc_real, abs(llr_i16[8 * i + 4])); + llr_i16[8 * i + 7] = saturating_sub(magc_imag, abs(llr_i16[8 * i + 5])); } } simde_mm_empty(); @@ -393,34 +383,16 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, { switch(mod_order){ case 2: - nr_ulsch_qpsk_llr(rxdataF_comp, - ulsch_llr, - nb_re, - symbol); + nr_qpsk_llr(rxdataF_comp, ulsch_llr, nb_re, symbol); break; case 4: - nr_ulsch_16qam_llr(rxdataF_comp, - ul_ch_mag, - ulsch_llr, - nb_re, - symbol); + nr_16qam_llr(rxdataF_comp, ul_ch_mag, ulsch_llr, nb_re, symbol); break; case 6: - nr_ulsch_64qam_llr(rxdataF_comp, - ul_ch_mag, - ul_ch_magb, - ulsch_llr, - nb_re, - symbol); + nr_64qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ulsch_llr, nb_re, symbol); break; case 8: - nr_ulsch_256qam_llr(rxdataF_comp, - ul_ch_mag, - ul_ch_magb, - ul_ch_magc, - ulsch_llr, - nb_re, - symbol); + nr_256qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ul_ch_magc, ulsch_llr, nb_re, symbol); break; default: AssertFatal(1==0,"nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n",symbol, mod_order); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index 82b3410bc1..3a67306905 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -36,6 +36,10 @@ #include "PHY/TOOLS/tools_defs.h" #include "PHY/sse_intrin.h" +#ifdef __aarch64__ +#define USE_128BIT +#endif + //#define DEBUG_LLR_SIC //============================================================================================== @@ -323,191 +327,3 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, simde_m_empty(); } -//============================================================================================== -// DUAL-STREAM -//============================================================================================== - -//---------------------------------------------------------------------------------------------- -// QPSK -//---------------------------------------------------------------------------------------------- - -simde__m128i y0r_over2 __attribute__ ((aligned(16))); -simde__m128i y0i_over2 __attribute__ ((aligned(16))); -simde__m128i y1r_over2 __attribute__ ((aligned(16))); -simde__m128i y1i_over2 __attribute__ ((aligned(16))); - -simde__m128i A __attribute__ ((aligned(16))); -simde__m128i B __attribute__ ((aligned(16))); -simde__m128i C __attribute__ ((aligned(16))); -simde__m128i D __attribute__ ((aligned(16))); -simde__m128i E __attribute__ ((aligned(16))); -simde__m128i F __attribute__ ((aligned(16))); -simde__m128i G __attribute__ ((aligned(16))); -simde__m128i H __attribute__ ((aligned(16))); - - - -void nr_qpsk_qpsk(short *stream0_in, - short *stream1_in, - short *stream0_out, - short *rho01, - int length - ) -{ - - /* - This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are QPSK. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. - - Parameters: - stream0_in = Matched filter output y0' = (h0*g0)*y0 - stream1_in = Matched filter output y1' = (h0*g1)*y0 - stream0_out = LLRs - rho01 = Correlation between the two effective channels \rho_{10} = (h1*g1)*(h0*g0) - length = number of resource elements - */ - - simde__m128i *rho01_128i = (simde__m128i *)rho01; - simde__m128i *stream0_128i_in = (simde__m128i *)stream0_in; - simde__m128i *stream1_128i_in = (simde__m128i *)stream1_in; - simde__m128i *stream0_128i_out = (simde__m128i *)stream0_out; - simde__m128i ONE_OVER_SQRT_8 =simde_mm_set1_epi16(23170); //round(2^16/sqrt(8)) - - int i; - - - for (i=0; i>2; i+=2) { - // in each iteration, we take 8 complex samples - simde__m128i xmm0 = rho01_128i[i]; // 4 symbols - simde__m128i xmm1 = rho01_128i[i+1]; - - // put (rho_r + rho_i)/2sqrt2 in rho_rpi - // put (rho_r - rho_i)/2sqrt2 in rho_rmi - - xmm0 =simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - simde__m128i xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) - simde__m128i rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) - simde__m128i rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) - - // divide by sqrt(8), no shift needed ONE_OVER_SQRT_8 = Q1.16 - rho_rpi =simde_mm_mulhi_epi16(rho_rpi,ONE_OVER_SQRT_8); - rho_rmi =simde_mm_mulhi_epi16(rho_rmi,ONE_OVER_SQRT_8); - // Compute LLR for first bit of stream 0 - - // Compute real and imaginary parts of MF output for stream 0 - xmm0 = stream0_128i_in[i]; - xmm1 = stream0_128i_in[i+1]; - - xmm0 =simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - simde__m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); - - simde__m128i y0r_over2 = simde_mm_srai_epi16(y0r, 1); // divide by 2 - simde__m128i y0i_over2 = simde_mm_srai_epi16(y0i, 1); // divide by 2 - // Compute real and imaginary parts of MF output for stream 1 - xmm0 = stream1_128i_in[i]; - xmm1 = stream1_128i_in[i+1]; - - xmm0 =simde_mm_shufflelo_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shufflehi_epi16(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm0 =simde_mm_shuffle_epi32(xmm0,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflelo_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shufflehi_epi16(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - xmm1 =simde_mm_shuffle_epi32(xmm1,0xd8); // SIMDE_MM_SHUFFLE(0,2,1,3)); - //xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - //xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - simde__m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - simde__m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] - - simde__m128i y1r_over2 = simde_mm_srai_epi16(y1r, 1); // divide by 2 - simde__m128i y1i_over2 = simde_mm_srai_epi16(y1i, 1); // divide by 2 - - // Compute the terms for the LLR of first bit - - xmm0 =simde_mm_setzero_si128(); // ZERO - - // 1 term for numerator of LLR - xmm3 =simde_mm_subs_epi16(y1r_over2,rho_rpi); - A =simde_mm_abs_epi16(xmm3); // A = |y1r/2 - rho/sqrt(8)| - xmm2 =simde_mm_adds_epi16(A,y0i_over2); // = |y1r/2 - rho/sqrt(8)| + y0i/2 - xmm3 =simde_mm_subs_epi16(y1i_over2,rho_rmi); - B =simde_mm_abs_epi16(xmm3); // B = |y1i/2 - rho*/sqrt(8)| - simde__m128i logmax_num_re0 =simde_mm_adds_epi16(B,xmm2); // = |y1r/2 - rho/sqrt(8)|+|y1i/2 - rho*/sqrt(8)| + y0i/2 - - // 2 term for numerator of LLR - xmm3 =simde_mm_subs_epi16(y1r_over2,rho_rmi); - C =simde_mm_abs_epi16(xmm3); // C = |y1r/2 - rho*/4| - xmm2 =simde_mm_subs_epi16(C,y0i_over2); // = |y1r/2 - rho*/4| - y0i/2 - xmm3 =simde_mm_adds_epi16(y1i_over2,rho_rpi); - D =simde_mm_abs_epi16(xmm3); // D = |y1i/2 + rho/4| - xmm2 =simde_mm_adds_epi16(xmm2,D); // |y1r/2 - rho*/4| + |y1i/2 + rho/4| - y0i/2 - logmax_num_re0 =simde_mm_max_epi16(logmax_num_re0,xmm2); // max, numerator done - - // 1 term for denominator of LLR - xmm3 =simde_mm_adds_epi16(y1r_over2,rho_rmi); - E =simde_mm_abs_epi16(xmm3); // E = |y1r/2 + rho*/4| - xmm2 =simde_mm_adds_epi16(E,y0i_over2); // = |y1r/2 + rho*/4| + y0i/2 - xmm3 =simde_mm_subs_epi16(y1i_over2,rho_rpi); - F =simde_mm_abs_epi16(xmm3); // F = |y1i/2 - rho/4| - simde__m128i logmax_den_re0 =simde_mm_adds_epi16(F,xmm2); // = |y1r/2 + rho*/4| + |y1i/2 - rho/4| + y0i/2 - - // 2 term for denominator of LLR - xmm3 =simde_mm_adds_epi16(y1r_over2,rho_rpi); - G =simde_mm_abs_epi16(xmm3); // G = |y1r/2 + rho/4| - xmm2 =simde_mm_subs_epi16(G,y0i_over2); // = |y1r/2 + rho/4| - y0i/2 - xmm3 =simde_mm_adds_epi16(y1i_over2,rho_rmi); - H =simde_mm_abs_epi16(xmm3); // H = |y1i/2 + rho*/4| - xmm2 =simde_mm_adds_epi16(xmm2,H); // = |y1r/2 + rho/4| + |y1i/2 + rho*/4| - y0i/2 - logmax_den_re0 =simde_mm_max_epi16(logmax_den_re0,xmm2); // max, denominator done - - // Compute the terms for the LLR of first bit - - // 1 term for nominator of LLR - xmm2 = simde_mm_adds_epi16(A,y0r_over2); - simde__m128i logmax_num_im0 = simde_mm_adds_epi16(B, xmm2); // = |y1r/2 - rho/4| + |y1i/2 - rho*/4| + y0r/2 - - // 2 term for nominator of LLR - xmm2 =simde_mm_subs_epi16(E,y0r_over2); - xmm2 =simde_mm_adds_epi16(xmm2,F); // = |y1r/2 + rho*/4| + |y1i/2 - rho/4| - y0r/2 - - logmax_num_im0 =simde_mm_max_epi16(logmax_num_im0,xmm2); // max, nominator done - - // 1 term for denominator of LLR - xmm2 =simde_mm_adds_epi16(C,y0r_over2); - simde__m128i logmax_den_im0 =simde_mm_adds_epi16(D,xmm2); // = |y1r/2 - rho*/4| + |y1i/2 + rho/4| - y0r/2 - - xmm2 =simde_mm_subs_epi16(G,y0r_over2); - xmm2 =simde_mm_adds_epi16(xmm2,H); // = |y1r/2 + rho/4| + |y1i/2 + rho*/4| - y0r/2 - - logmax_den_im0 =simde_mm_max_epi16(logmax_den_im0,xmm2); // max, denominator done - - // LLR of first bit [L1(1), L1(2), L1(3), L1(4)] - y0r =simde_mm_adds_epi16(y0r,logmax_num_re0); - y0r =simde_mm_subs_epi16(y0r,logmax_den_re0); - - // LLR of second bit [L2(1), L2(2), L2(3), L2(4)] - y0i =simde_mm_adds_epi16(y0i,logmax_num_im0); - y0i =simde_mm_subs_epi16(y0i,logmax_den_im0); - - simde_mm_storeu_si128(&stream0_128i_out[i],simde_mm_unpacklo_epi16(y0r,y0i)); // = [L1(1), L2(1), L1(2), L2(2)] - - if (i<((length>>1) - 1)) // false if only 2 REs remain - simde_mm_storeu_si128(&stream0_128i_out[i+1],simde_mm_unpackhi_epi16(y0r,y0i)); - - } - -} 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 9b7fbb1023..44151bfbaf 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -52,42 +52,6 @@ */ void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations); -/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception. - @param stream0_in Input from channel compensated (MR combined) stream 0 - @param stream1_in Input from channel compensated (MR combined) stream 1 - @param stream0_out Output from LLR unit for stream0 - @param rho01 Cross-correlation between channels (MR combined) - @param length in complex channel outputs*/ -void nr_qpsk_qpsk(int16_t *stream0_in, - int16_t *stream1_in, - int16_t *stream0_out, - int16_t *rho01, - int32_t length); - -/** \brief This function perform LLR computation for dual-stream (QPSK/QPSK) transmission. - @param frame_parms Frame descriptor structure - @param rxdataF_comp Compensated channel output - @param rxdataF_comp_i Compensated channel output for interference - @param rho_i Correlation between channel of signal and inteference - @param dlsch_llr llr output - @param symbol OFDM symbol index in sub-frame - @param len - @param first_symbol_flag flag to indicate this is the first symbol of the dlsch - @param nb_rb number of RBs for this allocation - @param pbch_pss_sss_adj Number of channel bits taken by PBCH/PSS/SSS - @param llr128p pointer to pointer to symbol in dlsch_llr*/ -int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int32_t **rxdataF_comp_i, - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t symbol, - uint32_t len, - uint8_t first_symbol_flag, - uint16_t nb_rb, - uint16_t pbch_pss_sss_adj, - int16_t **llr128p); - /** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms @param frame_parms Frame descriptor structure @param rxdataF_comp Compensated channel output From aeb562756afa3f95b1648b55edbeb72e835e8fad Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 16 Aug 2024 16:51:00 +0200 Subject: [PATCH 2/6] moving LLR functions to phy_common --- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 336 +---------------- .../PHY/nr_phy_common/inc/nr_phy_common.h | 10 + .../PHY/nr_phy_common/src/nr_phy_common.c | 339 ++++++++++++++++++ 3 files changed, 350 insertions(+), 335 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 5ca3f3e203..450408e794 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -32,346 +32,12 @@ #include "PHY/defs_gNB.h" #include "PHY/sse_intrin.h" +#include "nr_phy_common.h" #ifdef __aarch64__ #define USE_128BIT #endif -int16_t saturating_sub(int16_t a, int16_t b) -{ - int32_t result = (int32_t)a - (int32_t)b; - - if (result < INT16_MIN) { - return INT16_MIN; - } else if (result > INT16_MAX) { - return INT16_MAX; - } else { - return (int16_t)result; - } -} - -//---------------------------------------------------------------------------------------------- -// QPSK -//---------------------------------------------------------------------------------------------- -void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re, uint8_t symbol) -{ - c16_t *rxF = (c16_t *)rxdataF_comp; - c16_t *llr32 = (c16_t *)llr; - for (int i = 0; i < nb_re; i++) { - llr32[i].r = rxF[i].r >> 3; - llr32[i].i = rxF[i].i >> 3; - } -} - -//---------------------------------------------------------------------------------------------- -// 16-QAM -//---------------------------------------------------------------------------------------------- - -void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re, uint8_t symbol) -{ - simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; - simde__m256i *ch_mag = (simde__m256i *)ch_mag_in; - int64_t *llr_64 = (int64_t *)llr; - -#ifndef USE_128BIT - simde__m256i xmm0, xmm1, xmm2; - - for (int i = 0; i < (nb_re >> 3); i++) { - // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - xmm0 = simde_mm256_abs_epi16(*rxF_256); - // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 - xmm0 = simde_mm256_subs_epi16(*ch_mag, xmm0); - - xmm1 = simde_mm256_unpacklo_epi32(*rxF_256, xmm0); - xmm2 = simde_mm256_unpackhi_epi32(*rxF_256, xmm0); - - // xmm1 |1st 2ed 3rd 4th 9th 10th 13rd 14th| - // xmm2 |5th 6th 7th 8th 11st 12ed 15th 16th| - - *llr_64++ = simde_mm256_extract_epi64(xmm1, 0); - *llr_64++ = simde_mm256_extract_epi64(xmm1, 1); - *llr_64++ = simde_mm256_extract_epi64(xmm2, 0); - *llr_64++ = simde_mm256_extract_epi64(xmm2, 1); - *llr_64++ = simde_mm256_extract_epi64(xmm1, 2); - *llr_64++ = simde_mm256_extract_epi64(xmm1, 3); - *llr_64++ = simde_mm256_extract_epi64(xmm2, 2); - *llr_64++ = simde_mm256_extract_epi64(xmm2, 3); - rxF_256++; - ch_mag++; - } - - nb_re &= 0x7; -#endif - - simde__m128i *rxF_128 = (simde__m128i *)rxF_256; - simde__m128i *ch_mag_128 = (simde__m128i *)ch_mag; - simde__m128i *llr_128 = (simde__m128i *)llr_64; - - // Each iteration does 4 RE (gives 16 16bit-llrs) - for (int i = 0; i < (nb_re >> 2); i++) { - // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - simde__m128i xmm0 = simde_mm_abs_epi16(*rxF_128); - // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 - xmm0 = simde_mm_subs_epi16(*ch_mag_128, xmm0); - - llr_128[0] = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs - llr_128[1] = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs - llr_128 += 2; - rxF_128++; - ch_mag_128++; - } - - simde_mm_empty(); - - nb_re &= 0x3; - int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; - int16_t *llr_i16 = (int16_t *)llr_128; - for (uint i = 0U; i < nb_re; i++) { - int16_t real = rxDataF_i16[2 * i]; - int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ch_mag_i16[2 * i]; - int16_t mag_imag = ch_mag_i16[2 * i + 1]; - llr_i16[4 * i] = real; - llr_i16[4 * i + 1] = imag; - llr_i16[4 * i + 2] = saturating_sub(mag_real, abs(real)); - llr_i16[4 * i + 3] = saturating_sub(mag_imag, abs(imag)); - } -} - -//---------------------------------------------------------------------------------------------- -// 64-QAM -//---------------------------------------------------------------------------------------------- - -void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re, uint8_t symbol) -{ - simde__m256i *rxF = (simde__m256i *)rxdataF_comp; - - simde__m256i *ch_maga = (simde__m256i *)ch_mag; - simde__m256i *ch_magb = (simde__m256i *)ch_mag2; - - 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; - // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - 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); - 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| - // xmm2 |3rd 6th 9th 12th 15th 18th 21st 24th| - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 0); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 0); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 0); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 1); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 1); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 1); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 2); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 2); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 2); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 3); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 3); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 3); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 4); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 4); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 4); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 5); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 5); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 5); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 6); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 6); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 6); - - *llr_32++ = simde_mm256_extract_epi32(xmm0, 7); - *llr_32++ = simde_mm256_extract_epi32(xmm1, 7); - *llr_32++ = simde_mm256_extract_epi32(xmm2, 7); - rxF++; - ch_maga++; - ch_magb++; - } - - nb_re &= 0x7; -#endif - - simde__m128i *rxF_128 = (simde__m128i *)rxF; - simde__m128i *ch_mag_128 = (simde__m128i *)ch_maga; - simde__m128i *ch_magb_128 = (simde__m128i *)ch_magb; - - simde__m64 *llr64 = (simde__m64 *)llr_32; - - // Each iteration does 4 RE (gives 24 16bit-llrs) - for (int i = 0; i < (nb_re >> 2); i++) { - simde__m128i xmm0, xmm1, xmm2; - xmm0 = *rxF_128; - xmm1 = simde_mm_abs_epi16(xmm0); - xmm1 = simde_mm_subs_epi16(*ch_mag_128, xmm1); - xmm2 = simde_mm_abs_epi16(xmm1); - xmm2 = simde_mm_subs_epi16(*ch_magb_128, xmm2); - - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm1, 0), simde_mm_extract_epi32(xmm0, 0)); - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm0, 1), simde_mm_extract_epi32(xmm2, 0)); - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm2, 1), simde_mm_extract_epi32(xmm1, 1)); - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm1, 2), simde_mm_extract_epi32(xmm0, 2)); - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm0, 3), simde_mm_extract_epi32(xmm2, 2)); - *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm2, 3), simde_mm_extract_epi32(xmm1, 3)); - rxF_128++; - ch_mag_128++; - ch_magb_128++; - } - - nb_re &= 0x3; - - int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; - int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; - int16_t *llr_i16 = (int16_t *)llr64; - for (int i = 0; i < nb_re; i++) { - int16_t real = rxDataF_i16[2 * i]; - int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ch_mag_i16[2 * i]; - int16_t mag_imag = ch_mag_i16[2 * i + 1]; - llr_i16[6 * i] = real; - llr_i16[6 * i + 1] = imag; - llr_i16[6 * i + 2] = saturating_sub(mag_real, abs(real)); - llr_i16[6 * i + 3] = saturating_sub(mag_imag, abs(imag)); - int16_t mag_realb = ch_magb_i16[2 * i]; - int16_t mag_imagb = ch_magb_i16[2 * i + 1]; - llr_i16[6 * i + 4] = saturating_sub(mag_realb, abs(llr_i16[6 * i + 2])); - llr_i16[6 * i + 5] = saturating_sub(mag_imagb, abs(llr_i16[6 * i + 3])); - } - simde_mm_empty(); -} - -void nr_256qam_llr(int32_t *rxdataF_comp, - int32_t *ch_mag, - int32_t *ch_mag2, - int32_t *ch_mag3, - int16_t *llr, - uint32_t nb_re, - uint8_t symbol) -{ - simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; - simde__m256i *llr256 = (simde__m256i *)llr; - - simde__m256i *ch_maga = (simde__m256i *)ch_mag; - simde__m256i *ch_magb = (simde__m256i *)ch_mag2; - simde__m256i *ch_magc = (simde__m256i *)ch_mag3; -#ifndef USE_128BIT - simde__m256i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; - - for (int i = 0; i < (nb_re >> 3); i++) { - // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - xmm0 = simde_mm256_abs_epi16(*rxF_256); - // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 - xmm0 = simde_mm256_subs_epi16(*ch_maga, xmm0); - // xmmtmpD2 contains 16 LLRs - xmm1 = simde_mm256_abs_epi16(xmm0); - xmm1 = simde_mm256_subs_epi16(*ch_magb, xmm1); // contains 16 LLRs - xmm2 = simde_mm256_abs_epi16(xmm1); - xmm2 = simde_mm256_subs_epi16(*ch_magc, xmm2); // contains 16 LLRs - // rxF[i] A0 A1 A2 A3 A4 A5 A6 A7 bits 7,6 - // xmm0 B0 B1 B2 B3 B4 B5 B6 B7 bits 5,4 - // xmm1 C0 C1 C2 C3 C4 C5 C6 C7 bits 3,2 - // xmm2 D0 D1 D2 D3 D4 D5 D6 D7 bits 1,0 - xmm3 = simde_mm256_unpacklo_epi32(*rxF_256, xmm0); // A0 B0 A1 B1 A4 B4 A5 B5 - xmm4 = simde_mm256_unpackhi_epi32(*rxF_256, xmm0); // A2 B2 A3 B3 A6 B6 A7 B7 - xmm5 = simde_mm256_unpacklo_epi32(xmm1, xmm2); // C0 D0 C1 D1 C4 D4 C5 D5 - xmm6 = simde_mm256_unpackhi_epi32(xmm1, xmm2); // C2 D2 C3 D3 C6 D6 C7 D7 - - xmm0 = simde_mm256_unpacklo_epi64(xmm3, xmm5); // A0 B0 C0 D0 A4 B4 C4 D4 - xmm1 = simde_mm256_unpackhi_epi64(xmm3, xmm5); // A1 B1 C1 D1 A5 B5 C5 D5 - xmm2 = simde_mm256_unpacklo_epi64(xmm4, xmm6); // A2 B2 C2 D2 A6 B6 C6 D6 - xmm3 = simde_mm256_unpackhi_epi64(xmm4, xmm6); // A3 B3 C3 D3 A7 B7 C7 D7 - *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x20); // A0 B0 C0 D0 A1 B1 C1 D1 - *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x20); // A2 B2 C2 D2 A3 B3 C3 D3 - *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x31); // A4 B4 C4 D4 A5 B5 C5 D5 - *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x31); // A6 B6 C6 D6 A7 B7 C7 D7 - ch_magc++; - ch_magb++; - ch_maga++; - rxF_256++; - } - - nb_re &= 0x7; -#endif - - simde__m128i *rxF_128 = (simde__m128i *)rxF_256; - simde__m128i *llr_128 = (simde__m128i *)llr256; - - simde__m128i *ch_maga_128 = (simde__m128i *)ch_maga; - simde__m128i *ch_magb_128 = (simde__m128i *)ch_magb; - simde__m128i *ch_magc_128 = (simde__m128i *)ch_magc; - - for (int i = 0; i < (nb_re >> 2); i++) { - simde__m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; - // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| - xmm0 = simde_mm_abs_epi16(*rxF_128); - // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 - xmm0 = simde_mm_subs_epi16(*ch_maga_128, xmm0); - xmm1 = simde_mm_abs_epi16(xmm0); - xmm1 = simde_mm_subs_epi16(*ch_magb_128, xmm1); // contains 8 LLRs - xmm2 = simde_mm_abs_epi16(xmm1); - xmm2 = simde_mm_subs_epi16(*ch_magc_128, xmm2); // contains 8 LLRs - // rxF[i] A0 A1 A2 A3 - // xmm0 B0 B1 B2 B3 - // xmm1 C0 C1 C2 C3 - // xmm2 D0 D1 D2 D3 - xmm3 = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // A0 B0 A1 B1 - xmm4 = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // A2 B2 A3 B3 - xmm5 = simde_mm_unpacklo_epi32(xmm1, xmm2); // C0 D0 C1 D1 - xmm6 = simde_mm_unpackhi_epi32(xmm1, xmm2); // C2 D2 C3 D3 - - *llr_128++ = simde_mm_unpacklo_epi64(xmm3, xmm5); // A0 B0 C0 D0 - *llr_128++ = simde_mm_unpackhi_epi64(xmm3, xmm5); // A1 B1 C1 D1 - *llr_128++ = simde_mm_unpacklo_epi64(xmm4, xmm6); // A2 B2 C2 D2 - *llr_128++ = simde_mm_unpackhi_epi64(xmm4, xmm6); // A3 B3 C3 D3 - - rxF_128++; - ch_maga_128++; - ch_magb_128++; - ch_magc_128++; - } - - if (nb_re & 3) { - for (int i = 0; i < (nb_re & 0x3); i++) { - int16_t *rxDataF_i16 = (int16_t *)rxF_128; - int16_t *ch_mag_i16 = (int16_t *)ch_maga_128; - int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; - int16_t *ch_magc_i16 = (int16_t *)ch_magc_128; - int16_t *llr_i16 = (int16_t *)llr_128; - int16_t real = rxDataF_i16[2 * i + 0]; - int16_t imag = rxDataF_i16[2 * i + 1]; - int16_t mag_real = ch_mag_i16[2 * i]; - int16_t mag_imag = ch_mag_i16[2 * i + 1]; - llr_i16[8 * i] = real; - llr_i16[8 * i + 1] = imag; - llr_i16[8 * i + 2] = saturating_sub(mag_real, abs(real)); - llr_i16[8 * i + 3] = saturating_sub(mag_imag, abs(imag)); - int16_t magb_real = ch_magb_i16[2 * i]; - int16_t magb_imag = ch_magb_i16[2 * i + 1]; - llr_i16[8 * i + 4] = saturating_sub(magb_real, abs(llr_i16[8 * i + 2])); - llr_i16[8 * i + 5] = saturating_sub(magb_imag, abs(llr_i16[8 * i + 3])); - int16_t magc_real = ch_magc_i16[2 * i]; - int16_t magc_imag = ch_magc_i16[2 * i + 1]; - llr_i16[8 * i + 6] = saturating_sub(magc_real, abs(llr_i16[8 * i + 4])); - llr_i16[8 * i + 7] = saturating_sub(magc_imag, abs(llr_i16[8 * i + 5])); - } - } - simde_mm_empty(); -} - void nr_ulsch_compute_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int32_t *ul_ch_magb, diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 8e8f7399f0..216c186894 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -24,6 +24,16 @@ #include "PHY/impl_defs_top.h" #include "PHY/TOOLS/tools_defs.h" +void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re, uint8_t symbol); +void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re, uint8_t symbol); +void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re, uint8_t symbol); +void nr_256qam_llr(int32_t *rxdataF_comp, + int32_t *ch_mag, + int32_t *ch_mag2, + int32_t *ch_mag3, + int16_t *llr, + uint32_t nb_re, + uint8_t symbol); void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal); void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay); unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb); 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 b67a94d8f6..42315a1436 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -21,6 +21,345 @@ #include "nr_phy_common.h" +#ifdef __aarch64__ +#define USE_128BIT +#endif + +int16_t saturating_sub(int16_t a, int16_t b) +{ + int32_t result = (int32_t)a - (int32_t)b; + + if (result < INT16_MIN) { + return INT16_MIN; + } else if (result > INT16_MAX) { + return INT16_MAX; + } else { + return (int16_t)result; + } +} + +//---------------------------------------------------------------------------------------------- +// QPSK +//---------------------------------------------------------------------------------------------- +void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re, uint8_t symbol) +{ + c16_t *rxF = (c16_t *)rxdataF_comp; + c16_t *llr32 = (c16_t *)llr; + for (int i = 0; i < nb_re; i++) { + llr32[i].r = rxF[i].r >> 3; + llr32[i].i = rxF[i].i >> 3; + } +} + +//---------------------------------------------------------------------------------------------- +// 16-QAM +//---------------------------------------------------------------------------------------------- + +void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re, uint8_t symbol) +{ + simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; + simde__m256i *ch_mag = (simde__m256i *)ch_mag_in; + int64_t *llr_64 = (int64_t *)llr; + +#ifndef USE_128BIT + simde__m256i xmm0, xmm1, xmm2; + + for (int i = 0; i < (nb_re >> 3); i++) { + // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| + xmm0 = simde_mm256_abs_epi16(*rxF_256); + // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = simde_mm256_subs_epi16(*ch_mag, xmm0); + + xmm1 = simde_mm256_unpacklo_epi32(*rxF_256, xmm0); + xmm2 = simde_mm256_unpackhi_epi32(*rxF_256, xmm0); + + // xmm1 |1st 2ed 3rd 4th 9th 10th 13rd 14th| + // xmm2 |5th 6th 7th 8th 11st 12ed 15th 16th| + + *llr_64++ = simde_mm256_extract_epi64(xmm1, 0); + *llr_64++ = simde_mm256_extract_epi64(xmm1, 1); + *llr_64++ = simde_mm256_extract_epi64(xmm2, 0); + *llr_64++ = simde_mm256_extract_epi64(xmm2, 1); + *llr_64++ = simde_mm256_extract_epi64(xmm1, 2); + *llr_64++ = simde_mm256_extract_epi64(xmm1, 3); + *llr_64++ = simde_mm256_extract_epi64(xmm2, 2); + *llr_64++ = simde_mm256_extract_epi64(xmm2, 3); + rxF_256++; + ch_mag++; + } + + nb_re &= 0x7; +#endif + + simde__m128i *rxF_128 = (simde__m128i *)rxF_256; + simde__m128i *ch_mag_128 = (simde__m128i *)ch_mag; + simde__m128i *llr_128 = (simde__m128i *)llr_64; + + // Each iteration does 4 RE (gives 16 16bit-llrs) + for (int i = 0; i < (nb_re >> 2); i++) { + // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| + simde__m128i xmm0 = simde_mm_abs_epi16(*rxF_128); + // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = simde_mm_subs_epi16(*ch_mag_128, xmm0); + + llr_128[0] = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // llr128[0] contains the llrs of the 1st,2nd,5th and 6th REs + llr_128[1] = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // llr128[1] contains the llrs of the 3rd, 4th, 7th and 8th REs + llr_128 += 2; + rxF_128++; + ch_mag_128++; + } + + simde_mm_empty(); + + nb_re &= 0x3; + int16_t *rxDataF_i16 = (int16_t *)rxF_128; + int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; + int16_t *llr_i16 = (int16_t *)llr_128; + for (uint i = 0U; i < nb_re; i++) { + int16_t real = rxDataF_i16[2 * i]; + int16_t imag = rxDataF_i16[2 * i + 1]; + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr_i16[4 * i] = real; + llr_i16[4 * i + 1] = imag; + llr_i16[4 * i + 2] = saturating_sub(mag_real, abs(real)); + llr_i16[4 * i + 3] = saturating_sub(mag_imag, abs(imag)); + } +} + +//---------------------------------------------------------------------------------------------- +// 64-QAM +//---------------------------------------------------------------------------------------------- + +void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re, uint8_t symbol) +{ + simde__m256i *rxF = (simde__m256i *)rxdataF_comp; + + simde__m256i *ch_maga = (simde__m256i *)ch_mag; + simde__m256i *ch_magb = (simde__m256i *)ch_mag2; + + 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; + // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| + 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); + 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| + // xmm2 |3rd 6th 9th 12th 15th 18th 21st 24th| + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 0); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 0); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 0); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 1); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 1); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 1); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 2); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 2); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 2); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 3); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 3); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 3); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 4); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 4); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 4); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 5); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 5); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 5); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 6); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 6); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 6); + + *llr_32++ = simde_mm256_extract_epi32(xmm0, 7); + *llr_32++ = simde_mm256_extract_epi32(xmm1, 7); + *llr_32++ = simde_mm256_extract_epi32(xmm2, 7); + rxF++; + ch_maga++; + ch_magb++; + } + + nb_re &= 0x7; +#endif + + simde__m128i *rxF_128 = (simde__m128i *)rxF; + simde__m128i *ch_mag_128 = (simde__m128i *)ch_maga; + simde__m128i *ch_magb_128 = (simde__m128i *)ch_magb; + + simde__m64 *llr64 = (simde__m64 *)llr_32; + + // Each iteration does 4 RE (gives 24 16bit-llrs) + for (int i = 0; i < (nb_re >> 2); i++) { + simde__m128i xmm0, xmm1, xmm2; + xmm0 = *rxF_128; + xmm1 = simde_mm_abs_epi16(xmm0); + xmm1 = simde_mm_subs_epi16(*ch_mag_128, xmm1); + xmm2 = simde_mm_abs_epi16(xmm1); + xmm2 = simde_mm_subs_epi16(*ch_magb_128, xmm2); + + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm1, 0), simde_mm_extract_epi32(xmm0, 0)); + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm0, 1), simde_mm_extract_epi32(xmm2, 0)); + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm2, 1), simde_mm_extract_epi32(xmm1, 1)); + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm1, 2), simde_mm_extract_epi32(xmm0, 2)); + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm0, 3), simde_mm_extract_epi32(xmm2, 2)); + *llr64++ = simde_mm_set_pi32(simde_mm_extract_epi32(xmm2, 3), simde_mm_extract_epi32(xmm1, 3)); + rxF_128++; + ch_mag_128++; + ch_magb_128++; + } + + nb_re &= 0x3; + + int16_t *rxDataF_i16 = (int16_t *)rxF_128; + int16_t *ch_mag_i16 = (int16_t *)ch_mag_128; + int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; + int16_t *llr_i16 = (int16_t *)llr64; + for (int i = 0; i < nb_re; i++) { + int16_t real = rxDataF_i16[2 * i]; + int16_t imag = rxDataF_i16[2 * i + 1]; + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr_i16[6 * i] = real; + llr_i16[6 * i + 1] = imag; + llr_i16[6 * i + 2] = saturating_sub(mag_real, abs(real)); + llr_i16[6 * i + 3] = saturating_sub(mag_imag, abs(imag)); + int16_t mag_realb = ch_magb_i16[2 * i]; + int16_t mag_imagb = ch_magb_i16[2 * i + 1]; + llr_i16[6 * i + 4] = saturating_sub(mag_realb, abs(llr_i16[6 * i + 2])); + llr_i16[6 * i + 5] = saturating_sub(mag_imagb, abs(llr_i16[6 * i + 3])); + } + simde_mm_empty(); +} + +void nr_256qam_llr(int32_t *rxdataF_comp, + int32_t *ch_mag, + int32_t *ch_mag2, + int32_t *ch_mag3, + int16_t *llr, + uint32_t nb_re, + uint8_t symbol) +{ + simde__m256i *rxF_256 = (simde__m256i *)rxdataF_comp; + simde__m256i *llr256 = (simde__m256i *)llr; + + simde__m256i *ch_maga = (simde__m256i *)ch_mag; + simde__m256i *ch_magb = (simde__m256i *)ch_mag2; + simde__m256i *ch_magc = (simde__m256i *)ch_mag3; +#ifndef USE_128BIT + simde__m256i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; + + for (int i = 0; i < (nb_re >> 3); i++) { + // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| + xmm0 = simde_mm256_abs_epi16(*rxF_256); + // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = simde_mm256_subs_epi16(*ch_maga, xmm0); + // xmmtmpD2 contains 16 LLRs + xmm1 = simde_mm256_abs_epi16(xmm0); + xmm1 = simde_mm256_subs_epi16(*ch_magb, xmm1); // contains 16 LLRs + xmm2 = simde_mm256_abs_epi16(xmm1); + xmm2 = simde_mm256_subs_epi16(*ch_magc, xmm2); // contains 16 LLRs + // rxF[i] A0 A1 A2 A3 A4 A5 A6 A7 bits 7,6 + // xmm0 B0 B1 B2 B3 B4 B5 B6 B7 bits 5,4 + // xmm1 C0 C1 C2 C3 C4 C5 C6 C7 bits 3,2 + // xmm2 D0 D1 D2 D3 D4 D5 D6 D7 bits 1,0 + xmm3 = simde_mm256_unpacklo_epi32(*rxF_256, xmm0); // A0 B0 A1 B1 A4 B4 A5 B5 + xmm4 = simde_mm256_unpackhi_epi32(*rxF_256, xmm0); // A2 B2 A3 B3 A6 B6 A7 B7 + xmm5 = simde_mm256_unpacklo_epi32(xmm1, xmm2); // C0 D0 C1 D1 C4 D4 C5 D5 + xmm6 = simde_mm256_unpackhi_epi32(xmm1, xmm2); // C2 D2 C3 D3 C6 D6 C7 D7 + + xmm0 = simde_mm256_unpacklo_epi64(xmm3, xmm5); // A0 B0 C0 D0 A4 B4 C4 D4 + xmm1 = simde_mm256_unpackhi_epi64(xmm3, xmm5); // A1 B1 C1 D1 A5 B5 C5 D5 + xmm2 = simde_mm256_unpacklo_epi64(xmm4, xmm6); // A2 B2 C2 D2 A6 B6 C6 D6 + xmm3 = simde_mm256_unpackhi_epi64(xmm4, xmm6); // A3 B3 C3 D3 A7 B7 C7 D7 + *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x20); // A0 B0 C0 D0 A1 B1 C1 D1 + *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x20); // A2 B2 C2 D2 A3 B3 C3 D3 + *llr256++ = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x31); // A4 B4 C4 D4 A5 B5 C5 D5 + *llr256++ = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x31); // A6 B6 C6 D6 A7 B7 C7 D7 + ch_magc++; + ch_magb++; + ch_maga++; + rxF_256++; + } + + nb_re &= 0x7; +#endif + + simde__m128i *rxF_128 = (simde__m128i *)rxF_256; + simde__m128i *llr_128 = (simde__m128i *)llr256; + + simde__m128i *ch_maga_128 = (simde__m128i *)ch_maga; + simde__m128i *ch_magb_128 = (simde__m128i *)ch_magb; + simde__m128i *ch_magc_128 = (simde__m128i *)ch_magc; + + for (int i = 0; i < (nb_re >> 2); i++) { + simde__m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; + // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I| + xmm0 = simde_mm_abs_epi16(*rxF_128); + // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2 + xmm0 = simde_mm_subs_epi16(*ch_maga_128, xmm0); + xmm1 = simde_mm_abs_epi16(xmm0); + xmm1 = simde_mm_subs_epi16(*ch_magb_128, xmm1); // contains 8 LLRs + xmm2 = simde_mm_abs_epi16(xmm1); + xmm2 = simde_mm_subs_epi16(*ch_magc_128, xmm2); // contains 8 LLRs + // rxF[i] A0 A1 A2 A3 + // xmm0 B0 B1 B2 B3 + // xmm1 C0 C1 C2 C3 + // xmm2 D0 D1 D2 D3 + xmm3 = simde_mm_unpacklo_epi32(*rxF_128, xmm0); // A0 B0 A1 B1 + xmm4 = simde_mm_unpackhi_epi32(*rxF_128, xmm0); // A2 B2 A3 B3 + xmm5 = simde_mm_unpacklo_epi32(xmm1, xmm2); // C0 D0 C1 D1 + xmm6 = simde_mm_unpackhi_epi32(xmm1, xmm2); // C2 D2 C3 D3 + + *llr_128++ = simde_mm_unpacklo_epi64(xmm3, xmm5); // A0 B0 C0 D0 + *llr_128++ = simde_mm_unpackhi_epi64(xmm3, xmm5); // A1 B1 C1 D1 + *llr_128++ = simde_mm_unpacklo_epi64(xmm4, xmm6); // A2 B2 C2 D2 + *llr_128++ = simde_mm_unpackhi_epi64(xmm4, xmm6); // A3 B3 C3 D3 + + rxF_128++; + ch_maga_128++; + ch_magb_128++; + ch_magc_128++; + } + + if (nb_re & 3) { + for (int i = 0; i < (nb_re & 0x3); i++) { + int16_t *rxDataF_i16 = (int16_t *)rxF_128; + int16_t *ch_mag_i16 = (int16_t *)ch_maga_128; + int16_t *ch_magb_i16 = (int16_t *)ch_magb_128; + int16_t *ch_magc_i16 = (int16_t *)ch_magc_128; + int16_t *llr_i16 = (int16_t *)llr_128; + int16_t real = rxDataF_i16[2 * i + 0]; + int16_t imag = rxDataF_i16[2 * i + 1]; + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr_i16[8 * i] = real; + llr_i16[8 * i + 1] = imag; + llr_i16[8 * i + 2] = saturating_sub(mag_real, abs(real)); + llr_i16[8 * i + 3] = saturating_sub(mag_imag, abs(imag)); + int16_t magb_real = ch_magb_i16[2 * i]; + int16_t magb_imag = ch_magb_i16[2 * i + 1]; + llr_i16[8 * i + 4] = saturating_sub(magb_real, abs(llr_i16[8 * i + 2])); + llr_i16[8 * i + 5] = saturating_sub(magb_imag, abs(llr_i16[8 * i + 3])); + int16_t magc_real = ch_magc_i16[2 * i]; + int16_t magc_imag = ch_magc_i16[2 * i + 1]; + llr_i16[8 * i + 6] = saturating_sub(magc_real, abs(llr_i16[8 * i + 4])); + llr_i16[8 * i + 7] = saturating_sub(magc_imag, abs(llr_i16[8 * i + 5])); + } + } + simde_mm_empty(); +} + void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal) { const idft_size_idx_t idft_size = get_idft(ofdm_symbol_size); From 98a8e5dca3a9c88a392a3d5ae0b0a9635f4ca9cd Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 16 Aug 2024 17:37:18 +0200 Subject: [PATCH 3/6] use common LLR functions at UE for DLSCH --- CMakeLists.txt | 1 - doc/Doxyfile | 1 - .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 12 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 31 +- .../nr_dlsch_llr_computation.c | 329 ------------------ .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 74 ---- .../PHY/nr_phy_common/inc/nr_phy_common.h | 14 +- .../PHY/nr_phy_common/src/nr_phy_common.c | 14 +- 8 files changed, 29 insertions(+), 447 deletions(-) delete mode 100644 openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c diff --git a/CMakeLists.txt b/CMakeLists.txt index faa3d9dc35..95232c3915 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1066,7 +1066,6 @@ set(PHY_SRC_UE ${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 ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c diff --git a/doc/Doxyfile b/doc/Doxyfile index 5f377964cf..0d53026705 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -2256,7 +2256,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/sss_nr.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/dci_nr.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/nr_prach.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c \ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 450408e794..6c5c37385b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -47,21 +47,21 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, uint8_t symbol, uint8_t mod_order) { - switch(mod_order){ + switch(mod_order) { case 2: - nr_qpsk_llr(rxdataF_comp, ulsch_llr, nb_re, symbol); + nr_qpsk_llr(rxdataF_comp, ulsch_llr, nb_re); break; case 4: - nr_16qam_llr(rxdataF_comp, ul_ch_mag, ulsch_llr, nb_re, symbol); + nr_16qam_llr(rxdataF_comp, ul_ch_mag, ulsch_llr, nb_re); break; case 6: - nr_64qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ulsch_llr, nb_re, symbol); + nr_64qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ulsch_llr, nb_re); break; case 8: - nr_256qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ul_ch_magc, ulsch_llr, nb_re, symbol); + nr_256qam_llr(rxdataF_comp, ul_ch_mag, ul_ch_magb, ul_ch_magc, ulsch_llr, nb_re); break; default: - AssertFatal(1==0,"nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n",symbol, mod_order); + AssertFatal(false, "nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n",symbol, mod_order); break; } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 6537e4b840..3482d2a80a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -28,6 +28,7 @@ * \note * \warning */ +#include "nr_phy_common.h" #include "PHY/defs_nr_UE.h" #include "PHY/phy_extern.h" #include "nr_transport_proto_ue.h" @@ -1898,33 +1899,31 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol, NR_UE_DLSCH_t dlsch[2], uint32_t llr_offset[14]) { - uint32_t llr_offset_symbol; - - if (first_symbol_flag==1) - llr_offset[symbol-1] = 0; - llr_offset_symbol = llr_offset[symbol-1]; + if (first_symbol_flag == 1) + llr_offset[symbol - 1] = 0; + uint32_t llr_offset_symbol = llr_offset[symbol - 1]; - llr_offset[symbol] = len*dlsch[0].dlsch_config.qamModOrder + llr_offset_symbol; + llr_offset[symbol] = len * dlsch[0].dlsch_config.qamModOrder + llr_offset_symbol; switch (dlsch[0].dlsch_config.qamModOrder) { case 2 : - for(int l=0; l < dlsch[0].Nl; l++) - nr_dlsch_qpsk_llr(frame_parms, rxdataF_comp[l][0], layer_llr[l] + llr_offset_symbol, symbol, len, first_symbol_flag, nb_rb); + for(int l = 0; l < dlsch[0].Nl; l++) + nr_qpsk_llr(&rxdataF_comp[l][0][symbol * nb_rb * 12], layer_llr[l] + llr_offset_symbol, len); break; case 4 : - for(int l=0; l < dlsch[0].Nl; l++) - nr_dlsch_16qam_llr(frame_parms, rxdataF_comp[l][0], layer_llr[l] + llr_offset_symbol, dl_ch_mag, symbol, len, first_symbol_flag, nb_rb); + for(int l = 0; l < dlsch[0].Nl; l++) + nr_16qam_llr(&rxdataF_comp[l][0][symbol * nb_rb * 12], dl_ch_mag, layer_llr[l] + llr_offset_symbol, len); break; case 6 : for(int l=0; l < dlsch[0].Nl; l++) - nr_dlsch_64qam_llr(frame_parms, rxdataF_comp[l][0], layer_llr[l] + llr_offset_symbol, dl_ch_mag, dl_ch_magb, symbol, len, first_symbol_flag, nb_rb); + nr_64qam_llr(&rxdataF_comp[l][0][symbol * nb_rb * 12], dl_ch_mag, dl_ch_magb, layer_llr[l] + llr_offset_symbol, len); break; case 8: for(int l=0; l < dlsch[0].Nl; l++) - nr_dlsch_256qam_llr(frame_parms, rxdataF_comp[l][0], layer_llr[l] + llr_offset_symbol, dl_ch_mag, dl_ch_magb, dl_ch_magr, symbol, len, first_symbol_flag, nb_rb); + nr_256qam_llr(&rxdataF_comp[l][0][symbol * nb_rb * 12], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[l] + llr_offset_symbol, len); break; default: @@ -1937,19 +1936,19 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol, if (dlsch1_harq) { switch (dlsch[1].dlsch_config.qamModOrder) { case 2 : - nr_dlsch_qpsk_llr(frame_parms, rxdataF_comp[0][0], layer_llr[0] + llr_offset_symbol, symbol, len, first_symbol_flag, nb_rb); + nr_qpsk_llr(&rxdataF_comp[0][0][symbol * nb_rb * 12], layer_llr[0] + llr_offset_symbol, len); break; case 4: - nr_dlsch_16qam_llr(frame_parms, rxdataF_comp[0][0], layer_llr[0] + llr_offset_symbol, dl_ch_mag, symbol, len, first_symbol_flag, nb_rb); + nr_16qam_llr(&rxdataF_comp[0][0][symbol * nb_rb * 12], dl_ch_mag, layer_llr[0] + llr_offset_symbol, len); break; case 6 : - nr_dlsch_64qam_llr(frame_parms, rxdataF_comp[0][0], layer_llr[0] + llr_offset_symbol, dl_ch_mag, dl_ch_magb, symbol, len, first_symbol_flag, nb_rb); + nr_64qam_llr(&rxdataF_comp[0][0][symbol * nb_rb * 12], dl_ch_mag, dl_ch_magb, layer_llr[0] + llr_offset_symbol, len); break; case 8 : - nr_dlsch_256qam_llr(frame_parms, rxdataF_comp[0][0], layer_llr[0] + llr_offset_symbol, dl_ch_mag, dl_ch_magb, dl_ch_magr, symbol, len, first_symbol_flag, nb_rb); + nr_256qam_llr(&rxdataF_comp[0][0][symbol * nb_rb * 12], dl_ch_mag, dl_ch_magb, dl_ch_magr, layer_llr[0] + llr_offset_symbol, len); break; default: diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c deleted file mode 100644 index 3a67306905..0000000000 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c - * \brief Top-level routines for LLR computation of the PDSCH physical channel - * \author H. WANG - * \date 2018 - * \version 0.1 - * \company Eurecom - * \email: - * \note - * \warning - */ - -#include "PHY/defs_nr_UE.h" -#include "PHY/phy_extern_nr_ue.h" -#include "nr_transport_proto_ue.h" -#include "PHY/TOOLS/tools_defs.h" -#include "PHY/sse_intrin.h" - -#ifdef __aarch64__ -#define USE_128BIT -#endif - -//#define DEBUG_LLR_SIC - -//============================================================================================== -// SINGLE-STREAM -//============================================================================================== - -//---------------------------------------------------------------------------------------------- -// QPSK -//---------------------------------------------------------------------------------------------- - -int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t *rxdataF_comp, - int16_t *dlsch_llr, - uint8_t symbol, - uint32_t len, - uint8_t first_symbol_flag, - uint16_t nb_rb) -{ - - c16_t *rxF = (c16_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)]; - c16_t *llr32 = (c16_t *)dlsch_llr; - int i; - - if (!llr32) { - LOG_E(PHY,"nr_dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32); - return(-1); - } - - /* - LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n", - symbol, - len, - dlsch_llr, - llr32); - */ - for (i=0; ir = rxF->r >> 3; - llr32->i = rxF->i >> 3; - LOG_D(PHY,"dlsch_qpsk_llr %d : (%d,%d)\n", i, llr32->r, llr32->i); - rxF++; - llr32++; - } - return(0); -} - - -//---------------------------------------------------------------------------------------------- -// 16-QAM -//---------------------------------------------------------------------------------------------- - -void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t *rxdataF_comp, - int16_t *dlsch_llr, - int32_t *dl_ch_mag, - uint8_t symbol, - uint32_t len, - uint8_t first_symbol_flag, - uint16_t nb_rb) -{ - - simde__m128i *rxF = (simde__m128i*)&rxdataF_comp[(symbol*nb_rb*12)]; - simde__m128i *ch_mag; - simde__m128i llr128[2]; - uint32_t *llr32; - - - int i; - unsigned char len_mod4=0; - - - llr32 = (uint32_t*)dlsch_llr; - ch_mag = (simde__m128i *)dl_ch_mag; - - - // printf("len=%d\n", len); - len_mod4 = len&3; - // printf("len_mod4=%d\n", len_mod4); - len>>=2; // length in quad words (4 REs) - // printf("len>>=2=%d\n", len); - len+=(len_mod4==0 ? 0 : 1); - // printf("len+=%d\n", len); - for (i=0; i>2; // length in quad words (4 REs) - len2+=((len_mod4==0)?0:1); - - for (i=0; i>2; // length in quad words (4 REs) - len2+=((len_mod4==0)?0:1); - - for (i=0; i Date: Tue, 20 Aug 2024 17:24:56 +0200 Subject: [PATCH 4/6] adapt LLR unit test to a generic UL/DL scenario --- openair1/PHY/NR_TRANSPORT/tests/test_llr.cpp | 265 +++++++++---------- openair1/PHY/nr_phy_common/CMakeLists.txt | 2 +- 2 files changed, 124 insertions(+), 143 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/tests/test_llr.cpp b/openair1/PHY/NR_TRANSPORT/tests/test_llr.cpp index 5778bd6c39..bd0c95d2ae 100644 --- a/openair1/PHY/NR_TRANSPORT/tests/test_llr.cpp +++ b/openair1/PHY/NR_TRANSPORT/tests/test_llr.cpp @@ -25,20 +25,9 @@ #include #include extern "C" { -void nr_ulsch_16qam_llr(int32_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsch_llr, uint32_t nb_re, uint8_t symbol); -void nr_ulsch_64qam_llr(int32_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol); -void nr_ulsch_256qam_llr(int32_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int32_t *ul_ch_magc, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol); +void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re); +void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re); +void nr_256qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int32_t *ch_mag3, int16_t *llr, uint32_t nb_re); struct configmodule_interface_s; struct configmodule_interface_s *uniqCfg = NULL; @@ -72,74 +61,72 @@ int16_t saturating_sub(int16_t a, int16_t b) } } -void nr_ulsch_16qam_llr_ref(c16_t *rxdataF_comp, int32_t *ul_ch_mag, int16_t *ulsch_llr, uint32_t nb_re, uint8_t symbol) +void nr_16qam_llr_ref(c16_t *rxdataF_comp, int32_t *ch_mag, int16_t *llr, uint32_t nb_re) { - int16_t *ul_ch_mag_i16 = (int16_t *)ul_ch_mag; + int16_t *ch_mag_i16 = (int16_t *)ch_mag; for (auto i = 0U; i < nb_re; i++) { int16_t real = rxdataF_comp[i].r; int16_t imag = rxdataF_comp[i].i; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; - ulsch_llr[4 * i] = real; - ulsch_llr[4 * i + 1] = imag; - ulsch_llr[4 * i + 2] = saturating_sub(mag_real, std::abs(real)); - ulsch_llr[4 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr[4 * i] = real; + llr[4 * i + 1] = imag; + llr[4 * i + 2] = saturating_sub(mag_real, std::abs(real)); + llr[4 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); } } -void nr_ulsch_64qam_llr_ref(c16_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol) +void nr_64qam_llr_ref(c16_t *rxdataF_comp, + int32_t *ch_mag, + int32_t *ch_magb, + int16_t *llr, + uint32_t nb_re) { - int16_t *ul_ch_mag_i16 = (int16_t *)ul_ch_mag; - int16_t *ul_ch_magb_i16 = (int16_t *)ul_ch_magb; + int16_t *ch_mag_i16 = (int16_t *)ch_mag; + int16_t *ch_magb_i16 = (int16_t *)ch_magb; for (auto i = 0U; i < nb_re; i++) { int16_t real = rxdataF_comp[i].r; int16_t imag = rxdataF_comp[i].i; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; - ulsch_llr[6 * i] = real; - ulsch_llr[6 * i + 1] = imag; - ulsch_llr[6 * i + 2] = saturating_sub(mag_real, std::abs(real)); - ulsch_llr[6 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); - int16_t mag_realb = ul_ch_magb_i16[2 * i]; - int16_t mag_imagb = ul_ch_magb_i16[2 * i + 1]; - ulsch_llr[6 * i + 4] = saturating_sub(mag_realb, std::abs(ulsch_llr[6 * i + 2])); - ulsch_llr[6 * i + 5] = saturating_sub(mag_imagb, std::abs(ulsch_llr[6 * i + 3])); + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr[6 * i] = real; + llr[6 * i + 1] = imag; + llr[6 * i + 2] = saturating_sub(mag_real, std::abs(real)); + llr[6 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); + int16_t mag_realb = ch_magb_i16[2 * i]; + int16_t mag_imagb = ch_magb_i16[2 * i + 1]; + llr[6 * i + 4] = saturating_sub(mag_realb, std::abs(llr[6 * i + 2])); + llr[6 * i + 5] = saturating_sub(mag_imagb, std::abs(llr[6 * i + 3])); } } -void nr_ulsch_256qam_llr_ref(c16_t *rxdataF_comp, - int32_t *ul_ch_mag, - int32_t *ul_ch_magb, - int32_t *ul_ch_magc, - int16_t *ulsch_llr, - uint32_t nb_re, - uint8_t symbol) +void nr_256qam_llr_ref(c16_t *rxdataF_comp, + int32_t *ch_mag, + int32_t *ch_magb, + int32_t *ch_magc, + int16_t *llr, + uint32_t nb_re) { - int16_t *ul_ch_mag_i16 = (int16_t *)ul_ch_mag; - int16_t *ul_ch_magb_i16 = (int16_t *)ul_ch_magb; - int16_t *ul_ch_magc_i16 = (int16_t *)ul_ch_magc; + int16_t *ch_mag_i16 = (int16_t *)ch_mag; + int16_t *ch_magb_i16 = (int16_t *)ch_magb; + int16_t *ch_magc_i16 = (int16_t *)ch_magc; for (auto i = 0U; i < nb_re; i++) { int16_t real = rxdataF_comp[i].r; int16_t imag = rxdataF_comp[i].i; - int16_t mag_real = ul_ch_mag_i16[2 * i]; - int16_t mag_imag = ul_ch_mag_i16[2 * i + 1]; - ulsch_llr[8 * i] = real; - ulsch_llr[8 * i + 1] = imag; - ulsch_llr[8 * i + 2] = saturating_sub(mag_real, std::abs(real)); - ulsch_llr[8 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); - int16_t magb_real = ul_ch_magb_i16[2 * i]; - int16_t magb_imag = ul_ch_magb_i16[2 * i + 1]; - ulsch_llr[8 * i + 4] = saturating_sub(magb_real, std::abs(ulsch_llr[8 * i + 2])); - ulsch_llr[8 * i + 5] = saturating_sub(magb_imag, std::abs(ulsch_llr[8 * i + 3])); - int16_t magc_real = ul_ch_magc_i16[2 * i]; - int16_t magc_imag = ul_ch_magc_i16[2 * i + 1]; - ulsch_llr[8 * i + 6] = saturating_sub(magc_real, std::abs(ulsch_llr[8 * i + 4])); - ulsch_llr[8 * i + 7] = saturating_sub(magc_imag, std::abs(ulsch_llr[8 * i + 5])); + int16_t mag_real = ch_mag_i16[2 * i]; + int16_t mag_imag = ch_mag_i16[2 * i + 1]; + llr[8 * i] = real; + llr[8 * i + 1] = imag; + llr[8 * i + 2] = saturating_sub(mag_real, std::abs(real)); + llr[8 * i + 3] = saturating_sub(mag_imag, std::abs(imag)); + int16_t magb_real = ch_magb_i16[2 * i]; + int16_t magb_imag = ch_magb_i16[2 * i + 1]; + llr[8 * i + 4] = saturating_sub(magb_real, std::abs(llr[8 * i + 2])); + llr[8 * i + 5] = saturating_sub(magb_imag, std::abs(llr[8 * i + 3])); + int16_t magc_real = ch_magc_i16[2 * i]; + int16_t magc_imag = ch_magc_i16[2 * i + 1]; + llr[8 * i + 6] = saturating_sub(magc_real, std::abs(llr[8 * i + 4])); + llr[8 * i + 7] = saturating_sub(magc_imag, std::abs(llr[8 * i + 5])); } } @@ -149,21 +136,21 @@ void test_function_16_qam(AlignedVector512 nb_res) uint32_t nb_re = nb_res[i]; auto rf_data = generate_random_c16(nb_re); auto magnitude_data = generate_random_uint16(nb_re * 2); - AlignedVector512 ulsch_llr_ref; - ulsch_llr_ref.resize(nb_re); - std::fill(ulsch_llr_ref.begin(), ulsch_llr_ref.end(), 0); - nr_ulsch_16qam_llr_ref((c16_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int16_t *)ulsch_llr_ref.data(), nb_re, 0); + AlignedVector512 llr_ref; + llr_ref.resize(nb_re); + std::fill(llr_ref.begin(), llr_ref.end(), 0); + nr_16qam_llr_ref((c16_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int16_t *)llr_ref.data(), nb_re); - AlignedVector512 ulsch_llr; - ulsch_llr.resize(nb_re); - std::fill(ulsch_llr.begin(), ulsch_llr.end(), 0); - nr_ulsch_16qam_llr((int32_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int16_t *)ulsch_llr.data(), nb_re, 0); + AlignedVector512 llr; + llr.resize(nb_re); + std::fill(llr.begin(), llr.end(), 0); + nr_16qam_llr((int32_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int16_t *)llr.data(), nb_re); int num_errors = 0; for (auto i = 0U; i < nb_re; i++) { - EXPECT_EQ(ulsch_llr_ref[i], ulsch_llr[i]) - << "Mismatch 16qam REF " << std::hex << ulsch_llr_ref[i] << " != DUT " << ulsch_llr[i] << " at " << std::dec << i; - if (ulsch_llr_ref[i] != ulsch_llr[i]) { + EXPECT_EQ(llr_ref[i], llr[i]) + << "Mismatch 16qam REF " << std::hex << llr_ref[i] << " != DUT " << llr[i] << " at " << std::dec << i; + if (llr_ref[i] != llr[i]) { num_errors++; } } @@ -178,31 +165,29 @@ void test_function_64_qam(AlignedVector512 nb_res) auto rf_data = generate_random_c16(nb_re); auto magnitude_data = generate_random_uint16(nb_re * 2); auto magnitude_b_data = generate_random_uint16(nb_re * 2); - AlignedVector512 ulsch_llr_ref; - ulsch_llr_ref.resize(nb_re * 3); - std::fill(ulsch_llr_ref.begin(), ulsch_llr_ref.end(), 0); - nr_ulsch_64qam_llr_ref((c16_t *)rf_data.data(), + AlignedVector512 llr_ref; + llr_ref.resize(nb_re * 3); + std::fill(llr_ref.begin(), llr_ref.end(), 0); + nr_64qam_llr_ref((c16_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), - (int16_t *)ulsch_llr_ref.data(), - nb_re, - 0); + (int16_t *)llr_ref.data(), + nb_re); - AlignedVector512 ulsch_llr; - ulsch_llr.resize(nb_re * 3); - std::fill(ulsch_llr.begin(), ulsch_llr.end(), 0); - nr_ulsch_64qam_llr((int32_t *)rf_data.data(), + AlignedVector512 llr; + llr.resize(nb_re * 3); + std::fill(llr.begin(), llr.end(), 0); + nr_64qam_llr((int32_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), - (int16_t *)ulsch_llr.data(), - nb_re, - 0); + (int16_t *)llr.data(), + nb_re); int num_errors = 0; for (auto i = 0U; i < nb_re * 3; i++) { - EXPECT_EQ(ulsch_llr_ref[i], ulsch_llr[i]) - << "Mismatch 64qam REF " << std::hex << ulsch_llr_ref[i] << " != DUT " << ulsch_llr[i] << " at " << std::dec << i; - if (ulsch_llr_ref[i] != ulsch_llr[i]) { + EXPECT_EQ(llr_ref[i], llr[i]) + << "Mismatch 64qam REF " << std::hex << llr_ref[i] << " != DUT " << llr[i] << " at " << std::dec << i; + if (llr_ref[i] != llr[i]) { num_errors++; } } @@ -218,33 +203,31 @@ void test_function_256_qam(AlignedVector512 nb_res) auto magnitude_data = generate_random_uint16(nb_re * 2); auto magnitude_b_data = generate_random_uint16(nb_re * 2); auto magnitude_c_data = generate_random_uint16(nb_re * 2); - AlignedVector512 ulsch_llr_ref; - ulsch_llr_ref.resize(nb_re * 4); - std::fill(ulsch_llr_ref.begin(), ulsch_llr_ref.end(), 0); - nr_ulsch_256qam_llr_ref((c16_t *)rf_data.data(), + AlignedVector512 llr_ref; + llr_ref.resize(nb_re * 4); + std::fill(llr_ref.begin(), llr_ref.end(), 0); + nr_256qam_llr_ref((c16_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), (int32_t *)magnitude_c_data.data(), - (int16_t *)ulsch_llr_ref.data(), - nb_re, - 0); + (int16_t *)llr_ref.data(), + nb_re); - AlignedVector512 ulsch_llr; - ulsch_llr.resize(nb_re * 4); - std::fill(ulsch_llr.begin(), ulsch_llr.end(), 0); - nr_ulsch_256qam_llr((int32_t *)rf_data.data(), + AlignedVector512 llr; + llr.resize(nb_re * 4); + std::fill(llr.begin(), llr.end(), 0); + nr_256qam_llr((int32_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), (int32_t *)magnitude_c_data.data(), - (int16_t *)ulsch_llr.data(), - nb_re, - 0); + (int16_t *)llr.data(), + nb_re); int num_errors = 0; for (auto i = 0U; i < nb_re * 4; i++) { - EXPECT_EQ(ulsch_llr_ref[i], ulsch_llr[i]) - << "Mismatch 256qam REF " << std::hex << ulsch_llr_ref[i] << " != DUT " << ulsch_llr[i] << " at " << std::dec << i; - if (ulsch_llr_ref[i] != ulsch_llr[i]) { + EXPECT_EQ(llr_ref[i], llr[i]) + << "Mismatch 256qam REF " << std::hex << llr_ref[i] << " != DUT " << llr[i] << " at " << std::dec << i; + if (llr_ref[i] != llr[i]) { num_errors++; } } @@ -370,59 +353,57 @@ TEST(test_llr, check_2_res_256_qam) AlignedVector512 magnitude_data = {1, 1, 1, 1}; AlignedVector512 magnitude_b_data = {2, 2, 2, 2}; AlignedVector512 magnitude_c_data = {3, 3, 3, 3}; - AlignedVector512 ulsch_llr_ref; - ulsch_llr_ref.resize(2 * 8); - std::fill(ulsch_llr_ref.begin(), ulsch_llr_ref.end(), 0); - nr_ulsch_256qam_llr_ref((c16_t *)rf_data.data(), + AlignedVector512 llr_ref; + llr_ref.resize(2 * 8); + std::fill(llr_ref.begin(), llr_ref.end(), 0); + nr_256qam_llr_ref((c16_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), (int32_t *)magnitude_c_data.data(), - (int16_t *)ulsch_llr_ref.data(), - 2, - 0); + (int16_t *)llr_ref.data(), + 2); - AlignedVector512 ulsch_llr; - ulsch_llr.resize(2 * 8); - std::fill(ulsch_llr.begin(), ulsch_llr.end(), 0); - nr_ulsch_256qam_llr((int32_t *)rf_data.data(), + AlignedVector512 llr; + llr.resize(2 * 8); + std::fill(llr.begin(), llr.end(), 0); + nr_256qam_llr((int32_t *)rf_data.data(), (int32_t *)magnitude_data.data(), (int32_t *)magnitude_b_data.data(), (int32_t *)magnitude_c_data.data(), - (int16_t *)ulsch_llr.data(), - 2, - 0); + (int16_t *)llr.data(), + 2); printf("\nDUT:\n"); for (auto i = 0U; i < 2; i++) { printf("%d %d %d %d %d %d %d %d\n", - ulsch_llr[i * 8], - ulsch_llr[i * 8 + 1], - ulsch_llr[i * 8 + 2], - ulsch_llr[i * 8 + 3], - ulsch_llr[i * 8 + 4], - ulsch_llr[i * 8 + 5], - ulsch_llr[i * 8 + 6], - ulsch_llr[i * 8 + 7]); + llr[i * 8], + llr[i * 8 + 1], + llr[i * 8 + 2], + llr[i * 8 + 3], + llr[i * 8 + 4], + llr[i * 8 + 5], + llr[i * 8 + 6], + llr[i * 8 + 7]); } printf("\nREF:\n"); for (auto i = 0U; i < 2; i++) { printf("%d %d %d %d %d %d %d %d\n", - ulsch_llr_ref[i * 8], - ulsch_llr_ref[i * 8 + 1], - ulsch_llr_ref[i * 8 + 2], - ulsch_llr_ref[i * 8 + 3], - ulsch_llr_ref[i * 8 + 4], - ulsch_llr_ref[i * 8 + 5], - ulsch_llr_ref[i * 8 + 6], - ulsch_llr_ref[i * 8 + 7]); + llr_ref[i * 8], + llr_ref[i * 8 + 1], + llr_ref[i * 8 + 2], + llr_ref[i * 8 + 3], + llr_ref[i * 8 + 4], + llr_ref[i * 8 + 5], + llr_ref[i * 8 + 6], + llr_ref[i * 8 + 7]); } int num_errors = 0; for (auto i = 0U; i < 2 * 8; i++) { - EXPECT_EQ(ulsch_llr_ref[i], ulsch_llr[i]) - << "Mismatch 256qam REF " << std::hex << ulsch_llr_ref[i] << " != DUT " << ulsch_llr[i] << " at " << std::dec << i; - if (ulsch_llr_ref[i] != ulsch_llr[i]) { + EXPECT_EQ(llr_ref[i], llr[i]) + << "Mismatch 256qam REF " << std::hex << llr_ref[i] << " != DUT " << llr[i] << " at " << std::dec << i; + if (llr_ref[i] != llr[i]) { num_errors++; } } diff --git a/openair1/PHY/nr_phy_common/CMakeLists.txt b/openair1/PHY/nr_phy_common/CMakeLists.txt index ebbc3fcbc7..ee5fb820a8 100644 --- a/openair1/PHY/nr_phy_common/CMakeLists.txt +++ b/openair1/PHY/nr_phy_common/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(nr_phy_common src/nr_phy_common.c) -target_link_libraries(nr_phy_common PRIVATE UTIL) +target_link_libraries(nr_phy_common PRIVATE UTIL PHY_COMMON) target_include_directories(nr_phy_common PUBLIC inc/) add_library(nr_ue_phy_meas src/nr_ue_phy_meas.c) From 299137016903fd4cb0323476baae2e2836b4fd34 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 25 Aug 2024 09:34:15 +0200 Subject: [PATCH 5/6] 32byte aligned DLSCH RX symbol size --- .../nr_dl_channel_estimation.c | 12 +-- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 98 +++++++++---------- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- 3 files changed, 51 insertions(+), 61 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index d10f5b5b42..53c302e789 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1633,7 +1633,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, nr_slot_rx, symbol, frame_parms->ofdm_symbol_size, - (int16_t *)(rxdataF_comp[0][aarx] + symbol * nb_re_pdsch), + (int16_t *)(rxdataF_comp[0][aarx] + symbol * rx_size_symbol), gold, (int16_t *)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); @@ -1654,21 +1654,21 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } #ifdef DEBUG_DL_PTRS LOG_M("ptrsEst.m","est",ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); - LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + (*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb), (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb), 1, 1); + LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + (*startSymbIndex) * rx_size_symbol, rx_size_symbol * (*nbSymb), 1, 1); #endif /*------------------------------------------------------------------------------------------------------- */ /* 3) Compensated DMRS based estimated signal with PTRS estimation */ /*--------------------------------------------------------------------------------------------------------*/ - for(uint8_t i = *startSymbIndex; i< symbInSlot ;i++) { + for(uint8_t i = *startSymbIndex; i < symbInSlot; i++) { /* DMRS Symbol has 0 phase so no need to rotate the respective symbol */ /* Skip rotation if the slot processing is wrong */ - if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { + if((!is_dmrs_symbol(i, *dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_DL_PTRS printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((c16_t *)&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t *)&rxdataF_comp[0][aarx][i * rx_size_symbol], &phase_per_symbol[i], - (c16_t *)&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + (c16_t *)&rxdataF_comp[0][aarx][i * rx_size_symbol], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 3482d2a80a..05e8986ba5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -116,7 +116,6 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol, unsigned char harq_pid, unsigned char first_symbol_flag, unsigned char symbol, - unsigned short nb_rb, int32_t codeword_TB0, int32_t codeword_TB1, uint32_t len, @@ -221,17 +220,16 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol, uint8_t pilots, uint32_t len, unsigned short nb_rb); -void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, - short n_tx, - short n_rx, - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - int32_t dl_ch_mag[][n_rx][rx_size_symbol], - int32_t dl_ch_magb[][n_rx][rx_size_symbol], - int32_t dl_ch_magr[][n_rx][rx_size_symbol], - unsigned char symbol, - unsigned short nb_rb, - int length); +static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, + short n_tx, + short n_rx, + int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int ***rho, + int32_t dl_ch_mag[][n_rx][rx_size_symbol], + int32_t dl_ch_magb[][n_rx][rx_size_symbol], + int32_t dl_ch_magr[][n_rx][rx_size_symbol], + unsigned char symbol, + int length); static bool overlap_csi_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu, int symbol) { @@ -596,7 +594,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_magb, dl_ch_magr, symbol, - nb_rb_pdsch, nb_re_pdsch); if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers nr_dlsch_mmse(rx_size_symbol, @@ -691,7 +688,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, harq_pid, first_symbol_flag, i, - nb_rb_pdsch, codeword_TB0, codeword_TB1, dl_valid_re[i - 1], @@ -877,15 +873,13 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, QAM_amp128r = simde_mm_set1_epi16(QAM256_n3); } - // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); - for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx]; dl_ch_mag128 = (simde__m128i *)dl_ch_mag[l][aarx]; dl_ch_mag128b = (simde__m128i *)dl_ch_magb[l][aarx]; dl_ch_mag128r = (simde__m128i *)dl_ch_magr[l][aarx]; rxdataF128 = (simde__m128i *)rxdataF_ext[aarx]; - rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * nb_rb * 12); + rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * rx_size_symbol); for (int rb = 0; rb < nb_rb_0; rb++) { if (mod_order > 2) { @@ -1260,37 +1254,34 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, } } -void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, - short n_tx, - short n_rx, - int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int ***rho, - int32_t dl_ch_mag[][n_rx][rx_size_symbol], - int32_t dl_ch_magb[][n_rx][rx_size_symbol], - int32_t dl_ch_magr[][n_rx][rx_size_symbol], - unsigned char symbol, - unsigned short nb_rb, - int length) { - unsigned char aatx, aarx; - int i; +static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol, + short n_tx, + short n_rx, + int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int ***rho, + int32_t dl_ch_mag[][n_rx][rx_size_symbol], + int32_t dl_ch_magb[][n_rx][rx_size_symbol], + int32_t dl_ch_magr[][n_rx][rx_size_symbol], + unsigned char symbol, + int length) +{ simde__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r; - uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); - if (n_rx>1) { - for (aatx=0; aatx 1) { + for (int aatx = 0; aatx < n_tx; aatx++) { + rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[aatx][0] + symbol * rx_size_symbol); dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[aatx][0]; dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[aatx][0]; dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[aatx][0]; - for (aarx=1; aarxframe_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; 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; + 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)); From db098651b0662f78b08e05ef78aeda6a36b1f9c4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 25 Aug 2024 11:24:36 +0200 Subject: [PATCH 6/6] improvements in nr_dlsch_llr function --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 108 +++++++----------- 1 file changed, 39 insertions(+), 69 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 05e8986ba5..6e17495925 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -102,26 +102,20 @@ static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], int16_t llr_layers[][sz]); /* compute LLR */ -static int nr_dlsch_llr(uint32_t rx_size_symbol, - int nbRx, - uint sz, - int16_t layer_llr[][sz], - NR_DL_FRAME_PARMS *frame_parms, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int32_t dl_ch_mag[rx_size_symbol], - int32_t dl_ch_magb[rx_size_symbol], - int32_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, - NR_DL_UE_HARQ_t *dlsch1_harq, - unsigned char harq_pid, - unsigned char first_symbol_flag, - unsigned char symbol, - int32_t codeword_TB0, - int32_t codeword_TB1, - uint32_t len, - uint8_t nr_slot_rx, - NR_UE_DLSCH_t dlsch[2], - uint32_t llr_offset[NR_SYMBOLS_PER_SLOT]); +static void nr_dlsch_llr(uint32_t rx_size_symbol, + int nbRx, + uint sz, + int16_t layer_llr[][sz], + int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int32_t dl_ch_mag[rx_size_symbol], + int32_t dl_ch_magb[rx_size_symbol], + int32_t dl_ch_magr[rx_size_symbol], + NR_DL_UE_HARQ_t *dlsch0_harq, + NR_DL_UE_HARQ_t *dlsch1_harq, + unsigned char symbol, + uint32_t len, + NR_UE_DLSCH_t dlsch[2], + uint32_t llr_offset_symbol); /** \fn nr_dlsch_extract_rbs \brief This function extracts the received resource blocks, both channel estimates and data symbols, for the current @@ -626,7 +620,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, /* Store the valid DL RE's */ - dl_valid_re[symbol-1] = nb_re_pdsch; + dl_valid_re[symbol] = nb_re_pdsch; int startSymbIdx = 0; int nbSymb = 0; int pduBitmap = 0; @@ -654,10 +648,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, (nb_rb_pdsch * 12), dlsch[0].rnti, dlsch); - dl_valid_re[symbol - 1] -= ptrs_re_per_slot[0][symbol]; + dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol]; } /* at last symbol in a slot calculate LLR's for whole slot */ - if(symbol == (startSymbIdx + nbSymb -1)) { + if(symbol == (startSymbIdx + nbSymb - 1)) { const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl; if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) { @@ -666,41 +660,32 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size]; - for(int i = startSymbIdx; i < startSymbIdx+nbSymb; i++) { - /* re evaluating the first symbol flag as LLR's are done in symbol loop */ - if(i == startSymbIdx && i < 3) - first_symbol_flag = 1; - else - first_symbol_flag = 0; + for(int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) { /* Calculate LLR's for each symbol */ start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); nr_dlsch_llr(rx_size_symbol, nbRx, rx_llr_layer_size, layer_llr, - frame_parms, rxdataF_comp, dl_ch_mag[0][0], dl_ch_magb[0][0], dl_ch_magr[0][0], dlsch0_harq, dlsch1_harq, - harq_pid, - first_symbol_flag, i, - codeword_TB0, - codeword_TB1, - dl_valid_re[i - 1], - nr_slot_rx, + dl_valid_re[i], dlsch, - llr_offset); + llr_offset[i]); + if (i < startSymbIdx + nbSymb - 1) // up to the penultimate symbol + llr_offset[i + 1] = dl_valid_re[i] * dlsch_config->qamModOrder + llr_offset[i]; stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS); } start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING); nr_dlsch_layer_demapping(llr, dlsch[0].Nl, - dlsch[0].dlsch_config.qamModOrder, + dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, @@ -1868,33 +1853,21 @@ static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], } } -static int nr_dlsch_llr(uint32_t rx_size_symbol, - int nbRx, - uint sz, - int16_t layer_llr[][sz], - NR_DL_FRAME_PARMS *frame_parms, - int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], - int32_t dl_ch_mag[rx_size_symbol], - int32_t dl_ch_magb[rx_size_symbol], - int32_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, - NR_DL_UE_HARQ_t *dlsch1_harq, - unsigned char harq_pid, - unsigned char first_symbol_flag, - unsigned char symbol, - int32_t codeword_TB0, - int32_t codeword_TB1, - uint32_t len, - uint8_t nr_slot_rx, - NR_UE_DLSCH_t dlsch[2], - uint32_t llr_offset[14]) +static void nr_dlsch_llr(uint32_t rx_size_symbol, + int nbRx, + uint sz, + int16_t layer_llr[][sz], + int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT], + int32_t dl_ch_mag[rx_size_symbol], + int32_t dl_ch_magb[rx_size_symbol], + int32_t dl_ch_magr[rx_size_symbol], + NR_DL_UE_HARQ_t *dlsch0_harq, + NR_DL_UE_HARQ_t *dlsch1_harq, + unsigned char symbol, + uint32_t len, + NR_UE_DLSCH_t dlsch[2], + uint32_t llr_offset_symbol) { - if (first_symbol_flag == 1) - llr_offset[symbol - 1] = 0; - uint32_t llr_offset_symbol = llr_offset[symbol - 1]; - - llr_offset[symbol] = len * dlsch[0].dlsch_config.qamModOrder + llr_offset_symbol; - switch (dlsch[0].dlsch_config.qamModOrder) { case 2 : for(int l = 0; l < dlsch[0].Nl; l++) @@ -1917,8 +1890,7 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol, break; default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); + AssertFatal(false, "Unknown mod_order!!!!\n"); break; } @@ -1942,11 +1914,9 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol, break; default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); + AssertFatal(false, "Unknown mod_order!!!!\n"); break; } } - return 0; } //==============================================================================================