/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see .
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \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_antennas_tx_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
msg("[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
msg("[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
msg("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
msg("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
msg("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++)
msg("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
#endif
#ifdef DEBUG_DCI_ENCODING
msg("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
msg("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) {
msg("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 mod_sym_t wtemp[2][Msymb];
void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,mod_sym_t **z, mod_sym_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) {
mod_sym_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
// msg("[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_antennas_tx_eNB;a++){
//msg("a %d k %d\n",a,k);
wptr = &wtemp[a][k<<2];
zptr = &z[a][(index-ND)<<2];
//msg("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_antennas_tx_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) {
//msg("dci_demapping : skipping REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
if ((lprime == 0)&&((kprime%6)==0))
re_offset0+=4;
}
else { // not allocated to PHICH/PCFICH
// msg("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
msg("[PHY] PDCCH demapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset0,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
#endif
mprime++;
re_offset0++;
}
}
}
else if ((lprime==1)&&(frame_parms->nb_antennas_tx_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
msg("[PHY] PDCCH demapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,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) {
msg("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
return;
}
// undo permutation
for (i=0;iNid_cell)%Mquad)<<2];
wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr2 = &wbar[i<<2];
wptr[0] = wptr2[0];
wptr[1] = wptr2[1];
wptr[2] = wptr2[2];
wptr[3] = wptr2[3];
/*
msg("pdcch_deinterleaving (%p,%p): quad %d -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,
((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) {
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *rxF_i=(__m128i*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *rho=(__m128i*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *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 = (__m128i*)pdcch_llr;
if (!llr128) {
msg("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
return -1;
}
qpsk_qpsk((int16_t *)rxF,
(int16_t *)rxF_i,
(int16_t *)llr128,
(int16_t *)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) {
msg("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
return(-1);
}
// msg("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;
__m128i *dl_ch128;
for (aatx=0;aatxnb_antennas_tx_eNB;aatx++)
for (aarx=0;aarxnb_antennas_rx;aarx++) {
//clear average level
avg128P = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
for (rb=0;rbnb_antennas_rx;aarx++) {
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];
for (rb=0;rbN_RB_DL;rb++) {
// multiply by conjugated channel
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;
}
}
_mm_empty();
_m_empty();
}
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;
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
int32_t i;
if (frame_parms->nb_antennas_rx>1) {
for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) {
//if (frame_parms->mode1_flag && (aatx>0)) break;
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];
// MRC on each re of rb on MF output
for (i=0;iN_RB_DL*3;i++) {
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
}
}
rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
for (i=0;iN_RB_DL*3;i++) {
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
}
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];
// MRC on each re of rb on MF and rho
for (i=0;iN_RB_DL*3;i++) {
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));
}
}
_mm_empty();
_m_empty();
}
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
msg("[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)
// msg("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;
}
}
}
}
_mm_empty();
_m_empty();
}
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;
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)];
// msg("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));
/*
msg("rb %d\n",rb);
for (i=0;i<12;i++)
msg("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
msg("\n");
*/
for (i=0;i<12;i++) {
rxF_ext[i]=rxF[i];
// msg("%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++) {
// msg("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) {
// msg("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;
}
}
}
}
_mm_empty();
_m_empty();
}
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;
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
__m128i *dl_ch128_2, *rho128;
uint8_t aatx,aarx,pilots=0;
#ifdef DEBUG_DCI_DECODING
msg("[PHY] PDCCH comp: symbol %d\n",symbol);
#endif
if (symbol==0)
pilots=1;
for (aatx=0;aatxnb_antennas_tx_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_antennas_tx_eNB
for (aarx=0;aarxnb_antennas_rx;aarx++) {
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];
for (rb=0;rbN_RB_DL;rb++) {
// 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;
}
}
}
}
if (rho) {
for (aarx=0;aarxnb_antennas_rx;aarx++) {
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];
for (rb=0;rbN_RB_DL;rb++) {
// 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;
}
}
}
_mm_empty();
_m_empty();
}
void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t symbol) {
uint8_t aatx;
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
int32_t i;
if (frame_parms->nb_antennas_rx>1) {
for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) {
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];
// MRC on each re of rb
for (i=0;iN_RB_DL*3;i++) {
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
}
}
}
_mm_empty();
_m_empty();
}
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;
}
}
_mm_empty();
_m_empty();
}
int32_t avgP[4];
int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars,
LTE_UE_PDCCH **lte_ue_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; //lte_ue_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,
lte_ue_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
lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
high_speed_flag,
frame_parms);
#ifdef MU_RECEIVER
pdcch_extract_rbs_single(lte_ue_common_vars->rxdataF,
lte_ue_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
lte_ue_pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
lte_ue_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_antennas_tx_eNB>1) {
pdcch_extract_rbs_dual(lte_ue_common_vars->rxdataF,
lte_ue_common_vars->dl_ch_estimates[eNB_id],
lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
high_speed_flag,
frame_parms);
} else {
pdcch_extract_rbs_single(lte_ue_common_vars->rxdataF,
lte_ue_common_vars->dl_ch_estimates[eNB_id],
lte_ue_pdcch_vars[eNB_id]->rxdataF_ext,
lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
s,
high_speed_flag,
frame_parms);
}
}
pdcch_channel_level(lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
frame_parms,
avgP,
frame_parms->N_RB_DL);
avgs = 0;
for (aatx=0;aatxnb_antennas_tx_eNB;aatx++)
for (aarx=0;aarxnb_antennas_rx;aarx++)
avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
log2_maxh = (log2_approx(avgs)/2) + 2 + frame_parms->nb_antennas_rx - 1;
#ifdef DEBUG_PHY
msg("[PDCCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgP[0],avgs);
#endif
for (s=0;srxdataF_ext,
lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
(aatx>1) ? lte_ue_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",<e_ue_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(lte_ue_pdcch_vars[eNB_id_i]->rxdataF_ext,
lte_ue_pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
(aatx>1) ? lte_ue_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",<e_ue_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,
lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext,
lte_ue_pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
lte_ue_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,
lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
lte_ue_pdcch_vars[eNB_id]->rho,
lte_ue_pdcch_vars[eNB_id]->dl_ch_rho_ext,
s);
#ifdef DEBUG_PHY
write_output("rxF_comp_d.m","rxF_c_d",<e_ue_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",<e_ue_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,
lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
s);
}
if (mimo_mode == SISO)
pdcch_siso(frame_parms,lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,s);
else
pdcch_alamouti(frame_parms,lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,s);
#ifdef MU_RECEIVER
if (is_secondary_ue) {
pdcch_qpsk_qpsk_llr(frame_parms,
lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
lte_ue_pdcch_vars[eNB_id_i]->rxdataF_comp,
lte_ue_pdcch_vars[eNB_id]->dl_ch_rho_ext,
lte_ue_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)
lte_ue_pdcch_vars[eNB_id]->llr,
s);
/*
#ifdef DEBUG_PHY
if (subframe==5) {
write_output("llr8_seq.m","llr8",<e_ue_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",<e_ue_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,
lte_ue_pdcch_vars[eNB_id]->rxdataF_comp,
(char *)lte_ue_pdcch_vars[eNB_id]->llr,
s);
/*#ifdef DEBUG_PHY
write_output("llr8_seq.m","llr8",<e_ue_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,
lte_ue_pdcch_vars[eNB_id],
mimo_mode);
if (n_pdcch_symbols>3)
n_pdcch_symbols=1;
#ifdef DEBUG_DCI_DECODING
msg("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols);
msg("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
#endif
pdcch_demapping(lte_ue_pdcch_vars[eNB_id]->llr,
lte_ue_pdcch_vars[eNB_id]->wbar,
frame_parms,
n_pdcch_symbols,
get_mi(frame_parms,subframe));
pdcch_deinterleaving(frame_parms,
(uint16_t*)lte_ue_pdcch_vars[eNB_id]->e_rx,
lte_ue_pdcch_vars[eNB_id]->wbar,
n_pdcch_symbols,
mi);
pdcch_unscrambling(frame_parms,
subframe,
lte_ue_pdcch_vars[eNB_id]->e_rx,
get_nCCE(n_pdcch_symbols,frame_parms,mi)*72);
lte_ue_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&0x1f))&1));
if (((s>>(i%32))&1)==0)
llr[i] = -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_antennas_tx_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_antennas_tx_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_antennas_tx_eNB==4) ? 10 : 11)))
return(4);
}
else { // extended CP
if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antennas_tx_eNB==4) ? 9 : 10)))
return(4);
}
}
msg("[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 interpred 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].nCCE),
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].nCCE),
dci_alloc[i].dci_length,
dci_alloc[i].L,
dci_alloc[i].rnti);
}
}
}
}
// 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));
#ifdef DEBUG_DCI_ENCODING
LOG_I(PHY," PDCCH Modulation, Msymb %d\n",Msymb);
#endif
// 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;
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 == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
((int16_t*)&y[0][i])[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
// second antenna position n -> -x1*
((int16_t*)&y[1][i])[0] = (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
e_ptr++;
((int16_t*)&y[1][i])[1] = (*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
LOG_I(PHY," PDCCH Interleaving\n");
#endif
// msg("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
msg("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_antennas_tx_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_antennas_tx_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 { // 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_antennas_tx_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_antennas_tx_eNB > 1)
txdataF[1][tti_offset+0] = 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,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
#endif
mprime++;
txdataF[0][tti_offset+1] = wbar[0][mprime];
if (frame_parms->nb_antennas_tx_eNB > 1)
txdataF[1][tti_offset+1] = 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+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_antennas_tx_eNB > 1)
txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = 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-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_antennas_tx_eNB > 1)
txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = 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-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->lte_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_eNB_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_eNB_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_eNB[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
msg("Before Viterbi\n");
for (i=0;i<16+DCI_LENGTH;i++)
msg("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
#endif
//debug_msg("Doing DCI Viterbi \n");
phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH);
//debug_msg("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_max(uint8_t Mod_id,uint8_t CC_id) {
// check for eNB only !
return(get_nCCE(3,&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,1)); // 5, 15,21
}
void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint8_t subframe,
DCI_ALLOC_t *dci_alloc,
int16_t eNB_id,
LTE_DL_FRAME_PARMS *frame_parms,
uint8_t mi,
uint16_t si_rnti,
uint16_t ra_rnti,
uint8_t L,
uint8_t format_si,
uint8_t format_ra,
uint8_t format_c,
uint8_t sizeof_bits,
uint8_t sizeof_bytes,
uint8_t *dci_cnt,
uint8_t *format0_found,
uint8_t *format_c_found,
uint32_t *CCEmap0,
uint32_t *CCEmap1,
uint32_t *CCEmap2) {
uint16_t crc,CCEind,nCCE;
uint32_t *CCEmap=NULL,CCEmap_mask=0;
int L2=(1<num_pdcch_symbols,frame_parms,mi);
if (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");
}
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;
}
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,
<e_ue_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
msg("crc =>%x\n",crc);
#endif
if (((L>1) && ((crc == si_rnti)||
(crc == ra_rnti)))||
(crc == lte_ue_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].nCCE = 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
msg("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
msg("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==ra_rnti) {
dci_alloc[*dci_cnt].format = format_ra;
// store first nCCE of group for PUCCH transmission of ACK/NAK
lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
*dci_cnt = *dci_cnt+1;
}
else if (crc==lte_ue_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;
lte_ue_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;
lte_ue_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;
lte_ue_pdcch_vars[eNB_id]->nCCE[subframe]=CCEind;
}
}
}
// 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 *phy_vars_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 **lte_ue_pdcch_vars = phy_vars_ue->lte_ue_pdcch_vars;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
uint8_t mi = get_mi(&phy_vars_ue->lte_frame_parms,subframe);
uint16_t ra_rnti=99;
uint8_t format0_found=0,format_c_found=0;
uint8_t tmode = phy_vars_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 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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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);
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_antennas_tx_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_antennas_tx_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 (phy_vars_ue->prach_resources[eNB_id])
ra_rnti = phy_vars_ue->prach_resources[eNB_id]->ra_RNTI;
// First check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI format 0/1A),
// and UE_SPEC format0 (PUSCH) too while we're at it
dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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);
//#ifdef ALL_AGGREGATION
// Disabled for performance
// Now check common search spaces at aggregation 8 (SI_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(lte_ue_pdcch_vars,1,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
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);
//#endif
}
if (phy_vars_ue->UE_mode[eNB_id] <= PRACH)
return(dci_cnt);
if (phy_vars_ue->prach_resources[eNB_id])
ra_rnti = phy_vars_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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
1,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
0,
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) {
// Now check UE_SPEC format 1 search spaces at aggregation 1
old_dci_cnt=dci_cnt;
dci_decoding_procedure0(lte_ue_pdcch_vars,0,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
0,
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(lte_ue_pdcch_vars,0,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
1,
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(lte_ue_pdcch_vars,0,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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(lte_ue_pdcch_vars,0,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
0,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
1,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
0,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
1,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
format1A,
format1A,
format2,
format2_size_bits,
format2_size_bytes,
&dci_cnt,
&format0_found,
&format_c_found,
&CCEmap0,
&CCEmap1,
&CCEmap2);
//#endif
}
else if (tmode >=5) { // 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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
0,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
1,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
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(lte_ue_pdcch_vars,0,
subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
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 **lte_ue_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,lte_ue_pdcch_vars[eNB_id]->crnti,dci_alloc_tx[i].format,
dci_alloc_tx[i].dci_pdu[0]&0x80);
if (dci_alloc_tx[i].rnti == lte_ue_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