polartest.c 12.9 KB
Newer Older
Guy De Souza's avatar
Guy De Souza committed
1
2
3
4
5
6
7
8
9
10
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>

#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
Florian Kaltenberger's avatar
WIP    
Florian Kaltenberger committed
11
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
yilmazt's avatar
yilmazt committed
12
#include "PHY/CODING/coding_defs.h"
yilmazt's avatar
yilmazt committed
13
#include "SIMULATION/TOOLS/sim.h"
14
15
//#include "PHY/NR_TRANSPORT/nr_transport.h"
//#include "common/utils/LOG/log.h"
Guy De Souza's avatar
Guy De Souza committed
16

Florian Kaltenberger's avatar
Florian Kaltenberger committed
17
//#define DEBUG_DCI_POLAR_PARAMS
yilmazt's avatar
yilmazt committed
18
//#define DEBUG_POLAR_TIMING
19
20
//#define DEBUG_POLARTEST

Guy De Souza's avatar
Guy De Souza committed
21
int main(int argc, char *argv[]) {
22
  //Default simulation values (Aim for iterations = 1000000.)
23
  int decoder_int16=0;
24
25
26
27
28
  int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
  double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
  double SNR, SNR_lin;
  int16_t nBitError = 0; // -1 = Decoding failed (All list entries have failed the CRC checks).
  uint32_t decoderState=0, blockErrorState=0; //0 = Success, -1 = Decoding failed, 1 = Block Error.
29
  uint16_t testLength = NR_POLAR_PBCH_PAYLOAD_BITS, coderLength = NR_POLAR_PBCH_E;
30
  uint16_t blockErrorCumulative=0, bitErrorCumulative=0;
31
  double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
32
  uint8_t aggregation_level = 8, decoderListSize = 8, logFlag = 0;
33
  uint16_t rnti=0;
34

35
  while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:p:hqgFL:k:")) != -1)
36
    switch (arguments) {
37
    case 's':
38
39
    	SNRstart = atof(optarg);
    	break;
40
41

    case 'd':
42
43
    	SNRinc = atof(optarg);
    	break;
44
45

    case 'f':
46
47
    	SNRstop = atof(optarg);
    	break;
48
49

    case 'm':
50
51
52
53
    	polarMessageType = atoi(optarg);
    	if (polarMessageType!=0 && polarMessageType!=1 && polarMessageType!=2)
    		printf("Illegal polar message type %d (should be 0,1 or 2)\n", polarMessageType);
    	break;
54
55

    case 'i':
56
57
    	iterations = atoi(optarg);
    	break;
58
59
60
61
62
63

    case 'l':
      decoderListSize = (uint8_t) atoi(optarg);
      break;

    case 'q':
64
65
    	decoder_int16 = 1;
    	break;
66
67

    case 'g':
68
69
70
71
72
    	iterations = 1;
    	SNRstart = -6.0;
    	SNRstop = -6.0;
    	decoder_int16 = 1;
    	break;
73

74
75
76
    case 'F':
    	logFlag = 1;
    	break;
77

78
79
80
81
82
83
84
    case 'L':
    	aggregation_level=atoi(optarg);
    	if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 && aggregation_level != 16) {
    		printf("Illegal aggregation level %d \n",aggregation_level);
    		exit(-1);
    	}
    	break;
85

86
    case 'k':
87
88
89
90
91
92
    	testLength=atoi(optarg);
    	if (testLength < 12 || testLength > 60) {
    		printf("Illegal packet bitlength %d \n",testLength);
    		exit(-1);
    	}
    	break;
93
94

    case 'h':
95
      printf("./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
96
97
             "-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
    		 "-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
98
99
100
101
102
103
104
      exit(-1);
      break;

    default:
      perror("[polartest.c] Problem at argument parsing with getopt");
      exit(-1);
      break;
105
106
    }

107
108
109
110
111
112
113
114
115
  //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
    time_stats_t timeEncoder,timeDecoder;
    opp_enabled=1;
    cpu_freq_GHz = get_cpu_freq_GHz();
    reset_meas(&timeEncoder);
    reset_meas(&timeDecoder);
    randominit(0);
    crcTableInit();

116
  if (polarMessageType == 0) { //PBCH
117
	  aggregation_level = NR_POLAR_PBCH_AGGREGATION_LEVEL;
118
  } else if (polarMessageType == 1) { //DCI
119
	  coderLength = 108*aggregation_level;
120
  } else if (polarMessageType == -1) { //UCI
121
122
	  printf("UCI testing not supported yet\n");
	  exit(-1);
123
124
125
126
127
128
  }

  //Logging
  time_t currentTime;
  char fileName[512], currentTimeInfo[25];
  char folderName[] = ".";
129
130
131
132
133
134
  FILE *logFile;
  /*folderName=getenv("HOME");
    strcat(folderName,"/Desktop/polartestResults");*/

if (logFlag){
	time (&currentTime);
yilmazt's avatar
yilmazt committed
135
#ifdef DEBUG_POLAR_TIMING
136
  sprintf(fileName,"%s/TIMING_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
yilmazt's avatar
yilmazt committed
137
#else
138
  sprintf(fileName,"%s/_ListSize_%d_Payload_%d_Itr_%d", folderName, decoderListSize, testLength, iterations);
yilmazt's avatar
yilmazt committed
139
#endif
140
141
142
  strftime(currentTimeInfo, 25, "_%Y-%m-%d-%H-%M-%S.csv", localtime(&currentTime));
  strcat(fileName,currentTimeInfo);
  //Create "~/Desktop/polartestResults" folder if it doesn't already exist.
143
144
  /*struct stat folder = {0};
    if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);*/
145
146
147
148
149
150
  logFile = fopen(fileName, "w");

  if (logFile==NULL) {
    fprintf(stderr,"[polartest.c] Problem creating file %s with fopen\n",fileName);
    exit(-1);
  }
Guy De Souza's avatar
Guy De Souza committed
151

152
#ifdef DEBUG_POLAR_TIMING
153
  fprintf(logFile,",timeEncoderCRCByte[us],timeEncoderCRCBit[us],timeEncoderInterleaver[us],timeEncoderBitInsertion[us],timeEncoder1[us],timeEncoder2[us],timeEncoderRateMatching[us],timeEncoderByte2Bit[us]\n");
154
155
156
#else
  fprintf(logFile,",SNR,nBitError,blockErrorState,t_encoder[us],t_decoder[us]\n");
#endif
157
158
}

159
160
161
162
163
164
165
166
167
168
169
170
  uint8_t testArrayLength = ceil(testLength / 32.0);
  uint8_t coderArrayLength = ceil(coderLength / 32.0);
  uint32_t testInput[testArrayLength]; //generate randomly
  uint32_t encoderOutput[coderArrayLength];
  uint32_t estimatedOutput[testArrayLength]; //decoder output
  memset(testInput,0,sizeof(uint32_t) * testArrayLength);
  memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
  memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
  uint8_t encoderOutputByte[coderLength];
  double modulatedInput[coderLength]; //channel input
  double channelOutput[coderLength];  //add noise
  int16_t channelOutput_int16[coderLength];
171

Thomas Laurent's avatar
Thomas Laurent committed
172
  t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
173

yilmazt's avatar
yilmazt committed
174
#ifdef DEBUG_DCI_POLAR_PARAMS
175
176
177
  uint32_t dci_pdu[4];
  memset(dci_pdu,0,sizeof(uint32_t)*4);
  dci_pdu[0]=0x01189400;
178
  printf("dci_pdu: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_pdu[0], dci_pdu[1], dci_pdu[2], dci_pdu[3]);
179
  uint16_t size=41;
180
  rnti=3;
181
  aggregation_level=8;
182
183
  uint32_t encoder_output[54];
  memset(encoder_output,0,sizeof(uint32_t)*54);
184
185
  t_nrPolar_params *currentPtrDCI=nr_polar_params(1, size, aggregation_level);

186
187
  polar_encoder_dci(dci_pdu, encoder_output, currentPtrDCI, rnti);
  for (int i=0; i<54; i++) printf("encoder_output: [%2d]->0x%08x \n", i, encoder_output[i]);
188
189

  uint8_t *encoder_outputByte = malloc(sizeof(uint8_t) * currentPtrDCI->encoderLength);
190
191
192
193
194
  double *modulated_input = malloc (sizeof(double) * currentPtrDCI->encoderLength);
  double *channel_output = malloc (sizeof(double) * currentPtrDCI->encoderLength);
  uint32_t dci_est[4];
  memset(dci_est,0,sizeof(uint32_t)*4);
  printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
195
  nr_bit2byte_uint32_8(encoder_output, currentPtrDCI->encoderLength, encoder_outputByte);
196
  printf("[polartest] encoder_outputByte: ");
197
  for (int i = 0; i < currentPtrDCI->encoderLength; i++) printf("%d-", encoder_outputByte[i]); printf("\n");
198

199
  SNR_lin = pow(10, 0/10); //SNR = 0 dB
200
  for(int i=0; i<currentPtrDCI->encoderLength; i++) {
201
202
203
204
205
	  if (encoder_outputByte[i] == 0)
		  modulated_input[i]=1/sqrt(2);
	  else
		  modulated_input[i]=(-1)/sqrt(2);
	  channel_output[i] = modulated_input[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
206
  }
207
  decoderState = polar_decoder_dci(channel_output, dci_est, currentPtrDCI, NR_POLAR_DECODER_LISTSIZE, rnti);
208
  printf("dci_est: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", dci_est[0], dci_est[1], dci_est[2], dci_est[3]);
209
210
  free(encoder_outputByte);
  free(channel_output);
211
  free(modulated_input);
212
  return 0;
213
#endif
214
215

  for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
216
217
218
219
220
221
222
223
224
225
226
227
	  printf("SNR %f\n",SNR);
	  SNR_lin = pow(10, SNR/10);

	  for (itr = 1; itr <= iterations; itr++) {
		  //Generate random values for all the bits of "testInput", not just as much as "currentPtr->payloadBits".
		  for (int i = 0; i < testArrayLength; i++) {
			  for (int j = 0; j < (sizeof(testInput[0])*8)-1; j++) {
				  testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
				  testInput[i]<<=1;
			  }
			  testInput[i] |= ( ((uint32_t) (rand()%2)) &1);
		  }
228

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#ifdef DEBUG_POLARTEST
		  //testInput[0] = 0x360f8a5c;
		  printf("testInput: [0]->0x%08x\n", testInput[0]);
#endif
		  int len_mod64=currentPtr->payloadBits&63;
		  ((uint64_t *)testInput)[currentPtr->payloadBits/64]&=((((uint64_t)1)<<len_mod64)-1);

		  start_meas(&timeEncoder);
		  if (decoder_int16==1) {
			  polar_encoder_fast((uint64_t *)testInput, encoderOutput, 0, currentPtr);
			  //polar_encoder_fast((uint64_t*)testInput, (uint64_t*)encoderOutput,0, currentPtr);
		  } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
			  if (polarMessageType == 0)
				  polar_encoder(testInput, encoderOutput, currentPtr);
			  else if (polarMessageType == 1)
				  polar_encoder_dci(testInput, encoderOutput, currentPtr, rnti);
		  }
		  stop_meas(&timeEncoder);

#ifdef DEBUG_POLARTEST
		  printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]);
		  //for (int i=1;i<coderArrayLength;i++) printf("encoderOutput: [i]->0x%08x\n", i, encoderOutput[1]);
#endif
252
253

      //Bit-to-byte:
254
      nr_bit2byte_uint32_8(encoderOutput, coderLength, encoderOutputByte);
255
256
257

      //BPSK modulation
      for(int i=0; i<coderLength; i++) {
258
259
260
261
262
263
264
265
266
267
268
269
    	  if (encoderOutputByte[i] == 0)
    		  modulatedInput[i]=1/sqrt(2);
    	  else
    		  modulatedInput[i]=(-1)/sqrt(2);

    	  channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));

    	  if (decoder_int16==1) {
    		  if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
    		  else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
    		  else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
    	  }
270
271
272
273
      }

      start_meas(&timeDecoder);

274
275
276
      if (decoder_int16==1) {
    	  decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, currentPtr);
      } else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
277
    	  if (polarMessageType == 0) {
278
279
280
281
    		  decoderState = polar_decoder(channelOutput,
    				                       estimatedOutput,
										   currentPtr,
										   decoderListSize);
282
    	  } else if (polarMessageType == 1) {
283
284
285
286
287
    		  decoderState = polar_decoder_dci(channelOutput,
    				  	  	  	  	  	  	   estimatedOutput,
											   currentPtr,
											   decoderListSize,
											   rnti);
288
    	  }
289
      }
290
      stop_meas(&timeDecoder);
291
292
293
294
      
#ifdef DEBUG_POLARTEST
      printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);
#endif
295
296
297

      //calculate errors
      if (decoderState!=0) {
298
299
    	  blockErrorState=-1;
    	  nBitError=-1;
300
      } else {
301
302
303
304
305
306
307
308
309
    	  for (int i = 0; i < (testArrayLength-1); i++) {
    	  		for (int j = 0; j < 32; j++) {
    	  			if ( ((estimatedOutput[i]>>j) & 1) != ((testInput[i]>>j) & 1) )
    	  				nBitError++;
    	  		}
    	  	}
    	  for (int j = 0; j < testLength - ((testArrayLength-1) * 32); j++)
    		  if ( ((estimatedOutput[(testArrayLength-1)]>>j) & 1) != ((testInput[(testArrayLength-1)]>>j) & 1) )
    			  nBitError++;
310
      }
311
312
313
314
315
      if (nBitError>0) blockErrorState=1;
#ifdef DEBUG_POLARTEST
          		  for (int i = 0; i < testArrayLength; i++)
          			  printf("[polartest/decoderState=%d] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]);
#endif
316
317
318
319

      //Iteration times are in microseconds.
      timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
      timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0));
320
      if (logFlag) fprintf(logFile,",%f,%d,%d,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
321
322
323
324
325
326
327
328
329
330
331
332

      if (nBitError<0) {
        blockErrorCumulative++;
        bitErrorCumulative+=testLength;
      } else {
        blockErrorCumulative+=blockErrorState;
        bitErrorCumulative+=nBitError;
      }

      decoderState=0;
      nBitError=0;
      blockErrorState=0;
333
334
335
	  memset(testInput,0,sizeof(uint32_t) * testArrayLength);
	  memset(encoderOutput,0,sizeof(uint32_t) * coderArrayLength);
	  memset(estimatedOutput,0,sizeof(uint32_t) * testArrayLength);
336
337
338
    }

    //Calculate error statistics for the SNR.
339
340
    printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
           decoderListSize, SNR, ((double)blockErrorCumulative/iterations),
341
342
343
344
           ((double)bitErrorCumulative / (iterations*testLength)),
           (double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
    //(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);

345
    if (blockErrorCumulative==0 && bitErrorCumulative==0) break;
346
347
348
349
350
351
352
353
354

    blockErrorCumulative = 0;
    bitErrorCumulative = 0;
    timeEncoderCumulative = 0;
    timeDecoderCumulative = 0;
  }

  print_meas(&timeEncoder,"polar_encoder",NULL,NULL);
  print_meas(&timeDecoder,"polar_decoder",NULL,NULL);
355
  if (logFlag) fclose(logFile);
356
  return (0);
Guy De Souza's avatar
Guy De Souza committed
357
}