예제 #1
0
int main(int argc, char **argv) {
  int i, j;
  float mse;
  cf_t *x[SRSLTE_MAX_LAYERS], *r[SRSLTE_MAX_PORTS], *y[SRSLTE_MAX_PORTS], *h[SRSLTE_MAX_PORTS],
      *xr[SRSLTE_MAX_LAYERS];
  srslte_mimo_type_t type;
  srslte_precoding_t precoding; 
  
  parse_args(argc, argv);

  if (nof_ports > SRSLTE_MAX_PORTS || nof_layers > SRSLTE_MAX_LAYERS) {
    fprintf(stderr, "Invalid number of layers or ports\n");
    exit(-1);
  }

  if (srslte_str2mimotype(mimo_type_name, &type)) {
    fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name);
    exit(-1);
  }

  for (i = 0; i < nof_layers; i++) {
    x[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!x[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
    xr[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!xr[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }
  for (i = 0; i < nof_ports; i++) {
    y[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
    // TODO: The number of symbols per port is different in spatial multiplexing.
    if (!y[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
    h[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
    if (!h[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }

  /* only 1 receiver antenna supported now */
  r[0] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols * nof_layers);
  if (!r[0]) {
    perror("srslte_vec_malloc");
    exit(-1);
  }

  /* generate random data */
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      x[i][j] = (2*(rand()%2)-1+(2*(rand()%2)-1)*_Complex_I)/sqrt(2);
    }
  }
  
  if (srslte_precoding_init(&precoding, nof_symbols * nof_layers)) {
    fprintf(stderr, "Error initializing precoding\n");
    exit(-1);
  }

  /* precoding */
  if (srslte_precoding_type(&precoding, x, y, nof_layers, nof_ports, nof_symbols, type) < 0) {
    fprintf(stderr, "Error layer mapper encoder\n");
    exit(-1);
  }

  /* generate channel */
  for (i = 0; i < nof_ports; i++) {
    for (j = 0; j < nof_symbols; j++) {
      h[i][nof_layers*j] = (float) rand()/RAND_MAX+((float) rand()/RAND_MAX)*_Complex_I;
      // assume the channel is time-invariant in nlayer consecutive symbols
      for (int k=0;k<nof_layers;k++) {
        h[i][nof_layers*j+k] = h[i][nof_layers*j];      
      }
    }
  }

  /* pass signal through channel
   (we are in the frequency domain so it's a multiplication) */
  /* there's only one receiver antenna, signals from different transmitter
   * ports are simply combined at the receiver
   */
  for (j = 0; j < nof_symbols * nof_layers; j++) {
    r[0][j] = 0;
    for (i = 0; i < nof_ports; i++) {
      r[0][j] += y[i][j] * h[i][j];
    }
  }
  
  /* predecoding / equalization */
  struct timeval t[3];
  gettimeofday(&t[1], NULL);
  if (srslte_predecoding_type(&precoding, r[0], h, xr, nof_ports, nof_layers,
      nof_symbols * nof_layers, type, 0) < 0) {
    fprintf(stderr, "Error layer mapper encoder\n");
    exit(-1);
  }
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  printf("Execution Time: %d us\n", t[0].tv_usec);
  
  /* check errors */
  mse = 0;
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      mse += cabsf(xr[i][j] - x[i][j]);
    }
  }
  printf("MSE: %f\n", mse/ nof_layers / nof_symbols );
  if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) {
    exit(-1);
  } 

  for (i = 0; i < nof_layers; i++) {
    free(x[i]);
    free(xr[i]);
  }
  for (i = 0; i < nof_ports; i++) {
    free(y[i]);
    free(h[i]);
  }

  free(r[0]);
  
  srslte_precoding_free(&precoding);
  
  printf("Ok\n");
  exit(0); 
}
예제 #2
0
int main(int argc, char **argv) {
  int i, j, k, nof_errors = 0, ret = SRSLTE_SUCCESS;
  float mse;
  cf_t *x[SRSLTE_MAX_LAYERS], *r[SRSLTE_MAX_PORTS], *y[SRSLTE_MAX_PORTS], *h[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
      *xr[SRSLTE_MAX_LAYERS];
  srslte_mimo_type_t type;
  
  parse_args(argc, argv);

  /* Check input ranges */
  if (nof_tx_ports > SRSLTE_MAX_PORTS || nof_rx_ports > SRSLTE_MAX_PORTS || nof_layers > SRSLTE_MAX_LAYERS) {
    fprintf(stderr, "Invalid number of layers or ports\n");
    exit(-1);
  }

  /* Parse MIMO Type */
  if (srslte_str2mimotype(mimo_type_name, &type)) {
    fprintf(stderr, "Invalid MIMO type %s\n", mimo_type_name);
    exit(-1);
  }

  /* Check scenario conditions are OK */
  switch (type) {
    case SRSLTE_MIMO_TYPE_TX_DIVERSITY:
      nof_re = nof_layers*nof_symbols;
      break;
    case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX:
      nof_re = nof_symbols;
      break;
    case SRSLTE_MIMO_TYPE_CDD:
      nof_re = nof_symbols*nof_tx_ports/nof_layers;
      if (nof_rx_ports != 2 || nof_tx_ports != 2) {
        fprintf(stderr, "CDD nof_tx_ports=%d nof_rx_ports=%d is not currently supported\n", nof_tx_ports, nof_rx_ports);
        exit(-1);
      }
      break;
    default:
      nof_re = nof_symbols*nof_layers;
  }

  /* Allocate x and xr (received symbols) in memory for each layer */
  for (i = 0; i < nof_layers; i++) {
    /* Source data */
    x[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!x[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }

    /* Sink data */
    xr[i] = srslte_vec_malloc(sizeof(cf_t) * nof_symbols);
    if (!xr[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }

  /* Allocate y in memory for tx each port */
  for (i = 0; i < nof_tx_ports; i++) {
    y[i] = srslte_vec_malloc(sizeof(cf_t) * nof_re);
    if (!y[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }

  /* Allocate h in memory for each cross channel and layer */
  for (i = 0; i < nof_tx_ports; i++) {
    for (j = 0; j < nof_rx_ports; j++) {
      h[i][j] = srslte_vec_malloc(sizeof(cf_t) * nof_re);
      if (!h[i][j]) {
        perror("srslte_vec_malloc");
        exit(-1);
      }
    }
  }

  /* Allocate r */
  for (i = 0; i < nof_rx_ports; i++) {
    r[i] = srslte_vec_malloc(sizeof(cf_t) * nof_re);
    if (!r[i]) {
      perror("srslte_vec_malloc");
      exit(-1);
    }
  }

  /* Generate source random data */
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      x[i][j] = (2 * (rand() % 2) - 1 + (2 * (rand() % 2) - 1) * _Complex_I) / sqrt(2);
    }
  }

  /* Execute Precoding (Tx) */
  if (srslte_precoding_type(x, y, nof_layers, nof_tx_ports, codebook_idx, nof_symbols, scaling, type) < 0) {
    fprintf(stderr, "Error layer mapper encoder\n");
    exit(-1);
  }

  /* generate channel */
  populate_channel(type, h);

  /* pass signal through channel
   (we are in the frequency domain so it's a multiplication) */
  for (i = 0; i < nof_rx_ports; i++) {
    for (k = 0; k < nof_re; k++) {
      r[i][k] = (cf_t) (0.0 + 0.0 * _Complex_I);
      for (j = 0; j < nof_tx_ports; j++) {
        r[i][k] += y[j][k] * h[j][i][k];
      }
    }
  }

  awgn(r, (uint32_t) nof_re, snr_db);

  /* If CDD or Spatial muliplex choose decoder */
  if (strncmp(decoder_type_name, "zf", 16) == 0) {
    srslte_predecoding_set_mimo_decoder(SRSLTE_MIMO_DECODER_ZF);
  } else if (strncmp(decoder_type_name, "mmse", 16) == 0) {
    srslte_predecoding_set_mimo_decoder(SRSLTE_MIMO_DECODER_MMSE);
  } else {
    ret = SRSLTE_ERROR;
    goto quit;
  }


  /* predecoding / equalization */
  struct timeval t[3];
  gettimeofday(&t[1], NULL);
  srslte_predecoding_type(r, h, xr, NULL, nof_rx_ports, nof_tx_ports, nof_layers,
                          codebook_idx, nof_re, type, scaling, powf(10, -snr_db / 10));
  gettimeofday(&t[2], NULL);
  get_time_interval(t);

  /* check errors */
  mse = 0;
  for (i = 0; i < nof_layers; i++) {
    for (j = 0; j < nof_symbols; j++) {
      mse += cabsf(xr[i][j] - x[i][j]);

      if ((crealf(xr[i][j]) > 0) != (crealf(x[i][j]) > 0)) {
        nof_errors ++;
      }
      if ((cimagf(xr[i][j]) > 0) != (cimagf(x[i][j]) > 0)) {
        nof_errors ++;
      }
    }
  }
  printf("SNR: %5.1fdB;\tExecution time: %5ldus;\tMSE: %.6f;\tBER: %.6f\n", snr_db, t[0].tv_usec,
         mse / nof_layers / nof_symbols, (float) nof_errors / (4.0f * nof_re));
  if (mse / nof_layers / nof_symbols > MSE_THRESHOLD) {
    ret = SRSLTE_ERROR;
  } 

  quit:
  /* Free all data */
  for (i = 0; i < nof_layers; i++) {
    free(x[i]);
    free(xr[i]);
  }

  for (i = 0; i < nof_rx_ports; i++) {
    free(r[i]);
  }

  for (i = 0; i < nof_rx_ports; i++) {
    for (j = 0; j < nof_tx_ports; j++) {
      free(h[j][i]);
    }
  }

  exit(ret);
}