phy_procedures_nr_gNB.c 40.2 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
#include "PHY/defs_gNB.h"
Guy De Souza's avatar
Guy De Souza committed
23
#include "sched_nr.h"
24
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
Guy De Souza's avatar
Guy De Souza committed
25
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
26
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
27
#include "PHY/NR_TRANSPORT/nr_dci.h"
28 29 30 31
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
#include "fapi_nr_l1.h"
32 33
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
34
#include "PHY/INIT/phy_init.h"
35
#include "PHY/MODULATION/nr_modulation.h"
rmagueta's avatar
rmagueta committed
36
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
Guy De Souza's avatar
Guy De Souza committed
37
#include "T.h"
38
#include "executables/nr-softmodem.h"
39
#include "executables/softmodem-common.h"
Guy De Souza's avatar
Guy De Souza committed
40 41 42 43 44

#include "assertions.h"

#include <time.h>

45
#include "intertask_interface.h"
Guy De Souza's avatar
Guy De Souza committed
46

47 48
//#define DEBUG_RXDATA

49 50
uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,254,32,34,36,38,40,42,44,46,254,254,48,50,52,54,56,58,60,62};

Guy De Souza's avatar
Guy De Souza committed
51
extern uint8_t nfapi_mode;
52

53
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
54

Guy De Souza's avatar
Guy De Souza committed
55
  NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
56
  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
Guy De Souza's avatar
Guy De Souza committed
57
  int **txdataF = gNB->common_vars.txdataF;
58
  uint8_t ssb_index, n_hf;
59
  uint16_t ssb_start_symbol;
60
  int txdataF_offset = slot*fp->samples_per_slot_wCP;
61 62
  uint16_t slots_per_hf = (fp->slots_per_frame)>>1;

63 64 65 66
  if (slot<slots_per_hf)
    n_hf=0;
  else
    n_hf=1;
67

68 69
  ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
  LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n",frame,slot,ssb_index);
70

71 72
  int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb
  ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot;  // start symbol wrt slot
73

74 75 76
  // setting the first subcarrier
  fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset);
  LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset);
77

78
  LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
79 80
  nr_generate_pss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
  nr_generate_sss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
81

francescomani's avatar
francescomani committed
82
  if (fp->Lmax == 4)
83 84 85 86 87 88 89 90 91 92
    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
  else
    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);

  if (T_ACTIVE(T_GNB_PHY_MIB)) {
    unsigned char bch[3];
    bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
    bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
    bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
    T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
93
  }
94

95 96 97 98 99
  // Beam_id is currently used only for FR2
  if (fp->freq_range==nr_FR2){
    LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
    for (int j=0;j<fp->symbols_per_slot;j++) 
      gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
100
  }
101

102
  nr_generate_pbch(&ssb_pdu,
103 104 105 106 107
                   gNB->nr_pbch_interleaver,
                   &txdataF[0][txdataF_offset],
                   AMP,
                   ssb_start_symbol,
                   n_hf, frame, cfg, fp);
Guy De Souza's avatar
Guy De Souza committed
108 109
}

110

111 112 113
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
                           int frame,
                           int slot,
114
                           int do_meas) {
115

Guy De Souza's avatar
Guy De Souza committed
116
  int aa;
117
  PHY_VARS_gNB *gNB = msgTx->gNB;
Guy De Souza's avatar
Guy De Souza committed
118
  NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
119
  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
Guy De Souza's avatar
Guy De Souza committed
120
  int offset = gNB->CC_id;
121
  int txdataF_offset = slot*fp->samples_per_slot_wCP;
Guy De Souza's avatar
Guy De Souza committed
122

Rakesh's avatar
Rakesh committed
123
  if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
124
      (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
Guy De Souza's avatar
Guy De Souza committed
125

Rakesh's avatar
Rakesh committed
126
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,1);
127

128
  // clear the transmit data array and beam index for the current slot
Raymond Knopp's avatar
Raymond Knopp committed
129
  for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
130
    memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
131
    memset(&gNB->common_vars.beam_id[aa][slot*fp->symbols_per_slot],255,fp->symbols_per_slot*sizeof(uint8_t));
Guy De Souza's avatar
Guy De Souza committed
132 133
  }

Rakesh's avatar
Rakesh committed
134
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
135
  for (int i=0; i<fp->Lmax; i++) {
136 137 138
    if (msgTx->ssb[i].active) {
      nr_common_signal_procedures(gNB,frame,slot,msgTx->ssb[i].ssb_pdu);
      msgTx->ssb[i].active = false;
139
    }
140
  }
141
  
Rakesh's avatar
Rakesh committed
142
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
143

144
  int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch;
145

146 147 148
  if (num_pdcch_pdus > 0) {
    LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL PDCCH PDUs %d/%d)\n",
	  gNB->Mod_id, frame, slot, msgTx->num_ul_pdcch, msgTx->num_dl_pdcch);
149
  
Rakesh's avatar
Rakesh committed
150
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
151

152
    nr_generate_dci_top(msgTx, slot,
153
			&gNB->common_vars.txdataF[0][txdataF_offset],
francescomani's avatar
francescomani committed
154
			AMP, fp);
155

Rakesh's avatar
Rakesh committed
156
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
157
  }
158
 
Sakthivel Velumani's avatar
Sakthivel Velumani committed
159
  if (msgTx->num_pdsch_slot > 0) {
160
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
161
    LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", msgTx->num_pdsch_slot,frame,slot);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
162
    nr_generate_pdsch(msgTx, frame, slot);
163
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
164
  }
165

166
  for (int i=0;i<NUMBER_OF_NR_CSIRS_MAX;i++){
167
    NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
168
    if (csirs->active == 1) {
169
      LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
170
      nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
171
      nr_generate_csi_rs(&gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot, NULL, NULL, NULL, NULL, NULL);
172
      csirs->active = 0;
173 174 175
    }
  }

176
//  if ((frame&127) == 0) dump_pdsch_stats(gNB);
177 178

  //apply the OFDM symbol rotation here
179
  for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
francescomani's avatar
francescomani committed
180
    apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[aa][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size);
181
  }
182

Rakesh's avatar
Rakesh committed
183
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
Guy De Souza's avatar
Guy De Souza committed
184
}
185

Sakthivel Velumani's avatar
Sakthivel Velumani committed
186
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
Sakthi's avatar
Sakthi committed
187 188 189 190
  ldpcDecode_t *rdata = (ldpcDecode_t*) NotifiedFifoData(req);
  NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
  NR_gNB_ULSCH_t *ulsch = rdata->ulsch;
  int r = rdata->segment_r;
191
  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id]->harq_processes[rdata->harq_pid]->ulsch_pdu;
192

193
  bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
194 195 196
  ulsch_harq->processedSegments++;
  LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
	rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
Sakthi's avatar
Sakthi committed
197 198 199 200 201 202
  gNB->nbDecode--;
  LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode);
  
  if (decodeSuccess) {
    memcpy(ulsch_harq->b+rdata->offset,
           ulsch_harq->c[r],
Cedric Roux's avatar
Cedric Roux committed
203
           rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0));
Sakthi's avatar
Sakthi committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217

  } else {
    if ( rdata->nbSegments != ulsch_harq->processedSegments ) {
      int nb=abortTpool(gNB->threadPool, req->key);
      nb+=abortNotifiedFIFO(gNB->respDecode, req->key);
      gNB->nbDecode-=nb;
      LOG_D(PHY,"uplink segment error %d/%d, aborted %d segments\n",rdata->segment_r,rdata->nbSegments, nb);
      LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
      AssertFatal(ulsch_harq->processedSegments+nb == rdata->nbSegments,"processed: %d, aborted: %d, total %d\n",
		  ulsch_harq->processedSegments, nb, rdata->nbSegments);
      ulsch_harq->processedSegments=rdata->nbSegments;
    }
  }

rmagueta's avatar
rmagueta committed
218
  //int dumpsig=0;
219
  // if all segments are done
Sakthi's avatar
Sakthi committed
220 221
  if (rdata->nbSegments == ulsch_harq->processedSegments) {
    if (decodeSuccess) {
222 223
      LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n",
            gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations);
Sakthi's avatar
Sakthi committed
224 225 226 227
      ulsch_harq->status = SCH_IDLE;
      ulsch_harq->round  = 0;
      ulsch->harq_mask &= ~(1 << rdata->harq_pid);

Eurecom's avatar
Eurecom committed
228
      LOG_D(PHY, "ULSCH received ok \n");
229
      nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 0,0);
rmagueta's avatar
rmagueta committed
230
      //dumpsig=1;
231
    } else {
Raymond Knopp's avatar
Raymond Knopp committed
232
      LOG_D(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, ndi %d, status %d, round %d, RV %d, prb_start %d, prb_size %d, TBS %d) r %d\n",
Sakthi's avatar
Sakthi committed
233
            gNB->Mod_id, ulsch_harq->frame, ulsch_harq->slot,
234 235 236 237 238 239 240
            rdata->harq_pid, pusch_pdu->pusch_data.new_data_indicator, ulsch_harq->status,
	          ulsch_harq->round,
            ulsch_harq->ulsch_pdu.pusch_data.rv_index,
	          ulsch_harq->ulsch_pdu.rb_start,
	          ulsch_harq->ulsch_pdu.rb_size,
	          ulsch_harq->TBS,
	          r);
241
      ulsch_harq->round++;
Sakthi's avatar
Sakthi committed
242 243 244 245 246 247 248 249 250
      if (ulsch_harq->round >= ulsch->Mlimit) {
        ulsch_harq->status = SCH_IDLE;
        ulsch_harq->round  = 0;
        ulsch_harq->handled  = 0;
        ulsch->harq_mask &= ~(1 << rdata->harq_pid);
      }
      ulsch_harq->handled  = 1;

      LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
251
      nr_fill_indication(gNB,ulsch_harq->frame, ulsch_harq->slot, rdata->ulsch_id, rdata->harq_pid, 1,0);
252
//      dumpsig=1;
253
    }
254
/*
255
    if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
Eurecom's avatar
Eurecom committed
256 257 258 259 260 261
#ifdef __AVX2__
      int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;
#else
      int off = 0;
#endif

262
      LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(ulsch_harq->slot&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
Eurecom's avatar
Eurecom committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
      LOG_M("rxsigF0_ext.m","rxsF0_ext",
             &gNB->pusch_vars[0]->rxdataF_ext[0][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
      LOG_M("chestF0.m","chF0",
            &gNB->pusch_vars[0]->ul_ch_estimates[0][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
      LOG_M("chestF0_ext.m","chF0_ext",
            &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size))],
            (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
      LOG_M("rxsigF0_comp.m","rxsF0_comp",
            &gNB->pusch_vars[0]->rxdataF_comp[0][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
      LOG_M("rxsigF0_llr.m","rxsF0_llr",
            &gNB->pusch_vars[0]->llr[0],(ulsch_harq->ulsch_pdu.nr_of_symbols-1)*NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size * ulsch_harq->ulsch_pdu.qam_mod_order,1,0);
      if (gNB->frame_parms.nb_antennas_rx > 1) {

        LOG_M("rxsigF1_ext.m","rxsF0_ext",
               &gNB->pusch_vars[0]->rxdataF_ext[1][ulsch_harq->ulsch_pdu.start_symbol_index*NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
        LOG_M("chestF1.m","chF1",
              &gNB->pusch_vars[0]->ul_ch_estimates[1][ulsch_harq->ulsch_pdu.start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
        LOG_M("chestF1_ext.m","chF1_ext",
              &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(ulsch_harq->ulsch_pdu.start_symbol_index+1)*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size))],
              (ulsch_harq->ulsch_pdu.nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
        LOG_M("rxsigF1_comp.m","rxsF1_comp",
              &gNB->pusch_vars[0]->rxdataF_comp[1][ulsch_harq->ulsch_pdu.start_symbol_index*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size))],ulsch_harq->ulsch_pdu.nr_of_symbols*(off+(NR_NB_SC_PER_RB * ulsch_harq->ulsch_pdu.rb_size)),1,1);
      }
      exit(-1);
287

288 289
    } 
*/
Sakthi's avatar
Sakthi committed
290 291 292 293 294
    ulsch->last_iteration_cnt = rdata->decodeIterations;
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
  }
}

295

Raymond Knopp's avatar
Raymond Knopp committed
296
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
297
{
298
  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
299
  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->ulsch_pdu;
300
  
301
  uint8_t l, number_dmrs_symbols = 0;
302
  uint32_t G;
303
  uint16_t start_symbol, number_symbols, nb_re_dmrs;
304

305 306
  start_symbol = pusch_pdu->start_symbol_index;
  number_symbols = pusch_pdu->nr_of_symbols;
307 308

  for (l = start_symbol; l < start_symbol + number_symbols; l++)
Francesco Mani's avatar
Francesco Mani committed
309
    number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
310

311 312
  if (pusch_pdu->dmrs_config_type==pusch_dmrs_type1)
    nb_re_dmrs = 6*pusch_pdu->num_dmrs_cdm_grps_no_data;
313
  else
314
    nb_re_dmrs = 4*pusch_pdu->num_dmrs_cdm_grps_no_data;
315 316

  G = nr_get_G(pusch_pdu->rb_size,
317
               number_symbols,
318
               nb_re_dmrs,
319
               number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
320 321
               pusch_pdu->qam_mod_order,
               pusch_pdu->nrOfLayers);
322
  
Raphael Defosseux's avatar
Raphael Defosseux committed
323
  AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n",
324 325 326 327 328 329
	      pusch_pdu->rb_size,
	      number_symbols,
	      nb_re_dmrs,
	      number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
	      pusch_pdu->qam_mod_order,
	      pusch_pdu->nrOfLayers);
330
  LOG_D(PHY,"rb_size %d, number_symbols %d, nb_re_dmrs %d, dmrs symbol positions %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n",
331 332 333
	pusch_pdu->rb_size,
	number_symbols,
	nb_re_dmrs,
334
        pusch_pdu->ul_dmrs_symb_pos,
335 336 337
	number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
	pusch_pdu->qam_mod_order,
	pusch_pdu->nrOfLayers);
338 339 340


  nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id]->llr,
341 342 343 344
                           pusch_pdu->nrOfLayers,
                           pusch_pdu->qam_mod_order,
                           G,
                           gNB->pusch_vars[ULSCH_id]->llr_layers);
345
             
346 347 348
  //----------------------------------------------------------
  //------------------- ULSCH unscrambling -------------------
  //----------------------------------------------------------
349
  start_meas(&gNB->ulsch_unscrambling_stats);
350 351 352 353
  nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id]->llr,
                        G,
                        pusch_pdu->data_scrambling_id,
                        pusch_pdu->rnti);
354
  stop_meas(&gNB->ulsch_unscrambling_stats);
355 356 357 358
  //----------------------------------------------------------
  //--------------------- ULSCH decoding ---------------------
  //----------------------------------------------------------

359
  start_meas(&gNB->ulsch_decoding_stats);
360 361 362 363 364 365 366 367 368
  nr_ulsch_decoding(gNB,
                    ULSCH_id,
                    gNB->pusch_vars[ULSCH_id]->llr,
                    frame_parms,
                    pusch_pdu,
                    frame_rx,
                    slot_rx,
                    harq_pid,
                    G);
369

370 371
  while (gNB->nbDecode > 0) {
    notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
372
    nr_postDecode(gNB, req);
373 374
    delNotifiedFIFO_elt(req);
  }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
375
  stop_meas(&gNB->ulsch_decoding_stats);
376 377 378
}


379
void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag, int dtx_flag) {
380

381
  pthread_mutex_lock(&gNB->UL_INFO_mutex);
382

383
  NR_gNB_ULSCH_t                       *ulsch                 = gNB->ulsch[ULSCH_id];
384
  NR_UL_gNB_HARQ_t                     *harq_process          = ulsch->harq_processes[harq_pid];
385
  NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch);
386

387
  nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
388

389
  //  pdu->data                              = gNB->ulsch[ULSCH_id+1]->harq_processes[harq_pid]->b;
390
  int sync_pos = nr_est_timing_advance_pusch(gNB, ULSCH_id); // estimate timing advance for MAC
391

392
  // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
393
  uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
394

395
  // do some integer rounding to improve TA accuracy
396
  int sync_pos_rounded;
397
  if (sync_pos > 0)
398
    sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
399
  else
400
    sync_pos_rounded = sync_pos - (bw_scaling / 2) + 1;
401 402
  if (stats) stats->sync_pos = sync_pos;

403
  int timing_advance_update = sync_pos_rounded / bw_scaling;
404 405 406 407 408 409 410

  // put timing advance command in 0..63 range
  timing_advance_update += 31;

  if (timing_advance_update < 0)  timing_advance_update = 0;
  if (timing_advance_update > 63) timing_advance_update = 63;

rmagueta's avatar
rmagueta committed
411
  if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is  = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update);
412 413 414 415 416 417 418 419 420
  else if (harq_process->round>0 || dtx_flag == 0) { // increment round if crc_flag == 1 and not(dtx_flag ==1 and round==0)
      harq_process->round++;
      if (harq_process->round >= ulsch->Mlimit) {
        harq_process->status = SCH_IDLE;
        harq_process->round  = 0;
        harq_process->handled  = 0;
        ulsch->harq_mask &= ~(1 << harq_pid);
      }
  }
421
  // estimate UL_CQI for MAC
422

423
  int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) -
424 425
                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot);

426
  LOG_D(PHY, "%d.%d: Estimated SNR for PUSCH is = %f dB (ulsch_power %f, noise %f) delay %d\n", frame, slot_rx, SNRtimes10/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot)/10.0,dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot)/10.0,sync_pos);
427

428
  int cqi;
429 430 431 432
  if      (SNRtimes10 < -640) cqi=0;
  else if (SNRtimes10 >  635) cqi=255;
  else                        cqi=(640+SNRtimes10)/5;

Eurecom's avatar
Eurecom committed
433

434
  if (0/*pusch_pdu->mcs_index == 9*/) {
435
      __attribute__((unused))
Eurecom's avatar
Eurecom committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
#ifdef __AVX2__
      int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
#else
      int off = 0;
#endif
      LOG_M("rxsigF0.m","rxsF0",&gNB->common_vars.rxdataF[0][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
      LOG_M("rxsigF0_ext.m","rxsF0_ext",
             &gNB->pusch_vars[0]->rxdataF_ext[0][pusch_pdu->start_symbol_index*NR_NB_SC_PER_RB * pusch_pdu->rb_size],pusch_pdu->nr_of_symbols*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
      LOG_M("chestF0.m","chF0",
            &gNB->pusch_vars[0]->ul_ch_estimates[0][pusch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
      LOG_M("chestF0_ext.m","chF0_ext",
            &gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(pusch_pdu->start_symbol_index+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
            (pusch_pdu->nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
      LOG_M("rxsigF0_comp.m","rxsF0_comp",
            &gNB->pusch_vars[0]->rxdataF_comp[0][pusch_pdu->start_symbol_index*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],pusch_pdu->nr_of_symbols*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
      LOG_M("rxsigF0_llr.m","rxsF0_llr",
            &gNB->pusch_vars[0]->llr[0],(pusch_pdu->nr_of_symbols-1)*NR_NB_SC_PER_RB *pusch_pdu->rb_size * pusch_pdu->qam_mod_order,1,0);
      if (gNB->frame_parms.nb_antennas_rx > 1) {
        LOG_M("rxsigF1.m","rxsF1",&gNB->common_vars.rxdataF[1][(slot_rx&3)*gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot],gNB->frame_parms.ofdm_symbol_size*gNB->frame_parms.symbols_per_slot,1,1);
        LOG_M("rxsigF1_ext.m","rxsF1_ext",
               &gNB->pusch_vars[0]->rxdataF_ext[1][pusch_pdu->start_symbol_index*NR_NB_SC_PER_RB * pusch_pdu->rb_size],pusch_pdu->nr_of_symbols*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
        LOG_M("chestF1.m","chF1",
              &gNB->pusch_vars[0]->ul_ch_estimates[1][pusch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size],gNB->frame_parms.ofdm_symbol_size,1,1);
        LOG_M("chestF1_ext.m","chF1_ext",
              &gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(pusch_pdu->start_symbol_index+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
              (pusch_pdu->nr_of_symbols-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
        LOG_M("rxsigF1_comp.m","rxsF1_comp",
              &gNB->pusch_vars[0]->rxdataF_comp[1][pusch_pdu->start_symbol_index*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],pusch_pdu->nr_of_symbols*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
      }
      exit(-1);

467 468
    }

469 470 471 472 473 474 475 476 477 478
  // crc indication
  uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs;
  gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0];
  gNB->UL_INFO.crc_ind.sfn = frame;
  gNB->UL_INFO.crc_ind.slot = slot_rx;

  gNB->crc_pdu_list[num_crc].handle = pusch_pdu->handle;
  gNB->crc_pdu_list[num_crc].rnti = pusch_pdu->rnti;
  gNB->crc_pdu_list[num_crc].harq_id = harq_pid;
  gNB->crc_pdu_list[num_crc].tb_crc_status = crc_flag;
479
  gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
480 481
  gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
  gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
482
  // in terms of dBFS range -128 to 0 with 0.1 step
483
  gNB->crc_pdu_list[num_crc].rssi = (dtx_flag==0) ? 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0])) : 0;
484 485 486 487 488 489 490 491 492 493 494 495 496

  gNB->UL_INFO.crc_ind.number_crcs++;

  // rx indication
  uint16_t num_rx = gNB->UL_INFO.rx_ind.number_of_pdus;
  gNB->UL_INFO.rx_ind.pdu_list = &gNB->rx_pdu_list[0];
  gNB->UL_INFO.rx_ind.sfn = frame;
  gNB->UL_INFO.rx_ind.slot = slot_rx;
  gNB->rx_pdu_list[num_rx].handle = pusch_pdu->handle;
  gNB->rx_pdu_list[num_rx].rnti = pusch_pdu->rnti;
  gNB->rx_pdu_list[num_rx].harq_id = harq_pid;
  gNB->rx_pdu_list[num_rx].ul_cqi = cqi;
  gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update;
497
  gNB->rx_pdu_list[num_rx].rssi = gNB->crc_pdu_list[num_crc].rssi;
498 499 500 501 502 503
  if (crc_flag)
    gNB->rx_pdu_list[num_rx].pdu_length = 0;
  else {
    gNB->rx_pdu_list[num_rx].pdu_length = harq_process->TBS;
    gNB->rx_pdu_list[num_rx].pdu = harq_process->b;
  }
504

505
  gNB->UL_INFO.rx_ind.number_of_pdus++;
506

507
  pthread_mutex_unlock(&gNB->UL_INFO_mutex);
508
}
509

510 511 512
// Function to fill UL RB mask to be used for N0 measurements
void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {

rmagueta's avatar
rmagueta committed
513 514 515 516
  int rb = 0;
  int rb2 = 0;
  int prbpos = 0;

517
  for (int symbol=0;symbol<14;symbol++) {
rmagueta's avatar
rmagueta committed
518 519 520 521 522 523
    for (int m=0;m<9;m++) {
      gNB->rb_mask_ul[symbol][m] = 0;
      for (int i=0;i<32;i++) {
        prbpos = (m*32)+i;
        if (prbpos>gNB->frame_parms.N_RB_UL) break;
        gNB->rb_mask_ul[symbol][m] |= (gNB->ulprbbl[prbpos]>0 ? 1 : 0)<<i;
524
      }
rmagueta's avatar
rmagueta committed
525 526
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
527 528 529 530 531 532 533 534 535 536

  for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
    NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
    if (pucch) {
      if ((pucch->active == 1) &&
          (pucch->frame == frame_rx) &&
          (pucch->slot == slot_rx) ) {
        nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
        LOG_D(PHY,"%d.%d pucch %d : start_symbol %d, nb_symbols %d, prb_size %d\n",frame_rx,slot_rx,i,pucch_pdu->start_symbol_index,pucch_pdu->nr_of_symbols,pucch_pdu->prb_size);
        for (int symbol=pucch_pdu->start_symbol_index ; symbol<(pucch_pdu->start_symbol_index+pucch_pdu->nr_of_symbols);symbol++) {
537 538
          if(gNB->frame_parms.frame_type == FDD ||
              (gNB->frame_parms.frame_type == TDD && gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol].slot_config.value==1)) {
539
            for (rb=0; rb<pucch_pdu->prb_size; rb++) {
540
              rb2 = rb + pucch_pdu->bwp_start +
luis_pereira87's avatar
luis_pereira87 committed
541 542
                    ((symbol < pucch_pdu->start_symbol_index+(pucch_pdu->nr_of_symbols>>1)) || (pucch_pdu->freq_hop_flag == 0) ?
                     pucch_pdu->prb_start : pucch_pdu->second_hop_prb);
543
              gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31));
544 545 546 547
            }
          }
        }
      }
548
    }
luis_pereira87's avatar
luis_pereira87 committed
549 550 551
  }

  for (int ULSCH_id=0;ULSCH_id<gNB->number_of_nr_ulsch_max;ULSCH_id++) {
552
    NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id];
luis_pereira87's avatar
luis_pereira87 committed
553 554 555 556 557 558 559 560 561 562 563 564 565 566
    int harq_pid;
    NR_UL_gNB_HARQ_t *ulsch_harq;
    if ((ulsch) &&
        (ulsch->rnti > 0)) {
      for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) {
        ulsch_harq = ulsch->harq_processes[harq_pid];
        AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
        if ((ulsch_harq->status == NR_ACTIVE) &&
            (ulsch_harq->frame == frame_rx) &&
            (ulsch_harq->slot == slot_rx) &&
            (ulsch_harq->handled == 0)){
          uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
          uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
          for (int symbol=symbol_start ; symbol<symbol_end ; symbol++) {
567 568
            if(gNB->frame_parms.frame_type == FDD ||
                (gNB->frame_parms.frame_type == TDD && gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol].slot_config.value==1)) {
569 570 571 572
              LOG_D(PHY,"symbol %d Filling rb_mask_ul rb_size %d\n",symbol,ulsch_harq->ulsch_pdu.rb_size);
              for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) {
                rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start;
                gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31));
573 574 575 576
              }
            }
          }
        }
577
      }
578 579
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
580

581 582 583 584 585 586 587 588 589 590 591 592 593 594
  for (int i=0;i<NUMBER_OF_NR_SRS_MAX;i++) {
    NR_gNB_SRS_t *srs = gNB->srs[i];
    if (srs) {
      if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
        nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
        for(int symbol = 0; symbol<(1<<srs_pdu->num_symbols); symbol++) {
          for(rb = srs_pdu->bwp_start; rb < (srs_pdu->bwp_start+srs_pdu->bwp_size); rb++) {
            gNB->rb_mask_ul[gNB->frame_parms.symbols_per_slot-srs_pdu->time_start_position-1+symbol][rb>>5] |= 1<<(rb&31);
          }
        }
      }
    }
  }

595 596
}

597
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
598 599

  uint8_t symbol;
600
  unsigned char aa;
rmagueta's avatar
rmagueta committed
601

602
  for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) {
603 604 605 606 607
    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,
608
                     slot_rx,
609 610
                     0);
    }
611
  }
612

613 614 615 616 617 618 619 620 621
  for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
    apply_nr_rotation_ul(&gNB->frame_parms,
			 gNB->common_vars.rxdataF[aa],
			 slot_rx,
			 0,
			 gNB->frame_parms.Ncp==EXTENDED?12:14,
			 gNB->frame_parms.ofdm_symbol_size);
  }

622 623
}

624
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
Cedric Roux's avatar
Cedric Roux committed
625 626 627
  /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
  int pucch_decode_done = 0;
  int pusch_decode_done = 0;
628
  int phy_procedures_errors = 0;
629

Rakesh's avatar
Rakesh committed
630
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
631
  LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
632

633
  fill_ul_rb_mask(gNB, frame_rx, slot_rx);
cig's avatar
cig committed
634

635 636 637 638
  int first_symb=0,num_symb=0;
  if (gNB->frame_parms.frame_type == TDD)
    for(int symbol_count=0; symbol_count<NR_NUMBER_OF_SYMBOLS_PER_SLOT; symbol_count++) {
      if (gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) {
639 640
	      if (num_symb==0) first_symb=symbol_count;
	      num_symb++;
641 642
      }
    }
643
  else num_symb=NR_NUMBER_OF_SYMBOLS_PER_SLOT;
Eurecom's avatar
Eurecom committed
644
  gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb);
645

646
  int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
647
  int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset+(47*12)],12*18);
648 649
  LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);

650 651
  start_meas(&gNB->phy_proc_rx);

Francesco Mani's avatar
Francesco Mani committed
652 653 654
  for (int i=0;i<NUMBER_OF_NR_PUCCH_MAX;i++){
    NR_gNB_PUCCH_t *pucch = gNB->pucch[i];
    if (pucch) {
David Kim's avatar
David Kim committed
655 656
      if (NFAPI_MODE == NFAPI_MODE_PNF)
        pucch->frame = frame_rx;
657
      if ((pucch->active == 1) &&
658 659
          (pucch->frame == frame_rx) &&
          (pucch->slot == slot_rx) ) {
660

Cedric Roux's avatar
Cedric Roux committed
661 662
        pucch_decode_done = 1;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
663
        nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
664 665 666 667 668 669 670 671 672 673 674
        uint16_t num_ucis;
        switch (pucch_pdu->format_type) {
        case 0:
          num_ucis = gNB->UL_INFO.uci_ind.num_ucis;
          gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0];
          gNB->UL_INFO.uci_ind.sfn = frame_rx;
          gNB->UL_INFO.uci_ind.slot = slot_rx;
          gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
          gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
          nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1;

675 676
          offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
          power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12);
rmagueta's avatar
rmagueta committed
677
          LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n",frame_rx,slot_rx,power_rxF);
678

679
          nr_decode_pucch0(gNB,
680
                           frame_rx,
681
                           slot_rx,
682 683 684 685 686
                           uci_pdu_format0,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
687
	        break;
688 689 690 691 692 693 694 695 696
        case 2:
          num_ucis = gNB->UL_INFO.uci_ind.num_ucis;
          gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0];
          gNB->UL_INFO.uci_ind.sfn = frame_rx;
          gNB->UL_INFO.uci_ind.slot = slot_rx;
          gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE;
          gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t);
          nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_2_3_4;

697
          LOG_D(PHY,"%d.%d Calling nr_decode_pucch2\n",frame_rx,slot_rx);
698 699 700 701 702 703 704
          nr_decode_pucch2(gNB,
                           slot_rx,
                           uci_pdu_format2,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
705
          break;
706
        default:
707
	        AssertFatal(1==0,"Only PUCCH formats 0 and 2 are currently supported\n");
708
        }
Francesco Mani's avatar
Francesco Mani committed
709 710 711 712
      }
    }
  }

713
  for (int ULSCH_id=0;ULSCH_id<gNB->number_of_nr_ulsch_max;ULSCH_id++) {
714
    NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id];
715
    int harq_pid;
rmagueta's avatar
rmagueta committed
716
    int no_sig;
717 718 719
    NR_UL_gNB_HARQ_t *ulsch_harq;

    if ((ulsch) &&
720
        (ulsch->rnti > 0)) {
721 722
      // for for an active HARQ process
      for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) {
723 724 725
        ulsch_harq = ulsch->harq_processes[harq_pid];
        AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid);
        if ((ulsch_harq->status == NR_ACTIVE) &&
726 727 728
            (ulsch_harq->frame == frame_rx) &&
            (ulsch_harq->slot == slot_rx) &&
            (ulsch_harq->handled == 0)){
729

730
          LOG_D(PHY, "PUSCH detection started in frame %d slot %d\n",
731
                frame_rx,slot_rx);
732 733 734
          int num_dmrs=0;
          for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT; s++)
             num_dmrs+=(ulsch_harq->ulsch_pdu.ul_dmrs_symb_pos>>s)&1;
735

736
#ifdef DEBUG_RXDATA
737 738
          NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
          RU_t *ru = gNB->RU_list[0];
739 740
          int slot_offset = frame_parms->get_samples_slot_timestamp(slot_rx,frame_parms,0);
          slot_offset -= ru->N_TA_offset;
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[0]=(int16_t)ulsch->rnti;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[1]=(int16_t)ulsch_harq->ulsch_pdu.rb_size;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[2]=(int16_t)ulsch_harq->ulsch_pdu.rb_start;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[3]=(int16_t)ulsch_harq->ulsch_pdu.nr_of_symbols;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[4]=(int16_t)ulsch_harq->ulsch_pdu.start_symbol_index;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[5]=(int16_t)ulsch_harq->ulsch_pdu.mcs_index;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[6]=(int16_t)ulsch_harq->ulsch_pdu.pusch_data.rv_index;
          ((int16_t*)&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset])[7]=(int16_t)harq_pid;
          memcpy(&gNB->common_vars.debugBuff[gNB->common_vars.debugBuff_sample_offset+4],&ru->common.rxdata[0][slot_offset],frame_parms->get_samples_per_slot(slot_rx,frame_parms)*sizeof(int32_t));
          gNB->common_vars.debugBuff_sample_offset+=(frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+4);
          if(gNB->common_vars.debugBuff_sample_offset>((frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+2)*20)) {
            FILE *f;
            f = fopen("rxdata_buff.raw", "w"); if (f == NULL) exit(1);
            fwrite((int16_t*)gNB->common_vars.debugBuff,2,(frame_parms->get_samples_per_slot(slot_rx,frame_parms)+1000+4)*20*2, f);
            fclose(f);
            exit(-1);
          }
758 759
#endif

Cedric Roux's avatar
Cedric Roux committed
760
          pusch_decode_done = 1;
761

Rakesh's avatar
Rakesh committed
762
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
763
	        start_meas(&gNB->rx_pusch_stats);
rmagueta's avatar
rmagueta committed
764
          no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid);
765
          if (no_sig) {
rmagueta's avatar
rmagueta committed
766
            LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx);
767
            nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1);
768 769
            phy_procedures_errors++;
            continue;
rmagueta's avatar
rmagueta committed
770
          }
771 772
          gNB->pusch_vars[ULSCH_id]->ulsch_power_tot=0;
          gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot=0;
773 774
          for (int aarx=0;aarx<gNB->frame_parms.nb_antennas_rx;aarx++) {
             gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx]/=num_dmrs;
775
             gNB->pusch_vars[ULSCH_id]->ulsch_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_power[aarx];
776
             gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx]/=num_dmrs;
777
             gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot += gNB->pusch_vars[ULSCH_id]->ulsch_noise_power[aarx];
778
          }
779
          if (dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) <
780
              dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot) + gNB->pusch_thres) {
781 782
             NR_gNB_SCH_STATS_t *stats=get_ulsch_stats(gNB,ulsch);

rmagueta's avatar
rmagueta committed
783
             LOG_D(PHY, "PUSCH not detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx,
784 785
                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
                   dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres);
786
             gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot;
787
             gNB->pusch_vars[ULSCH_id]->DTX=1;
Eurecom's avatar
Eurecom committed
788
             if (stats) stats->DTX++;
789 790 791 792
             if (!get_softmodem_params()->phy_test) {
               /* in case of phy_test mode, we still want to decode to measure execution time. 
                  Therefore, we don't yet call nr_fill_indication, it will be called later */
               nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1);
793 794
               phy_procedures_errors++;
               continue;
795
             }
796 797 798 799
          } else {
            LOG_D(PHY, "PUSCH detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx,
                  dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot),
                  dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot),gNB->pusch_thres);
800 801


802 803 804

            gNB->pusch_vars[ULSCH_id]->DTX=0;
          }
805
          stop_meas(&gNB->rx_pusch_stats);
Rakesh's avatar
Rakesh committed
806
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0);
807 808
          //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1);
          //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1);
809
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,1);
810
          nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid);
811
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX,0);
812 813
          break;
        }
Francesco Mani's avatar
Francesco Mani committed
814
      }
815 816
    }
  }
817 818 819 820 821

  for (int i=0;i<NUMBER_OF_NR_SRS_MAX;i++) {
    NR_gNB_SRS_t *srs = gNB->srs[i];
    if (srs) {
      if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
rmagueta's avatar
rmagueta committed
822

823
        LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i);
rmagueta's avatar
rmagueta committed
824

825
        nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
rmagueta's avatar
rmagueta committed
826 827

        // At least currently, the configuration is constant, so it is enough to generate the sequence just once.
828
        if(gNB->nr_srs_info[i]->sc_list_length == 0) {
829
          generate_srs_nr(srs_pdu, &gNB->frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
rmagueta's avatar
rmagueta committed
830 831
        }

832
        nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info[i], gNB->nr_srs_info[i]->srs_received_signal);
833 834 835 836 837

        nr_srs_channel_estimation(gNB,frame_rx,slot_rx,srs_pdu,
                                  gNB->nr_srs_info[i],
                                  gNB->nr_srs_info[i]->srs_generated_signal,
                                  gNB->nr_srs_info[i]->srs_received_signal,
rmagueta's avatar
rmagueta committed
838
                                  gNB->nr_srs_info[i]->srs_estimated_channel_freq,
839
                                  gNB->nr_srs_info[i]->srs_estimated_channel_time,
rmagueta's avatar
rmagueta committed
840
                                  gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted,
841 842
                                  gNB->nr_srs_info[i]->noise_power);

rmagueta's avatar
rmagueta committed
843 844
        T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
          T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t)));
845

rmagueta's avatar
rmagueta committed
846 847
        T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0),
          T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t)));
848

849 850 851 852 853
        srs->active = 0;
      }
    }
  }

854
  stop_meas(&gNB->phy_proc_rx);
rmagueta's avatar
rmagueta committed
855

Cedric Roux's avatar
Cedric Roux committed
856 857 858 859
  if (pucch_decode_done || pusch_decode_done) {
    T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
  }

Rakesh's avatar
Rakesh committed
860
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
861
  return phy_procedures_errors;
862
}