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
This commit is contained in:
@@ -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_mag0 = (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:
|
||||
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,
|
||||
//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_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <stdio.h>
|
||||
#include "dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
@@ -180,93 +180,265 @@ uint8_t is_ptrs_subcarrier(uint16_t k,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int main(int argc, char const *argv[])
|
||||
/* return the total number of ptrs symbol in a slot */
|
||||
uint8_t get_ptrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t start_symb, uint16_t nb_symb)
|
||||
{
|
||||
|
||||
dmrs_UplinkConfig_t dmrs_Uplink_Config;
|
||||
ptrs_UplinkConfig_t ptrs_Uplink_Config;
|
||||
uint8_t resourceElementOffset;
|
||||
uint8_t dmrs_antenna_port;
|
||||
uint8_t L_ptrs, K_ptrs;
|
||||
int16_t k_RE_ref;
|
||||
uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k;
|
||||
uint8_t duration_in_symbols, I_mcs;
|
||||
uint8_t start_symbol, l;
|
||||
uint8_t ptrs_symbol_flag;
|
||||
uint16_t n_rnti;
|
||||
|
||||
dmrs_Uplink_Config.pusch_dmrs_type = pusch_dmrs_type1;
|
||||
dmrs_Uplink_Config.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos1;
|
||||
dmrs_Uplink_Config.pusch_maxLength = pusch_len2;
|
||||
|
||||
ptrs_Uplink_Config.timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration
|
||||
ptrs_Uplink_Config.timeDensity.ptrs_mcs2 = 0;
|
||||
ptrs_Uplink_Config.timeDensity.ptrs_mcs3 = 0;
|
||||
ptrs_Uplink_Config.frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration
|
||||
ptrs_Uplink_Config.frequencyDensity.n_rb1 = 0;
|
||||
ptrs_Uplink_Config.resourceElementOffset = 0;
|
||||
|
||||
n_rnti = 0x1234;
|
||||
resourceElementOffset = 0;
|
||||
ptrs_symbols = 0;
|
||||
dmrs_antenna_port = 0;
|
||||
N_RB = 50;
|
||||
duration_in_symbols = 14;
|
||||
ofdm_symbol_size = 2048;
|
||||
I_mcs = 9;
|
||||
start_symbol = 0;
|
||||
ptrs_symbol_flag = 0;
|
||||
|
||||
k_RE_ref = get_kRE_ref(dmrs_antenna_port, dmrs_Uplink_Config.pusch_dmrs_type, resourceElementOffset);
|
||||
|
||||
K_ptrs = get_K_ptrs(&ptrs_Uplink_Config, N_RB);
|
||||
|
||||
L_ptrs = get_L_ptrs(&ptrs_Uplink_Config, I_mcs);
|
||||
|
||||
set_ptrs_symb_idx(&ptrs_symbols,
|
||||
&ptrs_Uplink_Config,
|
||||
&dmrs_Uplink_Config,
|
||||
1,
|
||||
duration_in_symbols,
|
||||
start_symbol,
|
||||
L_ptrs,
|
||||
ofdm_symbol_size);
|
||||
|
||||
printf("PTRS OFDM symbol indicies: ");
|
||||
|
||||
for (l = start_symbol; l < start_symbol + duration_in_symbols; l++){
|
||||
|
||||
ptrs_symbol_flag = is_ptrs_symbol(l,
|
||||
0,
|
||||
n_rnti,
|
||||
N_RB,
|
||||
duration_in_symbols,
|
||||
dmrs_antenna_port,
|
||||
K_ptrs,
|
||||
ptrs_symbols,
|
||||
dmrs_Uplink_Config.pusch_dmrs_type,
|
||||
&ptrs_Uplink_Config);
|
||||
|
||||
if (ptrs_symbol_flag == 1)
|
||||
printf(" %d ", l);
|
||||
|
||||
uint8_t tmp = 0;
|
||||
for (int i = start_symb; i <= nb_symb; i++)
|
||||
{
|
||||
tmp += (l_prime_mask >> i) & 0x01;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("PTRS subcarrier indicies: ");
|
||||
|
||||
for (k = 0; k < N_RB*12; k++){
|
||||
|
||||
if (is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref) == 1)
|
||||
printf(" %d ", k);
|
||||
|
||||
/* return the position of next ptrs symbol in a slot */
|
||||
uint8_t get_next_ptrs_symbol_in_slot(uint16_t ptrs_symb_pos, uint8_t counter, uint8_t nb_symb)
|
||||
{
|
||||
for(uint8_t symbol = counter; symbol < nb_symb; symbol++)
|
||||
{
|
||||
if((ptrs_symb_pos >>symbol)&0x01 )
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/* get the next nearest estimate from DMRS or PTRS */
|
||||
uint8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb)
|
||||
{
|
||||
uint8_t nextPtrs = get_next_ptrs_symbol_in_slot(ptrsSymbPos, counter,nb_symb);
|
||||
uint8_t nextDmrs = get_next_dmrs_symbol_in_slot(dmrsSymbPos, counter,nb_symb);
|
||||
if(nextDmrs == 0)
|
||||
{
|
||||
return nextPtrs;
|
||||
}
|
||||
return (nextPtrs > nextDmrs)?nextDmrs:nextPtrs;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_ptrs_cpe_estimation
|
||||
*
|
||||
* PARAMETERS : K_ptrs : K value for PTRS
|
||||
* ptrsReOffset : RE offset for PTRS
|
||||
* dmrsConfigType: DMRS configuration type
|
||||
* nb_rb : No. of resource blocks
|
||||
* rnti : RNTI
|
||||
* ptrs_ch_p : pointer to ptrs channel structure
|
||||
* Ns :
|
||||
* symbol : OFDM symbol
|
||||
* ofdm_symbol_size: OFDM Symbol Size
|
||||
* rxF_comp : pointer to channel compensated signal
|
||||
* gold_seq : Gold sequence pointer
|
||||
* error_est : Estimated error output vector [Re Im]
|
||||
* ptrs_sc : Total PTRS RE in a symbol
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* perform phase estimation from regenerated PTRS SC and channel compensated
|
||||
* signal
|
||||
*********************************************************************/
|
||||
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)
|
||||
{
|
||||
//#define DEBUG_PTRS 1
|
||||
uint8_t is_ptrs_re = 0;
|
||||
uint16_t re_cnt = 0;
|
||||
uint16_t cnt = 0;
|
||||
unsigned short nb_re_pdsch = NR_NB_SC_PER_RB * nb_rb;
|
||||
uint16_t sc_per_symbol = (nb_rb + 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_PTRS
|
||||
double alpha = 0;
|
||||
#endif
|
||||
/* generate PTRS RE for the symbol */
|
||||
nr_gen_ref_conj_symbols(gold_seq,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_pdsch; re++)
|
||||
{
|
||||
is_ptrs_re = is_ptrs_subcarrier(re,
|
||||
rnti,
|
||||
0,
|
||||
dmrsConfigType,
|
||||
K_ptrs,
|
||||
nb_rb,
|
||||
ptrsReOffset,
|
||||
0,// start_re is 0 here
|
||||
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_PTRS
|
||||
alpha = atan(imag/real);
|
||||
printf("[PHY][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_PTRS
|
||||
printf("[PHY][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_ptrs_process_slot
|
||||
*
|
||||
* PARAMETERS : dmrsSymbPos DMRS symbol index mask per slot
|
||||
* ptrsSymbpos PTRS symbol index mask per slot
|
||||
* estPerSymb Estimated CPE pointer
|
||||
* startSymbIdx First symbol index in a slot
|
||||
* noSymb total number of OFDM symbols in a slot
|
||||
* RETURN : True if slot is process correctly
|
||||
* DESCRIPTION :
|
||||
* Process whole slot and interpolate or extrapolate estimation for the symbols
|
||||
* where there is neither PTRS nor DMRS configured
|
||||
*
|
||||
*********************************************************************/
|
||||
int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos,
|
||||
uint16_t ptrsSymbPos,
|
||||
int16_t *estPerSymb,
|
||||
uint16_t startSymbIdx,
|
||||
uint16_t noSymb)
|
||||
{
|
||||
int32_t slope = 0;
|
||||
int16_t *slope_p = (int16_t*)&slope;
|
||||
uint8_t symbInSlot = startSymbIdx + noSymb;
|
||||
uint8_t rightRef = 0;
|
||||
uint8_t leftRef = 0;
|
||||
uint8_t tmp = 0;
|
||||
for(uint8_t symb = startSymbIdx; symb <symbInSlot; symb ++)
|
||||
{
|
||||
/* set DMRS estimates to 0 angle with magnitude 1 */
|
||||
if(is_dmrs_symbol(symb,dmrsSymbPos))
|
||||
{
|
||||
/* set DMRS estimation */
|
||||
estPerSymb[symb*2]=(int16_t)((1<<15)-1); // 32767
|
||||
estPerSymb[(symb*2)+1]= 0; // no angle
|
||||
}
|
||||
/* Update left and right reference from an estimated symbol */
|
||||
if((is_ptrs_symbol(symb, ptrsSymbPos)) || (is_dmrs_symbol(symb,dmrsSymbPos)))
|
||||
{
|
||||
leftRef = symb;
|
||||
rightRef = get_next_estimate_in_slot(ptrsSymbPos,dmrsSymbPos,symb+1,symbInSlot);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The very first symbol must be a PTRS or DMRS */
|
||||
if((symb == startSymbIdx) && (leftRef == 0) && (rightRef == 0))
|
||||
{
|
||||
printf("Wrong PTRS Setup, PTRS compensation will be skipped !");
|
||||
return -1;
|
||||
}
|
||||
/* check for left side first */
|
||||
/* right side a DMRS symbol then we need to left extrapolate */
|
||||
if(is_dmrs_symbol(rightRef,dmrsSymbPos))
|
||||
{
|
||||
/* calculate slope from next valid estimates*/
|
||||
tmp = get_next_estimate_in_slot(ptrsSymbPos,dmrsSymbPos,rightRef+1,symbInSlot);
|
||||
get_slope_from_estimates(rightRef, tmp, estPerSymb, slope_p);
|
||||
ptrs_estimate_from_slope(estPerSymb,slope_p,leftRef, rightRef);
|
||||
symb = rightRef -1;
|
||||
}
|
||||
else if(is_ptrs_symbol(rightRef,ptrsSymbPos))
|
||||
{
|
||||
/* calculate slope from next valid estimates*/
|
||||
get_slope_from_estimates(leftRef,rightRef,estPerSymb, slope_p);
|
||||
ptrs_estimate_from_slope(estPerSymb,slope_p,leftRef, rightRef);
|
||||
symb = rightRef -1;
|
||||
}
|
||||
else if((rightRef ==0) && (symb <symbInSlot))
|
||||
{
|
||||
// in right extrapolation use the last slope
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Last Slop Reused :(%4d %4d)\n", slope_p[0],slope_p[1]);
|
||||
#endif
|
||||
ptrs_estimate_from_slope(estPerSymb,slope_p,symb-1,symbInSlot);
|
||||
symb = symbInSlot;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Wrong PTRS Setup, PTRS compensation will be skipped !");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate slope from 2 reference points */
|
||||
void get_slope_from_estimates(uint8_t start, uint8_t end, int16_t *est_p, int16_t *slope_p)
|
||||
{
|
||||
uint8_t distance = end - start;
|
||||
slope_p[0] = (((double)(est_p[end*2]) - (double)(est_p[start*2])) /(double)distance);
|
||||
slope_p[1] = (((double)(est_p[(end*2)+1]) - (double)(est_p[(start*2)+1])) /(double)distance);
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Slop is :(%4d %4d) between Symbol %2d & Symbol %2d\n", slope_p[0],slope_p[1], start, end);
|
||||
//printf("%d %d - %d %d\n",est_p[end*2],est_p[(end*2)+1],est_p[start*2],est_p[(start*2)+1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* estimate from slope */
|
||||
void ptrs_estimate_from_slope(int16_t *error_est, int16_t *slope_p, uint8_t start, uint8_t end)
|
||||
{
|
||||
for(uint8_t i = 1; i< (end -start);i++)
|
||||
{
|
||||
error_est[(start+i)*2] = 8 * (((double)(error_est[start*2]) * 0.125 ) + ((double)(0.125 * i * slope_p[0])));// real
|
||||
error_est[((start +i)*2)+1] = 8 * (((double)(error_est[(start*2)+1]) * 0.125) + ((double)(0.125 * i * slope_p[1]))); //imag
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Estimated Symbol %2d -> %4d %4d from Slope (%4d %4d)\n", start+i,error_est[(start+i)*2],error_est[((start +i)*2)+1],
|
||||
slope_p[0],slope_p[1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
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 */
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "SCHED_NR_UE/defs.h"
|
||||
#include "nr_estimation.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"
|
||||
|
||||
//#define DEBUG_PDSCH
|
||||
@@ -937,3 +939,171 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
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,
|
||||
|
||||
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
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
//#include "extern.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "T.h"
|
||||
#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
|
||||
#ifndef USER_MODE
|
||||
@@ -140,12 +141,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
|
||||
NR_UE_DLSCH_t **dlsch;
|
||||
uint16_t startSymbIdx=0;
|
||||
uint16_t nbSymb=0;
|
||||
|
||||
|
||||
int avg[4];
|
||||
// int avg_0[2];
|
||||
// int avg_1[2];
|
||||
// int avg_0[2];
|
||||
// int avg_1[2];
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
uint8_t slot = 0;
|
||||
@@ -174,6 +173,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
uint16_t n_tx=1, n_rx=1;
|
||||
int32_t median[16];
|
||||
uint32_t len;
|
||||
uint16_t startSymbIdx=0;
|
||||
uint16_t nbSymb=0;
|
||||
uint16_t pduBitmap=0x0;
|
||||
|
||||
switch (type) {
|
||||
case SI_PDSCH:
|
||||
@@ -693,49 +695,56 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
{
|
||||
startSymbIdx = dlsch0_harq->start_symbol;
|
||||
nbSymb = dlsch0_harq->nb_symbols;
|
||||
pduBitmap = dlsch0_harq->pduBitmap;
|
||||
}
|
||||
if(dlsch1_harq)
|
||||
{
|
||||
startSymbIdx = dlsch1_harq->start_symbol;
|
||||
nbSymb = dlsch1_harq->nb_symbols;
|
||||
pduBitmap = dlsch1_harq->pduBitmap;
|
||||
}
|
||||
//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
|
||||
// -> // compute @pointer where llrs should filled for this ofdm-symbol
|
||||
|
||||
/* 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];
|
||||
}
|
||||
|
||||
/* at last symbol in a slot calculate LLR's for whole slot */
|
||||
if(symbol == (startSymbIdx + nbSymb -1))
|
||||
{
|
||||
for(uint8_t i =startSymbIdx; i <= nbSymb;i++)
|
||||
{
|
||||
/* re evaluating the first symbol flag as LLR's are done in symbol loop */
|
||||
if(i == startSymbIdx && i < 3)
|
||||
{
|
||||
first_symbol_flag =1;
|
||||
}
|
||||
{
|
||||
first_symbol_flag =1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_symbol_flag=0;
|
||||
}
|
||||
/* Calculate LLR's for ech symbol */
|
||||
nr_dlsch_llr(pdsch_vars,
|
||||
frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
dl_ch_mag_ptr,
|
||||
dlsch0_harq,
|
||||
dlsch1_harq,
|
||||
rx_type,
|
||||
harq_pid,
|
||||
eNB_id,
|
||||
eNB_id_i,
|
||||
{
|
||||
first_symbol_flag=0;
|
||||
}
|
||||
/* Calculate LLR's for each symbol */
|
||||
nr_dlsch_llr(pdsch_vars, frame_parms,
|
||||
rxdataF_comp_ptr, dl_ch_mag_ptr,
|
||||
dlsch0_harq, dlsch1_harq,
|
||||
rx_type, harq_pid,
|
||||
eNB_id, eNB_id_i,
|
||||
first_symbol_flag,
|
||||
i,
|
||||
nb_rb,
|
||||
round,
|
||||
codeword_TB0,
|
||||
codeword_TB1,
|
||||
i, nb_rb, round,
|
||||
codeword_TB0, codeword_TB1,
|
||||
pdsch_vars[eNB_id]->dl_valid_re[i-1],
|
||||
nr_tti_rx,
|
||||
beamforming_mode);
|
||||
nr_tti_rx, beamforming_mode);
|
||||
}
|
||||
|
||||
//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) {
|
||||
nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr,
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#include "openair1/SIMULATION/TOOLS/sim.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "NR_RRCReconfiguration.h"
|
||||
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
@@ -143,8 +143,7 @@ int generate_dlsch_header(unsigned char *mac_header,
|
||||
// needed for some functions
|
||||
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)
|
||||
{
|
||||
@@ -214,6 +213,16 @@ int main(int argc, char **argv)
|
||||
int css_flag=0;
|
||||
|
||||
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) {
|
||||
exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
|
||||
@@ -226,7 +235,7 @@ int main(int argc, char **argv)
|
||||
|
||||
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) {
|
||||
case 'f':
|
||||
scg_fd = fopen(optarg,"r");
|
||||
@@ -409,9 +418,16 @@ int main(int argc, char **argv)
|
||||
eff_tp_check = (float)atoi(optarg)/100;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
output_fd = fopen("txdata.dat", "w+");
|
||||
break;
|
||||
case 'w':
|
||||
output_fd = fopen("txdata.dat", "w+");
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
enable_ptrs=1;
|
||||
for(i=0; i < atoi(optarg); i++){
|
||||
ptrs_arg[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
@@ -443,6 +459,7 @@ int main(int argc, char **argv)
|
||||
printf("-j Number of symbols for PDSCH (fixed for now)\n");
|
||||
printf("-e MSC index\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("-w Write txdata to binary file (one frame)\n");
|
||||
exit (-1);
|
||||
@@ -539,7 +556,14 @@ int main(int argc, char **argv)
|
||||
0);
|
||||
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");
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
@@ -792,7 +816,22 @@ int main(int argc, char **argv)
|
||||
Sched_INFO.UL_dci_req = NULL;
|
||||
Sched_INFO.TX_req = &gNB_mac->TX_req[0];
|
||||
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)
|
||||
nr_common_signal_procedures(gNB,frame,slot);
|
||||
else
|
||||
@@ -876,7 +915,7 @@ int main(int argc, char **argv)
|
||||
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
|
||||
sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR;
|
||||
sigma2 = pow(10, sigma2_dB/10);
|
||||
@@ -889,6 +928,12 @@ int main(int argc, char **argv)
|
||||
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+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)
|
||||
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);
|
||||
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++) {
|
||||
|
||||
@@ -1084,3 +1134,57 @@ int main(int argc, char **argv)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user