Beispiel #1
0
int main(int argc, char **argv) {
  int frame_cnt;
  float *llr;
  unsigned char *llr_c;
  char *data_tx, *data_rx, *symbols;
  int i, j;
  float var[SNR_POINTS];
  int snr_points;
  float ber[MAX_ITERATIONS][SNR_POINTS];
  unsigned int errors[100];
  int coded_length;
  struct timeval tdata[3];
  float mean_usec;
  tdec_t tdec;
  tcod_t tcod;

  parse_args(argc, argv);

  if (!seed) {
    seed = time(NULL);
  }
  srand(seed);

  if (test_known_data) {
    frame_length = KNOWN_DATA_LEN;
  } else {
    frame_length = lte_cb_size(lte_find_cb_index(frame_length));
  }

  coded_length = 3 * (frame_length) + TOTALTAIL;

  printf("  Frame length: %d\n", frame_length);
  if (ebno_db < 100.0) {
    printf("  EbNo: %.2f\n", ebno_db);
  }

  data_tx = malloc(frame_length * sizeof(char));
  if (!data_tx) {
    perror("malloc");
    exit(-1);
  }

  data_rx = malloc(frame_length * sizeof(char));
  if (!data_rx) {
    perror("malloc");
    exit(-1);
  }

  symbols = malloc(coded_length * sizeof(char));
  if (!symbols) {
    perror("malloc");
    exit(-1);
  }
  llr = malloc(coded_length * sizeof(float));
  if (!llr) {
    perror("malloc");
    exit(-1);
  }
  llr_c = malloc(coded_length * sizeof(char));
  if (!llr_c) {
    perror("malloc");
    exit(-1);
  }

  if (tcod_init(&tcod, frame_length)) {
    fprintf(stderr, "Error initiating Turbo coder\n");
    exit(-1);
  }

  if (tdec_init(&tdec, frame_length)) {
    fprintf(stderr, "Error initiating Turbo decoder\n");
    exit(-1);
  }

  float ebno_inc, esno_db;
  ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS;
  if (ebno_db == 100.0) {
    snr_points = SNR_POINTS;
    for (i = 0; i < snr_points; i++) {
      ebno_db = SNR_MIN + i * ebno_inc;
      esno_db = ebno_db + 10 * log10((double) 1 / 3);
      var[i] = sqrt(1 / (pow(10, esno_db / 10)));
    }
  } else {
    esno_db = ebno_db + 10 * log10((double) 1 / 3);
    var[0] = sqrt(1 / (pow(10, esno_db / 10)));
    snr_points = 1;
  }
  for (i = 0; i < snr_points; i++) {
    mean_usec = 0;
    frame_cnt = 0;
    bzero(errors, sizeof(int) * MAX_ITERATIONS);
    while (frame_cnt < nof_frames) {

      /* generate data_tx */
      for (j = 0; j < frame_length; j++) {
        if (test_known_data) {
          data_tx[j] = known_data[j];
        } else {
          data_tx[j] = rand() % 2;
        }
      }

      /* coded BER */
      if (test_known_data) {
        for (j = 0; j < coded_length; j++) {
          symbols[j] = known_data_encoded[j];
        }
      } else {
        tcod_encode(&tcod, data_tx, symbols, frame_length);
      }

      for (j = 0; j < coded_length; j++) {
        llr[j] = symbols[j] ? sqrt(2) : -sqrt(2);
      }

      ch_awgn_f(llr, llr, var[i], coded_length);

      /* decoder */
      tdec_reset(&tdec, frame_length);

      int t;
      if (nof_iterations == -1) {
        t = MAX_ITERATIONS;
      } else {
        t = nof_iterations;
      }
      for (j = 0; j < t; j++) {

        if (!j)
          gettimeofday(&tdata[1], NULL); // Only measure 1 iteration
        tdec_iteration(&tdec, llr, frame_length);
        tdec_decision(&tdec, data_rx, frame_length);
        if (!j)
          gettimeofday(&tdata[2], NULL);
        if (!j)
          get_time_interval(tdata);
        if (!j)
          mean_usec = (float) mean_usec * 0.9 + (float) tdata[0].tv_usec * 0.1;

        /* check errors */
        errors[j] += bit_diff(data_tx, data_rx, frame_length);
        if (j < MAX_ITERATIONS) {
          ber[j][i] = (float) errors[j] / (frame_cnt * frame_length);
        }
      }
      frame_cnt++;
      printf("Eb/No: %3.2f %10d/%d   ",
      SNR_MIN + i * ebno_inc, frame_cnt, nof_frames);
      printf("BER: %.2e  ", (float) errors[j - 1] / (frame_cnt * frame_length));
      printf("%3.1f Mbps (%6.2f usec)", (float) frame_length / mean_usec,
          mean_usec);
      printf("\r");

    }
    printf("\n");

    if (snr_points == 1) {
      if (test_known_data && seed == KNOWN_DATA_SEED
          && ebno_db == KNOWN_DATA_EBNO && frame_cnt == KNOWN_DATA_NFRAMES) {
        for (j = 0; j < MAX_ITERATIONS; j++) {
          if (errors[j] > known_data_errors[j]) {
            fprintf(stderr, "Expected %d errors but got %d\n",
                known_data_errors[j], errors[j]);
            exit(-1);
          } else {
            printf("Iter %d ok\n", j + 1);
          }
        }
      } else {
        for (j = 0; j < MAX_ITERATIONS; j++) {
          printf("BER: %g\t%u errors\n",
              (float) errors[j] / (frame_cnt * frame_length), errors[j]);
          if (test_errors) {
            if (errors[j]
                > get_expected_errors(frame_cnt, seed, j + 1, frame_length,
                    ebno_db)) {
              fprintf(stderr, "Expected %d errors but got %d\n",
                  get_expected_errors(frame_cnt, seed, j + 1, frame_length,
                      ebno_db), errors[j]);
              exit(-1);
            } else {
              printf("Iter %d ok\n", j + 1);
            }
          }
        }
      }
    }
  }

  free(data_tx);
  free(symbols);
  free(llr);
  free(llr_c);
  free(data_rx);

  tdec_free(&tdec);
  tcod_free(&tcod);

  printf("\n");
  output_matlab(ber, snr_points);
  printf("Done\n");
  exit(0);
}
Beispiel #2
0
int main(int argc, char **argv) {
    int frame_cnt;
    float *llr;
    uint8_t *llr_c;
    uint8_t *data_tx, *data_rx[NTYPES], *symbols;
    int i, j;
    float var[SNR_POINTS], varunc[SNR_POINTS];
    int snr_points;
    float ber[NTYPES][SNR_POINTS];
    uint32_t errors[NTYPES];
    srslte_viterbi_type_t srslte_viterbi_type[NCODS];
    srslte_viterbi_t dec[NCODS];
    srslte_convcoder_t cod[NCODS];
    int coded_length[NCODS];
    int n, ncods, max_coded_length;


    parse_args(argc, argv);

    if (!seed) {
        seed = time(NULL);
    }
    srand(seed);

    switch (K) {
    case 9:
        cod[0].poly[0] = 0x1ed;
        cod[0].poly[1] = 0x19b;
        cod[0].poly[2] = 0x127;
        cod[0].tail_biting = false;
        cod[0].K = 9;
        srslte_viterbi_type[0] = SRSLTE_VITERBI_39;
        ncods=1;
        break;
    case 7:
        cod[0].poly[0] = 0x6D;
        cod[0].poly[1] = 0x4F;
        cod[0].poly[2] = 0x57;
        cod[0].K = 7;
        cod[0].tail_biting = tail_biting;
        srslte_viterbi_type[0] = SRSLTE_VITERBI_37;
        ncods=1;
        break;
    default:
        cod[0].poly[0] = 0x1ed;
        cod[0].poly[1] = 0x19b;
        cod[0].poly[2] = 0x127;
        cod[0].tail_biting = false;
        cod[0].K = 9;
        srslte_viterbi_type[0] = SRSLTE_VITERBI_39;
        cod[1].poly[0] = 0x6D;
        cod[1].poly[1] = 0x4F;
        cod[1].poly[2] = 0x57;
        cod[1].tail_biting = false;
        cod[1].K = 7;
        srslte_viterbi_type[1] = SRSLTE_VITERBI_37;
        cod[2].poly[0] = 0x6D;
        cod[2].poly[1] = 0x4F;
        cod[2].poly[2] = 0x57;
        cod[2].tail_biting = true;
        cod[2].K = 7;
        srslte_viterbi_type[2] = SRSLTE_VITERBI_37;
        ncods=3;
    }

    max_coded_length = 0;
    for (i=0; i<ncods; i++) {
        cod[i].R = 3;
        coded_length[i] = cod[i].R * (frame_length + ((cod[i].tail_biting) ? 0 : cod[i].K - 1));
        if (coded_length[i] > max_coded_length) {
            max_coded_length = coded_length[i];
        }
        srslte_viterbi_init(&dec[i], srslte_viterbi_type[i], cod[i].poly, frame_length, cod[i].tail_biting);
        printf("Convolutional Code 1/3 K=%d Tail bitting: %s\n", cod[i].K, cod[i].tail_biting ? "yes" : "no");
    }

    printf("  Frame length: %d\n", frame_length);
    if (ebno_db < 100.0) {
        printf("  EbNo: %.2f\n", ebno_db);
    }

    data_tx = malloc(frame_length * sizeof(uint8_t));
    if (!data_tx) {
        perror("malloc");
        exit(-1);
    }

    for (i = 0; i < NTYPES; i++) {
        data_rx[i] = malloc(frame_length * sizeof(uint8_t));
        if (!data_rx[i]) {
            perror("malloc");
            exit(-1);
        }
    }

    symbols = malloc(max_coded_length * sizeof(uint8_t));
    if (!symbols) {
        perror("malloc");
        exit(-1);
    }
    llr = malloc(max_coded_length * sizeof(float));
    if (!llr) {
        perror("malloc");
        exit(-1);
    }
    llr_c = malloc(2 * max_coded_length * sizeof(uint8_t));
    if (!llr_c) {
        perror("malloc");
        exit(-1);
    }

    float ebno_inc, esno_db;
    ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS;
    if (ebno_db == 100.0) {
        snr_points = SNR_POINTS;
        for (i = 0; i < snr_points; i++) {
            ebno_db = SNR_MIN + i * ebno_inc;
            esno_db = ebno_db + 10 * log10((double) 1 / 3);
            var[i] = sqrt(1 / (pow(10, esno_db / 10)));
            varunc[i] = sqrt(1 / (pow(10, ebno_db / 10)));
        }
    } else {
        esno_db = ebno_db + 10 * log10((double) 1 / 3);
        var[0] = sqrt(1 / (pow(10, esno_db / 10)));
        varunc[0] = sqrt(1 / (pow(10, ebno_db / 10)));
        snr_points = 1;
    }

    float Gain = 32;

    for (i = 0; i < snr_points; i++) {
        frame_cnt = 0;
        for (j = 0; j < NTYPES; j++) {
            errors[j] = 0;
        }
        while (frame_cnt < nof_frames) {

            /* generate data_tx */
            for (j = 0; j < frame_length; j++) {
                data_tx[j] = rand() % 2;
            }

            /* uncoded BER */
            for (j = 0; j < frame_length; j++) {
                llr[j] = data_tx[j] ? sqrt(2) : -sqrt(2);
            }
            srslte_ch_awgn_f(llr, llr, varunc[i], frame_length);
            for (j = 0; j < frame_length; j++) {
                data_rx[0][j] = llr[j] > 0 ? 1 : 0;
            }

            /* coded BER */
            for (n=0; n<ncods; n++) {
                srslte_convcoder_encode(&cod[n], data_tx, symbols, frame_length);

                for (j = 0; j < coded_length[n]; j++) {
                    llr[j] = symbols[j] ? sqrt(2) : -sqrt(2);
                }

                srslte_ch_awgn_f(llr, llr, var[i], coded_length[n]);
                srslte_vec_quant_fuc(llr, llr_c, Gain, 127.5, 255, coded_length[n]);

                /* decoder 1 */
                srslte_viterbi_decode_uc(&dec[n], llr_c, data_rx[1+n], frame_length);
            }

            /* check errors */
            for (j = 0; j < 1+ncods; j++) {
                errors[j] += srslte_bit_diff(data_tx, data_rx[j], frame_length);
            }
            frame_cnt++;
            printf("Eb/No: %3.2f %10d/%d   ",
                   SNR_MIN + i * ebno_inc,frame_cnt,nof_frames);
            for (n=0; n<1+ncods; n++) {
                printf("BER: %.2e  ",(float) errors[n] / (frame_cnt * frame_length));
            }
            printf("\r");
        }
        printf("\n");
        for (j = 0; j < 1+ncods; j++) {
            ber[j][i] = (float) errors[j] / (frame_cnt * frame_length);
        }

        if (snr_points == 1) {
            printf("BER uncoded: %g\t%u errors\n",
                   (float) errors[0] / (frame_cnt * frame_length), errors[0]);
            for (n=0; n<ncods; n++) {
                printf("BER K=%d:    %g\t%u errors\n",cod[n].K,
                       (float) errors[1+n] / (frame_cnt * frame_length), errors[1+n]);
            }
        }
    }
    for (n=0; n<ncods; n++) {
        srslte_viterbi_free(&dec[n]);
    }

    free(data_tx);
    free(symbols);
    free(llr);
    free(llr_c);
    for (i = 0; i < NTYPES; i++) {
        free(data_rx[i]);
    }

    if (snr_points == 1) {
        int expected_errors = get_expected_errors(nof_frames,
                              seed, frame_length, K, tail_biting, ebno_db);
        if (expected_errors == -1) {
            fprintf(stderr, "Test parameters not defined in test_results.h\n");
            exit(-1);
        } else {
            printf("errors =%d, expected =%d\n", errors[1], expected_errors);
            exit(errors[1] > expected_errors);
        }
    } else {
        printf("\n");
        output_matlab(ber, snr_points, cod, ncods);
        printf("Done\n");
        exit(0);
    }
}