Merge remote-tracking branch 'origin/develop' into benetel_phase_rotation
This commit is contained in:
@@ -469,6 +469,9 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
unsigned int *F,
|
||||
uint8_t BG);
|
||||
|
||||
/*!\fn uint32_t nr_compute_tbs
|
||||
\brief This function returns the TBS in bits as per 6.1.4.2 of TS 38.214
|
||||
*/
|
||||
uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
uint16_t R,
|
||||
uint16_t nb_rb,
|
||||
@@ -480,8 +483,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
|
||||
uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
uint16_t nb_rb,
|
||||
uint8_t Nl,
|
||||
uint8_t C);
|
||||
uint8_t Nl);
|
||||
|
||||
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f);
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (E + F <= Ncb-ind) { //E+F doesn't contain all coded bits
|
||||
if (E <= Ncb-ind) { //E+F doesn't contain all coded bits
|
||||
memcpy((void*)(e),(void*)(w+ind),E);
|
||||
k=E;
|
||||
}
|
||||
|
||||
@@ -121,13 +121,13 @@ int phy_init_RU(RU_t *ru) {
|
||||
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
|
||||
//AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
//"nb_antennas_rx too large");
|
||||
ru->prach_rxsigF = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
|
||||
ru->prach_rxsigF[0] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
|
||||
|
||||
for (j=0; j<4; j++) ru->prach_rxsigF_br[j] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
ru->prach_rxsigF[i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
|
||||
ru->prach_rxsigF[0][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[0][i]);
|
||||
|
||||
for (j=0; j<4; j++) {
|
||||
ru->prach_rxsigF_br[j][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
|
||||
@@ -230,14 +230,14 @@ void phy_free_RU(RU_t *ru) {
|
||||
}
|
||||
|
||||
for (i = 0; i < ru->nb_rx; i++) {
|
||||
free_and_zero(ru->prach_rxsigF[i]);
|
||||
free_and_zero(ru->prach_rxsigF[0][i]);
|
||||
|
||||
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]);
|
||||
|
||||
free_and_zero(ru->prach_rxsigF);
|
||||
free_and_zero(ru->prach_rxsigF[0]);
|
||||
/* ru->prach_rxsigF_br is not allocated -> don't free */
|
||||
|
||||
for (i = 0; i < RC.nb_L1_inst; i++) {
|
||||
|
||||
@@ -251,10 +251,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ptrs_phase_per_slot = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
|
||||
pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
|
||||
@@ -263,21 +264,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
for (i=0; i<Prx; i++) {
|
||||
pusch_vars[ULSCH_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot); // symbols per slot
|
||||
pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
|
||||
pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
|
||||
}
|
||||
printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
|
||||
pusch_vars[ULSCH_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
|
||||
printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
|
||||
printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
|
||||
pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot);
|
||||
} //ulsch_id
|
||||
/*
|
||||
for (ulsch_id=0; ulsch_id<NUMBER_OF_UE_MAX; ulsch_id++)
|
||||
@@ -338,6 +341,7 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]);
|
||||
@@ -353,6 +357,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_valid_re_per_slot);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
|
||||
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0);
|
||||
@@ -491,11 +497,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
|
||||
fd_occasion = 0;
|
||||
nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
|
||||
short_sequence = prach_config->prach_sequence_length.value;
|
||||
// for(fd_occasion = 0; fd_occasion <= prach_config->num_prach_fd_occasions.value ; fd_occasion) { // TODO Need to handle for msg1-fdm > 1
|
||||
num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value;
|
||||
rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value;
|
||||
|
||||
compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
|
||||
|
||||
// }
|
||||
RC.gNB[Mod_id]->configured = 1;
|
||||
|
||||
init_symbol_rotation(fp,fp->dl_CarrierFreq);
|
||||
|
||||
@@ -107,12 +107,14 @@ int nr_phy_init_RU(RU_t *ru) {
|
||||
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
|
||||
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
|
||||
// "nb_antennas_rx too large");
|
||||
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
// largest size for PRACH FFT is 4x98304 (16*24576)
|
||||
ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
|
||||
|
||||
for (i=0; i<ru->nb_rx; i++) {
|
||||
// largest size for PRACH FFT is 4x98304 (16*24576)
|
||||
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
|
||||
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(RC.nb_nr_L1_inst <= NUMBER_OF_eNB_MAX,"gNB instances %d > %d\n",
|
||||
@@ -186,10 +188,12 @@ void nr_phy_free_RU(RU_t *ru)
|
||||
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
|
||||
free_and_zero(ru->common.rxdataF);
|
||||
|
||||
for (i = 0; i < ru->nb_rx; i++) {
|
||||
free_and_zero(ru->prach_rxsigF[i]);
|
||||
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
|
||||
for (i = 0; i < ru->nb_rx; i++) {
|
||||
free_and_zero(ru->prach_rxsigF[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < RC.nb_nr_L1_inst; i++) {
|
||||
for (p = 0; p < 15; p++) {
|
||||
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
|
||||
|
||||
@@ -49,7 +49,7 @@ void send_IF4p5(RU_t *ru,
|
||||
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
|
||||
int32_t **txdataF = ru->common.txdataF_BF;
|
||||
int32_t **rxdataF = ru->common.rxdataF;
|
||||
int16_t **prach_rxsigF = ru->prach_rxsigF;
|
||||
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
|
||||
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
|
||||
void *tx_buffer = ru->ifbuffer.tx[subframe&1];
|
||||
void *tx_buffer_prach = ru->ifbuffer.tx_prach;
|
||||
@@ -276,7 +276,7 @@ void recv_IF4p5(RU_t *ru,
|
||||
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
|
||||
int32_t **txdataF = ru->common.txdataF_BF;
|
||||
int32_t **rxdataF = ru->common.rxdataF;
|
||||
int16_t **prach_rxsigF = ru->prach_rxsigF;
|
||||
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
|
||||
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
|
||||
void *rx_buffer = ru->ifbuffer.rx;
|
||||
uint16_t element_id;
|
||||
|
||||
@@ -167,7 +167,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
||||
br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
|
||||
}
|
||||
} else {
|
||||
rxsigF = ru->prach_rxsigF;
|
||||
rxsigF = ru->prach_rxsigF[0];
|
||||
|
||||
if (LOG_DEBUGFLAG(PRACH)) {
|
||||
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "nr_ul_estimation.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
|
||||
//#define DEBUG_CH
|
||||
@@ -507,3 +509,408 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_pusch_ptrs_processing
|
||||
*
|
||||
* PARAMETERS : gNB : gNB data structure
|
||||
* rel15_ul : UL parameters
|
||||
* UE_id : UE ID
|
||||
* nr_tti_rx : slot rx TTI
|
||||
* dmrs_symbol_flag: DMRS Symbol Flag
|
||||
* symbol : OFDM Symbol
|
||||
* nb_re_pusch : PUSCH RE's
|
||||
* nb_re_pusch : PUSCH RE's
|
||||
*
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* If ptrs is enabled process the symbol accordingly
|
||||
* 1) Estimate phase noise per PTRS symbol
|
||||
* 2) Interpolate PTRS estimated value in TD after all PTRS symbols
|
||||
* 3) Compensated DMRS based estimated signal with PTRS estimation for slot
|
||||
*********************************************************************/
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
uint8_t ulsch_id,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t dmrs_symbol_flag,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int16_t *phase_per_symbol;
|
||||
|
||||
uint8_t L_ptrs = 0;
|
||||
uint8_t right_side_ref = 0;
|
||||
uint8_t left_side_ref = 0;
|
||||
uint8_t nb_dmrs_in_slot = 0;
|
||||
|
||||
//#define DEBUG_UL_PTRS 1
|
||||
/* First symbol calculate PTRS symbol index for slot & set the variables */
|
||||
if(symbol == rel15_ul->start_symbol_index)
|
||||
{
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
|
||||
L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
|
||||
set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
|
||||
rel15_ul->nr_of_symbols,
|
||||
rel15_ul->start_symbol_index,
|
||||
L_ptrs,
|
||||
rel15_ul->ul_dmrs_symb_pos);
|
||||
}/* First symbol check */
|
||||
|
||||
/* loop over antennas */
|
||||
for (int aarx=0; aarx< frame_parms->nb_antennas_rx; aarx++)
|
||||
{
|
||||
phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx];
|
||||
/* set the previous estimations to zero at first symbol */
|
||||
if(symbol == rel15_ul->start_symbol_index)
|
||||
{
|
||||
memset(phase_per_symbol,0,sizeof(int32_t)*frame_parms->symbols_per_slot);
|
||||
}
|
||||
/* if not PTRS symbol set current ptrs symbol index to zero*/
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = 0;
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
|
||||
/* Check if current symbol contains PTRS */
|
||||
if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
|
||||
{
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 1) Estimate phase noise per PTRS symbol */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
nr_pusch_phase_estimation(frame_parms,
|
||||
rel15_ul,
|
||||
(int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch],
|
||||
nr_tti_rx,
|
||||
symbol,
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
|
||||
gNB->nr_gold_pusch_dmrs[rel15_ul->scid],
|
||||
&phase_per_symbol[2* symbol],
|
||||
&gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol);
|
||||
}
|
||||
/* DMRS Symbol channel estimates extraction */
|
||||
else if(dmrs_symbol_flag)
|
||||
{
|
||||
phase_per_symbol[2* symbol]= (int16_t)((1<<15)-1); // 32767
|
||||
phase_per_symbol[2* symbol +1]= 0;// no angle
|
||||
}
|
||||
/* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
|
||||
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
|
||||
{
|
||||
nb_dmrs_in_slot = get_dmrs_symbols_in_slot(rel15_ul->ul_dmrs_symb_pos,(rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
for(uint8_t dmrs_sym = 0; dmrs_sym < nb_dmrs_in_slot; dmrs_sym ++)
|
||||
{
|
||||
if(dmrs_sym == 0)
|
||||
{
|
||||
/* get first DMRS position */
|
||||
left_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
/* get first DMRS position is not at start symbol position then we need to extrapolate left side */
|
||||
if(left_side_ref > rel15_ul->start_symbol_index)
|
||||
{
|
||||
left_side_ref = rel15_ul->start_symbol_index;
|
||||
}
|
||||
}
|
||||
/* get the next symbol from left_side_ref value */
|
||||
right_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, left_side_ref+1, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
/* if no symbol found then interpolate till end of slot*/
|
||||
if(right_side_ref == 0)
|
||||
{
|
||||
right_side_ref = (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
|
||||
}
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 2) Interpolate PTRS estimated value in TD */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
nr_pusch_phase_interpolation(phase_per_symbol,left_side_ref,right_side_ref);
|
||||
/* set left to last dmrs */
|
||||
left_side_ref = right_side_ref;
|
||||
} /*loop over dmrs positions */
|
||||
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
LOG_M("ptrsEst.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
|
||||
LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
|
||||
rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
|
||||
/*--------------------------------------------------------------------------------------------------------*/
|
||||
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++)
|
||||
{
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
|
||||
#endif
|
||||
rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
&phase_per_symbol[2* i],
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
(rel15_ul->rb_size * NR_NB_SC_PER_RB),
|
||||
15);
|
||||
}// symbol loop
|
||||
}//interpolation and compensation
|
||||
}// Antenna loop
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_pusch_phase_estimation
|
||||
*
|
||||
* PARAMETERS : frame_parms : UL frame parameters
|
||||
* rel15_ul : UL PDU Structure
|
||||
* Ns :
|
||||
* Symbol : OFDM symbol index
|
||||
* rxF : Channel compensated signal
|
||||
* ptrs_gold_seq: Gold sequence for PTRS regeneration
|
||||
* error_est : Estimated error output vector [Re Im]
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* perform phase estimation from regenerated PTRS SC and channel compensated
|
||||
* signal
|
||||
*********************************************************************/
|
||||
void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
int16_t *ptrs_ch_p,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t ***ptrs_gold_seq,
|
||||
int16_t *error_est,
|
||||
uint16_t *ptrs_sc)
|
||||
{
|
||||
uint8_t is_ptrs_re = 0;
|
||||
uint16_t re_cnt = 0;
|
||||
uint16_t cnt = 0;
|
||||
unsigned short nb_re_pusch = NR_NB_SC_PER_RB * rel15_ul->rb_size;
|
||||
uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density;
|
||||
uint16_t sc_per_symbol = (rel15_ul->rb_size + K_ptrs - 1)/K_ptrs;
|
||||
int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
|
||||
int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
|
||||
double abs = 0.0;
|
||||
double real = 0.0;
|
||||
double imag = 0.0;
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
double alpha = 0;
|
||||
#endif
|
||||
/* generate PTRS RE for the symbol */
|
||||
nr_gen_ref_conj_symbols(ptrs_gold_seq[Ns][symbol],sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK
|
||||
|
||||
/* loop over all sub carriers to get compensated RE on ptrs symbols*/
|
||||
for (int re = 0; re < nb_re_pusch; re++)
|
||||
{
|
||||
is_ptrs_re = is_ptrs_subcarrier(re,
|
||||
rel15_ul->rnti,
|
||||
0,
|
||||
rel15_ul->dmrs_config_type,
|
||||
K_ptrs,
|
||||
rel15_ul->rb_size,
|
||||
rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
0,// start_re is 0 here
|
||||
frame_parms->ofdm_symbol_size);
|
||||
if(is_ptrs_re)
|
||||
{
|
||||
dmrs_comp_p[re_cnt*2] = rxF_comp[re *2];
|
||||
dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1];
|
||||
re_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip PTRS symbols and keep data in a continuous vector */
|
||||
rxF_comp[cnt *2]= rxF_comp[re *2];
|
||||
rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1];
|
||||
cnt++;
|
||||
}
|
||||
}/* RE loop */
|
||||
/* update the total ptrs RE in a symbol */
|
||||
*ptrs_sc = re_cnt;
|
||||
|
||||
/*Multiple compensated data with conj of PTRS */
|
||||
mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted
|
||||
|
||||
/* loop over all ptrs sub carriers in a symbol */
|
||||
/* sum the error vector */
|
||||
for(int i = 0;i < sc_per_symbol; i++)
|
||||
{
|
||||
real+= ptrs_ch_p[(2*i)];
|
||||
imag+= ptrs_ch_p[(2*i)+1];
|
||||
}
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
alpha = atan(imag/real);
|
||||
printf("PTRS: Symbol %d atan(Im,real):= %f \n",symbol, alpha );
|
||||
#endif
|
||||
/* mean */
|
||||
real /= sc_per_symbol;
|
||||
imag /= sc_per_symbol;
|
||||
/* absolute calculation */
|
||||
abs = sqrt(((real * real) + (imag * imag)));
|
||||
/* normalized error estimation */
|
||||
error_est[0]= (real / abs)*(1<<15);
|
||||
/* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/
|
||||
error_est[1]= (-1)*(imag / abs)*(1<<15);
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] );
|
||||
#endif
|
||||
/* free vectors */
|
||||
free(ptrs_p);
|
||||
free(dmrs_comp_p);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_pusch_phase_interpolation
|
||||
*
|
||||
* PARAMETERS : *error_est : Data Pointer [Re Im Re Im ...]
|
||||
* start_symbol : Start Symbol
|
||||
* end_symbol : End Symbol
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* Perform Interpolation, extrapolation based upon the estimation
|
||||
* location between the data Pointer Array.
|
||||
*
|
||||
*********************************************************************/
|
||||
void nr_pusch_phase_interpolation(int16_t *error_est,
|
||||
uint8_t start_symbol,
|
||||
uint8_t end_symbol
|
||||
)
|
||||
{
|
||||
|
||||
int next = 0, prev = 0, candidates= 0, distance=0, leftEdge= 0, rightEdge = 0, getDiff =0 ;
|
||||
double weight = 0.0;
|
||||
double scale = 0.125 ; // to avoid saturation due to fixed point multiplication
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Left limit %d, Right limit %d, Loop over %d Symbols \n",
|
||||
start_symbol,end_symbol-1, (end_symbol -start_symbol)-1);
|
||||
#endif
|
||||
for(int i =start_symbol; i< end_symbol;i++)
|
||||
{
|
||||
/* Only update when an estimation is found */
|
||||
if( error_est[i*2] != 0 )
|
||||
{
|
||||
/* if found a symbol then set next symbol also */
|
||||
next = nr_ptrs_find_next_estimate(error_est, i, end_symbol);
|
||||
/* left extrapolation, if first estimate value is zero */
|
||||
if( error_est[i*2] == 0 )
|
||||
{
|
||||
leftEdge = 1;
|
||||
}
|
||||
/* right extrapolation, if next is 0 before end symbol */
|
||||
if((next == 0) && (end_symbol > i))
|
||||
{
|
||||
rightEdge = 1;
|
||||
/* special case as no right extrapolation possible with DMRS on left */
|
||||
/* In this case take mean of most recent 2 estimated points */
|
||||
if(prev ==0)
|
||||
{
|
||||
prev = start_symbol -1;
|
||||
next = start_symbol -2;
|
||||
getDiff =1;
|
||||
}else
|
||||
{
|
||||
/* for right edge previous is second last from right side */
|
||||
next = prev;
|
||||
/* Set the current as recent estimation reference */
|
||||
prev = i;
|
||||
}
|
||||
}
|
||||
/* update current symbol as prev for next symbol */
|
||||
if (rightEdge==0)
|
||||
/* Set the current as recent estimation reference */
|
||||
prev = i;
|
||||
}
|
||||
/*extrapolation left side*/
|
||||
if(leftEdge)
|
||||
{
|
||||
distance = next - prev;
|
||||
weight = 1.0/distance;
|
||||
candidates = i;
|
||||
for(int j = 1; j <= candidates; j++)
|
||||
{
|
||||
error_est[(i-j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[next*2]) * scale * j * weight));
|
||||
error_est[((i-j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale* (distance + j) * weight) -
|
||||
((double)(error_est[((next*2)+1)]) * scale * j * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Left Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i-j),weight, error_est[(i-j)*2],error_est[((i-j)*2)+1], prev,next);
|
||||
#endif
|
||||
}
|
||||
leftEdge = 0;
|
||||
}
|
||||
/* extrapolation at right side */
|
||||
else if (rightEdge )
|
||||
{
|
||||
if(getDiff)
|
||||
{
|
||||
error_est[(i+1)*2] = ((1<<15) +(error_est[prev*2]) - error_est[next*2]);
|
||||
error_est[((i+1)*2)+1]= error_est[(prev*2)+1] - error_est[(next*2)+1];
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Right Edge Special Case i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i+1),weight, error_est[(i+1)*2],error_est[((i+1)*2)+1], prev,next);
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = prev - next;
|
||||
candidates = (end_symbol -1) - i;
|
||||
weight = 1.0/distance;
|
||||
for(int j = 1; j <= candidates; j++)
|
||||
{
|
||||
error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[next*2]) * scale * j * weight));
|
||||
error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[((next*2)+1)]) * scale *j * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Right Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1], prev,next);
|
||||
#endif
|
||||
}
|
||||
if(candidates > 1)
|
||||
{
|
||||
i+=candidates;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Interpolation between 2 estimated points */
|
||||
else if(next != 0 && ( error_est[2*i] == 0 ))
|
||||
{
|
||||
distance = next - prev;
|
||||
weight = 1.0/distance;
|
||||
candidates = next - i ;
|
||||
for(int j = 0; j < candidates; j++)
|
||||
{
|
||||
|
||||
error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance - (j+1)) * weight) +
|
||||
((double)(error_est[next*2]) * scale * (j+1) * weight));
|
||||
error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale *(distance - (j+1)) * weight) +
|
||||
((double)(error_est[((next*2)+1)]) * scale *(j+1) * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Interpolation i= %d weight= %f %d + j*%d, Prev %d Next %d\n",
|
||||
(i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1],prev,next);
|
||||
#endif
|
||||
}
|
||||
if(candidates > 1)
|
||||
{
|
||||
i+=candidates-1;
|
||||
}
|
||||
}// interpolation
|
||||
}// symbol loop
|
||||
}
|
||||
|
||||
/* Find the next non zero Real value in a complex vector */
|
||||
int nr_ptrs_find_next_estimate(int16_t *error_est,
|
||||
uint8_t counter,
|
||||
uint8_t end_symbol)
|
||||
{
|
||||
for (int i = counter +1 ; i< end_symbol; i++)
|
||||
{
|
||||
if( error_est[2*i] != 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -51,4 +51,30 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB);
|
||||
|
||||
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
|
||||
|
||||
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
uint8_t ulsch_id,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t dmrs_symbol_flag,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch);
|
||||
|
||||
void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
int16_t *ptrs_ch_p,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t ***ptrs_gold_seq,
|
||||
int16_t *error_est,
|
||||
uint16_t *ptrs_sc);
|
||||
|
||||
void nr_pusch_phase_interpolation(int16_t *error_est,
|
||||
uint8_t start_symbol,
|
||||
uint8_t end_symbol);
|
||||
|
||||
int nr_ptrs_find_next_estimate(int16_t *error_est,
|
||||
uint8_t counter,
|
||||
uint8_t end_symbol);
|
||||
#endif
|
||||
|
||||
@@ -362,4 +362,25 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H
|
||||
free(dmrs_sequence);
|
||||
#endif
|
||||
}
|
||||
/* return the position of next dmrs symbol in a slot */
|
||||
int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol)
|
||||
{
|
||||
for(uint8_t symbol = counter; symbol < end_symbol; symbol++)
|
||||
if((ul_dmrs_symb_pos >>symbol)&0x01 )
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* return the total number of dmrs symbol in a slot */
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb)
|
||||
{
|
||||
uint8_t tmp = 0;
|
||||
for (int i = 0; i < nb_symb; i++)
|
||||
{
|
||||
tmp += (l_prime_mask >> i) & 0x01;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -223,3 +223,27 @@ int nr_pbch_dmrs_rx(int symbol,
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief This function generate gold ptrs sequence for each OFDM symbol
|
||||
\param *in gold sequence for ptrs per OFDM symbol
|
||||
\param length is number of RE in a OFDM symbol
|
||||
\param *output pointer to all ptrs RE in a OFDM symbol
|
||||
*/
|
||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order)
|
||||
{
|
||||
uint8_t idx, b_idx;
|
||||
for (int i=0; i<length/mod_order; i++)
|
||||
{
|
||||
idx = 0;
|
||||
for (int j=0; j<mod_order; j++)
|
||||
{
|
||||
b_idx = (i*mod_order+j)&0x1f;
|
||||
if (i && (!b_idx))
|
||||
in++;
|
||||
idx ^= (((*in)>>b_idx)&1)<<(mod_order-j-1);
|
||||
}
|
||||
output[i<<1] = nr_rx_mod_table[(offset+idx)<<1];
|
||||
output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void init_scrambling_luts(void);
|
||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
||||
uint8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
|
||||
|
||||
void nr_generate_modulation_table(void);
|
||||
|
||||
|
||||
@@ -39,95 +39,6 @@
|
||||
//#define DEBUG_DCI
|
||||
//#define DEBUG_CHANNEL_CODING
|
||||
|
||||
|
||||
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
||||
nfapi_nr_rnti_type_e rnti_type,
|
||||
uint16_t N_RB) {
|
||||
uint16_t size = 0;
|
||||
|
||||
switch(format) {
|
||||
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
|
||||
case NFAPI_NR_UL_DCI_FORMAT_0_0:
|
||||
/// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
|
||||
size += 20;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
|
||||
size += nr_get_dci_size(NFAPI_NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB) - size; // Padding to match 1_0 size
|
||||
// UL/SUL indicator assumed to be 0
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UL_DCI_FORMAT_0_1:
|
||||
/// fixed: Format identifier 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2, SRS request 2 --17
|
||||
size += 17;
|
||||
// Carrier indicator
|
||||
// UL/SUL indicator
|
||||
// BWP Indicator
|
||||
// Freq domain assignment
|
||||
// Time domain assignment
|
||||
// VRB to PRB mapping
|
||||
// Frequency Hopping flag
|
||||
// 1st DAI
|
||||
// 2nd DAI
|
||||
// SRS resource indicator
|
||||
// Precoding info and number of layers
|
||||
// Antenna ports
|
||||
// CSI request
|
||||
// CBGTI
|
||||
// PTRS - DMRS association
|
||||
// beta offset indicator
|
||||
// DMRS sequence init
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_1_0:
|
||||
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
|
||||
size += 28;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_1_1:
|
||||
// Carrier indicator
|
||||
size += 1; // Format identifier
|
||||
// BWP Indicator
|
||||
// Freq domain assignment
|
||||
// Time domain assignment
|
||||
// VRB to PRB mapping
|
||||
// PRB bundling size indicator
|
||||
// Rate matching indicator
|
||||
// ZP CSI-RS trigger
|
||||
/// TB1- MCS 5, NDI 1, RV 2
|
||||
size += 8;
|
||||
// TB2
|
||||
size += 4 ; // HARQ PID
|
||||
// DAI
|
||||
size += 2; // TPC PUCCH
|
||||
size += 3; // PUCCH resource indicator
|
||||
size += 3; // PDSCH to HARQ timing indicator
|
||||
// Antenna ports
|
||||
// Tx Config Indication
|
||||
size += 2; // SRS request
|
||||
// CBGTI
|
||||
// CBGFI
|
||||
size += 1; // DMRS sequence init
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_0:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_1:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_2:
|
||||
break;
|
||||
|
||||
case NFAPI_NR_DL_DCI_FORMAT_2_3:
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(1==0, "Invalid NR DCI format %d\n", format);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void nr_pdcch_scrambling(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
@@ -153,37 +64,23 @@ void nr_pdcch_scrambling(uint32_t *in,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS frame_parms) {
|
||||
void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS frame_parms) {
|
||||
|
||||
int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration
|
||||
uint16_t cset_start_sc;
|
||||
uint8_t cset_start_symb, cset_nsymb;
|
||||
int k,l,k_prime,dci_idx, dmrs_idx;
|
||||
/*First iteration: single DCI*/
|
||||
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15=NULL;
|
||||
|
||||
|
||||
// find coreset descriptor
|
||||
|
||||
int rb_offset;
|
||||
int n_rb;
|
||||
|
||||
AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
|
||||
AssertFatal(pdcch_pdu==NULL || ul_dci_pdu==NULL,"Can't handle both DL and UL DCI in same slot\n");
|
||||
|
||||
|
||||
if (pdcch_pdu) pdcch_pdu_rel15 = &pdcch_pdu->pdcch_pdu_rel15;
|
||||
else if (ul_dci_pdu) pdcch_pdu_rel15 = &ul_dci_pdu->pdcch_pdu_rel15;
|
||||
|
||||
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
|
||||
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
@@ -330,6 +227,25 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
} // reg_idx
|
||||
|
||||
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
int32_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS frame_parms) {
|
||||
|
||||
AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n");
|
||||
|
||||
if (pdcch_pdu && ul_dci_pdu) {
|
||||
nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
}
|
||||
else if (pdcch_pdu)
|
||||
nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
else
|
||||
nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
|
||||
nfapi_nr_rnti_type_e rnti_type,
|
||||
uint16_t N_RB);
|
||||
|
||||
uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
void nr_generate_dci_top(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu *ul_pdcch_pdu,
|
||||
uint32_t **gold_pdcch_dmrs,
|
||||
|
||||
@@ -527,7 +527,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
if (rel15->nrOfLayers < Nl)
|
||||
Nl = rel15->nrOfLayers;
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl,dlsch->harq_processes[harq_pid]->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
|
||||
|
||||
start_meas(dlsch_rate_matching_stats);
|
||||
nr_rate_matching_ldpc(Ilbrm,
|
||||
|
||||
@@ -37,31 +37,42 @@
|
||||
extern uint16_t prach_root_sequence_map_0_3[838];
|
||||
extern uint16_t prach_root_sequence_map_abc[138];
|
||||
extern uint16_t nr_du[838];
|
||||
extern const char *prachfmt[9];
|
||||
extern const char *prachfmt[];
|
||||
|
||||
void init_prach_list(PHY_VARS_gNB *gNB) {
|
||||
|
||||
AssertFatal(gNB!=NULL,"gNB is null\n");
|
||||
for (int i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) gNB->prach_vars.list[i].frame=-1;
|
||||
for (int i=0; i<NUMBER_OF_NR_PRACH_MAX; i++){
|
||||
gNB->prach_vars.list[i].frame = -1;
|
||||
gNB->prach_vars.list[i].slot = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) {
|
||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) {
|
||||
|
||||
uint16_t i;
|
||||
int16_t first_free_index=-1;
|
||||
gNB->prach_vars.list[prach_id].frame = -1;
|
||||
gNB->prach_vars.list[prach_id].slot = -1;
|
||||
|
||||
}
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
|
||||
|
||||
AssertFatal(gNB!=NULL,"gNB is null\n");
|
||||
for (i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
|
||||
LOG_D(PHY,"searching for PRACH in %d.%d with numRA %d: prach_index %d=> %d.%d numRA %d\n", frame,slot,numRA,i,
|
||||
gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra);
|
||||
if ((gNB->prach_vars.list[i].frame == frame) &&
|
||||
(gNB->prach_vars.list[i].slot == slot) &&
|
||||
(gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i;
|
||||
else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
|
||||
for (uint16_t i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
|
||||
LOG_D(PHY,"searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame,slot,i,
|
||||
gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot);
|
||||
if((type == SEARCH_EXIST_OR_FREE) &&
|
||||
(gNB->prach_vars.list[i].frame == -1) &&
|
||||
(gNB->prach_vars.list[i].slot == -1)) {
|
||||
return i;
|
||||
}
|
||||
else if ((type == SEARCH_EXIST) &&
|
||||
(gNB->prach_vars.list[i].frame == frame) &&
|
||||
(gNB->prach_vars.list[i].slot == slot)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (type == SEARCH_EXIST) return -1;
|
||||
|
||||
return first_free_index;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
@@ -69,9 +80,9 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu) {
|
||||
|
||||
int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal( (prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX),
|
||||
"illegal or no prach_id found!!! numRA %d prach_id %d\n",prach_pdu->num_ra,prach_id);
|
||||
int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0),
|
||||
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
|
||||
|
||||
gNB->prach_vars.list[prach_id].frame=SFN;
|
||||
gNB->prach_vars.list[prach_id].slot=Slot;
|
||||
@@ -82,31 +93,35 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
void init_prach_ru_list(RU_t *ru) {
|
||||
|
||||
AssertFatal(ru!=NULL,"ruis null\n");
|
||||
for (int i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) ru->prach_list[i].frame=-1;
|
||||
for (int i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
ru->prach_list[i].frame = -1;
|
||||
ru->prach_list[i].slot = -1;
|
||||
}
|
||||
pthread_mutex_init(&ru->prach_list_mutex,NULL);
|
||||
}
|
||||
|
||||
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) {
|
||||
|
||||
uint16_t i;
|
||||
int16_t first_free_index=-1;
|
||||
|
||||
AssertFatal(ru!=NULL,"ru is null\n");
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
for (i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
for (uint16_t i=0; i<NUMBER_OF_NR_RU_PRACH_MAX; i++) {
|
||||
LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame,slot,i,
|
||||
ru->prach_list[i].frame,ru->prach_list[i].slot);
|
||||
if ((ru->prach_list[i].frame == frame) &&
|
||||
(ru->prach_list[i].slot == slot)) {
|
||||
if((type == SEARCH_EXIST_OR_FREE) &&
|
||||
(ru->prach_list[i].frame == -1) &&
|
||||
(ru->prach_list[i].slot == -1)) {
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
return i;
|
||||
}
|
||||
else if ((type == SEARCH_EXIST) &&
|
||||
(ru->prach_list[i].frame == frame) &&
|
||||
(ru->prach_list[i].slot == slot)) {
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
return i;
|
||||
}
|
||||
else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i;
|
||||
}
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
if (type == SEARCH_EXIST) return -1;
|
||||
|
||||
return first_free_index;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_fill_prach_ru(RU_t *ru,
|
||||
@@ -115,7 +130,7 @@ void nr_fill_prach_ru(RU_t *ru,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu) {
|
||||
|
||||
int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE);
|
||||
AssertFatal( (prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX),
|
||||
AssertFatal( ((prach_id>=0) && (prach_id<NUMBER_OF_NR_PRACH_MAX)) || (prach_id < 0) ,
|
||||
"illegal or no prach_id found!!! prach_id %d\n",prach_id);
|
||||
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
@@ -124,6 +139,7 @@ void nr_fill_prach_ru(RU_t *ru,
|
||||
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
|
||||
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
|
||||
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
|
||||
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
|
||||
}
|
||||
@@ -132,7 +148,8 @@ void free_nr_ru_prach_entry(RU_t *ru,
|
||||
int prach_id) {
|
||||
|
||||
pthread_mutex_lock(&ru->prach_list_mutex);
|
||||
ru->prach_list[prach_id].frame=-1;
|
||||
ru->prach_list[prach_id].frame = -1;
|
||||
ru->prach_list[prach_id].slot = -1;
|
||||
pthread_mutex_unlock(&ru->prach_list_mutex);
|
||||
|
||||
}
|
||||
@@ -142,6 +159,7 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
int prachFormat,
|
||||
int numRA,
|
||||
int prachStartSymbol,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int slot) {
|
||||
|
||||
@@ -156,15 +174,21 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
|
||||
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
|
||||
|
||||
rxsigF = ru->prach_rxsigF;
|
||||
int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
|
||||
//to be checked for mu=0;
|
||||
|
||||
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
|
||||
|
||||
rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
|
||||
AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n");
|
||||
|
||||
for (int aa=0; aa<ru->nb_rx; aa++){
|
||||
if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe;
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset];
|
||||
prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))+sample_offset_slot-ru->N_TA_offset];
|
||||
}
|
||||
|
||||
|
||||
int dftlen=0;
|
||||
int mu = fp->numerology_index;
|
||||
int Ncp = 0;
|
||||
@@ -198,22 +222,24 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol);
|
||||
|
||||
switch (prachFormat) {
|
||||
case 0: //A1
|
||||
case 4: //A1
|
||||
Ncp = 288/(1<<mu);
|
||||
break;
|
||||
|
||||
case 1: //A2
|
||||
case 5: //A2
|
||||
Ncp = 576/(1<<mu);
|
||||
break;
|
||||
|
||||
case 2: //A3
|
||||
case 6: //A3
|
||||
Ncp = 864/(1<<mu);
|
||||
break;
|
||||
|
||||
case 3: //B1
|
||||
case 7: //B1
|
||||
Ncp = 216/(1<<mu);
|
||||
break;
|
||||
|
||||
/*
|
||||
// B2 and B3 do not exist in FAPI
|
||||
case 4: //B2
|
||||
Ncp = 360/(1<<mu);
|
||||
break;
|
||||
@@ -221,16 +247,16 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
case 5: //B3
|
||||
Ncp = 504/(1<<mu);
|
||||
break;
|
||||
|
||||
case 6: //B4
|
||||
*/
|
||||
case 8: //B4
|
||||
Ncp = 936/(1<<mu);
|
||||
break;
|
||||
|
||||
case 7: //C0
|
||||
case 9: //C0
|
||||
Ncp = 1240/(1<<mu);
|
||||
break;
|
||||
|
||||
case 8: //C2
|
||||
case 10: //C2
|
||||
Ncp = 2048/(1<<mu);
|
||||
break;
|
||||
|
||||
@@ -265,7 +291,8 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
if (k<0) k+=(fp->ofdm_symbol_size);
|
||||
|
||||
k*=K;
|
||||
k+=kbar;
|
||||
k+=kbar;
|
||||
|
||||
int reps=1;
|
||||
|
||||
for (int aa=0; aa<ru->nb_rx; aa++) {
|
||||
@@ -308,21 +335,21 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
else if (mu==1) {
|
||||
dftlen=2048;
|
||||
dft(DFT_2048,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 7) { // !=C0
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1);
|
||||
reps++;
|
||||
}
|
||||
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1);
|
||||
dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1);
|
||||
dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6) {
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
@@ -363,22 +390,22 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
else if (mu==1) {
|
||||
dftlen=1536;
|
||||
dft(DFT_1536,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 7) {
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1);
|
||||
dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1);
|
||||
dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6) {
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
@@ -423,22 +450,22 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
else if (mu==1) {
|
||||
dftlen=4096;
|
||||
dft(DFT_4096,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 7) { //!=C0
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1);
|
||||
dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1);
|
||||
dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6) {
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
@@ -475,22 +502,22 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
else if (mu==1) {
|
||||
dftlen=3072;
|
||||
dft(DFT_3072,prach2,rxsigF[aa],1);
|
||||
if (prachFormat != 7) { //!=C0
|
||||
if (prachFormat != 9/*C0*/) {
|
||||
dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1);
|
||||
reps++;
|
||||
}
|
||||
|
||||
if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) {
|
||||
if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) {
|
||||
dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1);
|
||||
dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) {
|
||||
if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) {
|
||||
dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1);
|
||||
dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1);
|
||||
reps+=2;
|
||||
}
|
||||
if (prachFormat == 6) {
|
||||
if (prachFormat == 8/*B4*/) {
|
||||
for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1);
|
||||
reps+=6;
|
||||
}
|
||||
@@ -515,13 +542,13 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
for (int i=1;i<reps;i++) rxsigF_tmp[j] += rxsigF2[k2+(i*dftlen<<1)];
|
||||
}
|
||||
memcpy((void*)rxsigF2,(void *)rxsigF_tmp,N_ZC<<2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int subframe,
|
||||
uint16_t *max_preamble,
|
||||
@@ -570,13 +597,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
fp = &gNB->frame_parms;
|
||||
|
||||
nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
|
||||
|
||||
rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value;
|
||||
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value;
|
||||
rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
|
||||
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
|
||||
NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
|
||||
int prach_sequence_length = cfg->prach_sequence_length.value;
|
||||
|
||||
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value;
|
||||
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
|
||||
// int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
|
||||
// cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
|
||||
|
||||
@@ -585,7 +610,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
uint8_t prach_fmt = prach_pdu->prach_format;
|
||||
uint16_t N_ZC = (prach_sequence_length==0)?839:139;
|
||||
|
||||
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC);
|
||||
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt);
|
||||
|
||||
prach_ifft = gNB->prach_vars.prach_ifft;
|
||||
prachF = gNB->prach_vars.prachF;
|
||||
|
||||
@@ -157,7 +157,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
NR_gNB_PUSCH *pusch_vars,
|
||||
unsigned char symbol,
|
||||
uint8_t is_dmrs_symbol,
|
||||
uint8_t is_ptrs_symbol,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
@@ -289,6 +288,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
|
||||
|
||||
void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int subframe,
|
||||
uint16_t *max_preamble,
|
||||
@@ -299,6 +299,7 @@ void rx_nr_prach_ru(RU_t *ru,
|
||||
int prach_fmt,
|
||||
int numRA,
|
||||
int prachStartSymbol,
|
||||
int prachOccasion,
|
||||
int frame,
|
||||
int subframe);
|
||||
|
||||
@@ -307,7 +308,7 @@ void nr_fill_prach_ru(RU_t *ru,
|
||||
int Slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu);
|
||||
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type);
|
||||
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
|
||||
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
|
||||
|
||||
NR_gNB_PUCCH_t *new_gNB_pucch(void);
|
||||
@@ -326,7 +327,7 @@ int nr_find_pucch(uint16_t rnti,
|
||||
void init_prach_list(PHY_VARS_gNB *gNB);
|
||||
void init_prach_ru_list(RU_t *ru);
|
||||
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
|
||||
|
||||
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
|
||||
|
||||
void nr_decode_pucch1(int32_t **rxdataF,
|
||||
pucch_GroupHopping_t pucch_GroupHopping,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulsch,uint8_t N_RB_UL);
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
//#define PRINT_CRC_CHECK
|
||||
|
||||
static uint64_t nb_total_decod =0;
|
||||
static uint64_t nb_error_decod =0;
|
||||
|
||||
//extern double cpuf;
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t **ulschptr,uint8_t N_RB_UL)
|
||||
@@ -286,7 +283,177 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
|
||||
static uint32_t prnt_crc_cnt = 0;
|
||||
#endif
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
void nr_processULSegment(void* arg) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
|
||||
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
||||
int length_dec;
|
||||
int no_iteration_ldpc;
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
int K_bytes_F;
|
||||
uint8_t crc_type;
|
||||
int i;
|
||||
int j;
|
||||
int r = rdata->segment_r;
|
||||
int A = rdata->A;
|
||||
int E = rdata->E;
|
||||
int Qm = rdata->Qm;
|
||||
int rv_index = rdata->rv_index;
|
||||
int r_offset = rdata->r_offset;
|
||||
uint8_t kc = rdata->Kc;
|
||||
uint32_t Tbslbrm = rdata->Tbslbrm;
|
||||
short* ulsch_llr = rdata->ulsch_llr;
|
||||
int max_ldpc_iterations = p_decoderParms->numMaxIter;
|
||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
uint8_t Ilbrm = 0;
|
||||
|
||||
Kr = ulsch_harq->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
K_bytes_F = Kr_bytes-(ulsch_harq->F>>3);
|
||||
|
||||
t_nrLDPC_time_stats procTime;
|
||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
|
||||
|
||||
nr_deinterleaving_ldpc(E,
|
||||
Qm,
|
||||
ulsch_harq->e[r],
|
||||
ulsch_llr+r_offset);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);
|
||||
|
||||
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
|
||||
/*LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
ulsch_harq->TBS,
|
||||
Qm,
|
||||
nb_rb,
|
||||
n_layers,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
ulsch_harq->round);*/
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
p_decoderParms->BG,
|
||||
p_decoderParms->Z,
|
||||
ulsch_harq->d[r],
|
||||
ulsch_harq->e[r],
|
||||
ulsch_harq->C,
|
||||
rv_index,
|
||||
(ulsch_harq->round==0)?1:0,
|
||||
E,
|
||||
ulsch_harq->F,
|
||||
Kr-ulsch_harq->F-2*(p_decoderParms->Z))==-1) {
|
||||
|
||||
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||
rdata->decodeIterations = max_ldpc_iterations + 1;
|
||||
return;
|
||||
} else {
|
||||
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
|
||||
}
|
||||
|
||||
memset(ulsch_harq->c[r],0,Kr_bytes);
|
||||
|
||||
if (ulsch_harq->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = ulsch_harq->B;
|
||||
}
|
||||
else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (ulsch_harq->B+24*ulsch_harq->C)/ulsch_harq->C;
|
||||
}
|
||||
|
||||
//start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||
|
||||
memset(pv,0,2*ulsch_harq->Z*sizeof(int16_t));
|
||||
memset((pv+K_bytes_F),127,ulsch_harq->F*sizeof(int16_t));
|
||||
|
||||
for (i=((2*p_decoderParms->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
|
||||
}
|
||||
|
||||
AssertFatal(kc!=255,"");
|
||||
j+=(ulsch_harq->F>>3);
|
||||
for (i=Kr_bytes; i < ((kc*p_decoderParms->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
|
||||
}
|
||||
|
||||
for (i=0, j=0; j < ((kc*p_decoderParms->Z)>>4); i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
|
||||
(int8_t*)&pl[0],
|
||||
llrProcBuf,
|
||||
ulsch_harq->p_nrLDPC_procBuf[r],
|
||||
p_procTime);
|
||||
|
||||
if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
LOG_I(PHY, "Segment %d CRC OK\n",r);
|
||||
#endif
|
||||
rdata->decodeIterations = no_iteration_ldpc;
|
||||
} else {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
LOG_I(PHY, "CRC NOK\n");
|
||||
#endif
|
||||
rdata->decodeIterations = max_ldpc_iterations + 1;
|
||||
}
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++) {
|
||||
ulsch_harq->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
//stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||
}
|
||||
|
||||
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
@@ -296,36 +463,36 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t harq_pid,
|
||||
uint32_t G) {
|
||||
|
||||
uint32_t A,E;
|
||||
uint32_t ret, offset;
|
||||
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;
|
||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
uint32_t A;
|
||||
uint32_t r;
|
||||
uint32_t r_offset;
|
||||
uint32_t offset;
|
||||
int kc;
|
||||
int Tbslbrm;
|
||||
int E;
|
||||
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
prnt_crc_cnt++;
|
||||
#endif
|
||||
|
||||
|
||||
NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0];
|
||||
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
|
||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
|
||||
|
||||
t_nrLDPC_dec_params decParams;
|
||||
t_nrLDPC_dec_params* p_decParams = &decParams;
|
||||
t_nrLDPC_time_stats procTime;
|
||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
||||
if (!harq_process) {
|
||||
printf("ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
|
||||
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
uint8_t kc = 255;
|
||||
uint8_t Ilbrm = 0;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
|
||||
phy_vars_gNB->nbDecode = 0;
|
||||
harq_process->processedSegments = 0;
|
||||
|
||||
if (!harq_process) {
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
double Coderate = 0.0;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -336,30 +503,16 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
uint32_t i,j;
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
|
||||
if (!ulsch_llr) {
|
||||
printf("ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!frame_parms) {
|
||||
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
|
||||
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
|
||||
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
||||
harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];
|
||||
|
||||
A = (harq_process->TBS)<<3;
|
||||
ret = ulsch->max_ldpc_iterations + 1;
|
||||
|
||||
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
|
||||
|
||||
@@ -401,12 +554,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
NR_gNB_SCH_STATS_t *stats=NULL;
|
||||
int first_free=-1;
|
||||
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++) {
|
||||
if (gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
|
||||
if (phy_vars_gNB->ulsch_stats[i].rnti == 0 && first_free == -1) {
|
||||
first_free = i;
|
||||
stats=&gNB->ulsch_stats[i];
|
||||
stats=&phy_vars_gNB->ulsch_stats[i];
|
||||
}
|
||||
if (gNB->ulsch_stats[i].rnti == ulsch->rnti) {
|
||||
stats=&gNB->ulsch_stats[i];
|
||||
if (phy_vars_gNB->ulsch_stats[i].rnti == ulsch->rnti) {
|
||||
stats=&phy_vars_gNB->ulsch_stats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -420,13 +573,13 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
stats->current_RI = n_layers;
|
||||
stats->total_bytes_tx += harq_process->TBS;
|
||||
}
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
if (A > 3824)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
}
|
||||
if (A > 3824)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
harq_process->B,
|
||||
@@ -437,18 +590,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
p_decParams->BG);
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
|
||||
if (!frame%100)
|
||||
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
|
||||
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
|
||||
if (!frame%100)
|
||||
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
|
||||
#endif
|
||||
}
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers);
|
||||
|
||||
p_decParams->Z = harq_process->Z;
|
||||
|
||||
|
||||
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
|
||||
p_decParams->outMode= 0;
|
||||
|
||||
err_flag = 0;
|
||||
r_offset = 0;
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
|
||||
@@ -460,284 +613,48 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB,
|
||||
|
||||
if (harq_process->C > a_segments) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
return 1;
|
||||
}
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
|
||||
//opp_enabled=1;
|
||||
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
K_bytes_F = Kr_bytes-(harq_process->F>>3);
|
||||
offset = 0;
|
||||
void (*nr_processULSegment_ptr)(void*) = &nr_processULSegment;
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
||||
|
||||
union ldpcReqUnion id = {.s={ulsch->rnti,frame,nr_tti_rx,0,0}};
|
||||
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment_ptr);
|
||||
ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);
|
||||
|
||||
start_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
|
||||
|
||||
nr_deinterleaving_ldpc(E,
|
||||
Qm,
|
||||
harq_process->e[r],
|
||||
ulsch_llr+r_offset);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
stop_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
|
||||
|
||||
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rvidx %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
harq_process->TBS,
|
||||
Qm,
|
||||
nb_rb,
|
||||
n_layers,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
harq_process->round);
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
|
||||
|
||||
start_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
p_decParams->BG,
|
||||
p_decParams->Z,
|
||||
harq_process->d[r],
|
||||
harq_process->e[r],
|
||||
harq_process->C,
|
||||
pusch_pdu->pusch_data.rv_index,
|
||||
(harq_process->round==0)?1:0,
|
||||
E,
|
||||
harq_process->F,
|
||||
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
|
||||
|
||||
stop_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
|
||||
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
|
||||
return (ulsch->max_ldpc_iterations + 1);
|
||||
} else {
|
||||
stop_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
}
|
||||
|
||||
rdata->gNB = phy_vars_gNB;
|
||||
rdata->ulsch_harq = harq_process;
|
||||
rdata->decoderParms = decParams;
|
||||
rdata->ulsch_llr = ulsch_llr;
|
||||
rdata->Kc = kc;
|
||||
rdata->harq_pid = harq_pid;
|
||||
rdata->segment_r = r;
|
||||
rdata->nbSegments = harq_process->C;
|
||||
rdata->E = E;
|
||||
rdata->A = A;
|
||||
rdata->Qm = Qm;
|
||||
rdata->r_offset = r_offset;
|
||||
rdata->Kr_bytes = Kr_bytes;
|
||||
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
rdata->Tbslbrm = Tbslbrm;
|
||||
rdata->offset = offset;
|
||||
rdata->ulsch = ulsch;
|
||||
rdata->ulsch_id = UE_id;
|
||||
pushTpool(phy_vars_gNB->threadPool,req);
|
||||
phy_vars_gNB->nbDecode++;
|
||||
LOG_D(PHY,"Added a block to decode, in pipe: %d\n",phy_vars_gNB->nbDecode);
|
||||
r_offset += E;
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
|
||||
}
|
||||
|
||||
printf("decoder input(segment %u) :", r);
|
||||
int i;
|
||||
for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
// printf("done\n");
|
||||
if (harq_process->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = harq_process->B;
|
||||
}
|
||||
else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
|
||||
}
|
||||
|
||||
if (err_flag == 0) {
|
||||
|
||||
start_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
|
||||
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
|
||||
|
||||
|
||||
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
|
||||
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
|
||||
|
||||
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||
}
|
||||
|
||||
AssertFatal(kc!=255,"");
|
||||
j+=(harq_process->F>>3);
|
||||
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
|
||||
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
|
||||
}
|
||||
|
||||
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
|
||||
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
|
||||
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
|
||||
(int8_t*)&pl[0],
|
||||
llrProcBuf,
|
||||
p_nrLDPC_procBuf[r],
|
||||
p_procTime);
|
||||
|
||||
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
//if (prnt_crc_cnt % 10 == 0)
|
||||
LOG_I(PHY, "Segment %d CRC OK\n",r);
|
||||
#endif
|
||||
ret = no_iteration_ldpc;
|
||||
} else {
|
||||
#ifdef PRINT_CRC_CHECK
|
||||
//if (prnt_crc_cnt%10 == 0)
|
||||
LOG_I(PHY, "CRC NOK\n");
|
||||
#endif
|
||||
ret = ulsch->max_ldpc_iterations + 1;
|
||||
}
|
||||
nb_total_decod++;
|
||||
|
||||
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
|
||||
nb_error_decod++;
|
||||
}
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++) {
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int k=0;k<A>>3;k++)
|
||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
|
||||
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
|
||||
#endif
|
||||
|
||||
stop_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
}
|
||||
|
||||
if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
|
||||
// a Code segment is in error so break;
|
||||
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
|
||||
err_flag = 1;
|
||||
}
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
int32_t frame_rx_prev = frame;
|
||||
int32_t tti_rx_prev = nr_tti_rx - 1;
|
||||
if (tti_rx_prev < 0) {
|
||||
frame_rx_prev--;
|
||||
tti_rx_prev += frame_parms->slots_per_frame;
|
||||
}
|
||||
frame_rx_prev = frame_rx_prev%1024;
|
||||
|
||||
if (err_flag == 1) {
|
||||
|
||||
#ifdef gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n",
|
||||
gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r);
|
||||
#endif
|
||||
|
||||
// harq_process->harq_ack.ack = 0;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
// harq_process->errors[harq_process->round]++;
|
||||
//harq_process->round++;
|
||||
|
||||
if (harq_process->round >= ulsch->Mlimit) {
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
harq_process->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||
}
|
||||
|
||||
// LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
// gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS);
|
||||
|
||||
harq_process->handled = 1;
|
||||
ret = ulsch->max_ldpc_iterations + 1;
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef gNB_DEBUG_TRACE
|
||||
LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
|
||||
gNB->Mod_id,nr_tti_rx,harq_process->TBS);
|
||||
#endif
|
||||
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
// harq_process->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << harq_pid);
|
||||
// harq_process->harq_ack.ack = 1;
|
||||
// harq_process->harq_ack.harq_id = harq_pid;
|
||||
// harq_process->harq_ack.send_harq_status = 1;
|
||||
|
||||
// LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS);
|
||||
|
||||
|
||||
// Reassembly of Transport block here
|
||||
offset = 0;
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
|
||||
memcpy(harq_process->b+offset,
|
||||
harq_process->c[r],
|
||||
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("Segment %u : Kr = %u bytes\n", r, Kr_bytes);
|
||||
printf("copied %d bytes to b sequence (harq_pid %d)\n", (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)), harq_pid);
|
||||
printf("b[0] = %x, c[%d] = %x\n", harq_process->b[offset], harq_process->F>>3, harq_process->c[r]);
|
||||
#endif
|
||||
|
||||
}
|
||||
if (stats) stats->total_bytes_rx += harq_process->TBS;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
LOG_I(PHY, "Decoder output (payload) at SFN/SF: %d/%d TBS: %d\n", frame, nr_tti_rx,harq_process->TBS);
|
||||
for (i = 0; i < harq_process->TBS; i++) {
|
||||
//harq_process_ul_ue->a[i] = (unsigned char) rand();
|
||||
//printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
|
||||
printf("%02x ",harq_process->b[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
ulsch->last_iteration_cnt = ret;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
|
||||
return(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -226,25 +226,19 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
NR_gNB_PUSCH *pusch_vars,
|
||||
unsigned char symbol,
|
||||
uint8_t is_dmrs_symbol,
|
||||
uint8_t is_ptrs_symbol,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
|
||||
unsigned short start_re, re, nb_re_pusch;
|
||||
unsigned char aarx;
|
||||
uint8_t K_ptrs = 0;
|
||||
uint32_t rxF_ext_index = 0;
|
||||
uint32_t ul_ch0_ext_index = 0;
|
||||
uint32_t ul_ch0_index = 0;
|
||||
uint32_t ul_ch0_ptrs_ext_index = 0;
|
||||
uint32_t ul_ch0_ptrs_index = 0;
|
||||
uint8_t k_prime;
|
||||
uint16_t n=0, num_ptrs_symbols;
|
||||
uint16_t n;
|
||||
int16_t *rxF,*rxF_ext;
|
||||
int *ul_ch0,*ul_ch0_ext;
|
||||
int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
|
||||
uint16_t n_rnti = pusch_pdu->rnti;
|
||||
uint8_t delta = 0;
|
||||
|
||||
#ifdef DEBUG_RB_EXT
|
||||
@@ -253,8 +247,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
|
||||
|
||||
#endif
|
||||
|
||||
uint8_t is_dmrs_re=0,is_ptrs_re=0;
|
||||
|
||||
uint8_t is_dmrs_re;
|
||||
start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
|
||||
nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
|
||||
#ifdef __AVX2__
|
||||
@@ -263,10 +257,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
int nb_re_pusch2 = nb_re_pusch;
|
||||
#endif
|
||||
|
||||
num_ptrs_symbols = 0;
|
||||
|
||||
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 *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
|
||||
|
||||
@@ -274,20 +266,17 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
|
||||
ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2];
|
||||
|
||||
ul_ch0_ptrs = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
|
||||
|
||||
ul_ch0_ptrs_ext = &pusch_vars->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch];
|
||||
|
||||
n = 0;
|
||||
k_prime = 0;
|
||||
|
||||
if (is_dmrs_symbol == 0 && is_ptrs_symbol == 0) {
|
||||
if (is_dmrs_symbol == 0) {
|
||||
//
|
||||
//rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) memcpy1((void*)rxF_ext,
|
||||
(void*)&rxF[start_re*2],
|
||||
nb_re_pusch*sizeof(int32_t));
|
||||
else {
|
||||
if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) {
|
||||
memcpy1((void*)rxF_ext,
|
||||
(void*)&rxF[start_re*2],
|
||||
nb_re_pusch*sizeof(int32_t));
|
||||
} else {
|
||||
int neg_length = frame_parms->ofdm_symbol_size-start_re;
|
||||
int pos_length = nb_re_pusch-neg_length;
|
||||
|
||||
@@ -298,58 +287,36 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
|
||||
}
|
||||
else {
|
||||
for (re = 0; re < nb_re_pusch; re++) {
|
||||
|
||||
if (is_dmrs_symbol) is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
|
||||
|
||||
if (is_ptrs_symbol) {
|
||||
K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
|
||||
is_ptrs_re = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
|
||||
n_rnti,
|
||||
aarx,
|
||||
pusch_pdu->dmrs_config_type,
|
||||
K_ptrs,
|
||||
pusch_pdu->rb_size,
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
start_re,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
|
||||
num_ptrs_symbols+=is_ptrs_re;
|
||||
|
||||
}
|
||||
|
||||
|
||||
is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
|
||||
|
||||
#ifdef DEBUG_RB_EXT
|
||||
printf("re = %d, kprime %d, n %d, is_ptrs_symbol = %d, symbol = %d\n", re, k_prime,n,is_ptrs_symbol, symbol);
|
||||
printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol);
|
||||
#endif
|
||||
|
||||
if ( is_dmrs_re == 0 && is_ptrs_re == 0) {
|
||||
|
||||
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
|
||||
ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
|
||||
|
||||
/* save only data and respective channel estimates */
|
||||
if (is_dmrs_re == 0) {
|
||||
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
|
||||
ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
|
||||
|
||||
#ifdef DEBUG_RB_EXT
|
||||
printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n",
|
||||
is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
|
||||
ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
|
||||
printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n",
|
||||
is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
|
||||
ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
|
||||
#endif
|
||||
ul_ch0_ext_index++;
|
||||
ul_ch0_ptrs_ext_index++;
|
||||
rxF_ext_index +=2;
|
||||
} else {
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
}
|
||||
ul_ch0_index++;
|
||||
ul_ch0_ptrs_index++;
|
||||
ul_ch0_ext_index++;
|
||||
rxF_ext_index +=2;
|
||||
} else {
|
||||
n += k_prime;
|
||||
k_prime ^= 1;
|
||||
}
|
||||
ul_ch0_index++;
|
||||
}
|
||||
} // is_dmrs_symbol ==0 && is_ptrs_symbol == 0
|
||||
}
|
||||
pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
NR_gNB_ULSCH_t **ulsch_gNB,
|
||||
@@ -1116,34 +1083,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
|
||||
uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
|
||||
uint8_t ptrs_symbol_flag; // a flag to indicate PTRS REs in current symbol
|
||||
uint32_t nb_re_pusch, bwp_start_subcarrier;
|
||||
uint8_t L_ptrs = 0; // PTRS parameter
|
||||
int avgs;
|
||||
int avg[4];
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
|
||||
|
||||
dmrs_symbol_flag = 0;
|
||||
ptrs_symbol_flag = 0;
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
|
||||
|
||||
if(symbol == rel15_ul->start_symbol_index){
|
||||
gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = 0;
|
||||
gNB->pusch_vars[ulsch_id]->dmrs_symbol = 0;
|
||||
gNB->pusch_vars[ulsch_id]->cl_done = 0;
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
|
||||
|
||||
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
|
||||
L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
|
||||
|
||||
set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
|
||||
rel15_ul->nr_of_symbols,
|
||||
rel15_ul->start_symbol_index,
|
||||
L_ptrs,
|
||||
rel15_ul->ul_dmrs_symb_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1172,13 +1122,6 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
|
||||
}
|
||||
|
||||
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
|
||||
if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols)) {
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
|
||||
ptrs_symbol_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- Channel estimation ---------------------
|
||||
//----------------------------------------------------------
|
||||
@@ -1204,6 +1147,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
//--------------------- RBs extraction ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
|
||||
|
||||
if (nb_re_pusch > 0) {
|
||||
|
||||
start_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
@@ -1211,11 +1156,14 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
gNB->pusch_vars[ulsch_id],
|
||||
symbol,
|
||||
dmrs_symbol_flag,
|
||||
ptrs_symbol_flag,
|
||||
rel15_ul,
|
||||
frame_parms);
|
||||
stop_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- Channel Scaling --------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
|
||||
frame_parms,
|
||||
gNB->ulsch[ulsch_id],
|
||||
@@ -1244,6 +1192,10 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
gNB->pusch_vars[ulsch_id]->cl_done = 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- Channel Compensation ---------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
start_meas(&gNB->ulsch_channel_compensation_stats);
|
||||
nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
|
||||
@@ -1271,29 +1223,54 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------
|
||||
//-------------------- LLRs computation --------------------
|
||||
//----------------------------------------------------------
|
||||
start_meas(&gNB->ulsch_llr_stats);
|
||||
AssertFatal(gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- PTRS Processing --------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
/* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
|
||||
* otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
|
||||
if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS)
|
||||
{
|
||||
start_meas(&gNB->ulsch_ptrs_processing_stats);
|
||||
nr_pusch_ptrs_processing(gNB,
|
||||
rel15_ul,
|
||||
ulsch_id,
|
||||
nr_tti_rx,
|
||||
dmrs_symbol_flag,
|
||||
symbol,
|
||||
nb_re_pusch);
|
||||
stop_meas(&gNB->ulsch_ptrs_processing_stats);
|
||||
|
||||
/* Subtract total PTRS RE's in the symbol from PUSCH RE's */
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------- */
|
||||
/*-------------------- LLRs computation -------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
|
||||
{
|
||||
#ifdef __AVX2__
|
||||
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
|
||||
int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
|
||||
#else
|
||||
int off = 0;
|
||||
int off = 0;
|
||||
#endif
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off+(rel15_ul->rb_size * NR_NB_SC_PER_RB))],
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
|
||||
&gNB->pusch_vars[ulsch_id]->llr[gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
|
||||
rel15_ul->rb_size,
|
||||
nb_re_pusch,
|
||||
symbol,
|
||||
rel15_ul->qam_mod_order);
|
||||
stop_meas(&gNB->ulsch_llr_stats);
|
||||
|
||||
uint32_t rxdataF_ext_offset = 0;
|
||||
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
|
||||
start_meas(&gNB->ulsch_llr_stats);
|
||||
nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
|
||||
gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
|
||||
&gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
|
||||
rel15_ul->rb_size,
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
|
||||
i,
|
||||
rel15_ul->qam_mod_order);
|
||||
stop_meas(&gNB->ulsch_llr_stats);
|
||||
rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
|
||||
}// symbol loop
|
||||
}// last symbol check
|
||||
}
|
||||
|
||||
gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset + nb_re_pusch;
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ int nr_find_pucch(uint16_t rnti,
|
||||
AssertFatal(gNB!=NULL,"gNB is null\n");
|
||||
int index = -1;
|
||||
|
||||
for (int i=0; i<NUMBER_OF_NR_ULSCH_MAX; i++) {
|
||||
for (int i=0; i<NUMBER_OF_NR_PUCCH_MAX; i++) {
|
||||
AssertFatal(gNB->pucch[i]!=NULL,"gNB->pucch[%d] is null\n",i);
|
||||
if ((gNB->pucch[i]->active >0) &&
|
||||
(gNB->pucch[i]->pucch_pdu.rnti==rnti) &&
|
||||
@@ -414,7 +414,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
|
||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
|
||||
uci_pdu->harq->harq_list[0].harq_value = index&0x01;
|
||||
LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
LOG_D(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||
@@ -429,7 +429,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
|
||||
uci_pdu->harq->harq_list[1].harq_value = index&0x01;
|
||||
uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01;
|
||||
LOG_I(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
LOG_D(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n",
|
||||
uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level);
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||
|
||||
@@ -845,7 +845,6 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
for (int i=0;i<pdcch_vars->nb_search_space;i++) {
|
||||
|
||||
rel15 = &pdcch_vars->pdcch_config[i];
|
||||
int dci_length = rel15->dci_length;
|
||||
//int gNB_id = 0;
|
||||
int16_t tmp_e[16*108];
|
||||
rnti_t n_rnti;
|
||||
@@ -853,41 +852,47 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
for (int j=0;j<rel15->number_of_candidates;j++) {
|
||||
int CCEind = rel15->CCE[j];
|
||||
int L = rel15->L[j];
|
||||
uint64_t dci_estimation[2]= {0};
|
||||
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
|
||||
|
||||
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
|
||||
// Loop over possible DCI lengths
|
||||
for (int k = 0; k < rel15->num_dci_options; k++) {
|
||||
int dci_length = rel15->dci_length_options[k];
|
||||
uint64_t dci_estimation[2]= {0};
|
||||
const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
|
||||
|
||||
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
|
||||
LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
|
||||
|
||||
#ifdef DEBUG_DCI_DECODING
|
||||
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
|
||||
for (int index_z = 0; index_z < 96; index_z++){
|
||||
for (int i=0; i<9; i++) {
|
||||
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
|
||||
nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
|
||||
|
||||
#ifdef DEBUG_DCI_DECODING
|
||||
uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
|
||||
for (int index_z = 0; index_z < 96; index_z++){
|
||||
for (int i=0; i<9; i++) {
|
||||
LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t crc = polar_decoder_int16(tmp_e,
|
||||
dci_estimation,
|
||||
1,
|
||||
currentPtrDCI);
|
||||
|
||||
n_rnti = rel15->rnti;
|
||||
|
||||
if (crc == n_rnti) {
|
||||
LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
|
||||
dci_ind->SFN = frame;
|
||||
dci_ind->slot = slot;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k];
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
|
||||
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
|
||||
dci_ind->number_of_dcis++;
|
||||
break; // If DCI is found, no need to check for remaining DCI lengths
|
||||
} else {
|
||||
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t crc = polar_decoder_int16(tmp_e,
|
||||
dci_estimation,
|
||||
1,
|
||||
currentPtrDCI);
|
||||
|
||||
n_rnti = rel15->rnti;
|
||||
|
||||
if (crc == n_rnti) {
|
||||
LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
|
||||
dci_ind->SFN = frame;
|
||||
dci_ind->slot = slot;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
|
||||
memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
|
||||
dci_ind->number_of_dcis++;
|
||||
} else {
|
||||
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,9 +478,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_RATE_MATCHING, VCD_FUNCTION_IN);
|
||||
|
||||
if ((harq_process->Nl)<4)
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
|
||||
else
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
|
||||
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
@@ -1069,7 +1069,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
if (harq_process->Nl < Nl)
|
||||
Nl = harq_process->Nl;
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,harq_process->Nl);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
@@ -1610,9 +1610,9 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
#endif
|
||||
|
||||
if (Nl<4)
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
|
||||
else
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,4);
|
||||
|
||||
if (nr_rate_matching_ldpc_rx(Ilbrm,
|
||||
Tbslbrm,
|
||||
|
||||
@@ -53,11 +53,9 @@ int16_t nr_dlsch_demod_shift = 0;
|
||||
//int16_t interf_unaw_shift = 13;
|
||||
|
||||
//#define DEBUG_HARQ
|
||||
|
||||
//#define DEBUG_PHY 1
|
||||
//#define DEBUG_DLSCH_DEMOD 1
|
||||
|
||||
|
||||
//#define DEBUG_PHY
|
||||
//#define DEBUG_DLSCH_DEMOD
|
||||
//#define DEBUG_PDSCH_RX
|
||||
|
||||
// [MCS][i_mod (0,1,2) = (2,4,6)]
|
||||
//unsigned char offset_mumimo_llr_drange_fix=0;
|
||||
@@ -188,7 +186,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
if (dlsch0_harq && dlsch1_harq){
|
||||
|
||||
//printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
|
||||
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
|
||||
|
||||
if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
|
||||
@@ -1042,42 +1039,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Please keep it: useful for debugging
|
||||
#if 0
|
||||
if( (symbol == 13) && (nr_tti_rx==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/)
|
||||
{
|
||||
LOG_E(PHY,"Dump Phy Chan Est \n");
|
||||
if(1)
|
||||
{
|
||||
#if 1
|
||||
write_output("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("rxdataF1.m" , "rxdataF1", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
write_output("dl_ch_estimates00.m", "dl_ch_estimates00", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates01.m", "dl_ch_estimates01", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates10.m", "dl_ch_estimates10", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
//write_output("dl_ch_estimates11.m", "dl_ch_estimates11", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
#ifdef DEBUG_PDSCH_RX
|
||||
char filename[40];
|
||||
uint8_t aa = 0;
|
||||
|
||||
snprintf(filename, 40, "rxdataF0_symb_%d_nr_tti_rx_%d.m", symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
//write_output("rxdataF_ext00.m" , "rxdataF_ext00", &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext01.m" , "rxdataF_ext01", &pdsch_vars[eNB_id]->rxdataF_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext10.m" , "rxdataF_ext10", &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_ext11.m" , "rxdataF_ext11", &pdsch_vars[eNB_id]->rxdataF_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
write_output("rxdataF_comp00.m","rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
//write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1);
|
||||
#endif
|
||||
write_output("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
//write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "dl_ch_estimates", &pdsch_vars[eNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
||||
|
||||
snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF_ext", &pdsch_vars[eNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
AssertFatal(0," ");
|
||||
}
|
||||
snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx);
|
||||
write_output(filename, "rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
|
||||
|
||||
for (int i=0; i < 2; i++){
|
||||
snprintf(filename, 40, "llr%d_symb_%d_nr_tti_rx_%d.m", i, symbol, nr_tti_rx);
|
||||
write_output(filename,"llr", &pdsch_vars[eNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2572,51 +2557,51 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *
|
||||
char fname[32],vname[32];
|
||||
int N_RB_DL=ue->frame_parms.N_RB_DL;
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_ext0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx >1) {
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_ext1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext00",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->transmission_mode[eNB_id]==7){
|
||||
sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_bf_ch_r%d",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
|
||||
//write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext01",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext10",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
if (ue->frame_parms.nb_antennas_rx == 2) {
|
||||
sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_ch_r%d_ext11",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_uespec0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
|
||||
|
||||
/*
|
||||
@@ -2624,33 +2609,33 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *
|
||||
write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
|
||||
write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
|
||||
*/
|
||||
sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
|
||||
sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_rho.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl_rho_r%d_%d",eNB_id,round);
|
||||
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
|
||||
sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_rho2.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl_rho2_r%d_%d",eNB_id,round);
|
||||
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_comp0",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
|
||||
if (ue->frame_parms.nb_antenna_ports_gNB == 2) {
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_rxF_r%d_comp1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
|
||||
}
|
||||
|
||||
sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_llr",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_llr",eNB_id,round);
|
||||
write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
|
||||
sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_mag1",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_mag1.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_mag1",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
|
||||
sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round);
|
||||
sprintf(vname,"dl%d_r%d_mag2",eNB_id,round);
|
||||
snprintf(fname, 32, "dlsch%d_r%d_mag2.m",eNB_id,round);
|
||||
snprintf(vname, 32, "dl%d_r%d_mag2",eNB_id,round);
|
||||
write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
|
||||
|
||||
// printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh);
|
||||
|
||||
@@ -48,8 +48,7 @@ extern uint16_t prach_root_sequence_map_0_3[838];
|
||||
extern uint16_t prach_root_sequence_map_abc[138];
|
||||
extern uint16_t nr_du[838];
|
||||
extern int16_t nr_ru[2*839];
|
||||
extern const char *prachfmt[9];
|
||||
extern const char *prachfmt03[4];
|
||||
extern const char *prachfmt[];
|
||||
|
||||
// Note:
|
||||
// - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt
|
||||
@@ -181,14 +180,14 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
}
|
||||
|
||||
// now generate PRACH signal
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
#ifdef NR_PRACH_DEBUG
|
||||
if (NCS>0)
|
||||
LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n",
|
||||
Mod_id,
|
||||
slot,
|
||||
rootSequenceIndex,
|
||||
preamble_index,
|
||||
prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id],
|
||||
prachfmt[prach_fmt_id],
|
||||
NCS,
|
||||
N_ZC,
|
||||
preamble_offset,
|
||||
@@ -362,31 +361,33 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
} else {
|
||||
|
||||
switch (prach_fmt_id) {
|
||||
case 0: //A1
|
||||
case 4: //A1
|
||||
Ncp = 288/(1<<mu);
|
||||
break;
|
||||
case 1: //A2
|
||||
case 5: //A2
|
||||
Ncp = 576/(1<<mu);
|
||||
break;
|
||||
case 2: //A3
|
||||
case 6: //A3
|
||||
Ncp = 864/(1<<mu);
|
||||
break;
|
||||
case 3: //B1
|
||||
case 7: //B1
|
||||
Ncp = 216/(1<<mu);
|
||||
break;
|
||||
/*
|
||||
case 4: //B2
|
||||
Ncp = 360/(1<<mu);
|
||||
break;
|
||||
case 5: //B3
|
||||
Ncp = 504/(1<<mu);
|
||||
break;
|
||||
case 6: //B4
|
||||
*/
|
||||
case 8: //B4
|
||||
Ncp = 936/(1<<mu);
|
||||
break;
|
||||
case 7: //C0
|
||||
case 9: //C0
|
||||
Ncp = 1240/(1<<mu);
|
||||
break;
|
||||
case 8: //C2
|
||||
case 10: //C2
|
||||
Ncp = 2048/(1<<mu);
|
||||
break;
|
||||
default:
|
||||
@@ -440,19 +441,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (12288*4)+Ncp;
|
||||
}
|
||||
} else { // short PRACH sequence
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
|
||||
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
|
||||
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_2048,prachF,prach2,1);
|
||||
// here we have |empty | Prach2048 |
|
||||
if (prach_fmt_id != 7) {
|
||||
if (prach_fmt_id != 9) {
|
||||
memmove(prach2+(2048<<1),prach2,(2048<<2));
|
||||
prach_len = (2048*2)+Ncp;
|
||||
}
|
||||
else prach_len = (2048*1)+Ncp;
|
||||
memmove(prach,prach+(2048<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
|
||||
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048
|
||||
} else if (prach_fmt_id == 5) { // 6x2048
|
||||
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_2048,prachF,prach2,1);
|
||||
@@ -464,7 +465,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(2048<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach2048 |
|
||||
prach_len = (2048*4)+Ncp;
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048
|
||||
} else if (prach_fmt_id == 6) { // 6x2048
|
||||
Ncp+=32;
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_2048,prachF,prach2,1);
|
||||
@@ -478,7 +479,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(2048<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach2048 |
|
||||
prach_len = (2048*6)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 12x2048
|
||||
} else if (prach_fmt_id == 8) { // 12x2048
|
||||
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_2048,prachF,prach2,1);
|
||||
@@ -533,12 +534,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (9216*4)+Ncp;
|
||||
}
|
||||
} else { // short sequence
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
|
||||
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
|
||||
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_1536,prachF,prach2,1);
|
||||
// here we have |empty | Prach1536 |
|
||||
if (prach_fmt_id != 7) {
|
||||
if (prach_fmt_id != 9) {
|
||||
memmove(prach2+(1536<<1),prach2,(1536<<2));
|
||||
prach_len = (1536*2)+Ncp;
|
||||
} else prach_len = (1536*1)+Ncp;
|
||||
@@ -546,7 +547,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(1536<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
|
||||
|
||||
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536
|
||||
} else if (prach_fmt_id == 5) { // 6x1536
|
||||
|
||||
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
@@ -559,7 +560,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(1536<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach1536 |
|
||||
prach_len = (1536*4)+Ncp;
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536
|
||||
} else if (prach_fmt_id == 6) { // 6x1536
|
||||
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_1536,prachF,prach2,1);
|
||||
@@ -573,7 +574,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(1536<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach1536 |
|
||||
prach_len = (1536*6)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 12x1536
|
||||
} else if (prach_fmt_id == 8) { // 12x1536
|
||||
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_1536,prachF,prach2,1);
|
||||
@@ -630,18 +631,18 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (24576*4)+Ncp;
|
||||
}
|
||||
} else { // short sequence
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
|
||||
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
|
||||
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_4096,prachF,prach2,1);
|
||||
// here we have |empty | Prach4096 |
|
||||
if (prach_fmt_id != 7) {
|
||||
if (prach_fmt_id != 9) {
|
||||
memmove(prach2+(4096<<1),prach2,(4096<<2));
|
||||
prach_len = (4096*2)+Ncp;
|
||||
} else prach_len = (4096*1)+Ncp;
|
||||
memmove(prach,prach+(4096<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
|
||||
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096
|
||||
} else if (prach_fmt_id == 5) { // 4x4096
|
||||
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_4096,prachF,prach2,1);
|
||||
@@ -653,7 +654,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(4096<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach4096 |
|
||||
prach_len = (4096*4)+Ncp;
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096
|
||||
} else if (prach_fmt_id == 6) { // 6x4096
|
||||
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_4096,prachF,prach2,1);
|
||||
@@ -667,7 +668,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(4096<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach4096 |
|
||||
prach_len = (4096*6)+Ncp;
|
||||
} else if (prach_fmt_id == 6) { // 12x4096
|
||||
} else if (prach_fmt_id == 8) { // 12x4096
|
||||
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_4096,prachF,prach2,1);
|
||||
@@ -722,18 +723,18 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
prach_len = (18432*4)+Ncp;
|
||||
}
|
||||
} else { // short sequence
|
||||
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
|
||||
if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) {
|
||||
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_3072,prachF,prach2,1);
|
||||
// here we have |empty | Prach3072 |
|
||||
if (prach_fmt_id != 7) {
|
||||
if (prach_fmt_id != 9) {
|
||||
memmove(prach2+(3072<<1),prach2,(3072<<2));
|
||||
prach_len = (3072*2)+Ncp;
|
||||
} else prach_len = (3072*1)+Ncp;
|
||||
memmove(prach,prach+(3072<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
|
||||
} else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072
|
||||
} else if (prach_fmt_id == 6) { // 6x3072
|
||||
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_3072,prachF,prach2,1);
|
||||
@@ -747,7 +748,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
memmove(prach,prach+(3072<<1),(Ncp<<2));
|
||||
// here we have |Prefix | Prach3072 |
|
||||
prach_len = (3072*6)+Ncp;
|
||||
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072
|
||||
} else if (prach_fmt_id == 5) { // 4x3072
|
||||
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
|
||||
prach2 = prach+(Ncp<<1);
|
||||
idft(IDFT_3072,prachF,prach2,1);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
//#define DEBUG_ULSCH_CODING
|
||||
|
||||
void free_nr_ue_ulsch(NR_UE_ULSCH_t **ulschptr,unsigned char N_RB_UL)
|
||||
|
||||
@@ -248,7 +249,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
crc = 1;
|
||||
harq_process = ulsch->harq_processes[harq_pid];
|
||||
nb_rb = harq_process->pusch_pdu.rb_size;
|
||||
A = harq_process->pusch_pdu.pusch_data.tb_size;
|
||||
A = harq_process->pusch_pdu.pusch_data.tb_size*8;
|
||||
pz = &Z;
|
||||
mod_order = nr_get_Qm_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
|
||||
R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table);
|
||||
@@ -271,7 +272,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
// if (harq_process->Ndi == 1) { // this is a new packet
|
||||
if (harq_process->round == 0) { // this is a new packet
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("encoding thinks this is a new packet \n");
|
||||
#endif
|
||||
|
||||
@@ -345,7 +346,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
F = harq_process->F;
|
||||
Kr = harq_process->K;
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
uint16_t Kr_bytes;
|
||||
Kr_bytes = Kr>>3;
|
||||
#endif
|
||||
@@ -358,7 +359,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
//start_meas(te_stats);
|
||||
for (r=0; r<harq_process->C; r++) {
|
||||
//channel_input[r] = &harq_process->d[r][0];
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
|
||||
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
|
||||
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
@@ -391,6 +392,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
encoder_implemparams_t impp;
|
||||
impp.n_segments=harq_process->C;
|
||||
impp.macro_num=0;
|
||||
impp.tinput = NULL;
|
||||
impp.tprep = NULL;
|
||||
impp.tparity = NULL;
|
||||
impp.toutput = NULL;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -400,7 +405,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
//stop_meas(te_stats);
|
||||
//printf("end ldpc encoder -- output\n");
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
write_output("ulsch_enc_input0.m","enc_in0",&harq_process->c[0][0],Kr_bytes,1,4);
|
||||
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
|
||||
#endif
|
||||
@@ -438,7 +443,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
E = nr_get_E(G, harq_process->C, mod_order, harq_process->pusch_pdu.nrOfLayers, r);
|
||||
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers,harq_process->C);
|
||||
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
|
||||
nr_rate_matching_ldpc(Ilbrm,
|
||||
@@ -456,7 +461,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output ratematching e[%d]= %d r_offset %d\n", i,harq_process->e[i+r_offset], r_offset);
|
||||
#endif
|
||||
@@ -482,7 +487,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
//stop_meas(i_stats);
|
||||
|
||||
|
||||
#ifdef DEBUG_DLSCH_CODING
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
for (int i =0; i<16; i++)
|
||||
printf("output interleaving f[%d]= %d r_offset %d\n", i,harq_process->f[i+r_offset], r_offset);
|
||||
|
||||
|
||||
@@ -101,74 +101,53 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
uint32_t available_bits;
|
||||
uint8_t mod_order, cwd_index, num_of_codewords, l;
|
||||
uint8_t cwd_index, l;
|
||||
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
|
||||
uint32_t ***pusch_dmrs;
|
||||
int16_t **tx_layers;
|
||||
int32_t **txdataF;
|
||||
uint16_t start_sc, start_rb;
|
||||
int8_t Wf[2], Wt[2], l_prime[2], delta;
|
||||
uint16_t rnti, n_dmrs, code_rate, number_dmrs_symbols, nb_rb, k;
|
||||
uint8_t dmrs_type, nb_dmrs_re_per_rb, number_of_symbols, mcs, Nl;
|
||||
int ap, start_symbol, Nid_cell, i;
|
||||
int sample_offsetF, N_RE_prime, N_PRB_oh;
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t L_ptrs, K_ptrs; // PTRS parameters
|
||||
uint16_t beta_ptrs; // PTRS parameter related to power control
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
int ap, i;
|
||||
int sample_offsetF, N_RE_prime;
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
|
||||
NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
|
||||
// ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig;
|
||||
|
||||
num_of_codewords = 1; // tmp assumption
|
||||
Nid_cell = 0;
|
||||
N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
number_dmrs_symbols = 0;
|
||||
uint8_t num_of_codewords = 1; // tmp assumption
|
||||
int Nid_cell = 0;
|
||||
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
|
||||
for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {
|
||||
|
||||
ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
|
||||
harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;
|
||||
|
||||
start_symbol = harq_process_ul_ue->pusch_pdu.start_symbol_index;
|
||||
ul_dmrs_symb_pos = harq_process_ul_ue->pusch_pdu.ul_dmrs_symb_pos;
|
||||
number_of_symbols = harq_process_ul_ue->pusch_pdu.nr_of_symbols;
|
||||
dmrs_type = harq_process_ul_ue->pusch_pdu.dmrs_config_type;
|
||||
int start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
uint16_t start_rb = pusch_pdu->rb_start;
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
uint8_t Nl = pusch_pdu->nrOfLayers;
|
||||
uint8_t mod_order = pusch_pdu->qam_mod_order;
|
||||
uint16_t rnti = pusch_pdu->rnti;
|
||||
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
for (i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01)
|
||||
number_dmrs_symbols += 1;
|
||||
|
||||
}
|
||||
|
||||
rnti = harq_process_ul_ue->pusch_pdu.rnti;
|
||||
ulsch_ue->Nid_cell = Nid_cell;
|
||||
|
||||
nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data;
|
||||
get_num_re_dmrs(pusch_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols);
|
||||
|
||||
// TbD num_of_mod_symbols is set but never used
|
||||
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
|
||||
|
||||
nb_rb = harq_process_ul_ue->pusch_pdu.rb_size;
|
||||
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
|
||||
|
||||
mcs = harq_process_ul_ue->pusch_pdu.mcs_index;
|
||||
Nl = harq_process_ul_ue->pusch_pdu.nrOfLayers;
|
||||
mod_order = nr_get_Qm_ul(mcs, 0);
|
||||
code_rate = nr_get_code_rate_ul(mcs, 0);
|
||||
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = nr_compute_tbs(mod_order,
|
||||
code_rate,
|
||||
nb_rb,
|
||||
number_of_symbols,
|
||||
nb_dmrs_re_per_rb*number_dmrs_symbols,
|
||||
0,
|
||||
0,
|
||||
harq_process_ul_ue->pusch_pdu.nrOfLayers);
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
|
||||
@@ -210,14 +189,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/////////////////////////DMRS Modulation/////////////////////////
|
||||
///////////
|
||||
pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
n_dmrs = (nb_rb*((dmrs_type == pusch_dmrs_type1) ? 6:4)*number_dmrs_symbols);
|
||||
uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
|
||||
uint16_t n_dmrs = (start_rb+nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
|
||||
int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -226,12 +201,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
/////////////////////////PTRS parameters' initialization/////////////////////////
|
||||
///////////
|
||||
|
||||
int16_t mod_ptrs[(nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
|
||||
K_ptrs = 0; // just to avoid a warning
|
||||
int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
|
||||
uint8_t L_ptrs, K_ptrs = 0;
|
||||
uint16_t beta_ptrs = 1; // temp value until power control is implemented
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
K_ptrs = (harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density)?4:2;
|
||||
K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density;
|
||||
L_ptrs = 1<<harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_time_density;
|
||||
|
||||
beta_ptrs = 1; // temp value until power control is implemented
|
||||
@@ -274,11 +250,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01)
|
||||
is_dmrs = 1;
|
||||
else
|
||||
is_dmrs = 0;
|
||||
|
||||
if (is_dmrs == 1)
|
||||
nb_re_dmrs_per_rb = nb_dmrs_re_per_rb;
|
||||
else
|
||||
nb_re_dmrs_per_rb = 0;
|
||||
@@ -303,64 +274,70 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
txdataF = UE->common_vars.txdataF;
|
||||
|
||||
start_rb = harq_process_ul_ue->pusch_pdu.rb_start;
|
||||
start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
for (ap=0; ap< Nl; ap++) {
|
||||
|
||||
uint8_t k_prime = 0;
|
||||
uint16_t m = 0;
|
||||
|
||||
// DMRS params for this ap
|
||||
get_Wt(Wt, ap, dmrs_type);
|
||||
get_Wf(Wf, ap, dmrs_type);
|
||||
delta = get_delta(ap, dmrs_type);
|
||||
|
||||
|
||||
uint8_t k_prime=0;
|
||||
uint8_t is_dmrs, is_ptrs, is_dmrs_symbol;
|
||||
uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
|
||||
|
||||
for (l=start_symbol; l<start_symbol+number_of_symbols; l++) {
|
||||
|
||||
k = start_sc;
|
||||
n = 0;
|
||||
dmrs_idx = 0;
|
||||
uint16_t k = start_sc;
|
||||
uint16_t n = 0;
|
||||
uint8_t is_dmrs_sym = 0;
|
||||
uint8_t is_ptrs_sym = 0;
|
||||
uint16_t dmrs_idx = 0, ptrs_idx = 0;
|
||||
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_sym = 1;
|
||||
|
||||
if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled
|
||||
if (dmrs_type == pusch_dmrs_type1)
|
||||
dmrs_idx = start_rb*6;
|
||||
else
|
||||
dmrs_idx = start_rb*4;
|
||||
} else {
|
||||
dmrs_idx = 0;
|
||||
}
|
||||
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
|
||||
is_ptrs_sym = 1;
|
||||
nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
|
||||
|
||||
uint8_t is_dmrs = 0;
|
||||
uint8_t is_ptrs = 0;
|
||||
|
||||
sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
|
||||
|
||||
is_dmrs = 0;
|
||||
is_ptrs = 0;
|
||||
is_dmrs_symbol = 0;
|
||||
|
||||
if((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_symbol = 1;
|
||||
if (is_dmrs_sym) {
|
||||
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
|
||||
is_dmrs = 1;
|
||||
}
|
||||
|
||||
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS){
|
||||
|
||||
if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols))
|
||||
} else if (is_ptrs_sym) {
|
||||
is_ptrs = is_ptrs_subcarrier(k,
|
||||
rnti,
|
||||
ap,
|
||||
dmrs_type,
|
||||
K_ptrs,
|
||||
nb_rb,
|
||||
harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
if (is_dmrs == 1) {
|
||||
|
||||
if (k == start_sc){
|
||||
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
}
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
|
||||
@@ -378,16 +355,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
} else if (is_ptrs == 1) {
|
||||
|
||||
if (k == start_sc){
|
||||
nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
|
||||
}
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;
|
||||
|
||||
ptrs_idx++;
|
||||
|
||||
} else if (!is_dmrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,harq_process_ul_ue->pusch_pdu.num_dmrs_cdm_grps_no_data,dmrs_type)) {
|
||||
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, cdm_grps_no_data, dmrs_type)) {
|
||||
|
||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1];
|
||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
|
||||
@@ -412,8 +385,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//}
|
||||
NR_UL_UE_HARQ_t *harq_process_ulsch=NULL;
|
||||
harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid];
|
||||
harq_process_ulsch->status = SCH_IDLE;
|
||||
|
||||
@@ -191,9 +191,11 @@ typedef struct {
|
||||
int fmt;
|
||||
int numRA;
|
||||
int prachStartSymbol;
|
||||
int num_prach_ocas;
|
||||
} RU_PRACH_list_t;
|
||||
|
||||
#define NUMBER_OF_NR_RU_PRACH_MAX 8
|
||||
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
|
||||
|
||||
typedef struct RU_proc_t_s {
|
||||
/// Pointer to associated RU descriptor
|
||||
@@ -594,8 +596,8 @@ typedef struct RU_t_s {
|
||||
RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
|
||||
/// mutex for prach_list access
|
||||
pthread_mutex_t prach_list_mutex;
|
||||
/// received frequency-domain signal for PRACH (IF4p5 RRU)
|
||||
int16_t **prach_rxsigF;
|
||||
/// received frequency-domain signal for PRACH (IF4p5 RRU)
|
||||
int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX];
|
||||
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
|
||||
int16_t **prach_rxsigF_br[4];
|
||||
/// sequence number for IF5
|
||||
|
||||
+49
-3
@@ -263,6 +263,8 @@ typedef struct {
|
||||
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
|
||||
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
|
||||
uint32_t E;
|
||||
/// Number of segments processed so far
|
||||
uint32_t processedSegments;
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -397,8 +399,6 @@ 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[
|
||||
@@ -466,11 +466,17 @@ typedef struct {
|
||||
uint16_t ptrs_symbols;
|
||||
// PTRS subcarriers per OFDM symbol
|
||||
uint16_t ptrs_sc_per_ofdm_symbol;
|
||||
/// \brief Estimated phase error based upon PTRS on each symbol .
|
||||
/// - first index: ? [0..7] Number of Antenna
|
||||
/// - second index: ? [0...14] smybol per slot
|
||||
int32_t **ptrs_phase_per_slot;
|
||||
/// \brief Total RE count after DMRS/PTRS RE's are extracted from respective symbol.
|
||||
/// - first index: ? [0...14] smybol per slot
|
||||
int16_t *ul_valid_re_per_slot;
|
||||
/// flag to verify if channel level computation is done
|
||||
uint8_t cl_done;
|
||||
} NR_gNB_PUSCH;
|
||||
|
||||
|
||||
/// Context data structure for RX/TX portion of slot processing
|
||||
typedef struct {
|
||||
/// Component Carrier index
|
||||
@@ -807,15 +813,55 @@ typedef struct PHY_VARS_gNB_s {
|
||||
time_stats_t ulsch_deinterleaving_stats;
|
||||
time_stats_t ulsch_unscrambling_stats;
|
||||
time_stats_t ulsch_channel_estimation_stats;
|
||||
time_stats_t ulsch_ptrs_processing_stats;
|
||||
time_stats_t ulsch_channel_compensation_stats;
|
||||
time_stats_t ulsch_rbs_extraction_stats;
|
||||
time_stats_t ulsch_mrc_stats;
|
||||
time_stats_t ulsch_llr_stats;
|
||||
|
||||
/*
|
||||
time_stats_t rx_dft_stats;
|
||||
time_stats_t ulsch_freq_offset_estimation_stats;
|
||||
*/
|
||||
notifiedFIFO_t *respDecode;
|
||||
tpool_t *threadPool;
|
||||
int nbDecode;
|
||||
|
||||
} PHY_VARS_gNB;
|
||||
|
||||
typedef struct LDPCDecode_s {
|
||||
PHY_VARS_gNB *gNB;
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq;
|
||||
t_nrLDPC_dec_params decoderParms;
|
||||
NR_gNB_ULSCH_t *ulsch;
|
||||
short* ulsch_llr;
|
||||
int ulsch_id;
|
||||
int harq_pid;
|
||||
int rv_index;
|
||||
int A;
|
||||
int E;
|
||||
int Kc;
|
||||
int Qm;
|
||||
int Kr_bytes;
|
||||
int nbSegments;
|
||||
int segment_r;
|
||||
int r_offset;
|
||||
int offset;
|
||||
int Tbslbrm;
|
||||
int decodeIterations;
|
||||
} ldpcDecode_t;
|
||||
|
||||
struct ldpcReqId {
|
||||
uint16_t rnti;
|
||||
uint16_t frame;
|
||||
uint8_t subframe;
|
||||
uint8_t codeblock;
|
||||
uint16_t spare;
|
||||
} __attribute__((packed));
|
||||
|
||||
union ldpcReqUnion {
|
||||
struct ldpcReqId s;
|
||||
uint64_t p;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -912,10 +912,6 @@ typedef struct {
|
||||
char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||
|
||||
unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
uint8_t Msg3_startSymbol[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
uint8_t Msg3_Length[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
|
||||
NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
int turbo_iterations, turbo_cntl_iterations;
|
||||
|
||||
@@ -244,8 +244,15 @@ void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe)
|
||||
eNB->pbch_configured=0;
|
||||
}
|
||||
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(pbch_pdu, 3));
|
||||
if (T_ACTIVE(T_ENB_PHY_MIB)) {
|
||||
/* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */
|
||||
uint8_t mib[3];
|
||||
mib[0] = pbch_pdu[2];
|
||||
mib[1] = pbch_pdu[1];
|
||||
mib[2] = pbch_pdu[0];
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(mib, 3));
|
||||
}
|
||||
generate_pbch_fembms (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, (frame & 15)/4);
|
||||
} //else if ((subframe == 1) && (fp->frame_type == TDD)) {
|
||||
//generate_pss (txdataF, AMP, fp, 2, 2);
|
||||
@@ -313,8 +320,15 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
|
||||
eNB->pbch_configured=0;
|
||||
}
|
||||
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(pbch_pdu, 3));
|
||||
if (T_ACTIVE(T_ENB_PHY_MIB)) {
|
||||
/* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */
|
||||
uint8_t mib[3];
|
||||
mib[0] = pbch_pdu[2];
|
||||
mib[1] = pbch_pdu[1];
|
||||
mib[2] = pbch_pdu[0];
|
||||
T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
|
||||
T_BUFFER(mib, 3));
|
||||
}
|
||||
generate_pbch (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, frame & 3);
|
||||
} else if ((subframe == 1) && (fp->frame_type == TDD)) {
|
||||
generate_pss (txdataF, AMP, fp, 2, 2);
|
||||
|
||||
@@ -80,7 +80,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
|
||||
ru=eNB->RU_list[i];
|
||||
|
||||
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
|
||||
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
|
||||
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
|
||||
int ce_level;
|
||||
|
||||
if (br_flag==1)
|
||||
|
||||
@@ -52,87 +52,114 @@ extern uint8_t nfapi_mode;
|
||||
extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind);
|
||||
|
||||
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
|
||||
nfapi_nr_prach_pdu_t *prach_pdu) {
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
|
||||
|
||||
uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0};
|
||||
uint16_t i;
|
||||
|
||||
|
||||
gNB->UL_INFO.rach_ind.number_of_pdus=0;
|
||||
|
||||
uint8_t pdu_index = 0;
|
||||
RU_t *ru;
|
||||
int aa=0;
|
||||
int ru_aa;
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
|
||||
gNB->UL_INFO.rach_ind.sfn = frame;
|
||||
gNB->UL_INFO.rach_ind.slot = slot;
|
||||
gNB->UL_INFO.rach_ind.pdu_list = gNB->prach_pdu_indication_list;
|
||||
gNB->UL_INFO.rach_ind.number_of_pdus = 0;
|
||||
|
||||
ru=gNB->RU_list[0];
|
||||
|
||||
int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST);
|
||||
|
||||
if (prach_id>=0) {
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
|
||||
uint8_t prachStartSymbol;
|
||||
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
|
||||
|
||||
/*
|
||||
uint16_t format,RA_sfn_index;
|
||||
uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period;
|
||||
|
||||
for (i=0;i<gNB->num_RU;i++) {
|
||||
ru=gNB->RU_list[i];
|
||||
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
|
||||
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[i]->prach_rxsigF[ru_aa];
|
||||
}
|
||||
}
|
||||
get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value,
|
||||
frame,slot,
|
||||
gNB->gNB_config.carrier_config.dl_frequency.value,
|
||||
gNB->frame_parms.numerology_index,
|
||||
gNB->frame_parms.frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&RA_sfn_index,
|
||||
&N_RA_slot,
|
||||
&config_period);
|
||||
*/
|
||||
|
||||
for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) {
|
||||
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
|
||||
gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa];
|
||||
}
|
||||
|
||||
rx_nr_prach(gNB,
|
||||
prach_pdu,
|
||||
prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur;
|
||||
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
|
||||
|
||||
rx_nr_prach(gNB,
|
||||
prach_pdu,
|
||||
prach_oc,
|
||||
frame,
|
||||
slot,
|
||||
&max_preamble[0],
|
||||
&max_preamble_energy[0],
|
||||
&max_preamble_delay[0]
|
||||
);
|
||||
free_nr_prach_entry(gNB,prach_id);
|
||||
LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
|
||||
frame,slot,prach_oc,prachStartSymbol,
|
||||
max_preamble[0],
|
||||
max_preamble_energy[0]/10,
|
||||
max_preamble_delay[0],
|
||||
gNB->prach_energy_counter);
|
||||
|
||||
if ((gNB->prach_energy_counter == 100) &&
|
||||
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
|
||||
|
||||
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n",
|
||||
gNB->Mod_id,
|
||||
frame,
|
||||
slot,
|
||||
&max_preamble[0],
|
||||
&max_preamble_energy[0],
|
||||
&max_preamble_delay[0]
|
||||
);
|
||||
|
||||
LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
|
||||
frame,slot,
|
||||
max_preamble[0],
|
||||
max_preamble_energy[0]/10,
|
||||
max_preamble_delay[0],
|
||||
gNB->prach_energy_counter);
|
||||
|
||||
if ((gNB->prach_energy_counter == 100) &&
|
||||
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
|
||||
|
||||
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
|
||||
gNB->Mod_id,
|
||||
frame,
|
||||
slot,
|
||||
max_preamble[0],
|
||||
max_preamble_energy[0]/10,
|
||||
max_preamble_energy[0]%10,
|
||||
max_preamble_delay[0]);
|
||||
|
||||
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
|
||||
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
|
||||
|
||||
|
||||
gNB->UL_INFO.rach_ind.number_of_pdus = 1;
|
||||
gNB->UL_INFO.rach_ind.pdu_list = &gNB->prach_pdu_indication_list[0];
|
||||
gNB->UL_INFO.rach_ind.sfn = frame;
|
||||
gNB->UL_INFO.rach_ind.slot = slot;
|
||||
|
||||
gNB->prach_pdu_indication_list[0].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
|
||||
gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol; // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion)
|
||||
gNB->prach_pdu_indication_list[0].slot_index = slot;
|
||||
gNB->prach_pdu_indication_list[0].freq_index = prach_pdu->num_ra;
|
||||
gNB->prach_pdu_indication_list[0].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
|
||||
gNB->prach_pdu_indication_list[0].avg_snr = 0xff; // invalid for now
|
||||
|
||||
|
||||
gNB->prach_pdu_indication_list[0].num_preamble = 1;
|
||||
gNB->prach_pdu_indication_list[0].preamble_list = gNB->preamble_list;
|
||||
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index = max_preamble[0];
|
||||
gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance = max_preamble_delay[0];
|
||||
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr = 0xffffffff;
|
||||
}
|
||||
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
|
||||
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
|
||||
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
|
||||
|
||||
|
||||
max_preamble[0],
|
||||
max_preamble_energy[0]/10,
|
||||
max_preamble_energy[0]%10,
|
||||
max_preamble_delay[0],
|
||||
prachStartSymbol,
|
||||
prach_pdu->num_ra);
|
||||
|
||||
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
|
||||
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
|
||||
|
||||
|
||||
gNB->UL_INFO.rach_ind.number_of_pdus += 1;
|
||||
|
||||
gNB->prach_pdu_indication_list[pdu_index].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
|
||||
gNB->prach_pdu_indication_list[pdu_index].symbol_index = prachStartSymbol;
|
||||
gNB->prach_pdu_indication_list[pdu_index].slot_index = slot;
|
||||
gNB->prach_pdu_indication_list[pdu_index].freq_index = prach_pdu->num_ra;
|
||||
gNB->prach_pdu_indication_list[pdu_index].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
|
||||
gNB->prach_pdu_indication_list[pdu_index].avg_snr = 0xff; // invalid for now
|
||||
|
||||
gNB->prach_pdu_indication_list[pdu_index].num_preamble = 1;
|
||||
gNB->prach_pdu_indication_list[pdu_index].preamble_list = gNB->preamble_list;
|
||||
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_index = max_preamble[0];
|
||||
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].timing_advance = max_preamble_delay[0];
|
||||
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff;
|
||||
pdu_index++;
|
||||
}
|
||||
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
|
||||
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
|
||||
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
|
||||
} //if prach_id>0
|
||||
} //for NUMBER_OF_NR_PRACH_OCCASION_MAX
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
|
||||
}
|
||||
|
||||
|
||||
@@ -217,12 +217,74 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
|
||||
*/
|
||||
|
||||
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
|
||||
int r = rdata->segment_r;
|
||||
|
||||
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
|
||||
ulsch_harq->processedSegments++;
|
||||
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
|
||||
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
|
||||
gNB->nbDecode--;
|
||||
LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode);
|
||||
|
||||
if (decodeSuccess) {
|
||||
memcpy(ulsch_harq->b+rdata->offset,
|
||||
ulsch_harq->c[r],
|
||||
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
|
||||
|
||||
} else {
|
||||
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
|
||||
int nb=abortTpool(gNB->threadPool, req->key);
|
||||
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
|
||||
gNB->nbDecode-=nb;
|
||||
LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
|
||||
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
||||
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
|
||||
ulsch_harq->processedSegments, nb, rdata->nbSegments);
|
||||
ulsch_harq->processedSegments=rdata->nbSegments;
|
||||
}
|
||||
}
|
||||
|
||||
// if all segments are done
|
||||
if (rdata->nbSegments == ulsch_harq->processedSegments) {
|
||||
if (decodeSuccess) {
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n",
|
||||
gNB->Mod_id,ulsch_harq->slot,ulsch_harq->TBS);
|
||||
ulsch_harq->status = SCH_IDLE;
|
||||
ulsch_harq->round = 0;
|
||||
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||
|
||||
LOG_D(PHY, "ULSCH received ok \n");
|
||||
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0);
|
||||
} else {
|
||||
LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) r %d\n",
|
||||
gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot,
|
||||
rdata->harq_pid,ulsch_harq->status, ulsch_harq->round,ulsch_harq->TBS,r);
|
||||
if (ulsch_harq->round >= ulsch->Mlimit) {
|
||||
ulsch_harq->status = SCH_IDLE;
|
||||
ulsch_harq->round = 0;
|
||||
ulsch_harq->handled = 0;
|
||||
ulsch->harq_mask &= ~(1 << rdata->harq_pid);
|
||||
}
|
||||
ulsch_harq->handled = 1;
|
||||
|
||||
LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
|
||||
nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1);
|
||||
}
|
||||
ulsch->last_iteration_cnt = rdata->decodeIterations;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu;
|
||||
|
||||
uint8_t ret;
|
||||
uint8_t l, number_dmrs_symbols = 0;
|
||||
uint32_t G;
|
||||
uint16_t start_symbol, number_symbols, nb_re_dmrs;
|
||||
@@ -274,25 +336,22 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
|
||||
//----------------------------------------------------------
|
||||
|
||||
start_meas(&gNB->ulsch_decoding_stats);
|
||||
ret = nr_ulsch_decoding(gNB,
|
||||
ULSCH_id,
|
||||
gNB->pusch_vars[ULSCH_id]->llr,
|
||||
frame_parms,
|
||||
pusch_pdu,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
harq_pid,
|
||||
G);
|
||||
stop_meas(&gNB->ulsch_decoding_stats);
|
||||
nr_ulsch_decoding(gNB,
|
||||
ULSCH_id,
|
||||
gNB->pusch_vars[ULSCH_id]->llr,
|
||||
frame_parms,
|
||||
pusch_pdu,
|
||||
frame_rx,
|
||||
slot_rx,
|
||||
harq_pid,
|
||||
G);
|
||||
|
||||
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
|
||||
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
|
||||
}
|
||||
else if(gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->b!=NULL){
|
||||
LOG_D(PHY, "ULSCH received ok \n");
|
||||
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 0);
|
||||
while (gNB->nbDecode > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
|
||||
nr_postDecode(gNB, req);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
stop_meas(&gNB->ulsch_decoding_stats);
|
||||
}
|
||||
|
||||
|
||||
@@ -490,7 +549,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
(pucch->frame == frame_rx) &&
|
||||
(pucch->slot == slot_rx) ) {
|
||||
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||
uint16_t num_ucis;
|
||||
|
||||
switch (pucch_pdu->format_type) {
|
||||
|
||||
@@ -39,7 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
|
||||
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, int frame_rx, int slot_rx);
|
||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_prach_pdu_t *prach_pdu);
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
|
||||
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);
|
||||
|
||||
@@ -111,17 +111,18 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
*/
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t thread_id);
|
||||
|
||||
/*! \brief Scheduling for UE RX procedures in normal subframes.
|
||||
@param last_slot Index of last slot (0-19)
|
||||
@param phy_vars_ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to RXn_TXnp4 proc information
|
||||
@param eNB_id Local id of eNB on which to act
|
||||
@param abstraction_flag Indicator of PHY abstraction
|
||||
@param mode calibration/debug mode
|
||||
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
|
||||
@param phy_vars_rn pointer to RN variables
|
||||
@param ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to proc information
|
||||
@param gNB_id Local id of eNB on which to act
|
||||
@param mode calibration/debug mode
|
||||
*/
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t do_pdcch_flag,runmode_t mode);
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id,
|
||||
runmode_t mode);
|
||||
|
||||
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type);
|
||||
|
||||
|
||||
|
||||
@@ -57,10 +57,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0];
|
||||
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
|
||||
NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
|
||||
//PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
|
||||
|
||||
// PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
|
||||
// PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
|
||||
|
||||
if(scheduled_response->dl_config != NULL){
|
||||
fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
|
||||
@@ -93,11 +89,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
dlsch0->current_harq_pid = current_harq_pid;
|
||||
dlsch0->active = 1;
|
||||
dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti;
|
||||
//dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs;
|
||||
dlsch0_harq = dlsch0->harq_processes[current_harq_pid];
|
||||
|
||||
if (dlsch0_harq){
|
||||
|
||||
dlsch0_harq->status = ACTIVE;
|
||||
dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart;
|
||||
dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize;
|
||||
dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs;
|
||||
@@ -121,8 +117,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pdcch_vars->nb_search_space = 0;
|
||||
dl_config->number_pdus = 0;
|
||||
}
|
||||
|
||||
if (scheduled_response->ul_config != NULL){
|
||||
@@ -159,13 +154,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH;
|
||||
|
||||
if (scheduled_response->tx_request){
|
||||
if (scheduled_response->tx_request){ // TBR todo here it should loop through the number of tx pdus
|
||||
fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body;
|
||||
|
||||
//harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char));
|
||||
memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length);
|
||||
|
||||
harq_process_ul_ue->status = ACTIVE;
|
||||
|
||||
scheduled_response->tx_request->number_of_pdus = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -223,7 +219,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
|
||||
case (FAPI_NR_UL_CONFIG_TYPE_PRACH):
|
||||
// prach config pdu
|
||||
//prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[gNB_id];
|
||||
prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
|
||||
memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu));
|
||||
PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_Config_enabled = 1;
|
||||
@@ -233,11 +228,9 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ul_config->number_pdus = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,9 @@
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
@@ -84,8 +87,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
// dummy functions
|
||||
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
const int CC_id,
|
||||
const uint8_t gNB_index,
|
||||
@@ -96,19 +97,33 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pdcp_layer_init(void) {}
|
||||
boolean_t
|
||||
pdcp_data_ind(
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
) { return(false);}
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
int rrc_init_nr_global_param(void){return(0);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int pdsch_AntennaPorts,
|
||||
@@ -124,7 +139,6 @@ int generate_dlsch_header(unsigned char *mac_header,
|
||||
unsigned char *ue_cont_res_id,
|
||||
unsigned char short_padding,
|
||||
unsigned short post_padding){return 0;}
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
|
||||
// needed for some functions
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
@@ -184,7 +198,7 @@ int main(int argc, char **argv)
|
||||
|
||||
int frame=1,slot=1;
|
||||
int frame_length_complex_samples;
|
||||
int frame_length_complex_samples_no_prefix;
|
||||
//int frame_length_complex_samples_no_prefix;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
NR_Sched_Rsp_t Sched_INFO;
|
||||
@@ -192,12 +206,11 @@ int main(int argc, char **argv)
|
||||
NR_UE_MAC_INST_t *UE_mac;
|
||||
int cyclic_prefix_type = NFAPI_CP_NORMAL;
|
||||
int run_initial_sync=0;
|
||||
int do_pdcch_flag=1;
|
||||
int pusch_tgt_snrx10 = 200;
|
||||
int pucch_tgt_snrx10 = 200;
|
||||
int loglvl=OAILOG_INFO;
|
||||
|
||||
float target_error_rate = 0.01;
|
||||
//float target_error_rate = 0.01;
|
||||
int css_flag=0;
|
||||
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
@@ -359,7 +372,7 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'I':
|
||||
run_initial_sync=1;
|
||||
target_error_rate=0.1;
|
||||
//target_error_rate=0.1;
|
||||
slot = 0;
|
||||
break;
|
||||
|
||||
@@ -585,7 +598,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
|
||||
s_re = malloc(2*sizeof(double*));
|
||||
s_im = malloc(2*sizeof(double*));
|
||||
@@ -698,7 +711,7 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
nr_ue_phy_config_request(&UE_mac->phy_config);
|
||||
NR_UE_list_t *UE_list = &RC.nrmac[0]->UE_list;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
|
||||
//NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels;
|
||||
snrRun = 0;
|
||||
|
||||
@@ -759,12 +772,14 @@ int main(int argc, char **argv)
|
||||
memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
|
||||
|
||||
UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid;
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid;
|
||||
gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
gNB_mac->UE_info.num_pdcch_cand[0][i] = 0;
|
||||
|
||||
if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config);
|
||||
else nr_schedule_css_dlsch_phytest(0,frame,slot);
|
||||
@@ -856,7 +871,6 @@ int main(int argc, char **argv)
|
||||
phy_procedures_nrUE_RX(UE,
|
||||
&UE_proc,
|
||||
0,
|
||||
do_pdcch_flag,
|
||||
normal_txrx);
|
||||
|
||||
//printf("dlsim round %d ends\n",round);
|
||||
@@ -999,7 +1013,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
//if ((float)n_errors/(float)n_trials <= target_error_rate) {
|
||||
if (effRate >= (eff_tp_check*TBS)) {
|
||||
if (effRate > (eff_tp_check*TBS)) {
|
||||
printf("PDSCH test OK\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
#define NR_PRACH_DEBUG 1
|
||||
#define PRACH_WRITE_OUTPUT_DEBUG 1
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
@@ -66,17 +70,34 @@ int sl_ahead = 0;
|
||||
uint64_t get_softmodem_optmask(void) {return 0;}
|
||||
softmodem_params_t *get_softmodem_params(void) {return 0;}
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP) {return(false);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
void pdcp_layer_init(void) {}
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
@@ -92,6 +113,10 @@ int main(int argc, char **argv){
|
||||
uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
|
||||
uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
|
||||
uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
|
||||
uint16_t RA_sfn_index;
|
||||
uint8_t N_RA_slot;
|
||||
uint8_t config_period;
|
||||
int prachOccasion = 0;
|
||||
double DS_TDL = .03;
|
||||
|
||||
// int8_t interf1=-19,interf2=-19;
|
||||
@@ -407,15 +432,18 @@ int main(int argc, char **argv){
|
||||
gNB->proc.slot_rx = slot;
|
||||
|
||||
int ret = get_nr_prach_info_from_index(config_index,
|
||||
(int)frame,
|
||||
(int)slot_gNB,
|
||||
absoluteFrequencyPointA,
|
||||
mu,
|
||||
frame_parms->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur);
|
||||
(int)frame,
|
||||
(int)slot_gNB,
|
||||
absoluteFrequencyPointA,
|
||||
mu,
|
||||
frame_parms->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&RA_sfn_index,
|
||||
&N_RA_slot,
|
||||
&config_period);
|
||||
|
||||
if (ret == 0) {printf("No prach in %d.%d, mu %d, config_index %d\n",frame,slot,mu,config_index); exit(-1);}
|
||||
format0 = format&0xff; // first column of format from table
|
||||
@@ -424,60 +452,54 @@ int main(int argc, char **argv){
|
||||
if (format1 != 0xff) {
|
||||
switch(format0) {
|
||||
case 0xa1:
|
||||
prach_format = 9;
|
||||
prach_format = 11;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_format = 10;
|
||||
prach_format = 12;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_format = 11;
|
||||
prach_format = 13;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
|
||||
}
|
||||
} else {
|
||||
switch(format0) {
|
||||
case 0xa1:
|
||||
prach_format = 0;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_format = 1;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_format = 2;
|
||||
break;
|
||||
case 0xb1:
|
||||
prach_format = 3;
|
||||
break;
|
||||
case 0xb2:
|
||||
prach_format = 4;
|
||||
break;
|
||||
case 0xb3:
|
||||
prach_format = 5;
|
||||
break;
|
||||
case 0xb4:
|
||||
prach_format = 6;
|
||||
break;
|
||||
case 0xc0:
|
||||
prach_format = 7;
|
||||
break;
|
||||
case 0xc2:
|
||||
prach_format = 8;
|
||||
break;
|
||||
case 0:
|
||||
// long formats are handled @ PHY
|
||||
break;
|
||||
case 1:
|
||||
// long formats are handled @ PHY
|
||||
break;
|
||||
case 2:
|
||||
// long formats are handled @ PHY
|
||||
break;
|
||||
case 3:
|
||||
// long formats are handled @ PHY
|
||||
break;
|
||||
switch(format0) { // single PRACH format
|
||||
case 0:
|
||||
prach_format = 0;
|
||||
break;
|
||||
case 1:
|
||||
prach_format = 1;
|
||||
break;
|
||||
case 2:
|
||||
prach_format = 2;
|
||||
break;
|
||||
case 3:
|
||||
prach_format = 3;
|
||||
break;
|
||||
case 0xa1:
|
||||
prach_format = 4;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_format = 5;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_format = 6;
|
||||
break;
|
||||
case 0xb1:
|
||||
prach_format = 7;
|
||||
break;
|
||||
case 0xb4:
|
||||
prach_format = 8;
|
||||
break;
|
||||
case 0xc0:
|
||||
prach_format = 9;
|
||||
break;
|
||||
case 0xc2:
|
||||
prach_format = 10;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0, "Invalid PRACH format");
|
||||
AssertFatal(1 == 0, "Invalid PRACH format");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,11 +722,11 @@ int main(int argc, char **argv){
|
||||
}
|
||||
|
||||
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, slot);
|
||||
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
|
||||
|
||||
gNB->prach_vars.rxsigF = ru->prach_rxsigF;
|
||||
gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion];
|
||||
if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value);
|
||||
rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
|
||||
rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
|
||||
|
||||
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "openair1/SIMULATION/RF/rf.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
//#define DEBUG_NR_ULSCHSIM
|
||||
|
||||
@@ -67,6 +68,44 @@ PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
|
||||
uint16_t n_rnti = 0x1234;
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
|
||||
int r = rdata->segment_r;
|
||||
|
||||
bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
|
||||
ulsch_harq->processedSegments++;
|
||||
gNB->nbDecode--;
|
||||
|
||||
if (decodeSuccess) {
|
||||
memcpy(ulsch_harq->b+rdata->offset,
|
||||
ulsch_harq->c[r],
|
||||
rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
|
||||
} else {
|
||||
if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
|
||||
int nb=abortTpool(gNB->threadPool, req->key);
|
||||
nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
|
||||
gNB->nbDecode-=nb;
|
||||
AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
|
||||
ulsch_harq->processedSegments, nb, rdata->nbSegments);
|
||||
ulsch_harq->processedSegments=rdata->nbSegments;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if all segments are done
|
||||
if (rdata->nbSegments == ulsch_harq->processedSegments) {
|
||||
if (decodeSuccess) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
ulsch->last_iteration_cnt = rdata->decodeIterations;
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c;
|
||||
@@ -92,7 +131,7 @@ int main(int argc, char **argv)
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
double sigma;
|
||||
unsigned char qbits = 8;
|
||||
int ret;
|
||||
int ret=0;
|
||||
int loglvl = OAILOG_WARNING;
|
||||
uint64_t SSB_positions=0x01;
|
||||
uint16_t nb_symb_sch = 12;
|
||||
@@ -338,6 +377,11 @@ int main(int argc, char **argv)
|
||||
gNB = RC.gNB[0];
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char tp_param[] = "n";
|
||||
initTpool(tp_param, gNB->threadPool, true);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
|
||||
frame_parms->nb_antennas_tx = n_tx;
|
||||
frame_parms->nb_antennas_rx = n_rx;
|
||||
@@ -408,7 +452,7 @@ int main(int argc, char **argv)
|
||||
rel15_ul->pusch_data.rv_index = rvidx;
|
||||
rel15_ul->nrOfLayers = Nl;
|
||||
rel15_ul->target_code_rate = code_rate;
|
||||
rel15_ul->pusch_data.tb_size = TBS>>3;
|
||||
rel15_ul->pusch_data.tb_size = TBS/8;
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
|
||||
@@ -444,7 +488,7 @@ int main(int argc, char **argv)
|
||||
harq_process_ul_ue->pusch_pdu.nr_of_symbols = nb_symb_sch;
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.rv_index = rvidx;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS/8;
|
||||
harq_process_ul_ue->a = &test_input[0];
|
||||
|
||||
}
|
||||
@@ -531,10 +575,15 @@ int main(int argc, char **argv)
|
||||
rel15_ul->qam_mod_order,
|
||||
rel15_ul->nrOfLayers);
|
||||
|
||||
ret = nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
|
||||
nr_ulsch_decoding(gNB, UE_id, channel_output_fixed, frame_parms, rel15_ul,
|
||||
frame, subframe, harq_pid, G);
|
||||
while (gNB->nbDecode > 0) {
|
||||
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
|
||||
ret = nr_postDecode_sim(gNB, req);
|
||||
delNotifiedFIFO_elt(req);
|
||||
}
|
||||
|
||||
if (ret > ulsch_gNB->max_ldpc_iterations)
|
||||
if (ret)
|
||||
n_errors++;
|
||||
|
||||
//count errors
|
||||
|
||||
+231
-123
@@ -55,11 +55,17 @@
|
||||
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
|
||||
//#define DEBUG_ULSIM
|
||||
|
||||
unsigned char NB_eNB_INST=0;
|
||||
LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC;
|
||||
rlc_info_t Rlc_info_um,Rlc_info_am_config;
|
||||
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
@@ -84,20 +90,34 @@ int generate_dlsch_header(unsigned char *mac_header,
|
||||
unsigned char *ue_cont_res_id,
|
||||
unsigned char short_padding,
|
||||
unsigned short post_padding){return 0;}
|
||||
void pdcp_layer_init (void) {}
|
||||
boolean_t pdcp_data_ind(
|
||||
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const MBMS_flag_t MBMS_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
mem_block_t *const sdu_buffer_pP
|
||||
) { return(false);}
|
||||
const rb_id_t Srb_id,
|
||||
const sdu_size_t sdu_sizeP,
|
||||
const uint8_t *const buffer_pP
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;}
|
||||
void nr_DRB_preconfiguration(void){}
|
||||
int rrc_init_nr_global_param(void){return(0);}
|
||||
int
|
||||
gtpv1u_create_s1u_tunnel(
|
||||
const instance_t instanceP,
|
||||
const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP,
|
||||
gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP,
|
||||
uint8_t *inde_list
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// needed for some functions
|
||||
uint16_t n_rnti = 0x1234;
|
||||
@@ -165,6 +185,13 @@ int main(int argc, char **argv)
|
||||
//float eff_tp_check = 0.7;
|
||||
uint8_t snrRun;
|
||||
|
||||
int enable_ptrs = 0;
|
||||
int modify_dmrs = 0;
|
||||
/* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
|
||||
int ptrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
|
||||
int dmrs_arg[2] = {-1,-1};// Invalid values
|
||||
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
FILE *scg_fd=NULL;
|
||||
int file_offset = 0;
|
||||
@@ -174,6 +201,7 @@ int main(int argc, char **argv)
|
||||
int pucch_tgt_snrx10 = 200;
|
||||
int ibwps=24;
|
||||
int ibwp_rboffset=41;
|
||||
int params_from_file = 0;
|
||||
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0 ) {
|
||||
exit_fun("[NR_ULSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -181,7 +209,7 @@ int main(int argc, char **argv)
|
||||
//logInit();
|
||||
randominit(0);
|
||||
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:M:N:PR:S:L:G:H:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
|
||||
printf("handling optarg %c\n",c);
|
||||
switch (c) {
|
||||
|
||||
@@ -359,7 +387,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'G':
|
||||
file_offset = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
slot = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
// SSB_positions = atoi(optarg);
|
||||
break;
|
||||
@@ -388,14 +424,24 @@ int main(int argc, char **argv)
|
||||
loglvl = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
file_offset = atoi(optarg);
|
||||
case 'T':
|
||||
enable_ptrs=1;
|
||||
for(i=0; i < atoi(optarg); i++){
|
||||
ptrs_arg[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
slot = atoi(optarg);
|
||||
case 'U':
|
||||
modify_dmrs = 1;
|
||||
for(i=0; i < atoi(optarg); i++){
|
||||
dmrs_arg[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'Q':
|
||||
params_from_file = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
|
||||
@@ -417,7 +463,7 @@ int main(int argc, char **argv)
|
||||
printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
|
||||
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-G raw file containing RRC configuration (generated by gNB)\n");
|
||||
printf("-G Offset of samples to read from file (0 default)\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
@@ -425,6 +471,9 @@ int main(int argc, char **argv)
|
||||
printf("-t Acceptable effective throughput (in percentage)\n");
|
||||
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
|
||||
printf("-P Print ULSCH performances\n");
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
|
||||
printf("-Q If -F used, read parameters from file\n");
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
@@ -469,8 +518,13 @@ int main(int argc, char **argv)
|
||||
UE2gNB->max_Doppler = maxDoppler;
|
||||
|
||||
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
|
||||
RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
|
||||
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
|
||||
gNB = RC.gNB[0];
|
||||
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
char tp_param[] = "n";
|
||||
initTpool(tp_param, gNB->threadPool, true);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
@@ -513,7 +567,7 @@ int main(int argc, char **argv)
|
||||
0);
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
// xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
|
||||
|
||||
@@ -607,13 +661,9 @@ int main(int argc, char **argv)
|
||||
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fapi_nr_ul_config_request_t ul_config;
|
||||
fapi_nr_tx_request_t tx_req;
|
||||
fapi_nr_tx_request_body_t tx_req_body;
|
||||
|
||||
unsigned int TBS;
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
unsigned int available_bits;
|
||||
uint8_t nb_re_dmrs;
|
||||
unsigned char mod_order;
|
||||
uint16_t code_rate;
|
||||
uint8_t ptrs_mcs1 = 2;
|
||||
uint8_t ptrs_mcs2 = 4;
|
||||
uint8_t ptrs_mcs3 = 10;
|
||||
@@ -624,28 +674,80 @@ int main(int argc, char **argv)
|
||||
uint8_t max_rounds = 4;
|
||||
uint8_t crc_status = 0;
|
||||
|
||||
uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct
|
||||
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs); // [hna] remove dmrs struct
|
||||
unsigned char mod_order = nr_get_Qm_ul(Imcs, 0);
|
||||
uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
|
||||
|
||||
uint8_t mapping_type = typeB; // Default Values
|
||||
pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values
|
||||
pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos0; // Default Values
|
||||
|
||||
/* validate parameters othwerwise default values are used */
|
||||
/* -U flag can be used to set DMRS parameters*/
|
||||
if(modify_dmrs)
|
||||
{
|
||||
if(dmrs_arg[0] == 0)
|
||||
{
|
||||
mapping_type = typeA;
|
||||
}
|
||||
else if (dmrs_arg[0] == 1)
|
||||
{
|
||||
mapping_type = typeB;
|
||||
}
|
||||
/* Additional DMRS positions */
|
||||
if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
|
||||
{
|
||||
add_pos = dmrs_arg[1];
|
||||
}
|
||||
printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
|
||||
}
|
||||
|
||||
uint8_t length_dmrs = pusch_len1;
|
||||
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
|
||||
uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
|
||||
uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
|
||||
unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
|
||||
|
||||
uint8_t ulsch_input_buffer[TBS/8];
|
||||
|
||||
ulsch_input_buffer[0] = 0x31;
|
||||
for (i = 1; i < TBS/8; i++) {
|
||||
ulsch_input_buffer[i] = (unsigned char) rand();
|
||||
}
|
||||
|
||||
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
|
||||
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
|
||||
int ptrs_symbols = 0; // to calculate total PTRS RE's in a slot
|
||||
|
||||
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
|
||||
|
||||
/* -T option enable PTRS */
|
||||
if(enable_ptrs)
|
||||
{
|
||||
/* validate parameters othwerwise default values are used */
|
||||
if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 )
|
||||
{
|
||||
ptrs_time_density = ptrs_arg[0];
|
||||
}
|
||||
if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 )
|
||||
{
|
||||
ptrs_freq_density = ptrs_arg[1];
|
||||
}
|
||||
pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
|
||||
printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
|
||||
}
|
||||
|
||||
if (input_fd != NULL) max_rounds=1;
|
||||
|
||||
if(1<<ptrs_time_density >= nb_symb_sch)
|
||||
pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
|
||||
for (i = 0; i < nb_symb_sch; i++) {
|
||||
number_dmrs_symbols += (l_prime_mask >> i) & 0x01;
|
||||
}
|
||||
|
||||
mod_order = nr_get_Qm_ul(Imcs, 0);
|
||||
code_rate = nr_get_code_rate_ul(Imcs, 0);
|
||||
|
||||
printf("\n");
|
||||
|
||||
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
|
||||
snrRun = 0;
|
||||
int n_errs = 0;
|
||||
int read_errors=0;
|
||||
|
||||
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
|
||||
@@ -655,35 +757,39 @@ int main(int argc, char **argv)
|
||||
// 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s,
|
||||
AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing);
|
||||
|
||||
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
|
||||
fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
|
||||
printf("rnti %x\n",n_rnti);
|
||||
fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_rb %d\n",nb_rb);
|
||||
int16_t dummy;
|
||||
fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("rb_start %d\n",start_rb);
|
||||
fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_symb_sch %d\n",nb_symb_sch);
|
||||
fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
|
||||
printf("start_symbol %d\n",start_symbol);
|
||||
fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
|
||||
printf("mcs %d\n",Imcs);
|
||||
fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
|
||||
printf("rv_index %d\n",rv_index);
|
||||
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
|
||||
fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (params_from_file) {
|
||||
fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET);
|
||||
read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd);
|
||||
printf("rnti %x\n",n_rnti);
|
||||
read_errors+=fread((void*)&nb_rb,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_rb %d\n",nb_rb);
|
||||
int16_t dummy;
|
||||
read_errors+=fread((void*)&start_rb,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("rb_start %d\n",start_rb);
|
||||
read_errors+=fread((void*)&nb_symb_sch,sizeof(int16_t),1,input_fd);
|
||||
//fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("nb_symb_sch %d\n",nb_symb_sch);
|
||||
read_errors+=fread((void*)&start_symbol,sizeof(int16_t),1,input_fd);
|
||||
printf("start_symbol %d\n",start_symbol);
|
||||
read_errors+=fread((void*)&Imcs,sizeof(int16_t),1,input_fd);
|
||||
printf("mcs %d\n",Imcs);
|
||||
read_errors+=fread((void*)&rv_index,sizeof(int16_t),1,input_fd);
|
||||
printf("rv_index %d\n",rv_index);
|
||||
// fread((void*)&harq_pid,sizeof(int16_t),1,input_fd);
|
||||
read_errors+=fread((void*)&dummy,sizeof(int16_t),1,input_fd);
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
}
|
||||
fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET);
|
||||
read_errors+=fread((void*)&gNB->common_vars.rxdata[0][slot_offset-delay],
|
||||
sizeof(int16_t),
|
||||
slot_length<<1,
|
||||
input_fd);
|
||||
if (read_errors==0) exit(1);
|
||||
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
|
||||
slot_offset,
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
|
||||
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
|
||||
}
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||
@@ -694,6 +800,17 @@ int main(int argc, char **argv)
|
||||
int n_errors[4] = {0,0,0,0};;
|
||||
int round_trials[4]={0,0,0,0};
|
||||
uint32_t errors_scrambling[4] = {0,0,0,0};
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
reset_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_unscrambling_stats);
|
||||
reset_meas(&gNB->ulsch_channel_estimation_stats);
|
||||
reset_meas(&gNB->ulsch_llr_stats);
|
||||
reset_meas(&gNB->ulsch_channel_compensation_stats);
|
||||
reset_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
|
||||
clear_pusch_stats(gNB);
|
||||
for (trial = 0; trial < n_trials; trial++) {
|
||||
@@ -707,39 +824,10 @@ int main(int argc, char **argv)
|
||||
ulsch_ue[0]->harq_processes[harq_pid]->round = round;
|
||||
gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round;
|
||||
rv_index = nr_rv_round_map[round];
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_deinterleaving_stats);
|
||||
reset_meas(&gNB->ulsch_rate_unmatching_stats);
|
||||
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
|
||||
reset_meas(&gNB->ulsch_unscrambling_stats);
|
||||
reset_meas(&gNB->ulsch_channel_estimation_stats);
|
||||
reset_meas(&gNB->ulsch_llr_stats);
|
||||
reset_meas(&gNB->ulsch_mrc_stats);
|
||||
reset_meas(&gNB->ulsch_channel_compensation_stats);
|
||||
reset_meas(&gNB->ulsch_rbs_extraction_stats);
|
||||
|
||||
UE_proc.nr_tti_tx = slot;
|
||||
UE_proc.frame_tx = frame;
|
||||
|
||||
// --------- setting parameters for gNB --------
|
||||
/*
|
||||
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.length_dmrs = length_dmrs;
|
||||
rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
|
||||
rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
|
||||
rel15_ul->ulsch_pdu_rel15.rv = 0;
|
||||
rel15_ul->ulsch_pdu_rel15.ndi = 0;
|
||||
rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers;
|
||||
rel15_ul->ulsch_pdu_rel15.R = code_rate;
|
||||
///////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
UL_tti_req->SFN = frame;
|
||||
UL_tti_req->Slot = slot;
|
||||
UL_tti_req->n_pdus = 1;
|
||||
@@ -766,6 +854,7 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->bwp_size = abwp_size;
|
||||
}
|
||||
|
||||
pusch_pdu->pusch_data.tb_size = TBS/8;
|
||||
pusch_pdu->pdu_bit_map = pdu_bit_map;
|
||||
pusch_pdu->rnti = n_rnti;
|
||||
pusch_pdu->mcs_index = Imcs;
|
||||
@@ -776,7 +865,7 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
|
||||
pusch_pdu->dmrs_config_type = 0;
|
||||
pusch_pdu->dmrs_config_type = dmrs_config_type;
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->scid = 0;
|
||||
pusch_pdu->dmrs_ports = 1;
|
||||
@@ -809,44 +898,49 @@ int main(int argc, char **argv)
|
||||
scheduled_response.slot = slot;
|
||||
scheduled_response.dl_config = NULL;
|
||||
scheduled_response.ul_config = &ul_config;
|
||||
scheduled_response.tx_request = (fapi_nr_tx_request_t *) malloc(sizeof(fapi_nr_tx_request_t));
|
||||
scheduled_response.tx_request->tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t));
|
||||
scheduled_response.tx_request = &tx_req;
|
||||
scheduled_response.tx_request->tx_request_body = &tx_req_body;
|
||||
|
||||
// Config UL TX PDU
|
||||
tx_req.slot = slot;
|
||||
tx_req.sfn = frame;
|
||||
// tx_req->tx_config // TbD
|
||||
tx_req.number_of_pdus = 1;
|
||||
tx_req_body.pdu_length = TBS/8;
|
||||
tx_req_body.pdu_index = 0;
|
||||
tx_req_body.pdu = &ulsch_input_buffer[0];
|
||||
|
||||
ul_config.slot = slot;
|
||||
ul_config.number_pdus = 1;
|
||||
ul_config.ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rnti = n_rnti;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.qam_mod_order = mod_order;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rb_size = nb_rb;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.rb_start = start_rb;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = 0;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
//there are plenty of other parameters that we don't seem to be using for now. e.g.
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
|
||||
|
||||
nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
|
||||
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
|
||||
TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
|
||||
pusch_pdu->pusch_data.tb_size = TBS>>3;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
|
||||
|
||||
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
|
||||
|
||||
for (int i=0;i<(TBS>>3);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
double scale = 1;
|
||||
|
||||
if (input_fd == NULL) {
|
||||
@@ -905,10 +999,15 @@ int main(int argc, char **argv)
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
|
||||
/* Add phase noise if enabled */
|
||||
if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
|
||||
&((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -963,6 +1062,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//----------------- count and print errors -----------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
|
||||
ptrs_symbols = 0;
|
||||
for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){
|
||||
ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
|
||||
}
|
||||
/* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
|
||||
available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
|
||||
printf("After PTRS subtraction available_bits are : %u \n", available_bits);
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
|
||||
@@ -977,12 +1090,6 @@ int main(int argc, char **argv)
|
||||
|
||||
} // round
|
||||
|
||||
//----------------------------------------------------------
|
||||
//----------------- count and print errors -----------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
if (n_trials == 1 && errors_scrambling[0] > 0) {
|
||||
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
|
||||
}
|
||||
@@ -1044,28 +1151,29 @@ int main(int argc, char **argv)
|
||||
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
|
||||
printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
|
||||
printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
|
||||
printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
|
||||
printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
|
||||
printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
|
||||
printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
|
||||
printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
|
||||
printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
|
||||
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
|
||||
printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
|
||||
printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
|
||||
printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
|
||||
//printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
|
||||
//printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
|
||||
//printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
if(n_trials==1)
|
||||
break;
|
||||
|
||||
|
||||
if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
|
||||
printf("*************\n");
|
||||
printf("PUSCH test OK\n");
|
||||
printf("*************\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
snrRun++;
|
||||
n_errs = n_errors[0];
|
||||
} // SNR loop
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "sim.h"
|
||||
|
||||
|
||||
/* linear phase noise model */
|
||||
void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
|
||||
{
|
||||
double fd = 300;//0.01*30000
|
||||
static double i=0;
|
||||
double real, imag,x ,y;
|
||||
i++;
|
||||
real = cos(fd * 2 * M_PI * i * ts);
|
||||
imag = sin (fd * 2 * M_PI * i * ts);
|
||||
x = ((real * (double)InRe[0]) - (imag * (double)InIm[0])) ;
|
||||
y= ((real * (double)InIm[0]) + (imag * (double)InRe[0])) ;
|
||||
InRe[0]= (int16_t)(x);
|
||||
InIm[0]= (int16_t)(y);
|
||||
}
|
||||
@@ -460,6 +460,14 @@ void init_channelmod(void) ;
|
||||
double N_RB2sampling_rate(uint16_t N_RB);
|
||||
double N_RB2channel_bandwidth(uint16_t N_RB);
|
||||
|
||||
/* Linear phase noise model */
|
||||
/*!
|
||||
\brief This function produce phase noise and add to input signal
|
||||
\param ts Sampling time
|
||||
\param *Re *Im Real and Imag part of the signal
|
||||
*/
|
||||
void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
|
||||
|
||||
#include "targets/RT/USER/rfsim.h"
|
||||
|
||||
void do_DL_sig(sim_t *sim,
|
||||
|
||||
Reference in New Issue
Block a user