示例#1
0
文件: pdsch.c 项目: mfkiwl/srsLTE
/** Decodes the PDSCH from the received symbols
 */
int srslte_pdsch_decode(srslte_pdsch_t *q,
                        srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS],
                        cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS],
                        float noise_estimate, uint16_t rnti, uint8_t *data[SRSLTE_MAX_CODEWORDS],
                        bool acks[SRSLTE_MAX_CODEWORDS])
{

  /* Set pointers for layermapping & precoding */
  uint32_t i;
  cf_t *x[SRSLTE_MAX_LAYERS];

  if (q            != NULL &&
      sf_symbols   != NULL &&
      data         != NULL &&
      cfg          != NULL)
  {
    uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(&cfg->grant);

    INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, NofSymbols: %d, C_prb=%d, mimo_type=%s, nof_layers=%d, nof_tb=%d\n",
        cfg->sf_idx, rnti, cfg->nbits[0].nof_re, cfg->grant.nof_prb, srslte_mod_string(cfg->grant.mcs->mod), cfg->nof_layers, nof_tb);

    // Extract Symbols and Channel Estimates
    for (int j=0;j<q->nof_rx_antennas;j++) {
      int n = srslte_pdsch_get(q, sf_symbols[j], q->symbols[j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
      if (n != cfg->nbits[0].nof_re) {
        fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
        return SRSLTE_ERROR;
      }

      for (i = 0; i < q->cell.nof_ports; i++) {
        n = srslte_pdsch_get(q, ce[i][j], q->ce[i][j], &cfg->grant, cfg->nbits[0].lstart, cfg->sf_idx);
        if (n != cfg->nbits[0].nof_re) {
          fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
          return SRSLTE_ERROR;
        }
      }
    }

    // Prepare layers
    int nof_symbols [SRSLTE_MAX_CODEWORDS];
    nof_symbols[0] = cfg->nbits[0].nof_re * nof_tb / cfg->nof_layers;
    nof_symbols[1] = cfg->nbits[1].nof_re * nof_tb / cfg->nof_layers;

    if (cfg->nof_layers == nof_tb) {
      /* Skip layer demap */
      for (i = 0; i < cfg->nof_layers; i++) {
        x[i] = q->d[i];
      }
    } else {
      /* number of layers equals number of ports */
      for (i = 0; i < cfg->nof_layers; i++) {
        x[i] = q->x[i];
      }
      memset(&x[cfg->nof_layers], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - cfg->nof_layers));
    }

    float pdsch_scaling = 1.0f;
    if (q->rho_a != 0.0f) {
      pdsch_scaling = q->rho_a;
    }

    // Pre-decoder
    if (srslte_predecoding_type(q->symbols, q->ce, x, q->nof_rx_antennas, q->cell.nof_ports, cfg->nof_layers,
                                      cfg->codebook_idx, cfg->nbits[0].nof_re, cfg->mimo_type, pdsch_scaling, noise_estimate)<0) {
      DEBUG("Error predecoding\n");
      return SRSLTE_ERROR;
    }

    // Layer demapping only if necessary
    if (cfg->nof_layers != nof_tb) {
        srslte_layerdemap_type(x, q->d, cfg->nof_layers, nof_tb,
                             nof_symbols[0], nof_symbols, cfg->mimo_type);
    }

    /* Codeword decoding: Implementation of 3GPP 36.212 Table 5.3.3.1.5-1 and Table 5.3.3.1.5-2 */
    uint32_t cw_idx = (nof_tb == SRSLTE_MAX_TB && cfg->tb_cw_swap) ? 1 : 0;
    for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
      /* Decode only if transport block is enabled and the default ACK is not true */
      if (cfg->grant.tb_en[tb_idx]) {
        if (!acks[tb_idx]) {
          int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb_idx], rnti, data[tb_idx], cw_idx, tb_idx, &acks[tb_idx]);

          /* Check if there has been any execution error */
          if (ret) {
            return ret;
          }
        }

        cw_idx = (cw_idx + 1) % SRSLTE_MAX_CODEWORDS;
      }
    }

    pdsch_decode_debug(q, cfg, sf_symbols, ce);

    return SRSLTE_SUCCESS;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
示例#2
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); 
}
示例#3
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);
}