Restructuring ulsim and introducing more functionalities in RX at gNB
This commit is contained in:
committed by
Thomas Schlichter
parent
749bb66988
commit
15417570aa
@@ -694,7 +694,6 @@ typedef struct {
|
||||
uint8_t Qm;
|
||||
uint8_t ndi;
|
||||
uint8_t rv;
|
||||
uint8_t harq_process_nbr;
|
||||
int8_t accumulated_delta_PUSCH;
|
||||
int8_t absolute_delta_PUSCH;
|
||||
uint8_t n_layers;
|
||||
|
||||
@@ -452,10 +452,14 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
||||
gNB->dlsch[i][j]->rnti=0;
|
||||
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////// Initializing gNB ULSCH /////////////////////////
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||
for (i=0; i<NUMBER_OF_NR_UE_MAX; i++) {
|
||||
|
||||
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
|
||||
|
||||
for (j=0; j<2; j++) {
|
||||
// ULSCH for RA
|
||||
if(i==0) {
|
||||
gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
|
||||
@@ -487,7 +491,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
|
||||
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
|
||||
gNB->rx_total_gain_dB=130;
|
||||
|
||||
for(i=0; i<NUMBER_OF_UE_MAX; i++)
|
||||
for(i=0; i<NUMBER_OF_NR_UE_MAX; i++)
|
||||
gNB->mu_mimo_mode[i].dl_pow_off = 2;
|
||||
|
||||
gNB->check_for_total_transmissions = 0;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
|
||||
#define DMRS_MOD_ORDER 2
|
||||
|
||||
@@ -51,4 +52,20 @@ void nr_layer_mapping(int16_t **mod_symbs,
|
||||
uint16_t n_symbs,
|
||||
int16_t **tx_layers);
|
||||
|
||||
|
||||
/*!
|
||||
\brief This function implements the OFDM front end processor on reception (FEP)
|
||||
\param phy_vars_ue Pointer to PHY variables
|
||||
\param symbol symbol within slot (0..12/14)
|
||||
\param Ns Slot number (0..19)
|
||||
\param sample_offset offset within rxdata (points to beginning of subframe)
|
||||
\param no_prefix if 1 prefix is removed by HW
|
||||
*/
|
||||
|
||||
int nr_slot_fep_ul(PHY_VARS_gNB *phy_vars_gNB,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix);
|
||||
|
||||
#endif
|
||||
@@ -19,9 +19,10 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "modulation_UE.h"
|
||||
#include "nr_modulation.h"
|
||||
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
|
||||
@@ -198,3 +199,72 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int nr_slot_fep_ul(PHY_VARS_gNB *gNB,
|
||||
unsigned char symbol,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix)
|
||||
{
|
||||
unsigned char aa;
|
||||
uint32_t slot_offset;
|
||||
uint32_t rxdata_offset;
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
|
||||
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dft = dft128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
dft = dft256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
dft = dft512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
dft = dft1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
dft = dft1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
dft = dft2048;
|
||||
break;
|
||||
|
||||
case 4096:
|
||||
dft = dft4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
dft = dft8192;
|
||||
break;
|
||||
|
||||
default:
|
||||
dft = dft512;
|
||||
break;
|
||||
}
|
||||
|
||||
slot_offset = Ns * frame_parms->samples_per_slot;
|
||||
|
||||
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
if(symbol == 0)
|
||||
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
|
||||
else
|
||||
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
|
||||
|
||||
dft((int16_t *)&gNB->common_vars.rxdata[0][rxdata_offset],
|
||||
(int16_t *)&gNB->common_vars.rxdataF[0][symbol * frame_parms->ofdm_symbol_size], 1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs.h
|
||||
* \brief
|
||||
* \author
|
||||
* \date
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "PHY/defs_nr_common.h"
|
||||
|
||||
|
||||
/** \brief This function is the top-level entry point to PUSCH demodulation, after frequency-domain transformation and channel estimation. It performs
|
||||
- RB extraction (signal and channel estimates)
|
||||
- channel compensation (matched filtering)
|
||||
@@ -45,15 +44,14 @@
|
||||
@param frame Frame number
|
||||
@param nr_tti_rx TTI number
|
||||
@param symbol Symbol on which to act (within-in nr_TTI_rx)
|
||||
@param first_symbol_flag set to 1 on first ULSCH symbol
|
||||
@param harq_pid HARQ process ID
|
||||
*/
|
||||
int nr_rx_ulsch(PHY_VARS_gNB *gNB,
|
||||
uint8_t UE_id,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
unsigned char symbol,
|
||||
unsigned char first_symbol_flag,
|
||||
unsigned char harq_pid);
|
||||
void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
uint8_t UE_id,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
unsigned char symbol,
|
||||
unsigned char harq_pid);
|
||||
|
||||
|
||||
/** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented)
|
||||
@@ -62,18 +60,18 @@ int nr_rx_ulsch(PHY_VARS_gNB *gNB,
|
||||
@param rb_alloc RB allocation map (used for Resource Allocation Type 0 in NR)
|
||||
@param symbol Symbol on which to act (within-in nr_TTI_rx)
|
||||
@param start_rb The starting RB in the RB allocation (used for Resource Allocation Type 1 in NR)
|
||||
@param nb_pusch_rb The number of RBs allocated (used for Resource Allocation Type 1 in NR)
|
||||
@param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR)
|
||||
@param frame_parms, Pointer to frame descriptor structure
|
||||
|
||||
*/
|
||||
unsigned short nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **rxdataF_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_pusch_rb,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **rxdataF_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pusch,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
|
||||
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
|
||||
|
||||
@@ -46,7 +46,6 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8
|
||||
@param nr_tti_rx, current received TTI
|
||||
@param harq_pid, harq process id
|
||||
@param is_crnti
|
||||
@param llr8_flag If 1, indicate that the 8-bit decoder should be used
|
||||
*/
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
@@ -57,8 +56,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint16_t nb_symb_sch,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag);
|
||||
uint8_t is_crnti);
|
||||
|
||||
|
||||
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
|
||||
@@ -75,3 +73,9 @@ void nr_ulsch_unscrambling(int16_t* llr,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI);
|
||||
|
||||
|
||||
void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
|
||||
gNB_L1_rxtx_proc_t *proc,
|
||||
int UE_id,
|
||||
uint8_t harq_pid);
|
||||
|
||||
|
||||
@@ -278,13 +278,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint16_t nb_symb_sch,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint8_t is_crnti,
|
||||
uint8_t llr8_flag)
|
||||
uint8_t is_crnti)
|
||||
{
|
||||
|
||||
uint32_t A,E;
|
||||
uint32_t G;
|
||||
uint32_t ret,offset;
|
||||
uint32_t nb_rb;
|
||||
int32_t no_iteration_ldpc, length_dec;
|
||||
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
|
||||
uint8_t crc_type;
|
||||
@@ -306,7 +306,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t kc;
|
||||
uint8_t Ilbrm = 0;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
uint16_t nb_rb = 30; //to update
|
||||
uint8_t nb_re_dmrs = 6;
|
||||
uint16_t length_dmrs = 1;
|
||||
double Coderate = 0.0;
|
||||
@@ -341,7 +340,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
A = harq_process->TBS;
|
||||
ret = ulsch->max_ldpc_iterations;
|
||||
|
||||
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers);
|
||||
// harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers);
|
||||
G = harq_process->G;
|
||||
|
||||
LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb);
|
||||
|
||||
@@ -1,49 +1,97 @@
|
||||
// This should have nr_rx_pdsch, nr_ulsch_extract_rbs_single, and nr_ulsch_compute_llr
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "nr_transport_proto.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
|
||||
//==============================================================================================
|
||||
// Extraction functions
|
||||
//==============================================================================================
|
||||
|
||||
unsigned short nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **rxdataF_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pdsch,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
|
||||
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||
int **rxdataF_ext,
|
||||
uint32_t rxdataF_ext_offset,
|
||||
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
unsigned char symbol,
|
||||
unsigned short start_rb,
|
||||
unsigned short nb_rb_pusch,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
unsigned short start_re,re;
|
||||
unsigned char aarx, is_dmrs_symbol = 0;
|
||||
uint32_t rxF_ext_index = 0, nb_re_pdsch = 0;
|
||||
uint32_t rxF_ext_index = 0, nb_re_pusch = 0;
|
||||
|
||||
int16_t *rxF,*rxF_ext;
|
||||
|
||||
|
||||
is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config
|
||||
|
||||
start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB);
|
||||
|
||||
nb_re_pdsch = NR_NB_SC_PER_RB * nb_rb_pdsch;
|
||||
nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
|
||||
|
||||
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
|
||||
rxF_ext = (int16_t *)&rxdataF_ext[aarx][rxdataF_ext_offset];
|
||||
|
||||
for (re = 0; re < nb_re_pdsch; re++) {
|
||||
for (re = 0; re < nb_re_pusch; re++) {
|
||||
|
||||
if ( (is_dmrs_symbol && ((re&1) != frame_parms->nushift)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
|
||||
if ( (is_dmrs_symbol && ((re&1) != frame_parms->nushift)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
|
||||
|
||||
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)] << 15) >> AMP_SHIFT;
|
||||
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)] << 15) >> AMP_SHIFT;
|
||||
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)] << 15) >> AMP_SHIFT;
|
||||
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)] << 15) >> AMP_SHIFT;
|
||||
|
||||
rxF_ext_index = rxF_ext_index + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
uint8_t UE_id,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
unsigned char symbol,
|
||||
unsigned char harq_pid)
|
||||
{
|
||||
|
||||
return(nb_rb_pdsch/frame_parms->nb_antennas_rx);
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
||||
uint32_t nb_re;
|
||||
|
||||
if(symbol == rel15_ul->start_symbol)
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
|
||||
|
||||
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
||||
nb_re = rel15_ul->number_rbs * 6;
|
||||
else
|
||||
nb_re = rel15_ul->number_rbs * 12;
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- RBs extraction ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset,
|
||||
// rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
symbol,
|
||||
rel15_ul->start_rb,
|
||||
nb_re,
|
||||
frame_parms);
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//-------------------- LLRs computation --------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][gNB->pusch_vars[UE_id]->rxdataF_ext_offset],
|
||||
gNB->pusch_vars[UE_id]->ul_ch_mag,
|
||||
gNB->pusch_vars[UE_id]->ul_ch_magb,
|
||||
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
|
||||
nb_re,
|
||||
symbol,
|
||||
rel15_ul->Qm);
|
||||
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re;
|
||||
|
||||
}
|
||||
@@ -116,7 +116,7 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
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));
|
||||
temp_channel = _mm_set1_epi16((int16_t)((QAM16_n1 * one_over_sqrt_2)>>15));
|
||||
|
||||
for (i=0; i<nb_re; i++) {
|
||||
|
||||
@@ -151,16 +151,16 @@ void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
|
||||
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[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);
|
||||
@@ -218,9 +218,9 @@ void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
|
||||
// #endif
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
len_mod4 =nb_re&3;
|
||||
nb_re=nb_re>>2; // length in quad words (4 REs)
|
||||
nb_re+=((len_mod4==0)?0:1);
|
||||
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));
|
||||
|
||||
@@ -363,6 +363,8 @@ typedef struct {
|
||||
/// - 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 Offset for calculating the index of rxdataF_ext for the current symbol
|
||||
uint32_t rxdataF_ext_offset;
|
||||
/// \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[
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "sched_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "SCHED/sched_eNB.h"
|
||||
#include "SCHED/sched_common_extern.h"
|
||||
#include "nfapi_interface.h"
|
||||
@@ -31,7 +33,7 @@
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "T.h"
|
||||
|
||||
#include "assertions.h"
|
||||
@@ -200,3 +202,67 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
|
||||
}
|
||||
|
||||
|
||||
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, uint8_t harq_pid) {
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu;
|
||||
uint8_t ret;
|
||||
int Nid_cell = 0; // shouldn't be a local variable
|
||||
|
||||
//----------------------------------------------------------
|
||||
//------------------- ULSCH unscrambling -------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_unscrambling(gNB->pusch_vars[UE_id]->llr, gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->G, 0, Nid_cell, rel15_ul->rnti);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- ULSCH decoding ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, gNB->pusch_vars[UE_id]->llr, frame_parms, proc->frame_rx,
|
||||
rel15_ul->ulsch_pdu_rel15.number_symbols, proc->slot_rx, harq_pid, 0);
|
||||
|
||||
// if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
// n_errors++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
|
||||
|
||||
uint8_t symbol;
|
||||
|
||||
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
|
||||
nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end) {
|
||||
|
||||
uint8_t UE_id;
|
||||
uint8_t symbol;
|
||||
uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ)
|
||||
// In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ)
|
||||
|
||||
for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
|
||||
|
||||
|
||||
|
||||
for(symbol = symbol_start; symbol < symbol_end; symbol++) {
|
||||
|
||||
nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
|
||||
|
||||
}
|
||||
|
||||
nr_ulsch_procedures(gNB, proc, UE_id, harq_pid);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
|
||||
nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot);
|
||||
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp);
|
||||
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx,int slot_tx, int do_meas);
|
||||
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
|
||||
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc);
|
||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end);
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
|
||||
|
||||
@@ -546,7 +546,7 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms,
|
||||
frame, nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||
frame, nb_symb_sch, subframe, harq_pid, is_crnti);
|
||||
|
||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
n_errors++;
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
|
||||
#include "PHY/NR_REFSIG/nr_mod_table.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/MODULATION/modulation_eNB.h"
|
||||
#include "PHY/MODULATION/modulation_UE.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
@@ -51,13 +50,14 @@
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "SCHED_NR/sched_nr.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
|
||||
//#include "PHY/MODULATION/modulation_common.h"
|
||||
//#include "common/config/config_load_configmodule.h"
|
||||
//#include "UTIL/LISTS/list.h"
|
||||
//#include "common/ran_context.h"
|
||||
|
||||
//#define DEBUG_ULSCHSIM
|
||||
//#define DEBUG_ULSIM
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
@@ -194,14 +194,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
char c;
|
||||
int i,sf;
|
||||
double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0;
|
||||
double sigma2, sigma2_dB;
|
||||
double SNR, snr0 = -2.0, snr1 = 2.0;
|
||||
double sigma, sigma_dB;
|
||||
double snr_step = 0.1;
|
||||
uint8_t snr1set = 0;
|
||||
int slot = 0;
|
||||
int **txdata;
|
||||
int32_t **txdataF;
|
||||
int16_t **r_re, **r_im;
|
||||
FILE *output_fd = NULL;
|
||||
//uint8_t write_output_file = 0;
|
||||
int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
|
||||
@@ -216,22 +213,21 @@ int main(int argc, char **argv) {
|
||||
ulsim_params_t ulsim_params;
|
||||
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
|
||||
//unsigned char frame_type = 0;
|
||||
int frame = 0, subframe = 0;
|
||||
int frame = 0;
|
||||
int frame_length_complex_samples;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
double sigma;
|
||||
unsigned char qbits = 8;
|
||||
int ret;
|
||||
int loglvl = OAILOG_WARNING;
|
||||
uint64_t SSB_positions=0x01;
|
||||
uint16_t nb_symb_sch = 12;
|
||||
int start_symbol = NR_SYMBOLS_PER_SLOT - nb_symb_sch;
|
||||
uint16_t nb_rb = 50;
|
||||
uint8_t Imcs = 9;
|
||||
int eNB_id = 0;
|
||||
int ap;
|
||||
int tx_offset;
|
||||
double txlev;
|
||||
int start_rb = 0;
|
||||
int start_rb = 90;
|
||||
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
|
||||
@@ -444,6 +440,10 @@ int main(int argc, char **argv) {
|
||||
RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
|
||||
gNB = RC.gNB[0][0];
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
gNB_L1_rxtx_proc_t gNB_proc;
|
||||
|
||||
gNB_proc.frame_rx = frame;
|
||||
gNB_proc.slot_rx = slot;
|
||||
|
||||
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||
frame_parms->nb_antennas_tx = n_tx;
|
||||
@@ -461,15 +461,6 @@ int main(int argc, char **argv) {
|
||||
|
||||
frame_length_complex_samples = frame_parms->samples_per_subframe;
|
||||
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
|
||||
r_re = malloc(2 * sizeof(int16_t *));
|
||||
r_im = malloc(2 * sizeof(int16_t *));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
r_re[i] = malloc(frame_length_complex_samples * sizeof(int16_t));
|
||||
bzero(r_re[i], frame_length_complex_samples * sizeof(int16_t));
|
||||
r_im[i] = malloc(frame_length_complex_samples * sizeof(int16_t));
|
||||
bzero(r_im[i], frame_length_complex_samples * sizeof(int16_t));
|
||||
}
|
||||
|
||||
//configure UE
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
@@ -510,328 +501,114 @@ int main(int argc, char **argv) {
|
||||
ulsim_params.n_rnti = n_rnti;
|
||||
|
||||
unsigned char harq_pid = 0;
|
||||
uint8_t is_crnti = 0, llr8_flag = 0;
|
||||
uint8_t is_crnti = 0;
|
||||
unsigned int TBS = 8424;
|
||||
unsigned int available_bits;
|
||||
uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4;
|
||||
uint16_t length_dmrs = 1;
|
||||
unsigned char mod_order;
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[ulsim_params.UE_id+1][0];
|
||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
||||
|
||||
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
|
||||
mod_order = nr_get_Qm(Imcs, 1);
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
|
||||
TBS = nr_compute_tbs(Imcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, ulsim_params.Nl);
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[ulsim_params.UE_id+1][0];
|
||||
ulsch_gNB->harq_processes[harq_pid]->G = available_bits; // [hna] temp until length_dmrs and nb_re_dmrs are signaled
|
||||
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu;
|
||||
|
||||
NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0];
|
||||
|
||||
|
||||
printf("available bits %d TBS %d mod_order %d\n", available_bits, TBS, mod_order);
|
||||
|
||||
/////////// setting rel15_ul parameters ///////////
|
||||
rel15_ul->number_rbs = nb_rb;
|
||||
rel15_ul->number_symbols = nb_symb_sch;
|
||||
rel15_ul->Qm = mod_order;
|
||||
rel15_ul->mcs = Imcs;
|
||||
rel15_ul->rv = ulsim_params.rvidx;
|
||||
rel15_ul->n_layers = ulsim_params.Nl;
|
||||
// --------- setting rel15_ul parameters ----------
|
||||
rel15_ul->rnti = n_rnti;
|
||||
rel15_ul->ulsch_pdu_rel15.start_rb = start_rb;
|
||||
rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
|
||||
rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
|
||||
rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
|
||||
rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
|
||||
rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
|
||||
rel15_ul->ulsch_pdu_rel15.rv = ulsim_params.rvidx;
|
||||
rel15_ul->ulsch_pdu_rel15.n_layers = ulsim_params.Nl;
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
|
||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
|
||||
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
|
||||
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
|
||||
|
||||
unsigned char *estimated_output_bit;
|
||||
unsigned char *test_input_bit;
|
||||
unsigned char *test_input;
|
||||
unsigned int errors_bit_uncoded;
|
||||
unsigned int errors_bit;
|
||||
uint8_t bit_index;
|
||||
uint32_t error_extraction;
|
||||
uint32_t errors_scrambling;
|
||||
uint32_t scrambling_index;
|
||||
uint8_t symbol;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
unsigned int errors_bit = 0;
|
||||
uint32_t errors_scrambling = 0;
|
||||
|
||||
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
|
||||
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
|
||||
int UE_id = ulsim_params.UE_id;
|
||||
int UE_id = ulsim_params.UE_id; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
|
||||
|
||||
/////////////////////////phy_procedures_nr_ue_TX///////////////////////
|
||||
///////////
|
||||
|
||||
|
||||
for (i = 0; i < TBS / 8; i++)
|
||||
test_input[i] = (unsigned char) rand();
|
||||
|
||||
generate_ue_ulsch_params(UE,
|
||||
&ulsim_params,
|
||||
0,
|
||||
harq_pid,
|
||||
test_input);
|
||||
|
||||
|
||||
|
||||
nr_ue_ulsch_procedures(UE,
|
||||
harq_pid,
|
||||
slot,
|
||||
generate_ue_ulsch_params(UE,
|
||||
&ulsim_params,
|
||||
0,
|
||||
eNB_id);
|
||||
harq_pid,
|
||||
test_input);
|
||||
|
||||
nr_ue_pusch_common_procedures(UE,
|
||||
slot,
|
||||
ulsim_params.Nl,
|
||||
&UE->frame_parms);
|
||||
nr_ue_ulsch_procedures(UE,
|
||||
harq_pid,
|
||||
slot,
|
||||
0,
|
||||
eNB_id);
|
||||
|
||||
nr_ue_pusch_common_procedures(UE,
|
||||
slot,
|
||||
ulsim_params.Nl,
|
||||
&UE->frame_parms);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
tx_offset = slot*frame_parms->samples_per_slot;
|
||||
txdata = UE->common_vars.txdata;
|
||||
txdataF = UE->common_vars.txdataF;
|
||||
|
||||
for (i=0; i<frame_length_complex_samples; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
|
||||
r_re[ap][i] = ((int16_t *)txdata[ap])[(i<<1)];
|
||||
r_im[ap][i] = ((int16_t *)txdata[ap])[(i<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
txlev = (double) signal_energy_amp_shift(&txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
txlev = (double) signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
|
||||
txlev = txlev/512.0; // output of signal_energy is fixed point representation
|
||||
|
||||
txlev = txlev/(double)AMP; // output of signal_energy is fixed point representation
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||
|
||||
n_errors = 0;
|
||||
n_false_positive = 0;
|
||||
|
||||
SNR_lin = pow(10, SNR / 10.0);
|
||||
sigma = 1.0 / sqrt(2 * SNR_lin);
|
||||
|
||||
//AWGN
|
||||
sigma2_dB = 10*log10((double)txlev)-SNR;
|
||||
sigma2 = pow(10,sigma2_dB/10);
|
||||
|
||||
sigma_dB = 10*log10((double)txlev)-SNR;
|
||||
sigma = pow(10,sigma_dB/10);
|
||||
|
||||
for (trial = 0; trial < n_trials; trial++) {
|
||||
|
||||
errors_bit_uncoded = 0;
|
||||
error_extraction = 0;
|
||||
errors_scrambling = 0;
|
||||
errors_bit = 0;
|
||||
scrambling_index = 0;
|
||||
|
||||
for (i=0; i<frame_length_complex_samples; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((short*) gNB->common_vars.rxdata[ap])[2*i] = (r_re[ap][i] + (int16_t)(sqrt(sigma2/2)*gaussdouble(0.0,1.0)*(double)AMP)); // convert to fixed point
|
||||
((short*) gNB->common_vars.rxdata[ap])[2*i+1] = (r_im[ap][i] + (int16_t)(sqrt(sigma2/2)*gaussdouble(0.0,1.0)*(double)AMP));
|
||||
|
||||
// [hna] doesn't work with noise in case of mod_order = 6
|
||||
((short*) gNB->common_vars.rxdata[ap])[2*i] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]);// + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP)); // convert to fixed point
|
||||
((short*) gNB->common_vars.rxdata[ap])[2*i+1] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]);// + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
#ifdef DEBUG_CODER
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Modulate bit-wise the scrambled output //
|
||||
////////////////////////////////////////////
|
||||
|
||||
bit_index = i & 0x1f;
|
||||
|
||||
if ((bit_index == 0) && (i != 0)) {
|
||||
scrambling_index++;
|
||||
}
|
||||
|
||||
if(((scrambled_output[0][scrambling_index] >> bit_index) & 1) == 0)
|
||||
modulated_input[i] = 1.0; ///sqrt(2); //QPSK
|
||||
else
|
||||
modulated_input[i] = -1.0; ///sqrt(2);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
#if 1
|
||||
channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0,
|
||||
modulated_input[i] + sigma * gaussdouble(0.0, 1.0),
|
||||
qbits);
|
||||
#else
|
||||
channel_output_fixed[i] = (short) quantize(0.01, modulated_input[i], qbits);
|
||||
#endif
|
||||
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
|
||||
//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
|
||||
|
||||
//Uncoded BER
|
||||
if (channel_output_fixed[i] < 0)
|
||||
channel_output_uncoded[i] = 1; //QPSK demod
|
||||
else
|
||||
channel_output_uncoded[i] = 0;
|
||||
|
||||
if (channel_output_uncoded[i] != ((scrambled_output[0][scrambling_index] >> bit_index) & 1)) {
|
||||
errors_bit_uncoded = errors_bit_uncoded + 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("errors bits uncoded = %u\n", errors_bit_uncoded);
|
||||
|
||||
|
||||
#ifdef DEBUG_CODER
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
phy_procedures_gNB_common_RX(gNB, &gNB_proc);
|
||||
|
||||
|
||||
uint32_t nb_re, nb_rb_per_antenna;
|
||||
uint32_t rxdataF_ext_offset = 0; // [hna] should be a member in the NR_gNB_PUSCH struct
|
||||
uint32_t rxdata_offset = 0;
|
||||
uint32_t d_mod_offset = 0;
|
||||
uint32_t llr_offset = 0; // [hna] should be a member in the NR_gNB_PUSCH struct
|
||||
uint32_t start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB);
|
||||
uint8_t sch_sym_start = NR_SYMBOLS_PER_SLOT - nb_symb_sch;
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
|
||||
switch (frame_parms->ofdm_symbol_size) {
|
||||
case 128:
|
||||
dft = dft128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
dft = dft256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
dft = dft512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
dft = dft1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
dft = dft1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
dft = dft2048;
|
||||
break;
|
||||
|
||||
case 4096:
|
||||
dft = dft4096;
|
||||
break;
|
||||
|
||||
case 8192:
|
||||
dft = dft8192;
|
||||
break;
|
||||
|
||||
default:
|
||||
dft = dft512;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
|
||||
|
||||
//----------------------------------------------------------
|
||||
//-------------------------- DFT ---------------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if(symbol == 0)
|
||||
rxdata_offset = frame_parms->nb_prefix_samples0;
|
||||
else
|
||||
rxdata_offset = frame_parms->nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples));
|
||||
|
||||
dft((int16_t *)&gNB->common_vars.rxdata[0][rxdata_offset],
|
||||
(int16_t *)&gNB->common_vars.rxdataF[0][symbol*frame_parms->ofdm_symbol_size],1);
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// [hna] start RBs extraction and llr_computation starting from sch_sym_start
|
||||
if(symbol < sch_sym_start)
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- RBs extraction ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nb_rb_per_antenna = nr_ulsch_extract_rbs_single(UE->common_vars.txdataF,
|
||||
gNB->pusch_vars[UE_id]->rxdataF_ext,
|
||||
rxdataF_ext_offset,
|
||||
// rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
|
||||
symbol,
|
||||
start_rb,
|
||||
nb_rb,
|
||||
frame_parms);
|
||||
|
||||
for(i = 0; i < nb_re; i++)
|
||||
{
|
||||
if(symbol != 2)
|
||||
if(gNB->pusch_vars[UE_id]->rxdataF_ext[0][rxdataF_ext_offset + i] != UE->common_vars.txdataF[0][(symbol*frame_parms->ofdm_symbol_size) + ((i+start_re) % frame_parms->ofdm_symbol_size)])
|
||||
error_extraction++;
|
||||
}
|
||||
|
||||
rxdataF_ext_offset = rxdataF_ext_offset + nb_re;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//-------------------- LLRs computation --------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][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 bits (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, gNB->pusch_vars[UE_id]->llr, frame_parms, frame,
|
||||
nb_symb_sch, subframe, harq_pid, is_crnti, llr8_flag);
|
||||
|
||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
n_errors++;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
phy_procedures_gNB_uespec_RX(gNB, &gNB_proc, rel15_ul->ulsch_pdu_rel15.start_symbol, rel15_ul->ulsch_pdu_rel15.start_symbol + rel15_ul->ulsch_pdu_rel15.number_symbols);
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//---------------------- count errors ----------------------
|
||||
//----------------------------------------------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
for (i = 0; i < TBS; i++) {
|
||||
|
||||
@@ -867,8 +644,7 @@ int main(int argc, char **argv) {
|
||||
} // [hna] for (trial = 0; trial < n_trials; trial++)
|
||||
|
||||
printf("*****************************************\n");
|
||||
printf("SNR %f, BLER %f (false positive %f)\n", SNR,
|
||||
(float) n_errors / (float) n_trials,
|
||||
printf("SNR %f, (false positive %f)\n", SNR,
|
||||
(float) n_false_positive / (float) n_trials);
|
||||
printf("*****************************************\n");
|
||||
|
||||
@@ -904,15 +680,6 @@ int main(int argc, char **argv) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
free(r_re[i]);
|
||||
free(r_im[i]);
|
||||
}
|
||||
|
||||
free(r_re);
|
||||
free(r_im);
|
||||
free(txdata);
|
||||
|
||||
if (output_fd)
|
||||
fclose(output_fd);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user