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:
194 195 196
      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;
Francesco Mani's avatar
Francesco Mani committed
197
      switch(fp->N_RB_DL){
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;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
203
          break;
Francesco Mani's avatar
Francesco Mani committed
204 205 206 207 208
        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;
209 210 211
          break;
      default:
        AssertFatal(1==0,"Number of resource blocks %d undefined for mu %d, frame parms = %p\n", fp->N_RB_DL, mu, fp);
212
      }
hongzhi wang's avatar
hongzhi wang committed
213 214 215
      break;

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

  default:
    AssertFatal(1==0,"Invalid numerology index %d", mu);
  }
224 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
}


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
254

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

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

Raymond Knopp's avatar
Raymond Knopp committed
261 262 263
  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;
264 265
  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
266
  fp->samples_per_subframe = (fp->samples_per_subframe_wCP + (fp->nb_prefix_samples0 * fp->slots_per_subframe) +
Raymond Knopp's avatar
Raymond Knopp committed
267
			      (fp->nb_prefix_samples * fp->slots_per_subframe * (fp->symbols_per_slot - 1)));
Raymond Knopp's avatar
Raymond Knopp committed
268 269
  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
270

271
  // definition of Lmax according to ts 38.213 section 4.1
272 273 274 275 276 277
  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 {
278
    fp->Lmax = 64;
279
  }
280

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

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

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

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

294 295 296
  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;
297
  int N_RB_UL = config->carrier_config.ul_grid_size[config->ssb_config.scs_common.value].value;
298
  return nr_init_frame_parms0(fp,
Raymond Knopp's avatar
Raymond Knopp committed
299 300
			      config,
			      0,
301
			      NFAPI_CP_NORMAL,
302 303
			      N_RB_DL,
                              N_RB_UL);
Raymond Knopp's avatar
Raymond Knopp committed
304
}
hongzhi wang's avatar
hongzhi wang committed
305

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

311 312 313 314 315
  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 ;
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

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

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

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

375 376 377
  return 0;
}

Raymond Knopp's avatar
Raymond Knopp committed
378
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
379
{
Raymond Knopp's avatar
Raymond Knopp committed
380 381 382 383 384 385 386 387 388
  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);
389 390
  LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
  LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq);
391
}
392 393 394