pdcch_test.c 7.91 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
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

#include "PHY/defs.h"
#include "PHY/vars.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/vars.h"
#include "MAC_INTERFACE/vars.h"
#include "PHY/CODING/defs.h"
//#include "PHY/CODING/lte_interleaver.h"
//#include "PHY/CODING/lte_interleaver_inline.h"


#include "SIMULATION/TOOLS/defs.h"
#include "PHY/LTE_TRANSPORT/defs.h"
//#include "PHY/LTE_TRANSPORT/dci.h"

//#include "decoder.h"

char current_dlsch_cqi;

44
45
void lte_param_init(unsigned char N_tx, unsigned char N_rx)
{
46
47
48
49
50
51
52
53

  printf("Start lte_param_init\n");
  PHY_vars = malloc(sizeof(PHY_VARS));
  PHY_config = malloc(sizeof(PHY_CONFIG));
  mac_xface = malloc(sizeof(MAC_xface));

  randominit(0);
  set_taus_seed(0);
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  crcTableInit();

  lte_frame_parms = &(PHY_config->lte_frame_parms);   //openair1/PHY/impl_defs_lte.h
  lte_ue_common_vars = &(PHY_vars->lte_ue_common_vars);
  lte_ue_dlsch_vars = &(PHY_vars->lte_ue_dlsch_vars);
  lte_ue_pbch_vars = &(PHY_vars->lte_ue_pbch_vars);
  lte_ue_pdcch_vars = &(PHY_vars->lte_ue_pdcch_vars);
  lte_ue_pbch_vars = &(PHY_vars->lte_ue_pbch_vars[0]);
  lte_ue_dlsch_vars_cntl = &PHY_vars->lte_ue_dlsch_vars_cntl[0];
  lte_ue_dlsch_vars_ra   = &PHY_vars->lte_ue_dlsch_vars_ra[0];
  lte_ue_dlsch_vars_1A   = &PHY_vars->lte_ue_dlsch_vars_1A[0];

  lte_frame_parms->N_RB_DL            = 25;   //50 for 10MHz and 25 for 5 MHz
  lte_frame_parms->Ncp                = 1;
  lte_frame_parms->Nid_cell           = 0;
  lte_frame_parms->nushift            = 1;
  lte_frame_parms->nb_antennas_tx     = N_tx;
  lte_frame_parms->nb_antennas_rx     = N_rx;
  init_frame_parms(lte_frame_parms);
74

75
  copy_lte_parms_to_phy_framing(lte_frame_parms, &(PHY_config->PHY_framing));
76

77
  phy_init_top(N_tx); //allocation
78

79
80
81
  lte_frame_parms->twiddle_fft      = twiddle_fft;
  lte_frame_parms->twiddle_ifft     = twiddle_ifft;
  lte_frame_parms->rev              = rev;
82

83
84
85
86
87
88
89
90
  generate_64qam_table();
  generate_16qam_table();
  phy_init_lte_ue(lte_frame_parms,lte_ue_common_vars,lte_ue_dlsch_vars,lte_ue_dlsch_vars_cntl,lte_ue_dlsch_vars_ra,lte_ue_dlsch_vars_1A,lte_ue_pbch_vars,lte_ue_pdcch_vars);//allocation
  printf("Done lte_param_init\n");
}


// 4-bit quantizer
91
92
char quantize4bit(double D,double x)
{
93
94
95
96
97
98
99
100
101
102
103
104
105
106

  double qxd;

  qxd = floor(x/D);
  //  printf("x=%f,qxd=%f\n",x,qxd);

  if (qxd <= -8)
    qxd = -8;
  else if (qxd > 7)
    qxd = 7;

  return((char)qxd);
}

107
108
char quantize(double D,double x,unsigned char B)
{
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

  double qxd;
  char maxlev;

  qxd = floor(x/D);
  //  printf("x=%f,qxd=%f\n",x,qxd);

  maxlev = 1<<(B-1);

  if (qxd <= -maxlev)
    qxd = -maxlev;
  else if (qxd >= maxlev)
    qxd = maxlev-1;

  return((char)qxd);
}

#define MAX_BLOCK_LENGTH 6000
static char channel_output[3*(MAX_DCI_SIZE_BITS+8)]__attribute__ ((aligned(16)));
static unsigned char decoded_output[1+(MAX_BLOCK_LENGTH>>3)];

int test_pdcch(double sigma,
131
132
133
134
135
136
137
               unsigned int DCI_LENGTH,
               unsigned int ntrials,
               unsigned int *errors,
               unsigned int *crc_misses,
               unsigned int *trials,
               unsigned int DCI_FMT)
{
138
139
140
141
142
143
144
145
146

  unsigned int i,n,coded_bits;
  unsigned char e[576];
  char e_rx[576] __attribute__ ((aligned(16)));
  unsigned char a[MAX_DCI_SIZE_BITS>>3];
  unsigned int crc,crce;

  memset(a,0,MAX_DCI_SIZE_BITS>>3);

147
  for (i=0; i<(DCI_LENGTH>>3); i++)
148
    a[i] = i;
149

150
151
152
153
154

  switch (DCI_FMT) {
  case 0:
    coded_bits = 72;
    break;
155

156
157
158
  case 1:
    coded_bits = 144;
    break;
159

160
161
162
  case 2:
    coded_bits = 288;
    break;
163

164
165
166
  case 3:
    coded_bits = 576;
    break;
167

168
169
170
171
172
  default:
    coded_bits = 72;
    break;
  }

173
174
  for (n=0; n<ntrials; n++) {

175
176

    dci_encoding(a,DCI_LENGTH,coded_bits,(unsigned char*)&e[0],0);
177
178

    for (i = 0; i < coded_bits; i++) {
179
180
      //      printf("e[%d] = %d -> ",i,e[i]);
      if (e[i] == 0)
181
        e_rx[i] = quantize4bit(sigma/4.0,(sqrt(2.0)*sigma*gaussdouble(0.0,1.0))- 1);
182
      else
183
184
        e_rx[i] = quantize4bit(sigma/4.0,(sqrt(2.0)*sigma*gaussdouble(0.0,1.0))+ 1);

185
186
      //      printf("e[%d] = %d\n",i,e_rx[i]);
    }
187

188
189
190
191
192
193
194
    // now do decoding

    dci_decoding(DCI_LENGTH,DCI_FMT,&e_rx[0],decoded_output);
    crce = extract_crc(decoded_output,DCI_LENGTH);
    crc = crc16(decoded_output,DCI_LENGTH);
    // check for errors
    /*printf("DCI_LEN %d : %x,%x\n",DCI_LENGTH,
195
196
197
     extract_crc(decoded_output,DCI_LENGTH),
     crc);
    */
198

199
200
    for (i=0; i<(((DCI_LENGTH>>3))); i++) {
      //      printf("decoded output %d -> %x\n",i,decoded_output[i]);
201
      if (decoded_output[i]!=i) {
202
203
204
205
206
207
208
209
210
        *errors = *errors+1;

        if ((extract_crc(decoded_output,DCI_LENGTH) ^ (crc16(decoded_output,DCI_LENGTH)>>16)) == 0) {
          *crc_misses = *crc_misses+1;
          printf("%x %x => %x\n",extract_crc(decoded_output,DCI_LENGTH),(crc16(decoded_output,DCI_LENGTH)>>16),
                 (extract_crc(decoded_output,DCI_LENGTH) ^ (crc16(decoded_output,DCI_LENGTH)>>16)));
        }

        break;
211
212
213
214
215
216
217
      }
    }

    //exit(-1);
    if (*errors == 100)
      break;
  }
218

219
  *trials = n;
220
221


222
  return(0);
223

224
225
226
227
}

#define NTRIALS 1000000

228
229
int main(int argc, char *argv[])
{
230

231
  int ret,ret2;
232
233
234
  unsigned int errors,crc_misses,trials;
  double SNR,sigma,rate;
  unsigned char qbits;
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  char done=0;


  unsigned short iind;
  unsigned int coded_bits;

  unsigned char DCI_FMT,DCI_LENGTH;

  PHY_config = malloc(sizeof(PHY_CONFIG));
  PHY_vars = malloc(sizeof(PHY_VARS));
  mac_xface = malloc(sizeof(MAC_xface));


  randominit(0);
  set_taus_seed(0);
251

252
253
254
  crcTableInit();
  ccodelte_init();
  ccodelte_init_inv();
255

256
257
258
259
260
261
262
263
264
  phy_generate_viterbi_tables_lte();
  lte_frame_parms = &(PHY_config->lte_frame_parms);
  lte_frame_parms->N_RB_DL            = 25;   //50 for 10MHz and 25 for 5 MHz
  lte_frame_parms->Ncp                = 1;
  lte_frame_parms->Nid_cell           = 0;
  lte_frame_parms->nushift            = 1;
  lte_frame_parms->nb_antennas_tx     = 2;
  lte_frame_parms->nb_antennas_rx     = 2;
  init_frame_parms(lte_frame_parms);
265

266
267
  copy_lte_parms_to_phy_framing(lte_frame_parms, &(PHY_config->PHY_framing));
  lte_param_init(2,2);
268

269
  phy_init_top(2); //allocation
270

271
272
273
274
275
276
  if (argc>1)
    DCI_FMT = atof(argv[1]);
  else
    DCI_FMT = 2;

  printf("DCI_FMT %d\n",DCI_FMT);
277
278


279
280
281
282
283
  if (argc>2)
    DCI_LENGTH = atoi(argv[2]);
  else
    DCI_LENGTH = sizeof_DCI0_5MHz_TDD_0_t;

284
285
286


  for (SNR=-2; SNR<4; SNR+=.2) {
287
288
289
290
291
292
293
294
295


    printf("\n\nSNR %f dB\n",SNR);

    sigma = pow(10.0,-.05*SNR);

    errors=0;
    crc_misses=0;

296
    if (done == 0) {
297
298

      printf("PDCCH %d\n",DCI_LENGTH);
299

300
      ret = test_pdcch(sigma,   // noise standard deviation
301
302
303
304
305
306
307
                       DCI_LENGTH,
                       NTRIALS,
                       &errors,
                       &crc_misses,
                       &trials,
                       DCI_FMT);

308
      if (ret>=0)
309
310
        printf("ref: Errors %d (%f), CRC Misses %d (%f)\n",errors,(double)errors/trials,crc_misses,(double)crc_misses/trials);

311
      if (((double)errors/trials) < 1e-3)
312
313
        done=1;
    }
314
315
316
317
318
319

    if (done==1) {
      printf("done\n");
      break;
    }
  }
320

321
322
  return(0);
}