phy_procedures_nr_gNB.c 52.6 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/nr_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"
Robert Schmidt's avatar
Robert Schmidt committed
40
#include "nfapi/oai_integration/vendor_ext.h"
41
#include "NR_SRS-ResourceSet.h"
Guy De Souza's avatar
Guy De Souza committed
42 43 44 45 46

#include "assertions.h"

#include <time.h>

47
//#define DEBUG_RXDATA
48
//#define SRS_IND_DEBUG
49

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

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

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

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

67 68
  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);
69

70 71
  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
72

73
  // setting the first subcarrier
74 75
  const int scs = cfg->ssb_config.scs_common.value;
  const int prb_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>scs : ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>(scs-2);
76 77
  const int sc_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> scs
                                                   : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset >> (scs - 2);
78 79
  fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset);
  LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier, prb_offset, sc_offset);
80

81
  LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
82 83
  nr_generate_pss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
  nr_generate_sss(&txdataF[0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
84

francescomani's avatar
francescomani committed
85
  if (fp->Lmax == 4)
86 87 88 89 90 91
    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index & 7],
                          &txdataF[0][txdataF_offset],
                          gNB->TX_AMP,
                          ssb_start_symbol,
                          cfg,
                          fp);
92
  else
93 94 95 96 97 98
    nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index & 7],
                          &txdataF[0][txdataF_offset],
                          gNB->TX_AMP,
                          ssb_start_symbol,
                          cfg,
                          fp);
99

100
#if T_TRACER
101 102 103 104 105 106
  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));
107
  }
108
#endif
109

110 111 112 113 114
  // 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;
115
  }
116

117
  nr_generate_pbch(&ssb_pdu,
118 119
                   gNB->nr_pbch_interleaver,
                   &txdataF[0][txdataF_offset],
120
                   gNB->TX_AMP,
121
                   ssb_start_symbol,
122 123 124 125
                   n_hf,
                   frame,
                   cfg,
                   fp);
Guy De Souza's avatar
Guy De Souza committed
126 127
}

128

129 130 131
void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
                           int frame,
                           int slot,
132
                           int do_meas) {
133

Guy De Souza's avatar
Guy De Souza committed
134
  int aa;
135
  PHY_VARS_gNB *gNB = msgTx->gNB;
Guy De Souza's avatar
Guy De Souza committed
136
  NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
137
  nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
138
  int slot_prs = 0;
139
  int txdataF_offset = slot*fp->samples_per_slot_wCP;
140
  prs_config_t *prs_config = NULL;
Guy De Souza's avatar
Guy De Souza committed
141

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

145
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 1);
146

147
  // clear the transmit data array and beam index for the current slot
Raymond Knopp's avatar
Raymond Knopp committed
148
  for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
149
    memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
150
    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
151 152
  }

153
  // Check for PRS slot - section 7.4.1.7.4 in 3GPP rel16 38.211
154
  for(int rsc_id = 0; rsc_id < gNB->prs_vars.NumPRSResources; rsc_id++)
155
  {
156 157
    prs_config = &gNB->prs_vars.prs_cfg[rsc_id];
    for (int i = 0; i < prs_config->PRSResourceRepetition; i++)
158
    {
159
      if( (((frame*fp->slots_per_frame + slot) - (prs_config->PRSResourceSetPeriod[1] + prs_config->PRSResourceOffset)+prs_config->PRSResourceSetPeriod[0])%prs_config->PRSResourceSetPeriod[0]) == i*prs_config->PRSResourceTimeGap )
160
      {
161
        slot_prs = (slot - i*prs_config->PRSResourceTimeGap + fp->slots_per_frame)%fp->slots_per_frame;
162
        LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id);
163
        nr_generate_prs(gNB->nr_gold_prs[rsc_id][slot_prs],&gNB->common_vars.txdataF[0][txdataF_offset], AMP, prs_config, cfg, fp);
164 165
      }
    }
166 167
  }

Rakesh's avatar
Rakesh committed
168
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
169
  for (int i=0; i<fp->Lmax; i++) {
170 171 172
    if (msgTx->ssb[i].active) {
      nr_common_signal_procedures(gNB,frame,slot,msgTx->ssb[i].ssb_pdu);
      msgTx->ssb[i].active = false;
173
    }
174
  }
175
  
Rakesh's avatar
Rakesh committed
176
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
177

178
  int num_pdcch_pdus = msgTx->num_ul_pdcch + msgTx->num_dl_pdcch;
179

180 181 182
  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);
183
  
Rakesh's avatar
Rakesh committed
184
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1);
185

186
    nr_generate_dci_top(msgTx, slot, (int32_t *)&gNB->common_vars.txdataF[0][txdataF_offset], gNB->TX_AMP, fp);
187

Rakesh's avatar
Rakesh committed
188
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,0);
189
  }
190
 
Sakthivel Velumani's avatar
Sakthivel Velumani committed
191
  if (msgTx->num_pdsch_slot > 0) {
192
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
193
    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
194
    nr_generate_pdsch(msgTx, frame, slot);
195
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
196
  }
197

198
  for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){
199
    NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
200
    if (csirs->active == 1) {
201
      LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
202
      nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
203 204 205 206 207 208 209 210 211 212 213 214 215 216
      nr_generate_csi_rs(&gNB->frame_parms,
                         (int32_t **)gNB->common_vars.txdataF,
                         gNB->TX_AMP,
                         gNB->nr_csi_info,
                         csi_params,
                         slot,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL,
                         NULL);
217
      csirs->active = 0;
218 219 220
    }
  }

221
//  if ((frame&127) == 0) dump_pdsch_stats(gNB);
222 223

  //apply the OFDM symbol rotation here
224
  for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
225 226 227 228 229 230 231
    apply_nr_rotation_TX(fp,
                         &gNB->common_vars.txdataF[aa][txdataF_offset],
                         fp->symbol_rotation[0],
                         slot,
                         fp->N_RB_DL,
                         0,
                         fp->Ncp == EXTENDED ? 12 : 14);
232

233 234 235
    T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0),
      T_INT(frame), T_INT(slot),
      T_INT(aa), T_BUFFER(&gNB->common_vars.txdataF[aa][txdataF_offset], fp->samples_per_slot_wCP*sizeof(int32_t)));
236
  }
237

238
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0);
Guy De Souza's avatar
Guy De Souza committed
239
}
240

241
static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
242
{
Sakthi's avatar
Sakthi committed
243 244 245 246
  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;
francescomani's avatar
francescomani committed
247
  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id].harq_process->ulsch_pdu;
248
  bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter);
249
  ulsch_harq->processedSegments++;
250 251 252 253 254
  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
255
  if (decodeSuccess) {
256
    memcpy(ulsch_harq->b + rdata->offset, ulsch_harq->c[r], rdata->Kr_bytes - (ulsch_harq->F >> 3) - ((ulsch_harq->C > 1) ? 3 : 0));
Sakthi's avatar
Sakthi committed
257 258

  } else {
259
    LOG_D(PHY, "ULSCH %d in error\n", rdata->ulsch_id);
Sakthi's avatar
Sakthi committed
260 261
  }

rmagueta's avatar
rmagueta committed
262
  //int dumpsig=0;
263
  // if all segments are done
264 265 266 267 268
  if (ulsch_harq->processedSegments == ulsch_harq->C) {
    // When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the
    // CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
    bool crc_valid = true;
    if (ulsch_harq->C > 1) {
269
      crc_valid = check_crc(ulsch_harq->b, lenWithCrc(1, rdata->A), crcType(1, rdata->A));
270 271 272
    }

    if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
francescomani's avatar
francescomani committed
273 274 275 276 277 278 279 280 281 282 283 284 285
      LOG_D(PHY,
            "[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation "
            "(all seg) %d)\n",
            gNB->Mod_id,
            ulsch->frame,
            ulsch->slot,
            ulsch->rnti,
            rdata->harq_pid,
            pusch_pdu->pusch_data.new_data_indicator,
            ulsch->active,
            ulsch_harq->round,
            ulsch_harq->TBS,
            rdata->decodeIterations);
286 287
      ulsch->active = false;
      ulsch_harq->round = 0;
Eurecom's avatar
Eurecom committed
288
      LOG_D(PHY, "ULSCH received ok \n");
francescomani's avatar
francescomani committed
289
      nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 0, 0);
rmagueta's avatar
rmagueta committed
290
      //dumpsig=1;
291
    } else {
francescomani's avatar
francescomani committed
292 293 294 295 296 297 298 299 300
      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",
            gNB->Mod_id,
            ulsch->frame,
            ulsch->slot,
            rdata->harq_pid,
            pusch_pdu->pusch_data.new_data_indicator,
            ulsch->active,
301
            ulsch_harq->round,
302
            ulsch_harq->ulsch_pdu.pusch_data.rv_index,
303 304 305 306 307
            ulsch_harq->ulsch_pdu.rb_start,
            ulsch_harq->ulsch_pdu.rb_size,
            ulsch_harq->TBS,
            r);
      ulsch->handled = 1;
Sakthi's avatar
Sakthi committed
308
      LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
francescomani's avatar
francescomani committed
309 310
      nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 1, 0);
      //      dumpsig=1;
311
    }
312
    ulsch->last_iteration_cnt = rdata->decodeIterations;
francescomani's avatar
francescomani committed
313 314 315 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 341 342 343 344 345 346
    /*
        if (ulsch_harq->ulsch_pdu.mcs_index == 0 && dumpsig==1) {
          int off = ((ulsch_harq->ulsch_pdu.rb_size&1) == 1)? 4:0;

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

francescomani's avatar
francescomani committed
348 349
        }
    */
Sakthi's avatar
Sakthi committed
350 351 352 353 354
    ulsch->last_iteration_cnt = rdata->decodeIterations;
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
  }
}

355
static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
356
{
357
  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
francescomani's avatar
francescomani committed
358 359
  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id].harq_process->ulsch_pdu;

360 361 362
  uint16_t nb_re_dmrs;
  uint16_t start_symbol = pusch_pdu->start_symbol_index;
  uint16_t number_symbols = pusch_pdu->nr_of_symbols;
363

364 365
  uint8_t number_dmrs_symbols = 0;
  for (int l = start_symbol; l < start_symbol + number_symbols; l++)
Francesco Mani's avatar
Francesco Mani committed
366
    number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
367

368 369
  if (pusch_pdu->dmrs_config_type==pusch_dmrs_type1)
    nb_re_dmrs = 6*pusch_pdu->num_dmrs_cdm_grps_no_data;
370
  else
371
    nb_re_dmrs = 4*pusch_pdu->num_dmrs_cdm_grps_no_data;
372

373 374 375 376
  uint32_t G = nr_get_G(pusch_pdu->rb_size,
                        number_symbols,
                        nb_re_dmrs,
                        number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
377
                        gNB->ulsch[ULSCH_id].unav_res,
378 379
                        pusch_pdu->qam_mod_order,
                        pusch_pdu->nrOfLayers);
francescomani's avatar
francescomani committed
380

Raphael Defosseux's avatar
Raphael Defosseux committed
381
  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",
382 383 384 385 386 387
	      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);
388
  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",
389 390 391
	pusch_pdu->rb_size,
	number_symbols,
	nb_re_dmrs,
392
        pusch_pdu->ul_dmrs_symb_pos,
393 394 395
	number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
	pusch_pdu->qam_mod_order,
	pusch_pdu->nrOfLayers);
396
  
397 398 399 400
  //----------------------------------------------------------
  //--------------------- ULSCH decoding ---------------------
  //----------------------------------------------------------

401
  start_meas(&gNB->ulsch_decoding_stats);
402 403
  int nbDecode =
      nr_ulsch_decoding(gNB, ULSCH_id, gNB->pusch_vars[ULSCH_id].llr, frame_parms, pusch_pdu, frame_rx, slot_rx, harq_pid, G);
404

405
  return nbDecode;
406 407 408
}


409 410
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)
{
411 412
  if (!get_softmodem_params()->reorder_thread_disable) 
    pthread_mutex_lock(&gNB->UL_INFO_mutex);
413

francescomani's avatar
francescomani committed
414
  NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
415 416
  NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
  NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti);
417

418
  nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
419

420
  // Get estimated timing advance for MAC
421
  int sync_pos = ulsch->delay.est_delay;
422

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

426
  // do some integer rounding to improve TA accuracy
427
  int sync_pos_rounded;
428
  if (sync_pos > 0)
429
    sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
430
  else
431
    sync_pos_rounded = sync_pos - (bw_scaling / 2) + 1;
francescomani's avatar
francescomani committed
432 433
  if (stats)
    stats->ulsch_stats.sync_pos = sync_pos;
434

435
  int timing_advance_update = sync_pos_rounded / bw_scaling;
436 437 438 439 440 441 442

  // 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
443
  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);
444

445
  // estimate UL_CQI for MAC
francescomani's avatar
francescomani committed
446 447 448 449 450 451 452 453 454 455 456
  int SNRtimes10 =
      dB_fixed_x10(gNB->pusch_vars[ULSCH_id].ulsch_power_tot) - dB_fixed_x10(gNB->pusch_vars[ULSCH_id].ulsch_noise_power_tot);

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

458
  int cqi;
459 460 461 462
  if      (SNRtimes10 < -640) cqi=0;
  else if (SNRtimes10 >  635) cqi=255;
  else                        cqi=(640+SNRtimes10)/5;

Eurecom's avatar
Eurecom committed
463

464
  if (0/*pusch_pdu->mcs_index == 9*/) {
465
      __attribute__((unused))
Eurecom's avatar
Eurecom committed
466
      int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
467

Eurecom's avatar
Eurecom committed
468
      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);
francescomani's avatar
francescomani committed
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
      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);
Eurecom's avatar
Eurecom committed
494 495
      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);
francescomani's avatar
francescomani committed
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
        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);
Eurecom's avatar
Eurecom committed
515 516 517
      }
      exit(-1);

518 519
    }

520 521 522 523 524 525 526 527 528 529
  // 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;
530
  gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
531 532
  gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
  gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
533
  // in terms of dBFS range -128 to 0 with 0.1 step
francescomani's avatar
francescomani committed
534 535
  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;
536 537 538 539 540 541 542 543 544 545 546 547 548

  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;
549
  gNB->rx_pdu_list[num_rx].rssi = gNB->crc_pdu_list[num_crc].rssi;
550 551 552 553 554 555
  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;
  }
556

557
  gNB->UL_INFO.rx_ind.number_of_pdus++;
558

559 560
  if (!get_softmodem_params()->reorder_thread_disable) 
    pthread_mutex_unlock(&gNB->UL_INFO_mutex);
561
}
562

563 564 565
// 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
566 567 568 569
  int rb = 0;
  int rb2 = 0;
  int prbpos = 0;

570
  for (int symbol=0;symbol<14;symbol++) {
rmagueta's avatar
rmagueta committed
571 572 573 574 575 576
    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;
577
      }
rmagueta's avatar
rmagueta committed
578 579
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
580

581
  for (int i = 0; i < gNB->max_nb_pucch; i++){
francescomani's avatar
francescomani committed
582
    NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
luis_pereira87's avatar
luis_pereira87 committed
583 584 585 586 587 588 589
    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++) {
590 591
          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)) {
592
            for (rb=0; rb<pucch_pdu->prb_size; rb++) {
593
              rb2 = rb + pucch_pdu->bwp_start +
luis_pereira87's avatar
luis_pereira87 committed
594 595
                    ((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);
596
              gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31));
597 598 599 600
            }
          }
        }
      }
601
    }
luis_pereira87's avatar
luis_pereira87 committed
602 603
  }

604
  for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
francescomani's avatar
francescomani committed
605
    NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
Robert Schmidt's avatar
Robert Schmidt committed
606
    NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
francescomani's avatar
francescomani committed
607
    AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid);
francescomani's avatar
francescomani committed
608
    if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) {
609 610
      uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
      uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
francescomani's avatar
francescomani committed
611 612 613 614 615 616 617 618 619 620
      for (int symbol = symbol_start; symbol < symbol_end; symbol++) {
        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)) {
          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;
621
            gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31);
622 623
          }
        }
624
      }
625 626
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
627

628
  for (int i = 0; i < gNB->max_nb_srs; i++) {
francescomani's avatar
francescomani committed
629
    NR_gNB_SRS_t *srs = &gNB->srs[i];
630 631 632 633 634
    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++) {
laurent's avatar
laurent committed
635 636
            gNB->rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U
                                                                                                                       << (rb & 31);
637 638 639 640 641 642
          }
        }
      }
    }
  }

643 644
}

645
int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs,
646 647
                                  const nfapi_nr_srs_pdu_t *srs_pdu,
                                  const int N_RB_UL,
648
                                  const int8_t *snr_per_rb,
649
                                  const int srs_est) {
650

651 652
  prgs->num_prgs = srs_pdu->beamforming.num_prgs;
  for(int prg_idx = 0; prg_idx < prgs->num_prgs; prg_idx++) {
653
    if (srs_est<0) {
654 655 656 657 658
      prgs->prg_list[prg_idx].rb_snr = 0xFF;
    } else if (snr_per_rb[prg_idx] < -64) {
      prgs->prg_list[prg_idx].rb_snr = 0;
    } else if (snr_per_rb[prg_idx] > 63) {
      prgs->prg_list[prg_idx].rb_snr = 0xFE;
659
    } else {
660
      prgs->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1;
661 662 663 664 665 666
    }
  }

  return 0;
}

667 668 669 670 671 672 673 674
int fill_srs_channel_matrix(uint8_t *channel_matrix,
                            const nfapi_nr_srs_pdu_t *srs_pdu,
                            const nr_srs_info_t *nr_srs_info,
                            const uint8_t normalized_iq_representation,
                            const uint16_t num_gnb_antenna_elements,
                            const uint16_t num_ue_srs_ports,
                            const uint16_t prg_size,
                            const uint16_t num_prgs,
675
                            const NR_DL_FRAME_PARMS *frame_parms,
676
                            const int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)]) {
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693

  const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*NR_NB_SC_PER_RB;
  const uint16_t step = prg_size*NR_NB_SC_PER_RB;

  c16_t *channel_matrix16 = (c16_t*)channel_matrix;
  c8_t *channel_matrix8 = (c8_t*)channel_matrix;

  for(int uI = 0; uI < num_ue_srs_ports; uI++) {
    for(int gI = 0; gI < num_gnb_antenna_elements; gI++) {

      uint16_t subcarrier = subcarrier_offset + nr_srs_info->k_0_p[uI][0];
      if (subcarrier>frame_parms->ofdm_symbol_size) {
        subcarrier -= frame_parms->ofdm_symbol_size;
      }

      for(int pI = 0; pI < num_prgs; pI++) {

694
        c16_t *srs_estimated_channel16 = (c16_t *)&srs_estimated_channel_freq[gI][uI][subcarrier];
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
        uint16_t index = uI*num_gnb_antenna_elements*num_prgs + gI*num_prgs + pI;

        if (normalized_iq_representation == 0) {
          channel_matrix8[index].r = (int8_t)(srs_estimated_channel16->r>>8);
          channel_matrix8[index].i = (int8_t)(srs_estimated_channel16->i>>8);
        } else {
          channel_matrix16[index].r = srs_estimated_channel16->r;
          channel_matrix16[index].i = srs_estimated_channel16->i;
        }

        // Subcarrier increment
        subcarrier += step;
        if (subcarrier >= frame_parms->ofdm_symbol_size) {
          subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
        }
      }
    }
  }

  return 0;
}

717 718 719 720 721 722 723 724 725 726 727 728 729 730
int check_srs_pdu(const nfapi_nr_srs_pdu_t *srs_pdu, nfapi_nr_srs_pdu_t *saved_srs_pdu)
{
  if (saved_srs_pdu->bwp_start == srs_pdu->bwp_start &&
      saved_srs_pdu->bwp_size == srs_pdu->bwp_size &&
      saved_srs_pdu->num_ant_ports == srs_pdu->num_ant_ports &&
      saved_srs_pdu->time_start_position == srs_pdu->time_start_position &&
      saved_srs_pdu->num_symbols == srs_pdu->num_symbols &&
      saved_srs_pdu->config_index == srs_pdu->config_index) {
    return 1;
  }
  *saved_srs_pdu = *srs_pdu;
  return 0;
}

731 732
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
{
Cedric Roux's avatar
Cedric Roux committed
733 734 735
  /* 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;
736
  int pusch_DTX = 0;
737

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

741
  fill_ul_rb_mask(gNB, frame_rx, slot_rx);
cig's avatar
cig committed
742

743 744 745 746
  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) {
747 748
	      if (num_symb==0) first_symb=symbol_count;
	      num_symb++;
749 750
      }
    }
751
  else
francescomani's avatar
francescomani committed
752
    num_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT;
Eurecom's avatar
Eurecom committed
753
  gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb);
754

755 756 757
  const int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
  int offset = 10 * gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
  int power_rxF = signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset + offset + (47 * 12)], 12 * 18);
758 759
  LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);

760 761
  start_meas(&gNB->phy_proc_rx);

762
  for (int i = 0; i < gNB->max_nb_pucch; i++) {
francescomani's avatar
francescomani committed
763
    NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
Francesco Mani's avatar
Francesco Mani committed
764
    if (pucch) {
David Kim's avatar
David Kim committed
765 766
      if (NFAPI_MODE == NFAPI_MODE_PNF)
        pucch->frame = frame_rx;
767
      if ((pucch->active == 1) &&
768 769
          (pucch->frame == frame_rx) &&
          (pucch->slot == slot_rx) ) {
770

Cedric Roux's avatar
Cedric Roux committed
771 772
        pucch_decode_done = 1;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
773
        nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
774 775 776 777 778 779 780 781 782 783 784
        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;

785
          offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
786 787
          power_rxF = signal_energy_nodc((int32_t *)&gNB->common_vars.rxdataF[0][soffset+offset], 12);
          LOG_D(PHY,"frame %d, slot %d: PUCCH signal energy %d\n", frame_rx, slot_rx, power_rxF);
788

789
          nr_decode_pucch0(gNB,
790
                           frame_rx,
791
                           slot_rx,
792 793 794 795 796
                           uci_pdu_format0,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
797
          break;
798 799 800 801 802 803 804 805 806
        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;

francescomani's avatar
francescomani committed
807
          LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx);
808
          nr_decode_pucch2(gNB,
809
                           frame_rx,
810 811 812 813 814 815
                           slot_rx,
                           uci_pdu_format2,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
816
          break;
817
        default:
francescomani's avatar
francescomani committed
818
          AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n");
819
        }
Francesco Mani's avatar
Francesco Mani committed
820 821 822 823
      }
    }
  }

824
  int totalDecode = 0;
825
  for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
francescomani's avatar
francescomani committed
826
    NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
827 828 829
    NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
    AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid);

francescomani's avatar
francescomani committed
830 831
    if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) {
      LOG_D(PHY, "PUSCH ID %d with RNTI %x detection started in frame %d slot %d\n", ULSCH_id, ulsch->rnti, frame_rx, slot_rx);
832 833 834
      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;
835

836
#ifdef DEBUG_RXDATA
837 838
      NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
      RU_t *ru = gNB->RU_list[0];
francescomani's avatar
francescomani committed
839
      int slot_offset = frame_parms->get_samples_slot_timestamp(slot_rx, frame_parms, 0);
840
      slot_offset -= ru->N_TA_offset;
Robert Schmidt's avatar
Robert Schmidt committed
841 842
      int32_t sample_offset = gNB->common_vars.debugBuff_sample_offset;
      nfapi_nr_pusch_pdu_t *pdu = &ulsch_harq->ulsch_pdu;
francescomani's avatar
francescomani committed
843 844 845 846 847 848 849 850 851 852 853 854 855 856
      int16_t *buf = (int16_t *)&gNB->common_vars.debugBuff[offset];
      buf[0] = (int16_t)ulsch->rnti;
      buf[1] = (int16_t)pdu->rb_size;
      buf[2] = (int16_t)pdu->rb_start;
      buf[3] = (int16_t)pdu->nr_of_symbols;
      buf[4] = (int16_t)pdu->start_symbol_index;
      buf[5] = (int16_t)pdu->mcs_index;
      buf[6] = (int16_t)pdu->pusch_data.rv_index;
      buf[7] = (int16_t)ulsch->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)) {
857
        FILE *f;
francescomani's avatar
francescomani committed
858 859 860 861 862 863 864
        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);
865 866 867
        fclose(f);
        exit(-1);
      }
868 869
#endif

870 871
      pusch_decode_done = 1;

francescomani's avatar
francescomani committed
872
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 1);
873
      start_meas(&gNB->rx_pusch_stats);
874
      nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
francescomani's avatar
francescomani committed
875
      NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
Robert Schmidt's avatar
Robert Schmidt committed
876 877
      pusch_vars->ulsch_power_tot = 0;
      pusch_vars->ulsch_noise_power_tot = 0;
francescomani's avatar
francescomani committed
878 879 880 881 882
      for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) {
        pusch_vars->ulsch_power[aarx] /= num_dmrs;
        pusch_vars->ulsch_power_tot += pusch_vars->ulsch_power[aarx];
        pusch_vars->ulsch_noise_power[aarx] /= num_dmrs;
        pusch_vars->ulsch_noise_power_tot += pusch_vars->ulsch_noise_power[aarx];
883
      }
francescomani's avatar
francescomani committed
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
      if (dB_fixed_x10(pusch_vars->ulsch_power_tot) < dB_fixed_x10(pusch_vars->ulsch_noise_power_tot) + gNB->pusch_thres) {
        NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti);

        LOG_D(PHY,
              "PUSCH not detected in %d.%d (%d,%d,%d)\n",
              frame_rx,
              slot_rx,
              dB_fixed_x10(pusch_vars->ulsch_power_tot),
              dB_fixed_x10(pusch_vars->ulsch_noise_power_tot),
              gNB->pusch_thres);
        pusch_vars->ulsch_power_tot = pusch_vars->ulsch_noise_power_tot;
        pusch_vars->DTX = 1;
        if (stats)
          stats->ulsch_stats.DTX++;
        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, ulsch->harq_pid, 1, 1);
          pusch_DTX++;
          continue;
        }
905
      } else {
francescomani's avatar
francescomani committed
906 907 908 909
        LOG_D(PHY,
              "PUSCH detected in %d.%d (%d,%d,%d)\n",
              frame_rx,
              slot_rx,
Robert Schmidt's avatar
Robert Schmidt committed
910
              dB_fixed_x10(pusch_vars->ulsch_power_tot),
francescomani's avatar
francescomani committed
911 912
              dB_fixed_x10(pusch_vars->ulsch_noise_power_tot),
              gNB->pusch_thres);
913

francescomani's avatar
francescomani committed
914
        pusch_vars->DTX = 0;
Francesco Mani's avatar
Francesco Mani committed
915
      }
916
      stop_meas(&gNB->rx_pusch_stats);
francescomani's avatar
francescomani committed
917 918 919 920
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 0);
      // 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);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 1);
mir's avatar
mir committed
921
      int const tasks_added = nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid);
Robert Schmidt's avatar
Robert Schmidt committed
922
      if (tasks_added > 0)
mir's avatar
mir committed
923 924
        totalDecode += tasks_added; 

francescomani's avatar
francescomani committed
925
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
926 927
    }
  }
928 929 930 931 932 933 934 935
    while (totalDecode > 0) {
      notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
      if (req == NULL)
        break; // Tpool has been stopped
      nr_postDecode(gNB, req);
      delNotifiedFIFO_elt(req);
      totalDecode--;
    }
936
  stop_meas(&gNB->ulsch_decoding_stats);
937
  for (int i = 0; i < gNB->max_nb_srs; i++) {
francescomani's avatar
francescomani committed
938
    NR_gNB_SRS_t *srs = &gNB->srs[i];
939 940 941
    if (srs) {
      if ((srs->active == 1) && (srs->frame == frame_rx) && (srs->slot == slot_rx)) {
        LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i);
rmagueta's avatar
rmagueta committed
942

943 944
        start_meas(&gNB->rx_srs_stats);

945
        NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
946
        nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
947 948 949 950 951
        uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols;
        int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size * N_symb_SRS];
        int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size * N_symb_SRS] __attribute__((aligned(32)));
        int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
        int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][1 << srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size];
952
        int8_t snr_per_rb[srs_pdu->bwp_size];
953
        int8_t snr = 0;
rmagueta's avatar
rmagueta committed
954

955
        start_meas(&gNB->generate_srs_stats);
956 957 958
        if (check_srs_pdu(srs_pdu, &gNB->nr_srs_info[i]->srs_pdu) == 0) {
          generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, 0, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx);
        }
959 960 961
        stop_meas(&gNB->generate_srs_stats);

        start_meas(&gNB->get_srs_signal_stats);
luis_pereira87's avatar
luis_pereira87 committed
962
        int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
963
        stop_meas(&gNB->get_srs_signal_stats);
964 965

        if (srs_est >= 0) {
966
          start_meas(&gNB->srs_channel_estimation_stats);
967 968 969 970
          nr_srs_channel_estimation(gNB,
                                    frame_rx,
                                    slot_rx,
                                    srs_pdu,
971
                                    gNB->nr_srs_info[i],
972
                                    (const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal,
973 974 975 976
                                    srs_received_signal,
                                    srs_estimated_channel_freq,
                                    srs_estimated_channel_time,
                                    srs_estimated_channel_time_shifted,
977 978
                                    snr_per_rb,
                                    &snr);
979
          stop_meas(&gNB->srs_channel_estimation_stats);
980
        }
981

luis_pereira87's avatar
luis_pereira87 committed
982 983 984
        if ((snr * 10) < gNB->srs_thres) {
          srs_est = -1;
        }
985

luis_pereira87's avatar
luis_pereira87 committed
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
        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(srs_estimated_channel_freq[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));

        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(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t)));
1001

1002 1003 1004
        gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0];
        gNB->UL_INFO.srs_ind.sfn = frame_rx;
        gNB->UL_INFO.srs_ind.slot = slot_rx;
luis_pereira87's avatar
luis_pereira87 committed
1005 1006 1007 1008

        nfapi_nr_srs_indication_pdu_t *srs_indication = &gNB->srs_pdu_list[gNB->UL_INFO.srs_ind.number_of_pdus];
        srs_indication->handle = srs_pdu->handle;
        srs_indication->rnti = srs_pdu->rnti;
1009
        start_meas(&gNB->srs_timing_advance_stats);
1010
        srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF;
1011
        stop_meas(&gNB->srs_timing_advance_stats);
1012
        srs_indication->timing_advance_offset_nsec = srs_est >= 0 ? (int16_t)((((int32_t)srs_indication->timing_advance_offset - 31) * ((int32_t)TC_NSEC_x32768)) >> 15) : 0xFFFF;
1013 1014 1015 1016
        switch (srs_pdu->srs_parameters_v4.usage) {
          case 0:
            LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
            return 0;
1017 1018
          case 1 << NR_SRS_ResourceSet__usage_beamManagement:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_beamManagement;
1019
            break;
1020 1021
          case 1 << NR_SRS_ResourceSet__usage_codebook:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_codebook;
1022
            break;
1023 1024
          case 1 << NR_SRS_ResourceSet__usage_nonCodebook:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_nonCodebook;
1025
            break;
1026 1027
          case 1 << NR_SRS_ResourceSet__usage_antennaSwitching:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching;
1028 1029 1030 1031
            break;
          default:
            LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage);
        }
1032
        srs_indication->report_type = srs_pdu->srs_parameters_v4.report_type[0];
1033 1034 1035 1036

#ifdef SRS_IND_DEBUG
        LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn);
        LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot);
1037 1038 1039 1040 1041
        LOG_I(NR_PHY, "srs_indication->rnti = %04x\n", srs_indication->rnti);
        LOG_I(NR_PHY, "srs_indication->timing_advance = %i\n", srs_indication->timing_advance_offset);
        LOG_I(NR_PHY, "srs_indication->timing_advance_offset_nsec = %i\n", srs_indication->timing_advance_offset_nsec);
        LOG_I(NR_PHY, "srs_indication->srs_usage = %i\n", srs_indication->srs_usage);
        LOG_I(NR_PHY, "srs_indication->report_type = %i\n", srs_indication->report_type);
1042 1043
#endif

1044 1045 1046
        nfapi_srs_report_tlv_t *report_tlv = &srs_indication->report_tlv;
        report_tlv->tag = 0;
        report_tlv->length = 0;
1047

1048
        start_meas(&gNB->srs_report_tlv_stats);
1049
        switch (srs_indication->srs_usage) {
1050
          case NR_SRS_ResourceSet__usage_beamManagement: {
1051
            start_meas(&gNB->srs_beam_report_stats);
1052 1053 1054 1055 1056
            nfapi_nr_srs_beamforming_report_t nr_srs_bf_report;
            nr_srs_bf_report.prg_size = srs_pdu->beamforming.prg_size;
            nr_srs_bf_report.num_symbols = 1 << srs_pdu->num_symbols;
            nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
            nr_srs_bf_report.num_reported_symbols = 1 << srs_pdu->num_symbols;
1057
            fill_srs_reported_symbol_list(&nr_srs_bf_report.prgs, srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
1058

1059
#ifdef SRS_IND_DEBUG
1060 1061 1062 1063 1064 1065
            LOG_I(NR_PHY, "nr_srs_bf_report.prg_size = %i\n", nr_srs_bf_report.prg_size);
            LOG_I(NR_PHY, "nr_srs_bf_report.num_symbols = %i\n", nr_srs_bf_report.num_symbols);
            LOG_I(NR_PHY, "nr_srs_bf_report.wide_band_snr = %i (%i dB)\n", nr_srs_bf_report.wide_band_snr, (nr_srs_bf_report.wide_band_snr >> 1) - 64);
            LOG_I(NR_PHY, "nr_srs_bf_report.num_reported_symbols = %i\n", nr_srs_bf_report.num_reported_symbols);
            LOG_I(NR_PHY, "nr_srs_bf_report.prgs[0].num_prgs = %i\n", nr_srs_bf_report.prgs[0].num_prgs);
            for (int prg_idx = 0; prg_idx < nr_srs_bf_report.prgs[0].num_prgs; prg_idx++) {
1066 1067
              LOG_I(NR_PHY,
                    "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
1068
                    prg_idx,
1069 1070
                     nr_srs_bf_report.prgs[0].prg_list[prg_idx].rb_snr,
                    (nr_srs_bf_report.prgs[0].prg_list[prg_idx].rb_snr >> 1) - 64);
1071
            }
1072 1073
#endif

1074
            report_tlv->length = pack_nr_srs_beamforming_report(&nr_srs_bf_report, report_tlv->value, sizeof(report_tlv->value));
1075
            stop_meas(&gNB->srs_beam_report_stats);
1076 1077 1078 1079
            break;
          }

          case NR_SRS_ResourceSet__usage_codebook: {
1080
            start_meas(&gNB->srs_iq_matrix_stats);
1081 1082 1083 1084 1085 1086 1087
            nfapi_nr_srs_normalized_channel_iq_matrix_t nr_srs_channel_iq_matrix;
            nr_srs_channel_iq_matrix.normalized_iq_representation = srs_pdu->srs_parameters_v4.iq_representation;
            nr_srs_channel_iq_matrix.num_gnb_antenna_elements = gNB->frame_parms.nb_antennas_rx;
            nr_srs_channel_iq_matrix.num_ue_srs_ports = srs_pdu->srs_parameters_v4.num_total_ue_antennas;
            nr_srs_channel_iq_matrix.prg_size = srs_pdu->srs_parameters_v4.prg_size;
            nr_srs_channel_iq_matrix.num_prgs = srs_pdu->srs_parameters_v4.srs_bandwidth_size / srs_pdu->srs_parameters_v4.prg_size;
            fill_srs_channel_matrix(nr_srs_channel_iq_matrix.channel_matrix,
1088 1089
                                    srs_pdu,
                                    gNB->nr_srs_info[i],
1090 1091 1092 1093 1094
                                    nr_srs_channel_iq_matrix.normalized_iq_representation,
                                    nr_srs_channel_iq_matrix.num_gnb_antenna_elements,
                                    nr_srs_channel_iq_matrix.num_ue_srs_ports,
                                    nr_srs_channel_iq_matrix.prg_size,
                                    nr_srs_channel_iq_matrix.num_prgs,
1095 1096
                                    &gNB->frame_parms,
                                    srs_estimated_channel_freq);
1097 1098

#ifdef SRS_IND_DEBUG
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
            LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.normalized_iq_representation = %i\n", nr_srs_channel_iq_matrix.normalized_iq_representation);
            LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.num_gnb_antenna_elements = %i\n", nr_srs_channel_iq_matrix.num_gnb_antenna_elements);
            LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.num_ue_srs_ports = %i\n", nr_srs_channel_iq_matrix.num_ue_srs_ports);
            LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.prg_size = %i\n", nr_srs_channel_iq_matrix.prg_size);
            LOG_I(NR_PHY, "nr_srs_channel_iq_matrix.num_prgs = %i\n", nr_srs_channel_iq_matrix.num_prgs);
            c16_t *channel_matrix16 = (c16_t *)nr_srs_channel_iq_matrix.channel_matrix;
            c8_t *channel_matrix8 = (c8_t *)nr_srs_channel_iq_matrix.channel_matrix;
            for (int uI = 0; uI < nr_srs_channel_iq_matrix.num_ue_srs_ports; uI++) {
              for (int gI = 0; gI < nr_srs_channel_iq_matrix.num_gnb_antenna_elements; gI++) {
                for (int pI = 0; pI < nr_srs_channel_iq_matrix.num_prgs; pI++) {
1109
                  uint16_t index =
1110
                      uI * nr_srs_channel_iq_matrix.num_gnb_antenna_elements * nr_srs_channel_iq_matrix.num_prgs + gI * nr_srs_channel_iq_matrix.num_prgs + pI;
1111 1112 1113 1114 1115
                  LOG_I(NR_PHY,
                        "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
                        uI,
                        gI,
                        pI,
1116 1117
                        nr_srs_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].r : channel_matrix16[index].r,
                        nr_srs_channel_iq_matrix.normalized_iq_representation == 0 ? channel_matrix8[index].i : channel_matrix16[index].i);
1118 1119 1120
                }
              }
            }
1121 1122
#endif

1123
            report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(&nr_srs_channel_iq_matrix, report_tlv->value, sizeof(report_tlv->value));
1124
            stop_meas(&gNB->srs_iq_matrix_stats);
1125 1126 1127 1128 1129 1130 1131 1132 1133
            break;
          }

          case NR_SRS_ResourceSet__usage_nonCodebook:
          case NR_SRS_ResourceSet__usage_antennaSwitching:
            LOG_W(NR_PHY, "PHY procedures for this SRS usage are not implemented yet!\n");
            break;

          default:
1134
            AssertFatal(1 == 0, "Invalid SRS usage\n");
1135
        }
1136
        stop_meas(&gNB->srs_report_tlv_stats);
1137

1138
#ifdef SRS_IND_DEBUG
1139 1140 1141 1142
        LOG_I(NR_PHY, "report_tlv->tag = %i\n", report_tlv->tag);
        LOG_I(NR_PHY, "report_tlv->length = %i\n", report_tlv->length);
        char *value = (char *)report_tlv->value;
        for (int b = 0; b < report_tlv->length; b++) {
1143
          LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b] & 0xFF);
1144 1145 1146
        }
#endif

1147
        gNB->UL_INFO.srs_ind.number_of_pdus += 1;
1148
        srs->active = 0;
1149 1150

        stop_meas(&gNB->rx_srs_stats);
1151 1152 1153 1154
      }
    }
  }

1155
  stop_meas(&gNB->phy_proc_rx);
rmagueta's avatar
rmagueta committed
1156

Cedric Roux's avatar
Cedric Roux committed
1157 1158 1159 1160
  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
1161
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
1162
  return pusch_DTX;
1163
}