ofdm_mod.c 11.4 KB
Newer Older
1
2
3
4
5
/*
 * 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
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 * 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
23
24
25
26
27
28
29
30
31
/*
* @defgroup _PHY_MODULATION_
* @ingroup _physical_layer_ref_implementation_
* @{
\section _phy_modulation_ OFDM Modulation Blocks
This section deals with basic functions for OFDM Modulation.


*/

32
#include "PHY/defs_eNB.h"
33
#include "PHY/defs_gNB.h"
34
#include "PHY/impl_defs_top.h"
35
36
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
37
#include "modulation_common.h"
knopp's avatar
knopp committed
38
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
knopp's avatar
knopp committed
39
//#define DEBUG_OFDM_MOD
40
41


42
43
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms)
{
44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  
  PHY_ofdm_mod(txdataF,        // input
	       txdata,         // output
	       frame_parms->ofdm_symbol_size,                
	       1,                 // number of symbols
	       frame_parms->nb_prefix_samples0,               // number of prefix samples
	       CYCLIC_PREFIX);
  PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,        // input
	       txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0,         // output
	       frame_parms->ofdm_symbol_size,                
	       nsymb-1,
	       frame_parms->nb_prefix_samples,               // number of prefix samples
	       CYCLIC_PREFIX);
  

  
62
63
}

Guy De Souza's avatar
Guy De Souza committed
64
65
66
67
68
69
70
71
72
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms)
{
  PHY_ofdm_mod(txdataF,        // input
	       txdata,         // output
	       frame_parms->ofdm_symbol_size,                
	       1,                 // number of symbols
	       frame_parms->nb_prefix_samples0,               // number of prefix samples
	       CYCLIC_PREFIX);
  PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,        // input
Guy De Souza's avatar
Guy De Souza committed
73
	       txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,         // output
Guy De Souza's avatar
Guy De Souza committed
74
75
76
77
78
79
	       frame_parms->ofdm_symbol_size,                
	       nsymb - 1,
	       frame_parms->nb_prefix_samples,               // number of prefix samples
	       CYCLIC_PREFIX);  
}

80
void PHY_ofdm_mod(int *input,                       /// pointer to complex input
81
                  int *output,                      /// pointer to complex output
82
                  int fftsize,            /// FFT_SIZE
83
84
85
86
87
                  unsigned char nb_symbols,         /// number of OFDM symbols
                  unsigned short nb_prefix_samples,  /// cyclic prefix length
                  Extension_t etype                /// type of extension
                 )
{
88

89
  short temp[4096*4] __attribute__((aligned(32)));
90
91
92
93
94
95
96
97
  unsigned short i,j;
  short k;

  volatile int *output_ptr=(int*)0;

  int *temp_ptr=(int*)0;
  void (*idft)(int16_t *,int16_t *, int);

98
99
  switch (fftsize) {
  case 128:
100
101
    idft = idft128;
    break;
102

103
  case 256:
104
105
    idft = idft256;
    break;
106

107
  case 512:
108
109
    idft = idft512;
    break;
110

111
  case 1024:
112
113
    idft = idft1024;
    break;
114

115
116
117
118
119
  case 1536:
    idft = idft1536;
    break;

  case 2048:
120
121
    idft = idft2048;
    break;
122

123
124
  case 3072:
    idft = idft3072;
knopp's avatar
knopp committed
125
    break;
126
127
  case 4096:
    idft = idft4096;
knopp's avatar
knopp committed
128
    break;
129
130
131
132
133
134
  default:
    idft = idft512;
    break;
  }

#ifdef DEBUG_OFDM_MOD
135
136
  printf("[PHY] OFDM mod (size %d,prefix %d) Symbols %d, input %p, output %p\n",
      fftsize,nb_prefix_samples,nb_symbols,input,output);
137
138
139
#endif


140
141

  for (i=0; i<nb_symbols; i++) {
142
143

#ifdef DEBUG_OFDM_MOD
144
    printf("[PHY] symbol %d/%d offset %d (%p,%p -> %p)\n",i,nb_symbols,i*fftsize+(i*nb_prefix_samples),input,&input[i*fftsize],&output[(i*fftsize) + ((i)*nb_prefix_samples)]);
145
146
#endif

147
148
#ifndef __AVX2__
    // handle 128-bit alignment for 128-bit SIMD (SSE4,NEON,AltiVEC)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
149
    idft((int16_t *)&input[i*fftsize],
150
         (fftsize==128) ? (int16_t *)temp : (int16_t *)&output[(i*fftsize) + ((1+i)*nb_prefix_samples)],
151
         1);
152
153
#else
    // on AVX2 need 256-bit alignment
Florian Kaltenberger's avatar
Florian Kaltenberger committed
154
    idft((int16_t *)&input[i*fftsize],
155
         (int16_t *)temp,
156
         1);
157

158
#endif
159

160
161
    // Copy to frame buffer with Cyclic Extension
    // Note:  will have to adjust for synchronization offset!
162

163
164
    switch (etype) {
    case CYCLIC_PREFIX:
165
      output_ptr = &output[(i*fftsize) + ((1+i)*nb_prefix_samples)];
166
      temp_ptr = (int *)temp;
167

168
169
170

      //      msg("Doing cyclic prefix method\n");

171
#ifndef __AVX2__
172
      if (fftsize==128) 
173
174
#endif
      {
175
        /*for (j=0; j<fftsize ; j++) {
176
          output_ptr[j] = temp_ptr[j];
177
178
        }*/
        memcpy((void*)output_ptr,(void*)temp_ptr,fftsize<<2);
179
      }
180

181
      j=fftsize;
182
183
184

      for (k=-1; k>=-nb_prefix_samples; k--) {
        output_ptr[k] = output_ptr[--j];
185
      }
186

187
      break;
188

189
    case CYCLIC_SUFFIX:
190
191


192
      output_ptr = &output[(i*fftsize)+ (i*nb_prefix_samples)];
193

194
      temp_ptr = (int *)temp;
195

196
197
      //      msg("Doing cyclic suffix method\n");

198
      for (j=0; j<fftsize ; j++) {
199
        output_ptr[j] = temp_ptr[2*j];
200
      }
201
202
203


      for (j=0; j<nb_prefix_samples; j++)
204
        output_ptr[fftsize+j] = output_ptr[j];
205

206
207
208
209
210
211
212
213
214
      break;

    case ZEROS:

      break;

    case NONE:

      //      msg("NO EXTENSION!\n");
215
      output_ptr = &output[fftsize];
216
217

      temp_ptr = (int *)temp;
218

219
      for (j=0; j<fftsize ; j++) {
220
        output_ptr[j] = temp_ptr[2*j];
221
222
223
224
225
226
227
228
229
230
231


      }

      break;

    default:
      break;

    }

232
233


234
  }
235

236

237
238
}

knopp's avatar
   
knopp committed
239

240
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms)
241
{
knopp's avatar
   
knopp committed
242
243
244
245
246

  int aa, slot_offset, slot_offset_F;

  slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7);
  slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
247

knopp's avatar
   
knopp committed
248
  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
249
    if (is_pmch_subframe(frame,next_slot>>1,frame_parms)) {
knopp's avatar
   
knopp committed
250
      if ((next_slot%2)==0) {
251
252
253
        LOG_D(PHY,"Frame %d, subframe %d: Doing MBSFN modulation (slot_offset %d)\n",frame,next_slot>>1,slot_offset);
        PHY_ofdm_mod(&txdataF[aa][slot_offset_F],        // input
                     &txdata[aa][slot_offset],         // output
254
                     frame_parms->ofdm_symbol_size,                
255
256
257
258
259
260
261
                     12,                 // number of symbols
                     frame_parms->ofdm_symbol_size>>2,               // number of prefix samples
                     CYCLIC_PREFIX);

        if (frame_parms->Ncp == EXTENDED)
          PHY_ofdm_mod(&txdataF[aa][slot_offset_F],        // input
                       &txdata[aa][slot_offset],         // output
262
                       frame_parms->ofdm_symbol_size,                
263
264
265
266
267
268
269
270
271
272
                       2,                 // number of symbols
                       frame_parms->nb_prefix_samples,               // number of prefix samples
                       CYCLIC_PREFIX);
        else {
          LOG_D(PHY,"Frame %d, subframe %d: Doing PDCCH modulation\n",frame,next_slot>>1);
          normal_prefix_mod(&txdataF[aa][slot_offset_F],
                            &txdata[aa][slot_offset],
                            2,
                            frame_parms);
        }
knopp's avatar
   
knopp committed
273
      }
274
    } else {
knopp's avatar
   
knopp committed
275
      if (frame_parms->Ncp == EXTENDED)
276
277
        PHY_ofdm_mod(&txdataF[aa][slot_offset_F],        // input
                     &txdata[aa][slot_offset],         // output
278
                     frame_parms->ofdm_symbol_size,                
279
280
281
                     6,                 // number of symbols
                     frame_parms->nb_prefix_samples,               // number of prefix samples
                     CYCLIC_PREFIX);
knopp's avatar
   
knopp committed
282
      else {
283
284
285
286
        normal_prefix_mod(&txdataF[aa][slot_offset_F],
                          &txdata[aa][slot_offset],
                          7,
                          frame_parms);
knopp's avatar
   
knopp committed
287
      }
288
    }
knopp's avatar
   
knopp committed
289
  }
290

knopp's avatar
   
knopp committed
291
292
}

293
/*
294
// OFDM modulation for each symbol
295
void do_OFDM_mod_symbol(LTE_eNB_COMMON *eNB_common_vars, RU_COMMON *common, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms,int do_precoding)
296
297
{

298
  int aa, l, slot_offset, slot_offsetF;
299
300
301
  int32_t **txdataF    = eNB_common_vars->txdataF;
  int32_t **txdataF_BF = common->txdataF_BF;
  int32_t **txdata     = common->txdata;
302

303
304
  slot_offset  = (next_slot)*(frame_parms->samples_per_tti>>1);
  slot_offsetF = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==EXTENDED) ? 6 : 7);
305
  //printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
306
307
308
309
  for (l=0; l<frame_parms->symbols_per_tti>>1; l++) {
  
    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {

310
311
      //printf("do_OFDM_mod_l, slot=%d, l=%d, NUMBER_OF_OFDM_CARRIERS=%d,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES=%d\n",next_slot, l,NUMBER_OF_OFDM_CARRIERS,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,1);
312
      if (do_precoding==1) beam_precoding(txdataF,txdataF_BF,frame_parms,eNB_common_vars->beam_weights,next_slot,l,aa);
313
314
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_BEAM_PRECODING,0);

315
316
      //PMCH case not implemented... 

317
318
      if (frame_parms->Ncp == EXTENDED)
        PHY_ofdm_mod((do_precoding == 1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],         // input
319
320
321
322
323
324
325
                     &txdata[aa][slot_offset+l*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],            // output
                     frame_parms->ofdm_symbol_size,       
                     1,                                   // number of symbols
                     frame_parms->nb_prefix_samples,      // number of prefix samples
                     CYCLIC_PREFIX);
      else {
        if (l==0) {
326
          PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],        // input
327
328
329
330
331
332
333
                       &txdata[aa][slot_offset],           // output
                       frame_parms->ofdm_symbol_size,      
                       1,                                  // number of symbols
                       frame_parms->nb_prefix_samples0,    // number of prefix samples
                       CYCLIC_PREFIX);
           
        } else {
334
	  PHY_ofdm_mod((do_precoding==1)?txdataF_BF[aa]:&txdataF[aa][slot_offsetF+l*frame_parms->ofdm_symbol_size],        // input
335
336
337
338
339
                       &txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],           // output
                       frame_parms->ofdm_symbol_size,      
                       1,                                  // number of symbols
                       frame_parms->nb_prefix_samples,     // number of prefix samples
                       CYCLIC_PREFIX);
340

341
342
          //printf("txdata[%d][%d]=%d\n",aa,slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,txdata[aa][slot_offset+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0+(l-1)*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES]);
 
343
344
345
346
347
348
        }
      }
    }
  }

}
349
*/