/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file PHY/LTE_TRANSPORT/dlsch_modulation.c * \brief Top-level routines for generating the PDSCH physical channel from 36-211, V8.6 2009-03 * \author R. Knopp, F. Kaltenberger * \date 2011 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr * \note * \warning */ #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" //#define DEBUG_DLSCH_MODULATION //#define NEW_ALLOC_RE //#define is_not_pilot(pilots,re,nushift,use2ndpilots) ((pilots==0) || ((re!=nushift) && (re!=nushift+6)&&((re!=nushift+3)||(use2ndpilots==1))&&((re!=nushift+9)||(use2ndpilots==1)))?1:0) uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots) { uint8_t offset = (pilots==2)?3:0; int nushiftmod3 = nushift%3; if (pilots==0) return(1); if (use2ndpilots==1) { // This is for SISO (mode 1) if ((re!=nushift+offset) && (re!=((nushift+6+offset)%12))) return(1); } else { // 2 antenna pilots if ((re!=nushiftmod3) && (re!=nushiftmod3+6) && (re!=nushiftmod3+3) && (re!=nushiftmod3+9)) return(1); } return(0); } /*uint8_t is_not_UEspecRS(int first_layer,int re) { return(1); }*/ uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode) { uint8_t offset = (lprime==1||lprime==3)?2:0; if (lprime==-1) return(1); switch (beamforming_mode) { case 7: if (Ncp == NORMAL){ if ((re!=nushift+offset) && (re!=((nushift+4+offset)%12)) && (re!=((nushift+8+offset)%12))) return(1); /*else{ LOG_I(PHY,"(is_no_UEspec_RS):lprime=%d, re=%d, nushift=%d, offset=%d\n",lprime, re,nushift,offset); }*/ } else { if ((re!=nushift+offset) && (re!=((nushift+3+offset)%12)) && (re!=((nushift+6+offset)%12)) && (re!=((nushift+9+offset)%12))) return(1); } break; default: LOG_E(PHY,"is_not_UEspecRS() [dlsch_modulation.c] : ERROR, unknown beamforming_mode %d\n",beamforming_mode); return(-1); } return(0); } void layer1prec2A(int32_t *antenna0_sample, int32_t *antenna1_sample, uint8_t precoding_index) { switch (precoding_index) { case 0: // 1 1 *antenna1_sample=*antenna0_sample; break; case 1: // 1 -1 ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[0]; ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[1]; break; case 2: // 1 j ((int16_t *)antenna1_sample)[0] = -((int16_t *)antenna0_sample)[1]; ((int16_t *)antenna1_sample)[1] = ((int16_t *)antenna0_sample)[0]; break; case 3: // 1 -j ((int16_t *)antenna1_sample)[0] = ((int16_t *)antenna0_sample)[1]; ((int16_t *)antenna1_sample)[1] = -((int16_t *)antenna0_sample)[0]; break; } // normalize /* ((int16_t *)antenna0_sample)[0] = (int16_t)((((int16_t *)antenna0_sample)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)antenna0_sample)[1] = (int16_t)((((int16_t *)antenna0_sample)[1]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)antenna1_sample)[0] = (int16_t)((((int16_t *)antenna1_sample)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)antenna1_sample)[1] = (int16_t)((((int16_t *)antenna1_sample)[1]*ONE_OVER_SQRT2_Q15)>>15); */ } uint32_t FOUR[2]={0,4}; uint32_t TWO[2]={0,2}; int allocate_REs_in_RB_no_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qpsk_table_offset_re = 0; uint32_t qpsk_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re,last_re; last_re=12; first_re=0; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; re=first_re; if (skip_dc == 0) { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; re<last_re; re++,x0p+=2,tti_offset++) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; } } else { // 1st half of PRB for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; re<6; re++,x0p+=2,tti_offset++) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; } // 2nd half of PRB for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7; re<12; re++,x0p+=2,tti_offset++) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 6; *jj=*jj + 12; } else { *re_allocated = *re_allocated + 12; *jj=*jj + 24; } return(0); } int allocate_REs_in_RB_pilots_QPSK_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qpsk_table_offset_re = 0; uint32_t qpsk_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re,last_re; last_re=12; first_re=0; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // printf("pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; re<last_re; x0p+=2) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; // printf("pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } else { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; re<6; x0p+=2) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6]; re<12; x0p+=2) { qpsk_table_offset_re=x0p[0]; qpsk_table_offset_im=x0p[1]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qpsk_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qpsk_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 5; *jj=*jj + 10; } else { *re_allocated = *re_allocated + 10; *jj=*jj + 20; } return(0); } int allocate_REs_in_RB_no_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qam16_table_offset_re = 0; uint32_t qam16_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re,last_re; last_re=12; first_re=0; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; re=first_re; if (skip_dc == 0) { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; re<last_re; re++,x0p+=4,tti_offset++) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; } } else { // 1st half of PRB for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; re<6; re++,x0p+=4,tti_offset++) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; } // 2nd half of PRB for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7; re<12; re++,x0p+=4,tti_offset++) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 6; *jj=*jj + 24; } else { *re_allocated = *re_allocated + 12; *jj=*jj + 48; } return(0); } int allocate_REs_in_RB_pilots_16QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qam16_table_offset_re = 0; uint32_t qam16_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re,last_re; last_re=12; first_re=0; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; re<last_re; x0p+=4) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; // LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } else { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; re<6; x0p+=4) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6]; re<12; x0p+=4) { qam16_table_offset_re=TWO[x0p[0]]; qam16_table_offset_im=TWO[x0p[1]]; qam16_table_offset_re+=x0p[2]; qam16_table_offset_im+=x0p[3]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam16_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 5; *jj=*jj + 20; } else { *re_allocated = *re_allocated + 10; *jj=*jj + 40; } return(0); } int allocate_REs_in_RB_no_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qam64_table_offset_re = 0; uint32_t qam64_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re; first_re=0; if (skip_half==2) first_re=6; re=first_re; if (skip_dc == 0) { x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; /* for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; re<12; re+=4,x0p+=24,tti_offset+=4) {*/ qam64_table_offset_re=(x0p[0]<<2)|(x0p[2]<<1)|x0p[4]; qam64_table_offset_im=(x0p[1]<<2)|(x0p[3]<<1)|x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[6]<<2)|(x0p[8]<<1)|x0p[10]; qam64_table_offset_im=(x0p[7]<<2)|(x0p[9]<<1)|x0p[11]; ((int16_t *)&txdataF[0][tti_offset])[2]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[3]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[12]<<2)|(x0p[14]<<1)|x0p[16]; qam64_table_offset_im=(x0p[13]<<2)|(x0p[15]<<1)|x0p[17]; ((int16_t *)&txdataF[0][tti_offset])[4]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[5]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[18]<<2)|(x0p[20]<<1)|x0p[22]; qam64_table_offset_im=(x0p[19]<<2)|(x0p[21]<<1)|x0p[23]; ((int16_t *)&txdataF[0][tti_offset])[6]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[7]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[24]<<2)|(x0p[26]<<1)|x0p[28]; qam64_table_offset_im=(x0p[25]<<2)|(x0p[27]<<1)|x0p[29]; ((int16_t *)&txdataF[0][tti_offset])[8]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[9]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[30]<<2)|(x0p[32]<<1)|x0p[34]; qam64_table_offset_im=(x0p[31]<<2)|(x0p[33]<<1)|x0p[35]; ((int16_t *)&txdataF[0][tti_offset])[10]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[11]=qam_table_s0[qam64_table_offset_im]; if(skip_half==0) { qam64_table_offset_re=(x0p[36]<<2)|(x0p[38]<<1)|x0p[40]; qam64_table_offset_im=(x0p[37]<<2)|(x0p[39]<<1)|x0p[41]; ((int16_t *)&txdataF[0][tti_offset])[12]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[13]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[42]<<2)|(x0p[44]<<1)|x0p[46]; qam64_table_offset_im=(x0p[43]<<2)|(x0p[45]<<1)|x0p[47]; ((int16_t *)&txdataF[0][tti_offset])[14]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[15]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[48]<<2)|(x0p[50]<<1)|x0p[52]; qam64_table_offset_im=(x0p[49]<<2)|(x0p[51]<<1)|x0p[53]; ((int16_t *)&txdataF[0][tti_offset])[16]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[17]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[54]<<2)|(x0p[56]<<1)|x0p[58]; qam64_table_offset_im=(x0p[55]<<2)|(x0p[57]<<1)|x0p[59]; ((int16_t *)&txdataF[0][tti_offset])[18]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[19]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[60]<<2)|(x0p[62]<<1)|x0p[64]; qam64_table_offset_im=(x0p[61]<<2)|(x0p[63]<<1)|x0p[65]; ((int16_t *)&txdataF[0][tti_offset])[20]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[21]=qam_table_s0[qam64_table_offset_im]; qam64_table_offset_re=(x0p[66]<<2)|(x0p[68]<<1)|x0p[70]; qam64_table_offset_im=(x0p[67]<<2)|(x0p[69]<<1)|x0p[71]; ((int16_t *)&txdataF[0][tti_offset])[22]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[23]=qam_table_s0[qam64_table_offset_im]; } // } } else { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset,re=0; re<6; re++,x0p+=6,tti_offset++) { qam64_table_offset_re=FOUR[x0p[0]]; qam64_table_offset_im=FOUR[x0p[1]]; qam64_table_offset_re+=TWO[x0p[2]]; qam64_table_offset_im+=TWO[x0p[3]]; qam64_table_offset_re+=x0p[4]; qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; } for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+7; re<12; re++,x0p+=6,tti_offset++) { qam64_table_offset_re=FOUR[x0p[0]]; qam64_table_offset_im=FOUR[x0p[1]]; qam64_table_offset_re+=TWO[x0p[2]]; qam64_table_offset_im+=TWO[x0p[3]]; qam64_table_offset_re+=x0p[4]; qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 6; *jj=*jj + 36; } else { *re_allocated = *re_allocated + 12; *jj=*jj + 72; } return(0); } int allocate_REs_in_RB_pilots_64QAM_siso(PHY_VARS_eNB* phy_vars_eNB, int **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->frame_parms; uint8_t *x0 = dlsch0_harq->e; uint32_t qam64_table_offset_re = 0; uint32_t qam64_table_offset_im = 0; uint32_t tti_offset; uint8_t re; uint8_t *x0p; uint8_t first_re,last_re; last_re=12; first_re=0; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; re=first_re+P1_SHIFT[0]; if (skip_dc == 0) { // LOG_I(PHY,"pilots: P1_SHIFT[0] %d\n",P1_SHIFT[0]); for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+re; re<last_re; x0p+=6) { qam64_table_offset_re=FOUR[x0p[0]]; qam64_table_offset_im=FOUR[x0p[1]]; qam64_table_offset_re+=TWO[x0p[2]]; qam64_table_offset_im+=TWO[x0p[3]]; qam64_table_offset_re+=x0p[4]; qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; // LOG_I(PHY,"pilots: re %d, tti_offset %d, P1_SHIFT %d\n",re,tti_offset,P1_SHIFT[re+1]); tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } else { for (x0p=&x0[*jj],tti_offset=symbol_offset+re_offset+P1_SHIFT[0],re=P1_SHIFT[0]; re<6; x0p+=6) { qam64_table_offset_re=FOUR[x0p[0]]; qam64_table_offset_im=FOUR[x0p[1]]; qam64_table_offset_re+=TWO[x0p[2]]; qam64_table_offset_im+=TWO[x0p[3]]; qam64_table_offset_re+=x0p[4]; qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } for (tti_offset=symbol_offset+re_offset-frame_parms->ofdm_symbol_size+6+P1_SHIFT[6]; re<12; x0p+=6) { qam64_table_offset_re=FOUR[x0p[0]]; qam64_table_offset_im=FOUR[x0p[1]]; qam64_table_offset_re+=TWO[x0p[2]]; qam64_table_offset_im+=TWO[x0p[3]]; qam64_table_offset_re+=x0p[4]; qam64_table_offset_im+=x0p[5]; ((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s0[qam64_table_offset_im]; tti_offset+=P1_SHIFT[re+1]; re+=P1_SHIFT[re+1]; } } if(skip_half!=0) { *re_allocated = *re_allocated + 5; *jj=*jj + 30; } else { *re_allocated = *re_allocated + 10; *jj=*jj + 60; } return(0); } int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, int32_t **txdataF, uint32_t *jj, uint32_t *jj2, uint16_t re_offset, uint32_t symbol_offset, LTE_DL_eNB_HARQ_t *dlsch0_harq, LTE_DL_eNB_HARQ_t *dlsch1_harq, uint8_t pilots, int16_t amp, uint8_t precoder_index, int16_t *qam_table_s0, int16_t *qam_table_s1, uint32_t *re_allocated, uint8_t skip_dc, uint8_t skip_half, uint8_t lprime, uint8_t mprime, uint8_t Ns, int *P1_SHIFT, int *P2_SHIFT) { uint8_t *x0 = NULL; MIMO_mode_t mimo_mode = -1; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; int first_layer0 = -1; //= dlsch0_harq->first_layer; int Nlayers0 = -1; // = dlsch0_harq->Nlayers; uint8_t mod_order0=0; uint8_t mod_order1=0; uint8_t precoder_index0,precoder_index1; uint8_t *x1=NULL; // Fill these in later for TM8-10 // int Nlayers1; // int first_layer1; int use2ndpilots = (frame_parms->nb_antenna_ports_eNB==1)?1:0; uint32_t tti_offset; //,aa; uint8_t re; 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; uint8_t qam64_table_offset_re0 = 0; uint8_t qam64_table_offset_im0 = 0; uint8_t qam16_table_offset_re0 = 0; uint8_t qam16_table_offset_im0 = 0; uint8_t qam64_table_offset_re1 = 0; uint8_t qam64_table_offset_im1 = 0; uint8_t qam16_table_offset_re1 = 0; uint8_t qam16_table_offset_im1 = 0; int16_t xx0_re,xx1_re; int16_t xx0_im,xx1_im; int16_t gain_lin_QPSK;//,gain_lin_16QAM1,gain_lin_16QAM2; int16_t re_off=re_offset; uint8_t first_re,last_re; int32_t tmp_sample1,tmp_sample2; int16_t tmp_amp=amp; int s=1; int mprime2 = mprime,ind,ind_dword,ind_qpsk_symb; gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); int32_t qpsk[4]; ((int16_t *)&qpsk[0])[0] = gain_lin_QPSK; ((int16_t *)&qpsk[0])[1] = gain_lin_QPSK; ((int16_t *)&qpsk[1])[0] = -gain_lin_QPSK; ((int16_t *)&qpsk[1])[1] = gain_lin_QPSK;; ((int16_t *)&qpsk[2])[0] = gain_lin_QPSK;; ((int16_t *)&qpsk[2])[1] = -gain_lin_QPSK;; ((int16_t *)&qpsk[3])[0] = -gain_lin_QPSK;; ((int16_t *)&qpsk[3])[1] = -gain_lin_QPSK; if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4 x0 = dlsch0_harq->e; mimo_mode = dlsch0_harq->mimo_mode; first_layer0 = dlsch0_harq->first_layer; Nlayers0 = dlsch0_harq->Nlayers; mod_order0 = dlsch0_harq->Qm; x1 = dlsch1_harq->e; // Fill these in later for TM8-10 // Nlayers1 = dlsch1_harq->Nlayers; // first_layer1 = dlsch1_harq->first_layer; mod_order1 = dlsch1_harq->Qm; } else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc x0 = dlsch0_harq->e; mimo_mode = dlsch0_harq->mimo_mode; first_layer0 = dlsch0_harq->first_layer; Nlayers0 = dlsch0_harq->Nlayers; mod_order0 = dlsch0_harq->Qm; } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission x0 = dlsch1_harq->e; mimo_mode = dlsch1_harq->mimo_mode; first_layer0 = dlsch1_harq->first_layer; Nlayers0 = dlsch1_harq->Nlayers; mod_order0 = dlsch1_harq->Qm; } if (dlsch0_harq != NULL){ #ifdef DEBUG_DLSCH_MODULATION LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); #endif } else{ #ifdef DEBUG_DLSCH_MODULATION LOG_I(PHY,"allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); #endif } first_re=0; last_re=12; if (skip_half==1) last_re=6; else if (skip_half==2) first_re=6; for (re=first_re; re<last_re; re++) { // LOG_I(PHY,"element %d precoder_index for allocation %d\n",re, precoder_index ); if ((skip_dc == 1) && (re==6)) re_off=re_off - frame_parms->ofdm_symbol_size+1; tti_offset = symbol_offset + re_off + re; //check that RE is not from Cell-specific RS if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) { //LOG_I(PHY,"re %d (jj %d)\n",re,*jj); if (mimo_mode == SISO) { //SISO mapping *re_allocated = *re_allocated + 1; switch (mod_order0) { case 2: //QPSK //LOG_I(PHY,"re %d %d(%d) : %d,%d => ",re,tti_offset,*jj,((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; 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_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; 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_s0[qam64_table_offset_re]; ((int16_t *)&txdataF[0][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im]; break; } } else if (mimo_mode == ALAMOUTI) { *re_allocated = *re_allocated + 1; amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); switch (mod_order0) { case 2: //QPSK // first antenna position n -> x0 ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj=*jj+1; ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj=*jj+1; // second antenna position n -> -x1* ((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK; *jj=*jj+1; ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj=*jj+1; //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore // normalization for 2 tx antennas ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0])); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1])); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0])); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1])); break; case 4: //16QAM // Antenna 0 position n 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]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]); ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]); // Antenna 1 position n Real part -> -x1* 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[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam16_table_offset_re]); ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]); //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; break; case 6: // 64-QAM // Antenna 0 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]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]); ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]); // Antenna 1 => -x1* 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[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam64_table_offset_re]); ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]); break; } // fill in the rest of the ALAMOUTI precoding if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) { ((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 ((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; ((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* ((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; } else { ((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 ((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; ((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* ((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; } } else if (mimo_mode == LARGE_CDD) { *re_allocated = *re_allocated + 1; if (frame_parms->nb_antenna_ports_eNB == 2) { switch (mod_order0) { default: LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0); xx0_re=xx0_im=0; break; case 2: //QPSK //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; case 4: //16QAM qam16_table_offset_re0 = 0; qam16_table_offset_im0 = 0; if (x0[*jj] == 1) qam16_table_offset_re0+=2; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im0+=2; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_re0+=1; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im0+=1; *jj=*jj+1; xx0_re = qam_table_s0[qam16_table_offset_re0]; xx0_im = qam_table_s0[qam16_table_offset_im0]; break; case 6: //64QAM qam64_table_offset_re0 = 0; qam64_table_offset_im0 = 0; if (x0[*jj] == 1) qam64_table_offset_re0+=4; *jj=*jj+1; if (x0[*jj] == 1) qam64_table_offset_im0+=4; *jj=*jj+1; if (x0[*jj] == 1) qam64_table_offset_re0+=2; *jj=*jj+1; if (x0[*jj] == 1) qam64_table_offset_im0+=2; *jj=*jj+1; if (x0[*jj] == 1) qam64_table_offset_re0+=1; *jj=*jj+1; if (x0[*jj] == 1) qam64_table_offset_im0+=1; *jj=*jj+1; xx0_re = qam_table_s0[qam64_table_offset_re0]; xx0_im = qam_table_s0[qam64_table_offset_im0]; break; } switch (mod_order1) { default: LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1); xx1_re=xx1_im=0; break; case 2: //QPSK //LOG_I(PHY,"%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; case 4: //16QAM qam16_table_offset_re1 = 0; qam16_table_offset_im1 = 0; if (x1[*jj2] == 1) qam16_table_offset_re1+=2; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam16_table_offset_im1+=2; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam16_table_offset_re1+=1; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam16_table_offset_im1+=1; *jj2 = *jj2 + 1; xx1_re = qam_table_s1[qam16_table_offset_re1]; xx1_im = qam_table_s1[qam16_table_offset_im1]; break; case 6: //64QAM qam64_table_offset_re1 = 0; qam64_table_offset_im1 = 0; if (x1[*jj2] == 1) qam64_table_offset_re1+=4; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam64_table_offset_im1+=4; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam64_table_offset_re1+=2; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam64_table_offset_im1+=2; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam64_table_offset_re1+=1; *jj2 = *jj2 + 1; if (x1[*jj2] == 1) qam64_table_offset_im1+=1; *jj2 = *jj2 + 1; xx1_re = qam_table_s1[qam64_table_offset_re1]; xx1_im = qam_table_s1[qam64_table_offset_im1]; break; } // This implements the Large CDD precoding for 2 TX antennas // - - - - - - - - - - - - //| y0 | | 1 0 || 1 0 || 1 1 || x0 | | x0 + x1 | //| y1 | = .5 | 0 1 || 0 (-1)^i || 1 -1 || x1 | = .5| (-1)^i(x0 - x1)| // - - - - - - - - - - - // Note: Factor .5 is accounted for in amplitude when calling this function ((int16_t *)&txdataF[0][tti_offset])[0]+=((xx0_re+xx1_re)>>1); ((int16_t *)&txdataF[1][tti_offset])[0]+=(s*((xx0_re-xx1_re)>>1)); ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1); ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1)); /* LOG_I(PHY,"CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n", xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1], ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]); */ // s alternates +1/-1 for each RE s = -s; } } else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { // this is for transmission modes 5-6 (1 layer) *re_allocated = *re_allocated + 1; amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); switch (mod_order0) { case 2: ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; //normalization for 2 tx antennas /*((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); }*/ // We remove ONE_OVER_SQRT2_Q15 that was coming from precoder, as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; case 4: 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*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; case 6: 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*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; } } else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) { // this is for transmission mode 4 (1 layer) *re_allocated = *re_allocated + 1; if (precoder_index==0) { precoder_index0 = 0; //[1 1] precoder_index1 = 1; //[1 -1] } else if (precoder_index==1) { precoder_index0 = 2; //[1 j] precoder_index1 = 3; //[1 -j] } else { LOG_I(PHY,"problem with precoder in TM4\n"); return(-1); } switch (mod_order0) { case 2: ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; //normalization for 2 tx antennas // We remove ONE_OVER_2_Q15 that was coming from precoder, //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function //ONE_OVER_SQRT2_Q15 remains from it ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); //LOG_I(PHY,"%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; case 4: 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*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); // We remove ONE_OVER_2_Q15 that was coming from precoder, //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function //ONE_OVER_SQRT2_Q15 remains from it ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; case 6: 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*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; } if (dlsch1_harq) { switch (mod_order1) { case 2: ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; //normalization for 2 tx antennas ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB== 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; case 4: qam16_table_offset_re = 0; qam16_table_offset_im = 0; if (x1[*jj2] == 1) qam16_table_offset_re+=2; *jj2=*jj2+1; if (x1[*jj2] == 1) qam16_table_offset_im+=2; *jj2=*jj2+1; if (x1[*jj2] == 1) qam16_table_offset_re+=1; *jj2=*jj2+1; if (x1[*jj2] == 1) qam16_table_offset_im+=1; *jj2=*jj2+1; ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; case 6: qam64_table_offset_re = 0; qam64_table_offset_im = 0; if (x1[*jj2] == 1) qam64_table_offset_re+=4; *jj2=*jj2+1; if (x1[*jj2] == 1) qam64_table_offset_im+=4; *jj2=*jj2+1; if (x1[*jj2] == 1) qam64_table_offset_re+=2; *jj2=*jj2+1; if (x1[*jj2] == 1) qam64_table_offset_im+=2; *jj2=*jj2+1; if (x1[*jj2] == 1) qam64_table_offset_re+=1; *jj2=*jj2+1; if (x1[*jj2] == 1) qam64_table_offset_im+=1; *jj2=*jj2+1; ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; } } } if (mimo_mode == ALAMOUTI) { re++; // adjacent carriers are taken care of by precoding *re_allocated = *re_allocated + 1; if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==0) { re++; *re_allocated = *re_allocated + 1; } } if (mimo_mode == TM7) { *re_allocated = *re_allocated + 1; if (is_not_UEspecRS(lprime,re,frame_parms->Nid_cell%3,frame_parms->Ncp,7)) { switch (mod_order0){ case 2: //QPSK ((int16_t*)&txdataF[5][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; ((int16_t*)&txdataF[5][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj = *jj + 1; //LOG_I(PHY,"%d(%d) : %d,%d => //",tti_offset,*jj,((int16_t*)&tmp_sample1)[0],((int16_t*)&tmp_sample1)[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[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); ((int16_t*)&txdataF[5][tti_offset])[1] = (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[5][tti_offset])[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); ((int16_t*)&txdataF[5][tti_offset])[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); break; } } else { //precoding UE spec RS //LOG_I(PHY,"precoding UE spec RS\n"); ind = 3*lprime*dlsch0_harq->nb_rb+mprime2; ind_dword = ind>>4; ind_qpsk_symb = ind&0xf; txdataF[5][tti_offset] = qpsk[(phy_vars_eNB->lte_gold_uespec_port5_table[0][Ns][ind_dword]>>(2*ind_qpsk_symb))&3]; mprime2++; } } else if (mimo_mode >= TM8) { //TM8,TM9,TM10 //uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode) if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) { switch (mod_order0) { case 2: //QPSK // LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) { ((int16_t*)&txdataF[layer][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; ((int16_t*)&txdataF[layer][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} *jj = *jj + 1; } break; case 4: //16QAM if (is_not_UEspecRS(lprime,re,frame_parms->nushift,frame_parms->Ncp,8)) { 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; for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) { ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam16_table_offset_re]; ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam16_table_offset_im]; } } 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; for (int layer=first_layer0; layer<=(first_layer0+Nlayers0); layer++) { ((int16_t*)&txdataF[layer][tti_offset])[0] = qam_table_s0[qam64_table_offset_re]; ((int16_t*)&txdataF[layer][tti_offset])[1] = qam_table_s0[qam64_table_offset_im]; } break; } } } else if (mimo_mode>=TM9_10) { LOG_I(PHY,"allocate_REs_in_RB() [dlsch.c] : ERROR, unknown mimo_mode %d\n",mimo_mode); return(-1); } } } return(0); } int allocate_REs_in_RB_MCH(int32_t **txdataF, uint32_t *jj, uint16_t re_offset, uint32_t symbol_offset, uint8_t *x0, uint8_t l, 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; 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 (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; } for (re=first_re; re<last_re; re+=inc) { if ((skip_dc == 1) && (re==(6+first_re))) re_off=re_off - frame_parms->ofdm_symbol_size+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_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); ((int16_t*)&txdataF[4][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i *jj = *jj + 1; ((int16_t*)&txdataF[4][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} *jj = *jj + 1; //LOG_I(PHY,"%d,%d\n",((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[4][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[4][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[4][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[4][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); } inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline)); inline int check_skip(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) { if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL // PBCH if ((subframe_offset==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { return(1); } if (frame_parms->frame_type == TDD) { // TDD //SSS TDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1)) ) { return(1); } //PSS TDD if (((subframe_offset==1) || (subframe_offset==6)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==2) ) { return(1); } } else { //PSS FDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-1)) ) { return(1); } //SSS FDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) { return(1); } } } else { // even N_RB_DL //PBCH if ((subframe_offset==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) return(1); if (frame_parms->frame_type == TDD) { // TDD //SSS if (((subframe_offset==0)|| (subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==nsymb-1) ) { return(1); } //PSS if (((subframe_offset==1)|| (subframe_offset==6)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==2) ) { return(1); } } else { // FDD //SSS if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-2)) ) { return(1); } //PSS if (((subframe_offset==0)||(subframe_offset==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==((nsymb>>1)-1)) ) { return(1); } } } return(0); } inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) __attribute__((always_inline)); inline int check_skiphalf(int rb,int subframe_offset,LTE_DL_FRAME_PARMS *frame_parms,int l,int nsymb) { // LOG_I(PHY,"check_skiphalf : rb %d, subframe_offset %d,l %d, nsymb %d\n",rb,subframe_offset,l,nsymb); if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL // PBCH if ((subframe_offset==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) return(1); else if ((subframe_offset==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) return(2); if (frame_parms->frame_type == TDD) { // TDD //SSS TDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==(nsymb-1))) return(1); else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(nsymb-1))) return(2); //PSS TDD if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==2)) return(1); else if (((subframe_offset==1)||(subframe_offset==6)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==2)) return(2); } else { // FDD //PSS FDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==((nsymb>>1)-1))) return(1); else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==(((nsymb>>1)-1)))) return(2); //SSS FDD if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && ((l==((nsymb>>1)-2)))) return(1); else if (((subframe_offset==0)||(subframe_offset==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && ((l==(nsymb>>1)-2))) return(2); } } else { // EVEN N_RB_DL return(0); } return(0); } inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) __attribute__((always_inline)); inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) { if (((frame_parms->N_RB_DL&1) == 1) && // odd N_RB_DL, rb==N_RB_DL/2 PRB contains DC element (rb==(frame_parms->N_RB_DL>>1))) return(1); else return(0); } int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, int32_t **txdataF, int16_t amp, int frame, uint32_t subframe_offset, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, LTE_eNB_DLSCH_t *dlsch1) { LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; uint8_t nsymb; uint8_t harq_pid = -1; //= dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL; LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; //= dlsch1->harq_processes[harq_pid]; uint32_t i,i2,jj,jj2,re_allocated,symbol_offset; uint16_t l,rb,re_offset; uint32_t rb_alloc_ind; uint32_t *rb_alloc = NULL; //=dlsch0_harq->rb_alloc; uint8_t pilots=0; uint8_t skip_dc,skip_half; uint8_t mod_order0 = 0; uint8_t mod_order1 = 0; int16_t amp_rho_a, amp_rho_b; int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8],qpsk_table_a0[2],qpsk_table_b0[2]; int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8],qpsk_table_a1[2],qpsk_table_b1[2]; int16_t *qam_table_s0=NULL,*qam_table_s1=NULL; int (*allocate_REs)(PHY_VARS_eNB*, int **, uint32_t*, uint32_t*, uint16_t, uint32_t, LTE_DL_eNB_HARQ_t *, LTE_DL_eNB_HARQ_t *, uint8_t, int16_t, uint8_t, int16_t *, int16_t *, uint32_t *, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int *, int *); int P1_SHIFT[13],P2_SHIFT[13]; int offset,nushiftmod3; uint8_t get_pmi_temp; MIMO_mode_t mimo_mode = -1; uint8_t mprime=0,Ns; int8_t lprime=-1; int aa=0; #ifdef DEBUG_DLSCH_MODULATION uint8_t Nl0; //= dlsch0_harq->Nl; uint8_t Nl1; #endif int ru_id; RU_t *ru; int eNB_id; if ((dlsch0 != NULL) && (dlsch1 != NULL)){ harq_pid = dlsch0->harq_ids[frame%2][subframe_offset]; if(harq_pid >= dlsch0->Mdlharq) { LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); return(-1); } dlsch0_harq = dlsch0->harq_processes[harq_pid]; mimo_mode = dlsch0_harq->mimo_mode; mod_order0 = dlsch0_harq->Qm; rb_alloc = dlsch0_harq->rb_alloc; #ifdef DEBUG_DLSCH_MODULATION Nl0 = dlsch0_harq->Nl; #endif dlsch1_harq = dlsch1->harq_processes[harq_pid]; mod_order1 = dlsch1_harq->Qm; #ifdef DEBUG_DLSCH_MODULATION Nl1 = dlsch1_harq->Nl; #endif }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){ harq_pid = dlsch0->harq_ids[frame%2][subframe_offset]; if(harq_pid >= dlsch0->Mdlharq) { LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); return(-1); } dlsch0_harq = dlsch0->harq_processes[harq_pid]; mimo_mode = dlsch0_harq->mimo_mode; mod_order0 = dlsch0_harq->Qm; rb_alloc = dlsch0_harq->rb_alloc; #ifdef DEBUG_DLSCH_MODULATION Nl0 = dlsch0_harq->Nl; #endif dlsch1_harq = NULL; mod_order1 = 0; #ifdef DEBUG_DLSCH_MODULATION Nl1 = 0; #endif }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){ harq_pid = dlsch1->harq_ids[frame%2][subframe_offset]; if(harq_pid >= dlsch1->Mdlharq) { LOG_E(PHY,"illegal harq_pid %d\n", harq_pid); return(-1); } dlsch1_harq = dlsch1->harq_processes[harq_pid]; mimo_mode = dlsch1_harq->mimo_mode; mod_order0 = dlsch1_harq->Qm; rb_alloc = dlsch1_harq->rb_alloc; #ifdef DEBUG_DLSCH_MODULATION Nl0 = dlsch1_harq->Nl; #endif dlsch0_harq = NULL; mod_order1 = 0; #ifdef DEBUG_DLSCH_MODULATION Nl1 = NULL; #endif } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN); nsymb = (frame_parms->Ncp==0) ? 14:12; if (dlsch0 != NULL){ amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); //amp=512 in full scale; dlsch0->sqrt_rho_a=8192in Q2.13, 1 in full scale amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13); } else{ amp_rho_a = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_a)>>13); amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); } if(mod_order0 == 2) { for(i=0;i<2;i++) { qpsk_table_a0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15); qpsk_table_b0[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15); } } else if (mod_order0 == 4) for (i=0;i<4; i++) { qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_b0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); } else if (mod_order0 == 6) for (i=0; i<8; i++) { qam64_table_a0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_a)>>15); qam64_table_b0[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15); } if (mod_order1 == 2) { for (i=0; i<2; i++) { qpsk_table_a1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_a)>>15); qpsk_table_b1[i] = (int16_t)(((int32_t)qpsk_table[i]*amp_rho_b)>>15); } } else if (mod_order1 == 4) for (i=0; i<4; i++) { qam16_table_a1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); qam16_table_b1[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_b)>>15); } else if (mod_order1 == 6) for (i=0; i<8; i++) { qam64_table_a1[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_a)>>15); qam64_table_b1[i] = (int16_t)(((int32_t)qam64_table[i]*amp_rho_b)>>15); } //Modulation mapping (difference w.r.t. LTE specs) jj=0; jj2=0; re_allocated=0; // LOG_I(PHY,"num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); for (l=num_pdcch_symbols; l<nsymb; l++) { if (dlsch0 != NULL ) { #ifdef DEBUG_DLSCH_MODULATION LOG_I(PHY,"Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d)\n", harq_pid, dlsch0_harq->mimo_mode, pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), mod_order0, mod_order1, rb_alloc[0] ); #endif } if (frame_parms->Ncp==0) { // normal prefix if ((l==4)||(l==11)) pilots=2; // pilots in nushift+3, nushift+9 else if (l==7) pilots=1; // pilots in nushift, nushift+6 else pilots=0; } else { if ((l==3)||(l==9)) pilots=2; else if (l==6) pilots=1; else pilots=0; } if(mimo_mode==TM7){ //36.211 V8.6.0 2009-03 mprime = 0; if (frame_parms->Ncp==0) { // normal prefix if (l==12) lprime=3; // pilots in nushift+3, nushift+9 else if (l==9) lprime=2; // pilots in nushift, nushift+6 else if (l==6) lprime=1; // pilots in nushift+3, nushift+9 else if (l==3) lprime=0; // pilots in nushift, nushift+6 else lprime=-1; } else { if (l==10) lprime=2; else if (l==7) lprime=1; else if (l==4) lprime=0; else lprime=-1; } // mapping ue specific beamforming weights from UE specified DLSCH structure to RU beam weights for the eNB for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { ru = RC.ru[ru_id]; for (eNB_id=0;eNB_id<ru->num_eNB;eNB_id++){ if (phy_vars_eNB == ru->eNB_list[eNB_id]) { for (aa=0;aa<ru->nb_tx;aa++){ LOG_I(PHY,"ru_id:%d eNB_id:%d aa:%d memcpy(ru->beam_weights, dlsch0->ue_spec_bf_weights[ru_id][0],)\n", ru_id, eNB_id, aa); memcpy(ru->beam_weights[eNB_id][5][aa], dlsch0->ue_spec_bf_weights[ru_id][0], frame_parms->ofdm_symbol_size*sizeof(int32_t)); } } } } } Ns = 2*subframe_offset+(l>=(nsymb>>1)); offset = (pilots==2)?3:0; nushiftmod3 = frame_parms->nushift%3; if (pilots>0) { // compute pilot arrays, could be done statically if performance suffers if (frame_parms->nb_antenna_ports_eNB == 1) { // LOG_I(PHY,"l %d, nushift %d, offset %d\n",l,frame_parms->nushift,offset); for (i=0,i2=0;i<12;i++) { if ((i!=(frame_parms->nushift+offset)) && (i!=((frame_parms->nushift+6+offset)%12))) P1_SHIFT[i2++]=1; else P1_SHIFT[i2++]=2; } P1_SHIFT[0]--; } else { for (i=0,i2=0;i<12;i++) { if ((i!=nushiftmod3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+3) && (i!=nushiftmod3+9)) P2_SHIFT[i2++]=1; else P2_SHIFT[i2++]=2; } P2_SHIFT[0]--; } } P1_SHIFT[12]=1;P2_SHIFT[12]=1; re_offset = frame_parms->first_carrier_offset; symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); allocate_REs = allocate_REs_in_RB; switch (mod_order0) { case 2: qam_table_s0 = NULL; if (pilots) { qam_table_s0 = qpsk_table_b0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_QPSK_siso : allocate_REs_in_RB; } else { qam_table_s0 = qpsk_table_a0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_QPSK_siso : allocate_REs_in_RB; } break; case 4: if (pilots) { qam_table_s0 = qam16_table_b0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_16QAM_siso : allocate_REs_in_RB; } else { qam_table_s0 = qam16_table_a0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_16QAM_siso : allocate_REs_in_RB; } break; case 6: if (pilots) { qam_table_s0 = qam64_table_b0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_64QAM_siso : allocate_REs_in_RB; } else { qam_table_s0 = qam64_table_a0; allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_64QAM_siso : allocate_REs_in_RB; } /* TODO: this is a quick hack to be removed. There is a problem * with above code that needs to be analyzed and fixed. In the * meantime, let's use the generic function. */ //allocate_REs = allocate_REs_in_RB; break; } /* TODO: hack, to be removed. The power is too different from * previous version. Some more work/validation is needed before * we switch to the new version. */ //if (frame_parms->N_RB_DL==25) //allocate_REs = allocate_REs_in_RB; switch (mod_order1) { case 2: qam_table_s1 = NULL; allocate_REs = allocate_REs_in_RB; if (pilots) { qam_table_s1 = qpsk_table_b1; } else { qam_table_s1 = qpsk_table_a1; } break; case 4: if (pilots) { qam_table_s1 = qam16_table_b1; } else { qam_table_s1 = qam16_table_a1; } break; case 6: if (pilots) { qam_table_s1 = qam64_table_b1; } else { qam_table_s1 = qam64_table_a1; } break; } //for (aa=0;aa<frame_parms->nb_antennas_tx;aa++) //memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2); //LOG_I(PHY,"symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots); for (rb=0; rb<frame_parms->N_RB_DL; rb++) { if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; else if (rb < 96) rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; else if (rb < 100) rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; else rb_alloc_ind = 0; if (check_skip(rb,subframe_offset,frame_parms,l,nsymb)==1) rb_alloc_ind = 0; skip_half = check_skiphalf(rb,subframe_offset,frame_parms,l,nsymb); skip_dc = check_skip_dc(rb,frame_parms); if (dlsch0) { if (dlsch0_harq->Nlayers>1) { LOG_E(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); return(-1); } } if (dlsch1) { if (dlsch1_harq->Nlayers>1) { LOG_I(PHY,"Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); return(-1); } } if (rb_alloc_ind > 0) { // LOG_I(PHY,"Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); if (dlsch0 != NULL) { get_pmi_temp = get_pmi(frame_parms->N_RB_DL, dlsch0->harq_processes[harq_pid]->mimo_mode, dlsch0->harq_processes[harq_pid]->pmi_alloc, rb); } else get_pmi_temp = get_pmi(frame_parms->N_RB_DL, dlsch1->harq_processes[harq_pid]->mimo_mode, dlsch1->harq_processes[harq_pid]->pmi_alloc, rb); allocate_REs(phy_vars_eNB, txdataF, &jj, &jj2, re_offset, symbol_offset, (dlsch0 == NULL) ? NULL : dlsch0->harq_processes[harq_pid], (dlsch1 == NULL) ? NULL : dlsch1->harq_processes[harq_pid], pilots, ((pilots) ? amp_rho_b : amp_rho_a), get_pmi_temp, qam_table_s0, qam_table_s1, &re_allocated, skip_dc, skip_half, lprime, mprime, Ns, P1_SHIFT, P2_SHIFT); if ((mimo_mode == TM7) && (lprime>=0)) mprime +=3+frame_parms->Ncp; } else { // LOG_I(PHY,"Unallocated rb %d/symbol %d, re_offset %d, jj %d\n",rb,l,re_offset,jj); } re_offset+=12; // go to next RB // check if we crossed the symbol boundary and skip DCs if (re_offset >= frame_parms->ofdm_symbol_size) { if (skip_dc == 0) //even number of RBs (doesn't straddle DC) re_offset=1; else re_offset=7; // odd number of RBs } } } #ifdef DEBUG_DLSCH_MODULATION if (dlsch0 != NULL){ LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1)); }else{ LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset,1)); } #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT); return (re_allocated); } int dlsch_modulation_SIC(int32_t **sic_buffer, uint32_t subframe_offset, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, int G) { AssertFatal(1==0,"This function needs to be reintegrated ...\n"); uint8_t harq_pid = -1;//dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; uint32_t i,jj,re_allocated=0; uint8_t mod_order0 = dlsch0_harq->Qm; uint8_t *x0 = dlsch0_harq->e; 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; #ifdef DEBUG_DLSCH_MODULATION uint8_t Nl0 = dlsch0_harq->Nl; uint8_t Nl1; #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN); gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); jj = 0; i = 0; while (jj <= G-1) { re_allocated = re_allocated + 1; switch (mod_order0) { case 2: //QPSK ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i jj = jj + 1; ((int16_t*)&sic_buffer[0][i])[1] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} jj = jj + 1; //LOG_I(PHY,"recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); i++; 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 *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im]; i++; break; case 6: 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 *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); i++; break; } } #ifdef DEBUG_DLSCH_MODULATION LOG_I(PHY,"generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset,1/*transmission mode*/)); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT); return (re_allocated); } int mch_modulation(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 = 12; 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=2; l<nsymb_pmch; l++) { #ifdef DEBUG_DLSCH_MODULATION LOG_I(PHY,"Generating MCH (mod %d) in subframe %d for symbol %d\n",mod_order, subframe_offset,l); #endif re_offset = frame_parms->first_carrier_offset; symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); for (rb=0; rb<frame_parms->N_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(txdataF, &jj, re_offset, symbol_offset, dlsch->harq_processes[0]->e, l, mod_order, amp, qam_table_s, &re_allocated, skip_dc, frame_parms); re_offset+=12; // go to next RB // check if we crossed the symbol boundary and skip DC if (re_offset >= frame_parms->ofdm_symbol_size) { if (skip_dc == 0) //even number of RBs (doesn't straddle DC) re_offset=1; else re_offset=7; // 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*/)); #endif return (re_allocated); }