nr_dl_channel_estimation.c 25.7 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
 */

knopp's avatar
knopp committed
22

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

Hongzhi Wang's avatar
Hongzhi Wang committed
25 26 27
//#include "defs.h"
//#include "SCHED/defs.h"
#include "PHY/defs_nr_UE.h"
knopp's avatar
knopp committed
28
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
Hongzhi Wang's avatar
Hongzhi Wang committed
29 30
#include "filt16a_32.h"
#include "T.h"
hongzhi wang's avatar
hongzhi wang committed
31
//#define DEBUG_PDSCH
Guy De Souza's avatar
Guy De Souza committed
32
//#define DEBUG_PDCCH
Hongzhi Wang's avatar
Hongzhi Wang committed
33

knopp's avatar
knopp committed
34

Hongzhi Wang's avatar
Hongzhi Wang committed
35
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
knopp's avatar
knopp committed
36 37 38 39 40
			       uint8_t eNB_id,
			       uint8_t eNB_offset,
			       unsigned char Ns,
			       unsigned char l,
			       unsigned char symbol)
Hongzhi Wang's avatar
Hongzhi Wang committed
41
{
knopp's avatar
knopp committed
42
  int pilot[200] __attribute__((aligned(16)));
hongzhi wang's avatar
hongzhi wang committed
43
  unsigned char aarx;
Hongzhi Wang's avatar
Hongzhi Wang committed
44
  unsigned short k;
hongzhi wang's avatar
hongzhi wang committed
45
  unsigned int pilot_cnt;
hongzhi wang's avatar
hongzhi wang committed
46
  int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr;
Hongzhi Wang's avatar
Hongzhi Wang committed
47
  int ch_offset,symbol_offset;
knopp's avatar
knopp committed
48
  int dmrss;
Hongzhi Wang's avatar
Hongzhi Wang committed
49

hongzhi wang's avatar
hongzhi wang committed
50
  //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
51

Hongzhi Wang's avatar
Hongzhi Wang committed
52
  uint8_t nushift, ssb_index=0, n_hf=0;
hongzhi wang's avatar
hongzhi wang committed
53
  int **dl_ch_estimates  =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
Hongzhi Wang's avatar
Hongzhi Wang committed
54 55
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;

56
  nushift =  ue->frame_parms.Nid_cell%4;
hongzhi wang's avatar
hongzhi wang committed
57
  ue->frame_parms.nushift = nushift;
knopp's avatar
knopp committed
58 59 60 61 62 63 64

  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;

  if (ue->is_synchronized ==0 ) dmrss = symbol-1;
  else dmrss = symbol-5;

Hongzhi Wang's avatar
Hongzhi Wang committed
65 66 67 68 69
  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;

knopp's avatar
knopp committed
70
  AssertFatal((symbol > 0 && symbol < 4 && ue->is_synchronized == 0) || 
71
	      (symbol > 4 && symbol < 8 && ue->is_synchronized == 1),
knopp's avatar
knopp committed
72 73 74
	      "symbol %d is illegal for PBCH DM-RS (is_synchronized %d)\n",
	      symbol,ue->is_synchronized);

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

knopp's avatar
knopp committed
77

Hongzhi Wang's avatar
Hongzhi Wang committed
78 79 80
  k = nushift;

#ifdef DEBUG_CH
knopp's avatar
knopp committed
81
  printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns>>1], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
hongzhi wang's avatar
hongzhi wang committed
82
         ue->frame_parms.Ncp,l,Ns,k, symbol);
Hongzhi Wang's avatar
Hongzhi Wang committed
83 84 85 86
#endif

  switch (k) {
  case 0:
knopp's avatar
knopp committed
87 88 89 90
    fl = filt16a_l0;
    fm = filt16a_m0;
    fr = filt16a_r0;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
91 92

  case 1:
knopp's avatar
knopp committed
93 94 95 96
    fl = filt16a_l1;
    fm = filt16a_m1;
    fr = filt16a_r1;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
97 98

  case 2:
knopp's avatar
knopp committed
99 100 101 102
    fl = filt16a_l2;
    fm = filt16a_m2;
    fr = filt16a_r2;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
103 104

  case 3:
knopp's avatar
knopp committed
105 106 107 108
    fl = filt16a_l3;
    fm = filt16a_m3;
    fr = filt16a_r3;
    break;
Hongzhi Wang's avatar
Hongzhi Wang committed
109 110 111 112 113 114 115 116

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

  // generate pilot
knopp's avatar
knopp committed
117
  nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
Hongzhi Wang's avatar
Hongzhi Wang committed
118

knopp's avatar
knopp committed
119
  int re_offset = ssb_offset;
Hongzhi Wang's avatar
Hongzhi Wang committed
120 121
  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {

knopp's avatar
knopp committed
122 123 124 125
    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];
 
Hongzhi Wang's avatar
Hongzhi Wang committed
126 127 128 129 130
    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);
131
#ifdef DEBUG_CH
knopp's avatar
knopp committed
132
    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
133
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
hongzhi wang's avatar
hongzhi wang committed
134 135
    printf("rxF addr %p\n", rxF);
    printf("dl_ch addr %p\n",dl_ch);
136
#endif
hongzhi wang's avatar
hongzhi wang committed
137
    //if ((ue->frame_parms.N_RB_DL&1)==0) {
Hongzhi Wang's avatar
Hongzhi Wang committed
138

knopp's avatar
knopp committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
    // 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);
#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;
    re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    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);
#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;
    re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    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);

#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;
    re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
    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;
	re_offset = (re_offset+144)&(ue->frame_parms.ofdm_symbol_size-1);
	rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
	dl_ch += 288;
      }
Hongzhi Wang's avatar
Hongzhi Wang committed
198 199
      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);
200
#ifdef DEBUG_CH
knopp's avatar
knopp committed
201
      printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
202
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
203
      multadd_real_vector_complex_scalar(fl,
knopp's avatar
knopp committed
204 205 206 207
					 ch,
					 dl_ch,
					 16);

208
      //for (int i= 0; i<8; i++)
knopp's avatar
knopp committed
209
      //            printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
Hongzhi Wang's avatar
Hongzhi Wang committed
210

knopp's avatar
knopp committed
211 212 213 214 215
      pil+=2;
      re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        
  
Hongzhi Wang's avatar
Hongzhi Wang committed
216 217 218
      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);
#ifdef DEBUG_CH
knopp's avatar
knopp committed
219
      printf("pilot %d : 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
220 221
#endif
      multadd_real_vector_complex_scalar(fm,
knopp's avatar
knopp committed
222 223 224
					 ch,
					 dl_ch,
					 16);
Hongzhi Wang's avatar
Hongzhi Wang committed
225
      pil+=2;
knopp's avatar
knopp committed
226 227 228
      re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
        
Hongzhi Wang's avatar
Hongzhi Wang committed
229 230 231 232

      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);

233
#ifdef DEBUG_CH
knopp's avatar
knopp committed
234
      printf("pilot %d : 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]);
235
#endif
Hongzhi Wang's avatar
Hongzhi Wang committed
236 237

      multadd_real_vector_complex_scalar(fr,
knopp's avatar
knopp committed
238 239 240
					 ch,
					 dl_ch,
					 16);
Hongzhi Wang's avatar
Hongzhi Wang committed
241
      pil+=2;
knopp's avatar
knopp committed
242 243
      re_offset = (re_offset+4)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
244
      dl_ch+=24;
Hongzhi Wang's avatar
Hongzhi Wang committed
245

knopp's avatar
knopp committed
246
    }
Hongzhi Wang's avatar
Hongzhi Wang committed
247 248


hongzhi wang's avatar
hongzhi wang committed
249
    //}
Hongzhi Wang's avatar
Hongzhi Wang committed
250 251 252 253 254 255

  }

  return(0);
}

256
int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
knopp's avatar
knopp committed
257 258 259 260 261 262 263
				uint8_t eNB_id,
				uint8_t eNB_offset,
				unsigned char Ns,
				unsigned char l,
				unsigned char symbol,
				unsigned short coreset_start_subcarrier,
				unsigned short nb_rb_coreset)
264
{
knopp's avatar
knopp committed
265
  int pilot[200] __attribute__((aligned(16)));
hongzhi wang's avatar
hongzhi wang committed
266
  unsigned char aarx,p;
267 268 269 270 271 272 273 274
  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;
275 276
  int **dl_ch_estimates  =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset];
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
277 278 279 280 281 282 283 284 285 286 287

  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;

288
  k = coreset_start_subcarrier;
289

hongzhi wang's avatar
hongzhi wang committed
290
#ifdef DEBUG_PDCCH
291
  printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size,
292 293 294 295 296 297 298
         ue->frame_parms.Ncp,l,Ns,k, symbol);
#endif

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

299

300
  // generate pilot 
301
  nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns>>1][symbol], &pilot[0],2000,nb_rb_coreset);
302 303 304 305


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

knopp's avatar
knopp committed
306
    pil   = (int16_t *)&pilot[0];
307
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
knopp's avatar
knopp committed
308
    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
309 310 311 312 313 314

    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
315
#ifdef DEBUG_PDCCH
knopp's avatar
knopp committed
316
    printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
317 318 319 320
    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);
321
#endif
322
    //    if ((ue->frame_parms.N_RB_DL&1)==0) {
323 324 325
      // 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
326
#ifdef DEBUG_PDCCH
327 328 329 330 331 332 333 334 335 336 337 338 339 340
      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
341
#ifdef DEBUG_PDCCH
342 343 344 345 346 347 348 349 350 351 352 353
      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
354
#ifdef DEBUG_PDCCH
355 356 357 358 359 360 361
      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
362
                                         
hongzhi wang's avatar
hongzhi wang committed
363
#ifdef DEBUG_PDCCH       
hongzhi wang's avatar
hongzhi wang committed
364
      for (int m =0; m<12; m++)
knopp's avatar
knopp committed
365
	printf("data :  dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
hongzhi wang's avatar
hongzhi wang committed
366
#endif      
367 368 369
      pil+=2;
      rxF+=8;
      dl_ch+=24;
370
      k+=12;
hongzhi wang's avatar
hongzhi wang committed
371 372
      
      
373

374
      for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt+=3) {
375

376
        if (k >= ue->frame_parms.ofdm_symbol_size){
knopp's avatar
knopp committed
377 378
	  k-=ue->frame_parms.ofdm_symbol_size;
	  rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];}
379 380 381

        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
382
#ifdef DEBUG_PDCCH
383 384 385 386 387 388 389 390 391 392 393 394 395
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#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
396 397
        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
398
#ifdef DEBUG_PDCCH
399
	printf("pilot %d : 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
400 401 402 403 404 405 406 407 408 409 410
#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
411
#ifdef DEBUG_PDCCH
412 413
	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
414 415 416 417 418 419 420

        multadd_real_vector_complex_scalar(fr,
                                           ch,
                                           dl_ch,
                                           16);
        pil+=2;
        rxF+=8;
hongzhi wang's avatar
hongzhi wang committed
421
        dl_ch+=24;
422
        k+=12;
Hongzhi Wang's avatar
Hongzhi Wang committed
423 424 425 426

      }


427
      //}
Hongzhi Wang's avatar
Hongzhi Wang committed
428 429

  }
hongzhi wang's avatar
hongzhi wang committed
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
  
  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;

  default:
    idft = idft512;
    break;
  }

463
  if( (Ns== 1) && (l == 0))
hongzhi wang's avatar
hongzhi wang committed
464 465 466 467
  {
      // 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++) {
468
              if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
hongzhi wang's avatar
hongzhi wang committed
469
              {
470 471 472
                  LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns], l);
                  idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][0],
                          (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
hongzhi wang's avatar
hongzhi wang committed
473 474 475
              }
          }
  }
Hongzhi Wang's avatar
Hongzhi Wang committed
476 477 478 479

  return(0);
}

480 481 482 483
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                              uint8_t eNB_id,
                              uint8_t eNB_offset,
                              unsigned char Ns,
hongzhi wang's avatar
hongzhi wang committed
484
                              unsigned short p,
485 486 487 488 489
                              unsigned char l,
                              unsigned char symbol,
							  unsigned short bwp_start_subcarrier,
							  unsigned short nb_rb_pdsch)
{
hongzhi wang's avatar
hongzhi wang committed
490
  int pilot[1320] __attribute__((aligned(16)));
491 492 493
  unsigned char aarx;
  unsigned short k;
  unsigned int pilot_cnt;
hongzhi wang's avatar
hongzhi wang committed
494
  int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr,*fml,*fmr,*fmm;
495 496 497 498 499
  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;
500 501
  int **dl_ch_estimates  =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].dl_ch_estimates[eNB_offset];
  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF;
502 503 504 505 506 507 508 509 510 511 512 513

  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
514
  int re_offset = k;
515 516

#ifdef DEBUG_CH
hongzhi wang's avatar
hongzhi wang committed
517
  printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%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,
518 519 520 521 522 523 524 525
         ue->frame_parms.Ncp,l,Ns,k, symbol);
#endif

  switch (nushift) {
   case 0:
         fl = filt8_l0;
         fm = filt8_m0;
         fr = filt8_r0;
hongzhi wang's avatar
hongzhi wang committed
526
         fmm = filt8_mm0;
527 528 529 530 531 532 533 534
         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
535
         fmm = filt8_mm1;
536 537 538 539 540 541 542 543 544 545 546 547
         fml = filt8_ml1;
         fmr = filt8_m1;
         break;

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


  // generate pilot
hongzhi wang's avatar
hongzhi wang committed
548
  nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][0], &pilot[0],1000,0,nb_rb_pdsch);
549 550 551

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

knopp's avatar
knopp committed
552
    pil   = (int16_t *)&pilot[0];
553
    rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
knopp's avatar
knopp committed
554
    dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
555 556 557 558 559 560

    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
561
#ifdef DEBUG_PDSCH
knopp's avatar
knopp committed
562
    printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
563
    printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
hongzhi wang's avatar
hongzhi wang committed
564
    printf("rxF addr %p p %d\n", rxF,p);
hongzhi wang's avatar
hongzhi wang committed
565
    printf("dl_ch addr %p nushift %d\n",dl_ch,nushift);
566
#endif
hongzhi wang's avatar
hongzhi wang committed
567
    //if ((ue->frame_parms.N_RB_DL&1)==0) {
568 569 570 571

      // 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
572
#ifdef DEBUG_PDSCH
573 574
      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]);
hongzhi wang's avatar
hongzhi wang committed
575
      printf("data 0 : rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",rxF[2],rxF[3],&rxF[2],ch[0],ch[1],pil[0],pil[1]);
576 577 578 579 580 581
#endif
      multadd_real_vector_complex_scalar(fl,
                                         ch,
                                         dl_ch,
                                         8);
      pil+=2;
hongzhi wang's avatar
hongzhi wang committed
582 583
      re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
584 585 586 587 588
      //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
589
#ifdef DEBUG_PDSCH
590 591 592 593 594 595 596
      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(fml,
                                         ch,
                                         dl_ch,
                                         8);
      pil+=2;
hongzhi wang's avatar
hongzhi wang committed
597 598
      re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
599
      //printf("dl_ch addr %p\n",dl_ch);
hongzhi wang's avatar
hongzhi wang committed
600 601 602
      
      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
603
#ifdef DEBUG_PDSCH
hongzhi wang's avatar
hongzhi wang committed
604
      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]);
hongzhi wang's avatar
hongzhi wang committed
605
#endif
hongzhi wang's avatar
hongzhi wang committed
606 607 608 609
      multadd_real_vector_complex_scalar(fmm,
                                         ch,
                                         dl_ch,
                                         8);
hongzhi wang's avatar
hongzhi wang committed
610 611 612 613
                                         
      //for (int i= 0; i<16; i++)
      //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));
      
hongzhi wang's avatar
hongzhi wang committed
614
      pil+=2;
hongzhi wang's avatar
hongzhi wang committed
615 616
      re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
617
      dl_ch+=8;
618

hongzhi wang's avatar
hongzhi wang committed
619
      for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pdsch-3); pilot_cnt+=2) {
hongzhi wang's avatar
hongzhi wang committed
620 621
    	//if ((pilot_cnt%6)==0)
    		//dl_ch+=4;
hongzhi wang's avatar
hongzhi wang committed
622
		//printf("re_offset %d\n",re_offset);
623 624 625

        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
626
#ifdef DEBUG_PDSCH
627 628 629 630 631 632 633 634
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
        multadd_real_vector_complex_scalar(fm,
                                           ch,
                                           dl_ch,
                                           8);

        pil+=2;
hongzhi wang's avatar
hongzhi wang committed
635 636
        re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
637
      
638 639
        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
640
#ifdef DEBUG_PDSCH
641 642
	printf("pilot %d : 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]);
#endif
hongzhi wang's avatar
hongzhi wang committed
643
        multadd_real_vector_complex_scalar(fmm,
644 645 646 647
                                           ch,
                                           dl_ch,
                                           8);
        pil+=2;
hongzhi wang's avatar
hongzhi wang committed
648 649
        re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
        rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
650
        dl_ch+=8;
651 652

      }
hongzhi wang's avatar
hongzhi wang committed
653
      
654
      // Treat first 2 pilots specially (right edge)
hongzhi wang's avatar
hongzhi wang committed
655 656
	  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
657 658 659 660
#ifdef DEBUG_PDSCH
	printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
      multadd_real_vector_complex_scalar(fm,
hongzhi wang's avatar
hongzhi wang committed
661 662 663
                                         ch,
                                         dl_ch,
                                         8);
hongzhi wang's avatar
hongzhi wang committed
664 665 666 667
                                         
      //for (int i= 0; i<8; i++)
      //printf("dl_ch addr %p %d\n", dl_ch+i, *(dl_ch+i));

hongzhi wang's avatar
hongzhi wang committed
668
      pil+=2;
hongzhi wang's avatar
hongzhi wang committed
669 670
      re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
671
             
672 673
      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
674
#ifdef DEBUG_PDSCH
675
      printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
hongzhi wang's avatar
hongzhi wang committed
676
      printf("pilot %d: rxF - > (%d,%d) addr %p  ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
677 678 679 680 681
#endif
      multadd_real_vector_complex_scalar(fmr,
                                         ch,
                                         dl_ch,
                                         8);
hongzhi wang's avatar
hongzhi wang committed
682
                                         
683
      pil+=2;
hongzhi wang's avatar
hongzhi wang committed
684 685
      re_offset = (re_offset+2)&(ue->frame_parms.ofdm_symbol_size-1);
      rxF   = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
hongzhi wang's avatar
hongzhi wang committed
686 687
      dl_ch+=8;
      
688 689
      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
690 691
#ifdef DEBUG_PDSCH
      printf("pilot %d: 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]);
692 693 694 695 696
#endif
      multadd_real_vector_complex_scalar(fr,
                                         ch,
                                         dl_ch,
                                         8);
hongzhi wang's avatar
hongzhi wang committed
697
    //}
698 699 700 701 702 703

  }

  return(0);
}