nr_ulsch_ue.c 19.8 KB
Newer Older
Khalid Ahmed's avatar
Khalid Ahmed committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 * 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
 */

/*! \file PHY/NR_UE_TRANSPORT/nr_ulsch.c
* \brief Top-level routines for transmission of the PUSCH TS 38.211 v 15.4.0
* \author Khalid Ahmed
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: khalid.ahmed@iis.fraunhofer.de
* \note
* \warning
*/
#include <stdint.h>
33
#include "PHY/NR_REFSIG/dmrs_nr.h"
adk's avatar
adk committed
34
#include "PHY/NR_REFSIG/ptrs_nr.h"
35
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
36 37
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/MODULATION/nr_modulation.h"
38
#include "PHY/MODULATION/modulation_common.h"
Khalid Ahmed's avatar
Khalid Ahmed committed
39
#include "common/utils/assertions.h"
40
#include "common/utils/LOG/vcd_signal_dumper.h"
Khalid Ahmed's avatar
Khalid Ahmed committed
41
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
42
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
Khalid Ahmed's avatar
Khalid Ahmed committed
43
#include "PHY/defs_nr_common.h"
44
#include "PHY/TOOLS/tools_defs.h"
45
#include "executables/nr-softmodem.h"
46
#include "executables/softmodem-common.h"
dir's avatar
dir committed
47
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
Laurent THOMAS's avatar
Laurent THOMAS committed
48
#include <openair2/UTIL/OPT/opt.h>
dir's avatar
dir committed
49

50
//#define DEBUG_PUSCH_MAPPING
51
//#define DEBUG_MAC_PDU
dir's avatar
dir committed
52
//#define DEBUG_DFT_IDFT
53

54
//extern int32_t uplink_counter;
55

56 57 58 59 60 61
void nr_pusch_codeword_scrambling_uci(uint8_t *in,
                                      uint32_t size,
                                      uint32_t Nid,
                                      uint32_t n_RNTI,
                                      uint32_t* out)
{
Khalid Ahmed's avatar
Khalid Ahmed committed
62
  uint8_t reset, b_idx;
Khalid Ahmed's avatar
Khalid Ahmed committed
63
  uint32_t x1, x2, s=0, temp_out;
Khalid Ahmed's avatar
Khalid Ahmed committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77

  reset = 1;
  x2 = (n_RNTI<<15) + Nid;

  for (int i=0; i<size; i++) {
    b_idx = i&0x1f;
    if (b_idx==0) {
      s = lte_gold_generic(&x1, &x2, reset);
      reset = 0;
      if (i)
        out++;
    }
    if (in[i]==NR_PUSCH_x)
      *out ^= 1<<b_idx;
Khalid Ahmed's avatar
Khalid Ahmed committed
78 79 80 81 82 83 84 85 86 87
    else if (in[i]==NR_PUSCH_y){
      if (b_idx!=0)
        *out ^= (*out & (1<<(b_idx-1)))<<1;
      else{

        temp_out = *(out-1);
        *out ^= temp_out>>31;

      }
    }
Khalid Ahmed's avatar
Khalid Ahmed committed
88 89 90 91
    else
      *out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
    //printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
  }
92
}
Khalid Ahmed's avatar
Khalid Ahmed committed
93

94 95 96 97 98 99 100 101 102 103 104
void nr_pusch_codeword_scrambling(uint8_t *in,
                                  uint32_t size,
                                  uint32_t Nid,
                                  uint32_t n_RNTI,
                                  bool uci_on_pusch,
                                  uint32_t* out)
{
  if (uci_on_pusch)
    nr_pusch_codeword_scrambling_uci(in, size, Nid, n_RNTI, out);
  else
    nr_codeword_scrambling(in, size, 0, Nid, n_RNTI, out);
105
}
106

107
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
108
                               unsigned char harq_pid,
109
                               uint32_t frame,
110 111
                               uint8_t slot,
                               uint8_t thread_id,
112
                               int gNB_id) {
113

114 115
  LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);

cig's avatar
cig committed
116
  uint32_t available_bits;
cig's avatar
cig committed
117
  uint8_t cwd_index, l;
118 119 120
  uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
  int16_t **tx_layers;
  int32_t **txdataF;
Raymond Knopp's avatar
Raymond Knopp committed
121 122
  int8_t Wf[2], Wt[2];
  int l_prime[2], delta;
cig's avatar
cig committed
123
  uint8_t nb_dmrs_re_per_rb;
124 125 126
  int ap, i;
  int sample_offsetF, N_RE_prime;

127
  NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
128
  NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id];
129

130 131 132
  uint8_t  num_of_codewords = 1; // tmp assumption
  int      N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
  uint16_t number_dmrs_symbols = 0;
133

134 135
  for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) {

136 137
    NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index];
    NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
cig's avatar
cig committed
138 139 140 141 142 143 144 145 146 147 148 149
    nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu;

    int start_symbol          = pusch_pdu->start_symbol_index;
    uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
    uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
    uint8_t dmrs_type         = pusch_pdu->dmrs_config_type;
    uint16_t start_rb         = pusch_pdu->rb_start;
    uint16_t nb_rb            = pusch_pdu->rb_size;
    uint8_t Nl                = pusch_pdu->nrOfLayers;
    uint8_t mod_order         = pusch_pdu->qam_mod_order;
    uint16_t rnti             = pusch_pdu->rnti;
    uint8_t cdm_grps_no_data  = pusch_pdu->num_dmrs_cdm_grps_no_data;
150
    uint16_t start_sc         = frame_parms->first_carrier_offset + (start_rb+pusch_pdu->bwp_start)*NR_NB_SC_PER_RB;
151

152 153
    if (start_sc >= frame_parms->ofdm_symbol_size)
      start_sc -= frame_parms->ofdm_symbol_size;
154

155
    ulsch_ue->Nid_cell    = frame_parms->Nid_cell;
156

francescomani's avatar
francescomani committed
157 158 159 160 161 162
    for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
      if((ul_dmrs_symb_pos >> i) & 0x01)
        number_dmrs_symbols += 1;
    }

    nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data;
163

164
    LOG_D(PHY,"ulsch %x : start_rb %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n",
rmagueta's avatar
rmagueta committed
165
          rnti,start_rb,pusch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb);
166

cig's avatar
cig committed
167
    // TbD num_of_mod_symbols is set but never used
168 169
    N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
    harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*num_of_codewords;
170

171 172 173
    /////////////////////////ULSCH coding/////////////////////////
    ///////////

174 175
    unsigned int G = nr_get_G(nb_rb, number_of_symbols,
                              nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
dir's avatar
dir committed
176 177
    

Laurent THOMAS's avatar
Laurent THOMAS committed
178 179 180 181
    trace_NRpdu(DIRECTION_UPLINK,
		ulsch_ue->harq_processes[harq_pid]->a,
		ulsch_ue->harq_processes[harq_pid]->pusch_pdu.pusch_data.tb_size,
		0, WS_C_RNTI, rnti, frame, slot, 0, 0);
182

183 184
    if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1)
      return;
185 186 187 188


    ///////////
    ////////////////////////////////////////////////////////////////////
189

190 191 192
    /////////////////////////ULSCH scrambling/////////////////////////
    ///////////

193
    available_bits = G;
194 195 196 197 198 199

    memset(scrambled_output[cwd_index], 0, ((available_bits>>5)+1)*sizeof(uint32_t));

    nr_pusch_codeword_scrambling(ulsch_ue->g,
                                 available_bits,
                                 ulsch_ue->Nid_cell,
200
                                 rnti,
201
                                 false,
202 203 204 205 206 207 208 209 210 211 212 213 214 215
                                 scrambled_output[cwd_index]); // assume one codeword for the moment


    /////////////
    //////////////////////////////////////////////////////////////////////////

    /////////////////////////ULSCH modulation/////////////////////////
    ///////////

    nr_modulation(scrambled_output[cwd_index], // assume one codeword for the moment
                  available_bits,
                  mod_order,
                  (int16_t *)ulsch_ue->d_mod);

216

dir's avatar
dir committed
217
    
218 219 220 221 222
    ///////////
    ////////////////////////////////////////////////////////////////////////

  /////////////////////////DMRS Modulation/////////////////////////
  ///////////
223
  uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
224
  uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
225
  int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
226 227 228
  ///////////
  ////////////////////////////////////////////////////////////////////////

adk's avatar
adk committed
229 230 231 232

  /////////////////////////PTRS parameters' initialization/////////////////////////
  ///////////

233
  int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
234 235
  uint8_t L_ptrs, K_ptrs = 0;
  uint16_t beta_ptrs = 1; // temp value until power control is implemented
adk's avatar
adk committed
236

cig's avatar
cig committed
237
  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
adk's avatar
adk committed
238

239
    K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density;
240
    L_ptrs = 1<<harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_time_density;
adk's avatar
adk committed
241 242 243 244 245 246

    beta_ptrs = 1; // temp value until power control is implemented

    ulsch_ue->ptrs_symbols = 0;

    set_ptrs_symb_idx(&ulsch_ue->ptrs_symbols,
247
                      number_of_symbols,
adk's avatar
adk committed
248 249
                      start_symbol,
                      L_ptrs,
250
                      ul_dmrs_symb_pos);
adk's avatar
adk committed
251 252 253 254 255
  }

  ///////////
  ////////////////////////////////////////////////////////////////////////////////

256 257 258 259 260
  /////////////////////////ULSCH layer mapping/////////////////////////
  ///////////

  tx_layers = (int16_t **)pusch_ue->txdataF_layers;

261
  nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id],
262
                      Nl,
263 264
                      available_bits/mod_order,
                      tx_layers);
265

266 267 268 269 270 271 272 273 274
  ///////////
  ////////////////////////////////////////////////////////////////////////


  //////////////////////// ULSCH transform precoding ////////////////////////
  ///////////

  l_prime[0] = 0; // single symbol ap 0

dir's avatar
dir committed
275 276 277
  uint16_t index;
  uint8_t u = 0, v = 0;
  int16_t *dmrs_seq = NULL;
278

279
  // if  transform precoding is enbaled (value 0)
280
  if (pusch_pdu->transform_precoding == 0) {
281

dir's avatar
dir committed
282 283 284 285 286
    uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB;
    uint32_t y_offset = 0;
    uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2);
    
    // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol
287
    index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);
dir's avatar
dir committed
288 289 290 291 292 293
    u = pusch_pdu->dfts_ofdm.low_papr_group_number;
    v = pusch_pdu->dfts_ofdm.low_papr_sequence_number;
    dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index];

    AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
    AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
294
    
dir's avatar
dir committed
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);

    for (l = start_symbol; l < start_symbol + number_of_symbols; l++) {

      if((ul_dmrs_symb_pos >> l) & 0x01)
        /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
        continue;

      nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);

      y_offset = y_offset + nb_re_pusch;

      LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset);

      #ifdef DEBUG_PUSCH_MAPPING
        printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n", 
            y_offset, nb_re_pusch, l, nb_rb);
      #endif
    }
314

dir's avatar
dir committed
315
    #ifdef DEBUG_DFT_IDFT
316
      int32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
dir's avatar
dir committed
317 318 319 320 321 322 323 324
      int offset = 0;
      printf("NR_ULSCH_UE: available_bits: %d, mod_order: %d", available_bits,mod_order);

      for (int ll = 0; ll < (available_bits/mod_order); ll++) {
          debug_symbols[ll] = ulsch_ue->y[ll];     
      }
      
      printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols);
325
      for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) {
dir's avatar
dir committed
326 327 328 329 330 331 332

        nr_idft(&debug_symbols[offset], nb_re_pusch);

        offset = offset + nb_re_pusch;

      }
      LOG_M("preDFT_all_symbols.m","UE_preDFT", tx_layers[0],number_of_symbols*nb_re_pusch,1,1);
333
      LOG_M("postDFT_all_symbols.m","UE_postDFT", ulsch_ue->y,number_of_symbols*nb_re_pusch,1,1);
dir's avatar
dir committed
334 335 336
      LOG_M("DEBUG_IDFT_SYMBOLS.m","UE_Debug_IDFT", debug_symbols,number_of_symbols*nb_re_pusch,1,1);
      LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1);
    #endif
337 338

  }
dir's avatar
dir committed
339 340 341
  else
    memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
  
342 343 344 345

  ///////////
  ////////////////////////////////////////////////////////////////////////

346 347


348 349 350 351 352
  /////////////////////////ULSCH RE mapping/////////////////////////
  ///////////

  txdataF = UE->common_vars.txdataF;

353
  for (ap=0; ap< Nl; ap++) {
354

355 356 357
    uint8_t k_prime = 0;
    uint16_t m = 0;

dir's avatar
dir committed
358 359 360 361 362 363 364
    
    #ifdef DEBUG_PUSCH_MAPPING
      printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u);
    #endif

  

365 366 367 368 369
    // DMRS params for this ap
    get_Wt(Wt, ap, dmrs_type);
    get_Wf(Wf, ap, dmrs_type);
    delta = get_delta(ap, dmrs_type);

370
    for (l=start_symbol; l<start_symbol+number_of_symbols; l++) {
371

372 373 374 375 376
      uint16_t k = start_sc;
      uint16_t n = 0;
      uint8_t is_dmrs_sym = 0;
      uint8_t is_ptrs_sym = 0;
      uint16_t dmrs_idx = 0, ptrs_idx = 0;
377

378 379
      if ((ul_dmrs_symb_pos >> l) & 0x01) {
        is_dmrs_sym = 1;
380

381
        // transform precoding disabled (value 1)
382
        if (pusch_pdu->transform_precoding == 1){
dir's avatar
dir committed
383
        
384
          if (dmrs_type == pusch_dmrs_type1)
385
            dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6;
386
          else
387 388 389 390
            dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4;

          // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
          // Perform this on gold sequence, not required when SC FDMA operation is done,
391
	        LOG_D(PHY,"DMRS in symbol %d\n",l);
dir's avatar
dir committed
392
          nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
393

394
        } else {
395 396
          dmrs_idx = 0;
        }
dir's avatar
dir committed
397 398
       
       
399
      } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
400

401
        AssertFatal(pusch_pdu->transform_precoding == 1, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
402 403 404 405

        if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) {
          is_ptrs_sym = 1;
          nr_modulation(pusch_dmrs[l][0], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
406
        }
407 408 409
      }

      for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
Khalid Ahmed's avatar
Khalid Ahmed committed
410

411 412
        uint8_t is_dmrs = 0;
        uint8_t is_ptrs = 0;
413

414 415 416 417 418 419
        sample_offsetF = l*frame_parms->ofdm_symbol_size + k;

        if (is_dmrs_sym) {
          if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
            is_dmrs = 1;
        } else if (is_ptrs_sym) {
420 421 422 423 424 425
            is_ptrs = is_ptrs_subcarrier(k,
                                         rnti,
                                         ap,
                                         dmrs_type,
                                         K_ptrs,
                                         nb_rb,
cig's avatar
cig committed
426
                                         pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
427 428
                                         start_sc,
                                         frame_parms->ofdm_symbol_size);
adk's avatar
adk committed
429 430
        }

Khalid Ahmed's avatar
Khalid Ahmed committed
431
        if (is_dmrs == 1) {
432
          // if transform precoding is enabled
433
          if (pusch_pdu->transform_precoding == 0) {
Raymond Knopp's avatar
Raymond Knopp committed
434

dir's avatar
dir committed
435 436 437 438 439 440 441 442 443
            ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
            ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
          
          } else {

              ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
              ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;

            }
444 445

          #ifdef DEBUG_PUSCH_MAPPING
446
            printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
447 448 449 450
            dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
            ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
          #endif

451

452 453 454 455 456
          dmrs_idx++;
          k_prime++;
          k_prime&=1;
          n+=(k_prime)?0:1;

adk's avatar
adk committed
457 458 459 460 461 462 463
        }  else if (is_ptrs == 1) {

          ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
          ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;

          ptrs_idx++;

464
        } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) {
465

466 467
          ((int16_t*)txdataF[ap])[(sample_offsetF)<<1]       = ((int16_t *) ulsch_ue->y)[m<<1];
          ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
468

469
        #ifdef DEBUG_PUSCH_MAPPING
470 471 472
          printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
          m, l, k, ((int16_t*)txdataF[ap])[(sample_offsetF)<<1],
          ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]);
473
        #endif
474

475
          m++;
476 477 478 479 480

        } else {

          ((int16_t*)txdataF[ap])[(sample_offsetF)<<1]       = 0;
          ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = 0;
481 482 483 484 485

        }

        if (++k >= frame_parms->ofdm_symbol_size)
          k -= frame_parms->ofdm_symbol_size;
486 487 488
      }
    }
  }
489
  }
490

491 492 493
  NR_UL_UE_HARQ_t *harq_process_ulsch=NULL;
  harq_process_ulsch = UE->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid];
  harq_process_ulsch->status = SCH_IDLE;
494

495 496 497 498 499 500 501 502
  ///////////
  ////////////////////////////////////////////////////////////////////////

}


uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
                                      uint8_t slot,
503 504
                                      NR_DL_FRAME_PARMS *frame_parms,
                                      uint8_t Nl) {
505 506 507 508 509 510 511 512

  int tx_offset, ap;
  int32_t **txdata;
  int32_t **txdataF;

  /////////////////////////IFFT///////////////////////
  ///////////

513
  tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
514

515 516 517 518 519 520 521
  // clear the transmit data array for the current subframe
  /*for (int aa=0; aa<UE->frame_parms.nb_antennas_tx; aa++) {
	  memset(&UE->common_vars.txdata[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t));
	  //memset(&UE->common_vars.txdataF[aa][tx_offset],0,UE->frame_parms.samples_per_slot*sizeof(int32_t));
  }*/


522 523 524
  txdata = UE->common_vars.txdata;
  txdataF = UE->common_vars.txdataF;

525 526 527
  int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
  for(ap = 0; ap < Nl; ap++) {
    for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT;s++){
528 529 530 531 532 533 534 535 536 537 538 539 540

      LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n",
        __FUNCTION__,
        s,
        s + symb_offset,
        frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
        frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]);

      rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
                        &frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
                        (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
                        frame_parms->ofdm_symbol_size,
                        15);
541 542 543
    }
  }

544 545 546 547 548 549 550 551 552 553 554 555
  for (ap = 0; ap < Nl; ap++) {
    if (frame_parms->Ncp == 1) { // extended cyclic prefix
      PHY_ofdm_mod(txdataF[ap],
                   &txdata[ap][tx_offset],
                   frame_parms->ofdm_symbol_size,
                   12,
                   frame_parms->nb_prefix_samples,
                   CYCLIC_PREFIX);
    } else { // normal cyclic prefix
      nr_normal_prefix_mod(txdataF[ap],
                           &txdata[ap][tx_offset],
                           14,
556 557
                           frame_parms,
                           slot);
558 559 560
    }
  }

561 562 563 564
  ///////////
  ////////////////////////////////////////////////////
  return 0;
}