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