Merge remote-tracking branch 'origin/nr_dl_ul_ptrs' into integration_2020_wk48_2
This commit is contained in:
@@ -1095,7 +1095,10 @@
|
||||
(Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16),
|
||||
(Test11: HARQ test 25% TP (4 rounds),
|
||||
(Test12: HARQ test 33% TP (3 rounds),
|
||||
(Test13: HARQ test 50% TP (2 rounds)</desc>
|
||||
(Test13: HARQ test 50% TP (2 rounds),
|
||||
(Test14: 3 PTRS, 8 Interpolated Symbols),
|
||||
(Test15: 6 PTRS, 5 Interpolated Symbols),
|
||||
(Test16: 11 PTRS, 0 Interpolated Symbols)</desc>
|
||||
<pre_compile_prog></pre_compile_prog>
|
||||
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
|
||||
<compile_prog_args> --phy_simulators -c </compile_prog_args>
|
||||
@@ -1114,8 +1117,11 @@
|
||||
-n100 -e16 -s10
|
||||
-n100 -s1 -t25
|
||||
-n100 -s1 -t33
|
||||
-n100 -s1 -t50</main_exec_args>
|
||||
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13</tags>
|
||||
-n100 -s1 -t50
|
||||
-n100 -s5 -T 2 2 2
|
||||
-n100 -s5 -T 2 1 2
|
||||
-n100 -s5 -T 2 0 4</main_exec_args>
|
||||
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16</tags>
|
||||
<search_expr_true>PDSCH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -472,6 +472,21 @@ typedef struct {
|
||||
uint8_t cbgti;
|
||||
uint8_t codeBlockGroupFlushIndicator;
|
||||
// to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
|
||||
// PTRS [TS38.214, sec 5.1.6.3]
|
||||
/// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used
|
||||
uint8_t PTRSPortIndex ;
|
||||
/// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4
|
||||
uint8_t PTRSTimeDensity;
|
||||
/// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4
|
||||
uint8_t PTRSFreqDensity;
|
||||
/// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3
|
||||
uint8_t PTRSReOffset;
|
||||
/// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3
|
||||
uint8_t nEpreRatioOfPDSCHToPTRS;
|
||||
/// MCS table for this DLSCH
|
||||
uint8_t mcs_table;
|
||||
|
||||
uint16_t pduBitmap;
|
||||
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -393,6 +393,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" );
|
||||
|
||||
@@ -413,6 +416,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "nr_ul_estimation.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
@@ -533,384 +534,107 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
* 3) Compensated DMRS based estimated signal with PTRS estimation for slot
|
||||
*********************************************************************/
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
uint8_t ulsch_id,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t dmrs_symbol_flag,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int16_t *phase_per_symbol;
|
||||
|
||||
uint8_t L_ptrs = 0;
|
||||
uint8_t right_side_ref = 0;
|
||||
uint8_t left_side_ref = 0;
|
||||
uint8_t nb_dmrs_in_slot = 0;
|
||||
|
||||
//#define DEBUG_UL_PTRS 1
|
||||
/* First symbol calculate PTRS symbol index for slot & set the variables */
|
||||
if(symbol == rel15_ul->start_symbol_index)
|
||||
{
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
|
||||
L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
|
||||
set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
|
||||
rel15_ul->nr_of_symbols,
|
||||
rel15_ul->start_symbol_index,
|
||||
L_ptrs,
|
||||
rel15_ul->ul_dmrs_symb_pos);
|
||||
}/* First symbol check */
|
||||
int16_t *phase_per_symbol = NULL;
|
||||
int32_t *ptrs_re_symbol = NULL;
|
||||
int8_t ret = 0;
|
||||
|
||||
uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols;
|
||||
uint8_t *startSymbIndex = &rel15_ul->start_symbol_index;
|
||||
uint8_t *nbSymb = &rel15_ul->nr_of_symbols;
|
||||
uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density;
|
||||
uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density;
|
||||
uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos;
|
||||
uint16_t *ptrsSymbPos = &gNB->pusch_vars[ulsch_id]->ptrs_symbols;
|
||||
uint8_t *ptrsSymbIdx = &gNB->pusch_vars[ulsch_id]->ptrs_symbol_index;
|
||||
uint8_t *dmrsConfigType = &rel15_ul->dmrs_config_type;
|
||||
uint16_t *nb_rb = &rel15_ul->rb_size;
|
||||
uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset;
|
||||
/* loop over antennas */
|
||||
for (int aarx=0; aarx< frame_parms->nb_antennas_rx; aarx++)
|
||||
{
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx];
|
||||
/* set the previous estimations to zero at first symbol */
|
||||
if(symbol == rel15_ul->start_symbol_index)
|
||||
{
|
||||
memset(phase_per_symbol,0,sizeof(int32_t)*frame_parms->symbols_per_slot);
|
||||
ptrs_re_symbol = &gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
|
||||
*ptrs_re_symbol = 0;
|
||||
phase_per_symbol[(2*symbol)+1] = 0; // Imag
|
||||
/* set DMRS estimates to 0 angle with magnitude 1 */
|
||||
if(is_dmrs_symbol(symbol,*dmrsSymbPos)) {
|
||||
/* set DMRS real estimation to 32767 */
|
||||
phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]);
|
||||
#endif
|
||||
}
|
||||
else {// real ptrs value is set to 0
|
||||
phase_per_symbol[2*symbol] = 0; // Real
|
||||
}
|
||||
|
||||
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*/
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = 0;
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
|
||||
*ptrsSymbIdx = 0;
|
||||
/* Check if current symbol contains PTRS */
|
||||
if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
|
||||
{
|
||||
gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
|
||||
if(is_ptrs_symbol(symbol, *ptrsSymbPos)) {
|
||||
*ptrsSymbIdx = symbol;
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 1) Estimate phase noise per PTRS symbol */
|
||||
/* 1) Estimate common phase error per PTRS symbol */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
nr_pusch_phase_estimation(frame_parms,
|
||||
rel15_ul,
|
||||
(int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch],
|
||||
nr_tti_rx,
|
||||
symbol,
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
|
||||
gNB->nr_gold_pusch_dmrs[rel15_ul->scid],
|
||||
&phase_per_symbol[2* symbol],
|
||||
&gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol);
|
||||
}
|
||||
/* DMRS Symbol channel estimates extraction */
|
||||
else if(dmrs_symbol_flag)
|
||||
{
|
||||
phase_per_symbol[2* symbol]= (int16_t)((1<<15)-1); // 32767
|
||||
phase_per_symbol[2* symbol +1]= 0;// no angle
|
||||
nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb,
|
||||
rel15_ul->rnti,
|
||||
(int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch],
|
||||
nr_tti_rx,
|
||||
symbol,frame_parms->ofdm_symbol_size,
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
|
||||
gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol],
|
||||
&phase_per_symbol[2* symbol],
|
||||
ptrs_re_symbol);
|
||||
}
|
||||
/* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
|
||||
if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
|
||||
{
|
||||
nb_dmrs_in_slot = get_dmrs_symbols_in_slot(rel15_ul->ul_dmrs_symb_pos,(rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
for(uint8_t dmrs_sym = 0; dmrs_sym < nb_dmrs_in_slot; dmrs_sym ++)
|
||||
{
|
||||
if(dmrs_sym == 0)
|
||||
{
|
||||
/* get first DMRS position */
|
||||
left_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
/* get first DMRS position is not at start symbol position then we need to extrapolate left side */
|
||||
if(left_side_ref > rel15_ul->start_symbol_index)
|
||||
{
|
||||
left_side_ref = rel15_ul->start_symbol_index;
|
||||
}
|
||||
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");
|
||||
}
|
||||
/* get the next symbol from left_side_ref value */
|
||||
right_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, left_side_ref+1, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
|
||||
/* if no symbol found then interpolate till end of slot*/
|
||||
if(right_side_ref == 0)
|
||||
{
|
||||
right_side_ref = (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
|
||||
}
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 2) Interpolate PTRS estimated value in TD */
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
nr_pusch_phase_interpolation(phase_per_symbol,left_side_ref,right_side_ref);
|
||||
/* set left to last dmrs */
|
||||
left_side_ref = right_side_ref;
|
||||
} /*loop over dmrs positions */
|
||||
|
||||
}
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
LOG_M("ptrsEst.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
|
||||
LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
|
||||
LOG_M("ptrsEstUl.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
|
||||
LOG_M("rxdataF_bf_ptrs_comp_ul.m","bf_ptrs_cmp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
|
||||
rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------- */
|
||||
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
|
||||
/*--------------------------------------------------------------------------------------------------------*/
|
||||
for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++)
|
||||
{
|
||||
for(uint8_t i = *startSymbIndex; i< symbInSlot ;i++) {
|
||||
/* DMRS Symbol has 0 phase so no need to rotate the respective symbol */
|
||||
/* Skip rotation if the slot processing is wrong */
|
||||
if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) {
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
|
||||
printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
|
||||
#endif
|
||||
rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
&phase_per_symbol[2* i],
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
(rel15_ul->rb_size * NR_NB_SC_PER_RB),
|
||||
15);
|
||||
rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
&phase_per_symbol[2* i],
|
||||
(int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
|
||||
((*nb_rb) * NR_NB_SC_PER_RB), 15);
|
||||
}// if not DMRS Symbol
|
||||
}// symbol loop
|
||||
}//interpolation and compensation
|
||||
}// Antenna loop
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_pusch_phase_estimation
|
||||
*
|
||||
* PARAMETERS : frame_parms : UL frame parameters
|
||||
* rel15_ul : UL PDU Structure
|
||||
* Ns :
|
||||
* Symbol : OFDM symbol index
|
||||
* rxF : Channel compensated signal
|
||||
* ptrs_gold_seq: Gold sequence for PTRS regeneration
|
||||
* error_est : Estimated error output vector [Re Im]
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* perform phase estimation from regenerated PTRS SC and channel compensated
|
||||
* signal
|
||||
*********************************************************************/
|
||||
void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
int16_t *ptrs_ch_p,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t ***ptrs_gold_seq,
|
||||
int16_t *error_est,
|
||||
uint16_t *ptrs_sc)
|
||||
{
|
||||
uint8_t is_ptrs_re = 0;
|
||||
uint16_t re_cnt = 0;
|
||||
uint16_t cnt = 0;
|
||||
unsigned short nb_re_pusch = NR_NB_SC_PER_RB * rel15_ul->rb_size;
|
||||
uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density;
|
||||
uint16_t sc_per_symbol = (rel15_ul->rb_size + K_ptrs - 1)/K_ptrs;
|
||||
int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
|
||||
int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
|
||||
double abs = 0.0;
|
||||
double real = 0.0;
|
||||
double imag = 0.0;
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
double alpha = 0;
|
||||
#endif
|
||||
/* generate PTRS RE for the symbol */
|
||||
nr_gen_ref_conj_symbols(ptrs_gold_seq[Ns][symbol],sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK
|
||||
|
||||
/* loop over all sub carriers to get compensated RE on ptrs symbols*/
|
||||
for (int re = 0; re < nb_re_pusch; re++)
|
||||
{
|
||||
is_ptrs_re = is_ptrs_subcarrier(re,
|
||||
rel15_ul->rnti,
|
||||
0,
|
||||
rel15_ul->dmrs_config_type,
|
||||
K_ptrs,
|
||||
rel15_ul->rb_size,
|
||||
rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
|
||||
0,// start_re is 0 here
|
||||
frame_parms->ofdm_symbol_size);
|
||||
if(is_ptrs_re)
|
||||
{
|
||||
dmrs_comp_p[re_cnt*2] = rxF_comp[re *2];
|
||||
dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1];
|
||||
re_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Skip PTRS symbols and keep data in a continuous vector */
|
||||
rxF_comp[cnt *2]= rxF_comp[re *2];
|
||||
rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1];
|
||||
cnt++;
|
||||
}
|
||||
}/* RE loop */
|
||||
/* update the total ptrs RE in a symbol */
|
||||
*ptrs_sc = re_cnt;
|
||||
|
||||
/*Multiple compensated data with conj of PTRS */
|
||||
mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted
|
||||
|
||||
/* loop over all ptrs sub carriers in a symbol */
|
||||
/* sum the error vector */
|
||||
for(int i = 0;i < sc_per_symbol; i++)
|
||||
{
|
||||
real+= ptrs_ch_p[(2*i)];
|
||||
imag+= ptrs_ch_p[(2*i)+1];
|
||||
}
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
alpha = atan(imag/real);
|
||||
printf("PTRS: Symbol %d atan(Im,real):= %f \n",symbol, alpha );
|
||||
#endif
|
||||
/* mean */
|
||||
real /= sc_per_symbol;
|
||||
imag /= sc_per_symbol;
|
||||
/* absolute calculation */
|
||||
abs = sqrt(((real * real) + (imag * imag)));
|
||||
/* normalized error estimation */
|
||||
error_est[0]= (real / abs)*(1<<15);
|
||||
/* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/
|
||||
error_est[1]= (-1)*(imag / abs)*(1<<15);
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] );
|
||||
#endif
|
||||
/* free vectors */
|
||||
free(ptrs_p);
|
||||
free(dmrs_comp_p);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : nr_pusch_phase_interpolation
|
||||
*
|
||||
* PARAMETERS : *error_est : Data Pointer [Re Im Re Im ...]
|
||||
* start_symbol : Start Symbol
|
||||
* end_symbol : End Symbol
|
||||
* RETURN : nothing
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* Perform Interpolation, extrapolation based upon the estimation
|
||||
* location between the data Pointer Array.
|
||||
*
|
||||
*********************************************************************/
|
||||
void nr_pusch_phase_interpolation(int16_t *error_est,
|
||||
uint8_t start_symbol,
|
||||
uint8_t end_symbol
|
||||
)
|
||||
{
|
||||
|
||||
int next = 0, prev = 0, candidates= 0, distance=0, leftEdge= 0, rightEdge = 0, getDiff =0 ;
|
||||
double weight = 0.0;
|
||||
double scale = 0.125 ; // to avoid saturation due to fixed point multiplication
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Left limit %d, Right limit %d, Loop over %d Symbols \n",
|
||||
start_symbol,end_symbol-1, (end_symbol -start_symbol)-1);
|
||||
#endif
|
||||
for(int i =start_symbol; i< end_symbol;i++)
|
||||
{
|
||||
/* Only update when an estimation is found */
|
||||
if( error_est[i*2] != 0 )
|
||||
{
|
||||
/* if found a symbol then set next symbol also */
|
||||
next = nr_ptrs_find_next_estimate(error_est, i, end_symbol);
|
||||
/* left extrapolation, if first estimate value is zero */
|
||||
if( error_est[i*2] == 0 )
|
||||
{
|
||||
leftEdge = 1;
|
||||
}
|
||||
/* right extrapolation, if next is 0 before end symbol */
|
||||
if((next == 0) && (end_symbol > i))
|
||||
{
|
||||
rightEdge = 1;
|
||||
/* special case as no right extrapolation possible with DMRS on left */
|
||||
/* In this case take mean of most recent 2 estimated points */
|
||||
if(prev ==0)
|
||||
{
|
||||
prev = start_symbol -1;
|
||||
next = start_symbol -2;
|
||||
getDiff =1;
|
||||
}else
|
||||
{
|
||||
/* for right edge previous is second last from right side */
|
||||
next = prev;
|
||||
/* Set the current as recent estimation reference */
|
||||
prev = i;
|
||||
}
|
||||
}
|
||||
/* update current symbol as prev for next symbol */
|
||||
if (rightEdge==0)
|
||||
/* Set the current as recent estimation reference */
|
||||
prev = i;
|
||||
}
|
||||
/*extrapolation left side*/
|
||||
if(leftEdge)
|
||||
{
|
||||
distance = next - prev;
|
||||
weight = 1.0/distance;
|
||||
candidates = i;
|
||||
for(int j = 1; j <= candidates; j++)
|
||||
{
|
||||
error_est[(i-j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[next*2]) * scale * j * weight));
|
||||
error_est[((i-j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale* (distance + j) * weight) -
|
||||
((double)(error_est[((next*2)+1)]) * scale * j * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Left Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i-j),weight, error_est[(i-j)*2],error_est[((i-j)*2)+1], prev,next);
|
||||
#endif
|
||||
}
|
||||
leftEdge = 0;
|
||||
}
|
||||
/* extrapolation at right side */
|
||||
else if (rightEdge )
|
||||
{
|
||||
if(getDiff)
|
||||
{
|
||||
error_est[(i+1)*2] = ((1<<15) +(error_est[prev*2]) - error_est[next*2]);
|
||||
error_est[((i+1)*2)+1]= error_est[(prev*2)+1] - error_est[(next*2)+1];
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Right Edge Special Case i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i+1),weight, error_est[(i+1)*2],error_est[((i+1)*2)+1], prev,next);
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = prev - next;
|
||||
candidates = (end_symbol -1) - i;
|
||||
weight = 1.0/distance;
|
||||
for(int j = 1; j <= candidates; j++)
|
||||
{
|
||||
error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[next*2]) * scale * j * weight));
|
||||
error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale * (distance + j) * weight) -
|
||||
((double)(error_est[((next*2)+1)]) * scale *j * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Right Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
|
||||
(i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1], prev,next);
|
||||
#endif
|
||||
}
|
||||
if(candidates > 1)
|
||||
{
|
||||
i+=candidates;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Interpolation between 2 estimated points */
|
||||
else if(next != 0 && ( error_est[2*i] == 0 ))
|
||||
{
|
||||
distance = next - prev;
|
||||
weight = 1.0/distance;
|
||||
candidates = next - i ;
|
||||
for(int j = 0; j < candidates; j++)
|
||||
{
|
||||
|
||||
error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance - (j+1)) * weight) +
|
||||
((double)(error_est[next*2]) * scale * (j+1) * weight));
|
||||
error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale *(distance - (j+1)) * weight) +
|
||||
((double)(error_est[((next*2)+1)]) * scale *(j+1) * weight));
|
||||
#ifdef DEBUG_UL_PTRS
|
||||
printf("PTRS: INT: Interpolation i= %d weight= %f %d + j*%d, Prev %d Next %d\n",
|
||||
(i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1],prev,next);
|
||||
#endif
|
||||
}
|
||||
if(candidates > 1)
|
||||
{
|
||||
i+=candidates-1;
|
||||
}
|
||||
}// interpolation
|
||||
}// symbol loop
|
||||
}
|
||||
|
||||
/* Find the next non zero Real value in a complex vector */
|
||||
int nr_ptrs_find_next_estimate(int16_t *error_est,
|
||||
uint8_t counter,
|
||||
uint8_t end_symbol)
|
||||
{
|
||||
for (int i = counter +1 ; i< end_symbol; i++)
|
||||
{
|
||||
if( error_est[2*i] != 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}// last symbol check
|
||||
}//Antenna loop
|
||||
}
|
||||
|
||||
@@ -53,28 +53,10 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
|
||||
|
||||
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
uint8_t ulsch_id,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t dmrs_symbol_flag,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pusch);
|
||||
|
||||
void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *rel15_ul,
|
||||
int16_t *ptrs_ch_p,
|
||||
unsigned char Ns,
|
||||
unsigned char symbol,
|
||||
int16_t *rxF_comp,
|
||||
uint32_t ***ptrs_gold_seq,
|
||||
int16_t *error_est,
|
||||
uint16_t *ptrs_sc);
|
||||
|
||||
void nr_pusch_phase_interpolation(int16_t *error_est,
|
||||
uint8_t start_symbol,
|
||||
uint8_t end_symbol);
|
||||
|
||||
int nr_ptrs_find_next_estimate(int16_t *error_est,
|
||||
uint8_t counter,
|
||||
uint8_t end_symbol);
|
||||
#endif
|
||||
|
||||
@@ -364,14 +364,14 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H
|
||||
#endif
|
||||
}
|
||||
/* return the position of next dmrs symbol in a slot */
|
||||
int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol)
|
||||
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol)
|
||||
{
|
||||
for(uint8_t symbol = counter; symbol < end_symbol; symbol++)
|
||||
if((ul_dmrs_symb_pos >>symbol)&0x01 )
|
||||
{
|
||||
for(uint8_t symbol = counter; symbol < end_symbol; symbol++) {
|
||||
if((ul_dmrs_symb_pos >> symbol) & 0x01 ) {
|
||||
return symbol;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -379,9 +379,30 @@ int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, ui
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb)
|
||||
{
|
||||
uint8_t tmp = 0;
|
||||
for (int i = 0; i < nb_symb; i++)
|
||||
{
|
||||
for (int i = 0; i < nb_symb; i++) {
|
||||
tmp += (l_prime_mask >> i) & 0x01;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* return the position of valid dmrs symbol in a slot for channel compensation */
|
||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter)
|
||||
{
|
||||
int8_t symbIdx = -1;
|
||||
/* if current symbol is DMRS then return this index */
|
||||
if(is_dmrs_symbol(counter, dmrs_symb_pos ) ==1) {
|
||||
return counter;
|
||||
}
|
||||
/* find previous DMRS symbol */
|
||||
for(int8_t symbol = counter;symbol >=0 ; symbol--) {
|
||||
if((1<<symbol & dmrs_symb_pos)> 0) {
|
||||
symbIdx = symbol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if there is no previous dmrs available then find the next possible*/
|
||||
if(symbIdx == -1) {
|
||||
symbIdx = get_next_dmrs_symbol_in_slot(dmrs_symb_pos,counter,15);
|
||||
}
|
||||
return symbIdx;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,12 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k,
|
||||
uint8_t numDmrsCdmGrpsNoData,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
||||
int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
|
||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter);
|
||||
|
||||
static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask ) { return ((dmrsSymbMask >> l) & 0x1); }
|
||||
#undef EXTERN
|
||||
|
||||
#endif /* DMRS_NR_H */
|
||||
|
||||
@@ -107,9 +107,7 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
||||
}
|
||||
|
||||
void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
unsigned short lbar,
|
||||
unsigned short *n_idDMRS,
|
||||
unsigned short length_dmrs)
|
||||
unsigned short *n_idDMRS)
|
||||
{
|
||||
unsigned char ns,l;
|
||||
unsigned int n,x1,x2,x2tmp0;
|
||||
@@ -129,12 +127,12 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
|
||||
for (ns=0; ns<20; ns++) {
|
||||
|
||||
for (l=0; l<length_dmrs; l++) {
|
||||
for (l=0; l<14; l++) {
|
||||
|
||||
x2tmp0 = ((14*ns+(lbar+l)+1)*((nid<<1)+1))<<17;
|
||||
x2tmp0 = ((14*ns+l+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit
|
||||
LOG_D(PHY,"UE DMRS slot %d, symb %d, lbar %d, x2 %x, nscid %d\n",ns,l,lbar,x2,nscid);
|
||||
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
|
||||
LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
|
||||
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
|
||||
|
||||
x1 = 1+ (1<<31);
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
@@ -145,7 +143,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
}
|
||||
|
||||
for (n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
|
||||
@@ -154,8 +152,8 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
ue->nr_gold_pdsch[nscid][ns][l][n] = x1^x2;
|
||||
// if ((ns==2)&&(l==0))
|
||||
//printf("n=%d : c %x\n",n,x1^x2);
|
||||
// if ((ns==2)&&(l==0))
|
||||
//printf("n=%d : c %x\n",n,x1^x2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,10 +53,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
|
||||
uint8_t dmrs_type);
|
||||
|
||||
void init_scrambling_luts(void);
|
||||
void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
|
||||
uint8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
|
||||
uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
|
||||
|
||||
void nr_generate_modulation_table(void);
|
||||
|
||||
extern __m64 byte2m64_re[256];
|
||||
|
||||
@@ -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,249 @@ 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 */
|
||||
int8_t get_next_ptrs_symbol_in_slot(uint16_t ptrs_symb_pos, uint8_t counter, uint8_t nb_symb)
|
||||
{
|
||||
for(int8_t symbol = counter; symbol < nb_symb; symbol++) {
|
||||
if((ptrs_symb_pos >>symbol)&0x01 ) {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
/* get the next nearest estimate from DMRS or PTRS */
|
||||
int8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb)
|
||||
{
|
||||
int8_t nextPtrs = get_next_ptrs_symbol_in_slot(ptrsSymbPos, counter,nb_symb);
|
||||
int8_t nextDmrs = get_next_dmrs_symbol_in_slot(dmrsSymbPos, counter,nb_symb);
|
||||
if(nextDmrs == -1) {
|
||||
return nextPtrs;
|
||||
}
|
||||
/* Special case when DMRS is next valid estimation */
|
||||
if(nextPtrs == -1) {
|
||||
return nextDmrs;
|
||||
}
|
||||
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)
|
||||
{
|
||||
double slope[2] = {0,0};
|
||||
double *slope_p = &slope[0];
|
||||
uint8_t symbInSlot = startSymbIdx + noSymb;
|
||||
int8_t rightRef = 0;
|
||||
int8_t leftRef = 0;
|
||||
int8_t tmp = 0;
|
||||
for(uint8_t symb = startSymbIdx; symb <symbInSlot; symb ++) {
|
||||
/* 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 == -1) && (rightRef == -1)) {
|
||||
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);
|
||||
/* Special case when DMRS is not followed by PTRS symbol then reuse old slope */
|
||||
if(tmp!=-1) {
|
||||
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 ==-1) && (symb <symbInSlot)) {
|
||||
// in right extrapolation use the last slope
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Last Slop Reused :(%4f %4f)\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, double *slope_p)
|
||||
{
|
||||
uint8_t distance = end - start;
|
||||
slope_p[0] = (double)(est_p[end*2] - est_p[start*2]) /distance;
|
||||
slope_p[1] = (double)(est_p[(end*2)+1] - est_p[(start*2)+1]) /distance;
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Slop is :(%4f %4f) 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, double *slope_p, uint8_t start, uint8_t end)
|
||||
{
|
||||
for(uint8_t i = 1; i< (end -start);i++) {
|
||||
error_est[(start+i)*2] = (error_est[start*2] + (int16_t)(i * slope_p[0]));// real
|
||||
error_est[((start +i)*2)+1] = (error_est[(start*2)+1] + (int16_t)( i * slope_p[1])); //imag
|
||||
#ifdef DEBUG_PTRS
|
||||
printf("[PHY][PTRS]: Estimated Symbol %2d -> %4d %4d from Slope (%4f %4f)\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);
|
||||
int8_t get_next_ptrs_symbol_in_slot(uint16_t ptrsSymbPos, uint8_t counter, uint8_t nb_symb);
|
||||
int8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb);
|
||||
|
||||
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, double *slope_p);
|
||||
void ptrs_estimate_from_slope(int16_t *error_est, double *slope_p, uint8_t start, uint8_t end);
|
||||
#endif /* PTRS_NR_H */
|
||||
|
||||
@@ -61,9 +61,7 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
||||
unsigned short length_dmrs);
|
||||
|
||||
void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
unsigned short lbar,
|
||||
unsigned short *n_idDMRS,
|
||||
unsigned short length_dmrs);
|
||||
unsigned short *n_idDMRS);
|
||||
|
||||
void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
|
||||
uint16_t *N_n_scid,
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
#include "nr_sch_dmrs.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
//#define DEBUG_DLSCH
|
||||
//#define DEBUG_DLSCH_MAPPING
|
||||
@@ -117,8 +119,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
|
||||
int32_t** txdataF = gNB->common_vars.txdataF;
|
||||
int16_t amp = AMP;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int xOverhead = 0;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
time_stats_t *dlsch_encoding_stats=&gNB->dlsch_encoding_stats;
|
||||
time_stats_t *dlsch_scrambling_stats=&gNB->dlsch_scrambling_stats;
|
||||
time_stats_t *dlsch_modulation_stats=&gNB->dlsch_modulation_stats;
|
||||
@@ -152,13 +154,31 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
|
||||
n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
|
||||
}
|
||||
uint16_t nb_re;
|
||||
nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
|
||||
|
||||
uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
|
||||
uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
|
||||
uint8_t Qm = rel15->qamModOrder[0];
|
||||
uint32_t encoded_length = nb_re*Qm;
|
||||
int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16)));
|
||||
|
||||
|
||||
|
||||
/* PTRS */
|
||||
uint16_t beta_ptrs = 1;
|
||||
uint8_t ptrs_symbol = 0;
|
||||
uint16_t dlPtrsSymPos = 0;
|
||||
uint16_t n_ptrs = 0;
|
||||
uint16_t ptrs_idx = 0;
|
||||
uint8_t is_ptrs_re = 0;
|
||||
if(rel15->pduBitmap & 0x1) {
|
||||
set_ptrs_symb_idx(&dlPtrsSymPos,
|
||||
rel15->NrOfSymbols,
|
||||
rel15->StartSymbolIndex,
|
||||
1<<rel15->PTRSTimeDensity,
|
||||
rel15->dlDmrsSymbPos);
|
||||
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity;
|
||||
}
|
||||
int16_t mod_ptrs[n_ptrs<<1] __attribute__ ((aligned(16)));
|
||||
|
||||
/// CRC, coding, interleaving and rate matching
|
||||
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
|
||||
start_meas(dlsch_encoding_stats);
|
||||
@@ -251,22 +271,21 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
|
||||
if (rel15->dlDmrsSymbPos & (1 << l))
|
||||
if (rel15->dlDmrsSymbPos & (1 << l)) {
|
||||
nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DLSCH
|
||||
l0 = get_l0(rel15->dlDmrsSymbPos);
|
||||
printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type);
|
||||
for (int i=0; i<n_dmrs>>4; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type);
|
||||
for (int i=0; i<n_dmrs>>4; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[l][((i<<3)+j)<<1], mod_dmrs[l][(((i<<3)+j)<<1)+1]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// Resource mapping
|
||||
|
||||
// Non interleaved VRB to PRB mapping
|
||||
@@ -293,30 +312,63 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
|
||||
1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
|
||||
#endif
|
||||
uint8_t k_prime=0;
|
||||
uint16_t m=0, n=0, dmrs_idx=0, k=0;
|
||||
|
||||
|
||||
uint16_t m=0, dmrs_idx=0, k=0;
|
||||
|
||||
int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP;
|
||||
|
||||
// Loop Over OFDM symbols:
|
||||
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
|
||||
/// DMRS QPSK modulation
|
||||
uint8_t k_prime=0;
|
||||
uint16_t n=0;
|
||||
if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
|
||||
dmrs_idx = rel15->rbStart*6;
|
||||
else
|
||||
dmrs_idx = rel15->rbStart*4;
|
||||
}
|
||||
|
||||
// Update l_prime in the case of double DMRS config
|
||||
if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion
|
||||
if (l==(l_overline+1)) //take into account the double DMRS symbols
|
||||
l_prime = 1;
|
||||
else if (l>(l_overline+1)) {//new DMRS pair
|
||||
l_overline = l;
|
||||
l_prime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate if current symbol is PTRS symbols */
|
||||
ptrs_idx = 0;
|
||||
|
||||
if(rel15->pduBitmap & 0x1) {
|
||||
ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos);
|
||||
if(ptrs_symbol) {
|
||||
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
||||
nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
|
||||
}
|
||||
}
|
||||
k = start_sc;
|
||||
n = 0;
|
||||
k_prime = 0;
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
|
||||
dmrs_idx = rel15->rbStart*6;
|
||||
else
|
||||
dmrs_idx = rel15->rbStart*4;
|
||||
// Loop Over SCs:
|
||||
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
|
||||
/* check if cuurent RE is PTRS RE*/
|
||||
is_ptrs_re=0;
|
||||
/* check for PTRS symbol and set flag for PTRS RE */
|
||||
if(ptrs_symbol){
|
||||
is_ptrs_re = is_ptrs_subcarrier(k,
|
||||
rel15->rnti,
|
||||
ap,
|
||||
rel15->dmrsConfigType,
|
||||
rel15->PTRSFreqDensity,
|
||||
rel15->rbSize,
|
||||
rel15->PTRSReOffset,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
|
||||
if ((rel15->dlDmrsSymbPos & (1 << l)) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
|
||||
|
||||
if (l==(l_overline+1)) //take into account the double DMRS symbols
|
||||
l_prime = 1;
|
||||
else if (l>(l_overline+1)) {//new DMRS pair
|
||||
l_overline = l;
|
||||
l_prime = 0;
|
||||
}
|
||||
|
||||
/* Map DMRS Symbol */
|
||||
if ( ( dmrs_symbol_map & (1 << l) ) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
@@ -328,10 +380,21 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
|
||||
} else {
|
||||
|
||||
if( (!(rel15->dlDmrsSymbPos & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
|
||||
}
|
||||
/* Map PTRS Symbol */
|
||||
else if(is_ptrs_re){
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
|
||||
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
|
||||
#endif
|
||||
ptrs_idx++;
|
||||
}
|
||||
/* Map DATA Symbol */
|
||||
else {
|
||||
if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
|
||||
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
|
||||
@@ -1234,16 +1234,16 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
{
|
||||
start_meas(&gNB->ulsch_ptrs_processing_stats);
|
||||
nr_pusch_ptrs_processing(gNB,
|
||||
frame_parms,
|
||||
rel15_ul,
|
||||
ulsch_id,
|
||||
nr_tti_rx,
|
||||
dmrs_symbol_flag,
|
||||
symbol,
|
||||
nb_re_pusch);
|
||||
stop_meas(&gNB->ulsch_ptrs_processing_stats);
|
||||
|
||||
/* Subtract total PTRS RE's in the symbol from PUSCH RE's */
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol;
|
||||
gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#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/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
#include "filt16a_32.h"
|
||||
|
||||
@@ -667,7 +670,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates;
|
||||
int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
|
||||
|
||||
if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
|
||||
if (ue->high_speed_flag == 0)
|
||||
ch_offset = ue->frame_parms.ofdm_symbol_size ;
|
||||
else
|
||||
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
|
||||
@@ -686,7 +689,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
|
||||
uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
|
||||
int8_t delta = get_delta(p, config_type);
|
||||
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset);
|
||||
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
|
||||
|
||||
if (config_type == pdsch_dmrs_type1){
|
||||
nushift = (p>>1)&1;
|
||||
@@ -1196,3 +1199,168 @@ 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_slot_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_slot_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)+1] = 0; // Imag
|
||||
/* set DMRS estimates to 0 angle with magnitude 1 */
|
||||
if(is_dmrs_symbol(symbol,*dmrsSymbPos)) {
|
||||
/* set DMRS real estimation to 32767 */
|
||||
phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767
|
||||
#ifdef DEBUG_DL_PTRS
|
||||
printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]);
|
||||
#endif
|
||||
}
|
||||
else { // real ptrs value is set to 0
|
||||
phase_per_symbol[2*symbol] = 0; // Real
|
||||
}
|
||||
|
||||
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_slot_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_slot_rx][symbol],
|
||||
&phase_per_symbol[2* symbol],
|
||||
&ptrs_re_symbol[symbol]);
|
||||
}
|
||||
}// 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 */
|
||||
/* Skip rotation if the slot processing is wrong */
|
||||
if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) {
|
||||
#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
|
||||
|
||||
@@ -103,6 +103,18 @@ 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_slot_rx,
|
||||
unsigned char symbol,
|
||||
uint32_t nb_re_pdsch,
|
||||
unsigned char harq_pid,
|
||||
uint16_t rnti,
|
||||
RX_type_t rx_type);
|
||||
|
||||
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
|
||||
|
||||
|
||||
@@ -279,7 +279,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
|
||||
}
|
||||
uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos);
|
||||
AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length);
|
||||
|
||||
uint32_t i,j;
|
||||
|
||||
|
||||
@@ -37,7 +37,10 @@
|
||||
//#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"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
|
||||
#ifndef USER_MODE
|
||||
#define NOCYGWIN_STATIC static
|
||||
@@ -99,6 +102,29 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
uint16_t length,
|
||||
int16_t **llr_layers);
|
||||
|
||||
|
||||
/* compute LLR */
|
||||
static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp_ptr,
|
||||
int32_t **dl_ch_mag_ptr,
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq,
|
||||
NR_DL_UE_HARQ_t *dlsch1_harq,
|
||||
RX_type_t rx_type,
|
||||
unsigned char harq_pid,
|
||||
unsigned char eNB_id,
|
||||
unsigned char eNB_id_i,
|
||||
unsigned char first_symbol_flag,
|
||||
unsigned char symbol,
|
||||
unsigned short nb_rb,
|
||||
unsigned short round,
|
||||
int32_t codeword_TB0,
|
||||
int32_t codeword_TB1,
|
||||
uint32_t len,
|
||||
uint8_t nr_slot_rx,
|
||||
uint8_t beamforming_mode);
|
||||
|
||||
/* Main Function */
|
||||
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
PDSCH_t type,
|
||||
@@ -143,19 +169,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
//to be updated higher layer
|
||||
unsigned short start_rb = 0;
|
||||
unsigned short nb_rb_pdsch = 50;
|
||||
int16_t *pllr_symbol_cw0;
|
||||
int16_t *pllr_symbol_cw1;
|
||||
int16_t *pllr_symbol_layer0;
|
||||
int16_t *pllr_symbol_layer1;
|
||||
//int16_t *pllr_symbol_cw0_deint;
|
||||
//int16_t *pllr_symbol_cw1_deint;
|
||||
uint32_t llr_offset_symbol;
|
||||
//uint16_t bundle_L = 2;
|
||||
uint8_t pilots=0;
|
||||
uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
|
||||
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:
|
||||
@@ -384,7 +408,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
nb_rb_pdsch,
|
||||
nr_slot_rx,
|
||||
ue->high_speed_flag,
|
||||
frame_parms);
|
||||
frame_parms,
|
||||
dlsch0_harq->dlDmrsSymbPos);
|
||||
|
||||
} /*else if(beamforming_mode>7) {
|
||||
LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n");
|
||||
@@ -673,376 +698,66 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||
#endif
|
||||
//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
|
||||
/* Store the valid DL RE's */
|
||||
pdsch_vars[eNB_id]->dl_valid_re[symbol-1] = len;
|
||||
|
||||
if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0;
|
||||
llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
|
||||
//pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
|
||||
//pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
|
||||
pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
|
||||
pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
|
||||
pllr_symbol_layer0 += llr_offset_symbol;
|
||||
pllr_symbol_layer1 += llr_offset_symbol;
|
||||
pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
|
||||
pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
|
||||
pllr_symbol_cw0 += llr_offset_symbol;
|
||||
pllr_symbol_cw1 += llr_offset_symbol;
|
||||
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
|
||||
|
||||
LOG_D(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d energy %d\n",
|
||||
symbol,
|
||||
nb_rb,dlsch0_harq->Qm,
|
||||
pdsch_vars[eNB_id]->llr_length[symbol],
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
signal_energy(pdsch_vars[eNB_id]->rxdataF_comp0[0], 7*2*frame_parms->N_RB_DL*12));
|
||||
|
||||
|
||||
/*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
|
||||
symbol,
|
||||
nb_rb,dlsch0_harq->Qm,
|
||||
pdsch_vars[eNB_id]->llr_length[symbol],
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pllr_symbol_cw0);*/
|
||||
|
||||
switch (dlsch0_harq->Qm) {
|
||||
case 2 :
|
||||
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
symbol,
|
||||
len,
|
||||
first_symbol_flag,
|
||||
nb_rb,
|
||||
beamforming_mode);
|
||||
|
||||
} else if (codeword_TB0 == -1){
|
||||
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw1,
|
||||
symbol,
|
||||
len,
|
||||
first_symbol_flag,
|
||||
nb_rb,
|
||||
beamforming_mode);
|
||||
if(dlsch0_harq->status == ACTIVE) {
|
||||
startSymbIdx = dlsch0_harq->start_symbol;
|
||||
nbSymb = dlsch0_harq->nb_symbols;
|
||||
pduBitmap = dlsch0_harq->pduBitmap;
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_qpsk_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_qpsk_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
if(dlsch1_harq) {
|
||||
startSymbIdx = dlsch1_harq->start_symbol;
|
||||
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_slot_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;
|
||||
}
|
||||
else {
|
||||
nr_dlsch_qpsk_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128,
|
||||
beamforming_mode);
|
||||
} else if (codeword_TB0 == -1){
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[1],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream,
|
||||
beamforming_mode);
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_16qam_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_16qam_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_dlsch_16qam_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
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,
|
||||
pdsch_vars[eNB_id]->dl_valid_re[i-1],
|
||||
nr_slot_rx, beamforming_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
(int16_t*)pllr_symbol_cw0,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
} else if (codeword_TB0 == -1){
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw1,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_64qam_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_64qam_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_dlsch_64qam_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
(int16_t*)pllr_symbol_layer0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol]);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pllr_symbol_layer1,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dlsch1_harq) {
|
||||
uint8_t Qm = nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table);
|
||||
if (Qm == 0){
|
||||
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
|
||||
return -1;
|
||||
}
|
||||
switch (Qm) {
|
||||
case 2 :
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128,
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//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,
|
||||
dlsch[0]->harq_processes[harq_pid]->Nl,
|
||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||
dlsch[0]->harq_processes[harq_pid]->G,
|
||||
pdsch_vars[eNB_id]->layer_llr);
|
||||
}
|
||||
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr,
|
||||
dlsch[0]->harq_processes[harq_pid]->Nl,
|
||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||
dlsch[0]->harq_processes[harq_pid]->G,
|
||||
pdsch_vars[eNB_id]->layer_llr);
|
||||
}
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||
@@ -2367,7 +2082,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short nb_rb_pdsch,
|
||||
unsigned char nr_slot_rx,
|
||||
uint32_t high_speed_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms) {
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos) {
|
||||
|
||||
|
||||
|
||||
@@ -2375,7 +2091,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned char i,aarx; //,nsymb,sss_symb,pss_symb=0,l;
|
||||
int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext;
|
||||
|
||||
|
||||
int8_t validDmrsEst = 0; //store last DMRS Symbol index
|
||||
|
||||
unsigned char j=0;
|
||||
|
||||
@@ -2390,10 +2106,9 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
|
||||
k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb;
|
||||
|
||||
if (high_speed_flag == 1)
|
||||
dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))];
|
||||
else
|
||||
dl_ch0 = &dl_ch_estimates[aarx][0];
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol);
|
||||
|
||||
dl_ch0 = &dl_ch_estimates[aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))];
|
||||
|
||||
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(nb_rb_pdsch*12)];
|
||||
|
||||
@@ -2572,6 +2287,387 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
|
||||
AssertFatal(0, "Not supported number of layers %d\n", Nl);
|
||||
}
|
||||
}
|
||||
|
||||
static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t **rxdataF_comp_ptr,
|
||||
int32_t **dl_ch_mag_ptr,
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq,
|
||||
NR_DL_UE_HARQ_t *dlsch1_harq,
|
||||
RX_type_t rx_type,
|
||||
unsigned char harq_pid,
|
||||
unsigned char eNB_id,
|
||||
unsigned char eNB_id_i,
|
||||
unsigned char first_symbol_flag,
|
||||
unsigned char symbol,
|
||||
unsigned short nb_rb,
|
||||
unsigned short round,
|
||||
int32_t codeword_TB0,
|
||||
int32_t codeword_TB1,
|
||||
uint32_t len,
|
||||
uint8_t nr_slot_rx,
|
||||
uint8_t beamforming_mode)
|
||||
{
|
||||
|
||||
int16_t *pllr_symbol_cw0;
|
||||
int16_t *pllr_symbol_cw1;
|
||||
int16_t *pllr_symbol_layer0;
|
||||
int16_t *pllr_symbol_layer1;
|
||||
uint32_t llr_offset_symbol;
|
||||
|
||||
if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0;
|
||||
llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1];
|
||||
//pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0];
|
||||
//pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1];
|
||||
pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0];
|
||||
pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1];
|
||||
pllr_symbol_layer0 += llr_offset_symbol;
|
||||
pllr_symbol_layer1 += llr_offset_symbol;
|
||||
pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0];
|
||||
pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1];
|
||||
pllr_symbol_cw0 += llr_offset_symbol;
|
||||
pllr_symbol_cw1 += llr_offset_symbol;
|
||||
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol;
|
||||
|
||||
/*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
|
||||
symbol,
|
||||
nb_rb,dlsch0_harq->Qm,
|
||||
pdsch_vars[eNB_id]->llr_length[symbol],
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
(int16_t*)pdsch_vars[eNB_id]->llr[0],
|
||||
pllr_symbol_cw0);*/
|
||||
|
||||
/*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n",
|
||||
symbol,
|
||||
nb_rb,dlsch0_harq->Qm,
|
||||
pdsch_vars[eNB_id]->llr_length[symbol],
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pllr_symbol_cw0);*/
|
||||
|
||||
switch (dlsch0_harq->Qm) {
|
||||
case 2 :
|
||||
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
symbol,
|
||||
len,
|
||||
first_symbol_flag,
|
||||
nb_rb,
|
||||
beamforming_mode);
|
||||
|
||||
} else if (codeword_TB0 == -1){
|
||||
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw1,
|
||||
symbol,
|
||||
len,
|
||||
first_symbol_flag,
|
||||
nb_rb,
|
||||
beamforming_mode);
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_qpsk_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_qpsk_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_dlsch_qpsk_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_qpsk_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4 :
|
||||
if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128,
|
||||
beamforming_mode);
|
||||
} else if (codeword_TB0 == -1){
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[1],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream,
|
||||
beamforming_mode);
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_16qam_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_16qam_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_dlsch_16qam_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_16qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
(int16_t*)pllr_symbol_cw0,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
} else if (codeword_TB0 == -1){
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw1,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
}
|
||||
else if (rx_type >= rx_IC_single_stream) {
|
||||
if (dlsch1_harq->Qm == 2) {
|
||||
nr_dlsch_64qam_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_qpsk_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else if (dlsch1_harq->Qm == 4) {
|
||||
nr_dlsch_64qam_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
pdsch_vars[eNB_id]->layer_llr[0],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_16qam_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pdsch_vars[eNB_id]->layer_llr[1],
|
||||
symbol,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr128_2ndstream);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nr_dlsch_64qam_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
rxdataF_comp_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
dl_ch_mag_ptr,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
|
||||
(int16_t*)pllr_symbol_layer0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol]);
|
||||
if (rx_type==rx_IC_dual_stream) {
|
||||
nr_dlsch_64qam_64qam_llr(frame_parms,
|
||||
rxdataF_comp_ptr,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,//i
|
||||
dl_ch_mag_ptr,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,//i
|
||||
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
|
||||
pllr_symbol_layer1,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol),
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dlsch1_harq) {
|
||||
switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) {
|
||||
case 2 :
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_qpsk_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_16qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pdsch_vars[eNB_id]->llr[0],
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr128,
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
case 6 :
|
||||
if (rx_type==rx_standard) {
|
||||
nr_dlsch_64qam_llr(frame_parms,
|
||||
pdsch_vars[eNB_id]->rxdataF_comp0,
|
||||
pllr_symbol_cw0,
|
||||
pdsch_vars[eNB_id]->dl_ch_mag0,
|
||||
pdsch_vars[eNB_id]->dl_ch_magb0,
|
||||
symbol,len,first_symbol_flag,nb_rb,
|
||||
pdsch_vars[eNB_id]->llr_offset[symbol],
|
||||
beamforming_mode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//==============================================================================================
|
||||
|
||||
#ifdef USER_MODE
|
||||
|
||||
@@ -707,7 +707,8 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF,
|
||||
unsigned short nb_pdsch_rb,
|
||||
unsigned char nr_slot_rx,
|
||||
uint32_t high_speed_flag,
|
||||
NR_DL_FRAME_PARMS *frame_parms);
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dlDmrsSymbPos);
|
||||
|
||||
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
|
||||
int32_t **dl_ch_estimates,
|
||||
|
||||
@@ -318,6 +318,19 @@ typedef struct {
|
||||
uint8_t codeword;
|
||||
/// HARQ-ACKs
|
||||
NR_UE_HARQ_STATUS_t harq_ack;
|
||||
/// PTRS Frequency Density
|
||||
uint8_t PTRSFreqDensity;
|
||||
/// PTRS Time Density
|
||||
uint8_t PTRSTimeDensity;
|
||||
uint8_t PTRSPortIndex ;
|
||||
uint8_t nEpreRatioOfPDSCHToPTRS;
|
||||
uint8_t PTRSReOffset;
|
||||
/// bit mask of PT-RS ofdm symbol indicies
|
||||
uint16_t ptrs_symbols;
|
||||
// PTRS symbol index, to be updated every PTRS symbol within a slot.
|
||||
uint8_t ptrs_symbol_index;
|
||||
/// PDU BITMAP
|
||||
uint16_t pduBitmap;
|
||||
} NR_DL_UE_HARQ_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -386,12 +386,13 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
|
||||
printf("%d \n", harq_process->d[0][cnt]);
|
||||
}
|
||||
printf("\n");*/
|
||||
encoder_implemparams_t impp;
|
||||
impp.n_segments = harq_process->C;
|
||||
impp.tinput = NULL;
|
||||
impp.tprep = NULL;
|
||||
impp.tparity = NULL;
|
||||
impp.toutput = NULL;
|
||||
encoder_implemparams_t impp = {
|
||||
.n_segments=harq_process->C,
|
||||
.macro_num=0,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL};
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ typedef struct {
|
||||
/// bit mask of PT-RS ofdm symbol indicies
|
||||
uint16_t ptrs_symbols;
|
||||
// PTRS subcarriers per OFDM symbol
|
||||
uint16_t ptrs_sc_per_ofdm_symbol;
|
||||
int32_t ptrs_re_per_slot;
|
||||
/// \brief Estimated phase error based upon PTRS on each symbol .
|
||||
/// - first index: ? [0..7] Number of Antenna
|
||||
/// - second index: ? [0...14] smybol per slot
|
||||
|
||||
@@ -338,6 +338,10 @@ typedef struct {
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_DL[
|
||||
int32_t **dl_ch_estimates_ext;
|
||||
/// \brief Downlink channel estimates extracted in PRBS.
|
||||
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
|
||||
/// - second index: ? [0..168*N_RB_DL[
|
||||
int32_t **dl_ch_ptrs_estimates_ext;
|
||||
/// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round
|
||||
/// - first index: ? [0..7] (hard coded) accessed via \c harq_pid
|
||||
/// - second index: ? [0..7] (hard coded) accessed via \c round
|
||||
@@ -414,6 +418,16 @@ typedef struct {
|
||||
uint32_t llr_offset[14];
|
||||
// llr length per ofdm symbol
|
||||
uint32_t llr_length[14];
|
||||
// llr offset per ofdm symbol
|
||||
uint32_t dl_valid_re[14];
|
||||
/// \brief Estimated phase error based upon PTRS on each symbol .
|
||||
/// - first index: ? [0..7] Number of Antenna
|
||||
/// - second index: ? [0...14] smybol per slot
|
||||
int32_t **ptrs_phase_per_slot;
|
||||
/// \brief Estimated phase error based upon PTRS on each symbol .
|
||||
/// - first index: ? [0..7] Number of Antenna
|
||||
/// - second index: ? [0...14] smybol per slot
|
||||
int32_t **ptrs_re_per_slot;
|
||||
} NR_UE_PDSCH;
|
||||
|
||||
#define NR_PDCCH_DEFS_NR_UE
|
||||
@@ -889,7 +903,7 @@ typedef struct {
|
||||
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
||||
|
||||
/// PDSCH DMRS
|
||||
uint32_t nr_gold_pdsch[2][20][2][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD];
|
||||
uint32_t nr_gold_pdsch[2][20][14][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD];
|
||||
|
||||
/// PDCCH DMRS
|
||||
uint32_t nr_gold_pdcch[7][20][3][52];
|
||||
|
||||
@@ -108,9 +108,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id;
|
||||
dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame;
|
||||
dlsch0_harq->Nl=1;
|
||||
dlsch0_harq->mcs_table=0;
|
||||
dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
|
||||
dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
|
||||
dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
|
||||
/* PTRS */
|
||||
dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
|
||||
dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity;
|
||||
dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex;
|
||||
dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS;
|
||||
dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset;
|
||||
dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap;
|
||||
LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs);
|
||||
|
||||
}
|
||||
|
||||
@@ -733,8 +733,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
|
||||
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
|
||||
|
||||
// do channel estimation for first DMRS only
|
||||
for (m = s0; m < 3; m++) {
|
||||
for (m = s0; m < (s0 +s1); m++) {
|
||||
if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) {
|
||||
for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers
|
||||
nr_pdsch_channel_estimation(ue,
|
||||
@@ -752,12 +751,13 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
char filename[100];
|
||||
for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
|
||||
sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx);
|
||||
int **dl_ch_estimates = ue->pdsch_vars[ue->current_thread_id[nr_slot_rx]][0]->dl_ch_estimates;
|
||||
int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates;
|
||||
LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
if ( ue->high_speed_flag == 0 ) //for slow speed case only estimate the channel once per slot
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (m = s0; m < (s1 + s0); m++) {
|
||||
@@ -930,7 +930,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
uint8_t is_cw0_active = 0;
|
||||
uint8_t is_cw1_active = 0;
|
||||
uint8_t dmrs_type, nb_re_dmrs;
|
||||
uint16_t length_dmrs = 1;
|
||||
uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos);
|
||||
uint16_t nb_symb_sch = 9;
|
||||
nr_downlink_indication_t dl_indication;
|
||||
fapi_nr_rx_indication_t rx_ind;
|
||||
@@ -1016,7 +1016,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
dlsch0->harq_processes[harq_pid]->G = nr_get_G(dlsch0->harq_processes[harq_pid]->nb_rb,
|
||||
nb_symb_sch,
|
||||
nb_re_dmrs,
|
||||
length_dmrs,
|
||||
dmrs_len,
|
||||
dlsch0->harq_processes[harq_pid]->Qm,
|
||||
dlsch0->harq_processes[harq_pid]->Nl);
|
||||
#if UE_TIMING_TRACE
|
||||
@@ -1099,11 +1099,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
if(is_cw1_active)
|
||||
{
|
||||
// start ldpc decode for CW 1
|
||||
dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
|
||||
nb_symb_sch,
|
||||
nb_re_dmrs,
|
||||
length_dmrs,
|
||||
dlsch1->harq_processes[harq_pid]->Qm,
|
||||
dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb,
|
||||
nb_symb_sch,
|
||||
nb_re_dmrs,
|
||||
dmrs_len,
|
||||
dlsch1->harq_processes[harq_pid]->Qm,
|
||||
dlsch1->harq_processes[harq_pid]->Nl);
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_unscrambling_stats);
|
||||
@@ -1851,7 +1851,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
for (int i=0;i<4;i++) if (((1<<i)&dlsch0_harq->dlDmrsSymbPos) > 0) {symb_dmrs=i;break;}
|
||||
AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n");
|
||||
LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos);
|
||||
nr_gold_pdsch(ue,symb_dmrs,0, 1);
|
||||
nr_gold_pdsch(ue,0);
|
||||
|
||||
for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
|
||||
nr_slot_fep(ue,
|
||||
@@ -2019,7 +2019,7 @@ start_meas(&ue->generic_stat);
|
||||
|
||||
if(nr_slot_rx==5 && ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid]->nb_rb > 20){
|
||||
//write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
|
||||
//write_output("llr.m","llr", &ue->pdsch_vars[gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
//write_output("llr.m","llr", &ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
|
||||
|
||||
write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
|
||||
//write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
|
||||
@@ -2027,10 +2027,10 @@ start_meas(&ue->generic_stat);
|
||||
//write_output("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1);
|
||||
|
||||
write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1);
|
||||
write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[proc->thread_id][0]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
//write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[proc->thread_id][0]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
//write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[proc->thread_id][0]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
//write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
//write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1);
|
||||
|
||||
AssertFatal (0,"");
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -148,7 +148,8 @@ int is_x2ap_enabled(void)
|
||||
|
||||
// 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,int8_t *ptrs_arg);
|
||||
void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg);
|
||||
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of
|
||||
dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */
|
||||
@@ -255,6 +256,19 @@ int main(int argc, char **argv)
|
||||
int css_flag=0;
|
||||
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
int8_t enable_ptrs = 0;
|
||||
int8_t modify_dmrs = 0;
|
||||
|
||||
int8_t dmrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
|
||||
int8_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");
|
||||
@@ -266,7 +280,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:U:")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
scg_fd = fopen(optarg,"r");
|
||||
@@ -450,6 +464,20 @@ int main(int argc, char **argv)
|
||||
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;
|
||||
|
||||
case 'U':
|
||||
modify_dmrs = 1;
|
||||
for(i=0; i < atoi(optarg); i++) {
|
||||
dmrs_arg[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
|
||||
@@ -480,6 +508,8 @@ 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("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
|
||||
printf("-P Print DLSCH performances\n");
|
||||
printf("-w Write txdata to binary file (one frame)\n");
|
||||
exit (-1);
|
||||
@@ -490,6 +520,8 @@ int main(int argc, char **argv)
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
/* initialize the sin table */
|
||||
InitSinLUT();
|
||||
|
||||
get_softmodem_params()->phy_test = 1;
|
||||
|
||||
@@ -578,7 +610,17 @@ int main(int argc, char **argv)
|
||||
n_tx,
|
||||
0);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
|
||||
/* -U option modify DMRS */
|
||||
if(modify_dmrs) {
|
||||
update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg);
|
||||
}
|
||||
/* -T option enable PTRS */
|
||||
if(enable_ptrs) {
|
||||
update_ptrs_config(secondaryCellGroup, &rbSize, &mcsIndex, ptrs_arg);
|
||||
}
|
||||
|
||||
|
||||
//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;
|
||||
@@ -693,6 +735,9 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if(modify_dmrs) {
|
||||
update_dmrs_config( NULL,UE,dmrs_arg);
|
||||
}
|
||||
init_nr_ue_transport(UE,0);
|
||||
|
||||
nr_gold_pbch(UE);
|
||||
@@ -837,7 +882,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: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
|
||||
}
|
||||
if (run_initial_sync)
|
||||
nr_common_signal_procedures(gNB,frame,slot);
|
||||
else
|
||||
@@ -894,7 +954,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);
|
||||
@@ -907,6 +967,11 @@ 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,13 +999,17 @@ int main(int argc, char **argv)
|
||||
int16_t *UE_llr = pdsch_vars[0]->llr[0];
|
||||
|
||||
TBS = UE_harq_process->TBS;//rel15->TBSize[0];
|
||||
uint16_t length_dmrs = 1;
|
||||
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_rb = rel15->rbSize;
|
||||
uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
uint8_t mod_order = rel15->qamModOrder[0];
|
||||
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: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) );
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
@@ -992,7 +1061,7 @@ int main(int argc, char **argv)
|
||||
printf("*****************************************\n");
|
||||
printf("\n");
|
||||
dump_pdsch_stats(gNB);
|
||||
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
|
||||
printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
|
||||
printf("\n");
|
||||
|
||||
if (print_perf==1) {
|
||||
@@ -1102,3 +1171,79 @@ int main(int argc, char **argv)
|
||||
return(n_errors);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex, int8_t *ptrs_arg)
|
||||
{
|
||||
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(ptrs_arg[0] ==0) {
|
||||
ptrsTimeDenst[2]= *mcsIndex -1;
|
||||
}
|
||||
else if(ptrs_arg[0] == 1) {
|
||||
ptrsTimeDenst[1]= *mcsIndex - 1;
|
||||
ptrsTimeDenst[2]= *mcsIndex + 1;
|
||||
}
|
||||
else if(ptrs_arg[0] ==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(ptrs_arg[1] ==2) {
|
||||
ptrsFreqDenst[0]= *rbSize - 1;
|
||||
ptrsFreqDenst[1]= *rbSize + 1;
|
||||
}
|
||||
else if(ptrs_arg[1] == 4) {
|
||||
ptrsFreqDenst[1]= *rbSize - 1;
|
||||
}
|
||||
else {
|
||||
printf("[DLSIM] Wrong K_PTRS value, using default values 2\n");
|
||||
}
|
||||
printf("[DLSIM] PTRS Enabled with L %d, K %d \n", 1<<ptrs_arg[0], ptrs_arg[1] );
|
||||
/* overwrite the values */
|
||||
rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset);
|
||||
}
|
||||
|
||||
void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg)
|
||||
{
|
||||
int8_t mapping_type = typeA;//default value
|
||||
int8_t add_pos = pdsch_dmrs_pos0;//default value
|
||||
if(dmrs_arg[0] == 0) {
|
||||
mapping_type = typeA;
|
||||
}
|
||||
else if (dmrs_arg[0] == 1) {
|
||||
mapping_type = typeB;
|
||||
}
|
||||
/* Additional DMRS positions 0 ,1 and 2 */
|
||||
if(dmrs_arg[1] >= 0 && dmrs_arg[1] <3 ) {
|
||||
add_pos = dmrs_arg[1];
|
||||
}
|
||||
|
||||
if(scg != NULL) {
|
||||
NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0];
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = add_pos;
|
||||
for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) {
|
||||
bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type;
|
||||
}
|
||||
}
|
||||
if(ue != NULL) {
|
||||
for (int i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++) {
|
||||
ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type;
|
||||
}
|
||||
ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos;
|
||||
}
|
||||
printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] );
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
|
||||
@@ -163,8 +163,7 @@ int main(int argc, char **argv)
|
||||
FILE *input_fd = NULL;
|
||||
SCM_t channel_model = AWGN; //Rayleigh1_anticorr;
|
||||
uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1;
|
||||
double tx_gain=1.0;
|
||||
double N0=30;
|
||||
|
||||
NB_UE_INST = 1;
|
||||
|
||||
//unsigned char frame_type = 0;
|
||||
@@ -179,7 +178,6 @@ int main(int argc, char **argv)
|
||||
int gNB_id = 0;
|
||||
int ap;
|
||||
int tx_offset;
|
||||
double txlev_float;
|
||||
int32_t txlev;
|
||||
int start_rb = 0;
|
||||
int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
|
||||
@@ -199,6 +197,9 @@ int main(int argc, char **argv)
|
||||
int ptrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
|
||||
int dmrs_arg[2] = {-1,-1};// Invalid values
|
||||
uint16_t ptrsSymPos = 0;
|
||||
uint16_t ptrsSymbPerSlot = 0;
|
||||
uint16_t ptrsRePerSymb = 0;
|
||||
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
FILE *scg_fd=NULL;
|
||||
@@ -217,6 +218,9 @@ int main(int argc, char **argv)
|
||||
//logInit();
|
||||
randominit(0);
|
||||
|
||||
/* initialize the sin-cos table */
|
||||
InitSinLUT();
|
||||
|
||||
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
|
||||
printf("handling optarg %c\n",c);
|
||||
switch (c) {
|
||||
@@ -950,8 +954,6 @@ int main(int argc, char **argv)
|
||||
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
|
||||
|
||||
for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff;
|
||||
double scale = 1;
|
||||
|
||||
if (input_fd == NULL) {
|
||||
|
||||
// set FAPI parameters for UE, put them in the scheduled response and call
|
||||
@@ -974,20 +976,16 @@ int main(int argc, char **argv)
|
||||
|
||||
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
|
||||
txlev_float = (double)txlev/scale; // output of signal_energy is fixed point representation
|
||||
|
||||
|
||||
}
|
||||
else n_trials = 1;
|
||||
|
||||
if (input_fd == NULL ) {
|
||||
|
||||
sigma_dB = N0;
|
||||
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
|
||||
sigma = pow(10,sigma_dB/10);
|
||||
|
||||
tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/txlev_float);
|
||||
if(n_trials==1) printf("txlev_float %f, sigma_dB %f, tx_gain %f tx_offset %d, slot_offset %d\n",10*log10(txlev_float),sigma_dB,tx_gain,tx_offset,slot_offset);
|
||||
|
||||
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb));
|
||||
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (int aa=0; aa<1; aa++) {
|
||||
@@ -1006,8 +1004,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
|
||||
/* Add phase noise if enabled */
|
||||
if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
|
||||
@@ -1018,6 +1016,17 @@ int main(int argc, char **argv)
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
|
||||
set_ptrs_symb_idx(&ptrsSymPos,
|
||||
pusch_pdu->nr_of_symbols,
|
||||
pusch_pdu->start_symbol_index,
|
||||
1<<ptrs_time_density,
|
||||
pusch_pdu->ul_dmrs_symb_pos);
|
||||
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymPos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols);
|
||||
ptrsRePerSymb = ((pusch_pdu->rb_size + ptrs_freq_density - 1)/ptrs_freq_density);
|
||||
printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------
|
||||
@@ -1082,7 +1091,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
/* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
|
||||
available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
|
||||
printf("After PTRS subtraction available_bits are : %u \n", available_bits);
|
||||
printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
@@ -29,14 +29,43 @@
|
||||
/* linear phase noise model */
|
||||
void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
|
||||
{
|
||||
static uint64_t i=0;
|
||||
int32_t x=0 ,y=0;
|
||||
double fd = 300;//0.01*30000
|
||||
static double i=0;
|
||||
double real, imag,x ,y;
|
||||
int16_t SinValue = 0, CosValue= 0;
|
||||
double IdxDouble = (double)(i*fd * ts * ResolSinCos * 4);
|
||||
int16_t IdxModulo = ((int32_t)(IdxDouble>0 ? IdxDouble+0.5 : IdxDouble-0.5)) % (ResolSinCos*4);
|
||||
IdxModulo = IdxModulo<0 ? IdxModulo+ResolSinCos*4 : IdxModulo;
|
||||
|
||||
if(IdxModulo<2*ResolSinCos) {//< 2 check for 1st and 2nd
|
||||
if(IdxModulo < ResolSinCos) {// 1st Quadrant
|
||||
SinValue = LUTSin[IdxModulo];
|
||||
CosValue = LUTSin[ResolSinCos-IdxModulo];
|
||||
}
|
||||
else {// 2nd Quadrant
|
||||
SinValue = LUTSin[2*ResolSinCos-IdxModulo];
|
||||
CosValue = -LUTSin[IdxModulo-ResolSinCos];
|
||||
}
|
||||
}
|
||||
else {// 3rd and 4th Quadrant
|
||||
if(IdxModulo < 3*ResolSinCos) {// 3rd Quadrant
|
||||
SinValue = -LUTSin[IdxModulo-2*ResolSinCos];
|
||||
CosValue = -LUTSin[3*ResolSinCos-IdxModulo];
|
||||
}
|
||||
else {//4th Quadrant
|
||||
SinValue = -LUTSin[4*ResolSinCos-IdxModulo];
|
||||
CosValue = LUTSin[IdxModulo-3*ResolSinCos];
|
||||
}
|
||||
}
|
||||
x = ( ((int32_t)InRe[0] * CosValue) - ((int32_t)InIm[0] * SinValue ));
|
||||
y = ( ((int32_t)InIm[0] * CosValue) + ((int32_t)InRe[0] * SinValue ));
|
||||
InRe[0]= (int16_t)(x>>14);
|
||||
InIm[0]= (int16_t)(y>>14);
|
||||
i++;
|
||||
real = cos(fd * 2 * M_PI * i * ts);
|
||||
imag = sin (fd * 2 * M_PI * i * ts);
|
||||
x = ((real * (double)InRe[0]) - (imag * (double)InIm[0])) ;
|
||||
y= ((real * (double)InIm[0]) + (imag * (double)InRe[0])) ;
|
||||
InRe[0]= (int16_t)(x);
|
||||
InIm[0]= (int16_t)(y);
|
||||
}
|
||||
/* Initialisation function for SIN table values */
|
||||
void InitSinLUT( void ) {
|
||||
for ( int i=0; i<(ResolSinCos+1); i++ ) {
|
||||
LUTSin[i] = sin((double)(M_PI*i)/(2*ResolSinCos)) * (1<<14); //Format: Q14
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,6 +466,10 @@ double N_RB2channel_bandwidth(uint16_t N_RB);
|
||||
\param ts Sampling time
|
||||
\param *Re *Im Real and Imag part of the signal
|
||||
*/
|
||||
//look-up table for the sine (cosine) function
|
||||
#define ResolSinCos 100
|
||||
uint16_t LUTSin[ResolSinCos+1];
|
||||
void InitSinLUT( void );
|
||||
void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
|
||||
|
||||
#include "targets/RT/USER/rfsim.h"
|
||||
|
||||
@@ -1879,7 +1879,8 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
|
||||
}
|
||||
uint8_t N_sh_symb = pdsch_rel15->NrOfSymbols;
|
||||
uint8_t Imcs = pdsch_rel15->mcsIndex[0];
|
||||
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh;
|
||||
uint16_t dmrs_length = get_num_dmrs(pdsch_rel15->dlDmrsSymbPos);
|
||||
uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS*dmrs_length - N_PRB_oh;
|
||||
LOG_D(MAC, "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", N_RE_prime, N_sh_symb, N_PRB_DMRS, N_PRB_oh);
|
||||
|
||||
uint16_t R;
|
||||
@@ -1896,10 +1897,10 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
|
||||
|
||||
TBS = nr_compute_tbs(Qm,
|
||||
R,
|
||||
pdsch_rel15->rbSize,
|
||||
N_sh_symb,
|
||||
N_PRB_DMRS, // FIXME // This should be multiplied by the number of dmrs symbols
|
||||
N_PRB_oh,
|
||||
pdsch_rel15->rbSize,
|
||||
N_sh_symb,
|
||||
N_PRB_DMRS*dmrs_length,
|
||||
N_PRB_oh,
|
||||
tb_scaling,
|
||||
pdsch_rel15->nrOfLayers)>>3;
|
||||
|
||||
@@ -2784,6 +2785,8 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
|
||||
if (NrOfSymbols < 13 && *dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0 | 1<<8);
|
||||
if (*dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0);
|
||||
if (*dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<<l0 | 1<<10);
|
||||
if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<<l0);
|
||||
if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<<l0 | 1<<10);
|
||||
}
|
||||
}
|
||||
else if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB &&
|
||||
@@ -2846,3 +2849,72 @@ int binomial(int n, int k) {
|
||||
return c;
|
||||
}
|
||||
|
||||
/* extract PTRS values from RC and validate it based upon 38.214 5.1.6.3 */
|
||||
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||
uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable,
|
||||
uint8_t *K_ptrs, uint8_t *L_ptrs,
|
||||
uint8_t *portIndex,uint8_t *nERatio, uint8_t *reOffset,
|
||||
uint8_t NrOfSymbols)
|
||||
{
|
||||
bool valid = true;
|
||||
|
||||
/* as defined in T 38.214 5.1.6.3 */
|
||||
if(rbSize < 3) {
|
||||
valid = false;
|
||||
return valid;
|
||||
}
|
||||
/* Check for Frequency Density values */
|
||||
if(ptrs_config->frequencyDensity->list.count < 2) {
|
||||
/* Default value for K_PTRS = 2 as defined in T 38.214 5.1.6.3 */
|
||||
*K_ptrs = 2;
|
||||
}
|
||||
else {
|
||||
*K_ptrs = get_K_ptrs(*ptrs_config->frequencyDensity->list.array[0],
|
||||
*ptrs_config->frequencyDensity->list.array[1],
|
||||
rbSize);
|
||||
}
|
||||
/* Check for time Density values */
|
||||
if(ptrs_config->timeDensity->list.count < 3) {
|
||||
/* Default value for L_PTRS = 1 as defined in T 38.214 5.1.6.3 */
|
||||
*L_ptrs = 1;
|
||||
}
|
||||
else {
|
||||
*L_ptrs = get_L_ptrs(*ptrs_config->timeDensity->list.array[0],
|
||||
*ptrs_config->timeDensity->list.array[1],
|
||||
*ptrs_config->timeDensity->list.array[2],
|
||||
mcsIndex,
|
||||
mcsTable);
|
||||
}
|
||||
*portIndex =*ptrs_config->epre_Ratio;
|
||||
*nERatio = *ptrs_config->resourceElementOffset;
|
||||
*reOffset = 0;
|
||||
/* If either or both of the parameters PT-RS time density (LPT-RS) and PT-RS frequency density (KPT-RS), shown in Table
|
||||
* 5.1.6.3-1 and Table 5.1.6.3-2, indicates that 'PT-RS not present', the UE shall assume that PT-RS is not present
|
||||
*/
|
||||
if(*K_ptrs ==2 || *K_ptrs ==4 ) {
|
||||
valid = true;
|
||||
}
|
||||
else {
|
||||
valid = false;
|
||||
return valid;
|
||||
}
|
||||
if(*L_ptrs ==0 || *L_ptrs ==1 || *L_ptrs ==2 ) {
|
||||
valid = true;
|
||||
}
|
||||
else {
|
||||
valid = false;
|
||||
return valid;
|
||||
}
|
||||
/* PTRS is not present also :
|
||||
* When the UE is receiving a PDSCH with allocation duration of 4 symbols and if LPT-RS is set to 4, the UE shall assume
|
||||
* PT-RS is not transmitted
|
||||
* When the UE is receiving a PDSCH with allocation duration of 2 symbols as defined in Clause 7.4.1.1.2 of [4, TS
|
||||
* 38.211] and if LPT-RS is set to 2 or 4, the UE shall assume PT-RS is not transmitted.
|
||||
*/
|
||||
if((NrOfSymbols == 4 && *L_ptrs ==2) || ((NrOfSymbols == 2 && *L_ptrs > 0))) {
|
||||
valid = false;
|
||||
return valid;
|
||||
}
|
||||
//printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
|
||||
return valid;
|
||||
}
|
||||
|
||||
@@ -179,4 +179,10 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint
|
||||
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
|
||||
|
||||
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
|
||||
|
||||
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||
uint16_t rbSize, uint8_t mcsIndex, uint8_t mcsTable,
|
||||
uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex,
|
||||
uint8_t *nERatio,uint8_t *reOffset,
|
||||
uint8_t NrOfSymbols);
|
||||
#endif
|
||||
|
||||
@@ -3134,7 +3134,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
int mu = 0;
|
||||
long k2 = 0;
|
||||
uint16_t frame_tx = 0, slot_tx = 0;
|
||||
|
||||
bool valid_ptrs_setup = 0;
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request;
|
||||
fapi_nr_ul_config_request_t *ul_config = NULL;
|
||||
@@ -3925,6 +3925,19 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
|
||||
|
||||
dl_config->number_pdus = dl_config->number_pdus + 1;
|
||||
/* TODO same calculation for MCS table as done in UL */
|
||||
dlsch_config_pdu_1_1->mcs_table = 0;
|
||||
/*PTRS configuration */
|
||||
if(mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) {
|
||||
valid_ptrs_setup = set_dl_ptrs_values(mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup,
|
||||
dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table,
|
||||
&dlsch_config_pdu_1_1->PTRSFreqDensity,&dlsch_config_pdu_1_1->PTRSTimeDensity,
|
||||
&dlsch_config_pdu_1_1->PTRSPortIndex,&dlsch_config_pdu_1_1->nEpreRatioOfPDSCHToPTRS,
|
||||
&dlsch_config_pdu_1_1->PTRSReOffset, dlsch_config_pdu_1_1->number_symbols);
|
||||
if(valid_ptrs_setup==true) {
|
||||
dlsch_config_pdu_1_1->pduBitmap |= 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -453,6 +453,7 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
const int bwp_id = sched_ctrl->active_bwp->bwp_Id;
|
||||
const int nrOfLayers = 1;
|
||||
const int mcs = sched_ctrl->mcs;
|
||||
bool valid_ptrs_setup = false;
|
||||
|
||||
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
@@ -521,6 +522,19 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
scc->dmrs_TypeA_Position,
|
||||
pdsch_pdu_rel15->NrOfSymbols);
|
||||
|
||||
/* Check and validate PTRS values */
|
||||
if(bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) {
|
||||
valid_ptrs_setup = set_dl_ptrs_values(bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup,
|
||||
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->mcsIndex[0],
|
||||
pdsch_pdu_rel15->mcsTable[0],
|
||||
&pdsch_pdu_rel15->PTRSFreqDensity,&pdsch_pdu_rel15->PTRSTimeDensity,
|
||||
&pdsch_pdu_rel15->PTRSPortIndex,&pdsch_pdu_rel15->nEpreRatioOfPDSCHToPTRS,
|
||||
&pdsch_pdu_rel15->PTRSReOffset, pdsch_pdu_rel15->NrOfSymbols);
|
||||
if(valid_ptrs_setup==true) {
|
||||
pdsch_pdu_rel15->pduBitmap |=0x1;
|
||||
}
|
||||
}
|
||||
|
||||
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
|
||||
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET);
|
||||
|
||||
|
||||
@@ -119,6 +119,14 @@ void *rrc_gnb_task(void *args_p);
|
||||
/* Trigger RRC periodic processing. To be called once per ms. */
|
||||
void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe);
|
||||
|
||||
/**\ Function to set or overwrite PTRS DL RRC parameters.
|
||||
\ *bwp Pointer to dedicated RC config structure
|
||||
\ *ptrsNrb Pointer to K_ptrs N_RB related parameters
|
||||
\ *ptrsMcs Pointer to L_ptrs MCS related parameters
|
||||
\ *epre_Ratio Pointer to ep_ratio
|
||||
\ *reOffset Pointer to RE Offset Value */
|
||||
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset);
|
||||
|
||||
uint8_t
|
||||
nr_rrc_data_req(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -133,4 +141,3 @@ nr_rrc_data_req(
|
||||
int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
rnti_t rntiP);
|
||||
|
||||
|
||||
@@ -1276,5 +1276,37 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
|
||||
}
|
||||
/* Function to set or overwrite PTRS DL RRC parameters */
|
||||
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset)
|
||||
{
|
||||
int i=0;
|
||||
/* check for memory allocation */
|
||||
if(bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS == NULL) {
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup= calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = calloc(1,sizeof(long));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = calloc(1,sizeof(long));
|
||||
/* Fill the given values */
|
||||
for(i = 0; i < 2; i++) {
|
||||
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list,&ptrsNrb[i]);
|
||||
}
|
||||
for(i = 0; i < 3; i++) {
|
||||
ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list,&ptrsMcs[i]);
|
||||
}
|
||||
}// if memory exist then over write the old values
|
||||
else {
|
||||
for(i = 0; i < 2; i++) {
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] = ptrsNrb[i];
|
||||
}
|
||||
for(i = 0; i < 3; i++) {
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] = ptrsMcs[i];
|
||||
}
|
||||
}
|
||||
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = *epre_Ratio;
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = *reOffset;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user