Initial NR PRS UE Channel estimation changes integrated to NR_PBCHSim
This commit is contained in:
@@ -194,6 +194,22 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//PRS init
|
||||||
|
ue->nr_gold_prs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||||
|
uint32_t ***prs = ue->nr_gold_prs;
|
||||||
|
AssertFatal(prs!=NULL, "NR UE init: positioning reference signal malloc failed\n");
|
||||||
|
|
||||||
|
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||||
|
prs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||||
|
AssertFatal(prs[slot]!=NULL, "NR UE init: positioning reference signal for slot %d - malloc failed\n", slot);
|
||||||
|
|
||||||
|
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||||
|
prs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
||||||
|
AssertFatal(prs[slot][symb]!=NULL, "NR UE init: positioning reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nr_gold_prs(ue);
|
||||||
|
|
||||||
/////////////////////////PUSCH DMRS init/////////////////////////
|
/////////////////////////PUSCH DMRS init/////////////////////////
|
||||||
///////////
|
///////////
|
||||||
ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||||
@@ -319,6 +335,16 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
|||||||
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
|
prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
|
||||||
pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
|
pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
|
||||||
|
|
||||||
|
// PRS channel estimates
|
||||||
|
ue->prs_ch_estimates = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
|
||||||
|
AssertFatal(ue->prs_ch_estimates!=NULL, "NR UE init: PRS channel estimates malloc failed\n");
|
||||||
|
|
||||||
|
for (i=0; i<fp->nb_antennas_rx; i++) {
|
||||||
|
ue->prs_ch_estimates[i] = (int32_t *)malloc16(2*fp->ofdm_symbol_size*NR_MAX_NUM_PRS_SYMB);
|
||||||
|
AssertFatal(ue->prs_ch_estimates[i]!=NULL, "NR UE init: PRS channel estimates malloc failed %d\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (abstraction_flag == 0) {
|
if (abstraction_flag == 0) {
|
||||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
||||||
phy_init_nr_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
|
phy_init_nr_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp );
|
||||||
|
|||||||
@@ -133,3 +133,39 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nr_gold_prs(PHY_VARS_NR_UE* ue)
|
||||||
|
{
|
||||||
|
unsigned int x1, x2;
|
||||||
|
uint16_t Nid;
|
||||||
|
|
||||||
|
fapi_nr_config_request_t *cfg = &ue->nrUE_config;
|
||||||
|
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||||
|
uint8_t reset;
|
||||||
|
uint8_t slotNum, symNum;
|
||||||
|
|
||||||
|
Nid = cfg->cell_config.phy_cell_id;
|
||||||
|
|
||||||
|
for (slotNum = 0; slotNum < fp->slots_per_frame; slotNum++) {
|
||||||
|
for (symNum = 0; symNum < fp->symbols_per_slot ; symNum++) {
|
||||||
|
reset = 1;
|
||||||
|
// initial x2 for prs as ts138.211
|
||||||
|
uint32_t c_init1, c_init2, c_init3;
|
||||||
|
uint32_t pow22=1<<22;
|
||||||
|
uint32_t pow10=1<<10;
|
||||||
|
c_init1 = pow22*ceil(Nid/1024);
|
||||||
|
c_init2 = pow10*(slotNum+symNum+1)*(2*(Nid%1024)+1);
|
||||||
|
c_init3 = Nid%1024;
|
||||||
|
x2 = c_init1 + c_init2 + c_init3;
|
||||||
|
|
||||||
|
|
||||||
|
for (uint8_t n=0; n<NR_MAX_PRS_INIT_LENGTH_DWORD; n++) {
|
||||||
|
ue->nr_gold_prs[slotNum][symNum][n] = lte_gold_generic(&x1, &x2, reset);
|
||||||
|
reset = 0;
|
||||||
|
//printf("%d \n",gNB->nr_gold_prs[slotNum][symNum][n]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,4 +67,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
|||||||
uint16_t *N_n_scid,
|
uint16_t *N_n_scid,
|
||||||
uint8_t n_scid);
|
uint8_t n_scid);
|
||||||
|
|
||||||
|
void nr_gold_prs(PHY_VARS_NR_UE* ue);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
|
|
||||||
//#define DEBUG_PRS_MOD
|
#define DEBUG_PRS_MOD
|
||||||
#define DEBUG_PRS_MAP
|
#define DEBUG_PRS_MAP
|
||||||
|
|
||||||
extern short nr_qpsk_mod_table[8];
|
extern short nr_qpsk_mod_table[8];
|
||||||
@@ -65,7 +65,7 @@ printf("m %d idx %d gold seq %d mod_prs %d %d\n", m, idx, nr_gold_prs[l][(m<<1)>
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_PRS_MAP
|
#ifdef DEBUG_PRS_MAP
|
||||||
printf("m %d at k %d of l %d\n", m, k, l);
|
printf("m %d at k %d of l %d reIdx %d\n", m, k, l, (l*frame_parms->ofdm_symbol_size + k)<<1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_prs[m<<1]) >> 15;
|
((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * mod_prs[m<<1]) >> 15;
|
||||||
|
|||||||
@@ -28,11 +28,154 @@
|
|||||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||||
|
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||||
#include "filt16a_32.h"
|
#include "filt16a_32.h"
|
||||||
|
|
||||||
//#define DEBUG_PDSCH
|
//#define DEBUG_PDSCH
|
||||||
//#define DEBUG_PDCCH
|
//#define DEBUG_PDCCH
|
||||||
|
//#define DEBUG_CH
|
||||||
|
#define DEBUG_PRS_CHEST
|
||||||
|
extern short nr_qpsk_mod_table[8];
|
||||||
|
|
||||||
|
int nr_prs_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||||
|
UE_nr_rxtx_proc_t *proc,
|
||||||
|
NR_DL_FRAME_PARMS *frame_params)
|
||||||
|
{
|
||||||
|
// Get K_Prime from the table for the length of PRS or LPRS
|
||||||
|
int k_prime_table[4][12] = {
|
||||||
|
{0,1,0,1,0,1,0,1,0,1,0,1},
|
||||||
|
{0,2,1,3,0,2,1,3,0,2,1,3},
|
||||||
|
{0,3,1,4,2,5,0,3,1,4,2,5},
|
||||||
|
{0,6,3,9,1,7,4,10,2,8,5,11}};
|
||||||
|
|
||||||
|
int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||||
|
uint32_t **nr_gold_prs = ue->nr_gold_prs[proc->nr_slot_rx];
|
||||||
|
prs_data_t *prs_cfg = &ue->prs_cfg;
|
||||||
|
|
||||||
|
int16_t *prs_chest, ch[2] = {0}, *rxF, *pil, *fl,*fm,*fr, mod_prs[NR_MAX_PRS_LENGTH<<1];
|
||||||
|
int16_t k_prime = 0, k = 0;
|
||||||
|
uint8_t idx = prs_cfg->NPRSID;
|
||||||
|
uint8_t rxAnt = 0; // ant 0 rxdataF for now
|
||||||
|
|
||||||
|
printf("Inside nr_prs_channel_estimation proc->thread_id %d, proc->nr_slot_rx %d\n", proc->thread_id, proc->nr_slot_rx);
|
||||||
|
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
|
||||||
|
{
|
||||||
|
int symInd = l-prs_cfg->SymbolStart;
|
||||||
|
if (prs_cfg->CombSize == 2) {
|
||||||
|
k_prime = k_prime_table[0][symInd];
|
||||||
|
}
|
||||||
|
else if (prs_cfg->CombSize == 4){
|
||||||
|
k_prime = k_prime_table[1][symInd];
|
||||||
|
}
|
||||||
|
else if (prs_cfg->CombSize == 6){
|
||||||
|
k_prime = k_prime_table[2][symInd];
|
||||||
|
}
|
||||||
|
else if (prs_cfg->CombSize == 12){
|
||||||
|
k_prime = k_prime_table[3][symInd];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("PRS config l %d k_prime %d:\nprs_cfg->SymbolStart %d\nprs_cfg->NumPRSSymbols %d\nprs_cfg->NumRB %d\nprs_cfg->CombSize %d\n", l, k_prime, prs_cfg->SymbolStart, prs_cfg->NumPRSSymbols, prs_cfg->NumRB, prs_cfg->CombSize);
|
||||||
|
//TODO currently supported only comb_size 2 and 4
|
||||||
|
switch (k_prime) {
|
||||||
|
case 0:
|
||||||
|
fl = filt16a_l0;
|
||||||
|
fm = filt16a_m0;
|
||||||
|
fr = filt16a_r0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
fl = filt16a_l1;
|
||||||
|
fm = filt16a_m1;
|
||||||
|
fr = filt16a_r1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
fl = filt16a_l2;
|
||||||
|
fm = filt16a_m2;
|
||||||
|
fr = filt16a_r2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
fl = filt16a_l3;
|
||||||
|
fm = filt16a_m3;
|
||||||
|
fr = filt16a_r3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("nr=prs channel_estimation: k_prime=%d -> ERROR\n",k_prime);
|
||||||
|
return(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//re_offset
|
||||||
|
k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + frame_params->first_carrier_offset;
|
||||||
|
|
||||||
|
// Pilots generation and modulation
|
||||||
|
for (int m = 0; m < (12/prs_cfg->CombSize)*prs_cfg->NumRB; m++)
|
||||||
|
{
|
||||||
|
idx = (((nr_gold_prs[l][(m<<1)>>5])>>((m<<1)&0x1f))&3);
|
||||||
|
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
|
||||||
|
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
pil = (int16_t *)&mod_prs[0];
|
||||||
|
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
|
||||||
|
prs_chest = (int16_t *)&ue->prs_ch_estimates[rxAnt][l*frame_params->ofdm_symbol_size];
|
||||||
|
memset(prs_chest,0,4*(ue->frame_parms.ofdm_symbol_size));
|
||||||
|
for(int pIdx = 0; pIdx < prs_cfg->NumRB*(12/prs_cfg->CombSize); pIdx+=3)
|
||||||
|
{
|
||||||
|
//pilot 0
|
||||||
|
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
|
||||||
|
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
|
||||||
|
|
||||||
|
#ifdef DEBUG_PRS_CHEST
|
||||||
|
printf("pilIdx %d at k %d of l %d reIdx %d rxF %d %d ch[0] %d ch[1] %d\n", pIdx, k, l, (l*frame_params->ofdm_symbol_size + k), rxF[0], rxF[1], ch[0], ch[1]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
multadd_real_vector_complex_scalar(fl,
|
||||||
|
ch,
|
||||||
|
prs_chest,
|
||||||
|
16);
|
||||||
|
|
||||||
|
pil +=2;
|
||||||
|
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
|
||||||
|
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
|
||||||
|
|
||||||
|
//pilot 1
|
||||||
|
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
|
||||||
|
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
|
||||||
|
|
||||||
|
multadd_real_vector_complex_scalar(fm,
|
||||||
|
ch,
|
||||||
|
prs_chest,
|
||||||
|
16);
|
||||||
|
|
||||||
|
pil +=2;
|
||||||
|
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
|
||||||
|
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
|
||||||
|
|
||||||
|
//pilot 2
|
||||||
|
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
|
||||||
|
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
|
||||||
|
|
||||||
|
multadd_real_vector_complex_scalar(fr,
|
||||||
|
ch,
|
||||||
|
prs_chest,
|
||||||
|
16);
|
||||||
|
|
||||||
|
pil +=2;
|
||||||
|
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
|
||||||
|
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
|
||||||
|
for (int re = 0; re < 12; re++)
|
||||||
|
printf("prs_ch[%d] %d %d\n", re, prs_chest[re<<1], prs_chest[(re<<1)+1]);
|
||||||
|
|
||||||
|
prs_chest +=24;
|
||||||
|
} //for m
|
||||||
|
} //for l
|
||||||
|
|
||||||
|
LOG_M("prsEst.m","prs_chest",&ue->prs_ch_estimates[rxAnt][prs_cfg->SymbolStart*frame_params->ofdm_symbol_size], prs_cfg->NumRB*12,1,1 );
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
@@ -395,6 +538,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
ch,
|
ch,
|
||||||
dl_ch,
|
dl_ch,
|
||||||
16);
|
16);
|
||||||
|
#ifdef DEBUG_CH
|
||||||
|
for (int re = 0; re < 12; re++)
|
||||||
|
printf("dl_ch[%d] %d %d\n", re, dl_ch[re<<1], dl_ch[(re<<1)+1]);
|
||||||
|
#endif
|
||||||
pil += 2;
|
pil += 2;
|
||||||
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
|
||||||
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
|
||||||
@@ -485,8 +632,8 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_PDCCH
|
#ifdef DEBUG_PDCCH
|
||||||
printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,
|
printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n",
|
||||||
ue->frame_parms.Ncp,Ns,k, symbol);
|
proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fl = filt16a_l1;
|
fl = filt16a_l1;
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
/*!\brief Timing drift hysterisis in samples*/
|
/*!\brief Timing drift hysterisis in samples*/
|
||||||
#define SYNCH_HYST 2
|
#define SYNCH_HYST 2
|
||||||
|
|
||||||
|
/* A function to perform the channel estimation of DL PRS signal */
|
||||||
|
int nr_prs_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||||
|
UE_nr_rxtx_proc_t *proc,
|
||||||
|
NR_DL_FRAME_PARMS *frame_params);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief This function performs channel estimation including frequency and temporal interpolation
|
\brief This function performs channel estimation including frequency and temporal interpolation
|
||||||
\param ue Pointer to UE PHY variables
|
\param ue Pointer to UE PHY variables
|
||||||
|
|||||||
+2
-17
@@ -48,6 +48,7 @@
|
|||||||
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
|
||||||
#define MAX_PUCCH0_NID 8
|
#define MAX_PUCCH0_NID 8
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int nb_id;
|
int nb_id;
|
||||||
int Nid[MAX_PUCCH0_NID];
|
int Nid[MAX_PUCCH0_NID];
|
||||||
@@ -779,6 +780,7 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
|
NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX];
|
||||||
NR_gNB_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX];
|
NR_gNB_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX];
|
||||||
t_nrPolar_params *uci_polarParams;
|
t_nrPolar_params *uci_polarParams;
|
||||||
|
prs_data_t prs_cfg;
|
||||||
|
|
||||||
uint8_t pbch_configured;
|
uint8_t pbch_configured;
|
||||||
char gNB_generate_rar;
|
char gNB_generate_rar;
|
||||||
@@ -949,23 +951,6 @@ typedef struct processingData_L1 {
|
|||||||
PHY_VARS_gNB *gNB;
|
PHY_VARS_gNB *gNB;
|
||||||
} processingData_L1_t;
|
} processingData_L1_t;
|
||||||
|
|
||||||
// structures prototype
|
|
||||||
typedef struct prs {
|
|
||||||
int PRSResourceSetPeriod[2]; //[slot period, slot offset]
|
|
||||||
int PRSResourceOffset; // array if more than one resource sets.slot offset (0...511) (default 0)
|
|
||||||
int PRSResourceRepetition;// slot offset (1 (default), 2, 4, 6, 8, 16, 32)
|
|
||||||
int PRSResourceTimeGap; // slot offset (1 (default), 2, 4, 6, 8, 16, 32)
|
|
||||||
int NumRB; //number of RBs in freq domain a scalar =< 275 RB
|
|
||||||
int NumPRSSymbols; //number of PRS symbols in time domain
|
|
||||||
int SymbolStart; //starting OFDM symbol of PRS resource in time domain
|
|
||||||
int RBOffset; //Starting PRB index of all PRS resources in a PRS resource set.
|
|
||||||
int CombSize; //RE density of all PRS resources in a PRS resource set. i∈{2,4,6,12}
|
|
||||||
int REOffset; //Starting RE offset in the first OFDM symbol of each PRS resource in a PRS resource set.
|
|
||||||
int MutingPattern1[2]; //Muting bit pattern option-1, specified as [] or a binary-valued vector of length 2, 4, 6, 8, 16, or 32.
|
|
||||||
int MutingPattern2[2];
|
|
||||||
int MutingBitRepetition;
|
|
||||||
int NPRSID;
|
|
||||||
} prs_data_t;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -823,7 +823,8 @@ typedef struct {
|
|||||||
NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_gNB_MAX];
|
NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_gNB_MAX];
|
NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
NR_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_gNB_MAX];
|
NR_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||||
|
prs_data_t prs_cfg;
|
||||||
|
|
||||||
//Paging parameters
|
//Paging parameters
|
||||||
uint32_t IMSImod1024;
|
uint32_t IMSImod1024;
|
||||||
uint32_t PF;
|
uint32_t PF;
|
||||||
@@ -845,6 +846,7 @@ typedef struct {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int32_t **prs_ch_estimates;
|
||||||
|
|
||||||
/// PBCH DMRS sequence
|
/// PBCH DMRS sequence
|
||||||
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
||||||
@@ -864,6 +866,9 @@ typedef struct {
|
|||||||
/// PUSCH DMRS sequence
|
/// PUSCH DMRS sequence
|
||||||
uint32_t ****nr_gold_pusch_dmrs;
|
uint32_t ****nr_gold_pusch_dmrs;
|
||||||
|
|
||||||
|
// PRS sequence
|
||||||
|
uint32_t ***nr_gold_prs;
|
||||||
|
|
||||||
uint32_t X_u[64][839];
|
uint32_t X_u[64][839];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,7 @@
|
|||||||
|
|
||||||
#define NR_MAX_PRS_LENGTH 3264 //272*6(max allocation per RB)*2(QPSK)
|
#define NR_MAX_PRS_LENGTH 3264 //272*6(max allocation per RB)*2(QPSK)
|
||||||
#define NR_MAX_PRS_INIT_LENGTH_DWORD 102 // ceil(NR_MAX_CSI_RS_LENGTH/32)
|
#define NR_MAX_PRS_INIT_LENGTH_DWORD 102 // ceil(NR_MAX_CSI_RS_LENGTH/32)
|
||||||
|
#define NR_MAX_NUM_PRS_SYMB 12
|
||||||
|
|
||||||
#define NR_MAX_PUSCH_DMRS_LENGTH NR_MAX_PDSCH_DMRS_LENGTH
|
#define NR_MAX_PUSCH_DMRS_LENGTH NR_MAX_PDSCH_DMRS_LENGTH
|
||||||
#define NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD
|
#define NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD
|
||||||
@@ -372,7 +373,23 @@ struct NR_DL_FRAME_PARMS {
|
|||||||
uint32_t ofdm_offset_divisor;
|
uint32_t ofdm_offset_divisor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PRS structures prototype
|
||||||
|
typedef struct prs {
|
||||||
|
int PRSResourceSetPeriod[2]; //[slot period, slot offset]
|
||||||
|
int PRSResourceOffset; // array if more than one resource sets.slot offset (0...511) (default 0)
|
||||||
|
int PRSResourceRepetition;// slot offset (1 (default), 2, 4, 6, 8, 16, 32)
|
||||||
|
int PRSResourceTimeGap; // slot offset (1 (default), 2, 4, 6, 8, 16, 32)
|
||||||
|
int NumRB; //number of RBs in freq domain a scalar =< 275 RB
|
||||||
|
int NumPRSSymbols; //number of PRS symbols in time domain
|
||||||
|
int SymbolStart; //starting OFDM symbol of PRS resource in time domain
|
||||||
|
int RBOffset; //Starting PRB index of all PRS resources in a PRS resource set.
|
||||||
|
int CombSize; //RE density of all PRS resources in a PRS resource set. i∈{2,4,6,12}
|
||||||
|
int REOffset; //Starting RE offset in the first OFDM symbol of each PRS resource in a PRS resource set.
|
||||||
|
int MutingPattern1[2]; //Muting bit pattern option-1, specified as [] or a binary-valued vector of length 2, 4, 6, 8, 16, or 32.
|
||||||
|
int MutingPattern2[2];
|
||||||
|
int MutingBitRepetition;
|
||||||
|
int NPRSID;
|
||||||
|
} prs_data_t;
|
||||||
|
|
||||||
#define KHz (1000UL)
|
#define KHz (1000UL)
|
||||||
#define MHz (1000*KHz)
|
#define MHz (1000*KHz)
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_
|
|||||||
prs_data.NumPRSSymbols=6;
|
prs_data.NumPRSSymbols=6;
|
||||||
prs_data.NumRB=273;
|
prs_data.NumRB=273;
|
||||||
prs_data.RBOffset=0;
|
prs_data.RBOffset=0;
|
||||||
prs_data.CombSize=6;
|
prs_data.CombSize=4;
|
||||||
prs_data.REOffset=0;
|
prs_data.REOffset=0;
|
||||||
prs_data.PRSResourceOffset=0;
|
prs_data.PRSResourceOffset=0;
|
||||||
prs_data.PRSResourceRepetition=1;
|
prs_data.PRSResourceRepetition=1;
|
||||||
@@ -239,7 +239,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
|||||||
prs_data.NumPRSSymbols=6;
|
prs_data.NumPRSSymbols=6;
|
||||||
prs_data.NumRB=273;
|
prs_data.NumRB=273;
|
||||||
prs_data.RBOffset=0;
|
prs_data.RBOffset=0;
|
||||||
prs_data.CombSize=6;
|
prs_data.CombSize=4;
|
||||||
prs_data.REOffset=0;
|
prs_data.REOffset=0;
|
||||||
prs_data.PRSResourceOffset=0;
|
prs_data.PRSResourceOffset=0;
|
||||||
prs_data.PRSResourceRepetition=1;
|
prs_data.PRSResourceRepetition=1;
|
||||||
|
|||||||
@@ -1716,6 +1716,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
|||||||
#if UE_TIMING_TRACE
|
#if UE_TIMING_TRACE
|
||||||
stop_meas(&ue->dlsch_channel_estimation_stats);
|
stop_meas(&ue->dlsch_channel_estimation_stats);
|
||||||
#endif
|
#endif
|
||||||
|
//PRS channel estimation
|
||||||
|
nr_prs_channel_estimation(ue,proc,fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_ue_rsrp_measurements(ue, gNB_id, proc, nr_slot_rx, 0);
|
nr_ue_rsrp_measurements(ue, gNB_id, proc, nr_slot_rx, 0);
|
||||||
|
|||||||
@@ -722,16 +722,35 @@ int main(int argc, char **argv)
|
|||||||
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
|
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
|
||||||
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
|
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
|
||||||
|
|
||||||
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
|
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
|
||||||
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
|
|
||||||
|
for(int j = 0; j < frame_parms->symbols_per_slot; j++)
|
||||||
|
{
|
||||||
nr_slot_fep(UE,
|
nr_slot_fep(UE,
|
||||||
&proc,
|
&proc,
|
||||||
i%frame_parms->symbols_per_slot,
|
j%frame_parms->symbols_per_slot,
|
||||||
ssb_slot);
|
ssb_slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
|
||||||
nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
|
nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
UE->prs_cfg.PRSResourceSetPeriod[0]=40; // PRS resource slot period
|
||||||
|
UE->prs_cfg.PRSResourceSetPeriod[1]=0; // resource slot offset
|
||||||
|
UE->prs_cfg.SymbolStart=7;
|
||||||
|
UE->prs_cfg.NumPRSSymbols=6;
|
||||||
|
UE->prs_cfg.NumRB=273;
|
||||||
|
UE->prs_cfg.RBOffset=0;
|
||||||
|
UE->prs_cfg.CombSize=4;
|
||||||
|
UE->prs_cfg.REOffset=0;
|
||||||
|
UE->prs_cfg.PRSResourceOffset=0;
|
||||||
|
UE->prs_cfg.PRSResourceRepetition=1;
|
||||||
|
UE->prs_cfg.PRSResourceTimeGap=1;
|
||||||
|
UE->prs_cfg.NPRSID=0;
|
||||||
|
|
||||||
|
//PRS channel estimation
|
||||||
|
nr_prs_channel_estimation(UE,&proc,frame_parms);
|
||||||
|
|
||||||
ret = nr_rx_pbch(UE,
|
ret = nr_rx_pbch(UE,
|
||||||
&proc,
|
&proc,
|
||||||
|
|||||||
Reference in New Issue
Block a user