ul_ref_seq_nr.c 10.4 KB
Newer Older
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/*
 * 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
 */

/***********************************************************************
*
* FILENAME    :  ul_ref_seq_nr.c
*
* MODULE      :  generation of uplink reference sequence for nr
*
* DESCRIPTION :  function to generate uplink reference sequences
*                see 3GPP TS 38.211 5.2.2 Low-PAPR sequence generation
*
************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "defs.h"

#define DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#undef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H

/*******************************************************************
*
* NAME :         base_sequence_less_3_RB
*
* PARAMETERS :   M_ZC length of Zadoff Chu sequence
*                u sequence group number
*                scaling to apply
*
* RETURN :       pointer to generated sequence
*
* DESCRIPTION :  base sequence generation of less than 36 elements
*                see TS 38.211 5.2.2.2 Base sequences of length less than 36
*
*********************************************************************/

yilmazt's avatar
yilmazt committed
57 58 59
int16_t *base_sequence_less_than_36(unsigned int M_ZC,
                                    unsigned int u,
                                    unsigned int scaling)
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
{
  char *phi_table;
  int16_t *rv_overbar;
  double x;
  unsigned int n;

  switch(M_ZC) {
    case 6:
      phi_table = (char *)phi_M_ZC_6;
      break;
    case 12:
      phi_table = (char *)phi_M_ZC_12;
      break;
    case 18:
      phi_table = (char *)phi_M_ZC_18;
      break;
    case 24:
      phi_table = (char *)phi_M_ZC_24;
      break;
    case 30:
      break;
    default:
yilmazt's avatar
yilmazt committed
82
      printf("function base_sequence_less_than 36_: unsupported base sequence size : %u \n", M_ZC);
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
      assert(0);
      break;
  }

  rv_overbar = malloc16(IQ_SIZE*M_ZC);

  if (rv_overbar == NULL) {
    msg("Fatal memory allocation problem \n");
    assert(0);
  }

  if (M_ZC == 30) {
    for (n=0; n<M_ZC; n++) {
      x = -(M_PI * (u + 1) * (n + 1) * (n + 2))/(double)31;
      rv_overbar[2*n]   =(int16_t)(floor(scaling*cos(x)));
      rv_overbar[2*n+1] =(int16_t)(floor(scaling*sin(x)));
    }
  }
  else {
    for (n=0; n<M_ZC; n++) {
      x = (double)phi_table[n + u*M_ZC] * (M_PI/4);
      rv_overbar[2*n]   = (int16_t)(floor(scaling*cos(x)));
      rv_overbar[2*n+1] = (int16_t)(floor(scaling*sin(x)));
    }
  }
  return rv_overbar;
}

dir's avatar
dir committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124
/*******************************************************************
*
* NAME :         get_index_for_dmrs_lowpapr_seq
*
* PARAMETERS :   num_dmrs_res - Total number of DMRS RES possible in allocated RBs                
*                
*
* RETURN :       returns index of array dmrs_ul_allocated_res 
*
* DESCRIPTION :  finds the index which in turn is used to index into dmrs low papr sequences 
*
*********************************************************************/

int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) {
125 126 127 128

  int16_t index = num_dmrs_res/6 - 1;

  if (index >= MAX_INDEX_DMRS_UL_ALLOCATED_REs)
dir's avatar
dir committed
129 130 131 132 133 134 135
    index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1;

  for (;index >= 0; index--) {
    if (dmrs_ul_allocated_res[index] == num_dmrs_res)
      break;
  }

136
  LOG_D(PHY, "num_dmrs_res: %d    INDEX RETURNED:  %d", num_dmrs_res, index);
dir's avatar
dir committed
137

138
  return index;
dir's avatar
dir committed
139 140
}

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/*******************************************************************
*
* NAME :         base_sequence_36_or_larger
*
* PARAMETERS :   M_ZC length of Zadoff chu sequence
*                u sequence group number
*                scaling to apply
*
* RETURN :       pointer to generated sequence
*
* DESCRIPTION :  base sequence generation of less than 36 elements
*                5.2.2.1 Base sequences of length 36 or larger
*
*********************************************************************/

yilmazt's avatar
yilmazt committed
156 157 158
int16_t *base_sequence_36_or_larger(unsigned int Msc_RS,
                                    unsigned int u,
                                    unsigned int v,
dir's avatar
dir committed
159
                                    unsigned int scaling, unsigned int if_dmrs_seq)
160 161
{
  int16_t *rv_overbar;
dir's avatar
dir committed
162
  unsigned int N_ZC, M_ZC;
163 164
  double q_overbar, x;
  unsigned int q,m,n;
dir's avatar
dir committed
165 166 167 168 169 170 171
  

  if (if_dmrs_seq)
    M_ZC = dmrs_ul_allocated_res[Msc_RS];
  else
    M_ZC = ul_allocated_re[Msc_RS];
  
172 173 174 175 176 177 178

  rv_overbar = malloc16(IQ_SIZE*M_ZC);
  if (rv_overbar == NULL) {
    msg("Fatal memory allocation problem \n");
    assert(0);
  }

dir's avatar
dir committed
179 180 181 182 183
  if (if_dmrs_seq)
    N_ZC = dmrs_ref_ul_primes[Msc_RS];
  else 
    N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
  
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201

  q_overbar = N_ZC * (u+1)/(double)31;

  /*  q = (q_overbar + 1/2) + v.(-1)^(2q_overbar) */
  if ((((int)floor(2*q_overbar))&1) == 0)
    q = (int)(floor(q_overbar+.5)) - v;
  else
    q = (int)(floor(q_overbar+.5)) + v;

  for (n = 0; n < M_ZC; n++) {
    m=n%N_ZC;
    x = (double)q * m * (m+1)/N_ZC;
    rv_overbar[2*n]   =  (int16_t)(floor(scaling*cos(M_PI*x)));   /* cos(-x) = cos(x) */
    rv_overbar[2*n+1] = -(int16_t)(floor(scaling*sin(M_PI*x)));   /* sin(-x) = -sin(x) */
  }
  return rv_overbar;
}

dir's avatar
dir committed
202 203
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling)
{
204 205 206 207 208
  /* prevent multiple calls, relevant when both UE & gNB initialize this */
  static bool already_called = false;
  if (already_called) return;
  already_called = true;

dir's avatar
dir committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
	unsigned int u,Msc_RS;
  unsigned int v = 0; // sequence hopping and group hopping are not supported yet

  for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {  	
    for (u=0; u < U_GROUP_NUMBER; u++) {
      gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
    }
  }

  for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {    
    for (u=0; u < U_GROUP_NUMBER; u++) {        
      gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);           
    }    
  } 
}

225 226 227

void generate_ul_reference_signal_sequences(unsigned int scaling)
{
228 229 230 231 232
  /* prevent multiple calls, relevant when both UE & gNB initialize this */
  static bool already_called = false;
  if (already_called) return;
  already_called = true;

233 234 235 236 237 238 239 240 241
	unsigned int u,v,Msc_RS;

#if 0

    char output_file[255];
    char sequence_name[255];

#endif

dir's avatar
dir committed
242
  
243
  for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
dir's avatar
dir committed
244
  	v = 0;
245 246
    for (u=0; u < U_GROUP_NUMBER; u++) {
      rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
dir's avatar
dir committed
247 248
      dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
    
249 250 251 252 253 254 255 256 257 258
#if 0
      sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
      sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
      printf("u %d Msc_RS %d allocate memory %x of size %d \n", u, Msc_RS, rv_ul_ref_sig[u][v][Msc_RS], (IQ_SIZE* ul_allocated_re[Msc_RS]));
      write_output(output_file, sequence_name,  rv_ul_ref_sig[u][v][Msc_RS], ul_allocated_re[Msc_RS], 1, 1);

#endif
    }
  }

dir's avatar
dir committed
259 260 261 262 263 264 265 266
 for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
    v = 0;  // neither group hopping or sequnce hopping is supported for PUSCH DMRS hence v = 0
    for (u=0; u < U_GROUP_NUMBER; u++) {        
      dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1);  
    }
    
  }
 
267 268
  for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < SRS_SB_CONF; Msc_RS++) {
    for (u=0; u < U_GROUP_NUMBER; u++) {
dir's avatar
dir committed
269 270 271
     for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
        rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 0);

272 273 274 275 276 277 278 279 280 281
#if 0
        sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
        sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
        printf("u %d Msc_RS %d allocate memory %x of size %d \n", u, Msc_RS, rv_ul_ref_sig[u][v][Msc_RS], (IQ_SIZE* ul_allocated_re[Msc_RS]));
        write_output(output_file, sequence_name,  rv_ul_ref_sig[u][v][Msc_RS], ul_allocated_re[Msc_RS], 1, 1);

#endif
      }
    }
  }
dir's avatar
dir committed
282 283


284 285
}

dir's avatar
dir committed
286

287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
/*******************************************************************
*
* NAME :         free_ul_reference_signal_sequences
*
* PARAMETERS :   none
*
* RETURN :       none
*
* DESCRIPTION :  free of uplink reference signal sequences
*
*********************************************************************/
void free_ul_reference_signal_sequences(void)
{
  unsigned int u,v,Msc_RS;
  for (Msc_RS=0; Msc_RS < SRS_SB_CONF; Msc_RS++) {
    for (u=0; u < U_GROUP_NUMBER; u++) {
      for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
        if (rv_ul_ref_sig[u][v][Msc_RS])
305
          free_and_zero(rv_ul_ref_sig[u][v][Msc_RS]);
dir's avatar
dir committed
306 307
        if ((v==0) && (Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs))
          if (dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS])
308
            free_and_zero(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS]);
309 310 311 312
      }
    }
  }
}
dir's avatar
dir committed
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
/*******************************************************************
*
* NAME :         free_gnb_lowpapr_sequences
*
* PARAMETERS :   none
*
* RETURN :       none
*
* DESCRIPTION :  free of uplink reference signal sequences
*
*********************************************************************/
void free_gnb_lowpapr_sequences(void)
{
  unsigned int u,v,Msc_RS;
  for (Msc_RS=0; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) {
    v=0;
    for (u=0; u < U_GROUP_NUMBER; u++) {      
      if (gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS])
331
        free_and_zero(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS]);
dir's avatar
dir committed
332 333 334 335
    }
  }
}