Commit 6fc41679 authored by Sagar Parsawar's avatar Sagar Parsawar

Initial NR PRS UE Channel estimation changes integrated to NR_PBCHSim

parent 800a8268
......@@ -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/////////////////////////
///////////
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));
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) {
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 );
......
......@@ -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,
uint8_t n_scid);
void nr_gold_prs(PHY_VARS_NR_UE* ue);
#endif
......@@ -4,7 +4,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/sse_intrin.h"
//#define DEBUG_PRS_MOD
#define DEBUG_PRS_MOD
#define DEBUG_PRS_MAP
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
#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
((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/ptrs_nr.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "filt16a_32.h"
//#define DEBUG_PDSCH
//#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,
UE_nr_rxtx_proc_t *proc,
......@@ -395,6 +538,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
ch,
dl_ch,
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;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
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
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,
ue->frame_parms.Ncp,Ns,k, symbol);
printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n",
proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size,ue->frame_parms.Ncp,Ns,symbol);
#endif
fl = filt16a_l1;
......
......@@ -32,6 +32,11 @@
/*!\brief Timing drift hysterisis in samples*/
#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
\param ue Pointer to UE PHY variables
......
......@@ -48,6 +48,7 @@
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#define MAX_PUCCH0_NID 8
typedef struct {
int nb_id;
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_UCI_STATS_t uci_stats[NUMBER_OF_NR_UCI_STATS_MAX];
t_nrPolar_params *uci_polarParams;
prs_data_t prs_cfg;
uint8_t pbch_configured;
char gNB_generate_rar;
......@@ -949,23 +951,6 @@ typedef struct processingData_L1 {
PHY_VARS_gNB *gNB;
} 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
......@@ -823,7 +823,8 @@ typedef struct {
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_MCH[NUMBER_OF_CONNECTED_gNB_MAX];
prs_data_t prs_cfg;
//Paging parameters
uint32_t IMSImod1024;
uint32_t PF;
......@@ -845,6 +846,7 @@ typedef struct {
#endif
int32_t **prs_ch_estimates;
/// PBCH DMRS sequence
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
......@@ -864,6 +866,9 @@ typedef struct {
/// PUSCH DMRS sequence
uint32_t ****nr_gold_pusch_dmrs;
// PRS sequence
uint32_t ***nr_gold_prs;
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_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_INIT_LENGTH_DWORD NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD
......@@ -372,7 +373,23 @@ struct NR_DL_FRAME_PARMS {
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 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.NumRB=273;
prs_data.RBOffset=0;
prs_data.CombSize=6;
prs_data.CombSize=4;
prs_data.REOffset=0;
prs_data.PRSResourceOffset=0;
prs_data.PRSResourceRepetition=1;
......@@ -239,7 +239,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
prs_data.NumPRSSymbols=6;
prs_data.NumRB=273;
prs_data.RBOffset=0;
prs_data.CombSize=6;
prs_data.CombSize=4;
prs_data.REOffset=0;
prs_data.PRSResourceOffset=0;
prs_data.PRSResourceRepetition=1;
......
......@@ -1716,6 +1716,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
#if UE_TIMING_TRACE
stop_meas(&ue->dlsch_channel_estimation_stats);
#endif
//PRS channel estimation
nr_prs_channel_estimation(ue,proc,fp);
}
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
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));
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
for(int j = 0; j < frame_parms->symbols_per_slot; j++)
{
nr_slot_fep(UE,
&proc,
i%frame_parms->symbols_per_slot,
j%frame_parms->symbols_per_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);
}
}
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,
&proc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment