phy_procedures_nr_gNB.c 10.5 KB
Newer Older
Guy De Souza's avatar
Guy De Souza committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.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 23
#include "PHY/phy_extern.h"
#include "PHY/defs_gNB.h"
Guy De Souza's avatar
Guy De Souza committed
24
#include "sched_nr.h"
Guy De Souza's avatar
Guy De Souza committed
25
#include "PHY/NR_TRANSPORT/nr_transport.h"
26
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
Guy De Souza's avatar
Guy De Souza committed
27
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
28
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
29 30
#include "SCHED/sched_eNB.h"
#include "SCHED/sched_common_extern.h"
31
#include "nfapi_interface.h"
Guy De Souza's avatar
Guy De Souza committed
32
#include "SCHED/fapi_l1.h"
33 34
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
35
#include "PHY/INIT/phy_init.h"
36
#include "PHY/MODULATION/nr_modulation.h"
Guy De Souza's avatar
Guy De Souza committed
37 38 39 40 41 42 43 44
#include "T.h"

#include "assertions.h"
#include "msc.h"

#include <time.h>

#if defined(ENABLE_ITTI)
45
  #include "intertask_interface.h"
Guy De Souza's avatar
Guy De Souza committed
46 47
#endif

Guy De Souza's avatar
Guy De Souza committed
48
extern uint8_t nfapi_mode;
49 50 51 52
/*
int return_ssb_type(nfapi_config_request_t *cfg)
{
  int mu = cfg->subframe_config.numerology_index_mu.value;
53
  nr_ssb_type_e ssb_type;
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

  switch(mu) {

  case NR_MU_0:
    ssb_type = nr_ssb_type_A;
    break;

  case NR_MU_1:
    ssb_type = nr_ssb_type_B;
    break;

  case NR_MU_3:
    ssb_type = nr_ssb_type_D;
    break;

  case NR_MU_4:
    ssb_type = nr_ssb_type_E;
    break;

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

  LOG_D(PHY, "SSB type %d\n", ssb_type);
  return ssb_type;

}*/

82

83

84
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp) {
85 86
  fp->ssb_start_subcarrier = (12 * cfg->sch_config.n_ssb_crb.value + cfg->sch_config.ssb_subcarrier_offset.value)/(1<<cfg->subframe_config.numerology_index_mu.value);
  LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->sch_config.n_ssb_crb.value,cfg->sch_config.ssb_subcarrier_offset.value);
87
}
Guy De Souza's avatar
Guy De Souza committed
88

89
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
Guy De Souza's avatar
Guy De Souza committed
90
  NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
91
  nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
Guy De Souza's avatar
Guy De Souza committed
92 93
  int **txdataF = gNB->common_vars.txdataF;
  uint8_t *pbch_pdu=&gNB->pbch_pdu[0];
94
  uint8_t ssb_index, n_hf;
95
  int ssb_start_symbol, rel_slot;
Guy De Souza's avatar
Guy De Souza committed
96

97
  n_hf = cfg->sch_config.half_frame_index.value;
98 99 100 101 102 103 104 105 106

  // if SSB periodicity is 5ms, they are transmitted in both half frames
  if ( cfg->sch_config.ssb_periodicity.value == 5) {
    if (slot<10)
      n_hf=0;
    else
      n_hf=1;
  }

107
  // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be
108
  rel_slot = (n_hf)? (slot-10) : slot; 
109

110
  LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
Guy De Souza's avatar
Guy De Souza committed
111

112
  if(rel_slot<10 && rel_slot>=0)  {
Francesco Mani's avatar
Francesco Mani committed
113
     for (int i=0; i<2; i++)  {  // max two SSB per slot
114
     
115
	ssb_index = i + 2*rel_slot; // computing the ssb_index
116 117
	if ((fp->L_ssb >> ssb_index) & 0x01)  { // generating the ssb only if the bit of L_ssb at current ssb index is 1
	
118
	  int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp, ssb_index, n_hf); // computing the starting symbol for current ssb
119 120
	  ssb_start_symbol = ssb_start_symbol_abs % 14;  // start symbol wrt slot

121
	  nr_set_ssb_first_subcarrier(cfg, fp);  // setting the first subcarrier
122
	  
123
	  // it is supposed that each logical antenna port correspont to a different beam so each SSB is stored into its own index of txdataF
124
    	  LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
125 126
    	  nr_generate_pss(gNB->d_pss, txdataF[ssb_index], AMP, ssb_start_symbol, cfg, fp);
    	  nr_generate_sss(gNB->d_sss, txdataF[ssb_index], AMP, ssb_start_symbol, cfg, fp);
127

128
	  if (fp->Lmax == 4)
129
	    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[ssb_index], AMP, ssb_start_symbol, cfg, fp);
130
	  else
131
	    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[ssb_index], AMP, ssb_start_symbol, cfg, fp);
132 133

    	  nr_generate_pbch(&gNB->pbch,
Guy De Souza's avatar
Guy De Souza committed
134 135
                      pbch_pdu,
                      gNB->nr_pbch_interleaver,
136
                      txdataF[ssb_index],
137
                      AMP,
Guy De Souza's avatar
Guy De Souza committed
138
                      ssb_start_symbol,
139
                      n_hf,fp->Lmax,ssb_index,
Guy De Souza's avatar
Guy De Souza committed
140
                      frame, cfg, fp);
141 142
	}
     }
143
  }
Guy De Souza's avatar
Guy De Souza committed
144 145 146
}

void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
147
                           int frame,int slot,
148
                           int do_meas) {
Guy De Souza's avatar
Guy De Souza committed
149
  int aa;
150
  uint8_t num_dci=0,num_pdsch_rnti;
Guy De Souza's avatar
Guy De Souza committed
151
  NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
WEI-TAI CHEN's avatar
WEI-TAI CHEN committed
152
  nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
Guy De Souza's avatar
Guy De Souza committed
153
  int offset = gNB->CC_id;
154 155 156 157 158 159
  uint8_t ssb_frame_periodicity;  // every how many frames SSB are generated

  if (cfg->sch_config.ssb_periodicity.value < 20)
    ssb_frame_periodicity = 1;
  else 
    ssb_frame_periodicity = (cfg->sch_config.ssb_periodicity.value)/10 ;  // 10ms is the frame length
Guy De Souza's avatar
Guy De Souza committed
160

161
  if ((cfg->subframe_config.duplex_mode.value == TDD) && (nr_slot_select(cfg,slot)==SF_UL)) return;
Guy De Souza's avatar
Guy De Souza committed
162

163
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
164

165
  if (do_meas==1) start_meas(&gNB->phy_proc_tx);
Guy De Souza's avatar
Guy De Souza committed
166 167

  // clear the transmit data array for the current subframe
168
  for (aa=0; aa<1/*15*/; aa++) {
169
    memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t));
Guy De Souza's avatar
Guy De Souza committed
170 171
  }

WANG Tsu-Han's avatar
WANG Tsu-Han committed
172
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,1);
173 174 175
  if (nfapi_mode == 0 || nfapi_mode == 1) { 
    if (!(frame%ssb_frame_periodicity))  // generate SSB only for given frames according to SSB periodicity
      nr_common_signal_procedures(gNB,frame, slot);
176
  }
WANG Tsu-Han's avatar
WANG Tsu-Han committed
177
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,0);
178 179

  num_dci = gNB->pdcch_vars.num_dci;
180
  num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
181

182
  if (num_dci) {
Raymond Knopp's avatar
Raymond Knopp committed
183
    LOG_D(PHY, "[gNB %d] Frame %d slot %d \
184
    Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci);
Guy De Souza's avatar
Guy De Souza committed
185

Raymond Knopp's avatar
Raymond Knopp committed
186
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1);
187
    if (nfapi_mode == 0 || nfapi_mode == 1) {
188
      nr_generate_dci_top(gNB->pdcch_vars,
189
                          gNB->nr_gold_pdcch_dmrs[slot],
190
                          gNB->common_vars.txdataF[0],  // hardcoded to beam 0
191
                          AMP, *fp, *cfg);
Raymond Knopp's avatar
Raymond Knopp committed
192
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0);
Guy De Souza's avatar
Guy De Souza committed
193
      if (num_pdsch_rnti) {
Raymond Knopp's avatar
Raymond Knopp committed
194 195
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
        LOG_D(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti);
196 197
        nr_generate_pdsch(gNB->dlsch[0][0],
                          &gNB->pdcch_vars.dci_alloc[0],
198
                          gNB->nr_gold_pdsch_dmrs[slot],
Guy De Souza's avatar
Guy De Souza committed
199
                          gNB->common_vars.txdataF,
200 201 202 203 204
                          AMP, frame, slot, fp, cfg,
                          &gNB->dlsch_encoding_stats,
                          &gNB->dlsch_scrambling_stats,
                          &gNB->dlsch_modulation_stats);

Raymond Knopp's avatar
Raymond Knopp committed
205
	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
Guy De Souza's avatar
Guy De Souza committed
206 207
      }
    }
208
  }
209

210
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
Guy De Souza's avatar
Guy De Souza committed
211
}
212 213 214 215 216


void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, uint8_t harq_pid) {
  
  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
217 218 219
  nfapi_nr_ul_config_ulsch_pdu         *rel15_ul              = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu;
  nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15;
  
220
  uint8_t ret;
221 222 223 224
  uint32_t G;
  int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled)

  G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, nfapi_ulsch_pdu_rel15->number_symbols, nfapi_ulsch_pdu_rel15->nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers);
225 226 227 228 229

  //----------------------------------------------------------
  //------------------- ULSCH unscrambling -------------------
  //----------------------------------------------------------

230
  nr_ulsch_unscrambling(gNB->pusch_vars[UE_id]->llr, G, 0, Nid_cell, rel15_ul->rnti);
231 232 233 234 235 236 237
      

  //----------------------------------------------------------
  //--------------------- ULSCH decoding ---------------------
  //----------------------------------------------------------

  ret = nr_ulsch_decoding(gNB, UE_id, gNB->pusch_vars[UE_id]->llr, frame_parms, proc->frame_rx,
238
                          nfapi_ulsch_pdu_rel15->number_symbols, proc->slot_rx, harq_pid, 0);
239 240 241 242 243 244 245 246 247 248
        
  // if (ret > ulsch_gNB->max_ldpc_iterations)
  //   n_errors++;

}


void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {

  uint8_t symbol;
249
  unsigned char aa;
250 251

  for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
252 253 254 255 256 257 258 259 260 261
    // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
    for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
      nr_slot_fep_ul(&gNB->frame_parms,
                     gNB->common_vars.rxdata[aa],
                     gNB->common_vars.rxdataF[aa],
                     symbol,
                     proc->slot_rx,
                     0,
                     0);
    }
262
  }
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277

}


void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end) {
  
  uint8_t UE_id;
  uint8_t symbol;
  uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ)
                        //       In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ)  

  for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
    
    for(symbol = symbol_start; symbol < symbol_end; symbol++) {

278
      nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
279 280 281 282 283 284 285 286

    }
      
    nr_ulsch_procedures(gNB, proc, UE_id, harq_pid);
        
  }

}