Implementation of LLR computation for 4, 16, and 64 QAM (tested)
This commit is contained in:
committed by
Thomas Schlichter
parent
54ebd39b79
commit
66442aa42d
@@ -1285,6 +1285,7 @@ set(PHY_SRC_UE
|
|||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||||
|
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
|
||||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
|
||||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||||
|
|||||||
+22
-23
@@ -80,8 +80,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
|
||||||
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||||
/*LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
||||||
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
/*LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
||||||
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
|
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
@@ -200,39 +200,38 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
|
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
|
||||||
|
|
||||||
prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
|
prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
|
||||||
|
*/
|
||||||
|
|
||||||
for (int ulsch_id=0; ulsch_id<NUMBER_OF_NR_ULSCH_MAX; ulsch_id++) {
|
for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
|
||||||
//FIXME
|
//FIXME
|
||||||
|
pusch_vars[UE_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
|
||||||
pusch_vars[UE_id] = (LTE_eNB_PUSCH *)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) );
|
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
|
||||||
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
|
||||||
|
|
||||||
for (i=0; i<2; i++) {
|
for (i=0; i<2; i++) {
|
||||||
// RK 2 times because of output format of FFT!
|
// RK 2 times because of output format of FFT!
|
||||||
// FIXME We should get rid of this
|
// FIXME We should get rid of this
|
||||||
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||||
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||||
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||||
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
||||||
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
|
||||||
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||||
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
|
||||||
}
|
}
|
||||||
|
|
||||||
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
|
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
|
||||||
} //UE_id
|
} //UE_id
|
||||||
|
/*
|
||||||
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
|
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
|
||||||
gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
|
gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
|
||||||
|
|
||||||
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
|
|
||||||
*/
|
*/
|
||||||
|
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -283,8 +282,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) {
|
|||||||
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
|
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
|
||||||
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
//nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
|
||||||
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
|
||||||
/*LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
NR_gNB_PUSCH **const pusch_vars = gNB->pusch_vars;
|
||||||
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
/*LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
|
||||||
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
|
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/
|
||||||
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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_TRANSPORT/nr_transport_proto.h.c
|
||||||
|
* \brief Function prototypes for PHY physical/transport channel processing and generation
|
||||||
|
* \author Ahmed Hussein
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company Fraunhofer IIS
|
||||||
|
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PHY/defs_nr_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
|
||||||
|
@param rxdataF_comp Compensated channel output
|
||||||
|
@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_qpsk_llr(int32_t *rxdataF_comp,
|
||||||
|
int16_t *ulsch_llr,
|
||||||
|
uint32_t nb_re,
|
||||||
|
uint8_t symbol);
|
||||||
|
|
||||||
|
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 16 QAM received waveforms.
|
||||||
|
@param rxdataF_comp Compensated channel output
|
||||||
|
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 16
|
||||||
|
@param ulsch_llr llr output
|
||||||
|
@param nb_re number of RBs for this allocation
|
||||||
|
@param symbol OFDM symbol index in sub-frame
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 64 QAM received waveforms.
|
||||||
|
@param rxdataF_comp Compensated channel output
|
||||||
|
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 64
|
||||||
|
@param ul_ch_magb uplink channel magnitude multiplied by the 2bd amplitude threshold in QAM 64
|
||||||
|
@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_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);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief This function computes the log-likelihood ratios for 4, 16, and 64 QAM
|
||||||
|
@param rxdataF_comp Compensated channel output
|
||||||
|
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 64
|
||||||
|
@param ul_ch_magb uplink channel magnitude multiplied by the 2bd amplitude threshold in QAM 64
|
||||||
|
@param ulsch_llr llr output
|
||||||
|
@param nb_re number of REs for this allocation
|
||||||
|
@param symbol OFDM symbol index in sub-frame
|
||||||
|
@param mod_order modulation order
|
||||||
|
*/
|
||||||
|
void nr_ulsch_compute_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,
|
||||||
|
uint8_t mod_order);
|
||||||
@@ -0,0 +1,365 @@
|
|||||||
|
/*
|
||||||
|
* 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_TRANSPORT/nr_ulsch_llr_computation.c
|
||||||
|
* \brief Top-level routines for LLR computation of the PDSCH physical channel
|
||||||
|
* \author Ahmed Hussein
|
||||||
|
* \date 2019
|
||||||
|
* \version 0.1
|
||||||
|
* \company Fraunhofer IIS
|
||||||
|
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||||
|
* \note
|
||||||
|
* \warning
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PHY/defs_nr_common.h"
|
||||||
|
#include "PHY/sse_intrin.h"
|
||||||
|
#include "PHY/impl_defs_top.h"
|
||||||
|
|
||||||
|
__m128i xmm0 __attribute__ ((aligned(16)));
|
||||||
|
__m128i xmm1 __attribute__ ((aligned(16)));
|
||||||
|
__m128i xmm2 __attribute__ ((aligned(16)));
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------
|
||||||
|
// QPSK
|
||||||
|
//----------------------------------------------------------------------------------------------
|
||||||
|
void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
|
||||||
|
int16_t *ulsch_llr,
|
||||||
|
uint32_t nb_re,
|
||||||
|
uint8_t symbol)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uint32_t *rxF = (uint32_t*)rxdataF_comp;
|
||||||
|
uint32_t *llr32 = (uint32_t*)ulsch_llr;
|
||||||
|
|
||||||
|
if (!llr32) {
|
||||||
|
LOG_E(PHY,"nr_ulsch_qpsk_llr: llr is null, symbol %d, llr32 = %p\n",symbol, llr32);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nb_re; i++) {
|
||||||
|
*llr32 = *rxF;
|
||||||
|
rxF++;
|
||||||
|
llr32++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
__m128i *rxF = (__m128i*)rxdataF_comp;
|
||||||
|
// __m128i *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
__m128i llr128[2];
|
||||||
|
uint32_t *llr32;
|
||||||
|
|
||||||
|
// [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
|
||||||
|
// else ul_ch_mag and ul_ch_magb should be used after channel estimation has benn implemented
|
||||||
|
__m128i temp_channel;
|
||||||
|
int16_t one_over_sqrt_2 = 23170;
|
||||||
|
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
|
||||||
|
// int16x8_t *ch_mag; // [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
int16x8_t xmm0;
|
||||||
|
int16_t *llr16;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int i;
|
||||||
|
unsigned char len_mod4 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
llr32 = (uint32_t*)ulsch_llr;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
llr16 = (int16_t*)ulsch_llr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// #if defined(__x86_64__) || defined(__i386__)
|
||||||
|
// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
|
// #elif defined(__arm__)
|
||||||
|
// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*nb_rb*12)];
|
||||||
|
// #endif
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
len_mod4 = nb_re&3;
|
||||||
|
nb_re >>= 2; // length in quad words (4 REs)
|
||||||
|
nb_re += (len_mod4 == 0 ? 0 : 1);
|
||||||
|
|
||||||
|
temp_channel = _mm_set1_epi16((int16_t)((QAM64_n1 * one_over_sqrt_2)>>15));
|
||||||
|
|
||||||
|
for (i=0; i<nb_re; i++) {
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386)
|
||||||
|
|
||||||
|
xmm0 = _mm_abs_epi16(rxF[i]); // registers of even index in xmm0-> |y_R|, registers of odd index in xmm0-> |y_I|
|
||||||
|
|
||||||
|
|
||||||
|
xmm0 = _mm_subs_epi16(temp_channel,xmm0); // registers of even index in xmm0-> |y_R|-|h|^2, registers of odd index in xmm0-> |y_I|-|h|^2
|
||||||
|
|
||||||
|
llr128[0] = _mm_unpacklo_epi32(rxF[i],xmm0); // llr128[0] contains the llrs of the 1st and 2nd REs
|
||||||
|
llr128[1] = _mm_unpackhi_epi32(rxF[i],xmm0); // llr128[1] contains the llrs of the 3rd and 4th REs
|
||||||
|
|
||||||
|
// 1st RE
|
||||||
|
llr32[0] = _mm_extract_epi32(llr128[0],0); // llr32[0] low 16 bits-> y_R , high 16 bits-> y_I
|
||||||
|
llr32[1] = _mm_extract_epi32(llr128[0],1); // llr32[1] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
|
||||||
|
|
||||||
|
// 2nd RE
|
||||||
|
llr32[2] = _mm_extract_epi32(llr128[0],2); // llr32[2] low 16 bits-> y_R , high 16 bits-> y_I
|
||||||
|
llr32[3] = _mm_extract_epi32(llr128[0],3); // llr32[3] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
|
||||||
|
|
||||||
|
// 3rd RE
|
||||||
|
llr32[4] = _mm_extract_epi32(llr128[1],0); // llr32[4] low 16 bits-> y_R , high 16 bits-> y_I
|
||||||
|
llr32[5] = _mm_extract_epi32(llr128[1],1); // llr32[5] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
|
||||||
|
|
||||||
|
// 4th RE
|
||||||
|
llr32[6] = _mm_extract_epi32(llr128[1],2); // llr32[6] low 16 bits-> y_R , high 16 bits-> y_I
|
||||||
|
llr32[7] = _mm_extract_epi32(llr128[1],3); // llr32[7] low 16 bits-> |h|-|y_R|^2, high 16 bits-> |h|-|y_I|^2
|
||||||
|
|
||||||
|
llr32+=8;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
xmm0 = vabsq_s16(rxF[i]);
|
||||||
|
xmm0 = vqsubq_s16((*(__m128i*)&ones[0]),xmm0);
|
||||||
|
|
||||||
|
llr16[0] = vgetq_lane_s16(rxF[i],0);
|
||||||
|
llr16[1] = vgetq_lane_s16(rxF[i],1);
|
||||||
|
llr16[2] = vgetq_lane_s16(xmm0,0);
|
||||||
|
llr16[3] = vgetq_lane_s16(xmm0,1);
|
||||||
|
llr16[4] = vgetq_lane_s16(rxF[i],2);
|
||||||
|
llr16[5] = vgetq_lane_s16(rxF[i],3);
|
||||||
|
llr16[6] = vgetq_lane_s16(xmm0,2);
|
||||||
|
llr16[7] = vgetq_lane_s16(xmm0,3);
|
||||||
|
llr16[8] = vgetq_lane_s16(rxF[i],4);
|
||||||
|
llr16[9] = vgetq_lane_s16(rxF[i],5);
|
||||||
|
llr16[10] = vgetq_lane_s16(xmm0,4);
|
||||||
|
llr16[11] = vgetq_lane_s16(xmm0,5);
|
||||||
|
llr16[12] = vgetq_lane_s16(rxF[i],6);
|
||||||
|
llr16[13] = vgetq_lane_s16(rxF[i],6);
|
||||||
|
llr16[14] = vgetq_lane_s16(xmm0,7);
|
||||||
|
llr16[15] = vgetq_lane_s16(xmm0,7);
|
||||||
|
llr16+=16;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
__m128i *rxF = (__m128i*)rxdataF_comp;
|
||||||
|
// __m128i *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
|
||||||
|
// [hna] temp_channel and one_over_sqrt_2 are for temporary use until channel estimation is implemented
|
||||||
|
// else ul_ch_mag and ul_ch_magb should be used after channel estimation has been implemented
|
||||||
|
__m128i temp_channel[2];
|
||||||
|
int16_t one_over_sqrt_2 = 23170;
|
||||||
|
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp;
|
||||||
|
// int16x8_t *ch_mag,*ch_magb; // [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
int16x8_t xmm1,xmm2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int i;
|
||||||
|
unsigned char len_mod4;
|
||||||
|
|
||||||
|
// [hna] This should be uncommented once channel estimation is implemented
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// #if defined(__x86_64__) || defined(__i386__)
|
||||||
|
// ch_mag = (__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||||
|
// ch_magb = (__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||||
|
// #elif defined(__arm__)
|
||||||
|
// ch_mag = (int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||||
|
// ch_magb = (int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_UL*12)];
|
||||||
|
// #endif
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
len_mod4 =nb_re&3;
|
||||||
|
nb_re=nb_re>>2; // length in quad words (4 REs)
|
||||||
|
nb_re+=((len_mod4==0)?0:1);
|
||||||
|
|
||||||
|
|
||||||
|
temp_channel[0] = _mm_set1_epi16((int16_t)((QAM64_n1 * one_over_sqrt_2)>>15));
|
||||||
|
temp_channel[1] = _mm_set1_epi16((int16_t)((QAM64_n2 * one_over_sqrt_2)>>15));
|
||||||
|
|
||||||
|
for (i=0; i<nb_re; i++) {
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
xmm1 = _mm_abs_epi16(rxF[i]);
|
||||||
|
xmm1 = _mm_subs_epi16(temp_channel[0],xmm1);
|
||||||
|
xmm2 = _mm_abs_epi16(xmm1);
|
||||||
|
xmm2 = _mm_subs_epi16(temp_channel[1],xmm2);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
xmm1 = vabsq_s16(rxF[i]);
|
||||||
|
xmm1 = vsubq_s16(ch_mag[i],xmm1);
|
||||||
|
xmm2 = vabsq_s16(xmm1);
|
||||||
|
xmm2 = vsubq_s16(ch_magb[i],xmm2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------s
|
||||||
|
// 1st RE
|
||||||
|
// ---------------------------------------
|
||||||
|
ulsch_llr[0] = ((short *)&rxF[i])[0];
|
||||||
|
ulsch_llr[1] = ((short *)&rxF[i])[1];
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
ulsch_llr[2] = _mm_extract_epi16(xmm1,0);
|
||||||
|
ulsch_llr[3] = _mm_extract_epi16(xmm1,1);
|
||||||
|
ulsch_llr[4] = _mm_extract_epi16(xmm2,0);
|
||||||
|
ulsch_llr[5] = _mm_extract_epi16(xmm2,1);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
ulsch_llr[2] = vgetq_lane_s16(xmm1,0);
|
||||||
|
ulsch_llr[3] = vgetq_lane_s16(xmm1,1);
|
||||||
|
ulsch_llr[4] = vgetq_lane_s16(xmm2,0);
|
||||||
|
ulsch_llr[5] = vgetq_lane_s16(xmm2,1);
|
||||||
|
#endif
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
ulsch_llr+=6;
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// 2nd RE
|
||||||
|
// ---------------------------------------
|
||||||
|
ulsch_llr[0] = ((short *)&rxF[i])[2];
|
||||||
|
ulsch_llr[1] = ((short *)&rxF[i])[3];
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
ulsch_llr[2] = _mm_extract_epi16(xmm1,2);
|
||||||
|
ulsch_llr[3] = _mm_extract_epi16(xmm1,3);
|
||||||
|
ulsch_llr[4] = _mm_extract_epi16(xmm2,2);
|
||||||
|
ulsch_llr[5] = _mm_extract_epi16(xmm2,3);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
ulsch_llr[2] = vgetq_lane_s16(xmm1,2);
|
||||||
|
ulsch_llr[3] = vgetq_lane_s16(xmm1,3);
|
||||||
|
ulsch_llr[4] = vgetq_lane_s16(xmm2,2);
|
||||||
|
ulsch_llr[5] = vgetq_lane_s16(xmm2,3);
|
||||||
|
#endif
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
ulsch_llr+=6;
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// 3rd RE
|
||||||
|
// ---------------------------------------
|
||||||
|
ulsch_llr[0] = ((short *)&rxF[i])[4];
|
||||||
|
ulsch_llr[1] = ((short *)&rxF[i])[5];
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
ulsch_llr[2] = _mm_extract_epi16(xmm1,4);
|
||||||
|
ulsch_llr[3] = _mm_extract_epi16(xmm1,5);
|
||||||
|
ulsch_llr[4] = _mm_extract_epi16(xmm2,4);
|
||||||
|
ulsch_llr[5] = _mm_extract_epi16(xmm2,5);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
ulsch_llr[2] = vgetq_lane_s16(xmm1,4);
|
||||||
|
ulsch_llr[3] = vgetq_lane_s16(xmm1,5);
|
||||||
|
ulsch_llr[4] = vgetq_lane_s16(xmm2,4);
|
||||||
|
ulsch_llr[5] = vgetq_lane_s16(xmm2,5);
|
||||||
|
#endif
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
ulsch_llr+=6;
|
||||||
|
|
||||||
|
// ---------------------------------------
|
||||||
|
// 4th RE
|
||||||
|
// ---------------------------------------
|
||||||
|
ulsch_llr[0] = ((short *)&rxF[i])[6];
|
||||||
|
ulsch_llr[1] = ((short *)&rxF[i])[7];
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
ulsch_llr[2] = _mm_extract_epi16(xmm1,6);
|
||||||
|
ulsch_llr[3] = _mm_extract_epi16(xmm1,7);
|
||||||
|
ulsch_llr[4] = _mm_extract_epi16(xmm2,6);
|
||||||
|
ulsch_llr[5] = _mm_extract_epi16(xmm2,7);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
ulsch_llr[2] = vgetq_lane_s16(xmm1,6);
|
||||||
|
ulsch_llr[3] = vgetq_lane_s16(xmm1,7);
|
||||||
|
ulsch_llr[4] = vgetq_lane_s16(xmm2,6);
|
||||||
|
ulsch_llr[5] = vgetq_lane_s16(xmm2,7);
|
||||||
|
#endif
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
ulsch_llr+=6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nr_ulsch_compute_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,
|
||||||
|
uint8_t mod_order)
|
||||||
|
{
|
||||||
|
switch(mod_order){
|
||||||
|
case 2:
|
||||||
|
nr_ulsch_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);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
nr_ulsch_64qam_llr(rxdataF_comp,
|
||||||
|
ul_ch_mag,
|
||||||
|
ul_ch_magb,
|
||||||
|
ulsch_llr,
|
||||||
|
nb_re,
|
||||||
|
symbol);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_E(PHY,"nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n",symbol, mod_order);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -204,7 +204,7 @@ typedef struct {
|
|||||||
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||||
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
|
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
|
||||||
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||||
int32_t d_mod[MAX_NUM_NR_RE];
|
int32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
|
||||||
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
|
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
|
||||||
int32_t z[MAX_NUM_NR_RE];
|
int32_t z[MAX_NUM_NR_RE];
|
||||||
/*
|
/*
|
||||||
|
|||||||
+39
-2
@@ -354,6 +354,43 @@ typedef struct {
|
|||||||
} NR_gNB_COMMON;
|
} NR_gNB_COMMON;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format.
|
||||||
|
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||||
|
/// - second index: ? [0..2*ofdm_symbol_size[
|
||||||
|
int32_t **rxdataF_ext;
|
||||||
|
/// \brief Holds the received data in the frequency domain for the allocated RBs in normal format.
|
||||||
|
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||||
|
/// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||||
|
int32_t **rxdataF_ext2;
|
||||||
|
/// \brief Hold the channel estimates in time domain based on DRS.
|
||||||
|
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||||
|
/// - second index: ? [0..4*ofdm_symbol_size[
|
||||||
|
int32_t **drs_ch_estimates_time;
|
||||||
|
/// \brief Hold the channel estimates in frequency domain based on DRS.
|
||||||
|
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||||
|
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||||
|
int32_t **drs_ch_estimates;
|
||||||
|
/// \brief Holds the compensated signal.
|
||||||
|
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||||
|
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||||
|
int32_t **rxdataF_comp;
|
||||||
|
/// \brief Magnitude of the UL channel estimates. Used for 2nd-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_mag;
|
||||||
|
/// \brief Magnitude of the UL channel estimates scaled for 3rd 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_magb;
|
||||||
|
/// measured RX power based on DRS
|
||||||
|
int ulsch_power[2];
|
||||||
|
/// \brief llr values.
|
||||||
|
/// - first index: ? [0..1179743] (hard coded)
|
||||||
|
int16_t *llr;
|
||||||
|
} NR_gNB_PUSCH;
|
||||||
|
|
||||||
|
|
||||||
/// Context data structure for RX/TX portion of slot processing
|
/// Context data structure for RX/TX portion of slot processing
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// Component Carrier index
|
/// Component Carrier index
|
||||||
@@ -569,13 +606,13 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
Sched_Rsp_t Sched_INFO;
|
Sched_Rsp_t Sched_INFO;
|
||||||
NR_gNB_PDCCH pdcch_vars;
|
NR_gNB_PDCCH pdcch_vars;
|
||||||
NR_gNB_PBCH pbch;
|
NR_gNB_PBCH pbch;
|
||||||
LTE_eNB_PHICH phich_vars[2];
|
// LTE_eNB_PHICH phich_vars[2];
|
||||||
|
|
||||||
NR_gNB_COMMON common_vars;
|
NR_gNB_COMMON common_vars;
|
||||||
/* LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
|
/* LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
|
||||||
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
||||||
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
|
||||||
LTE_eNB_PRACH prach_vars;*/
|
LTE_eNB_PRACH prach_vars;*/
|
||||||
|
NR_gNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||||
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
|
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
|
||||||
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA
|
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA
|
||||||
// LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
// LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
|
||||||
|
|||||||
@@ -48,16 +48,14 @@
|
|||||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||||
#include "SCHED_NR/sched_nr.h"
|
#include "SCHED_NR/sched_nr.h"
|
||||||
|
|
||||||
//#include "PHY/MODULATION/modulation_common.h"
|
//#include "PHY/MODULATION/modulation_common.h"
|
||||||
//#include "common/config/config_load_configmodule.h"
|
//#include "common/config/config_load_configmodule.h"
|
||||||
//#include "UTIL/LISTS/list.h"
|
//#include "UTIL/LISTS/list.h"
|
||||||
//#include "common/ran_context.h"
|
//#include "common/ran_context.h"
|
||||||
|
|
||||||
//#define DEBUG_ULSCHSIM
|
//#define DEBUG_ULSCHSIM
|
||||||
|
|
||||||
PHY_VARS_gNB *gNB;
|
PHY_VARS_gNB *gNB;
|
||||||
PHY_VARS_NR_UE *UE;
|
PHY_VARS_NR_UE *UE;
|
||||||
RAN_CONTEXT_t RC;
|
RAN_CONTEXT_t RC;
|
||||||
@@ -487,6 +485,7 @@ int main(int argc, char **argv) {
|
|||||||
uint8_t bit_index;
|
uint8_t bit_index;
|
||||||
uint32_t errors_scrambling;
|
uint32_t errors_scrambling;
|
||||||
uint32_t scrambling_index;
|
uint32_t scrambling_index;
|
||||||
|
uint8_t symbol;
|
||||||
int16_t **tx_layers;
|
int16_t **tx_layers;
|
||||||
int32_t *mod_symbols[MAX_NUM_NR_RE];
|
int32_t *mod_symbols[MAX_NUM_NR_RE];
|
||||||
uint16_t n_dmrs;
|
uint16_t n_dmrs;
|
||||||
@@ -573,7 +572,7 @@ int main(int argc, char **argv) {
|
|||||||
nr_modulation(scrambled_output[cwd], // assume one codeword for the moment
|
nr_modulation(scrambled_output[cwd], // assume one codeword for the moment
|
||||||
available_bits,
|
available_bits,
|
||||||
mod_order,
|
mod_order,
|
||||||
ulsch_ue[cwd]->d_mod);
|
(int16_t *)ulsch_ue[cwd]->d_mod);
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -718,12 +717,12 @@ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
|||||||
n_errors = 0;
|
n_errors = 0;
|
||||||
n_false_positive = 0;
|
n_false_positive = 0;
|
||||||
|
|
||||||
SNR_lin = pow(10, SNR / 10.0);
|
SNR_lin = pow(10, SNR / 10.0);
|
||||||
sigma = 1.0 / sqrt(2 * SNR_lin);
|
sigma = 1.0 / sqrt(2 * SNR_lin);
|
||||||
|
|
||||||
//AWGN
|
//AWGN
|
||||||
sigma2_dB = 10*log10((double)txlev)-SNR;
|
sigma2_dB = 10*log10((double)txlev)-SNR;
|
||||||
sigma2 = pow(10,sigma2_dB/10);
|
sigma2 = pow(10,sigma2_dB/10);
|
||||||
|
|
||||||
|
|
||||||
for (trial = 0; trial < n_trials; trial++) {
|
for (trial = 0; trial < n_trials; trial++) {
|
||||||
@@ -795,37 +794,70 @@ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
//----------------------------------------------------------
|
||||||
//////////////////// ULSCH unscrambling ////////////////////
|
//-------------------- LLRs computation --------------------
|
||||||
////////////////////////////////////////////////////////////
|
//----------------------------------------------------------
|
||||||
|
|
||||||
nr_ulsch_unscrambling(channel_output_fixed, available_bits, 0, Nid_cell, n_rnti);
|
int sch_sym_start = NR_SYMBOLS_PER_SLOT-nb_symb_sch;
|
||||||
|
uint32_t nb_re;
|
||||||
|
uint32_t d_mod_offset = 0;
|
||||||
|
uint32_t llr_offset = 0;
|
||||||
|
|
||||||
|
for(symbol = sch_sym_start; symbol < 14; symbol++) {
|
||||||
|
|
||||||
|
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
||||||
|
nb_re = nb_rb*6;
|
||||||
|
else
|
||||||
|
nb_re = nb_rb*12;
|
||||||
|
|
||||||
|
nr_ulsch_compute_llr(&ulsch_ue[0]->d_mod[d_mod_offset],
|
||||||
|
gNB->pusch_vars[UE_id]->ul_ch_mag,
|
||||||
|
gNB->pusch_vars[UE_id]->ul_ch_magb,
|
||||||
|
&gNB->pusch_vars[UE_id]->llr[llr_offset],
|
||||||
|
nb_re,
|
||||||
|
symbol,
|
||||||
|
rel15_ul->Qm);
|
||||||
|
|
||||||
|
d_mod_offset = d_mod_offset + nb_re; // [hna] d_mod is incremented by nb_re
|
||||||
|
llr_offset = llr_offset + (nb_re * rel15_ul->Qm); // [hna] llr is incremented by (nb_re*mod_order) because each RE has (mod_order) coded bit (i.e LLRs)
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------
|
||||||
|
//------------------- ULSCH unscrambling -------------------
|
||||||
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
nr_ulsch_unscrambling(gNB->pusch_vars[UE_id]->llr, available_bits, 0, Nid_cell, n_rnti);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////// ULSCH decoding //////////////////////
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, frame,
|
//----------------------------------------------------------
|
||||||
|
//--------------------- ULSCH decoding ---------------------
|
||||||
|
//----------------------------------------------------------
|
||||||
|
|
||||||
|
ret = nr_ulsch_decoding(gNB, UE_id, gNB->pusch_vars[UE_id]->llr, frame_parms, frame,
|
||||||
nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||||
|
|
||||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||||
n_errors++;
|
n_errors++;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
//----------------------------------------------------------
|
||||||
/////////////////////// count errors ///////////////////////
|
//---------------------- count errors ----------------------
|
||||||
////////////////////////////////////////////////////////////
|
//----------------------------------------------------------
|
||||||
|
|
||||||
for (i = 0; i < TBS; i++) {
|
for (i = 0; i < TBS; i++) {
|
||||||
|
|
||||||
if(((ulsch_ue[0]->g[i] == 0) && (channel_output_fixed[i] < 0)) || ((ulsch_ue[0]->g[i] == 1) && (channel_output_fixed[i] >= 0))) {
|
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
|
||||||
|
((ulsch_ue[0]->g[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
|
||||||
|
{
|
||||||
|
if(errors_scrambling == 0)
|
||||||
|
printf("First bit in error = %d\n",i);
|
||||||
errors_scrambling++;
|
errors_scrambling++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -839,14 +871,18 @@ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
if (errors_scrambling > 0) {
|
||||||
|
if (n_trials == 1)
|
||||||
|
printf("errors_scrambling %d (trial %d)\n", errors_scrambling, trial);
|
||||||
|
}
|
||||||
|
|
||||||
if (errors_bit > 0) {
|
if (errors_bit > 0) {
|
||||||
n_false_positive++;
|
n_false_positive++;
|
||||||
if (n_trials == 1)
|
if (n_trials == 1)
|
||||||
printf("errors_bit %d (trial %d)\n", errors_bit, trial);
|
printf("errors_bit %d (trial %d)\n", errors_bit, trial);
|
||||||
}
|
}
|
||||||
}
|
} // [hna] for (trial = 0; trial < n_trials; trial++)
|
||||||
|
|
||||||
printf("*****************************************\n");
|
printf("*****************************************\n");
|
||||||
printf("SNR %f, BLER %f (false positive %f)\n", SNR,
|
printf("SNR %f, BLER %f (false positive %f)\n", SNR,
|
||||||
@@ -858,7 +894,8 @@ m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
|
|||||||
printf("PUSCH test OK\n");
|
printf("PUSCH test OK\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} // [hna] for (SNR = snr0; SNR < snr1; SNR += snr_step)
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user