nr_parms.c 13.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.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
 */

22
#include "phy_init.h"
23
#include "common/utils/LOG/log.h"
24
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
25

26 27
/// Subcarrier spacings in Hz indexed by numerology index
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
28 29 30
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};


31

32
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
33 34 35
{

  int mu = fp->numerology_index;
36
  uint8_t half_frame_index = fp->half_frame_bit;
37
  uint8_t i_ssb = fp->ssb_index;
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  int symbol = 0;
  uint8_t n, n_temp;
  nr_ssb_type_e type = fp->ssb_type;
  int case_AC[2] = {2,8};
  int case_BD[4] = {4,8,16,20};
  int case_E[8] = {8, 12, 16, 20, 32, 36, 40, 44};

  switch(mu) {

	case NR_MU_0: // case A
	    n = i_ssb >> 1;
	    symbol = case_AC[i_ssb % 2] + 14*n;
	break;

	case NR_MU_1: 
	    if (type == 1){ // case B
		n = i_ssb >> 2;
	    	symbol = case_BD[i_ssb % 4] + 28*n;
	    }
	    if (type == 2){ // case C
		n = i_ssb >> 1;
		symbol = case_AC[i_ssb % 2] + 14*n;
	    }
	 break;

	 case NR_MU_3: // case D
	    n_temp = i_ssb >> 2; 
	    n = n_temp + (n_temp >> 2);
	    symbol = case_BD[i_ssb % 4] + 28*n;
	 break;

	 case NR_MU_4:  // case E
	    n_temp = i_ssb >> 3; 
	    n = n_temp + (n_temp >> 2);
	    symbol = case_E[i_ssb % 8] + 56*n;
	 break;


	 default:
	      AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
  }

  if (half_frame_index)
    symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);

  return symbol;
}

86
void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu)
87
{
hongzhi wang's avatar
hongzhi wang committed
88 89 90
  switch(mu) {

    case NR_MU_0: //15kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
91 92
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0];
93
      fp->ssb_type = nr_ssb_type_A;
hongzhi wang's avatar
hongzhi wang committed
94 95 96
      break;

    case NR_MU_1: //30kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
97 98
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1];
hongzhi wang's avatar
hongzhi wang committed
99

100
      // selection of SS block pattern according to TS 38101-1 Table 5.4.3.3-1 for SCS 30kHz
101
      if (fp->nr_band == 5 || fp->nr_band == 66) 
102 103
	      fp->ssb_type = nr_ssb_type_B;
      else{  
104
      	if (fp->nr_band == 41 || ( fp->nr_band > 76 && fp->nr_band < 80) )
105 106
		fp->ssb_type = nr_ssb_type_C;
	else
107
		AssertFatal(1==0,"NR Operating Band n%d not available for SS block SCS with mu=%d\n", fp->nr_band, mu);
108 109
      }

110
      switch(fp->N_RB_DL){
hongzhi wang's avatar
hongzhi wang committed
111 112 113 114 115 116 117 118
        case 11:
        case 24:
        case 38:
        case 78:
        case 51:
        case 65:

        case 106: //40 MHz
Raymond Knopp's avatar
Raymond Knopp committed
119 120
          if (fp->threequarter_fs) {
            fp->ofdm_symbol_size = 1536;
121
            fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
122 123
            fp->nb_prefix_samples0 = 132;
            fp->nb_prefix_samples = 108;
hongzhi wang's avatar
hongzhi wang committed
124 125
          }
          else {
Raymond Knopp's avatar
Raymond Knopp committed
126
            fp->ofdm_symbol_size = 2048;
127
            fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
128 129
            fp->nb_prefix_samples0 = 176;
            fp->nb_prefix_samples = 144;
hongzhi wang's avatar
hongzhi wang committed
130 131 132 133 134 135 136 137
          }
          break;

        case 133:
        case 162:
        case 189:

        case 217: //80 MHz
Raymond Knopp's avatar
Raymond Knopp committed
138 139
          if (fp->threequarter_fs) {
            fp->ofdm_symbol_size = 3072;
140
            fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
141 142
            fp->nb_prefix_samples0 = 264;
            fp->nb_prefix_samples = 216;
hongzhi wang's avatar
hongzhi wang committed
143
          }
Raymond Knopp's avatar
Raymond Knopp committed
144
	  else {
Raymond Knopp's avatar
Raymond Knopp committed
145
	    fp->ofdm_symbol_size = 4096;
146
	    fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
147 148
	    fp->nb_prefix_samples0 = 352;
	    fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
149
	  }
hongzhi wang's avatar
hongzhi wang committed
150 151 152
          break;

        case 245:
153
	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); 
Raymond Knopp's avatar
Raymond Knopp committed
154
	  fp->ofdm_symbol_size = 4096;
155
	  fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
156 157
	  fp->nb_prefix_samples0 = 352;
	  fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
158
	  break;
hongzhi wang's avatar
hongzhi wang committed
159
        case 273:
160
	  AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",fp->N_RB_DL,mu); 
Raymond Knopp's avatar
Raymond Knopp committed
161
	  fp->ofdm_symbol_size = 4096;
162
	  fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
Raymond Knopp's avatar
Raymond Knopp committed
163 164
	  fp->nb_prefix_samples0 = 352;
	  fp->nb_prefix_samples = 288;
Raymond Knopp's avatar
Raymond Knopp committed
165
	  break;
hongzhi wang's avatar
hongzhi wang committed
166
      default:
167
        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp);
hongzhi wang's avatar
hongzhi wang committed
168 169 170 171
      }
      break;

    case NR_MU_2: //60kHz scs
Raymond Knopp's avatar
Raymond Knopp committed
172 173
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2];
hongzhi wang's avatar
hongzhi wang committed
174

175
      switch(fp->N_RB_DL){ //FR1 bands only
hongzhi wang's avatar
hongzhi wang committed
176 177 178 179 180 181 182 183 184 185 186 187 188
        case 11:
        case 18:
        case 38:
        case 24:
        case 31:
        case 51:
        case 65:
        case 79:
        case 93:
        case 107:
        case 121:
        case 135:
      default:
189
        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp);
hongzhi wang's avatar
hongzhi wang committed
190 191 192 193
      }
      break;

    case NR_MU_3:
Francesco Mani's avatar
Francesco Mani committed
194
      switch(fp->N_RB_DL){
195 196 197 198 199 200 201 202
        case 66:
          fp->ofdm_symbol_size = 1024;
          fp->first_carrier_offset = 628; //1024 - ( (66*12) / 2 )
          fp->nb_prefix_samples0 = 88;
          fp->nb_prefix_samples = 72;
          fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
          fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
          fp->ssb_type = nr_ssb_type_D;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
203 204
          break;

Francesco Mani's avatar
Francesco Mani committed
205 206 207 208 209 210 211 212
        case 32:
          fp->ofdm_symbol_size = 512;
          fp->first_carrier_offset = 320; //1024 - ( (66*12) / 2 )
          fp->nb_prefix_samples0 = 44;
          fp->nb_prefix_samples = 36;
          fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3];
          fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3];
          fp->ssb_type = nr_ssb_type_D;
213
      }
hongzhi wang's avatar
hongzhi wang committed
214 215 216
      break;

    case NR_MU_4:
Raymond Knopp's avatar
Raymond Knopp committed
217 218
      fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4];
      fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4];
219
      fp->ssb_type = nr_ssb_type_E;
hongzhi wang's avatar
hongzhi wang committed
220 221 222 223 224
      break;

  default:
    AssertFatal(1==0,"Invalid numerology index %d", mu);
  }
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
}


int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
			 nfapi_nr_config_request_scf_t* cfg,
			 int mu0,
			 int Ncp,
			 int N_RB_DL,
                         int N_RB_UL)

{

  int mu = cfg!= NULL ?  cfg->ssb_config.scs_common.value : mu0;

#if DISABLE_LOG_X
  printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
#else
  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, N_RB_DL, Ncp);
#endif

  if (Ncp == NFAPI_CP_EXTENDED)
    AssertFatal(mu == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, mu);

  fp->half_frame_bit = 0;  // half frame bit initialized to 0 here
  fp->numerology_index = mu;
  fp->Ncp = Ncp;
  fp->N_RB_DL = N_RB_DL;
  fp->N_RB_UL = N_RB_UL;

  set_scs_parameters(fp, mu);
hongzhi wang's avatar
hongzhi wang committed
255

Raymond Knopp's avatar
Raymond Knopp committed
256
  fp->slots_per_frame = 10* fp->slots_per_subframe;
257

258
  fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration
259 260
  fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
  fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration
261

Raymond Knopp's avatar
Raymond Knopp committed
262 263 264
  fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
  fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
  fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
265 266
  fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; 
  fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); 
Raymond Knopp's avatar
Raymond Knopp committed
267
  fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
Raymond Knopp's avatar
Raymond Knopp committed
268
			      (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
Raymond Knopp's avatar
Raymond Knopp committed
269 270
  fp->samples_per_frame = 10 * fp->samples_per_subframe;
  fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
hongzhi wang's avatar
hongzhi wang committed
271

272
  // definition of Lmax according to ts 38.213 section 4.1
273 274 275 276 277 278
  if (fp->dl_CarrierFreq < 6e9) {
    if(fp->frame_type && (fp->ssb_type==2))
      fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
    else
      fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
  } else {
279
    fp->Lmax = 64;
280
  }
281

282
  fp->N_ssb = 0;
Raymond Knopp's avatar
Raymond Knopp committed
283 284 285
  int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value;

  for (int p=0; p<num_tx_ant; p++)
286
    fp->N_ssb += ((fp->L_ssb >> p) & 0x01);
Guy De Souza's avatar
Guy De Souza committed
287

hongzhi wang's avatar
hongzhi wang committed
288 289 290
  return 0;
}

291
int nr_init_frame_parms(nfapi_nr_config_request_scf_t* config,
yilmazt's avatar
yilmazt committed
292 293
                        NR_DL_FRAME_PARMS *fp)
{
294

295 296 297
  fp->frame_type = config->cell_config.frame_duplex_type.value;
  fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask.value)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask.value ;
  int N_RB_DL = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
298
  int N_RB_UL = config->carrier_config.ul_grid_size[config->ssb_config.scs_common.value].value;
299
  return nr_init_frame_parms0(fp,
Raymond Knopp's avatar
Raymond Knopp committed
300 301
			      config,
			      0,
302
			      NFAPI_CP_NORMAL,
303 304
			      N_RB_DL,
                              N_RB_UL);
Raymond Knopp's avatar
Raymond Knopp committed
305
}
hongzhi wang's avatar
hongzhi wang committed
306

Raymond Knopp's avatar
Raymond Knopp committed
307
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
308 309
			   fapi_nr_config_request_t* config, 
			   int Ncp) 
Raymond Knopp's avatar
Raymond Knopp committed
310
{
311

312 313 314 315 316
  uint64_t dl_bw_khz = (12*config->carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
  fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ;

  uint64_t ul_bw_khz = (12*config->carrier_config.ul_grid_size[config->ssb_config.scs_common])*(15<<config->ssb_config.scs_common);
  fp->ul_CarrierFreq = ((ul_bw_khz>>1) + config->carrier_config.uplink_frequency)*1000 ;
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341

  fp->numerology_index = config->ssb_config.scs_common;
  fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index];
  fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];

  int32_t uplink_frequency_offset = 0;

  get_band(fp->dl_CarrierFreq, &fp->nr_band, &uplink_frequency_offset, &fp->frame_type);

  AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band);
  AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+uplink_frequency_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band);

#if DISABLE_LOG_X
  printf("Initializing UE frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
#else
  LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp);
#endif

  if (Ncp == NFAPI_CP_EXTENDED)
    AssertFatal(fp->numerology_index == NR_MU_2,"Invalid cyclic prefix %d for numerology index %d\n", Ncp, fp->numerology_index);

  fp->Ncp = Ncp;

  set_scs_parameters(fp,fp->numerology_index);

342 343
  fp->slots_per_frame = 10* fp->slots_per_subframe;

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
  fp->nb_antenna_ports_gNB = 1; // default value until overwritten by RRCConnectionReconfiguration
  fp->nb_antennas_rx = 1; // default value until overwritten by RRCConnectionReconfiguration
  fp->nb_antennas_tx = 1; // default value until overwritten by RRCConnectionReconfiguration

  fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats
  fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe;
  fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP;
  fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; 
  fp->samples_per_slot = fp->nb_prefix_samples0 + ((fp->symbols_per_slot-1)*fp->nb_prefix_samples) + (fp->symbols_per_slot*fp->ofdm_symbol_size); 
  fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
			      (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
  fp->samples_per_frame = 10 * fp->samples_per_subframe;
  fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;

  fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + config->ssb_table.ssb_subcarrier_offset);

  // definition of Lmax according to ts 38.213 section 4.1
  if (fp->dl_CarrierFreq < 6e9) {
    if(fp->frame_type && (fp->ssb_type==2))
      fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8;
    else
      fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8;
  } else {
    fp->Lmax = 64;
  }

  fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[0].ssb_mask;
  
  fp->N_ssb = 0;
  for (int p=0; p<fp->Lmax; p++)
    fp->N_ssb += ((fp->L_ssb >> p) & 0x01);

376 377 378
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
379
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
380
{
Raymond Knopp's avatar
Raymond Knopp committed
381 382 383 384 385 386 387 388 389
  LOG_I(PHY,"fp->scs=%d\n",fp->subcarrier_spacing);
  LOG_I(PHY,"fp->ofdm_symbol_size=%d\n",fp->ofdm_symbol_size);
  LOG_I(PHY,"fp->nb_prefix_samples0=%d\n",fp->nb_prefix_samples0);
  LOG_I(PHY,"fp->nb_prefix_samples=%d\n",fp->nb_prefix_samples);
  LOG_I(PHY,"fp->slots_per_subframe=%d\n",fp->slots_per_subframe);
  LOG_I(PHY,"fp->samples_per_subframe_wCP=%d\n",fp->samples_per_subframe_wCP);
  LOG_I(PHY,"fp->samples_per_frame_wCP=%d\n",fp->samples_per_frame_wCP);
  LOG_I(PHY,"fp->samples_per_subframe=%d\n",fp->samples_per_subframe);
  LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
390 391
  LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
  LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq);
392
}
393 394 395