Commit 327ba9d3 authored by Parminder Singh's avatar Parminder Singh

PTRS DL extraction, estimation and compensation

- Added PTRS extraction and estimation for DL
- Added processing for whole slot wrt PTRS estimates
- DLSIM is updated to used -T flag to enable PTRS
- DMRS compensated signal is further compensated with PTRS estimation
parent 42e9c655
...@@ -604,6 +604,9 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, ...@@ -604,6 +604,9 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
//pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
// the allocated memory size is fixed: // the allocated memory size is fixed:
AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" );
...@@ -624,6 +627,9 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, ...@@ -624,6 +627,9 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch,
//pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); //pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
pdsch->ptrs_re_per_slot[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * 14);
pdsch->ptrs_phase_per_slot[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 );
pdsch->dl_ch_ptrs_estimates_ext[idx]= (int32_t *)malloc16_clear( sizeof(int32_t) * num);
} }
} }
} }
......
This diff is collapsed.
...@@ -80,6 +80,31 @@ uint8_t is_ptrs_subcarrier(uint16_t k, ...@@ -80,6 +80,31 @@ uint8_t is_ptrs_subcarrier(uint16_t k,
static inline uint8_t is_ptrs_symbol(uint8_t l, uint16_t ptrs_symbols) { return ((ptrs_symbols >> l) & 1); } static inline uint8_t is_ptrs_symbol(uint8_t l, uint16_t ptrs_symbols) { return ((ptrs_symbols >> l) & 1); }
uint8_t get_ptrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t start_symb, uint16_t nb_symb);
uint8_t get_next_ptrs_symbol_in_slot(uint16_t ptrsSymbPos, uint8_t counter, uint8_t nb_symb);
uint8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb);
void get_slope_from_estimates(uint8_t leftSide, uint8_t rightSide, int16_t *est_p, int16_t *slope_p);
int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos,
uint16_t ptrsSymbPos,
int16_t *estPerSymb,
uint16_t startSymbIdx,
uint16_t noSymb
);
/* general function to estimate common phase error based upon PTRS */
void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
uint8_t ptrsReOffset,
uint8_t dmrsConfigType,
uint16_t nb_rb,
uint16_t rnti,
int16_t *ptrs_ch_p,
unsigned char Ns,
unsigned char symbol,
uint16_t ofdm_symbol_size,
int16_t *rxF_comp,
uint32_t *gold_seq,
int16_t *error_est,
int32_t *ptrs_sc);
void get_slope_from_estimates(uint8_t start, uint8_t end, int16_t *est_p, int16_t *slope_p);
void ptrs_estimate_from_slope(int16_t *error_est, int16_t *slope_p, uint8_t start, uint8_t end);
#endif /* PTRS_NR_H */ #endif /* PTRS_NR_H */
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/defs.h"
#include "nr_estimation.h" #include "nr_estimation.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/NR_REFSIG/ptrs_nr.h"
#include "filt16a_32.h" #include "filt16a_32.h"
//#define DEBUG_PDSCH //#define DEBUG_PDSCH
...@@ -937,3 +939,171 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -937,3 +939,171 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
return(0); return(0);
} }
/*******************************************************************
*
* NAME : nr_pdsch_ptrs_processing
*
* PARAMETERS : ue : ue data structure
* NR_UE_PDSCH : pdsch_vars pointer
* NR_DL_FRAME_PARMS : frame_parms pointer
* NR_DL_UE_HARQ_t : dlsch0_harq pointer
* NR_DL_UE_HARQ_t : dlsch1_harq pointer
* uint8_t : eNB_id,
* uint8_t : nr_tti_rx,
* unsigned char : symbol,
* uint32_t : nb_re_pdsch,
* unsigned char : harq_pid
* uint16_t : rnti
* RX_type_t : rx_type
* RETURN : Nothing
*
* DESCRIPTION :
* If ptrs is enabled process the symbol accordingly
* 1) Estimate common phase error per PTRS symbol
* 2) Interpolate PTRS estimated value in TD after all PTRS symbols
* 3) Compensate signal with PTRS estimation for slot
*********************************************************************/
void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH **pdsch_vars,
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
uint8_t eNB_id,
uint8_t nr_tti_rx,
unsigned char symbol,
uint32_t nb_re_pdsch,
unsigned char harq_pid,
uint16_t rnti,
RX_type_t rx_type)
{
//#define DEBUG_DL_PTRS 1
int16_t *phase_per_symbol = NULL;
int32_t *ptrs_re_symbol = NULL;
int8_t ret = 0;
/* harq specific variables */
uint8_t symbInSlot = 0;
uint16_t *startSymbIndex = NULL;
uint16_t *nbSymb = NULL;
uint8_t *L_ptrs = NULL;
uint8_t *K_ptrs = NULL;
uint16_t *dmrsSymbPos = NULL;
uint16_t *ptrsSymbPos = NULL;
uint8_t *ptrsSymbIdx = NULL;
uint8_t *ptrsReOffset = NULL;
uint8_t *dmrsConfigType = NULL;
uint16_t *nb_rb = NULL;
if(dlsch0_harq->status == ACTIVE)
{
symbInSlot = dlsch0_harq->start_symbol + dlsch0_harq->nb_symbols;
startSymbIndex = &dlsch0_harq->start_symbol;
nbSymb = &dlsch0_harq->nb_symbols;
L_ptrs = &dlsch0_harq->PTRSTimeDensity;
K_ptrs = &dlsch0_harq->PTRSFreqDensity;
dmrsSymbPos = &dlsch0_harq->dlDmrsSymbPos;
ptrsSymbPos = &dlsch0_harq->ptrs_symbols;
ptrsSymbIdx = &dlsch0_harq->ptrs_symbol_index;
ptrsReOffset = &dlsch0_harq->PTRSReOffset;
dmrsConfigType = &dlsch0_harq->ptrs_symbol_index;
nb_rb = &dlsch0_harq->nb_rb;
}
if(dlsch1_harq)
{
symbInSlot = dlsch1_harq->start_symbol + dlsch0_harq->nb_symbols;
startSymbIndex = &dlsch1_harq->start_symbol;
nbSymb = &dlsch1_harq->nb_symbols;
L_ptrs = &dlsch1_harq->PTRSTimeDensity;
K_ptrs = &dlsch1_harq->PTRSFreqDensity;
dmrsSymbPos = &dlsch1_harq->dlDmrsSymbPos;
ptrsSymbPos = &dlsch1_harq->ptrs_symbols;
ptrsSymbIdx = &dlsch1_harq->ptrs_symbol_index;
ptrsReOffset = &dlsch1_harq->PTRSReOffset;
dmrsConfigType = &dlsch1_harq->ptrs_symbol_index;
nb_rb = &dlsch1_harq->nb_rb;
}
/* loop over antennas */
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
{
phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx];
ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx];
ptrs_re_symbol[symbol] = 0;
phase_per_symbol[2*symbol] = 0; // Real
phase_per_symbol[(2*symbol)+1] = 0; // Imag
if(dlsch0_harq->status == ACTIVE)
{
if(symbol == *startSymbIndex)
{
*ptrsSymbPos = 0;
set_ptrs_symb_idx(ptrsSymbPos,
*nbSymb,
*startSymbIndex,
1<< *L_ptrs,
*dmrsSymbPos);
}
/* if not PTRS symbol set current ptrs symbol index to zero*/
*ptrsSymbIdx = 0;
/* Check if current symbol contains PTRS */
if(is_ptrs_symbol(symbol, *ptrsSymbPos))
{
*ptrsSymbIdx = symbol;
/*------------------------------------------------------------------------------------------------------- */
/* 1) Estimate common phase error per PTRS symbol */
/*------------------------------------------------------------------------------------------------------- */
nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
rnti,
(int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch],
nr_tti_rx,
symbol,frame_parms->ofdm_symbol_size,
(int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
ue->nr_gold_pdsch[eNB_id][nr_tti_rx][symbol],
&phase_per_symbol[2* symbol],
&ptrs_re_symbol[symbol]);
/* if very first symbol is PTRS then we need to undo conjugate done in estimation */
if(symbol == *startSymbIndex)
{
phase_per_symbol[(2* symbol)+1] = (-1) * phase_per_symbol[(2* symbol)+1];
}
}
}// HARQ 0
/* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
if(symbol == (symbInSlot -1))
{
/*------------------------------------------------------------------------------------------------------- */
/* 2) Interpolate PTRS estimated value in TD */
/*------------------------------------------------------------------------------------------------------- */
/* If L-PTRS is > 0 then we need interpolation */
if(*L_ptrs > 0)
{
ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb);
if(ret != 0)
{
LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n");
}
}
#ifdef DEBUG_DL_PTRS
LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
(*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1);
#endif
/*------------------------------------------------------------------------------------------------------- */
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
/*--------------------------------------------------------------------------------------------------------*/
for(uint8_t i = *startSymbIndex; i< symbInSlot ;i++)
{
/* DMRS Symbol has 0 phase so no need to rotate the respective symbol */
if(!is_dmrs_symbol(i,*dmrsSymbPos))
{
#ifdef DEBUG_DL_PTRS
printf("[PHY][DL][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*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
&phase_per_symbol[2* i],
(int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
((*nb_rb) * NR_NB_SC_PER_RB), 15);
}// if not DMRS Symbol
}// symbol loop
}// last symbol check
}//Antenna loop
}//main function
...@@ -93,5 +93,17 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, ...@@ -93,5 +93,17 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH **pdsch_vars,
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
uint8_t eNB_id,
uint8_t nr_tti_rx,
unsigned char symbol,
uint32_t nb_re_pdsch,
unsigned char harq_pid,
uint16_t rnti,
RX_type_t rx_type);
#endif #endif
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
//#include "extern.h" //#include "extern.h"
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
#include "T.h" #include "T.h"
#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
#ifndef USER_MODE #ifndef USER_MODE
...@@ -140,12 +141,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -140,12 +141,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
PHY_NR_MEASUREMENTS *measurements = &ue->measurements; PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
NR_UE_DLSCH_t **dlsch; NR_UE_DLSCH_t **dlsch;
uint16_t startSymbIdx=0;
uint16_t nbSymb=0;
int avg[4]; int avg[4];
// int avg_0[2]; // int avg_0[2];
// int avg_1[2]; // int avg_1[2];
#if UE_TIMING_TRACE #if UE_TIMING_TRACE
uint8_t slot = 0; uint8_t slot = 0;
...@@ -174,6 +173,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -174,6 +173,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint16_t n_tx=1, n_rx=1; uint16_t n_tx=1, n_rx=1;
int32_t median[16]; int32_t median[16];
uint32_t len; uint32_t len;
uint16_t startSymbIdx=0;
uint16_t nbSymb=0;
uint16_t pduBitmap=0x0;
switch (type) { switch (type) {
case SI_PDSCH: case SI_PDSCH:
...@@ -693,15 +695,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -693,15 +695,30 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
{ {
startSymbIdx = dlsch0_harq->start_symbol; startSymbIdx = dlsch0_harq->start_symbol;
nbSymb = dlsch0_harq->nb_symbols; nbSymb = dlsch0_harq->nb_symbols;
pduBitmap = dlsch0_harq->pduBitmap;
} }
if(dlsch1_harq) if(dlsch1_harq)
{ {
startSymbIdx = dlsch1_harq->start_symbol; startSymbIdx = dlsch1_harq->start_symbol;
nbSymb = dlsch1_harq->nb_symbols; nbSymb = dlsch1_harq->nb_symbols;
pduBitmap = dlsch1_harq->pduBitmap;
}
/* Check for PTRS bitmap and process it respectively */
if((pduBitmap & 0x1) && (type == PDSCH))
{
nr_pdsch_ptrs_processing(ue,
pdsch_vars,
frame_parms,
dlsch0_harq, dlsch1_harq,
eNB_id, nr_tti_rx,
symbol, (nb_rb*12),
harq_pid,
dlsch[0]->rnti,rx_type);
pdsch_vars[eNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[eNB_id]->ptrs_re_per_slot[0][symbol];
} }
//printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
// compute LLRs /* at last symbol in a slot calculate LLR's for whole slot */
// -> // compute @pointer where llrs should filled for this ofdm-symbol
if(symbol == (startSymbIdx + nbSymb -1)) if(symbol == (startSymbIdx + nbSymb -1))
{ {
for(uint8_t i =startSymbIdx; i <= nbSymb;i++) for(uint8_t i =startSymbIdx; i <= nbSymb;i++)
...@@ -715,27 +732,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, ...@@ -715,27 +732,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
{ {
first_symbol_flag=0; first_symbol_flag=0;
} }
/* Calculate LLR's for ech symbol */ /* Calculate LLR's for each symbol */
nr_dlsch_llr(pdsch_vars, nr_dlsch_llr(pdsch_vars, frame_parms,
frame_parms, rxdataF_comp_ptr, dl_ch_mag_ptr,
rxdataF_comp_ptr, dlsch0_harq, dlsch1_harq,
dl_ch_mag_ptr, rx_type, harq_pid,
dlsch0_harq, eNB_id, eNB_id_i,
dlsch1_harq,
rx_type,
harq_pid,
eNB_id,
eNB_id_i,
first_symbol_flag, first_symbol_flag,
i, i, nb_rb, round,
nb_rb, codeword_TB0, codeword_TB1,
round,
codeword_TB0,
codeword_TB1,
pdsch_vars[eNB_id]->dl_valid_re[i-1], pdsch_vars[eNB_id]->dl_valid_re[i-1],
nr_tti_rx, nr_tti_rx, beamforming_mode);
beamforming_mode);
} }
//nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch); //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch);
if (rx_type==rx_IC_dual_stream) { if (rx_type==rx_IC_dual_stream) {
nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr, nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr,
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
#include "openair1/SIMULATION/TOOLS/sim.h" #include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "PHY/NR_REFSIG/ptrs_nr.h"
#include "NR_RRCReconfiguration.h" #include "NR_RRCReconfiguration.h"
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h" #include "SIMULATION/LTE_PHY/common_sim.h"
...@@ -143,8 +143,7 @@ int generate_dlsch_header(unsigned char *mac_header, ...@@ -143,8 +143,7 @@ int generate_dlsch_header(unsigned char *mac_header,
// needed for some functions // needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS]; openair0_config_t openair0_cfg[MAX_CARDS];
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex, uint8_t *K_ptrs, uint8_t *L_ptrs);
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
...@@ -214,6 +213,16 @@ int main(int argc, char **argv) ...@@ -214,6 +213,16 @@ int main(int argc, char **argv)
int css_flag=0; int css_flag=0;
cpuf = get_cpu_freq_GHz(); cpuf = get_cpu_freq_GHz();
int enable_ptrs = 0;
/* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
uint8_t ptrs_arg[2] = {-1,-1};// Invalid values
uint16_t ptrsRePerSymb = 0;
uint16_t pdu_bit_map = 0x0;
uint16_t dlPtrsSymPos = 0;
uint16_t ptrsSymbPerSlot = 0;
uint16_t rbSize = 106;
uint8_t mcsIndex = 9;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
...@@ -226,7 +235,7 @@ int main(int argc, char **argv) ...@@ -226,7 +235,7 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL; FILE *scg_fd=NULL;
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w")) != -1) { while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w:T:")) != -1) {
switch (c) { switch (c) {
case 'f': case 'f':
scg_fd = fopen(optarg,"r"); scg_fd = fopen(optarg,"r");
...@@ -413,6 +422,13 @@ int main(int argc, char **argv) ...@@ -413,6 +422,13 @@ int main(int argc, char **argv)
output_fd = fopen("txdata.dat", "w+"); output_fd = fopen("txdata.dat", "w+");
break; break;
case 'T':
enable_ptrs=1;
for(i=0; i < atoi(optarg); i++){
ptrs_arg[i] = atoi(argv[optind++]);
}
break;
default: default:
case 'h': 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", 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",
...@@ -443,6 +459,7 @@ int main(int argc, char **argv) ...@@ -443,6 +459,7 @@ int main(int argc, char **argv)
printf("-j Number of symbols for PDSCH (fixed for now)\n"); printf("-j Number of symbols for PDSCH (fixed for now)\n");
printf("-e MSC index\n"); printf("-e MSC index\n");
printf("-t Acceptable effective throughput (in percentage)\n"); printf("-t Acceptable effective throughput (in percentage)\n");
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
printf("-P Print DLSCH performances\n"); printf("-P Print DLSCH performances\n");
printf("-w Write txdata to binary file (one frame)\n"); printf("-w Write txdata to binary file (one frame)\n");
exit (-1); exit (-1);
...@@ -539,7 +556,14 @@ int main(int argc, char **argv) ...@@ -539,7 +556,14 @@ int main(int argc, char **argv)
0); 0);
fix_scc(scc,ssb_bitmap); fix_scc(scc,ssb_bitmap);
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); /* -T option enable PTRS */
if(enable_ptrs)
{
printf("[DLSIM] PTRS Enabled with L %d, K %d \n", 1<<ptrs_arg[0], ptrs_arg[1] );
update_ptrs_config(secondaryCellGroup, &rbSize, &mcsIndex, &ptrs_arg[1], &ptrs_arg[0]);
}
//xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
...@@ -793,6 +817,21 @@ int main(int argc, char **argv) ...@@ -793,6 +817,21 @@ int main(int argc, char **argv)
Sched_INFO.TX_req = &gNB_mac->TX_req[0]; Sched_INFO.TX_req = &gNB_mac->TX_req[0];
nr_schedule_response(&Sched_INFO); nr_schedule_response(&Sched_INFO);
/* PTRS values for DLSIM calculations */
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[Sched_INFO.CC_id].dl_tti_request_body;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1];
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
pdu_bit_map = pdsch_pdu_rel15->pduBitmap;
if(pdu_bit_map & 0x1){
set_ptrs_symb_idx(&dlPtrsSymPos,
pdsch_pdu_rel15->NrOfSymbols,
pdsch_pdu_rel15->StartSymbolIndex,
1<<pdsch_pdu_rel15->PTRSTimeDensity,
pdsch_pdu_rel15->dlDmrsSymbPos);
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, pdsch_pdu_rel15->StartSymbolIndex, pdsch_pdu_rel15->NrOfSymbols);
ptrsRePerSymb = ((rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity);
printf("[DLSIM] PTRS Symbols in a slot: %2d, RE per Symbol: %3d, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
}
if (run_initial_sync) if (run_initial_sync)
nr_common_signal_procedures(gNB,frame,slot); nr_common_signal_procedures(gNB,frame,slot);
else else
...@@ -876,7 +915,7 @@ int main(int argc, char **argv) ...@@ -876,7 +915,7 @@ int main(int argc, char **argv)
r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
} }
} }
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
//AWGN //AWGN
sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
sigma2 = pow(10, sigma2_dB/10); sigma2 = pow(10, sigma2_dB/10);
...@@ -889,6 +928,12 @@ int main(int argc, char **argv) ...@@ -889,6 +928,12 @@ int main(int argc, char **argv)
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
/* Add phase noise if enabled */
if (pdu_bit_map & 0x1)
{
phase_noise(ts, &((short*) UE->common_vars.rxdata[aa])[2*i],
&((short*) UE->common_vars.rxdata[aa])[2*i+1]);
}
} }
} }
...@@ -923,6 +968,11 @@ int main(int argc, char **argv) ...@@ -923,6 +968,11 @@ int main(int argc, char **argv)
uint8_t nb_symb_sch = rel15->NrOfSymbols; uint8_t nb_symb_sch = rel15->NrOfSymbols;
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, rel15->nrOfLayers);
if(pdu_bit_map & 0x1)
{
available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2);
printf("[DLSIM][PTRS] Available bits are: %5d, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
}
for (i = 0; i < available_bits; i++) { for (i = 0; i < available_bits; i++) {
...@@ -1084,3 +1134,57 @@ int main(int argc, char **argv) ...@@ -1084,3 +1134,57 @@ int main(int argc, char **argv)
return(n_errors); return(n_errors);
} }
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex, uint8_t *K_ptrs, uint8_t *L_ptrs)
{
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
int *ptrsFreqDenst = calloc(2, sizeof(long));
ptrsFreqDenst[0]= 25;
ptrsFreqDenst[1]= 115;
int *ptrsTimeDenst = calloc(3, sizeof(long));
ptrsTimeDenst[0]= 2;
ptrsTimeDenst[1]= 4;
ptrsTimeDenst[2]= 10;
int epre_Ratio = 0;
int reOffset = 0;
if(*L_ptrs ==0)
{
ptrsTimeDenst[2]= *mcsIndex -1;
}
else if(*L_ptrs == 1)
{
ptrsTimeDenst[1]= *mcsIndex - 1;
ptrsTimeDenst[2]= *mcsIndex + 1;
}
else if(*L_ptrs ==2)
{
ptrsTimeDenst[0]= *mcsIndex - 1;
ptrsTimeDenst[1]= *mcsIndex + 1;
}
else
{
printf("[DLSIM] Wrong L_PTRS value, using default values 1\n");
}
/* L = 4 if Imcs < MCS4 */
if(*K_ptrs ==2)
{
ptrsFreqDenst[0]= *rbSize - 1;
ptrsFreqDenst[1]= *rbSize + 1;
}
else if(*K_ptrs == 4)
{
ptrsFreqDenst[1]= *rbSize - 1;
}
else
{
printf("[DLSIM] Wrong K_PTRS value, using default values 2\n");
}
/* overwrite the values */
rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset);
}
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