Commit 1b77adcb authored by Rupanjali's avatar Rupanjali

Segregate the LLR and channel compensation related common functions into different files

Signed-off-by: default avatarRupanjali <rupanjali.srivastava@openairinterface.org>
parent 7db4dfec
# SPDX-License-Identifier: LicenseRef-CSSL-1.0 # SPDX-License-Identifier: LicenseRef-CSSL-1.0
add_library(nr_phy_common src/nr_phy_common.c) add_library(nr_phy_common src/nr_phy_common.c
src/nr_channel_compensation.c
src/nr_compute_llr.c)
target_link_libraries(nr_phy_common PRIVATE UTIL PHY_COMMON) target_link_libraries(nr_phy_common PRIVATE UTIL PHY_COMMON)
target_include_directories(nr_phy_common PUBLIC inc/) target_include_directories(nr_phy_common PUBLIC inc/)
......
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef __NR_CHANNEL_COMPENSATION__H__
#define __NR_CHANNEL_COMPENSATION__H__
#include "PHY/impl_defs_top.h"
/**
* @brief Common channel compensation function shared by DL (PDSCH) and UL (PUSCH) paths.
*
* Computes matched-filter output (rxComp) and channel magnitude arrays used for LLR
* computation. MRC across Rx antennas is performed inline: for each layer, contributions
* from all Rx antennas are accumulated into rxComp[layer * nb_rx_ant][symbol * buffer_length].
* Uses AVX2 (256-bit SIMD) for throughput.
*
* @param buffer_length Number of complex samples per symbol (must be a multiple of 8)
* @param nb_rx_ant Number of Rx antennas
* @param nb_layers Number of spatial layers
* @param rxFext Extracted received signal [nb_rx_ant][buffer_length]
* @param chFext Extracted channel estimates [nb_layers][nb_rx_ant][buffer_length]
* @param ch_maga Output magnitude array for threshold 'a' [nb_layers][buffer_length]
* @param ch_magb Output magnitude array for threshold 'b' [nb_layers][buffer_length]
* @param ch_magc Output magnitude array for threshold 'c' [nb_layers][buffer_length]
* @param rxComp Output compensated signal; row [l * nb_rx_ant] holds the MRC result
* for layer l at offset [symbol * buffer_length]
* @param rho Tx-correlation matrix [nb_layers][nb_layers][buffer_length], or NULL
* @param mod_order Modulation order (2=QPSK, 4=16QAM, 6=64QAM, 8=256QAM)
* @param symbol OFDM symbol index (used to compute offset into rxComp rows)
* @param output_shift Right-shift applied after each complex multiply
*/
void nr_channel_compensation(uint32_t buffer_length,
int nb_rx_ant,
int nb_layers,
c16_t rxFext[nb_rx_ant][buffer_length],
c16_t chFext[nb_layers][nb_rx_ant][buffer_length],
c16_t ch_maga[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t **rxComp,
c16_t (*rho)[nb_layers][buffer_length],
int mod_order,
uint32_t symbol,
uint32_t output_shift);
#endif /* __NR_CHANNEL_COMPENSATION__H__ */
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef __NR_COMPUTE_LLR__H__
#define __NR_COMPUTE_LLR__H__
#include "PHY/impl_defs_top.h"
void nr_compute_llr(c16_t *rxdataF_comp,
c16_t *ch_mag,
c16_t *ch_magb,
c16_t *ch_magc,
int16_t *llr,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order);
void nr_qpsk_llr_2layer(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_out, c16_t *rho01, uint32_t length);
void nr_qam16_llr_2layer(c16_t *stream0_in,
c16_t *stream1_in,
c16_t *ch_mag,
c16_t *ch_mag_i,
int16_t *stream0_out,
c16_t *rho01,
uint32_t length);
void nr_qam64_llr_2layer(c16_t *stream0_in,
c16_t *stream1_in,
c16_t *ch_mag,
c16_t *ch_mag_i,
int16_t *stream0_out,
c16_t *rho01,
uint32_t length);
void nr_compute_ML_llr(c16_t *rxdataF_comp0,
c16_t *rxdataF_comp1,
c16_t *ch_mag0,
c16_t *ch_mag1,
int16_t *llr_layers0,
int16_t *llr_layers1,
c16_t *rho0,
c16_t *rho1,
uint32_t nb_re,
uint8_t mod_order);
uint8_t nr_mmse_2layers(c16_t **rxdataF_comp,
uint32_t buffer_length,
int nb_rx_ant,
int nb_layers,
c16_t ch_mag[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ch_estimates_ext[][nb_rx_ant][buffer_length],
unsigned short nb_rb,
unsigned char mod_order,
int shift,
unsigned char symbol,
int length,
uint32_t noise_var);
#endif /* __NR_COMPUTE_LLR__H__ */
...@@ -377,93 +377,6 @@ int nr_get_ssb_start_sc(int scs, ...@@ -377,93 +377,6 @@ int nr_get_ssb_start_sc(int scs,
int ssb_sco, int ssb_sco,
frequency_range_t freq_range); frequency_range_t freq_range);
/** #include "nr_channel_compensation.h"
* @brief Common channel compensation function shared by DL (PDSCH) and UL (PUSCH) paths. #include "nr_compute_llr.h"
*
* Computes matched-filter output (rxComp) and channel magnitude arrays used for LLR
* computation. MRC across Rx antennas is performed inline: for each layer, contributions
* from all Rx antennas are accumulated into rxComp[layer * nb_rx_ant][symbol * buffer_length].
* Uses AVX2 (256-bit SIMD) for throughput.
*
* @param buffer_length Number of complex samples per symbol (must be a multiple of 8)
* @param nb_rx_ant Number of Rx antennas
* @param nb_layers Number of spatial layers
* @param rxFext Extracted received signal [nb_rx_ant][buffer_length]
* @param chFext Extracted channel estimates [nb_layers][nb_rx_ant][buffer_length]
* @param ch_maga Output magnitude array for threshold 'a' [nb_layers][buffer_length]
* @param ch_magb Output magnitude array for threshold 'b' [nb_layers][buffer_length]
* @param ch_magc Output magnitude array for threshold 'c' [nb_layers][buffer_length]
* @param rxComp Output compensated signal; row [l * nb_rx_ant] holds the MRC result
* for layer l at offset [symbol * buffer_length]
* @param rho Tx-correlation matrix [nb_layers][nb_layers][buffer_length], or NULL
* @param mod_order Modulation order (2=QPSK, 4=16QAM, 6=64QAM, 8=256QAM)
* @param symbol OFDM symbol index (used to compute offset into rxComp rows)
* @param output_shift Right-shift applied after each complex multiply
*/
void nr_channel_compensation(uint32_t buffer_length,
int nb_rx_ant,
int nb_layers,
c16_t rxFext[nb_rx_ant][buffer_length],
c16_t chFext[nb_layers][nb_rx_ant][buffer_length],
c16_t ch_maga[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t **rxComp,
c16_t (*rho)[nb_layers][buffer_length],
int mod_order,
uint32_t symbol,
uint32_t output_shift);
void nr_compute_llr(c16_t *rxdataF_comp,
c16_t *ch_mag,
c16_t *ch_magb,
c16_t *ch_magc,
int16_t *llr,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order);
void nr_qpsk_llr_2layer(c16_t *stream0_in, c16_t *stream1_in, int16_t *stream0_out, c16_t *rho01, uint32_t length);
void nr_qam16_llr_2layer(c16_t *stream0_in,
c16_t *stream1_in,
c16_t *ch_mag,
c16_t *ch_mag_i,
int16_t *stream0_out,
c16_t *rho01,
uint32_t length);
void nr_qam64_llr_2layer(c16_t *stream0_in,
c16_t *stream1_in,
c16_t *ch_mag,
c16_t *ch_mag_i,
int16_t *stream0_out,
c16_t *rho01,
uint32_t length);
void nr_compute_ML_llr(c16_t *rxdataF_comp0,
c16_t *rxdataF_comp1,
c16_t *ch_mag0,
c16_t *ch_mag1,
int16_t *llr_layers0,
int16_t *llr_layers1,
c16_t *rho0,
c16_t *rho1,
uint32_t nb_re,
uint8_t mod_order);
uint8_t nr_mmse_2layers(c16_t **rxdataF_comp,
uint32_t buffer_length,
int nb_rx_ant,
int nb_layers,
c16_t ch_mag[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t ul_ch_estimates_ext[][nb_rx_ant][buffer_length],
unsigned short nb_rb,
unsigned char mod_order,
int shift,
unsigned char symbol,
int length,
uint32_t noise_var);
#endif #endif
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "nr_channel_compensation.h"
#include "bits.h"
#include <complex.h>
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
#ifdef __aarch64__
#define USE_128BIT
#endif
void nr_channel_compensation(uint32_t buffer_length,
int nb_rx_ant,
int nb_layers,
c16_t rxFext[nb_rx_ant][buffer_length],
c16_t chFext[nb_layers][nb_rx_ant][buffer_length],
c16_t ch_maga[nb_layers][buffer_length],
c16_t ch_magb[nb_layers][buffer_length],
c16_t ch_magc[nb_layers][buffer_length],
c16_t **rxComp,
c16_t (*rho)[nb_layers][buffer_length],
int mod_order,
uint32_t symbol,
uint32_t output_shift)
{
simde__m256i QAM_ampa_256 = simde_mm256_setzero_si256();
simde__m256i QAM_ampb_256 = simde_mm256_setzero_si256();
simde__m256i QAM_ampc_256 = simde_mm256_setzero_si256();
if (mod_order == 4) {
QAM_ampa_256 = simde_mm256_set1_epi16(QAM16_n1);
} else if (mod_order == 6) {
QAM_ampa_256 = simde_mm256_set1_epi16(QAM64_n1);
QAM_ampb_256 = simde_mm256_set1_epi16(QAM64_n2);
} else if (mod_order == 8) {
QAM_ampa_256 = simde_mm256_set1_epi16(QAM256_n1);
QAM_ampb_256 = simde_mm256_set1_epi16(QAM256_n2);
QAM_ampc_256 = simde_mm256_set1_epi16(QAM256_n3);
}
for (int aatx = 0; aatx < nb_layers; aatx++) {
simde__m256i *rxComp_256 = (simde__m256i *)&rxComp[aatx * nb_rx_ant][symbol * buffer_length];
simde__m256i *ch_maga_256 = (simde__m256i *)ch_maga[aatx];
simde__m256i *ch_magb_256 = (simde__m256i *)ch_magb[aatx];
simde__m256i *ch_magc_256 = (simde__m256i *)ch_magc[aatx];
// First Rx antenna: direct store — eliminates need to pre memset the output buffers
{
simde__m256i *rxF_256 = (simde__m256i *)rxFext[0];
simde__m256i *chF_256 = (simde__m256i *)chFext[aatx][0];
for (uint32_t i = 0; i < buffer_length >> 3; i++) {
rxComp_256[i] = oai_mm256_cpx_mult_conj(chF_256[i], rxF_256[i], output_shift);
if (mod_order > 2) {
simde__m256i mag = oai_mm256_smadd(chF_256[i], chF_256[i], output_shift);
mag = simde_mm256_packs_epi32(mag, mag);
mag = simde_mm256_unpacklo_epi16(mag, mag);
ch_maga_256[i] = simde_mm256_mulhrs_epi16(mag, QAM_ampa_256);
if (mod_order > 4)
ch_magb_256[i] = simde_mm256_mulhrs_epi16(mag, QAM_ampb_256);
if (mod_order > 6)
ch_magc_256[i] = simde_mm256_mulhrs_epi16(mag, QAM_ampc_256);
}
}
if (rho) {
for (int atx = 0; atx < nb_layers; atx++) {
simde__m256i *rho_256 = (simde__m256i *)rho[aatx][atx];
simde__m256i *chF2_256 = (simde__m256i *)chFext[atx][0];
for (uint32_t i = 0; i < buffer_length >> 3; i++)
rho_256[i] = oai_mm256_cpx_mult_conj(chF_256[i], chF2_256[i], output_shift);
}
}
}
// Remaining Rx antennas: accumulate (MRC)
for (int aarx = 1; aarx < nb_rx_ant; aarx++) {
simde__m256i *rxF_256 = (simde__m256i *)rxFext[aarx];
simde__m256i *chF_256 = (simde__m256i *)chFext[aatx][aarx];
for (uint32_t i = 0; i < buffer_length >> 3; i++) {
simde__m256i comp = oai_mm256_cpx_mult_conj(chF_256[i], rxF_256[i], output_shift);
rxComp_256[i] = simde_mm256_add_epi16(rxComp_256[i], comp);
if (mod_order > 2) {
simde__m256i mag = oai_mm256_smadd(chF_256[i], chF_256[i], output_shift);
mag = simde_mm256_packs_epi32(mag, mag);
mag = simde_mm256_unpacklo_epi16(mag, mag);
ch_maga_256[i] = simde_mm256_add_epi16(ch_maga_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampa_256));
if (mod_order > 4)
ch_magb_256[i] = simde_mm256_add_epi16(ch_magb_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampb_256));
if (mod_order > 6)
ch_magc_256[i] = simde_mm256_add_epi16(ch_magc_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampc_256));
}
}
if (rho) {
for (int atx = 0; atx < nb_layers; atx++) {
simde__m256i *rho_256 = (simde__m256i *)rho[aatx][atx];
simde__m256i *chF2_256 = (simde__m256i *)chFext[atx][aarx];
for (uint32_t i = 0; i < buffer_length >> 3; i++)
rho_256[i] = simde_mm256_adds_epi16(rho_256[i], oai_mm256_cpx_mult_conj(chF_256[i], chF2_256[i], output_shift));
}
}
}
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment