From 3d11b3d65dd794942bf5540dc578b854c3f2dc93 Mon Sep 17 00:00:00 2001 From: Javier Morgade Date: Mon, 20 Jul 2020 10:51:51 +0200 Subject: [PATCH] fembms: FeMBMS (eNB) Top-level routines for generating the PDSCH physical channel from 36-211 V14.1 Signed-off-by: Javier Morgade --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 261 +++++++++++++++++- 1 file changed, 259 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 475c8bd521..eeb701657a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -20,12 +20,12 @@ */ /*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c - * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03 + * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03, V14.1 2017 (FeMBMS) * \author R. Knopp, F. Kaltenberger * \date 2011 * \version 0.1 * \company Eurecom - * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, javier.morgade@ieee.irg * \note * \warning */ @@ -2910,3 +2910,260 @@ int mch_modulation(int32_t **txdataF, return (re_allocated); } + +int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF, + uint32_t *jj, + uint16_t re_offset, + uint32_t symbol_offset, + uint8_t *x0, + uint8_t subframe, + uint8_t mod_order, + int16_t amp, + int16_t *qam_table_s, + uint32_t *re_allocated, + uint8_t skip_dc, + LTE_DL_FRAME_PARMS *frame_parms) +{ + uint32_t tti_offset; + uint8_t re,offset; + uint8_t qam64_table_offset_re = 0; + uint8_t qam64_table_offset_im = 0; + uint8_t qam16_table_offset_re = 0; + uint8_t qam16_table_offset_im = 0; + int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2; + int16_t re_off=re_offset; + gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); + uint8_t first_re,last_re; + int inc; +#ifdef DEBUG_DLSCH_MODULATION + LOG_I(PHY,"allocate_re_MCH khz_1dot25 (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]); +#endif + + /*last_re=12; + first_re=0; + inc=1; + + if ((l==2)||(l==10)) { + inc=2; + first_re=1; + } else if (l==6) { + inc=2; + }*/ + last_re=144; //12*12 + if ((subframe&0x1)==0){ // n_sf mod 2 == 0: even + first_re=1; + offset=0; + }else{ + first_re=0; + offset=3; + } + inc=1; + + for (re=first_re; reofdm_symbol_size_khz_1dot25+1; + } + + tti_offset = symbol_offset + re_off + re; + + //LOG_I(PHY,"re %d (jj %d)\n",re,*jj); + *re_allocated = *re_allocated + 1; + + + switch (mod_order) { + + case 2: //QPSK + + LOG_D(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + ((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i + + *jj = *jj + 1; + + ((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + + *jj = *jj + 1; + + LOG_D(PHY,"subframe%d alloc[%d][%d][%d](%d,%d)\n",subframe,tti_offset,symbol_offset,tti_offset-symbol_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + break; + + + case 4: //16QAM + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + + *jj=*jj+1; + + + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + break; + + case 6: //64QAM + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + + *jj=*jj+1; + + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + + *jj=*jj+1; + + ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + break; + + } + } + return(0); +} + +int mch_modulation_khz_1dot25(int32_t **txdataF, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + LTE_eNB_DLSCH_t *dlsch) +{ + uint8_t nsymb,nsymb_pmch; + uint32_t i,jj,re_allocated,symbol_offset; + uint16_t l,rb,re_offset; + uint8_t skip_dc=0; + uint8_t mod_order = dlsch->harq_processes[0]->Qm; + int16_t qam16_table_a[4],qam64_table_a[8];//,qam16_table_b[4],qam64_table_b[8]; + int16_t *qam_table_s; + + nsymb_pmch = 1; + nsymb = (frame_parms->Ncp == NORMAL) ? 14 : 12; + + if (mod_order == 4) + for (i=0; i<4; i++) { + qam16_table_a[i] = (int16_t)(((int32_t)qam16_table[i]*amp)>>15); + } + else if (mod_order == 6) + for (i=0; i<8; i++) { + qam64_table_a[i] = (int16_t)(((int32_t)qam64_table[i]*amp)>>15); + } + + jj=0; + re_allocated=0; + + + + + + // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); + for (l=0; lfirst_carrier_offset_khz_1dot25; + symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); + + for (rb=0; rbN_RB_DL; rb++) { + + + if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL + + if (rb==(frame_parms->N_RB_DL>>1)) + skip_dc = 1; + else + skip_dc = 0; + + } + + if (mod_order == 4) + qam_table_s = qam16_table_a; + else if (mod_order == 6) + qam_table_s = qam64_table_a; + else + qam_table_s = NULL; + + //LOG_I(PHY,"Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); + allocate_REs_in_RB_MCH_khz_1dot25(txdataF, + &jj, + re_offset, + symbol_offset, + dlsch->harq_processes[0]->eDL, + subframe_offset, + mod_order, + amp, + qam_table_s, + &re_allocated, + skip_dc, + frame_parms); + + re_offset+=144; // go to next RB 12*12 + + // check if we crossed the symbol boundary and skip DC + if (re_offset >= frame_parms->ofdm_symbol_size_khz_1dot25) { + if (skip_dc == 0) //even number of RBs (doesn't straddle DC) + re_offset=1; + else + re_offset=73; // odd number of RBs + } + } + } + +#ifdef DEBUG_DLSCH_MODULATION + LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset,1/*transmission mode*/)); + LOG_I(PHY,"generate_dlsch(MCH) : jj = %d,re_allocated = %d\n",jj,re_allocated); +#endif + + return (re_allocated); +} +