phy_procedures_nr_gNB.c 54.1 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 269 270 271 272 273 274 275 276 277
  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) {
      // Check ULSCH transport block CRC
      int crc_type = CRC16;
      if (rdata->A > 3824) {
        crc_type = CRC24_A;
      }
      crc_valid = check_crc(ulsch_harq->b, ulsch_harq->B, crc_type);
    }

    if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
francescomani's avatar
francescomani committed
278 279 280 281 282 283 284 285 286 287 288 289 290
      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);
291 292
      ulsch->active = false;
      ulsch_harq->round = 0;
Eurecom's avatar
Eurecom committed
293
      LOG_D(PHY, "ULSCH received ok \n");
francescomani's avatar
francescomani committed
294
      nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 0, 0);
rmagueta's avatar
rmagueta committed
295
      //dumpsig=1;
296
    } else {
francescomani's avatar
francescomani committed
297 298 299 300 301 302 303 304 305
      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,
306
            ulsch_harq->round,
307
            ulsch_harq->ulsch_pdu.pusch_data.rv_index,
308 309 310 311 312
            ulsch_harq->ulsch_pdu.rb_start,
            ulsch_harq->ulsch_pdu.rb_size,
            ulsch_harq->TBS,
            r);
      ulsch->handled = 1;
Sakthi's avatar
Sakthi committed
313
      LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id);
francescomani's avatar
francescomani committed
314 315
      nr_fill_indication(gNB, ulsch->frame, ulsch->slot, rdata->ulsch_id, rdata->harq_pid, 1, 0);
      //      dumpsig=1;
316
    }
317
    ulsch->last_iteration_cnt = rdata->decodeIterations;
francescomani's avatar
francescomani committed
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 347 348 349 350 351
    /*
        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);
352

francescomani's avatar
francescomani committed
353 354
        }
    */
Sakthi's avatar
Sakthi committed
355 356 357 358 359
    ulsch->last_iteration_cnt = rdata->decodeIterations;
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,0);
  }
}

360
static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
361
{
362
  NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
francescomani's avatar
francescomani committed
363 364
  nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id].harq_process->ulsch_pdu;

365 366 367
  uint16_t nb_re_dmrs;
  uint16_t start_symbol = pusch_pdu->start_symbol_index;
  uint16_t number_symbols = pusch_pdu->nr_of_symbols;
368

369 370
  uint8_t number_dmrs_symbols = 0;
  for (int l = start_symbol; l < start_symbol + number_symbols; l++)
Francesco Mani's avatar
Francesco Mani committed
371
    number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01;
372

373 374
  if (pusch_pdu->dmrs_config_type==pusch_dmrs_type1)
    nb_re_dmrs = 6*pusch_pdu->num_dmrs_cdm_grps_no_data;
375
  else
376
    nb_re_dmrs = 4*pusch_pdu->num_dmrs_cdm_grps_no_data;
377

378 379 380 381 382 383
  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
                        pusch_pdu->qam_mod_order,
                        pusch_pdu->nrOfLayers);
francescomani's avatar
francescomani committed
384

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

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
  if (gNB->use_pusch_tp == 0 ) 
  { 
    nr_ulsch_layer_demapping(gNB->pusch_vars[ULSCH_id].llr,
                             pusch_pdu->nrOfLayers,
                             pusch_pdu->qam_mod_order,
                             G,
                             gNB->pusch_vars[ULSCH_id].llr_layers);
    //----------------------------------------------------------
    //------------------- ULSCH unscrambling -------------------
    //----------------------------------------------------------
    start_meas(&gNB->ulsch_unscrambling_stats);
    nr_ulsch_unscrambling(gNB->pusch_vars[ULSCH_id].llr, G, pusch_pdu->data_scrambling_id, pusch_pdu->rnti);
    stop_meas(&gNB->ulsch_unscrambling_stats);
  }
  
416 417 418 419
  //----------------------------------------------------------
  //--------------------- ULSCH decoding ---------------------
  //----------------------------------------------------------

420
  start_meas(&gNB->ulsch_decoding_stats);
421 422
  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);
423

424
  return nbDecode;
425 426 427
}


428 429
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)
{
430 431
  if (!get_softmodem_params()->reorder_thread_disable) 
    pthread_mutex_lock(&gNB->UL_INFO_mutex);
432

francescomani's avatar
francescomani committed
433
  NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
434 435
  NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
  NR_gNB_PHY_STATS_t *stats = get_phy_stats(gNB, ulsch->rnti);
436

437
  nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
438

439
  // Get estimated timing advance for MAC
440
  int sync_pos = ulsch->delay.est_delay;
441

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

445
  // do some integer rounding to improve TA accuracy
446
  int sync_pos_rounded;
447
  if (sync_pos > 0)
448
    sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
449
  else
450
    sync_pos_rounded = sync_pos - (bw_scaling / 2) + 1;
francescomani's avatar
francescomani committed
451 452
  if (stats)
    stats->ulsch_stats.sync_pos = sync_pos;
453

454
  int timing_advance_update = sync_pos_rounded / bw_scaling;
455 456 457 458 459 460 461

  // 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
462
  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);
463

464
  // estimate UL_CQI for MAC
francescomani's avatar
francescomani committed
465 466 467 468 469 470 471 472 473 474 475
  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);
476

477
  int cqi;
478 479 480 481
  if      (SNRtimes10 < -640) cqi=0;
  else if (SNRtimes10 >  635) cqi=255;
  else                        cqi=(640+SNRtimes10)/5;

Eurecom's avatar
Eurecom committed
482

483
  if (0/*pusch_pdu->mcs_index == 9*/) {
484
      __attribute__((unused))
Eurecom's avatar
Eurecom committed
485
      int off = ((pusch_pdu->rb_size&1) == 1)? 4:0;
486

Eurecom's avatar
Eurecom committed
487
      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
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
      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);
Eurecom's avatar
Eurecom committed
519 520
      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
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
        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);
Eurecom's avatar
Eurecom committed
546 547 548
      }
      exit(-1);

549 550
    }

551 552 553 554 555 556 557 558 559 560
  // 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;
561
  gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb;
562 563
  gNB->crc_pdu_list[num_crc].ul_cqi = cqi;
  gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update;
564
  // in terms of dBFS range -128 to 0 with 0.1 step
francescomani's avatar
francescomani committed
565 566
  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;
567 568 569 570 571 572 573 574 575 576 577 578 579

  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;
580
  gNB->rx_pdu_list[num_rx].rssi = gNB->crc_pdu_list[num_crc].rssi;
581 582 583 584 585 586
  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;
  }
587

588
  gNB->UL_INFO.rx_ind.number_of_pdus++;
589

590 591
  if (!get_softmodem_params()->reorder_thread_disable) 
    pthread_mutex_unlock(&gNB->UL_INFO_mutex);
592
}
593

594 595 596
// 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
597 598 599 600
  int rb = 0;
  int rb2 = 0;
  int prbpos = 0;

601
  for (int symbol=0;symbol<14;symbol++) {
rmagueta's avatar
rmagueta committed
602 603 604 605 606 607
    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;
608
      }
rmagueta's avatar
rmagueta committed
609 610
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
611

612
  for (int i = 0; i < gNB->max_nb_pucch; i++){
francescomani's avatar
francescomani committed
613
    NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
luis_pereira87's avatar
luis_pereira87 committed
614 615 616 617 618 619 620
    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++) {
621 622
          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)) {
623
            for (rb=0; rb<pucch_pdu->prb_size; rb++) {
624
              rb2 = rb + pucch_pdu->bwp_start +
luis_pereira87's avatar
luis_pereira87 committed
625 626
                    ((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);
627
              gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31));
628 629 630 631
            }
          }
        }
      }
632
    }
luis_pereira87's avatar
luis_pereira87 committed
633 634
  }

635
  for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
francescomani's avatar
francescomani committed
636
    NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
Robert Schmidt's avatar
Robert Schmidt committed
637
    NR_UL_gNB_HARQ_t *ulsch_harq = ulsch->harq_process;
francescomani's avatar
francescomani committed
638
    AssertFatal(ulsch_harq != NULL, "harq_pid %d is not allocated\n", ulsch->harq_pid);
francescomani's avatar
francescomani committed
639
    if ((ulsch->active == true) && (ulsch->frame == frame_rx) && (ulsch->slot == slot_rx) && (ulsch->handled == 0)) {
640 641
      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
642 643 644 645 646 647 648 649 650 651
      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;
652
            gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31);
653 654
          }
        }
655
      }
656 657
    }
  }
luis_pereira87's avatar
luis_pereira87 committed
658

659
  for (int i = 0; i < gNB->max_nb_srs; i++) {
francescomani's avatar
francescomani committed
660
    NR_gNB_SRS_t *srs = &gNB->srs[i];
661 662 663 664 665
    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
666 667
            gNB->rb_mask_ul[gNB->frame_parms.symbols_per_slot - srs_pdu->time_start_position - 1 + symbol][rb >> 5] |= 1U
                                                                                                                       << (rb & 31);
668 669 670 671 672 673
          }
        }
      }
    }
  }

674 675
}

676
int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs,
677 678
                                  const nfapi_nr_srs_pdu_t *srs_pdu,
                                  const int N_RB_UL,
679
                                  const int8_t *snr_per_rb,
680
                                  const int srs_est) {
681

682 683
  prgs->num_prgs = srs_pdu->beamforming.num_prgs;
  for(int prg_idx = 0; prg_idx < prgs->num_prgs; prg_idx++) {
684
    if (srs_est<0) {
685 686 687 688 689
      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;
690
    } else {
691
      prgs->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1;
692 693 694 695 696 697
    }
  }

  return 0;
}

698 699 700 701 702 703 704 705
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,
706
                            const NR_DL_FRAME_PARMS *frame_parms,
707
                            const int32_t srs_estimated_channel_freq[][1<<srs_pdu->num_ant_ports][frame_parms->ofdm_symbol_size*(1<<srs_pdu->num_symbols)]) {
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724

  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++) {

725
        c16_t *srs_estimated_channel16 = (c16_t *)&srs_estimated_channel_freq[gI][uI][subcarrier];
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
        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;
}

748 749 750 751 752 753 754 755 756 757 758 759 760 761
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;
}

762 763
int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
{
Cedric Roux's avatar
Cedric Roux committed
764 765 766
  /* 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;
767
  int pusch_DTX = 0;
768

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

772
  fill_ul_rb_mask(gNB, frame_rx, slot_rx);
cig's avatar
cig committed
773

774 775 776 777
  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) {
778 779
	      if (num_symb==0) first_symb=symbol_count;
	      num_symb++;
780 781
      }
    }
782
  else
francescomani's avatar
francescomani committed
783
    num_symb = NR_NUMBER_OF_SYMBOLS_PER_SLOT;
Eurecom's avatar
Eurecom committed
784
  gNB_I0_measurements(gNB,slot_rx,first_symb,num_symb);
785

786 787 788
  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);
789 790
  LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);

791 792
  start_meas(&gNB->phy_proc_rx);

793
  for (int i = 0; i < gNB->max_nb_pucch; i++) {
francescomani's avatar
francescomani committed
794
    NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
Francesco Mani's avatar
Francesco Mani committed
795
    if (pucch) {
David Kim's avatar
David Kim committed
796 797
      if (NFAPI_MODE == NFAPI_MODE_PNF)
        pucch->frame = frame_rx;
798
      if ((pucch->active == 1) &&
799 800
          (pucch->frame == frame_rx) &&
          (pucch->slot == slot_rx) ) {
801

Cedric Roux's avatar
Cedric Roux committed
802 803
        pucch_decode_done = 1;

Sakthivel Velumani's avatar
Sakthivel Velumani committed
804
        nfapi_nr_pucch_pdu_t  *pucch_pdu = &pucch->pucch_pdu;
805 806 807 808 809 810 811 812 813 814 815
        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;

816
          offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12);
817 818
          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);
819

820
          nr_decode_pucch0(gNB,
821
                           frame_rx,
822
                           slot_rx,
823 824 825 826 827
                           uci_pdu_format0,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
828
          break;
829 830 831 832 833 834 835 836 837
        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
838
          LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx);
839
          nr_decode_pucch2(gNB,
840
                           frame_rx,
841 842 843 844 845 846
                           slot_rx,
                           uci_pdu_format2,
                           pucch_pdu);

          gNB->UL_INFO.uci_ind.num_ucis += 1;
          pucch->active = 0;
847
          break;
848
        default:
francescomani's avatar
francescomani committed
849
          AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n");
850
        }
Francesco Mani's avatar
Francesco Mani committed
851 852 853 854
      }
    }
  }

855
  int totalDecode = 0;
856
  for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
francescomani's avatar
francescomani committed
857
    NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id];
858 859 860
    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
861 862
    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);
863 864 865
      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;
866

867
#ifdef DEBUG_RXDATA
868 869
      NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
      RU_t *ru = gNB->RU_list[0];
francescomani's avatar
francescomani committed
870
      int slot_offset = frame_parms->get_samples_slot_timestamp(slot_rx, frame_parms, 0);
871
      slot_offset -= ru->N_TA_offset;
Robert Schmidt's avatar
Robert Schmidt committed
872 873
      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
874 875 876 877 878 879 880 881 882 883 884 885 886 887
      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)) {
888
        FILE *f;
francescomani's avatar
francescomani committed
889 890 891 892 893 894 895
        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);
896 897 898
        fclose(f);
        exit(-1);
      }
899 900
#endif

901 902
      pusch_decode_done = 1;

francescomani's avatar
francescomani committed
903
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH, 1);
904
      start_meas(&gNB->rx_pusch_stats);
905 906
      if (gNB->use_pusch_tp) nr_rx_pusch_tp(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
      else nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, ulsch->harq_pid);
francescomani's avatar
francescomani committed
907
      NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
Robert Schmidt's avatar
Robert Schmidt committed
908 909
      pusch_vars->ulsch_power_tot = 0;
      pusch_vars->ulsch_noise_power_tot = 0;
francescomani's avatar
francescomani committed
910 911 912 913 914
      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];
915
      }
francescomani's avatar
francescomani committed
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
      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;
        }
937
      } else {
francescomani's avatar
francescomani committed
938 939 940 941
        LOG_D(PHY,
              "PUSCH detected in %d.%d (%d,%d,%d)\n",
              frame_rx,
              slot_rx,
Robert Schmidt's avatar
Robert Schmidt committed
942
              dB_fixed_x10(pusch_vars->ulsch_power_tot),
francescomani's avatar
francescomani committed
943 944
              dB_fixed_x10(pusch_vars->ulsch_noise_power_tot),
              gNB->pusch_thres);
945

francescomani's avatar
francescomani committed
946
        pusch_vars->DTX = 0;
Francesco Mani's avatar
Francesco Mani committed
947
      }
948
      stop_meas(&gNB->rx_pusch_stats);
francescomani's avatar
francescomani committed
949 950 951 952
      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
953
      int const tasks_added = nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid);
Robert Schmidt's avatar
Robert Schmidt committed
954
      if (tasks_added > 0)
mir's avatar
mir committed
955 956
        totalDecode += tasks_added; 

francescomani's avatar
francescomani committed
957
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
958 959
    }
  }
960 961 962 963 964 965 966 967 968
  if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) {
    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--;
    }
969
    stop_meas(&gNB->ulsch_decoding_stats);
970
  }
971
  for (int i = 0; i < gNB->max_nb_srs; i++) {
francescomani's avatar
francescomani committed
972
    NR_gNB_SRS_t *srs = &gNB->srs[i];
973 974 975
    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
976

977 978
        start_meas(&gNB->rx_srs_stats);

979
        NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
980
        nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu;
981 982 983 984 985
        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];
986
        int8_t snr_per_rb[srs_pdu->bwp_size];
987
        int8_t snr = 0;
rmagueta's avatar
rmagueta committed
988

989
        start_meas(&gNB->generate_srs_stats);
990 991 992
        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);
        }
993 994 995
        stop_meas(&gNB->generate_srs_stats);

        start_meas(&gNB->get_srs_signal_stats);
luis_pereira87's avatar
luis_pereira87 committed
996
        int srs_est = nr_get_srs_signal(gNB, frame_rx, slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal);
997
        stop_meas(&gNB->get_srs_signal_stats);
998 999

        if (srs_est >= 0) {
1000
          start_meas(&gNB->srs_channel_estimation_stats);
1001 1002 1003 1004
          nr_srs_channel_estimation(gNB,
                                    frame_rx,
                                    slot_rx,
                                    srs_pdu,
1005
                                    gNB->nr_srs_info[i],
1006
                                    (const int32_t **)gNB->nr_srs_info[i]->srs_generated_signal,
1007 1008 1009 1010
                                    srs_received_signal,
                                    srs_estimated_channel_freq,
                                    srs_estimated_channel_time,
                                    srs_estimated_channel_time_shifted,
1011 1012
                                    snr_per_rb,
                                    &snr);
1013
          stop_meas(&gNB->srs_channel_estimation_stats);
1014
        }
1015

luis_pereira87's avatar
luis_pereira87 committed
1016 1017 1018
        if ((snr * 10) < gNB->srs_thres) {
          srs_est = -1;
        }
1019

luis_pereira87's avatar
luis_pereira87 committed
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
        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)));
1035

1036 1037 1038
        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
1039 1040 1041 1042

        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;
1043
        start_meas(&gNB->srs_timing_advance_stats);
1044
        srs_indication->timing_advance_offset = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, srs_estimated_channel_time[0]) : 0xFFFF;
1045
        stop_meas(&gNB->srs_timing_advance_stats);
1046
        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;
1047 1048 1049 1050
        switch (srs_pdu->srs_parameters_v4.usage) {
          case 0:
            LOG_W(NR_PHY, "SRS report was not requested by MAC\n");
            return 0;
1051 1052
          case 1 << NR_SRS_ResourceSet__usage_beamManagement:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_beamManagement;
1053
            break;
1054 1055
          case 1 << NR_SRS_ResourceSet__usage_codebook:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_codebook;
1056
            break;
1057 1058
          case 1 << NR_SRS_ResourceSet__usage_nonCodebook:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_nonCodebook;
1059
            break;
1060 1061
          case 1 << NR_SRS_ResourceSet__usage_antennaSwitching:
            srs_indication->srs_usage = NR_SRS_ResourceSet__usage_antennaSwitching;
1062 1063 1064 1065
            break;
          default:
            LOG_E(NR_PHY, "Invalid srs_pdu->srs_parameters_v4.usage %i\n", srs_pdu->srs_parameters_v4.usage);
        }
1066
        srs_indication->report_type = srs_pdu->srs_parameters_v4.report_type[0];
1067 1068 1069 1070

#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);
1071 1072 1073 1074 1075
        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);
1076 1077
#endif

1078 1079 1080
        nfapi_srs_report_tlv_t *report_tlv = &srs_indication->report_tlv;
        report_tlv->tag = 0;
        report_tlv->length = 0;
1081

1082
        start_meas(&gNB->srs_report_tlv_stats);
1083
        switch (srs_indication->srs_usage) {
1084
          case NR_SRS_ResourceSet__usage_beamManagement: {
1085
            start_meas(&gNB->srs_beam_report_stats);
1086 1087 1088 1089 1090
            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;
1091
            fill_srs_reported_symbol_list(&nr_srs_bf_report.prgs, srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
1092

1093
#ifdef SRS_IND_DEBUG
1094 1095 1096 1097 1098 1099
            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++) {
1100 1101
              LOG_I(NR_PHY,
                    "nr_srs_beamforming_report.prgs[0].prg_list[%3i].rb_snr = %i (%i dB)\n",
1102
                    prg_idx,
1103 1104
                     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);
1105
            }
1106 1107
#endif

1108
            report_tlv->length = pack_nr_srs_beamforming_report(&nr_srs_bf_report, report_tlv->value, sizeof(report_tlv->value));
1109
            stop_meas(&gNB->srs_beam_report_stats);
1110 1111 1112 1113
            break;
          }

          case NR_SRS_ResourceSet__usage_codebook: {
1114
            start_meas(&gNB->srs_iq_matrix_stats);
1115 1116 1117 1118 1119 1120 1121
            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,
1122 1123
                                    srs_pdu,
                                    gNB->nr_srs_info[i],
1124 1125 1126 1127 1128
                                    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,
1129 1130
                                    &gNB->frame_parms,
                                    srs_estimated_channel_freq);
1131 1132

#ifdef SRS_IND_DEBUG
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
            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++) {
1143
                  uint16_t index =
1144
                      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;
1145 1146 1147 1148 1149
                  LOG_I(NR_PHY,
                        "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
                        uI,
                        gI,
                        pI,
1150 1151
                        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);
1152 1153 1154
                }
              }
            }
1155 1156
#endif

1157
            report_tlv->length = pack_nr_srs_normalized_channel_iq_matrix(&nr_srs_channel_iq_matrix, report_tlv->value, sizeof(report_tlv->value));
1158
            stop_meas(&gNB->srs_iq_matrix_stats);
1159 1160 1161 1162 1163 1164 1165 1166 1167
            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:
1168
            AssertFatal(1 == 0, "Invalid SRS usage\n");
1169
        }
1170
        stop_meas(&gNB->srs_report_tlv_stats);
1171

1172
#ifdef SRS_IND_DEBUG
1173 1174 1175 1176
        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++) {
1177
          LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b] & 0xFF);
1178 1179 1180
        }
#endif

1181
        gNB->UL_INFO.srs_ind.number_of_pdus += 1;
1182
        srs->active = 0;
1183 1184

        stop_meas(&gNB->rx_srs_stats);
1185 1186 1187 1188
      }
    }
  }

1189
  stop_meas(&gNB->phy_proc_rx);
rmagueta's avatar
rmagueta committed
1190

Cedric Roux's avatar
Cedric Roux committed
1191 1192 1193 1194
  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
1195
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
1196
  return pusch_DTX;
1197
}