nr_dl_channel_estimation.c 28.6 KB
Newer Older
Hongzhi Wang's avatar
Hongzhi Wang committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

Raymond Knopp's avatar
Raymond Knopp committed
22

Hongzhi Wang's avatar
Hongzhi Wang committed
23
#include <string.h>
Raymond Knopp's avatar
Raymond Knopp committed
24

25
#include "nr_estimation.h"
Raymond Knopp's avatar
Raymond Knopp committed
26
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
27
#include "filt16a_32.h"
28

hongzhi wang's avatar
hongzhi wang committed
29
//#define DEBUG_PDSCH
Guy De Souza's avatar
Guy De Souza committed
30
//#define DEBUG_PDCCH
Hongzhi Wang's avatar
Hongzhi Wang committed
31

Raymond Knopp's avatar
Raymond Knopp committed
32

33
int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
yilmazt's avatar
yilmazt committed
34 35 36 37 38
                             uint8_t eNB_offset,
                             unsigned char Ns,
                             unsigned char symbol,
                             int dmrss,
                             NR_UE_SSB *current_ssb)
39 40 41 42 43 44 45
{
  int pilot[200] __attribute__((aligned(16)));
  unsigned char aarx;
  unsigned short k;
  unsigned int pilot_cnt;
  int16_t ch[2],*pil,*rxF;
  int symbol_offset;
46

47 48 49 50

  uint8_t nushift;
  uint8_t ssb_index=current_ssb->i_ssb;
  uint8_t n_hf=current_ssb->n_hf;
51
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
52 53 54 55 56 57

  nushift =  ue->frame_parms.Nid_cell%4;
  ue->frame_parms.nushift = nushift;
  unsigned int  ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
  if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;

58 59 60
  AssertFatal(dmrss >= 0 && dmrss < 3,
	      "symbol %d is illegal for PBCH DM-RS \n",
	      dmrss);
61 62 63 64 65 66 67

  symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;


  k = nushift;

#ifdef DEBUG_CH
68
  printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ue->frame_parms.ofdm_symbol_size,
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
         ue->frame_parms.Ncp,Ns,k, symbol);
#endif

  // generate pilot
  nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);

  int re_offset = ssb_offset;
  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {

    pil   = (int16_t *)&pilot[0];
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

#ifdef DEBUG_CH
    printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
    printf("rxF addr %p\n", rxF);
#endif
    //if ((ue->frame_parms.N_RB_DL&1)==0) {

    // Treat first 2 pilots specially (left edge)
    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

    current_ssb->c_re +=ch[0];
    current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
    printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
    printf("pilot 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif

    pil+=2;
101 102
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
103 104 105 106 107 108 109 110 111 112 113 114 115 116
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];


    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

    current_ssb->c_re +=ch[0];
    current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
    printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif

    pil+=2;
117 118
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
119 120 121 122 123 124 125 126 127 128
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

    current_ssb->c_re +=ch[0];
    current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
    printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif

    pil+=2;
129 130
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
131 132 133 134 135 136 137 138 139 140
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

    for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) {

      //	if (pilot_cnt == 30)
      //	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];

      // in 2nd symbol, skip middle  REs (48 with DMRS,  144 for SSS, and another 48 with DMRS) 
      if (dmrss == 1 && pilot_cnt == 12) {
	pilot_cnt=48;
141 142
	//re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
        re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144);
143 144 145 146 147 148 149 150 151
	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
      }
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
      
      current_ssb->c_re +=ch[0];
      current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
152
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
153 154 155
#endif

      pil+=2;
156 157
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
158 159 160 161 162 163 164 165 166 167
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        
  
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

      current_ssb->c_re +=ch[0];
      current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
168
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
169 170
#endif
      pil+=2;
171 172
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
173 174 175 176 177 178 179 180 181 182
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        

      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

      current_ssb->c_re +=ch[0];
      current_ssb->c_im +=ch[1];

#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
183
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
184 185 186
#endif

      pil+=2;
187 188
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
189 190 191 192 193 194 195 196 197 198 199
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

    }


    //}

  }
  return(0);
}

Francesco Mani's avatar
Francesco Mani committed
200

Hongzhi Wang's avatar
Hongzhi Wang committed
201
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
yilmazt's avatar
yilmazt committed
202 203 204 205 206 207
                               uint8_t eNB_offset,
                               unsigned char Ns,
                               unsigned char symbol,
                               int dmrss,
                               uint8_t ssb_index,
                               uint8_t n_hf)
Hongzhi Wang's avatar
Hongzhi Wang committed
208
{
Raymond Knopp's avatar
Raymond Knopp committed
209
  int pilot[200] __attribute__((aligned(16)));
hongzhi wang's avatar
hongzhi wang committed
210
  unsigned char aarx;
Hongzhi Wang's avatar
Hongzhi Wang committed
211
  unsigned short k;
hongzhi wang's avatar
hongzhi wang committed
212
  unsigned int pilot_cnt;
hongzhi wang's avatar
hongzhi wang committed
213
  int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
Hongzhi Wang's avatar
Hongzhi Wang committed
214 215
  int ch_offset,symbol_offset;

hongzhi wang's avatar
hongzhi wang committed
216
  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
Hongzhi Wang's avatar
Hongzhi Wang committed
217

Francesco Mani's avatar
Francesco Mani committed
218
  uint8_t nushift;
219
  int **dl_ch_estimates  =ue->pbch_vars[eNB_offset]->dl_ch_estimates;
220
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
Hongzhi Wang's avatar
Hongzhi Wang committed
221

hongzhi wang's avatar
hongzhi wang committed
222
  nushift =  ue->frame_parms.Nid_cell%4;
hongzhi wang's avatar
hongzhi wang committed
223
  ue->frame_parms.nushift = nushift;
Raymond Knopp's avatar
Raymond Knopp committed
224 225 226
  unsigned int  ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
  if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;

Hongzhi Wang's avatar
Hongzhi Wang committed
227 228 229 230 231
  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
  else
    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;

232 233 234
  AssertFatal(dmrss >= 0 && dmrss < 3,
	      "symbol %d is illegal for PBCH DM-RS \n",
	      dmrss);
Raymond Knopp's avatar
Raymond Knopp committed
235

Hongzhi Wang's avatar
Hongzhi Wang committed
236 237
  symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;

Raymond Knopp's avatar
Raymond Knopp committed
238

Hongzhi Wang's avatar
Hongzhi Wang committed
239 240 241
  k = nushift;

#ifdef DEBUG_CH
Francesco Mani's avatar
Francesco Mani committed
242
  printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
243
         ue->frame_parms.Ncp,Ns,k, symbol);
Hongzhi Wang's avatar
Hongzhi Wang committed
244 245 246 247
#endif

  switch (k) {
  case 0:
Raymond Knopp's avatar
Raymond Knopp committed
248 249 250 251
    fl = filt16a_l0;
    fm = filt16a_m0;
    fr = filt16a_r0;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
252 253

  case 1:
Raymond Knopp's avatar
Raymond Knopp committed
254 255 256 257
    fl = filt16a_l1;
    fm = filt16a_m1;
    fr = filt16a_r1;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
258 259

  case 2:
Raymond Knopp's avatar
Raymond Knopp committed
260 261 262 263
    fl = filt16a_l2;
    fm = filt16a_m2;
    fr = filt16a_r2;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
264 265

  case 3:
Raymond Knopp's avatar
Raymond Knopp committed
266 267 268 269
    fl = filt16a_l3;
    fm = filt16a_m3;
    fr = filt16a_r3;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
270 271 272 273 274 275 276 277

  default:
    msg("pbch_channel_estimation: k=%d -> ERROR\n",k);
    return(-1);
    break;
  }

  // generate pilot
Raymond Knopp's avatar
Raymond Knopp committed
278
  nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
Hongzhi Wang's avatar
Hongzhi Wang committed
279

Raymond Knopp's avatar
Raymond Knopp committed
280
  int re_offset = ssb_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
281 282
  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {

Raymond Knopp's avatar
Raymond Knopp committed
283 284 285
    pil   = (int16_t *)&pilot[0];
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
Francesco Mani's avatar
Francesco Mani committed
286

Hongzhi Wang's avatar
Hongzhi Wang committed
287 288 289 290 291
    memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         1,ue->frame_parms.ofdm_symbol_size);
292
#ifdef DEBUG_CH
Raymond Knopp's avatar
Raymond Knopp committed
293
    printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
Hongzhi Wang's avatar
Hongzhi Wang committed
294
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
hongzhi wang's avatar
hongzhi wang committed
295 296
    printf("rxF addr %p\n", rxF);
    printf("dl_ch addr %p\n",dl_ch);
297
#endif
hongzhi wang's avatar
hongzhi wang committed
298
    //if ((ue->frame_parms.N_RB_DL&1)==0) {
Hongzhi Wang's avatar
Hongzhi Wang committed
299

Raymond Knopp's avatar
Raymond Knopp committed
300 301 302
    // Treat first 2 pilots specially (left edge)
    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
Francesco Mani's avatar
Francesco Mani committed
303

Raymond Knopp's avatar
Raymond Knopp committed
304 305 306 307 308 309 310 311 312
#ifdef DEBUG_CH
    printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
    printf("pilot 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
    multadd_real_vector_complex_scalar(fl,
				       ch,
				       dl_ch,
				       16);
    pil+=2;
313 314
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
315 316 317 318 319 320 321
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

    //for (int i= 0; i<8; i++)
    //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));

    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
Francesco Mani's avatar
Francesco Mani committed
322 323


Raymond Knopp's avatar
Raymond Knopp committed
324 325 326 327 328 329 330 331
#ifdef DEBUG_CH
    printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
    multadd_real_vector_complex_scalar(fm,
				       ch,
				       dl_ch,
				       16);
    pil+=2;
332 333
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
334 335
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];

336 337 338
    ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
    ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

Raymond Knopp's avatar
Raymond Knopp committed
339 340 341 342 343 344 345 346 347
#ifdef DEBUG_CH
    printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif

    multadd_real_vector_complex_scalar(fr,
				       ch,
				       dl_ch,
				       16);
    pil+=2;
348 349
    //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
350 351 352 353 354 355 356 357 358 359 360
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
    dl_ch+=24;

    for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt+=3) {

      //	if (pilot_cnt == 30)
      //	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];

      // in 2nd symbol, skip middle  REs (48 with DMRS,  144 for SSS, and another 48 with DMRS) 
      if (dmrss == 1 && pilot_cnt == 12) {
	pilot_cnt=48;
361 362
	//re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
        re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 144) : (re_offset+144);
Raymond Knopp's avatar
Raymond Knopp committed
363 364 365
	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
	dl_ch += 288;
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
366 367
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
Francesco Mani's avatar
Francesco Mani committed
368

369
#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
370
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
371
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
372
      multadd_real_vector_complex_scalar(fl,
Raymond Knopp's avatar
Raymond Knopp committed
373 374 375 376
					 ch,
					 dl_ch,
					 16);

hongzhi wang's avatar
hongzhi wang committed
377
      //for (int i= 0; i<8; i++)
Raymond Knopp's avatar
Raymond Knopp committed
378
      //            printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
Hongzhi Wang's avatar
Hongzhi Wang committed
379

Raymond Knopp's avatar
Raymond Knopp committed
380
      pil+=2;
381 382
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
383 384 385
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        
  
Hongzhi Wang's avatar
Hongzhi Wang committed
386 387
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
Francesco Mani's avatar
Francesco Mani committed
388

Hongzhi Wang's avatar
Hongzhi Wang committed
389
#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
390
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
Hongzhi Wang's avatar
Hongzhi Wang committed
391 392
#endif
      multadd_real_vector_complex_scalar(fm,
Raymond Knopp's avatar
Raymond Knopp committed
393 394 395
					 ch,
					 dl_ch,
					 16);
Hongzhi Wang's avatar
Hongzhi Wang committed
396
      pil+=2;
397 398
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
399 400
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        
Hongzhi Wang's avatar
Hongzhi Wang committed
401 402 403 404

      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

hongzhi wang's avatar
hongzhi wang committed
405
#ifdef DEBUG_CH
yilmazt's avatar
yilmazt committed
406
      printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
hongzhi wang's avatar
hongzhi wang committed
407
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
408 409

      multadd_real_vector_complex_scalar(fr,
Raymond Knopp's avatar
Raymond Knopp committed
410 411 412
					 ch,
					 dl_ch,
					 16);
Hongzhi Wang's avatar
Hongzhi Wang committed
413
      pil+=2;
414 415
      //re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      re_offset = (re_offset >= ue->frame_parms.ofdm_symbol_size) ? (re_offset - ue->frame_parms.ofdm_symbol_size + 4) : (re_offset+4);
Raymond Knopp's avatar
Raymond Knopp committed
416
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
417
      dl_ch+=24;
Hongzhi Wang's avatar
Hongzhi Wang committed
418

Raymond Knopp's avatar
Raymond Knopp committed
419
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
420 421


hongzhi wang's avatar
hongzhi wang committed
422
    //}
Hongzhi Wang's avatar
Hongzhi Wang committed
423 424 425 426 427

  }
  return(0);
}

428
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
yilmazt's avatar
yilmazt committed
429 430 431 432 433
                                uint8_t eNB_offset,
                                unsigned char Ns,
                                unsigned char symbol,
                                unsigned short coreset_start_subcarrier,
                                unsigned short nb_rb_coreset)
434
{
Raymond Knopp's avatar
Raymond Knopp committed
435
  int pilot[200] __attribute__((aligned(16)));
hongzhi wang's avatar
hongzhi wang committed
436
  unsigned char aarx,p;
437 438 439 440 441 442 443 444
  unsigned short k;
  unsigned int pilot_cnt;
  int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
  int ch_offset,symbol_offset;

  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];

  uint8_t nushift;
445
  int **dl_ch_estimates  =ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates;
446
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
447 448 449 450 451 452 453 454 455 456 457

  nushift = 1;
  ue->frame_parms.nushift = nushift;

  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
  else
    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;

  symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;

458
  k = coreset_start_subcarrier;
459

hongzhi wang's avatar
hongzhi wang committed
460
#ifdef DEBUG_PDCCH
461 462
  printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
         ue->frame_parms.Ncp,Ns,k, symbol);
463 464 465 466 467 468
#endif

  fl = filt16a_l1;
  fm = filt16a_m1;
  fr = filt16a_r1;

469

470
  // generate pilot 
Florian Kaltenberger's avatar
Florian Kaltenberger committed
471
  nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset);
472 473 474 475


  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {

Raymond Knopp's avatar
Raymond Knopp committed
476
    pil   = (int16_t *)&pilot[0];
477
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
Raymond Knopp's avatar
Raymond Knopp committed
478
    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
479 480 481 482 483 484

    memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         1,ue->frame_parms.ofdm_symbol_size);
hongzhi wang's avatar
hongzhi wang committed
485
#ifdef DEBUG_PDCCH
Raymond Knopp's avatar
Raymond Knopp committed
486
    printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
487 488 489 490
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
    printf("rxF addr %p\n", rxF);

    printf("dl_ch addr %p\n",dl_ch);
491
#endif
492
    //    if ((ue->frame_parms.N_RB_DL&1)==0) {
493 494 495
      // Treat first 2 pilots specially (left edge)
      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
hongzhi wang's avatar
hongzhi wang committed
496
#ifdef DEBUG_PDCCH
497 498 499 500 501 502 503 504 505 506 507 508 509 510
      printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
      printf("pilot 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
      multadd_real_vector_complex_scalar(fl,
                                         ch,
                                         dl_ch,
                                         16);
      pil+=2;
      rxF+=8;
      //for (int i= 0; i<8; i++)
      //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));

      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
hongzhi wang's avatar
hongzhi wang committed
511
#ifdef DEBUG_PDCCH
512 513 514 515 516 517 518 519 520 521 522 523
      printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
      multadd_real_vector_complex_scalar(fm,
                                         ch,
                                         dl_ch,
                                         16);
      pil+=2;
      rxF+=8;

      ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
      ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

hongzhi wang's avatar
hongzhi wang committed
524
#ifdef DEBUG_PDCCH
525 526 527 528 529 530 531
      printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif

      multadd_real_vector_complex_scalar(fr,
                                         ch,
                                         dl_ch,
                                         16);
hongzhi wang's avatar
hongzhi wang committed
532
                                         
hongzhi wang's avatar
hongzhi wang committed
533
#ifdef DEBUG_PDCCH       
hongzhi wang's avatar
hongzhi wang committed
534
      for (int m =0; m<12; m++)
Raymond Knopp's avatar
Raymond Knopp committed
535
	printf("data :  dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
hongzhi wang's avatar
hongzhi wang committed
536
#endif      
537 538 539
      pil+=2;
      rxF+=8;
      dl_ch+=24;
540
      k+=12;
hongzhi wang's avatar
hongzhi wang committed
541 542
      
      
543

544
      for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
545

546
        if (k >= ue->frame_parms.ofdm_symbol_size){
Raymond Knopp's avatar
Raymond Knopp committed
547 548
	  k-=ue->frame_parms.ofdm_symbol_size;
	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
549 550 551

        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
hongzhi wang's avatar
hongzhi wang committed
552
#ifdef DEBUG_PDCCH
yilmazt's avatar
yilmazt committed
553
	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
554 555 556 557 558 559 560 561 562 563 564 565
#endif
        multadd_real_vector_complex_scalar(fl,
                                           ch,
                                           dl_ch,
                                           16);

        //for (int i= 0; i<8; i++)
        //            printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));

        pil+=2;
        rxF+=8;

Hongzhi Wang's avatar
Hongzhi Wang committed
566 567
        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
hongzhi wang's avatar
hongzhi wang committed
568
#ifdef DEBUG_PDCCH
yilmazt's avatar
yilmazt committed
569
	printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
Hongzhi Wang's avatar
Hongzhi Wang committed
570 571 572 573 574 575 576 577 578 579 580
#endif
        multadd_real_vector_complex_scalar(fm,
                                           ch,
                                           dl_ch,
                                           16);
        pil+=2;
        rxF+=8;

        ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
        ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);

hongzhi wang's avatar
hongzhi wang committed
581
#ifdef DEBUG_PDCCH
hongzhi wang's avatar
hongzhi wang committed
582 583
	printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
584 585 586 587 588 589 590

        multadd_real_vector_complex_scalar(fr,
                                           ch,
                                           dl_ch,
                                           16);
        pil+=2;
        rxF+=8;
hongzhi wang's avatar
hongzhi wang committed
591
        dl_ch+=24;
592
        k+=12;
Hongzhi Wang's avatar
Hongzhi Wang committed
593 594 595 596

      }


597
      //}
Hongzhi Wang's avatar
Hongzhi Wang committed
598 599

  }
hongzhi wang's avatar
hongzhi wang committed
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
  
  void (*idft)(int16_t *,int16_t *, int);

  switch (ue->frame_parms.ofdm_symbol_size) {
  case 128:
    idft = idft128;
    break;

  case 256:
    idft = idft256;
    break;

  case 512:
    idft = idft512;
    break;

  case 1024:
    idft = idft1024;
    break;

  case 1536:
    idft = idft1536;
    break;

  case 2048:
    idft = idft2048;
    break;

628 629 630 631 632 633
  case 3072:
    idft = idft3072;
    break;

  case 4096:
    idft = idft4096;
hongzhi wang's avatar
hongzhi wang committed
634
    break;
635 636 637 638

  default:
    printf("unsupported ofdm symbol size \n");
    assert(0);
hongzhi wang's avatar
hongzhi wang committed
639 640
  }

641
  if( (Ns== 1) && (symbol == 0))
hongzhi wang's avatar
hongzhi wang committed
642 643 644 645
  {
      // do ifft of channel estimate
      for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
          for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
646
              if (ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx])
hongzhi wang's avatar
hongzhi wang committed
647
              {
648
		LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], symbol);
649 650
		idft((int16_t*) &ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates[(p<<1)+aarx][0],
		     (int16_t*) ue->pdcch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates_time[(p<<1)+aarx],1);
hongzhi wang's avatar
hongzhi wang committed
651 652 653
              }
          }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
654 655 656 657

  return(0);
}

658
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
yilmazt's avatar
yilmazt committed
659 660 661 662 663 664
                                uint8_t eNB_offset,
                                unsigned char Ns,
                                unsigned short p,
                                unsigned char symbol,
                                unsigned short bwp_start_subcarrier,
                                unsigned short nb_rb_pdsch)
665
{
hongzhi wang's avatar
hongzhi wang committed
666
  int pilot[1320] __attribute__((aligned(16)));
667 668 669
  unsigned char aarx;
  unsigned short k;
  unsigned int pilot_cnt;
670
  int16_t ch[10],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm;
671 672 673 674 675
  int ch_offset,symbol_offset;

  //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];

  uint8_t nushift;
676
  int **dl_ch_estimates  =ue->pdsch_vars[ue->current_thread_id[Ns]][eNB_offset]->dl_ch_estimates;
677
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
678 679 680 681 682 683 684 685 686 687 688 689

  nushift = (p>>1)&1;
  ue->frame_parms.nushift = nushift;

  if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
    ch_offset     = ue->frame_parms.ofdm_symbol_size ;
  else
    ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;

  symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;

  k = bwp_start_subcarrier;
hongzhi wang's avatar
hongzhi wang committed
690
  int re_offset = k;
691 692

#ifdef DEBUG_CH
693 694
  printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size,
         ue->frame_parms.Ncp,Ns,k, symbol);
695 696 697 698 699 700 701
#endif

  switch (nushift) {
   case 0:
         fl = filt8_l0;
         fm = filt8_m0;
         fr = filt8_r0;
hongzhi wang's avatar
hongzhi wang committed
702
         fmm = filt8_mm0;
703 704 705 706 707 708 709 710
         fml = filt8_m0;
         fmr = filt8_mr0;
         break;

   case 1:
         fl = filt8_l1;
         fm = filt8_m1;
         fr = filt8_r1;
hongzhi wang's avatar
hongzhi wang committed
711
         fmm = filt8_mm1;
712 713 714 715 716 717 718 719 720 721 722 723
         fml = filt8_ml1;
         fmr = filt8_m1;
         break;

   default:
     msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift);
     return(-1);
     break;
   }


  // generate pilot
724 725 726
  uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
  int config_type = 0; // needs to be updated from higher layer
  nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
727 728 729

  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {

730
    pil   = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)];
731
    k     = k&(ue->frame_parms.ofdm_symbol_size-1);
732
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
Raymond Knopp's avatar
Raymond Knopp committed
733
    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
734 735 736 737 738 739

    memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
    if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
      multadd_complex_vector_real_scalar(dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         ue->ch_est_alpha,dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),
                                         1,ue->frame_parms.ofdm_symbol_size);
hongzhi wang's avatar
hongzhi wang committed
740
#ifdef DEBUG_PDSCH
Raymond Knopp's avatar
Raymond Knopp committed
741
    printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
742
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
hongzhi wang's avatar
hongzhi wang committed
743
    printf("rxF addr %p p %d\n", rxF,p);
hongzhi wang's avatar
hongzhi wang committed
744
    printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
745
#endif
hongzhi wang's avatar
hongzhi wang committed
746
    //if ((ue->frame_parms.N_RB_DL&1)==0) {
747 748
    
    for (uint16_t idx8Sym=0; idx8Sym<(nb_rb_pdsch*12)/8; idx8Sym++ ) {
749

750
      for (uint8_t idxPil=0; idxPil<10; idxPil+=2 ) {
hongzhi wang's avatar
hongzhi wang committed
751
        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
752 753
        ch[idxPil]   = (int16_t)(((int32_t)pil[idx8Sym*8+idxPil]*rxF[0] - (int32_t)pil[idx8Sym*idxPil+1]*rxF[1])>>15);
        ch[idxPil+1] = (int16_t)(((int32_t)pil[idx8Sym*8+idxPil]*rxF[1] + (int32_t)pil[idx8Sym*idxPil+1]*rxF[0])>>15);
754
        re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
755
      }
hongzhi wang's avatar
hongzhi wang committed
756
      
757 758 759 760 761 762
      simple_lerp(ch, dl_ch);
      dl_ch += 16;
    }
    // Do the same for the 2 left over pilots if any (nb_rb_pdsch*12 mod 8)
    if ((nb_rb_pdsch*12)%8) {
      uint16_t used_pils = (nb_rb_pdsch*12)/8*4;
763

764 765 766 767 768 769
      for (uint8_t idxPil=0; idxPil<4; idxPil+=2 ) {
        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
        ch[idxPil]   = (int16_t)(((int32_t)pil[used_pils+idxPil]*rxF[0] - (int32_t)pil[used_pils*idxPil+1]*rxF[1])>>15);
        ch[idxPil+1] = (int16_t)(((int32_t)pil[used_pils+idxPil]*rxF[1] + (int32_t)pil[used_pils*idxPil+1]*rxF[0])>>15);
        re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      }
770 771 772 773 774 775 776 777

      dl_ch[2] = (ch[0]+ch[2]) >> 1;
      dl_ch[3] = (ch[1]+ch[3]) >> 1;
      dl_ch[6] = (ch[4]+ch[5]) >> 1;
      dl_ch[7] = (ch[6]+ch[7]) >> 1;

      dl_ch[0] = ch[0]; dl_ch[1] = ch[1];
      dl_ch[4] = ch[5]; dl_ch[4] = ch[5];
778
    }
779 780 781 782 783
  }

  return(0);
}

784 785 786 787 788 789 790 791 792 793 794 795
void simple_lerp(int16_t *in, int16_t *out)
{
  __m128i est;
  __m128i *x0 = (__m128i*)in;
  __m128i *x1 = (__m128i*)(in+2);
  __m128i *y = (__m128i*)out;

  est  = _mm_srli_epi16(_mm_add_epi16 (*x0, *x1), 1);
  y[0] = _mm_unpacklo_epi32(*x0, est);
  y[1] = _mm_unpackhi_epi32(*x0, est);
}