dci_nr.c 79.2 KB
Newer Older
Agustin's avatar
Agustin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * 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/dci_nr.c
 * \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03.
 * \author R. Knopp, A. Mico Pereperez
 * \date 2018
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr
 * \note
 * \warning
 */
32

Agustin's avatar
Agustin committed
33
#ifdef USER_MODE
34 35 36
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
Agustin's avatar
Agustin committed
37
#endif
38

39 40
#include <LAYER2/NR_MAC_UE/mac_defs.h>
#include <LAYER2/NR_MAC_UE/mac_proto.h>
41 42
#include "executables/softmodem-common.h"

43
#include "nr_transport_proto_ue.h"
hongzhi wang's avatar
hongzhi wang committed
44
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
hongzhi wang's avatar
hongzhi wang committed
45 46
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/CODING/coding_extern.h"
Agustin's avatar
Agustin committed
47
#include "PHY/sse_intrin.h"
Francesco Mani's avatar
Francesco Mani committed
48
#include "PHY/NR_TRANSPORT/nr_dci.h"
Agustin's avatar
Agustin committed
49

50
#include "assertions.h"
Agustin's avatar
Agustin committed
51 52
#include "T.h"

53
//#define DEBUG_DCI_DECODING 1
Agustin's avatar
Agustin committed
54 55 56

//#define NR_LTE_PDCCH_DCI_SWITCH
#define NR_PDCCH_DCI_RUN              // activates new nr functions
Florian Kaltenberger's avatar
Florian Kaltenberger committed
57
//#define NR_PDCCH_DCI_DEBUG            // activates NR_PDCCH_DCI_DEBUG logs
58
#ifdef NR_PDCCH_DCI_DEBUG
59 60 61
#define LOG_DNL(a, ...) printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ )
#define LOG_DD(a, ...) printf("\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ )
#define LOG_DDD(a, ...) printf("\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ )
62 63 64 65 66
#else
#define LOG_DNL(a...)
#define LOG_DD(a...)
#define LOG_DDD(a...)
#endif
Agustin's avatar
Agustin committed
67 68 69 70
#define NR_NBR_CORESET_ACT_BWP 3      // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0)
#define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0)


71
#ifdef LOG_I
72 73
  #undef LOG_I
  #define LOG_I(A,B...) printf(B)
74
#endif
Agustin's avatar
Agustin committed
75

76
#ifdef NR_PDCCH_DCI_RUN
Agustin's avatar
Agustin committed
77

78 79

//static const int16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
Agustin's avatar
Agustin committed
80 81


82 83
void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
                                       uint32_t *z,
hongzhi wang's avatar
hongzhi wang committed
84 85 86 87
                                       uint8_t coreset_time_dur,
                                       uint32_t coreset_nbr_rb,
                                       uint8_t reg_bundle_size_L,
                                       uint8_t coreset_interleaver_size_R,
rmagueta's avatar
rmagueta committed
88 89 90 91
                                       uint8_t n_shift,
                                       uint8_t number_of_candidates,
                                       uint16_t *CCE,
                                       uint8_t *L) {
92 93 94 95
  /*
   * This function will do demapping and deinterleaving from llr containing demodulated symbols
   * Demapping will regroup in REG and bundles
   * Deinterleaving will order the bundles
96
   *
97 98 99
   * In the following example we can see the process. The llr contains the demodulated IQs, but they are not ordered from REG 0,1,2,..
   * In e_rx (z) we will order the REG ids and group them into bundles.
   * Then we will put the bundles in the correct order as indicated in subclause 7.3.2.2
100
   *
101 102 103 104 105 106 107 108
   llr --------------------------> e_rx (z) ----> e_rx (z)
   |   ...
   |   ...
   |   REG 26
   symbol 2    |   ...
   |   ...
   |   REG 5
   |   REG 2
109

110 111 112 113 114 115 116
   |   ...
   |   ...
   |   REG 25
   symbol 1    |   ...
   |   ...
   |   REG 4
   |   REG 1
117

118 119 120 121 122 123 124 125 126
   |   ...
   |   ...                           ...              ...
   |   REG 24 (bundle 7)             ...              ...
   symbol 0    |   ...                           bundle 3         bundle 6
   |   ...                           bundle 2         bundle 1
   |   REG 3                         bundle 1         bundle 7
   |   REG 0  (bundle 0)             bundle 0         bundle 0

  */
rmagueta's avatar
rmagueta committed
127 128 129
  int c = 0, r = 0;
  uint16_t bundle_j = 0, f_bundle_j = 0, f_reg = 0;
  uint32_t coreset_C = 0;
hongzhi wang's avatar
hongzhi wang committed
130 131
  uint16_t index_z, index_llr;
  int coreset_interleaved = 0;
132

rmagueta's avatar
rmagueta committed
133 134 135
  if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0
    coreset_interleaved = 1;
    coreset_C = (uint32_t) ((coreset_nbr_rb * coreset_time_dur) / (coreset_interleaver_size_R * reg_bundle_size_L));
hongzhi wang's avatar
hongzhi wang committed
136
  } else {
rmagueta's avatar
rmagueta committed
137
    reg_bundle_size_L = 6;
hongzhi wang's avatar
hongzhi wang committed
138
  }
Agustin's avatar
Agustin committed
139

rmagueta's avatar
rmagueta committed
140

141
  int f_bundle_j_list[NR_MAX_PDCCH_AGG_LEVEL] = {};
rmagueta's avatar
rmagueta committed
142 143 144

  for (int reg = 0; reg < ((coreset_nbr_rb * coreset_time_dur)); reg++) {
    if ((reg % reg_bundle_size_L) == 0) {
hongzhi wang's avatar
hongzhi wang committed
145
      if (r == coreset_interleaver_size_R) {
rmagueta's avatar
rmagueta committed
146
        r = 0;
hongzhi wang's avatar
hongzhi wang committed
147
        c++;
Agustin's avatar
Agustin committed
148
      }
149

rmagueta's avatar
rmagueta committed
150 151 152 153 154 155 156 157 158 159
      bundle_j = (c * coreset_interleaver_size_R) + r;
      f_bundle_j = ((r * coreset_C) + c + n_shift) % ((coreset_nbr_rb * coreset_time_dur) / reg_bundle_size_L);

      if (coreset_interleaved == 0) f_bundle_j = bundle_j;

      f_bundle_j_list[reg / 6] = f_bundle_j;

    }
    if ((reg % reg_bundle_size_L) == 0) r++;
  }
160

161

rmagueta's avatar
rmagueta committed
162 163
  // Get cce_list indices by reg_idx in ascending order
  int f_bundle_j_list_id = 0;
164
  int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {};
rmagueta's avatar
rmagueta committed
165 166
  for (int c_id = 0; c_id < number_of_candidates; c_id++ ) {
    f_bundle_j_list_id = CCE[c_id];
167
    for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) {
rmagueta's avatar
rmagueta committed
168 169 170 171 172 173 174
      for (int p2 = CCE[c_id]; p2 < CCE[c_id] + L[c_id]; p2++) {
        if (f_bundle_j_list[p2] == p) {
          f_bundle_j_list_ord[f_bundle_j_list_id] = p;
          f_bundle_j_list_id++;
          break;
        }
      }
Agustin's avatar
Agustin committed
175
    }
rmagueta's avatar
rmagueta committed
176 177 178 179
  }


  for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) {
180

rmagueta's avatar
rmagueta committed
181
    f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L);
182
    index_z   = 9*reg;
hongzhi wang's avatar
hongzhi wang committed
183
    index_llr = 9*((uint16_t)floor(f_reg/coreset_time_dur)+((f_reg%coreset_time_dur)*(coreset_nbr_rb)));
184

185 186
    for (int i=0; i<9; i++) {
      z[index_z + i] = llr[index_llr + i];
187
#ifdef NR_PDCCH_DCI_DEBUG
188
      LOG_D(PHY,"[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n",
189 190
             reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]),
             f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
191
#endif
hongzhi wang's avatar
hongzhi wang committed
192
    }
193

hongzhi wang's avatar
hongzhi wang committed
194
    if ((reg%reg_bundle_size_L) == 0) r++;
Agustin's avatar
Agustin committed
195
  }
hongzhi wang's avatar
hongzhi wang committed
196
}
Agustin's avatar
Agustin committed
197 198 199 200 201

#endif

#ifdef NR_PDCCH_DCI_RUN
int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp,
202 203
                     int16_t *pdcch_llr, uint8_t symbol,uint32_t coreset_nbr_rb) {
  int16_t *rxF = (int16_t *) &rxdataF_comp[0][(symbol * coreset_nbr_rb * 12)];
204
  int32_t i;
205 206
  int16_t *pdcch_llrp;
  pdcch_llrp = &pdcch_llr[2 * symbol * coreset_nbr_rb * 9];
Agustin's avatar
Agustin committed
207

208
  if (!pdcch_llrp) {
209
    LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n", symbol);
210 211
    return (-1);
  }
212

213
  LOG_DDD("llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %ld\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr);
214

215 216 217
  //for (i = 0; i < (frame_parms->N_RB_DL * ((symbol == 0) ? 16 : 24)); i++) {
  for (i = 0; i < (coreset_nbr_rb * ((symbol == 0) ? 18 : 18)); i++) {
    if (*rxF > 31)
218
      *pdcch_llrp = 31;
219
    else if (*rxF < -32)
220
      *pdcch_llrp = -32;
221
    else
222
      *pdcch_llrp = (*rxF);
223

224
    LOG_DDD("llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp);
225
    rxF++;
226
    pdcch_llrp++;
227
  }
Agustin's avatar
Agustin committed
228

229
  return (0);
Agustin's avatar
Agustin committed
230 231 232 233
}
#endif


234
#if 0
Agustin's avatar
Agustin committed
235 236 237
int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms,
                  int32_t **rxdataF_comp,
                  char *pdcch_llr,
238 239
                  uint8_t symbol) {
  int16_t *rxF= (int16_t *) &rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
Agustin's avatar
Agustin committed
240 241 242 243 244
  int32_t i;
  char *pdcch_llr8;
  pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12];

  if (!pdcch_llr8) {
245
    LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
Agustin's avatar
Agustin committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
    return(-1);
  }

  //    printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);

  for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) {
    if (*rxF>31)
      *pdcch_llr8=31;
    else if (*rxF<-32)
      *pdcch_llr8=-32;
    else
      *pdcch_llr8 = (char)(*rxF);

    //    printf("%d %d => %d\n",i,*rxF,*pdcch_llr8);
    rxF++;
    pdcch_llr8++;
  }

  return(0);
}
266
#endif
Agustin's avatar
Agustin committed
267 268 269 270

//__m128i avg128P;

//compute average channel_level on each (TX,RX) antenna pair
271
void nr_pdcch_channel_level(int32_t **dl_ch_estimates_ext,
Agustin's avatar
Agustin committed
272 273
                         NR_DL_FRAME_PARMS *frame_parms,
                         int32_t *avg,
274
                         uint8_t nb_rb) {
Agustin's avatar
Agustin committed
275
  int16_t rb;
276
  uint8_t aarx;
Agustin's avatar
Agustin committed
277 278 279 280 281 282 283
#if defined(__x86_64__) || defined(__i386__)
  __m128i *dl_ch128;
  __m128i avg128P;
#elif defined(__arm__)
  int16x8_t *dl_ch128;
  int32x4_t *avg128P;
#endif
284

285 286
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
    //clear average level
Agustin's avatar
Agustin committed
287
#if defined(__x86_64__) || defined(__i386__)
288 289
    avg128P = _mm_setzero_si128();
    dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][0];
Agustin's avatar
Agustin committed
290
#elif defined(__arm__)
frtabu's avatar
frtabu committed
291
    dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[aarx][0];
Agustin's avatar
Agustin committed
292
#endif
293

294
    for (rb=0; rb<(nb_rb*3)>>2; rb++) {
Agustin's avatar
Agustin committed
295
#if defined(__x86_64__) || defined(__i386__)
296 297 298
      avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
      avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
      avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
Agustin's avatar
Agustin committed
299 300
#elif defined(__arm__)
#endif
Raymond Knopp's avatar
Raymond Knopp committed
301
      //      for (int i=0;i<24;i+=2) printf("pdcch channel re %d (%d,%d)\n",(rb*12)+(i>>1),((int16_t*)dl_ch128)[i],((int16_t*)dl_ch128)[i+1]);
302 303
      dl_ch128+=3;
      /*
304 305 306 307 308
      if (rb==0) {
      print_shorts("dl_ch128",&dl_ch128[0]);
      print_shorts("dl_ch128",&dl_ch128[1]);
      print_shorts("dl_ch128",&dl_ch128[2]);
      }
309
      */
Agustin's avatar
Agustin committed
310
    }
311

312 313 314 315 316
    DevAssert( nb_rb );
    avg[aarx] = (((int32_t *)&avg128P)[0] +
                 ((int32_t *)&avg128P)[1] +
                 ((int32_t *)&avg128P)[2] +
                 ((int32_t *)&avg128P)[3])/(nb_rb*9);
317 318
    //            printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
  }
Agustin's avatar
Agustin committed
319 320 321 322 323 324 325 326

#if defined(__x86_64__) || defined(__i386__)
  _mm_empty();
  _m_empty();
#endif
}

#if defined(__x86_64) || defined(__i386__)
327
  __m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
Agustin's avatar
Agustin committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
#elif defined(__arm__)

#endif




#ifdef NR_PDCCH_DCI_RUN
// This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
                                 int32_t **dl_ch_estimates,
                                 int32_t **rxdataF_ext,
                                 int32_t **dl_ch_estimates_ext,
                                 uint8_t symbol,
                                 NR_DL_FRAME_PARMS *frame_parms,
343
                                 uint8_t *coreset_freq_dom,
Agustin's avatar
Agustin committed
344 345
                                 uint32_t coreset_nbr_rb,
                                 uint32_t n_BWP_start) {
346 347 348 349 350 351 352 353 354 355
  /*
   * This function is demapping DM-RS PDCCH RE
   * Implementing 38.211 Section 7.4.1.3.2 Mapping to physical resources
   * PDCCH DM-RS signals are mapped on RE a_k_l where:
   * k = 12*n + 4*kprime + 1
   * n=0,1,..
   * kprime=0,1,2
   * According to this equations, DM-RS PDCCH are mapped on k where k%12==1 || k%12==5 || k%12==9
   *
   */
Agustin's avatar
Agustin committed
356
  // the bitmap coreset_frq_domain contains 45 bits
357
#define CORESET_FREQ_DOMAIN_BITMAP_SIZE   45
Agustin's avatar
Agustin committed
358
  // each bit is associated to 6 RBs
359 360
#define BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN  6
#define NBR_RE_PER_RB_WITH_DMRS           12
Agustin's avatar
Agustin committed
361
  // after removing the 3 DMRS RE, the RB contains 9 RE with PDCCH
362
#define NBR_RE_PER_RB_WITHOUT_DMRS         9
363 364
  uint16_t c_rb, nb_rb = 0;
  //uint8_t rb_count_bit;
cig's avatar
cig committed
365
  uint8_t i, j, aarx;
Agustin's avatar
Agustin committed
366
  int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext;
367

368
#ifdef DEBUG_DCI_DECODING
369
  uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol;
370 371
  LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
#endif
Agustin's avatar
Agustin committed
372 373

  for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
374 375
    dl_ch0 = &dl_ch_estimates[aarx][0];
    LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx);
Agustin's avatar
Agustin committed
376

377
    dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)];
378
    LOG_DDD("dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n",
379
           aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS));
380
    rxF_ext = &rxdataF_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)];
381
    LOG_DDD("rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n",
382
           aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS));
383

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
    /*
     * The following for loop handles treatment of PDCCH contained in table rxdataF (in frequency domain)
     * In NR the PDCCH IQ symbols are contained within RBs in the CORESET defined by higher layers which is located within the BWP
     * Lets consider that the first RB to be considered as part of the CORESET and part of the PDCCH is n_BWP_start
     * Several cases have to be handled differently as IQ symbols are situated in different parts of rxdataF:
     * 1. Number of RBs in the system bandwidth is even
     *    1.1 The RB is <  than the N_RB_DL/2 -> IQ symbols are in the second half of the rxdataF (from first_carrier_offset)
     *    1.2 The RB is >= than the N_RB_DL/2 -> IQ symbols are in the first half of the rxdataF (from element 0)
     * 2. Number of RBs in the system bandwidth is odd
     * (particular case when the RB with DC as it is treated differently: it is situated in symbol borders of rxdataF)
     *    2.1 The RB is <= than the N_RB_DL/2   -> IQ symbols are in the second half of the rxdataF (from first_carrier_offset)
     *    2.2 The RB is >  than the N_RB_DL/2+1 -> IQ symbols are in the first half of the rxdataF (from element 0 + 2nd half RB containing DC)
     *    2.3 The RB is == N_RB_DL/2+1          -> IQ symbols are in the lower border of the rxdataF for first 6 IQ element and the upper border of the rxdataF for the last 6 IQ elements
     * If the first RB containing PDCCH within the UE BWP and within the CORESET is higher than half of the system bandwidth (N_RB_DL),
     * then the IQ symbol is going to be found at the position 0+c_rb-N_RB_DL/2 in rxdataF and
     * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF
     */
Agustin's avatar
Agustin committed
401

402
    LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb);
403
    int c_rb_by6;
rmagueta's avatar
rmagueta committed
404
    c_rb = 0;
405 406 407
    for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
      c_rb_by6 = c_rb/6;
      // skip zeros in frequency domain bitmap
408 409 410 411
      while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) {
	  c_rb+=6;
	  c_rb_by6 = c_rb/6;
	}
Agustin's avatar
Agustin committed
412

413
      LOG_DDD("c_rb=%d\n",c_rb);
laurent's avatar
laurent committed
414
      rxF=NULL;
415

Agustin's avatar
Agustin committed
416
      // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start)
rmagueta's avatar
rmagueta committed
417
      if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
Agustin's avatar
Agustin committed
418
        //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case
rmagueta's avatar
rmagueta committed
419
        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
420
        LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
421
               c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
Agustin's avatar
Agustin committed
422
      }
423

rmagueta's avatar
rmagueta committed
424
      if (((c_rb + n_BWP_start) >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
Agustin's avatar
Agustin committed
425 426
        // number of RBs is even  and c_rb is higher than half system bandwidth (we don't skip DC)
        // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
rmagueta's avatar
rmagueta committed
427
        rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol
428
        LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
Agustin's avatar
Agustin committed
429 430 431
               c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))));
        //rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
        //#ifdef NR_PDCCH_DCI_DEBUG
432
        //  LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
Agustin's avatar
Agustin committed
433 434 435
        //         c_rb,aarx,(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))));
        //#endif
      }
436

rmagueta's avatar
rmagueta committed
437
      if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
Agustin's avatar
Agustin committed
438
        //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case
rmagueta's avatar
rmagueta committed
439
        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
440 441
#ifdef NR_PDCCH_DCI_DEBUG
        LOG_D(PHY,"in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
442
               c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
443
#endif
Agustin's avatar
Agustin committed
444
      }
445

rmagueta's avatar
rmagueta committed
446
      if (((c_rb + n_BWP_start) > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
Agustin's avatar
Agustin committed
447 448
        // number of RBs is odd  and   c_rb is higher than half system bandwidth + 1
        // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC
rmagueta's avatar
rmagueta committed
449
        rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol
450 451
#ifdef NR_PDCCH_DCI_DEBUG
        LOG_D(PHY,"in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
452
               c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size))));
453
#endif
Agustin's avatar
Agustin committed
454
      }
455

rmagueta's avatar
rmagueta committed
456
      if (((c_rb + n_BWP_start) == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC
Agustin's avatar
Agustin committed
457 458
        // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC)
        // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table)
rmagueta's avatar
rmagueta committed
459
        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
460 461
#ifdef NR_PDCCH_DCI_DEBUG
        LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
462
               c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
463
#endif
Agustin's avatar
Agustin committed
464
        j = 0;
465

Agustin's avatar
Agustin committed
466 467 468 469 470 471 472
        for (i = 0; i < 6; i++) { //treating first part of the RB note that i=5 would correspond to DC. We treat it in NR
          if ((i != 1) && (i != 5)) {
            dl_ch0_ext[j] = dl_ch0[i];
            rxF_ext[j++] = rxF[i];
            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
          }
        }
473

Agustin's avatar
Agustin committed
474 475
        // then we point at the begining of the symbol part of rxdataF do process second part of RB
        rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
476 477
#ifdef NR_PDCCH_DCI_DEBUG
        LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n",
478
               c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size)));
479
#endif
Agustin's avatar
Agustin committed
480 481 482 483 484 485 486
        for (; i < 12; i++) {
          if ((i != 9)) {
            dl_ch0_ext[j] = dl_ch0[i];
            rxF_ext[j++] = rxF[(1 + i - 6)];
            //              printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1]));
          }
        }
487

Agustin's avatar
Agustin committed
488 489 490 491
        nb_rb++;
        dl_ch0_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
        rxF_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
        dl_ch0 += 12;
492 493 494
        //rxF += 7;
        //c_rb++;
        //n_BWP_start++; // We have to increment this variable here to be consequent in the for loop afterwards
Agustin's avatar
Agustin committed
495 496 497
        //}
      } else { // treatment of any RB that does not contain the DC
        j = 0;
498

Agustin's avatar
Agustin committed
499 500 501
        for (i = 0; i < 12; i++) {
          if ((i != 1) && (i != 5) && (i != 9)) {
            rxF_ext[j] = rxF[i];
502 503
#ifdef NR_PDCCH_DCI_DEBUG
            LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n",
504 505
                   c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short *) &rxF_ext[j]), i,
                   *(short *) &rxF[i], *(1 + (short *) &rxF[i]));
506
#endif
hongzhi wang's avatar
hongzhi wang committed
507
            dl_ch0_ext[j] = dl_ch0[i];
508

509
            //LOG_DDD("ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i]));
510
            //printf("\t-> dl_ch0[%d] => dl_ch0_ext[%d](%d,%d)\n", i,j, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i]));
hongzhi wang's avatar
hongzhi wang committed
511
            j++;
Agustin's avatar
Agustin committed
512
          } else {
513 514
#ifdef NR_PDCCH_DCI_DEBUG
            LOG_D(PHY,"RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n",
515 516
                   c_rb, i, j, *(short *) &rxF_ext[j], *(1 + (short *) &rxF_ext[j]), i,
                   *(short *) &rxF[i], *(1 + (short *) &rxF[i]));
517
#endif
Agustin's avatar
Agustin committed
518 519
          }
        }
520

Agustin's avatar
Agustin committed
521 522 523 524
        nb_rb++;
        dl_ch0_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
        rxF_ext += NBR_RE_PER_RB_WITHOUT_DMRS;
        dl_ch0 += 12;
525
        //rxF += 12;
Agustin's avatar
Agustin committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
        //}
      }
    }
  }
}

#endif



void nr_pdcch_channel_compensation(int32_t **rxdataF_ext,
                                   int32_t **dl_ch_estimates_ext,
                                   int32_t **rxdataF_comp,
                                   int32_t **rho,
                                   NR_DL_FRAME_PARMS *frame_parms,
                                   uint8_t symbol,
                                   uint8_t output_shift,
543
                                   uint32_t coreset_nbr_rb) {
hongzhi wang's avatar
hongzhi wang committed
544
  uint16_t rb; //,nb_rb=20;
545
  uint8_t aarx;
546
#if defined(__x86_64__) || defined(__i386__)
547
  __m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
548
#elif defined(__arm__)
549
  int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
550
#endif
hongzhi wang's avatar
hongzhi wang committed
551 552
#if defined(__x86_64__) || defined(__i386__)
  __m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
Agustin's avatar
Agustin committed
553 554 555
#elif defined(__arm__)
#endif

556
  for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
Agustin's avatar
Agustin committed
557
#if defined(__x86_64__) || defined(__i386__)
558 559 560 561 562
    dl_ch128          = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*coreset_nbr_rb*12];
    rxdataF128        = (__m128i *)&rxdataF_ext[aarx][symbol*coreset_nbr_rb*12];
    rxdataF_comp128   = (__m128i *)&rxdataF_comp[aarx][symbol*coreset_nbr_rb*12];
    //printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*20*12]);
    //printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
563
    //printf("rxdataf_comp addr %p\n",&rxdataF_comp[(aatx<<1)+aarx][symbol*20*12]);
Agustin's avatar
Agustin committed
564
#elif defined(__arm__)
565
    // to be filled in
Agustin's avatar
Agustin committed
566
#endif
567

568 569
    for (rb=0; rb<(coreset_nbr_rb*3)>>2; rb++) {
      //printf("rb %d\n",rb);
Agustin's avatar
Agustin committed
570
#if defined(__x86_64__) || defined(__i386__)
571 572 573 574 575 576
      // multiply by conjugated channel
      mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
      //  print_ints("re",&mmtmpP0);
      // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
      mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
577
      mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i *)&conjugate[0]);
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
      //  print_ints("im",&mmtmpP1);
      mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]);
      // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
      //  print_ints("re(shift)",&mmtmpP0);
      mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
      //  print_ints("im(shift)",&mmtmpP1);
      mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
      mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
      //      print_ints("c0",&mmtmpP2);
      //  print_ints("c1",&mmtmpP3);
      rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
      //print_shorts("rx:",rxdataF128);
      //print_shorts("ch:",dl_ch128);
      //print_shorts("pack:",rxdataF_comp128);
      // multiply by conjugated channel
      mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
      // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
      mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
598
      mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i *)&conjugate[0]);
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
      mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]);
      // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
      mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
      mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
      mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
      rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
      //print_shorts("rx:",rxdataF128+1);
      //print_shorts("ch:",dl_ch128+1);
      //print_shorts("pack:",rxdataF_comp128+1);
      // multiply by conjugated channel
      mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
      // mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
      mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
      mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
614
      mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i *)&conjugate[0]);
615 616 617 618 619 620 621 622 623 624 625
      mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]);
      // mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
      mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
      mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
      mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
      mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
      rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
      ///////////////////////////////////////////////////////////////////////////////////////////////
      //print_shorts("rx:",rxdataF128+2);
      //print_shorts("ch:",dl_ch128+2);
      //print_shorts("pack:",rxdataF_comp128+2);
626

627
      for (int i=0; i<12 ; i++)
628
        LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n",
629 630 631 632
               (rb*12)+i, ((short *)rxdataF128)[i<<1],((short *)rxdataF128)[1+(i<<1)],
               (rb*12)+i, ((short *)dl_ch128)[i<<1],((short *)dl_ch128)[1+(i<<1)],
               (rb*12)+i, ((short *)rxdataF_comp128)[i<<1],((short *)rxdataF_comp128)[1+(i<<1)]);

633 634 635
      dl_ch128+=3;
      rxdataF128+=3;
      rxdataF_comp128+=3;
hongzhi wang's avatar
hongzhi wang committed
636
#elif defined(__arm__)
637
      // to be filled in
Agustin's avatar
Agustin committed
638
#endif
hongzhi wang's avatar
hongzhi wang committed
639
    }
640
  }
641

Agustin's avatar
Agustin committed
642
#if defined(__x86_64__) || defined(__i386__)
hongzhi wang's avatar
hongzhi wang committed
643 644
  _mm_empty();
  _m_empty();
Agustin's avatar
Agustin committed
645 646 647 648
#endif
}


649
void nr_pdcch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
Agustin's avatar
Agustin committed
650
                         int32_t **rxdataF_comp,
651
                         uint8_t symbol) {
Agustin's avatar
Agustin committed
652 653 654
#if defined(__x86_64__) || defined(__i386__)
  __m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
#elif defined(__arm__)
655
  int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
Agustin's avatar
Agustin committed
656 657 658 659 660
#endif
  int32_t i;

  if (frame_parms->nb_antennas_rx>1) {
#if defined(__x86_64__) || defined(__i386__)
661 662
    rxdataF_comp128_0   = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp128_1   = (__m128i *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
Agustin's avatar
Agustin committed
663
#elif defined(__arm__)
664 665
    rxdataF_comp128_0   = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
    rxdataF_comp128_1   = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
Agustin's avatar
Agustin committed
666
#endif
667

668 669
    // MRC on each re of rb
    for (i=0; i<frame_parms->N_RB_DL*3; i++) {
Agustin's avatar
Agustin committed
670
#if defined(__x86_64__) || defined(__i386__)
671
      rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
Agustin's avatar
Agustin committed
672
#elif defined(__arm__)
673
      rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
Agustin's avatar
Agustin committed
674 675 676 677 678 679 680 681 682 683
#endif
    }
  }

#if defined(__x86_64__) || defined(__i386__)
  _mm_empty();
  _m_empty();
#endif
}

684
#if 0
Agustin's avatar
Agustin committed
685 686
void pdcch_siso(NR_DL_FRAME_PARMS *frame_parms,
                int32_t **rxdataF_comp,
687
                uint8_t l) {
Agustin's avatar
Agustin committed
688 689 690 691 692 693 694 695 696 697 698
  uint8_t rb,re,jj,ii;
  jj=0;
  ii=0;

  for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
    for (re=0; re<12; re++) {
      rxdataF_comp[0][jj++] = rxdataF_comp[0][ii];
      ii++;
    }
  }
}
699
#endif
Agustin's avatar
Agustin committed
700 701

#ifdef NR_PDCCH_DCI_RUN
702
int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
703
                    UE_nr_rxtx_proc_t *proc) {
704

705 706
  uint32_t frame = proc->frame_rx;
  uint32_t slot  = proc->nr_slot_rx;
707 708
  NR_UE_COMMON *common_vars      = &ue->common_vars;
  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
709
  NR_UE_PDCCH *pdcch_vars        = ue->pdcch_vars[proc->thread_id][0];
710 711 712 713 714 715 716 717 718 719
  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;

  uint8_t log2_maxh, aarx;
  int32_t avgs;
  int32_t avgP[4];
  for (int i=0;i<pdcch_vars->nb_search_space;i++) {

    rel15 = &pdcch_vars->pdcch_config[i];
    int n_rb,rb_offset;
    get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset);
cig's avatar
cig committed
720
    for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
721
      LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
cig's avatar
cig committed
722

723
      nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF,
724 725 726 727 728 729 730 731 732
				  pdcch_vars->dl_ch_estimates,
				  pdcch_vars->rxdataF_ext,
				  pdcch_vars->dl_ch_estimates_ext,
				  s,
				  frame_parms,
				  rel15->coreset.frequency_domain_resource,
				  n_rb,
				  rel15->BWPStart);

733 734
      LOG_D(PHY,"we enter nr_pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP);
      LOG_D(PHY,"in nr_pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n");
735
      // compute channel level based on ofdm symbol 0
cig's avatar
cig committed
736 737 738 739
      nr_pdcch_channel_level(pdcch_vars->dl_ch_estimates_ext,
                             frame_parms,
                             avgP,
                             n_rb);
740
      avgs = 0;
cig's avatar
cig committed
741

742
      for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
cig's avatar
cig committed
743
        avgs = cmax(avgs, avgP[aarx]);
744

Francesco Mani's avatar
Francesco Mani committed
745
      log2_maxh = (log2_approx(avgs) / 2) + 5;  //+frame_parms->nb_antennas_rx;
746 747 748 749 750
#ifdef UE_DEBUG_TRACE
      LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs);
#endif
#if T_TRACER
      T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(frame%1024), T_INT(slot),
cig's avatar
cig committed
751
	    T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3]));
752
#endif
753 754
      LOG_D(PHY,"we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh);
      LOG_D(PHY,"in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n");
755 756
      // compute LLRs for ofdm symbol 0 only
      nr_pdcch_channel_compensation(pdcch_vars->rxdataF_ext,
cig's avatar
cig committed
757 758 759 760 761 762 763
                                    pdcch_vars->dl_ch_estimates_ext,
                                    pdcch_vars->rxdataF_comp,
                                    NULL,
                                    frame_parms,
                                    s,
                                    log2_maxh,
                                    n_rb); // log2_maxh+I0_shift
Francesco Mani's avatar
Francesco Mani committed
764
      if (frame_parms->nb_antennas_rx > 1) {
765
        LOG_D(PHY,"we enter nr_pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx);
cig's avatar
cig committed
766
        nr_pdcch_detection_mrc(frame_parms, pdcch_vars->rxdataF_comp,s);
Francesco Mani's avatar
Francesco Mani committed
767
      }
768

769 770
      LOG_D(PHY,"we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s);
      LOG_D(PHY,"in nr_pdcch_llr(rxdataF_comp -> llr)\n");
Francesco Mani's avatar
Francesco Mani committed
771 772 773 774 775
      nr_pdcch_llr(frame_parms,
                   pdcch_vars->rxdataF_comp,
                   pdcch_vars->llr,
                   s,
                   n_rb);
776 777
#if T_TRACER
    
Francesco Mani's avatar
Francesco Mani committed
778 779 780
      //  T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
      //  T_INT(n_pdcch_symbols),
      //  T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
781 782 783
    
#endif
#ifdef DEBUG_DCI_DECODING
Francesco Mani's avatar
Francesco Mani committed
784
      printf("demapping: slot %d, mi %d\n",slot,get_mi(frame_parms,slot));
785 786 787
#endif
    }

788
    LOG_D(PHY,"we enter nr_pdcch_demapping_deinterleaving()\n");
Francesco Mani's avatar
Francesco Mani committed
789 790 791 792 793 794
    nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars->llr,
                                      (uint32_t *) pdcch_vars->e_rx,
                                      rel15->coreset.duration,
                                      n_rb,
                                      rel15->coreset.RegBundleSize,
                                      rel15->coreset.InterleaverSize,
rmagueta's avatar
rmagueta committed
795 796 797 798
                                      rel15->coreset.ShiftIndex,
                                      rel15->number_of_candidates,
                                      rel15->CCE,
                                      rel15->L);
799
    /*
Francesco Mani's avatar
Francesco Mani committed
800 801 802 803 804 805 806
    nr_pdcch_unscrambling(rel15->rnti,
                          frame_parms,
                          slot,
                          pdcch_vars->e_rx,
                          rel15->coreset.duration*n_rb*9*2,
                          // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72,
                          rel15->coreset.pdcch_dmrs_scrambling_id);
807 808 809
    */
    LOG_D(PHY,"we end nr_pdcch_unscrambling()\n");
    LOG_D(PHY,"Ending nr_rx_pdcch() function\n");
Francesco Mani's avatar
Francesco Mani committed
810 811 812

  }
  return (0);
813
}
Agustin's avatar
Agustin committed
814 815 816

#endif

zhenghuangkun's avatar
zhenghuangkun committed
817 818
#if 0
void nr_pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms,
819
                      uint8_t nr_slot_rx,
820 821
                      uint8_t *e,
                      uint32_t length) {
Agustin's avatar
Agustin committed
822 823 824 825 826
  int i;
  uint8_t reset;
  uint32_t x1, x2, s=0;
  reset = 1;
  // x1 is set in lte_gold_generic
827
  x2 = (nr_slot_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
828

Agustin's avatar
Agustin committed
829 830 831 832 833 834
  for (i=0; i<length; i++) {
    if ((i&0x1f)==0) {
      s = lte_gold_generic(&x1, &x2, reset);
      //printf("lte_gold[%d]=%x\n",i,s);
      reset = 0;
    }
835

Agustin's avatar
Agustin committed
836 837 838 839 840
    //    printf("scrambling %d : e %d, c %d\n",i,e[i],((s>>(i&0x1f))&1));
    if (e[i] != 2) // <NIL> element is 2
      e[i] = (e[i]&1) ^ ((s>>(i&0x1f))&1);
  }
}
zhenghuangkun's avatar
zhenghuangkun committed
841
#endif
Agustin's avatar
Agustin committed
842 843 844 845


#ifdef NR_PDCCH_DCI_RUN

cig's avatar
cig committed
846 847 848 849 850
void nr_pdcch_unscrambling(int16_t *z,
                           uint16_t scrambling_RNTI,
                           uint32_t length,
                           uint16_t pdcch_DMRS_scrambling_id,
                           int16_t *z2) {
851 852 853
  int i;
  uint8_t reset;
  uint32_t x1, x2, s = 0;
854
  uint16_t n_id; //{0,1,...,65535}
cig's avatar
cig committed
855
  uint32_t rnti = (uint32_t) scrambling_RNTI;
856 857
  reset = 1;
  // x1 is set in first call to lte_gold_generic
cig's avatar
cig committed
858 859
  n_id = pdcch_DMRS_scrambling_id;
  x2 = ((rnti<<16) + n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3
860

cig's avatar
cig committed
861
  LOG_D(PHY,"PDCCH Unscrambling x2 %x : scrambling_RNTI %x\n", x2, rnti);
862

863 864 865 866 867
  for (i = 0; i < length; i++) {
    if ((i & 0x1f) == 0) {
      s = lte_gold_generic(&x1, &x2, reset);
      reset = 0;
    }
868

869 870
    if (((s >> (i % 32)) & 1) == 1) z2[i] = -z[i];
    else z2[i]=z[i];
871
  }
872
}
Agustin's avatar
Agustin committed
873

874
#endif
Agustin's avatar
Agustin committed
875 876 877


#ifdef NR_PDCCH_DCI_RUN
878
uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
879 880
                                  UE_nr_rxtx_proc_t *proc,
                                  fapi_nr_dci_indication_t *dci_ind) {
881

882
  NR_UE_PDCCH *pdcch_vars        = ue->pdcch_vars[proc->thread_id][0];
883 884 885 886
  fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15;
  for (int i=0;i<pdcch_vars->nb_search_space;i++) {

    rel15 = &pdcch_vars->pdcch_config[i];
887
    //int gNB_id = 0;
888
    int16_t tmp_e[16*108];
889
    rnti_t n_rnti;
890

891 892 893
    for (int j=0;j<rel15->number_of_candidates;j++) {
      int CCEind = rel15->CCE[j];
      int L = rel15->L[j];
cig's avatar
cig committed
894

895 896 897 898 899
      // Loop over possible DCI lengths
      for (int k = 0; k < rel15->num_dci_options; k++) {
        int dci_length = rel15->dci_length_options[k];
        uint64_t dci_estimation[2]= {0};
        const t_nrPolar_params *currentPtrDCI = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L, 1, &ue->polarList);
cig's avatar
cig committed
900

901
        LOG_D(PHY, "Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d\n", j, rel15->number_of_candidates, CCEind, CCEind*9*6*2, L);
cig's avatar
cig committed
902

903 904 905 906 907 908 909 910
        nr_pdcch_unscrambling(&pdcch_vars->e_rx[CCEind*108], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);

        #ifdef DEBUG_DCI_DECODING
          uint32_t * z = (uint32_t *) &pdcch_vars->e_rx[CCEind*108];
          for (int index_z = 0; index_z < 96; index_z++){
            for (int i=0; i<9; i++) {
              LOG_D(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]));
            }
cig's avatar
cig committed
911
          }
912 913 914
        #endif

        uint16_t crc = polar_decoder_int16(tmp_e,
rmagueta's avatar
rmagueta committed
915
                                          dci_estimation,
916 917 918 919 920 921
                                          1,
                                          currentPtrDCI);

        n_rnti = rel15->rnti;

        if (crc == n_rnti) {
Thomas Schlichter's avatar
Thomas Schlichter committed
922
          LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
rmagueta's avatar
rmagueta committed
923
                proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation);
924 925
          dci_ind->SFN = proc->frame_rx;
          dci_ind->slot = proc->nr_slot_rx;
926 927 928 929 930 931 932 933
          dci_ind->dci_list[dci_ind->number_of_dcis].rnti        = n_rnti;
          dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE       = CCEind;
          dci_ind->dci_list[dci_ind->number_of_dcis].dci_format  = rel15->dci_format_options[k];
          dci_ind->dci_list[dci_ind->number_of_dcis].payloadSize = dci_length;
          memcpy((void*)dci_ind->dci_list[dci_ind->number_of_dcis].payloadBits,(void*)dci_estimation,8);
          dci_ind->number_of_dcis++;
          break;    // If DCI is found, no need to check for remaining DCI lengths
        } else {
rmagueta's avatar
rmagueta committed
934
          LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
cig's avatar
cig committed
935
        }
936 937 938 939 940 941 942
      }
    }
  }
  return(dci_ind->number_of_dcis);
}

/*
943 944 945 946 947 948
void nr_dci_decoding_procedure0(int s,
                                int p,
                                int coreset_time_dur,
                                uint16_t coreset_nbr_rb,
                                NR_UE_PDCCH **pdcch_vars,
                                int do_common,
949
                                uint8_t nr_slot_rx,
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
                                NR_DCI_ALLOC_t *dci_alloc,
                                int16_t eNB_id,
                                uint8_t current_thread_id,
                                NR_DL_FRAME_PARMS *frame_parms,
                                //uint8_t mi,
                                uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES],
                                uint8_t L,
                                NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t format_css,
                                NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t format_uss,
                                uint8_t sizeof_bits,
                                uint8_t sizeof_bytes,
                                uint8_t *dci_cnt,
                                crc_scrambled_t *crc_scrambled,
                                format_found_t *format_found,
                                uint16_t pdcch_DMRS_scrambling_id,
                                uint32_t *CCEmap0,
                                uint32_t *CCEmap1,
                                uint32_t *CCEmap2) {
Guy De Souza's avatar
Guy De Souza committed
968
  uint32_t crc, CCEind, nCCE[3];
Agustin's avatar
Agustin committed
969
  uint32_t *CCEmap = NULL, CCEmap_mask = 0;
hongzhi wang's avatar
hongzhi wang committed
970
  uint8_t L2 = (1 << L);
Agustin's avatar
Agustin committed
971 972
  unsigned int Yk, nb_candidates = 0, i, m;
  unsigned int CCEmap_cand;
Guy De Souza's avatar
Guy De Souza committed
973
  uint32_t decoderState=0;
Agustin's avatar
Agustin committed
974
  // A[p], p is the current active CORESET
975
  uint16_t A[3]= {39827,39829,39839};
Agustin's avatar
Agustin committed
976 977 978
  //Table 10.1-2: Maximum number of PDCCH candidates    per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3}
  uint8_t m_max_slot_pdcch_Table10_1_2 [4] = {44,36,22,20};
  //Table 10.1-3: Maximum number of non-overlapped CCEs per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3}
yilmazt's avatar
yilmazt committed
979
  //uint8_t cce_max_slot_pdcch_Table10_1_3 [4] = {56,56,48,32};
Agustin's avatar
Agustin committed
980
  int coreset_nbr_cce_per_symbol=0;
981
  LOG_DDD("format_found is %d \n", *format_found);
982 983
  //if (mode == NO_DCI) {
  //  #ifdef NR_PDCCH_DCI_DEBUG
984
  //    LOG_DDD("skip DCI decoding: expect no DCIs at nr_slot_rx %d in current searchSpace\n", nr_slot_rx);
985 986 987
  //  #endif
  //  return;
  //}
988
  LOG_DDD("frequencyDomainResources=%lx, duration=%d\n",
989 990
         pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources, pdcch_vars[eNB_id]->coreset[p].duration);

Agustin's avatar
Agustin committed
991 992 993 994 995
  // nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols, frame_parms, mi);
  for (int i = 0; i < 45; i++) {
    // this loop counts each bit of the bit map coreset_freq_dom, and increments nbr_RB_coreset for each bit set to '1'
    if (((pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources & 0x1FFFFFFFFFFF) >> i) & 0x1) coreset_nbr_cce_per_symbol++;
  }
996

Agustin's avatar
Agustin committed
997 998 999 1000 1001 1002
  nCCE[p] = pdcch_vars[eNB_id]->coreset[p].duration*coreset_nbr_cce_per_symbol; // 1 CCE = 6 RB
  // p is the current CORESET we are currently monitoring (among the 3 possible CORESETs in a BWP)
  // the number of CCE in the current CORESET is:
  //   the number of symbols in the CORESET (pdcch_vars[eNB_id]->coreset[p].duration)
  //   multiplied by the number of bits set to '1' in the frequencyDomainResources bitmap
  //   (1 bit set to '1' corresponds to 6 RB and 1 CCE = 6 RB)
1003
  LOG_DDD("nCCE[%d]=%d\n",p,nCCE[p]);
Agustin's avatar
Agustin committed
1004

1005 1006 1007 1008 1009 1010
  //  if (nCCE > get_nCCE(3, frame_parms, 1)) {
  //LOG_D(PHY,
  //"skip DCI decoding: nCCE=%d > get_nCCE(3,frame_parms,1)=%d\n",
  //nCCE, get_nCCE(3, frame_parms, 1));
  //return;
 // }
1011

1012 1013 1014 1015 1016 1017
//  if (nCCE < L2) {
//  LOG_D(PHY, "skip DCI decoding: nCCE=%d < L2=%d\n", nCCE, L2);
//  return;
//  }

//  if (mode == NO_DCI) {
1018 1019
//  LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_slot_rx %d\n",
//  nr_slot_rx);
1020 1021
//  return;
//  }
1022

Agustin's avatar
Agustin committed
1023 1024
  if (do_common == 1) {
    Yk = 0;
1025

Agustin's avatar
Agustin committed
1026
    if (pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.common_dci_formats == cformat2_0) {
1027 1028
      // for dci_format_2_0, the nb_candidates is obtained from a different variable
      switch (L2) {
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
        case 1:
          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel1;
          break;

        case 2:
          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel2;
          break;

        case 4:
          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel4;
          break;

        case 8:
          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel8;
          break;

        case 16:
          nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.sfi_nrofCandidates_aggrlevel16;
          break;

        default:
          break;
1051
      }
Agustin's avatar
Agustin committed
1052
    } else if (pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.common_dci_formats == cformat2_3) {
1053 1054
      // for dci_format_2_3, the nb_candidates is obtained from a different variable
      nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.srs_nrofCandidates;
Agustin's avatar
Agustin committed
1055 1056
    } else {
      nb_candidates = (L2 == 4) ? 4 : ((L2 == 8)? 2 : 1); // according to Table 10.1-1 (38.213 section 10.1)
1057
      LOG_DDD("we are in common searchSpace and nb_candidates=%u for L2=%d\n", nb_candidates, L2);
Agustin's avatar
Agustin committed
1058 1059 1060
    }
  } else {
    switch (L2) {
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
      case 1:
        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel1;
        break;

      case 2:
        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel2;
        break;

      case 4:
        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel4;
        break;

      case 8:
        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel8;
        break;

      case 16:
        nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].nrofCandidates_aggrlevel16;
        break;

      default:
        break;
Agustin's avatar
Agustin committed
1083
    }
1084

Agustin's avatar
Agustin committed
1085 1086 1087 1088
    // Find first available in ue specific search space
    // according to procedure in Section 10.1 of 38.213
    // compute Yk
    Yk = (unsigned int) pdcch_vars[eNB_id]->crnti;
1089

1090
    for (i = 0; i <= nr_slot_rx; i++)
1091
      Yk = (Yk * A[p%3]) % 65537;
Agustin's avatar
Agustin committed
1092
  }
1093

1094
  LOG_DDD("L2(%d) | nCCE[%d](%d) | Yk(%u) | nb_candidates(%u)\n", L2, p, nCCE[p], Yk, nb_candidates);
1095 1096 1097
  //  for (CCEind=0;
  //    CCEind<nCCE2;
  //    CCEind+=(1<<L)) {
1098 1099
  //  if (nb_candidates * L2 > nCCE[p])
  //    nb_candidates = nCCE[p] / L2;
1100
  // In the next code line there is maybe a bug. The spec is not comparing Table 10.1-2 with nb_candidates, but with total number of candidates for all s and all p
1101
  int m_p_s_L_max = (m_max_slot_pdcch_Table10_1_2[1]<=nb_candidates ? m_max_slot_pdcch_Table10_1_2[1] : nb_candidates);
1102

Agustin's avatar
Agustin committed
1103
  if (L==4) m_p_s_L_max=1; // Table 10.1-2 is not defined for L=4
1104

1105
  if(0 <= L && L < 4) LOG_DDD("m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]);
1106

Agustin's avatar
Agustin committed
1107 1108
  for (m = 0; m < nb_candidates; m++) {
    int n_ci = 0;
1109

1110
    if (nCCE[p] < L2) return;
yilmazt's avatar
yilmazt committed
1111

1112 1113
  LOG_DDD("debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",nCCE[p] / L2,p,nCCE[p],L2);
  LOG_DDD("debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",L2*m_p_s_L_max,L2,m_p_s_L_max);
yilmazt's avatar
yilmazt committed
1114
  CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2);
frtabu's avatar
frtabu committed
1115
  LOG_DDD("CCEind(%u) = (((Yk(%u) + ((m(%u)*nCCE[p](%u))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n",
1116
            CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max);
frtabu's avatar
frtabu committed
1117
  LOG_DDD("n_candidate(m)=%u | CCEind=%u |",m,CCEind);
1118

Agustin's avatar
Agustin committed
1119 1120 1121 1122 1123 1124
    if (CCEind < 32)
      CCEmap = CCEmap0;
    else if (CCEind < 64)
      CCEmap = CCEmap1;
    else if (CCEind < 96)
      CCEmap = CCEmap2;
frtabu's avatar
frtabu committed
1125
    else AssertFatal(1==0,"Illegal CCEind %u (Yk %u, m %u, nCCE %u, L2 %u\n", CCEind, Yk, m, nCCE[p], L2);
1126

Agustin's avatar
Agustin committed
1127
    switch (L2) {
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
      case 1:
        CCEmap_mask = (1 << (CCEind & 0x1f));
        break;

      case 2:
        CCEmap_mask = (3 << (CCEind & 0x1f));
        break;

      case 4:
        CCEmap_mask = (0xf << (CCEind & 0x1f));
        break;

      case 8:
        CCEmap_mask = (0xff << (CCEind & 0x1f));
        break;

      case 16:
        CCEmap_mask = (0xfff << (CCEind & 0x1f));
        break;

      default:
        LOG_E(PHY, "Illegal L2 value %d\n", L2);
        //mac_xface->macphy_exit("Illegal L2\n");
        return; // not reached
Agustin's avatar
Agustin committed
1152
    }
1153

Agustin's avatar
Agustin committed
1154 1155
    CCEmap_cand = (*CCEmap) & CCEmap_mask;
    // CCE is not allocated yet
1156
    LOG_DDD("CCEmap_cand=%u \n",CCEmap_cand);
1157

1158
    if (CCEmap_cand == 0) {
1159
#ifdef DEBUG_DCI_DECODING
1160

1161
      if (do_common == 1)
1162 1163
        LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
              pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
1164
      else
1165 1166 1167
        LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
              pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_uss);

1168
#endif
1169 1170
      LOG_DDD("... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L);
      LOG_DDD("... we have to replace this part of the code by polar decoding\n");
1171
      //      for (int m=0; m < (nCCE[p]*6*9*2); m++)
frtabu's avatar
frtabu committed
1172
      LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%u): \n",
1173
             coreset_time_dur,coreset_nbr_rb,p,CCEind);
1174 1175 1176 1177 1178 1179
      
      //int reg_p=0,reg_e=0;
      //for (int m=0; m < (L2*6); m++){
      //reg_p = (((int)floor(m/coreset_time_dur))+((m%coreset_time_dur)*(L2*6/coreset_time_dur)))*9*2;
      //reg_e = m*9*2;
      //for (int i=0; i<9*2; i++){
1180
      //polar_input[reg_p+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1.0):(-1.0);
1181
      //polar_input[reg_e+i] = (pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]>0) ? (1/sqrt(2)):((-1)/sqrt(2));
1182 1183 1184 1185
      //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_e+i,polar_input[reg_e+i],
      //        ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]);
      //printf("\t m=%d \tpolar_input[%d]=%lf <-> e_rx[%d]=%d\n",m,reg_p+i,polar_input[reg_p+i],
      //        ((CCEind*9*6*2) + reg_e + i),pdcch_vars[eNB_id]->e_rx[((CCEind*9*6*2) + reg_e + i)]);
1186 1187
      //}
      //}
1188

1189 1190 1191 1192 1193 1194
      //#ifdef NR_PDCCH_DCI_DEBUG
      //printf("\n");
      //int j=0;
      //uint32_t polar_hex[27] = {0};
      //for (int i=0; i<L2*9*6*2; i++){2
      //if ((i%32 == 0) && (i!=0)) j++;
1195
      //polar_hex[j] = (polar_hex[j]<<1) + ((polar_input[i]==-1)? 1:0);
1196 1197 1198 1199 1200
      //polar_hex[j] = polar_hex[j] + (((polar_input[i]==((-1)/sqrt(2)))?1:0)<<(i%32));
      //}
      //for (j=0;j<27;j++) LOG_DDD("polar_hex[%d]=%x\n",j,polar_hex[j]);
      //#endif
      
1201
      uint64_t dci_estimation[2]= {0};
Raymond Knopp's avatar
Raymond Knopp committed
1202
      const t_nrPolar_params *currentPtrDCI=nr_polar_params(1, sizeof_bits, L2,1);
1203
      decoderState = polar_decoder_int16(&pdcch_vars[eNB_id]->e_rx[CCEind*9*6*2],
1204
                                         dci_estimation,
1205
                                         1,
1206
                                         currentPtrDCI);
Guy De Souza's avatar
Guy De Souza committed
1207
      crc = decoderState;
1208
      //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits);
1209 1210
      LOG_DDD("... we end function dci_decoding() with crc=%x\n",crc);
      LOG_DDD("... we have to replace this part of the code by polar decoding\n");
1211
#ifdef DEBUG_DCI_DECODING
1212
      LOG_DDD("(nr_dci_decoding_procedure0: crc =>%d\n",crc);
1213
#endif //uint16_t tc_rnti, uint16_t int_rnti, uint16_t sfi_rnti, uint16_t tpc_pusch_rnti, uint16_t tpc_pucch_rnti, uint16_t tpc_srs__rnti
1214 1215
      LOG_DDD("format_found=%d\n",*format_found);
      LOG_DDD("crc_scrambled=%d\n",*crc_scrambled);
1216 1217

      if (crc == crc_scrambled_values[_C_RNTI_])  {
1218 1219
        *crc_scrambled =_c_rnti;
        *format_found=1;
1220
      }
1221

1222
      if (crc == crc_scrambled_values[_CS_RNTI_])  {
1223 1224
        *crc_scrambled =_cs_rnti;
        *format_found=1;
1225
      }
1226

1227
      if (crc == crc_scrambled_values[_NEW_RNTI_])  {
1228 1229
        *crc_scrambled =_new_rnti;
        *format_found=1;
1230
      }
1231

1232
      if (crc == crc_scrambled_values[_TC_RNTI_])  {
1233 1234
        *crc_scrambled =_tc_rnti;
        *format_found=_format_1_0_found;
Agustin's avatar
Agustin committed
1235
      }
1236

1237
      if (crc == crc_scrambled_values[_P_RNTI_])  {
1238 1239
        *crc_scrambled =_p_rnti;
        *format_found=_format_1_0_found;
1240
      }
1241

1242
      if (crc == crc_scrambled_values[_SI_RNTI_])  {
1243 1244
        *crc_scrambled =_si_rnti;
        *format_found=_format_1_0_found;
1245
      }
1246

1247
      if (crc == crc_scrambled_values[_RA_RNTI_])  {
1248 1249
        *crc_scrambled =_ra_rnti;
        *format_found=_format_1_0_found;
1250
      }
1251

1252
      if (crc == crc_scrambled_values[_SP_CSI_RNTI_])  {
1253 1254
        *crc_scrambled =_sp_csi_rnti;
        *format_found=_format_0_1_found;
1255
      }
1256

1257
      if (crc == crc_scrambled_values[_SFI_RNTI_])  {
1258 1259
        *crc_scrambled =_sfi_rnti;
        *format_found=_format_2_0_found;
1260
      }
1261

1262
      if (crc == crc_scrambled_values[_INT_RNTI_])  {
1263 1264
        *crc_scrambled =_int_rnti;
        *format_found=_format_2_1_found;
1265
      }
1266

1267
      if (crc == crc_scrambled_values[_TPC_PUSCH_RNTI_]) {
1268 1269
        *crc_scrambled =_tpc_pusch_rnti;
        *format_found=_format_2_2_found;
1270
      }
1271

1272
      if (crc == crc_scrambled_values[_TPC_PUCCH_RNTI_]) {
1273 1274
        *crc_scrambled =_tpc_pucch_rnti;
        *format_found=_format_2_2_found;
1275
      }
1276

1277
      if (crc == crc_scrambled_values[_TPC_SRS_RNTI_]) {
1278 1279
        *crc_scrambled =_tpc_srs_rnti;
        *format_found=_format_2_3_found;
1280
      }
1281

1282

1283 1284
      LOG_DDD("format_found=%d\n",*format_found);
      LOG_DDD("crc_scrambled=%d\n",*crc_scrambled);
1285

1286
      if (*format_found!=255) {
1287 1288 1289 1290
        dci_alloc[*dci_cnt].dci_length = sizeof_bits;
        dci_alloc[*dci_cnt].rnti = crc;
        dci_alloc[*dci_cnt].L = L;
        dci_alloc[*dci_cnt].firstCCE = CCEind;
1291 1292
        memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_estimation,8);

1293
        LOG_DDD("rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n",
1294
                dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes);
1295
        LOG_DDD("dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n",
1296 1297 1298 1299 1300 1301
                *dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]);
        if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) {
          if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) {
            dci_alloc[*dci_cnt].format = format1_0;
            *dci_cnt = *dci_cnt + 1;
            *format_found=_format_1_0_found;
1302
            //      LOG_DDD("a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt);
1303 1304 1305 1306 1307
          } else {
            if ((dci_estimation[0]&1) == 0) {
              dci_alloc[*dci_cnt].format = format0_0;
              *dci_cnt = *dci_cnt + 1;
              *format_found=_format_0_0_found;
1308
              //        LOG_DDD("b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt);
1309 1310 1311 1312 1313 1314
            }

            if ((dci_estimation[0]&1) == 1) {
              dci_alloc[*dci_cnt].format = format1_0;
              *dci_cnt = *dci_cnt + 1;
              *format_found=_format_1_0_found;
1315
              //        LOG_DDD("c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt);
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
            }
          }
        }

        if (format_css == cformat2_0) {
          dci_alloc[*dci_cnt].format = format2_0;
          *dci_cnt = *dci_cnt + 1;
          *format_found=_format_2_0_found;
        }

        if (format_css == cformat2_1) {
          dci_alloc[*dci_cnt].format = format2_1;
          *dci_cnt = *dci_cnt + 1;
          *format_found=_format_2_1_found;
        }

        if (format_css == cformat2_2) {
          dci_alloc[*dci_cnt].format = format2_2;
          *dci_cnt = *dci_cnt + 1;
          *format_found=_format_2_2_found;
        }

        if (format_css == cformat2_3) {
          dci_alloc[*dci_cnt].format = format2_3;
          *dci_cnt = *dci_cnt + 1;
          *format_found=_format_2_3_found;
        }

        if (format_uss == uformat0_1_and_1_1) {
          if ((dci_estimation[0]&1) == 0) {
            dci_alloc[*dci_cnt].format = format0_1;
            *dci_cnt = *dci_cnt + 1;
            *format_found=_format_0_1_found;
          }

          if ((dci_estimation[0]&1) == 1) {
            dci_alloc[*dci_cnt].format = format1_1;
            *dci_cnt = *dci_cnt + 1;
            *format_found=_format_1_1_found;
          }
        }

        // store first nCCE of group for PUCCH transmission of ACK/NAK
1359
        pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind;
1360

1361 1362 1363 1364 1365 1366 1367 1368 1369
        //        if (crc == si_rnti) {
        //        dci_alloc[*dci_cnt].format = format_si;
        //        *dci_cnt = *dci_cnt + 1;
        //        } else if (crc == p_rnti) {
        //        dci_alloc[*dci_cnt].format = format_p;
        //        *dci_cnt = *dci_cnt + 1;
        //        } else if (crc == ra_rnti) {
        //        dci_alloc[*dci_cnt].format = format_ra;
        //        // store first nCCE of group for PUCCH transmission of ACK/NAK
1370
        //        pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind;
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
        //        *dci_cnt = *dci_cnt + 1;
        //        } else if (crc == pdcch_vars[eNB_id]->crnti) {

        //        if ((mode & UL_DCI) && (format_c == format0)
        //        && ((dci_decoded_output[current_thread_id][0] & 0x80)
        //        == 0)) { // check if pdu is format 0 or 1A
        //        if (*format0_found == 0) {
        //        dci_alloc[*dci_cnt].format = format0;
        //        *format0_found = 1;
        //        *dci_cnt = *dci_cnt + 1;
1381
        //        pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind;
1382 1383 1384 1385
        //        }
        //        } else if (format_c == format0) { // this is a format 1A DCI
        //        dci_alloc[*dci_cnt].format = format1A;
        //        *dci_cnt = *dci_cnt + 1;
1386
        //        pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind;
1387 1388 1389 1390 1391 1392
        //        } else {
        //        // store first nCCE of group for PUCCH transmission of ACK/NAK
        //        if (*format_c_found == 0) {
        //        dci_alloc[*dci_cnt].format = format_c;
        //        *dci_cnt = *dci_cnt + 1;
        //        *format_c_found = 1;
1393
        //        pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind;
1394 1395 1396
        //        }
        //        }
        //        }
1397
        //LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[nr_slot_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_slot_rx, pdcch_vars[eNB_id]->nCCE[nr_slot_rx],L2);
1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419
        //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
        switch (1 << L) {
          case 1:
            *CCEmap |= (1 << (CCEind & 0x1f));
            break;

          case 2:
            *CCEmap |= (1 << (CCEind & 0x1f));
            break;

          case 4:
            *CCEmap |= (1 << (CCEind & 0x1f));
            break;

          case 8:
            *CCEmap |= (1 << (CCEind & 0x1f));
            break;

          case 16:
            *CCEmap |= (1 << (CCEind & 0x1f));
            break;
        }
Agustin's avatar
Agustin committed
1420

1421 1422 1423 1424 1425
#ifdef DEBUG_DCI_DECODING
        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %d in CCE %d (CCEmap %x) candidate %d / %d \n",
              *dci_cnt,crc,1<<L,sizeof_bits,dci_alloc[*dci_cnt-1].format,CCEind,*CCEmap,m,nb_candidates );
        //  nr_extract_dci_into(
        //  dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);
Agustin's avatar
Agustin committed
1426
#endif
1427
        return;
Agustin's avatar
Agustin committed
1428 1429
      } // rnti match
    } else { // CCEmap_cand == 0
1430 1431
      printf("\n");
    }
1432

1433 1434 1435 1436 1437 1438 1439 1440
    
    //  if ( agregationLevel != 0xFF &&
    //  (format_c == format0 && m==0 && si_rnti != SI_RNTI))
    //  {
    //  //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
    //  return;
    //  }
    
Agustin's avatar
Agustin committed
1441
  } // candidate loop
1442

1443
  LOG_DDD("end candidate loop\n");
Agustin's avatar
Agustin committed
1444 1445
}
*/
1446
#endif
1447 1448


1449

1450 1451 1452 1453




Agustin's avatar
Agustin committed
1454

1455
#if 0
Agustin's avatar
Agustin committed
1456 1457 1458


uint8_t nr_dci_decoding_procedure(int s,
1459 1460 1461 1462 1463
                                  int p,
                                  PHY_VARS_NR_UE *ue,
                                  NR_DCI_ALLOC_t *dci_alloc,
                                  NR_SEARCHSPACE_TYPE_t searchSpacetype,
                                  int16_t eNB_id,
1464
                                  uint8_t nr_slot_rx,
1465 1466 1467 1468 1469 1470
                                  uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
                                  uint16_t n_RB_ULBWP,
                                  uint16_t n_RB_DLBWP,
                                  crc_scrambled_t *crc_scrambled,
                                  format_found_t *format_found,
                                  uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) {
1471
  //                                  uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS],
1472 1473
  LOG_DD("(nr_dci_decoding_procedure) nr_slot_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n",
         nr_slot_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found);
hongzhi wang's avatar
hongzhi wang committed
1474 1475 1476 1477
  int do_common = (int)searchSpacetype;
  uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS];
  crc_scrambled_t crc_scrambled_ = *crc_scrambled;
  format_found_t format_found_   = *format_found;
Agustin's avatar
Agustin committed
1478 1479
  uint8_t dci_cnt = 0, old_dci_cnt = 0;
  uint32_t CCEmap0 = 0, CCEmap1 = 0, CCEmap2 = 0;
1480 1481
  NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]];
  NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]][eNB_id];
hongzhi wang's avatar
hongzhi wang committed
1482 1483 1484
  uint16_t pdcch_DMRS_scrambling_id = pdcch_vars2->coreset[p].pdcchDMRSScramblingID;
  uint64_t coreset_freq_dom = pdcch_vars2->coreset[p].frequencyDomainResources;
  int coreset_time_dur = pdcch_vars2->coreset[p].duration;
1485
  uint16_t coreset_nbr_rb=0;
1486

hongzhi wang's avatar
hongzhi wang committed
1487 1488 1489
  for (int i = 0; i < 45; i++) {
    // this loop counts each bit of the bit map coreset_freq_dom, and increments nbr_RB_coreset for each bit set to '1'
    if (((coreset_freq_dom & 0x1FFFFFFFFFFF) >> i) & 0x1) coreset_nbr_rb++;
Agustin's avatar
Agustin committed
1490
  }
1491

hongzhi wang's avatar
hongzhi wang committed
1492 1493
  coreset_nbr_rb = 6 * coreset_nbr_rb;
  // coreset_time_dur,coreset_nbr_rb,
Agustin's avatar
Agustin committed
1494
  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
1495
  //uint8_t mi;// = get_mi(&ue->frame_parms, nr_slot_rx);
1496 1497
  //uint8_t tmode = ue->transmission_mode[eNB_id];
  //uint8_t frame_type = frame_parms->frame_type;
1498 1499 1500 1501 1502 1503
  uint8_t format_0_0_1_0_size_bits = 0, format_0_0_1_0_size_bytes = 0; //FIXME
  uint8_t format_0_1_1_1_size_bits = 0, format_0_1_1_1_size_bytes = 0; //FIXME
  uint8_t format_2_0_size_bits = 0, format_2_0_size_bytes = 0; //FIXME
  uint8_t format_2_1_size_bits = 0, format_2_1_size_bytes = 0; //FIXME
  uint8_t format_2_2_size_bits = 0, format_2_2_size_bytes = 0; //FIXME
  uint8_t format_2_3_size_bits = 0, format_2_3_size_bytes = 0; //FIXME
Agustin's avatar
Agustin committed
1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
  /*
   *
   * The implementation of this function will depend on the information given by the searchSpace IE
   *
   * In LTE the UE has no knowledge about:
   * - the type of search (common or ue-specific)
   * - the DCI format it is going to be decoded when performing the PDCCH monitoring
   * So the blind decoding has to be done for common and ue-specific searchSpaces for each aggregation level and for each dci format
   *
   * In NR the UE has a knowledge about the search Space type and the DCI format it is going to be decoded,
   * so in the blind decoding we can call the function nr_dci_decoding_procedure0 with the searchSpace type and the dci format parameter
   * We will call this function as many times as aggregation levels indicated in searchSpace
   * Implementation according to 38.213 v15.1.0 Section 10.
   *
   */
hongzhi wang's avatar
hongzhi wang committed
1519 1520
  NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t css_dci_format = pdcch_vars2->searchSpace[s].searchSpaceType.common_dci_formats;       //FIXME!!!
  NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t uss_dci_format = pdcch_vars2->searchSpace[s].searchSpaceType.ue_specific_dci_formats;  //FIXME!!!
Agustin's avatar
Agustin committed
1521 1522 1523 1524 1525 1526 1527 1528 1529
  // The following initialization is only for test purposes. To be removed
  // NR_UE_SEARCHSPACE_CSS_DCI_FORMAT_t
  css_dci_format = cformat0_0_and_1_0;
  //NR_UE_SEARCHSPACE_USS_DCI_FORMAT_t
  uss_dci_format = uformat0_0_and_1_0;
  /*
   * Possible overlap between RE for SS/PBCH blocks (described in section 10, 38.213) has not been implemented yet
   * This can be implemented by setting variable 'mode = NO_DCI' when overlap occurs
   */
1530
  //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_slot_rx);
1531 1532
  LOG_DD("searSpaceType=%d\n",do_common);
  LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format);
1533 1534


Agustin's avatar
Agustin committed
1535
  // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces
hongzhi wang's avatar
hongzhi wang committed
1536
  if (do_common==0) { // COMMON SearchSpaceType assigned to current SearchSpace/CORESET
Agustin's avatar
Agustin committed
1537
    // Type0-PDCCH  common search space for a DCI format with CRC scrambled by a SI-RNTI
1538 1539 1540 1541 1542 1543
    // number of consecutive resource blocks and a number of consecutive symbols for
    // the control resource set of the Type0-PDCCH common search space from
    // the four most significant bits of RMSI-PDCCH-Config as described in Tables 13-1 through 13-10
    // and determines PDCCH monitoring occasions
    // from the four least significant bits of RMSI-PDCCH-Config,
    // included in MasterInformationBlock, as described in Tables 13-11 through 13-15
Agustin's avatar
Agustin committed
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558
    // Type0A-PDCCH common search space for a DCI format with CRC scrambled by a SI-RNTI
    // Type1-PDCCH  common search space for a DCI format with CRC scrambled by a RA-RNTI, or a TC-RNTI, or a C-RNTI
    // Type2-PDCCH  common search space for a DCI format with CRC scrambled by a P-RNTI
    if (css_dci_format == cformat0_0_and_1_0) {
      // 38.213 v15.1.0 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE
      // aggregation level for Type0/Type0A/Type2-PDCCH common search space
      //   CCE Aggregation Level    Number of Candidates
      //           4                       4
      //           8                       2
      //           16                      1
      // FIXME
      // We shall consider Table 10.1-1 to calculate the blind decoding only for Type0/Type0A/Type2-PDCCH
      // Shall we consider the nrofCandidates in SearSpace IE that considers Aggregation Levels 1,2,4,8,16? Our implementation considers Table 10.1-1
      // blind decoding (Type0-PDCCH,Type0A-PDCCH,Type1-PDCCH,Type2-PDCCH)
      // for format0_0 => we are NOT implementing format0_0 for common search spaces. FIXME!
1559
      // for format0_0 and format1_0, first we calculate dci pdu size
1560
      format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0);
1561
      format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1);
1562
      LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n",
1563 1564
             css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes);

1565
      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8
1566 1567
        //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) {
        // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0
1568
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1569 1570
               css_dci_format,(1<<aggregationLevel));
        old_dci_cnt = dci_cnt;
1571
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1572 1573 1574 1575 1576 1577 1578 1579
                                   crc_scrambled_values, aggregationLevel,
                                   cformat0_0_and_1_0, uformat0_0_and_1_0,
                                   format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_, pdcch_DMRS_scrambling_id,&CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
1580
          format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,crc_scrambled_,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,
1581 1582 1583 1584 1585 1586 1587
                                     0); // after decoding dci successfully we recalculate dci pdu size with correct crc scrambled to get the right field sizes
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1588
      }
Agustin's avatar
Agustin committed
1589 1590 1591 1592 1593 1594
    }

    // Type3-PDCCH  common search space for a DCI format with CRC scrambled by INT-RNTI, or SFI-RNTI,
    //    or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
    if (css_dci_format == cformat2_0) {
      // for format2_0, first we calculate dci pdu size
1595
      format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4);
1596
      format_2_0_size_bytes = (format_2_0_size_bits%8 == 0) ? (uint8_t)floor(format_2_0_size_bits/8) : (uint8_t)(floor(format_2_0_size_bits/8) + 1);
1597
      LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n",
1598 1599 1600
             css_dci_format,format_2_0_size_bits,format_2_0_size_bytes);

      for (int aggregationLevelSFI = 0; aggregationLevelSFI<5 ; aggregationLevelSFI++) {
1601
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1602 1603 1604
               css_dci_format,(1<<aggregationLevelSFI));
        // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
        old_dci_cnt = dci_cnt;
1605
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
                                   crc_scrambled_values, aggregationLevelSFI,
                                   cformat2_0, uformat0_0_and_1_0,
                                   format_2_0_size_bits, format_2_0_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevelSFI = 5;
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1620
      }
Agustin's avatar
Agustin committed
1621
    }
1622

Agustin's avatar
Agustin committed
1623 1624
    if (css_dci_format == cformat2_1) {
      // for format2_1, first we calculate dci pdu size
1625
      format_2_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_int_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,5);
1626
      format_2_1_size_bytes = (format_2_1_size_bits%8 == 0) ? (uint8_t)floor(format_2_1_size_bits/8) : (uint8_t)(floor(format_2_1_size_bits/8) + 1);
1627
      LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n",
1628 1629 1630
             css_dci_format,format_2_1_size_bits,format_2_1_size_bytes);

      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) {
1631
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1632 1633 1634
               css_dci_format,(1<<aggregationLevel));
        // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
        old_dci_cnt = dci_cnt;
1635
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
                                   crc_scrambled_values, aggregationLevel,
                                   cformat2_1, uformat0_0_and_1_0,
                                   format_2_1_size_bits, format_2_1_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1650
      }
Agustin's avatar
Agustin committed
1651
    }
1652

Agustin's avatar
Agustin committed
1653 1654
    if (css_dci_format == cformat2_2) {
      // for format2_2, first we calculate dci pdu size
1655
      format_2_2_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_tpc_pucch_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,6);
1656
      format_2_2_size_bytes = (format_2_2_size_bits%8 == 0) ? (uint8_t)floor(format_2_2_size_bits/8) : (uint8_t)(floor(format_2_2_size_bits/8) + 1);
1657
      LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n",
1658 1659 1660
             css_dci_format,format_2_2_size_bits,format_2_2_size_bytes);

      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) {
1661
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1662 1663 1664
               css_dci_format,(1<<aggregationLevel));
        // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
        old_dci_cnt = dci_cnt;
1665
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679
                                   crc_scrambled_values, aggregationLevel,
                                   cformat2_2, uformat0_0_and_1_0,
                                   format_2_2_size_bits, format_2_2_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1680
      }
Agustin's avatar
Agustin committed
1681
    }
1682

Agustin's avatar
Agustin committed
1683 1684
    if (css_dci_format == cformat2_3) {
      // for format2_1, first we calculate dci pdu size
1685
      format_2_3_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_tpc_srs_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,7);
1686
      format_2_3_size_bytes = (format_2_3_size_bits%8 == 0) ? (uint8_t)floor(format_2_3_size_bits/8) : (uint8_t)(floor(format_2_3_size_bits/8) + 1);
1687
      LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n",
1688
             css_dci_format,format_2_3_size_bits,format_2_3_size_bytes);
Agustin's avatar
Agustin committed
1689

1690
      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) {
1691
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1692 1693 1694
               css_dci_format,(1<<aggregationLevel));
        // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0
        old_dci_cnt = dci_cnt;
1695
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1696 1697 1698 1699 1700 1701 1702 1703 1704
                                   crc_scrambled_values, aggregationLevel,
                                   cformat2_3, uformat0_0_and_1_0,
                                   format_2_3_size_bits, format_2_3_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
          old_dci_cnt = dci_cnt;
Agustin's avatar
Agustin committed
1705

1706 1707 1708 1709 1710 1711
          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
      }
    }
Agustin's avatar
Agustin committed
1712 1713 1714
  } else { // UE-SPECIFIC SearchSpaceType assigned to current SearchSpace/CORESET
    // UE-specific search space for a DCI format with CRC scrambled by C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI
    if (uss_dci_format == uformat0_0_and_1_0) {
1715
      // for format0_0 and format1_0, first we calculate dci pdu size
1716
      format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0);
1717
      format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1);
1718
      LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n",
1719 1720
             css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes);

1721
      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8
1722 1723
        //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) {
        // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0
1724
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1725 1726
               css_dci_format,(1<<aggregationLevel));
        old_dci_cnt = dci_cnt;
1727
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
                                   crc_scrambled_values, aggregationLevel,
                                   cformat0_0_and_1_0, uformat0_0_and_1_0,
                                   format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1742
      }
1743
    }
Agustin's avatar
Agustin committed
1744

1745 1746
    if (uss_dci_format == uformat0_1_and_1_1) {
      // for format0_0 and format1_0, first we calculate dci pdu size
1747
      format_0_1_1_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,1);
1748
      format_0_1_1_1_size_bytes = (format_0_1_1_1_size_bits%8 == 0) ? (uint8_t)floor(format_0_1_1_1_size_bits/8) : (uint8_t)(floor(format_0_1_1_1_size_bits/8) + 1);
1749
      LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n",
1750 1751
             css_dci_format,format_0_1_1_1_size_bits,format_0_1_1_1_size_bytes);

1752
      for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8
1753 1754
        //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) {
        // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0
1755
        LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n",
1756 1757
               css_dci_format,(1<<aggregationLevel));
        old_dci_cnt = dci_cnt;
1758
        nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms,
1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
                                   crc_scrambled_values, aggregationLevel,
                                   cformat0_0_and_1_0, uformat0_1_and_1_1,
                                   format_0_1_1_1_size_bits, format_0_1_1_1_size_bytes, &dci_cnt,
                                   &crc_scrambled_, &format_found_,pdcch_DMRS_scrambling_id, &CCEmap0, &CCEmap1, &CCEmap2);

        if (dci_cnt != old_dci_cnt) {
          // we will exit the loop as we have found the DCI
          aggregationLevel = 5;
          old_dci_cnt = dci_cnt;

          for (int i=0; i<NBR_NR_DCI_FIELDS; i++)
            for (int j=0; j<NBR_NR_FORMATS; j++)
              dci_fields_sizes_cnt[dci_cnt-1][i][j]=dci_fields_sizes[i][j];
        }
1773
      }
Agustin's avatar
Agustin committed
1774
    }
1775
  }
1776

1777 1778
  *crc_scrambled = crc_scrambled_;
  *format_found  = format_found_;
1779 1780
  LOG_DD("at the end crc_scrambled=%d and format_found=%d\n",*crc_scrambled,*format_found);
  LOG_DD("at the end dci_cnt=%d \n",dci_cnt);
Agustin's avatar
Agustin committed
1781 1782
  return(dci_cnt);
}
1783

Agustin's avatar
Agustin committed
1784
#endif