Пример #1
0
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
                                               srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
                                               uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
  srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
  srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
  uint32_t rv = cfg->rv[tb_idx];
  int ret = SRSLTE_ERROR_INVALID_INPUTS;

  if (softbuffer && data && ack) {
    INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
         cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs,
         nbits->nof_re, nbits->nof_bits, rv);

    /* demodulate symbols
     * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
     * thus we don't need tot set it in the LLRs normalization
     */
    srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], nbits->nof_re);

    /* Select scrambling sequence */
    srslte_sequence_t *seq = get_user_sequence(q, rnti, codeword_idx, cfg->sf_idx, nbits->nof_bits);

    /* Bit scrambling */
    srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits);

    /* Return  */
    ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);

    q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);

    if (ret == SRSLTE_SUCCESS) {
      *ack = true;
    } else if (ret == SRSLTE_ERROR) {
      *ack = false;
      ret = SRSLTE_SUCCESS;
    } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {
      *ack = false;
      ret = SRSLTE_ERROR;
    }
  } else {
    ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack);
  }

  return ret;
}
Пример #2
0
/** Decodes the pmch from the received symbols
 */
int srslte_pmch_decode_multi(srslte_pmch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
                             cf_t *sf_symbols[SRSLTE_MAX_PORTS], cf_t *ce[SRSLTE_MAX_PORTS][SRSLTE_MAX_PORTS], float noise_estimate,
                             uint16_t area_id, uint8_t *data)
{

  /* Set pointers for layermapping & precoding */
  uint32_t i, n;
  cf_t *x[SRSLTE_MAX_LAYERS];
  
  if (q            != NULL &&
      sf_symbols   != NULL &&
      data         != NULL && 
      cfg          != NULL)
  {
    
    INFO("Decoding PMCH SF: %d, MBSFN area ID: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, C_prb=%d, cfi=%d\n",
        cfg->sf_idx, area_id, srslte_mod_string(cfg->grant.mcs[0].mod), cfg->grant.mcs[0].tbs, cfg->nbits[0].nof_re,
         cfg->nbits[0].nof_bits, 0, cfg->grant.nof_prb, cfg->nbits[0].lstart-1);

    /* number of layers equals number of ports */
    for (i = 0; i < q->cell.nof_ports; i++) {
      x[i] = q->x[i];
    }
    memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));
     
    for (int j=0;j<q->nof_rx_antennas;j++) {
      /* extract symbols */
      n = srslte_pmch_get(q, sf_symbols[j], q->symbols[j], cfg->nbits[0].lstart);
      if (n != cfg->nbits[0].nof_re) {
        fprintf(stderr, "PMCH 1 extract symbols error expecting %d symbols but got %d, lstart %d\n", cfg->nbits[0].nof_re, n, cfg->nbits[0].lstart);
        return SRSLTE_ERROR;
      }
      
      /* extract channel estimates */
      for (i = 0; i < q->cell.nof_ports; i++) {
        n = srslte_pmch_get(q, ce[i][j], q->ce[i][j], cfg->nbits[0].lstart);
        if (n != cfg->nbits[0].nof_re) {
          fprintf(stderr, "PMCH 2 extract chest error expecting %d symbols but got %d\n", cfg->nbits[0].nof_re, n);
          return SRSLTE_ERROR;
        }
      }      
    }
     
    // No tx diversity in MBSFN
    srslte_predecoding_single_multi(q->symbols, q->ce[0], q->d, NULL, q->nof_rx_antennas, cfg->nbits[0].nof_re, 1.0f, noise_estimate);
    
    if (SRSLTE_VERBOSE_ISDEBUG()) {
      DEBUG("SAVED FILE subframe.dat: received subframe symbols\n");
      srslte_vec_save_file("subframe.dat", sf_symbols, SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t));
      DEBUG("SAVED FILE hest0.dat: channel estimates for port 4\n");
      srslte_vec_save_file("hest0.dat", ce[0], SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)*sizeof(cf_t));
      DEBUG("SAVED FILE pmch_symbols.dat: symbols after equalization\n");
      srslte_vec_save_file("pmch_symbols.bin", q->d, cfg->nbits[0].nof_re*sizeof(cf_t));
    }
    
    /* demodulate symbols 
    * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, 
    * thus we don't need tot set it in thde LLRs normalization
    */
    srslte_demod_soft_demodulate_s(cfg->grant.mcs[0].mod, q->d, q->e, cfg->nbits[0].nof_re);
    
    /* descramble */
    srslte_scrambling_s_offset(&q->seqs[area_id]->seq[cfg->sf_idx], q->e, 0, cfg->nbits[0].nof_bits);
  
    if (SRSLTE_VERBOSE_ISDEBUG()) {
      DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n");
      srslte_vec_save_file("llr.dat", q->e, cfg->nbits[0].nof_bits*sizeof(int16_t));
    }
    return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Пример #3
0
/** Decodes the PDSCH from the received symbols
 */
int srslte_pdsch_decode_rnti(srslte_pdsch_t *q,
                             srslte_pdsch_cfg_t *cfg, srslte_softbuffer_rx_t *softbuffer,
                             cf_t *sf_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
                             uint16_t rnti, uint8_t *data)
{

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

    if (q            != NULL &&
            sf_symbols   != NULL &&
            data         != NULL &&
            cfg          != NULL)
    {

        INFO("Decoding PDSCH SF: %d, RNTI: 0x%x, Mod %s, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d, C_prb=%d\n",
             cfg->sf_idx, rnti, srslte_mod_string(cfg->grant.mcs.mod), cfg->grant.mcs.tbs, cfg->nbits.nof_re,
             cfg->nbits.nof_bits, cfg->rv, cfg->grant.nof_prb);

        /* number of layers equals number of ports */
        for (i = 0; i < q->cell.nof_ports; i++) {
            x[i] = q->x[i];
        }
        memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (SRSLTE_MAX_LAYERS - q->cell.nof_ports));

        /* extract symbols */
        n = srslte_pdsch_get(q, sf_symbols, q->symbols[0], &cfg->grant, cfg->nbits.lstart, cfg->sf_idx);
        if (n != cfg->nbits.nof_re) {
            fprintf(stderr, "Error expecting %d symbols but got %d\n", cfg->nbits.nof_re, n);
            return SRSLTE_ERROR;
        }

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

        /* TODO: only diversity is supported */
        if (q->cell.nof_ports == 1) {
            /* no need for layer demapping */
            srslte_predecoding_single(q->symbols[0], q->ce[0], q->d, cfg->nbits.nof_re, noise_estimate);
        } else {
            srslte_predecoding_diversity(&q->precoding, q->symbols[0], q->ce, x, q->cell.nof_ports,
                                         cfg->nbits.nof_re, noise_estimate);
            srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
                                        cfg->nbits.nof_re / q->cell.nof_ports);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE pdsch_symbols.dat: symbols after equalization\n",0);
            srslte_vec_save_file("pdsch_symbols.dat", q->d, cfg->nbits.nof_re*sizeof(cf_t));
        }

        /* demodulate symbols
        * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
        * thus we don't need tot set it in the LLRs normalization
        */
        srslte_demod_soft_demodulate_s(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re);

        /* descramble */
        if (rnti != q->rnti) {
            srslte_sequence_t seq;
            if (srslte_sequence_pdsch(&seq, rnti, 0, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
                return SRSLTE_ERROR;
            }
            srslte_scrambling_s_offset(&seq, q->e, 0, cfg->nbits.nof_bits);
            srslte_sequence_free(&seq);
        } else {
            srslte_scrambling_s_offset(&q->seq[cfg->sf_idx], q->e, 0, cfg->nbits.nof_bits);
        }

        if (SRSLTE_VERBOSE_ISDEBUG()) {
            DEBUG("SAVED FILE llr.dat: LLR estimates after demodulation and descrambling\n",0);
            srslte_vec_save_file("llr.dat", q->e, cfg->nbits.nof_bits*sizeof(int16_t));
        }

        return srslte_dlsch_decode(&q->dl_sch, cfg, softbuffer, q->e, data);

    } else {
        return SRSLTE_ERROR_INVALID_INPUTS;
    }
}
Пример #4
0
static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg,
                                               srslte_softbuffer_rx_t *softbuffer, uint16_t rnti, uint8_t *data,
                                               uint32_t codeword_idx, uint32_t tb_idx, bool *ack) {
  srslte_ra_nbits_t *nbits = &cfg->nbits[tb_idx];
  srslte_ra_mcs_t *mcs = &cfg->grant.mcs[tb_idx];
  uint32_t rv = cfg->rv[tb_idx];
  int ret = SRSLTE_ERROR_INVALID_INPUTS;

  if (softbuffer && data && ack) {
    INFO("Decoding PDSCH SF: %d (CW%d -> TB%d), Mod %s, NofBits: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n",
         cfg->sf_idx, codeword_idx, tb_idx, srslte_mod_string(mcs->mod), mcs->tbs,
         nbits->nof_re, nbits->nof_bits, rv);

    /* demodulate symbols
     * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation,
     * thus we don't need tot set it in the LLRs normalization
     */
    srslte_demod_soft_demodulate_s(mcs->mod, q->d[codeword_idx], q->e[codeword_idx], nbits->nof_re);

    /* Select scrambling sequence */
    srslte_sequence_t *seq = get_user_sequence(q, rnti, codeword_idx, cfg->sf_idx, nbits->nof_bits);

    /* Bit scrambling */
    srslte_scrambling_s_offset(seq, q->e[codeword_idx], 0, nbits->nof_bits);

    uint32_t qm = nbits->nof_bits/nbits->nof_re;
    switch(cfg->grant.mcs[tb_idx].mod) {

      case SRSLTE_MOD_BPSK:
        qm = 1;
        break;
      case SRSLTE_MOD_QPSK:
        qm = 2;
        break;
      case SRSLTE_MOD_16QAM:
        qm = 4;
        break;
      case SRSLTE_MOD_64QAM:
        qm = 6;
        break;
      default:
        ERROR("No modulation");
    }

    int16_t *e = q->e[codeword_idx];

    if (q->csi_enabled) {
      const uint32_t csi_max_idx = srslte_vec_max_fi(q->csi[codeword_idx], nbits->nof_bits / qm);
      float csi_max = 1.0f;
      if (csi_max_idx < nbits->nof_bits / qm) {
        csi_max = q->csi[codeword_idx][csi_max_idx];
      }
      for (int i = 0; i < nbits->nof_bits / qm; i++) {
        const float csi = q->csi[codeword_idx][i] / csi_max;
        for (int k = 0; k < qm; k++) {
          e[qm * i + k] = (int16_t) ((float) e[qm * i + k] * csi);
        }
      }
    }

    /* Return  */
    ret = srslte_dlsch_decode2(&q->dl_sch, cfg, softbuffer, q->e[codeword_idx], data, tb_idx);

    q->last_nof_iterations[codeword_idx] = srslte_sch_last_noi(&q->dl_sch);

    if (ret == SRSLTE_SUCCESS) {
      *ack = true;
    } else if (ret == SRSLTE_ERROR) {
      *ack = false;
      ret = SRSLTE_SUCCESS;
    } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) {
      *ack = false;
      ret = SRSLTE_ERROR;
    }
  } else {
    ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack);
  }

  return ret;
}