/* * 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.0 (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/dci.c * \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03. * \author R. Knopp * \date 2011 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr * \note * \warning */ #ifdef USER_MODE #include #include #include #endif #include "PHY/defs.h" #include "PHY/extern.h" #include "SCHED/defs.h" #include "SIMULATION/TOOLS/defs.h" // for taus #include "PHY/sse_intrin.h" #include "assertions.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 //#define DEBUG_PHY //#undef ALL_AGGREGATION //extern uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3]; //extern uint16_t pcfich_reg[4]; uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t lprime,uint8_t mi) { uint16_t i; uint16_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; uint16_t mprime; uint16_t *pcfich_reg = frame_parms->pcfich_reg; if ((lprime>0) && (frame_parms->Ncp==0) ) return(0); // printf("check_phich_reg : mi %d\n",mi); // compute REG based on symbol if ((lprime == 0)|| ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) mprime = kprime/6; else mprime = kprime>>2; // check if PCFICH uses mprime if ((lprime==0) && ((mprime == pcfich_reg[0]) || (mprime == pcfich_reg[1]) || (mprime == pcfich_reg[2]) || (mprime == pcfich_reg[3]))) { #ifdef DEBUG_DCI_ENCODING printf("[PHY] REG %d allocated to PCFICH\n",mprime); #endif return(1); } // handle Special subframe case for TDD !!! // printf("Checking phich_reg %d\n",mprime); if (mi > 0) { if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) Ngroup_PHICH++; if (frame_parms->Ncp == 1) { Ngroup_PHICH<<=1; } for (i=0; iphich_reg[i][0]) || (mprime == frame_parms->phich_reg[i][1]) || (mprime == frame_parms->phich_reg[i][2])) { #ifdef DEBUG_DCI_ENCODING printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime); #endif return(1); } } } return(0); } uint16_t extract_crc(uint8_t *dci,uint8_t dci_len) { uint16_t crc16; // uint8_t i; /* uint8_t crc; crc = ((uint16_t *)dci)[DCI_LENGTH>>4]; printf("crc1: %x, shift %d (DCI_LENGTH %d)\n",crc,DCI_LENGTH&0xf,DCI_LENGTH); crc = (crc>>(DCI_LENGTH&0xf)); // clear crc bits ((uint16_t *)dci)[DCI_LENGTH>>4] &= (0xffff>>(16-(DCI_LENGTH&0xf))); printf("crc2: %x, dci0 %x\n",crc,((int16_t *)dci)[DCI_LENGTH>>4]); crc |= (((uint16_t *)dci)[1+(DCI_LENGTH>>4)])<<(16-(DCI_LENGTH&0xf)); // clear crc bits (((uint16_t *)dci)[1+(DCI_LENGTH>>4)]) = 0; printf("extract_crc: crc %x\n",crc); */ #ifdef DEBUG_DCI_DECODING LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)], dci_len&0x7); #endif if ((dci_len&0x7) > 0) { ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]<<(dci_len&0x7) | dci[2+(dci_len>>3)]>>(8-(dci_len&0x7)); ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]<<(dci_len&0x7) | dci[1+(dci_len>>3)]>>(8-(dci_len&0x7)); } else { ((uint8_t *)&crc16)[0] = dci[1+(dci_len>>3)]; ((uint8_t *)&crc16)[1] = dci[(dci_len>>3)]; } #ifdef DEBUG_DCI_DECODING LOG_I(PHY,"dci_crc =>%x\n",crc16); #endif // dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf)); // dci[(dci_len>>3)+1] = 0; // dci[(dci_len>>3)+2] = 0; return((uint16_t)crc16); } static uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96]; static uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)]; void dci_encoding(uint8_t *a, uint8_t A, uint16_t E, uint8_t *e, uint16_t rnti) { uint8_t D = (A + 16); uint32_t RCC; #ifdef DEBUG_DCI_ENCODING int32_t i; #endif // encode dci #ifdef DEBUG_DCI_ENCODING printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti); #endif memset((void *)d,LTE_NULL,96); ccodelte_encode(A,2,a,d+96,rnti); #ifdef DEBUG_DCI_ENCODING for (i=0; i<16+A; i++) printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i))); #endif #ifdef DEBUG_DCI_ENCODING printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e); #endif RCC = sub_block_interleaving_cc(D,d+96,w); #ifdef DEBUG_DCI_ENCODING printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e); #endif lte_rate_matching_cc(RCC,E,w,e); } uint8_t *generate_dci0(uint8_t *dci, uint8_t *e, uint8_t DCI_LENGTH, uint8_t aggregation_level, uint16_t rnti) { uint16_t coded_bits; uint8_t dci_flip[8]; if (aggregation_level>3) { printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level); return NULL; } coded_bits = 72 * (1< %x,%x,%x,%x,%x,%x,%x,%x\n", dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3], dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]); #endif } dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti); return(e+coded_bits); } uint32_t Y; #define CCEBITS 72 #define CCEPERSYMBOL 33 // This is for 1200 RE #define CCEPERSYMBOL0 22 // This is for 1200 RE #define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS) #define Msymb (DCI_BITS_MAX/2) //#define Mquad (Msymb/4) static uint32_t bitrev_cc_dci[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30}; static int32_t wtemp[2][Msymb]; void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) { int32_t *wptr,*wptr2,*zptr; uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi); uint32_t RCC = (Mquad>>5), ND; uint32_t row,col,Kpi,index; int32_t i,k,a; #ifdef RM_DEBUG int32_t nulled=0; #endif // printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch); if ((Mquad&0x1f) > 0) RCC++; Kpi = (RCC<<5); ND = Kpi - Mquad; k=0; for (col=0; col<32; col++) { index = bitrev_cc_dci[col]; for (row=0; row=ND) { for (a=0; anb_antenna_ports_eNB; a++) { //printf("a %d k %d\n",a,k); wptr = &wtemp[a][k<<2]; zptr = &z[a][(index-ND)<<2]; //printf("wptr=%p, zptr=%p\n",wptr,zptr); wptr[0] = zptr[0]; wptr[1] = zptr[1]; wptr[2] = zptr[2]; wptr[3] = zptr[3]; } k++; } index+=32; } } // permutation for (i=0; inb_antenna_ports_eNB; a++) { //wptr = &wtemp[a][i<<2]; //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; wptr2 = &wbar[a][i<<2]; wptr2[0] = wptr[0]; wptr2[1] = wptr[1]; wptr2[2] = wptr[2]; wptr2[3] = wptr[3]; } } } void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parms,uint8_t num_pdcch_symbols,uint8_t mi) { uint32_t i, lprime; uint16_t kprime,kprime_mod12,mprime,symbol_offset,tti_offset,tti_offset0; int16_t re_offset,re_offset0; // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 int Msymb2; switch (frame_parms->N_RB_DL) { case 100: Msymb2 = Msymb; break; case 75: Msymb2 = 3*Msymb/4; break; case 50: Msymb2 = Msymb>>1; break; case 25: Msymb2 = Msymb>>2; break; case 15: Msymb2 = Msymb*15/100; break; case 6: Msymb2 = Msymb*6/100; break; default: Msymb2 = Msymb>>2; break; } mprime=0; re_offset = 0; re_offset0 = 0; // counter for symbol with pilots (extracted outside!) for (kprime=0; kprimeN_RB_DL*12; kprime++) { for (lprime=0; lprimeN_RB_DL*12*lprime; tti_offset = symbol_offset + re_offset; tti_offset0 = symbol_offset + re_offset0; // if REG is allocated to PHICH, skip it if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) { // printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime); if ((lprime == 0)&&((kprime%6)==0)) re_offset0+=4; } else { // not allocated to PHICH/PCFICH // printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2); if (lprime == 0) { // first symbol, or second symbol+4 TX antennas skip pilots kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { // kprime represents REG for (i=0; i<4; i++) { wbar[mprime] = llr[tti_offset0+i]; #ifdef DEBUG_DCI_DECODING LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); #endif mprime++; re_offset0++; } } } else if ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4)) { // LATER!!!! } else { // no pilots in this symbol kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) { // kprime represents REG for (i=0; i<4; i++) { wbar[mprime] = llr[tti_offset+i]; #ifdef DEBUG_DCI_DECODING LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime])); #endif mprime++; } } // is representative } // no pilots case } // not allocated to PHICH/PCFICH // Stop when all REGs are copied in if (mprime>=Msymb2) break; } //lprime loop re_offset++; } // kprime loop } static uint16_t wtemp_rx[Msymb]; void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t *wbar,uint8_t number_pdcch_symbols,uint8_t mi) { uint16_t *wptr,*zptr,*wptr2; uint16_t Mquad=get_nquad(number_pdcch_symbols,frame_parms,mi); uint32_t RCC = (Mquad>>5), ND; uint32_t row,col,Kpi,index; int32_t i,k; // printf("Mquad %d, RCC %d\n",Mquad,RCC); if (!z) { printf("dci.c: pdcch_deinterleaving: FATAL z is Null\n"); return; } // undo permutation for (i=0; iNid_cell)%Mquad)<<2]; wptr2 = &wbar[i<<2]; wptr[0] = wptr2[0]; wptr[1] = wptr2[1]; wptr[2] = wptr2[2]; wptr[3] = wptr2[3]; /* printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad, ((char*)wptr2)[0], ((char*)wptr2)[1], ((char*)wptr2)[2], ((char*)wptr2)[3], ((char*)wptr2)[4], ((char*)wptr2)[5], ((char*)wptr2)[6], ((char*)wptr2)[7]); */ } if ((Mquad&0x1f) > 0) RCC++; Kpi = (RCC<<5); ND = Kpi - Mquad; k=0; for (col=0; col<32; col++) { index = bitrev_cc_dci[col]; for (row=0; row=ND) { wptr = &wtemp_rx[k<<2]; zptr = &z[(index-ND)<<2]; zptr[0] = wptr[0]; zptr[1] = wptr[1]; zptr[2] = wptr[2]; zptr[3] = wptr[3]; /* printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND), ((int8_t *)wptr)[0], ((int8_t *)wptr)[1], ((int8_t *)wptr)[2], ((int8_t *)wptr)[3], ((int8_t *)wptr)[4], ((int8_t *)wptr)[5], ((int8_t *)wptr)[6], ((int8_t *)wptr)[7]); */ k++; } index+=32; } } for (i=0; i (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, ((int8_t *)zptr)[0], ((int8_t *)zptr)[1], ((int8_t *)zptr)[2], ((int8_t *)zptr)[3], ((int8_t *)zptr)[4], ((int8_t *)zptr)[5], ((int8_t *)zptr)[6], ((int8_t *)zptr)[7]); */ } } int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int32_t **rxdataF_comp_i, int32_t **rho_i, int16_t *pdcch_llr16, int16_t *pdcch_llr8in, uint8_t symbol) { int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; int16_t *llr128; int32_t i; char *pdcch_llr8; int16_t *pdcch_llr; pdcch_llr8 = (char *)&pdcch_llr8in[symbol*frame_parms->N_RB_DL*12]; pdcch_llr = &pdcch_llr16[symbol*frame_parms->N_RB_DL*12]; // printf("dlsch_qpsk_qpsk: symbol %d\n",symbol); llr128 = (int16_t*)pdcch_llr; if (!llr128) { printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol); return -1; } qpsk_qpsk(rxF, rxF_i, llr128, rho, frame_parms->N_RB_DL*12); //prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input. for (i=0; i<(frame_parms->N_RB_DL*24); i++) { if (*pdcch_llr>7) *pdcch_llr8=7; else if (*pdcch_llr<-8) *pdcch_llr8=-8; else *pdcch_llr8 = (char)(*pdcch_llr); pdcch_llr++; pdcch_llr8++; } return(0); } int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, char *pdcch_llr, uint8_t symbol) { int16_t *rxF= (int16_t*) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; int32_t i; char *pdcch_llr8; pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; if (!pdcch_llr8) { printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); return(-1); } // printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr); for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) { if (*rxF>31) *pdcch_llr8=31; else if (*rxF<-32) *pdcch_llr8=-32; else *pdcch_llr8 = (char)(*rxF); // printf("%d %d => %d\n",i,*rxF,*pdcch_llr8); rxF++; pdcch_llr8++; } return(0); } //__m128i avg128P; //compute average channel_level on each (TX,RX) antenna pair void pdcch_channel_level(int32_t **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, int32_t *avg, uint8_t nb_rb) { int16_t rb; uint8_t aatx,aarx; #if defined(__x86_64__) || defined(__i386__) __m128i *dl_ch128; __m128i avg128P; #elif defined(__arm__) int16x8_t *dl_ch128; int32x4_t *avg128P; #endif for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) for (aarx=0; aarxnb_antennas_rx; aarx++) { //clear average level #if defined(__x86_64__) || defined(__i386__) avg128P = _mm_setzero_si128(); dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12]; #elif defined(__arm__) #endif for (rb=0; rbnb_antennas_rx; aarx++) { #if defined(__x86_64__) || defined(__i386__) dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) #endif for (rb=0; rbN_RB_DL; rb++) { // multiply by conjugated channel #if defined(__x86_64__) || defined(__i386__) mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]); // print_ints("re",&mmtmpPD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); // print_ints("im",&mmtmpPD1); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); // print_ints("re(shift)",&mmtmpPD0); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); // print_ints("im(shift)",&mmtmpPD1); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); // print_ints("c0",&mmtmpPD2); // print_ints("c1",&mmtmpPD3); dl_ch_rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2); //print_shorts("ch:",dl_ch128); //print_shorts("pack:",rho128); // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[1]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); dl_ch_rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2+1); //print_shorts("ch:",dl_ch128+1); //print_shorts("pack:",rho128+1); // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128i[2]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); dl_ch_rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rho128+2); dl_ch128+=3; dl_ch128i+=3; dl_ch_rho128+=3; #elif defined(__arm__) #endif } } #if defined(__x86_64__) || defined(__i386__) _mm_empty(); _m_empty(); #endif } void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int32_t **rxdataF_comp_i, int32_t **rho, int32_t **rho_i, uint8_t symbol) { uint8_t aatx; #if defined(__x86_64__) || defined(__i386__) __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; #elif defined(__arm__) int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; #endif int32_t i; if (frame_parms->nb_antennas_rx>1) { for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { //if (frame_parms->mode1_flag && (aatx>0)) break; #if defined(__x86_64__) || defined(__i386__) rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; #endif // MRC on each re of rb on MF output for (i=0; iN_RB_DL*3; i++) { #if defined(__x86_64__) || defined(__i386__) rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); #elif defined(__arm__) rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); #endif } } #if defined(__x86_64__) || defined(__i386__) rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12]; rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12]; rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12]; #endif for (i=0; iN_RB_DL*3; i++) { #if defined(__x86_64__) || defined(__i386__) rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); #elif defined(__arm__) rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]); #endif } #if defined(__x86_64__) || defined(__i386__) rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; #endif // MRC on each re of rb on MF and rho for (i=0; iN_RB_DL*3; i++) { #if defined(__x86_64__) || defined(__i386__) rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); #elif defined(__arm__) rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]); rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]); #endif } } #if defined(__x86_64__) || defined(__i386__) _mm_empty(); _m_empty(); #endif } void pdcch_extract_rbs_single(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, uint8_t symbol, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms) { uint16_t rb,nb_rb=0; uint8_t i,j,aarx; int32_t *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int nushiftmod3 = frame_parms->nushift%3; uint8_t symbol_mod; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; #ifdef DEBUG_DCI_DECODING LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); #endif for (aarx=0; aarxnb_antennas_rx; aarx++) { if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; else dl_ch0 = &dl_ch_estimates[aarx][5]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs for (rb=0; rbN_RB_DL; rb++) { // For second half of RBs skip DC carrier if (rb==(frame_parms->N_RB_DL>>1)) { rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; //dl_ch0++; } if (symbol_mod>0) { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; } nb_rb++; dl_ch0_ext+=12; rxF_ext+=12; dl_ch0+=12; rxF+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=nushiftmod3) && (i!=(nushiftmod3+3)) && (i!=(nushiftmod3+6)) && (i!=(nushiftmod3+9))) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j++]=dl_ch0[i]; // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); } } nb_rb++; dl_ch0_ext+=8; rxF_ext+=8; dl_ch0+=12; rxF+=12; } } } else { // Odd number of RBs for (rb=0; rbN_RB_DL>>1; rb++) { if (symbol_mod>0) { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); for (i=0; i<12; i++) rxF_ext[i]=rxF[i]; nb_rb++; dl_ch0_ext+=12; rxF_ext+=12; dl_ch0+=12; rxF+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=nushiftmod3) && (i!=(nushiftmod3+3)) && (i!=(nushiftmod3+6)) && (i!=(nushiftmod3+9))) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j++]=dl_ch0[i]; // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); } } nb_rb++; dl_ch0_ext+=8; rxF_ext+=8; dl_ch0+=12; rxF+=12; } } // Do middle RB (around DC) // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); if (symbol_mod==0) { j=0; for (i=0; i<6; i++) { if ((i!=nushiftmod3) && (i!=(nushiftmod3+3))) { dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[i]; // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); } } rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; for (; i<12; i++) { if ((i!=(nushiftmod3+6)) && (i!=(nushiftmod3+9))) { dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[(1+i-6)]; // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); } } nb_rb++; dl_ch0_ext+=8; rxF_ext+=8; dl_ch0+=12; rxF+=7; rb++; } else { for (i=0; i<6; i++) { dl_ch0_ext[i]=dl_ch0[i]; rxF_ext[i]=rxF[i]; } rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; for (; i<12; i++) { dl_ch0_ext[i]=dl_ch0[i]; rxF_ext[i]=rxF[(1+i-6)]; } nb_rb++; dl_ch0_ext+=12; rxF_ext+=12; dl_ch0+=12; rxF+=7; rb++; } for (; rbN_RB_DL; rb++) { if (symbol_mod > 0) { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); for (i=0; i<12; i++) rxF_ext[i]=rxF[i]; nb_rb++; dl_ch0_ext+=12; rxF_ext+=12; dl_ch0+=12; rxF+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=(nushiftmod3)) && (i!=(nushiftmod3+3)) && (i!=(nushiftmod3+6)) && (i!=(nushiftmod3+9))) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j++]=dl_ch0[i]; } } nb_rb++; dl_ch0_ext+=8; rxF_ext+=8; dl_ch0+=12; rxF+=12; } } } } } void pdcch_extract_rbs_dual(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, uint8_t symbol, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms) { uint16_t rb,nb_rb=0; uint8_t i,aarx,j; int32_t *dl_ch0,*dl_ch0_ext,*dl_ch1,*dl_ch1_ext,*rxF,*rxF_ext; uint8_t symbol_mod; int nushiftmod3 = frame_parms->nushift%3; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; #ifdef DEBUG_DCI_DECODING LOG_I(PHY, "extract_rbs_dual: symbol_mod %d\n",symbol_mod); #endif for (aarx=0; aarxnb_antennas_rx; aarx++) { if (high_speed_flag==1) { dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; } else { dl_ch0 = &dl_ch_estimates[aarx][5]; dl_ch1 = &dl_ch_estimates[2+aarx][5]; } dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)]; // printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12)); rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs for (rb=0; rbN_RB_DL; rb++) { // For second half of RBs skip DC carrier if (rb==(frame_parms->N_RB_DL>>1)) { rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; // dl_ch0++; //dl_ch1++; } if (symbol_mod>0) { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); /* printf("rb %d\n",rb); for (i=0;i<12;i++) printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]); printf("\n"); */ for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; // printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2, // ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]); } nb_rb++; dl_ch0_ext+=12; dl_ch1_ext+=12; rxF_ext+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=nushiftmod3) && (i!=nushiftmod3+3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+9)) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j] =dl_ch0[i]; dl_ch1_ext[j++]=dl_ch1[i]; } } nb_rb++; dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; } dl_ch0+=12; dl_ch1+=12; rxF+=12; } else { // Odd number of RBs for (rb=0; rbN_RB_DL>>1; rb++) { // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); if (symbol_mod>0) { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); for (i=0; i<12; i++) rxF_ext[i]=rxF[i]; nb_rb++; dl_ch0_ext+=12; dl_ch1_ext+=12; rxF_ext+=12; dl_ch0+=12; dl_ch1+=12; rxF+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=nushiftmod3) && (i!=nushiftmod3+3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+9)) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j]=dl_ch0[i]; dl_ch1_ext[j++]=dl_ch1[i]; // printf("ch %d => (%d,%d)\n",i,*(short *)&dl_ch0[i],*(1+(short*)&dl_ch0[i])); } } nb_rb++; dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; dl_ch0+=12; dl_ch1+=12; rxF+=12; } } // Do middle RB (around DC) if (symbol_mod > 0) { for (i=0; i<6; i++) { dl_ch0_ext[i]=dl_ch0[i]; dl_ch1_ext[i]=dl_ch1[i]; rxF_ext[i]=rxF[i]; } rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; for (; i<12; i++) { dl_ch0_ext[i]=dl_ch0[i]; dl_ch1_ext[i]=dl_ch1[i]; rxF_ext[i]=rxF[(1+i)]; } nb_rb++; dl_ch0_ext+=12; dl_ch1_ext+=12; rxF_ext+=12; dl_ch0+=12; dl_ch1+=12; rxF+=7; rb++; } else { j=0; for (i=0; i<6; i++) { if ((i!=nushiftmod3) && (i!=nushiftmod3+3)) { dl_ch0_ext[j]=dl_ch0[i]; dl_ch1_ext[j]=dl_ch1[i]; rxF_ext[j++]=rxF[i]; // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); } } rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; for (; i<12; i++) { if ((i!=nushiftmod3+6) && (i!=nushiftmod3+9)) { dl_ch0_ext[j]=dl_ch0[i]; dl_ch1_ext[j]=dl_ch1[i]; rxF_ext[j++]=rxF[(1+i-6)]; // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); } } nb_rb++; dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; dl_ch0+=12; dl_ch1+=12; rxF+=7; rb++; } for (; rbN_RB_DL; rb++) { if (symbol_mod>0) { // printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]); memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t)); for (i=0; i<12; i++) rxF_ext[i]=rxF[i]; nb_rb++; dl_ch0_ext+=12; dl_ch1_ext+=12; rxF_ext+=12; dl_ch0+=12; dl_ch1+=12; rxF+=12; } else { j=0; for (i=0; i<12; i++) { if ((i!=nushiftmod3) && (i!=nushiftmod3+3) && (i!=nushiftmod3+6) && (i!=nushiftmod3+9)) { rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j]=dl_ch0[i]; dl_ch1_ext[j++]=dl_ch1[i]; } } nb_rb++; dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; dl_ch0+=12; dl_ch1+=12; rxF+=12; } } } } } void pdcch_channel_compensation(int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, int32_t **rxdataF_comp, int32_t **rho, LTE_DL_FRAME_PARMS *frame_parms, uint8_t symbol, uint8_t output_shift) { uint16_t rb; #if defined(__x86_64__) || defined(__i386__) __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128; __m128i *dl_ch128_2, *rho128; #elif defined(__arm__) #endif uint8_t aatx,aarx,pilots=0; #ifdef DEBUG_DCI_DECODING LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol); #endif if (symbol==0) pilots=1; for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { //if (frame_parms->mode1_flag && aatx>0) break; //if mode1_flag is set then there is only one stream to extract, independent of nb_antenna_ports_eNB for (aarx=0; aarxnb_antennas_rx; aarx++) { #if defined(__x86_64__) || defined(__i386__) dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) #endif for (rb=0; rbN_RB_DL; rb++) { #if defined(__x86_64__) || defined(__i386__) // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); // print_ints("re",&mmtmpPD0); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); // print_ints("im",&mmtmpPD1); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[0]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); // print_ints("re(shift)",&mmtmpPD0); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); // print_ints("im(shift)",&mmtmpPD1); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); // print_ints("c0",&mmtmpPD2); // print_ints("c1",&mmtmpPD3); rxdataF_comp128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[1]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); rxdataF_comp128[1] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch128+1); // print_shorts("pack:",rxdataF_comp128+1); // multiply by conjugated channel if (pilots == 0) { mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,rxdataF128[2]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); rxdataF_comp128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); } // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch128+2); // print_shorts("pack:",rxdataF_comp128+2); if (pilots==0) { dl_ch128+=3; rxdataF128+=3; rxdataF_comp128+=3; } else { dl_ch128+=2; rxdataF128+=2; rxdataF_comp128+=2; } #elif defined(__arm__) #endif } } } if (rho) { for (aarx=0; aarxnb_antennas_rx; aarx++) { #if defined(__x86_64__) || defined(__i386__) rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) #endif for (rb=0; rbN_RB_DL; rb++) { #if defined(__x86_64__) || defined(__i386__) // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)&conjugate[0]); // print_ints("im",&mmtmpPD1); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[0]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); // print_ints("re(shift)",&mmtmpD0); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); // print_ints("im(shift)",&mmtmpD1); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); // print_ints("c0",&mmtmpPD2); // print_ints("c1",&mmtmpPD3); rho128[0] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2); //print_shorts("ch:",dl_ch128); //print_shorts("pack:",rho128); // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); rho128[1] =_mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2+1); //print_shorts("ch:",dl_ch128+1); //print_shorts("pack:",rho128+1); // multiply by conjugated channel mmtmpPD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128_2[2]); // mmtmpPD0 contains real part of 4 consecutive outputs (32-bit) mmtmpPD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_shufflehi_epi16(mmtmpPD1,_MM_SHUFFLE(2,3,0,1)); mmtmpPD1 = _mm_sign_epi16(mmtmpPD1,*(__m128i*)conjugate); mmtmpPD1 = _mm_madd_epi16(mmtmpPD1,dl_ch128_2[2]); // mmtmpPD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpPD0 = _mm_srai_epi32(mmtmpPD0,output_shift); mmtmpPD1 = _mm_srai_epi32(mmtmpPD1,output_shift); mmtmpPD2 = _mm_unpacklo_epi32(mmtmpPD0,mmtmpPD1); mmtmpPD3 = _mm_unpackhi_epi32(mmtmpPD0,mmtmpPD1); rho128[2] = _mm_packs_epi32(mmtmpPD2,mmtmpPD3); //print_shorts("rx:",dl_ch128_2+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rho128+2); dl_ch128+=3; dl_ch128_2+=3; rho128+=3; #elif defined(__arm_) #endif } } } #if defined(__x86_64__) || defined(__i386__) _mm_empty(); _m_empty(); #endif } void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, uint8_t symbol) { uint8_t aatx; #if defined(__x86_64__) || defined(__i386__) __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; #elif defined(__arm__) int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1; #endif int32_t i; if (frame_parms->nb_antennas_rx>1) { for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { #if defined(__x86_64__) || defined(__i386__) rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; #endif // MRC on each re of rb for (i=0; iN_RB_DL*3; i++) { #if defined(__x86_64__) || defined(__i386__) rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); #elif defined(__arm__) rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); #endif } } } #if defined(__x86_64__) || defined(__i386__) _mm_empty(); _m_empty(); #endif } void pdcch_siso(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, uint8_t l) { uint8_t rb,re,jj,ii; jj=0; ii=0; for (rb=0; rbN_RB_DL; rb++) { for (re=0; re<12; re++) { rxdataF_comp[0][jj++] = rxdataF_comp[0][ii]; ii++; } } } void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, uint8_t symbol) { int16_t *rxF0,*rxF1; uint8_t rb,re; int32_t jj=(symbol*frame_parms->N_RB_DL*12); rxF0 = (int16_t*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y rxF1 = (int16_t*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y for (rb=0; rbN_RB_DL; rb++) { for (re=0; re<12; re+=2) { // Alamouti RX combining rxF0[0] = rxF0[0] + rxF1[2]; rxF0[1] = rxF0[1] - rxF1[3]; rxF0[2] = rxF0[2] - rxF1[0]; rxF0[3] = rxF0[3] + rxF1[1]; rxF0+=4; rxF1+=4; } } } int32_t avgP[4]; int32_t rx_pdcch(LTE_UE_COMMON *common_vars, LTE_UE_PDCCH **pdcch_vars, LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, uint8_t eNB_id, MIMO_mode_t mimo_mode, uint32_t high_speed_flag, uint8_t is_secondary_ue) { uint8_t log2_maxh,aatx,aarx; #ifdef MU_RECEIVER uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1 #endif int32_t avgs,s; uint8_t n_pdcch_symbols = 3; //pdcch_vars[eNB_id]->num_pdcch_symbols; uint8_t mi = get_mi(frame_parms,subframe); // printf("In rx_pdcch, subframe %d, eNB_id %d\n",subframe,eNB_id); for (s=0; srxdataF, common_vars->dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, s, high_speed_flag, frame_parms); #ifdef MU_RECEIVER pdcch_extract_rbs_single(common_vars->rxdataF, common_vars->dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna s, high_speed_flag, frame_parms); #endif //MU_RECEIVER } else if (frame_parms->nb_antenna_ports_eNB>1) { pdcch_extract_rbs_dual(common_vars->rxdataF, common_vars->dl_ch_estimates[eNB_id], pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, s, high_speed_flag, frame_parms); } else { pdcch_extract_rbs_single(common_vars->rxdataF, common_vars->dl_ch_estimates[eNB_id], pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, s, high_speed_flag, frame_parms); } } pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, avgP, frame_parms->N_RB_DL); avgs = 0; for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) for (aarx=0; aarxnb_antennas_rx; aarx++) avgs = cmax(avgs,avgP[(aarx<<1)+aatx]); log2_maxh = (log2_approx(avgs)/2) + 5; //+frame_parms->nb_antennas_rx; #ifdef DEBUG_PHY LOG_I(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs); #endif for (s=0; srxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, pdcch_vars[eNB_id]->rxdataF_comp, (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL, frame_parms, s, log2_maxh); // log2_maxh+I0_shift #ifdef DEBUG_PHY if (subframe==5) write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); #endif #ifdef MU_RECEIVER if (is_secondary_ue) { //get MF output for interfering stream pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext, pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, pdcch_vars[eNB_id_i]->rxdataF_comp, (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL, frame_parms, s, log2_maxh); // log2_maxh+I0_shift #ifdef DEBUG_PHY write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); #endif pdcch_dual_stream_correlation(frame_parms, s, pdcch_vars[eNB_id]->dl_ch_estimates_ext, pdcch_vars[eNB_id_i]->dl_ch_estimates_ext, pdcch_vars[eNB_id]->dl_ch_rho_ext, log2_maxh); } #endif //MU_RECEIVER if (frame_parms->nb_antennas_rx > 1) { #ifdef MU_RECEIVER if (is_secondary_ue) { pdcch_detection_mrc_i(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, pdcch_vars[eNB_id_i]->rxdataF_comp, pdcch_vars[eNB_id]->rho, pdcch_vars[eNB_id]->dl_ch_rho_ext, s); #ifdef DEBUG_PHY write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); #endif } else #endif //MU_RECEIVER pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, s); } if (mimo_mode == SISO) pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); else pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s); #ifdef MU_RECEIVER if (is_secondary_ue) { pdcch_qpsk_qpsk_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, pdcch_vars[eNB_id_i]->rxdataF_comp, pdcch_vars[eNB_id]->dl_ch_rho_ext, pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder) pdcch_vars[eNB_id]->llr, s); /* #ifdef DEBUG_PHY if (subframe==5) { write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); } #endif*/ } else { #endif //MU_RECEIVER pdcch_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, (char *)pdcch_vars[eNB_id]->llr, s); /*#ifdef DEBUG_PHY write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4); #endif*/ #ifdef MU_RECEIVER } #endif //MU_RECEIVER } // decode pcfich here n_pdcch_symbols = rx_pcfich(frame_parms, subframe, pdcch_vars[eNB_id], mimo_mode); if (n_pdcch_symbols>3) n_pdcch_symbols=1; #ifdef DEBUG_DCI_DECODING printf("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols); printf("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config); #endif pdcch_demapping(pdcch_vars[eNB_id]->llr, pdcch_vars[eNB_id]->wbar, frame_parms, n_pdcch_symbols, get_mi(frame_parms,subframe)); pdcch_deinterleaving(frame_parms, (uint16_t*)pdcch_vars[eNB_id]->e_rx, pdcch_vars[eNB_id]->wbar, n_pdcch_symbols, mi); pdcch_unscrambling(frame_parms, subframe, pdcch_vars[eNB_id]->e_rx, get_nCCE(n_pdcch_symbols,frame_parms,mi)*72); pdcch_vars[eNB_id]->num_pdcch_symbols = n_pdcch_symbols; return(0); } void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, uint8_t *e, uint32_t length) { int i; uint8_t reset; uint32_t x1, x2, s=0; reset = 1; // x1 is set in lte_gold_generic x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i>(i&0x1f))&1)); if (e[i] != 2) // element is 2 e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1); } } void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, int8_t* llr, uint32_t length) { int i; uint8_t reset; uint32_t x1, x2, s=0; reset = 1; // x1 is set in first call to lte_gold_generic x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i ",i,llr[i],((s>>(i&0x1f))&1)); if (((s>>(i%32))&1)==0) llr[i] = -llr[i]; // printf("%d\n",llr[i]); } } uint8_t get_num_pdcch_symbols(uint8_t num_dci, DCI_ALLOC_t *dci_alloc, LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe) { uint16_t numCCE = 0; uint8_t i; uint8_t nCCEmin = 0; // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211) if (frame_parms->Ncp==1) { // extended prefix if ((frame_parms->frame_type == TDD) && ((frame_parms->tdd_config<3)||(frame_parms->tdd_config==6)) && ((subframe==1) || (subframe==6))) // subframes 1 and 6 (S-subframes) for 5ms switching periodicity are 2 symbols nCCEmin = 2; else { // 10ms switching periodicity is always 3 symbols, any DL-only subframe is 3 symbols nCCEmin = 3; } } // compute numCCE for (i=0; i %d\n",i,dci_alloc[i].L); numCCE += (1<<(dci_alloc[i].L)); } //if ((9*numCCE) <= (frame_parms->N_RB_DL*2)) if (numCCE <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) return(cmax(1,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5))) else if (numCCE <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) return(cmax(2,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8))) else if (numCCE <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) return(cmax(3,nCCEmin)); else if (frame_parms->N_RB_DL<=10) { if (frame_parms->Ncp == 0) { // normal CP printf("numCCE %d, N_RB_DL = %d : should be returning 4 PDCCH symbols (%d,%d,%d)\n",numCCE,frame_parms->N_RB_DL, get_nCCE(1, frame_parms, get_mi(frame_parms, subframe)), get_nCCE(2, frame_parms, get_mi(frame_parms, subframe)), get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))); if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 10 : 11))) return(4); } else { // extended CP if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 9 : 10))) return(4); } } LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci); //for (i=0;inushift%3; int Msymb2; int split_flag=0; switch (frame_parms->N_RB_DL) { case 100: Msymb2 = Msymb; break; case 75: Msymb2 = 3*Msymb/4; break; case 50: Msymb2 = Msymb>>1; break; case 25: Msymb2 = Msymb>>2; break; case 15: Msymb2 = Msymb*15/100; break; case 6: Msymb2 = Msymb*6/100; break; default: Msymb2 = Msymb>>2; break; } num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe); // printf("subframe %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n", // subframe,num_pdcch_symbols,num_ue_spec_dci+num_common_dci); generate_pcfich(num_pdcch_symbols, amp, frame_parms, txdataF, subframe); wbar[0] = &wbar0[0]; wbar[1] = &wbar1[0]; y[0] = &yseq0[0]; y[1] = &yseq1[0]; // reset all bits to , here we set elements as 2 // memset(e, 2, DCI_BITS_MAX); // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. for (i=0; i=0; L--) { for (i=0; i=0) { e_ptr = generate_dci0(dci_alloc[i].dci_pdu, e+(72*dci_alloc[i].firstCCE), dci_alloc[i].dci_length, dci_alloc[i].L, dci_alloc[i].rnti); } } } for (; i= 0) { e_ptr = generate_dci0(dci_alloc[i].dci_pdu, e+(72*dci_alloc[i].firstCCE), dci_alloc[i].dci_length, dci_alloc[i].L, dci_alloc[i].rnti); } else { } } } } // Scrambling // printf("pdcch scrambling\n"); pdcch_scrambling(frame_parms, subframe, e, 8*get_nquad(num_pdcch_symbols, frame_parms, mi)); //72*get_nCCE(num_pdcch_symbols,frame_parms,mi)); // Now do modulation if (frame_parms->mode1_flag==1) gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); else gain_lin_QPSK = amp/2; e_ptr = e; #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK); #endif if (frame_parms->mode1_flag) { //SISO for (i=0; i>2); #endif // first antenna position n -> x0 ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; // second antenna position n -> -x1* ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK; e_ptr++; ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; // fill in the rest of the ALAMOUTI precoding ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0]; ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1]; ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0]; ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1]; } } #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Interleaving\n"); #endif // printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]); // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5 pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi); mprime=0; nsymb = (frame_parms->Ncp==0) ? 14:12; re_offset = frame_parms->first_carrier_offset; // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 // printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]); for (kprime=0; kprimeN_RB_DL*12; kprime++) { for (lprime=0; lprimeofdm_symbol_size*(lprime+(subframe*nsymb)); tti_offset = symbol_offset + re_offset; (re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0); // printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset); // if REG is allocated to PHICH, skip it if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) { #ifdef DEBUG_DCI_ENCODING printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime); #endif } else { // Copy REG to TX buffer if ((lprime == 0)|| ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) { // first symbol, or second symbol+4 TX antennas skip pilots kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { // kprime represents REG for (i=0; i<6; i++) { if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) { txdataF[0][tti_offset+i] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); #endif mprime++; } } } } else { // no pilots in this symbol kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 4) || (kprime_mod12 == 8)) { // kprime represents REG if (split_flag==0) { for (i=0; i<4; i++) { txdataF[0][tti_offset+i] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); #endif mprime++; } } else { txdataF[0][tti_offset+0] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset+0] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset+1] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset+1] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime], *(1+(short*)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime]; if (frame_parms->nb_antenna_ports_eNB > 1) txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime], *(1+(short*)&wbar[0][mprime])); #endif mprime++; } } } if (mprime>=Msymb2) return(num_pdcch_symbols); } // check_phich_reg } //lprime loop re_offset++; if (re_offset == (frame_parms->ofdm_symbol_size)) re_offset = 1; } // kprime loop return(num_pdcch_symbols); } #ifdef PHY_ABSTRACTION uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB, uint8_t num_ue_spec_dci, uint8_t num_common_dci, DCI_ALLOC_t *dci_alloc, uint8_t subframe) { int n_dci, n_dci_dl; uint8_t ue_id; LTE_eNB_DLSCH_t *dlsch_eNB; uint8_t num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci, dci_alloc, &phy_vars_eNB->frame_parms, subframe); eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.cfi=num_pdcch_symbols; memcpy(phy_vars_eNB->dci_alloc[subframe&1],dci_alloc,sizeof(DCI_ALLOC_t)*(num_ue_spec_dci+num_common_dci)); phy_vars_eNB->num_ue_spec_dci[subframe&1]=num_ue_spec_dci; phy_vars_eNB->num_common_dci[subframe&1]=num_common_dci; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci = num_ue_spec_dci; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci = num_common_dci; LOG_D(PHY,"[eNB %d][DCI][EMUL] CC id %d: num spec dci %d num comm dci %d num PMCH %d \n", phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, num_ue_spec_dci,num_common_dci, eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch); if (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].cntl.pmch_flag == 1 ) n_dci_dl = eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_pmch; else n_dci_dl = 0; for (n_dci =0 ; n_dci < (eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_ue_spec_dci+ eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].num_common_dci); n_dci++) { if (dci_alloc[n_dci].format > 0) { // exclude the uplink dci if (dci_alloc[n_dci].rnti == SI_RNTI) { dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_SI; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 0;//SI; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3; LOG_D(PHY,"[DCI][EMUL]SI tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl, eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]); } else if (dci_alloc[n_dci_dl].ra_flag == 1) { dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch_ra; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 1;//RA; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = 0; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[0]->TBS>>3; LOG_D(PHY,"[DCI][EMUL] RA tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl, eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]); } else { ue_id = find_ue(dci_alloc[n_dci_dl].rnti,PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]); DevAssert( ue_id != (uint8_t)-1 ); dlsch_eNB = PHY_vars_eNB_g[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id]->dlsch[ue_id][0]; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dlsch_type[n_dci_dl] = 2;//TB0; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl] = dlsch_eNB->current_harq_pid; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].ue_id[n_dci_dl] = ue_id; eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl] = dlsch_eNB->harq_processes[dlsch_eNB->current_harq_pid]->TBS>>3; LOG_D(PHY,"[DCI][EMUL] TB1 tbs is %d and dci index %d harq pid is %d \n",eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].tbs[n_dci_dl],n_dci_dl, eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].harq_pid[n_dci_dl]); // check for TB1 later } } n_dci_dl++; } memcpy((void *)&eNB_transport_info[phy_vars_eNB->Mod_id][phy_vars_eNB->CC_id].dci_alloc, (void *)dci_alloc, n_dci*sizeof(DCI_ALLOC_t)); return(num_pdcch_symbols); } #endif void dci_decoding(uint8_t DCI_LENGTH, uint8_t aggregation_level, int8_t *e, uint8_t *decoded_output) { uint8_t dummy_w_rx[3*(MAX_DCI_SIZE_BITS+16+64)]; int8_t w_rx[3*(MAX_DCI_SIZE_BITS+16+32)],d_rx[96+(3*(MAX_DCI_SIZE_BITS+16))]; uint16_t RCC; uint16_t D=(DCI_LENGTH+16+64); uint16_t coded_bits; #ifdef DEBUG_DCI_DECODING int32_t i; #endif if (aggregation_level>3) { LOG_I(PHY," dci.c: dci_decoding FATAL, illegal aggregation_level %d\n",aggregation_level); return; } coded_bits = 72 * (1<>3)); #ifdef DEBUG_DCI_DECODING printf("Before Viterbi\n"); for (i=0; i<16+DCI_LENGTH; i++) printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i))); #endif //debug_printf("Doing DCI Viterbi \n"); phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH); //debug_printf("Done DCI Viterbi \n"); } static uint8_t dci_decoded_output[(MAX_DCI_SIZE_BITS+64)/8]; uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) { return(get_nquad(num_pdcch_symbols,frame_parms,mi)/9); } uint16_t get_nquad(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) { uint16_t Nreg=0; uint8_t Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) Ngroup_PHICH++; if (frame_parms->Ncp == 1) { Ngroup_PHICH<<=1; } Ngroup_PHICH*=mi; if ((num_pdcch_symbols>0) && (num_pdcch_symbols<4)) switch (frame_parms->N_RB_DL) { case 6: Nreg=12+(num_pdcch_symbols-1)*18; break; case 25: Nreg=50+(num_pdcch_symbols-1)*75; break; case 50: Nreg=100+(num_pdcch_symbols-1)*150; break; case 100: Nreg=200+(num_pdcch_symbols-1)*300; break; default: return(0); } // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); return(Nreg - 4 - (3*Ngroup_PHICH)); } uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe) { // check for eNB only ! return(get_nCCE(num_pdcch_symbols, &PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms, get_mi(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,subframe))); } int get_nCCE_offset_l1(int *CCE_table, const unsigned char L, const int nCCE, const int common_dci, const unsigned short rnti, const unsigned char subframe) { int search_space_free,m,nb_candidates = 0,l,i; unsigned int Yk; /* printf("CCE Allocation: "); for (i=0;i=0 ; m--) { search_space_free = 1; for (l=0; lnum_pdcch_symbols,frame_parms,mi); if (nCCE > get_nCCE(3,frame_parms,1)) { LOG_D(PHY,"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n", nCCE, get_nCCE(3,frame_parms,1)); return; } if (nCCEcrnti; for (i=0; i<=subframe; i++) Yk = (Yk*39827)%65537; Yk = Yk % (nCCE/L2); switch (L2) { case 1: case 2: nb_candidates = 6; break; case 4: case 8: nb_candidates = 2; break; default: DevParam(L2, do_common, eNB_id); break; } } /* for (CCEind=0; CCEind nCCE) nb_candidates = nCCE/L2; for (m=0; mmacphy_exit("Illegal CCEind\n"); return; // not reached } switch (L2) { case 1: CCEmap_mask = (1<<(CCEind&0x1f)); break; case 2: CCEmap_mask = (3<<(CCEind&0x1f)); break; case 4: CCEmap_mask = (0xf<<(CCEind&0x1f)); break; case 8: CCEmap_mask = (0xff<<(CCEind&0x1f)); break; default: LOG_E( PHY, "Illegal L2 value %d\n", L2 ); mac_xface->macphy_exit( "Illegal L2\n" ); return; // not reached } CCEmap_cand = (*CCEmap)&CCEmap_mask; // CCE is not allocated yet if (CCEmap_cand == 0) { #ifdef DEBUG_DCI_DECODING if (do_common == 1) LOG_I(PHY,"[DCI search - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); else LOG_I(PHY,"[DCI search - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); #endif dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind*72], dci_decoded_output); /* for (i=0;i<3+(sizeof_bits>>3);i++) printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); */ crc = (crc16(dci_decoded_output,sizeof_bits)>>16) ^ extract_crc(dci_decoded_output,sizeof_bits); #ifdef DEBUG_DCI_DECODING printf("crc =>%x\n",crc); #endif if (((L>1) && ((crc == si_rnti)|| (crc == p_rnti)|| (crc == ra_rnti)))|| (crc == pdcch_vars[eNB_id]->crnti)) { dci_alloc[*dci_cnt].dci_length = sizeof_bits; dci_alloc[*dci_cnt].rnti = crc; dci_alloc[*dci_cnt].L = L; dci_alloc[*dci_cnt].firstCCE = CCEind; if (sizeof_bytes<=4) { dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[0]; dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[1]; dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[2]; dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[3]; #ifdef DEBUG_DCI_DECODING printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3]); #endif } else { dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[0]; dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[1]; dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[2]; dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[3]; dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[4]; dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[5]; dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[6]; dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[7]; #ifdef DEBUG_DCI_DECODING printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3], dci_decoded_output[4],dci_decoded_output[5],dci_decoded_output[6],dci_decoded_output[7]); #endif } if (crc==si_rnti) { dci_alloc[*dci_cnt].format = format_si; *dci_cnt = *dci_cnt+1; } else if (crc==p_rnti) { dci_alloc[*dci_cnt].format = format_p; *dci_cnt = *dci_cnt+1; } else if (crc==ra_rnti) { dci_alloc[*dci_cnt].format = format_ra; // store first nCCE of group for PUCCH transmission of ACK/NAK pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; *dci_cnt = *dci_cnt+1; } else if (crc==pdcch_vars[eNB_id]->crnti) { if ((format_c == format0)&&((dci_decoded_output[0]&0x80)==0)) {// check if pdu is format 0 or 1A if (*format0_found == 0) { dci_alloc[*dci_cnt].format = format0; *format0_found = 1; *dci_cnt = *dci_cnt+1; pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; } } else if (format_c == format0) { // this is a format 1A DCI dci_alloc[*dci_cnt].format = format1A; *dci_cnt = *dci_cnt+1; pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; } else { // store first nCCE of group for PUCCH transmission of ACK/NAK if (*format_c_found == 0) { dci_alloc[*dci_cnt].format = format_c; *dci_cnt = *dci_cnt+1; *format_c_found = 1; pdcch_vars[eNB_id]->nCCE[subframe]=CCEind; } } } LOG_D(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); switch (1<crnti) // return; } // rnti match } // CCEmap_cand == 0 } // candidate loop } uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, DCI_ALLOC_t *dci_alloc, int do_common, int16_t eNB_id, uint8_t subframe) { uint8_t dci_cnt=0,old_dci_cnt=0; uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; uint8_t mi = get_mi(&ue->frame_parms,subframe); uint16_t ra_rnti=99; uint8_t format0_found=0,format_c_found=0; uint8_t tmode = ue->transmission_mode[eNB_id]; uint8_t frame_type = frame_parms->frame_type; uint8_t format1A_size_bits=0,format1A_size_bytes=0; uint8_t format1C_size_bits=0,format1C_size_bytes=0; uint8_t format0_size_bits=0,format0_size_bytes=0; uint8_t format1_size_bits=0,format1_size_bytes=0; uint8_t format2_size_bits=0,format2_size_bytes=0; uint8_t format2A_size_bits=0,format2A_size_bytes=0; switch (frame_parms->N_RB_DL) { case 6: if (frame_type == TDD) { format1A_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t; format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); format1C_size_bits = sizeof_DCI1C_1_5MHz_t; format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t; format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_1_5MHz_2A_TDD_t; format2_size_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_TDD_t; format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_1_5MHz_4A_TDD_t; format2_size_bytes = sizeof(DCI2_1_5MHz_4A_TDD_t); format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_TDD_t; format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_TDD_t); } } else { format1A_size_bits = sizeof_DCI1A_1_5MHz_FDD_t; format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t); format1C_size_bits = sizeof_DCI1C_1_5MHz_t; format1C_size_bytes = sizeof(DCI1C_1_5MHz_t); format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t; format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t; format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_1_5MHz_2A_FDD_t; format2_size_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); format2A_size_bits = sizeof_DCI2A_1_5MHz_2A_FDD_t; format2A_size_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_1_5MHz_4A_FDD_t; format2_size_bytes = sizeof(DCI2_1_5MHz_4A_FDD_t); format2A_size_bits = sizeof_DCI2A_1_5MHz_4A_FDD_t; format2A_size_bytes = sizeof(DCI2A_1_5MHz_4A_FDD_t); } } break; case 25: default: if (frame_type == TDD) { format1A_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t; format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); format1C_size_bits = sizeof_DCI1C_5MHz_t; format1C_size_bytes = sizeof(DCI1C_5MHz_t); format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); format1_size_bits = sizeof_DCI1_5MHz_TDD_t; format1_size_bytes = sizeof(DCI1_5MHz_TDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_5MHz_2A_TDD_t; format2_size_bytes = sizeof(DCI2_5MHz_2A_TDD_t); format2A_size_bits = sizeof_DCI2A_5MHz_2A_TDD_t; format2A_size_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_5MHz_4A_TDD_t; format2_size_bytes = sizeof(DCI2_5MHz_4A_TDD_t); format2A_size_bits = sizeof_DCI2A_5MHz_4A_TDD_t; format2A_size_bytes = sizeof(DCI2A_5MHz_4A_TDD_t); } } else { format1A_size_bits = sizeof_DCI1A_5MHz_FDD_t; format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t); format1C_size_bits = sizeof_DCI1C_5MHz_t; format1C_size_bytes = sizeof(DCI1C_5MHz_t); format0_size_bits = sizeof_DCI0_5MHz_FDD_t; format0_size_bytes = sizeof(DCI0_5MHz_FDD_t); format1_size_bits = sizeof_DCI1_5MHz_FDD_t; format1_size_bytes = sizeof(DCI1_5MHz_FDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_5MHz_2A_FDD_t; format2_size_bytes = sizeof(DCI2_5MHz_2A_FDD_t); format2A_size_bits = sizeof_DCI2A_5MHz_2A_FDD_t; format2A_size_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_5MHz_4A_FDD_t; format2_size_bytes = sizeof(DCI2_5MHz_4A_FDD_t); format2A_size_bits = sizeof_DCI2A_5MHz_4A_FDD_t; format2A_size_bytes = sizeof(DCI2A_5MHz_4A_FDD_t); } } break; case 50: if (frame_type == TDD) { format1A_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t; format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); format1C_size_bits = sizeof_DCI1C_10MHz_t; format1C_size_bytes = sizeof(DCI1C_10MHz_t); format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); format1_size_bits = sizeof_DCI1_10MHz_TDD_t; format1_size_bytes = sizeof(DCI1_10MHz_TDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_10MHz_2A_TDD_t; format2_size_bytes = sizeof(DCI2_10MHz_2A_TDD_t); format2A_size_bits = sizeof_DCI2A_10MHz_2A_TDD_t; format2A_size_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_10MHz_4A_TDD_t; format2_size_bytes = sizeof(DCI2_10MHz_4A_TDD_t); format2A_size_bits = sizeof_DCI2A_10MHz_4A_TDD_t; format2A_size_bytes = sizeof(DCI2A_10MHz_4A_TDD_t); } } else { format1A_size_bits = sizeof_DCI1A_10MHz_FDD_t; format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t); format1C_size_bits = sizeof_DCI1C_10MHz_t; format1C_size_bytes = sizeof(DCI1C_10MHz_t); format0_size_bits = sizeof_DCI0_10MHz_FDD_t; format0_size_bytes = sizeof(DCI0_10MHz_FDD_t); format1_size_bits = sizeof_DCI1_10MHz_FDD_t; format1_size_bytes = sizeof(DCI1_10MHz_FDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_10MHz_2A_FDD_t; format2_size_bytes = sizeof(DCI2_10MHz_2A_FDD_t); format2A_size_bits = sizeof_DCI2A_10MHz_2A_FDD_t; format2A_size_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_10MHz_4A_FDD_t; format2_size_bytes = sizeof(DCI2_10MHz_4A_FDD_t); format2A_size_bits = sizeof_DCI2A_10MHz_4A_FDD_t; format2A_size_bytes = sizeof(DCI2A_10MHz_4A_FDD_t); } } break; case 100: if (frame_type == TDD) { format1A_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); format1C_size_bits = sizeof_DCI1C_20MHz_t; format1C_size_bytes = sizeof(DCI1C_20MHz_t); format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); format1_size_bits = sizeof_DCI1_20MHz_TDD_t; format1_size_bytes = sizeof(DCI1_20MHz_TDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_20MHz_2A_TDD_t; format2_size_bytes = sizeof(DCI2_20MHz_2A_TDD_t); format2A_size_bits = sizeof_DCI2A_20MHz_2A_TDD_t; format2A_size_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_20MHz_4A_TDD_t; format2_size_bytes = sizeof(DCI2_20MHz_4A_TDD_t); format2A_size_bits = sizeof_DCI2A_20MHz_4A_TDD_t; format2A_size_bytes = sizeof(DCI2A_20MHz_4A_TDD_t); } } else { format1A_size_bits = sizeof_DCI1A_20MHz_FDD_t; format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t); format1C_size_bits = sizeof_DCI1C_20MHz_t; format1C_size_bytes = sizeof(DCI1C_20MHz_t); format0_size_bits = sizeof_DCI0_20MHz_FDD_t; format0_size_bytes = sizeof(DCI0_20MHz_FDD_t); format1_size_bits = sizeof_DCI1_20MHz_FDD_t; format1_size_bytes = sizeof(DCI1_20MHz_FDD_t); if (frame_parms->nb_antenna_ports_eNB == 2) { format2_size_bits = sizeof_DCI2_20MHz_2A_FDD_t; format2_size_bytes = sizeof(DCI2_20MHz_2A_FDD_t); format2A_size_bits = sizeof_DCI2A_20MHz_2A_FDD_t; format2A_size_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); } else if (frame_parms->nb_antenna_ports_eNB == 4) { format2_size_bits = sizeof_DCI2_20MHz_4A_FDD_t; format2_size_bytes = sizeof(DCI2_20MHz_4A_FDD_t); format2A_size_bits = sizeof_DCI2A_20MHz_4A_FDD_t; format2A_size_bytes = sizeof(DCI2A_20MHz_4A_FDD_t); } } break; } if (do_common == 1) { #ifdef DEBUG_DCI_DECODING printf("[DCI search] doing common search/format0 aggregation 4\n"); #endif if (ue->prach_resources[eNB_id]) ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; // First check common search spaces at aggregation 4 (SI_RNTI, P_RNTI and RA_RNTI format 0/1A), // and UE_SPEC format0 (PUSCH) too while we're at it dci_decoding_procedure0(pdcch_vars,1,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format0, format1A_size_bits, format1A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff) || ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // Now check common search spaces at aggregation 4 (SI_RNTI,P_RNTI and RA_RNTI and C-RNTI format 1C), // and UE_SPEC format0 (PUSCH) too while we're at it dci_decoding_procedure0(pdcch_vars,1,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1C, format1C, format1C, format1C, format1C_size_bits, format1C_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff) || ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // Now check common search spaces at aggregation 8 (SI_RNTI,P_RNTI and RA_RNTI format 1A), // and UE_SPEC format0 (PUSCH) too while we're at it // printf("[DCI search] doing common search/format0 aggregation 3\n"); #ifdef DEBUG_DCI_DECODING printf("[DCI search] doing common search/format0 aggregation 8\n"); #endif dci_decoding_procedure0(pdcch_vars,1,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, P_RNTI, ra_rnti, 3, format1A, format1A, format1A, format0, format1A_size_bits, format1A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C), // and UE_SPEC format0 (PUSCH) too while we're at it dci_decoding_procedure0(pdcch_vars,1,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1C, format1C, format1C, format1C, format1C_size_bits, format1C_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); //#endif } if (ue->UE_mode[eNB_id] <= PRACH) return(dci_cnt); if (ue->prach_resources[eNB_id]) ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI; // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8 // printf("[DCI search] Format 0/1A aggregation 8\n"); dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 0, format1A, format1A, format1A, format0, format0_size_bits, format0_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // printf("[DCI search] Format 0 aggregation 4\n"); // Now check UE_SPEC format 0 search spaces at aggregation 4 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 1, format1A, format1A, format1A, format0, format0_size_bits, format0_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // printf("[DCI search] Format 0 aggregation 2\n"); // Now check UE_SPEC format 0 search spaces at aggregation 2 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format0, format0_size_bits, format0_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // printf("[DCI search] Format 0 aggregation 4\n"); // Now check UE_SPEC format 0 search spaces at aggregation 1 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1A, format1A, format1A, format0, format0_size_bits, format0_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); // These are for CRNTI based on transmission mode if ((tmode < 3) || (tmode == 7)) { // Now check UE_SPEC format 1 search spaces at aggregation 1 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 0, format1A, format1A, format1A, format1, format1_size_bits, format1_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff) || (format_c_found==1)) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 1 search spaces at aggregation 2 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 1, format1A, format1A, format1A, format1, format1_size_bits, format1_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| (format_c_found==1)) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 1 search spaces at aggregation 4 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format1, format1_size_bits, format1_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 1 search spaces at aggregation 8 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1A, format1A, format1A, format1, format1_size_bits, format1_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#endif //ALL_AGGREGATION } else if (tmode == 3) { // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 0, format1A, format1A, format1A, format2A, format2A_size_bits, format2A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2 search spaces at aggregation 2 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 1, format1A, format1A, format1A, format2A, format2A_size_bits, format2A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format2A, format2A_size_bits, format2A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1A, format1A, format1A, format2A, format2A_size_bits, format2A_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); //#endif } else if (tmode == 4) { // Now check UE_SPEC format 2_2A search spaces at aggregation 1 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 0, format1A, format1A, format1A, format2, format2_size_bits, format2_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2 search spaces at aggregation 2 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 1, format1A, format1A, format1A, format2, format2_size_bits, format2_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format2, format2_size_bits, format2_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1A, format1A, format1A, format2, format2_size_bits, format2_size_bytes, &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); //#endif } else if ((tmode==5) || (tmode==6)) { // This is MU-MIMO // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 1 #ifdef DEBUG_DCI_DECODING LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n"); #endif dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 0, format1A, format1A, format1A, format1E_2A_M10PRB, sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 1, format1A, format1A, format1A, format1E_2A_M10PRB, sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 2, format1A, format1A, format1A, format1E_2A_M10PRB, sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8 dci_decoding_procedure0(pdcch_vars,0, subframe, dci_alloc, eNB_id, frame_parms, mi, SI_RNTI, ra_rnti, P_RNTI, 3, format1A, format1A, format1A, format1E_2A_M10PRB, sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t, sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t), &dci_cnt, &format0_found, &format_c_found, &CCEmap0, &CCEmap1, &CCEmap2); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#endif //ALL_AGGREGATION } return(dci_cnt); } #ifdef PHY_ABSTRACTION uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **pdcch_vars, uint8_t num_ue_spec_dci, uint8_t num_common_dci, DCI_ALLOC_t *dci_alloc_tx, DCI_ALLOC_t *dci_alloc_rx, int16_t eNB_id) { uint8_t dci_cnt=0,i; memcpy(dci_alloc_rx,dci_alloc_tx,num_common_dci*sizeof(DCI_ALLOC_t)); dci_cnt = num_common_dci; LOG_D(PHY,"[DCI][EMUL] : num_common_dci %d\n",num_common_dci); for (i=num_common_dci; i<(num_ue_spec_dci+num_common_dci); i++) { LOG_D(PHY,"[DCI][EMUL] Checking dci %d => %x format %d (bit 0 %d)\n",i,pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format, dci_alloc_tx[i].dci_pdu[0]&0x80); if (dci_alloc_tx[i].rnti == pdcch_vars[eNB_id]->crnti) { memcpy(dci_alloc_rx+dci_cnt,dci_alloc_tx+i,sizeof(DCI_ALLOC_t)); dci_cnt++; } } return(dci_cnt); } #endif