Commit 7455bae4 authored by Raymond Knopp's avatar Raymond Knopp Committed by francescomani

added 256QAM LLR computation for ULSCH

parent a0b207fe
......@@ -706,23 +706,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_mag0 = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_magb0 = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_magc0 = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_mag = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_magb = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->ul_ch_magc = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->rho = (int32_t ***)malloc16(Prx * sizeof(int32_t **));
pusch->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers * sizeof(int32_t *));
for (i=0; i<Prx; i++) {
for (i = 0; i < Prx; i++) {
pusch->rxdataF_ext[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->rho[i] = (int32_t **)malloc16_clear(NR_MAX_NB_LAYERS * NR_MAX_NB_LAYERS * sizeof(int32_t *));
for (int j=0; j< max_ul_mimo_layers; j++) {
for (int k=0; k<max_ul_mimo_layers; k++) {
for (int j = 0; j < max_ul_mimo_layers; j++) {
for (int k = 0; k < max_ul_mimo_layers; k++) {
pusch->rho[i][j * max_ul_mimo_layers + k] =
(int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
}
}
}
for (i=0; i<n_buf; i++) {
for (i = 0; i < n_buf; i++) {
pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot);
pusch->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size);
......@@ -730,8 +731,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_mag0[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_magb0[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_magc0[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_mag[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_magb[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
pusch->ul_ch_magc[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
}
for (i=0; i< max_ul_mimo_layers; i++) {
......@@ -867,8 +870,10 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars->rxdataF_comp[i]);
free_and_zero(pusch_vars->ul_ch_mag0[i]);
free_and_zero(pusch_vars->ul_ch_magb0[i]);
free_and_zero(pusch_vars->ul_ch_magc0[i]);
free_and_zero(pusch_vars->ul_ch_mag[i]);
free_and_zero(pusch_vars->ul_ch_magb[i]);
free_and_zero(pusch_vars->ul_ch_magc[i]);
}
free_and_zero(pusch_vars->llr_layers);
free_and_zero(pusch_vars->rxdataF_ext);
......@@ -880,8 +885,10 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars->rxdataF_comp);
free_and_zero(pusch_vars->ul_ch_mag0);
free_and_zero(pusch_vars->ul_ch_magb0);
free_and_zero(pusch_vars->ul_ch_magc0);
free_and_zero(pusch_vars->ul_ch_mag);
free_and_zero(pusch_vars->ul_ch_magb);
free_and_zero(pusch_vars->ul_ch_magc);
free_and_zero(pusch_vars->rho);
free_and_zero(pusch_vars->llr);
......
......@@ -176,8 +176,9 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
@param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
@param ul_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
@param ul_ch_mag First Channel magnitudes (16QAM/64QAM)
@param ul_ch_magb Second weighted Channel magnitudes (64QAM)
@param ul_ch_mag First Channel magnitudes (16QAM/64QAM/256QAM)
@param ul_ch_magb Second weighted Channel magnitudes (64QAM/256QAM)
@param ul_ch_magc Third weighted Channel magnitudes (256QAM)
@param rxdataF_comp Compensated received waveform
@param frame_parms Pointer to frame descriptor
@param symbol Symbol on which to operate
......@@ -189,6 +190,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext,
int **ul_ch_estimates_ext,
int **ul_ch_mag,
int **ul_ch_magb,
int **ul_ch_magc,
int **rxdataF_comp,
int ***rho,
NR_DL_FRAME_PARMS *frame_parms,
......@@ -250,6 +252,23 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
uint32_t nb_re,
uint8_t symbol);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 256 QAM received waveforms.
@param rxdataF_comp Compensated channel output
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 256
@param ul_ch_magb uplink channel magnitude multiplied by the 2bd amplitude threshold in QAM 256
@param ul_ch_magc uplink channel magnitude multiplied by the 3rd amplitude threshold in QAM 256
@param ulsch_llr llr output
@param nb_re number of REs for this allocation
@param symbol OFDM symbol index in sub-frame
*/
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_rb,
uint32_t nb_re,
uint8_t symbol);
/** \brief This function computes the log-likelihood ratios for 4, 16, and 64 QAM
@param rxdataF_comp Compensated channel output
......@@ -263,6 +282,7 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
void nr_ulsch_compute_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_rb,
uint32_t nb_re,
......
......@@ -352,10 +352,118 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
#endif
}
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_rb,
uint32_t nb_re,
uint8_t symbol)
{
int off = ((nb_rb&1) == 1)? 4:0;
simde__m256i *rxF = (simde__m256i*)rxdataF_comp;
simde__m256i *ch_mag,*ch_magb,*ch_magc;
register simde__m256i xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6;
simde__m256i *llr256=(simde__m256i*)ulsch_llr;
ch_mag = (simde__m256i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
ch_magb = (simde__m256i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
ch_magc = (simde__m256i*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
int len_mod8 = nb_re&7;
int nb_re256 = nb_re>>3; // length in 256-bit words (8 REs)
for (int i=0; i<nb_re256; i++) {
xmm0 = simde_mm256_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
xmm0 = simde_mm256_subs_epi16(ch_mag[i],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
// xmmtmpD2 contains 16 LLRs
xmm1 = simde_mm256_abs_epi16(xmm0);
xmm1 = simde_mm256_subs_epi16(ch_magb[i],xmm1); // contains 16 LLRs
xmm2 = simde_mm256_abs_epi16(xmm1);
xmm2 = simde_mm256_subs_epi16(ch_magc[i],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[i],xmm0); // A0 B0 A1 B1 A4 B4 A5 B5
xmm4 = simde_mm256_unpackhi_epi32(rxF[i],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[0] = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x20); // A0 B0 C0 D0 A1 B1 C1 D1
llr256[1] = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x20); // A2 B2 C2 D2 A3 B3 C3 D3
llr256[2] = simde_mm256_permute2x128_si256(xmm0, xmm1, 0x31); // A4 B4 C4 D4 A5 B5 C5 D5
llr256[3] = simde_mm256_permute2x128_si256(xmm2, xmm3, 0x31); // A6 B6 C6 D6 A7 B7 C7 D7
llr256+=4;
}
simde__m128i *llr128 = (simde__m128i*)llr256;
if (len_mod8 >= 4) {
int nb_re128 = nb_re>>2;
simde__m128i xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6;
simde__m128i *rxF = (simde__m128i*)rxdataF_comp;
simde__m128i *ch_mag = (simde__m128i*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
simde__m128i *ch_magb = (simde__m128i*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
simde__m128i *ch_magc = (simde__m128i*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
xmm0 = simde_mm_abs_epi16(rxF[nb_re128-1]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
xmm0 = simde_mm_subs_epi16(ch_mag[nb_re128-1],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
// xmmtmpD2 contains 8 LLRs
xmm1 = simde_mm_abs_epi16(xmm0);
xmm1 = simde_mm_subs_epi16(ch_magb[nb_re128-1],xmm1); // contains 8 LLRs
xmm2 = simde_mm_abs_epi16(xmm1);
xmm2 = simde_mm_subs_epi16(ch_magc[nb_re128-1],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[nb_re128-1],xmm0); // A0 B0 A1 B1
xmm4 = simde_mm_unpackhi_epi32(rxF[nb_re128-1],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
llr128[0] = simde_mm_unpacklo_epi64(xmm3,xmm5); // A0 B0 C0 D0
llr128[1] = simde_mm_unpackhi_epi64(xmm3,xmm5); // A1 B1 C1 D1
llr128[2] = simde_mm_unpacklo_epi64(xmm4,xmm6); // A2 B2 C2 D2
llr128[3] = simde_mm_unpackhi_epi64(xmm4,xmm6); // A3 B3 C3 D3
llr128+=4;
}
if (len_mod8 == 6) {
int nb_re64 = nb_re>>1;
simde__m64 *llr64 = (simde__m64 *)llr128;
simde__m64 xmm0,xmm1,xmm2;
simde__m64 *rxF = (simde__m64*)rxdataF_comp;
simde__m64 *ch_mag = (simde__m64*)&ul_ch_mag[(symbol*(off+(nb_rb*12)))];
simde__m64 *ch_magb = (simde__m64*)&ul_ch_magb[(symbol*(off+(nb_rb*12)))];
simde__m64 *ch_magc = (simde__m64*)&ul_ch_magc[(symbol*(off+(nb_rb*12)))];
xmm0 = simde_mm_abs_pi16(rxF[nb_re64-1]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
xmm0 = simde_mm_subs_pi16(ch_mag[nb_re-1],xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
// xmmtmpD2 contains 4 LLRs
xmm1 = simde_mm_abs_pi16(xmm0);
xmm1 = simde_mm_subs_pi16(ch_magb[nb_re64-1],xmm1); // contains 4 LLRs
xmm2 = simde_mm_abs_pi16(xmm1);
xmm2 = simde_mm_subs_pi16(ch_magc[nb_re64-1],xmm2); // contains 4 LLRs
// rxF[i] A0 A1
// xmm0 B0 B1
// xmm1 C0 C1
// xmm2 D0 D1
llr64[0] = simde_m_punpckldq(rxF[nb_re64-1],xmm0); // A0 B0
llr64[2] = simde_m_punpckhdq(rxF[nb_re64-1],xmm0); // A1 B1
llr64[1] = simde_m_punpckldq(xmm1,xmm2); // C0 D0
llr64[3] = simde_m_punpckhdq(xmm1,xmm2); // C1 D1
}
}
void nr_ulsch_compute_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_rb,
uint32_t nb_re,
......@@ -386,6 +494,16 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
nb_re,
symbol);
break;
case 8:
nr_ulsch_256qam_llr(rxdataF_comp,
ul_ch_mag,
ul_ch_magb,
ul_ch_magc,
ulsch_llr,
nb_rb,
nb_re,
symbol);
break;
default:
AssertFatal(1==0,"nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n",symbol, mod_order);
break;
......
......@@ -353,28 +353,40 @@ typedef struct {
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_magb;
/// \brief Magnitude of the UL channel estimates scaled for 4th bit level thresholds in LLR computation
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_magc;
/// \brief Cross-correlation of two UE signals.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: symbol [0..]
int32_t ***rho;
/// \f$\log_2(\max|H_i|^2)\f$
int16_t log2_maxh;
/// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level).
/// \brief Magnitude of Uplink Channel first layer (16QAM level/First 64QAM level/First 256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_mag0;
/// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level).
/// \brief Magnitude of Uplink Channel second layer (16QAM level/First 64QAM level/First 256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_mag1[8][8];
/// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM level).
/// \brief Magnitude of Uplink Channel, first layer (2nd 64QAM/256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_magb0;
/// \brief Magnitude of Uplink Channel second layer (2nd 64QAM level).
/// \brief Magnitude of Uplink Channel second layer (2nd 64QAM/256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_magb1[8][8];
/// \brief Magnitude of Uplink Channel, first layer (3rd 256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_magc0;
/// \brief Magnitude of Uplink Channel second layer (3rd 256QAM level).
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
/// - second index: ? [0..168*N_RB_UL[
int32_t **ul_ch_magc1[8][8];
/// measured RX power based on DRS
int ulsch_power[8];
/// total signal over antennas
......
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