Пример #1
0
int main(int argc, char **argv) {
  int i;
  srslte_modem_table_t mod;
  uint8_t *input, *input_bytes, *output;
  cf_t *symbols, *symbols_bytes;
  float *llr, *llr2;

  parse_args(argc, argv);

  /* initialize objects */
  if (srslte_modem_table_lte(&mod, modulation)) {
    fprintf(stderr, "Error initializing modem table\n");
    exit(-1);
  }
  
  srslte_modem_table_bytes(&mod);

  /* check that num_bits is multiple of num_bits x symbol */
  if (num_bits % mod.nbits_x_symbol) {
    fprintf(stderr, "Error num_bits must be multiple of %d\n", mod.nbits_x_symbol);
    exit(-1);
  }

  /* allocate buffers */
  input = srslte_vec_malloc(sizeof(uint8_t) * num_bits);
  if (!input) {
    perror("malloc");
    exit(-1);
  }
  input_bytes = srslte_vec_malloc(sizeof(uint8_t) * num_bits/8);
  if (!input_bytes) {
    perror("malloc");
    exit(-1);
  }
  output = srslte_vec_malloc(sizeof(uint8_t) * num_bits);
  if (!output) {
    perror("malloc");
    exit(-1);
  }
  symbols = srslte_vec_malloc(sizeof(cf_t) * num_bits / mod.nbits_x_symbol);
  if (!symbols) {
    perror("malloc");
    exit(-1);
  }
  symbols_bytes = srslte_vec_malloc(sizeof(cf_t) * num_bits / mod.nbits_x_symbol);
  if (!symbols_bytes) {
    perror("malloc");
    exit(-1);
  }

  llr = srslte_vec_malloc(sizeof(float) * num_bits);
  if (!llr) {
    perror("malloc");
    exit(-1);
  }

  llr2 = srslte_vec_malloc(sizeof(float) * num_bits);
  if (!llr2) {
    perror("malloc");
    exit(-1);
  }

  /* generate random data */
  for (i=0;i<num_bits;i++) {
    input[i] = rand()%2;
  }

  /* modulate */
  struct timeval t[3];
  gettimeofday(&t[1], NULL);
  int ntrials = 100; 
  for (int i=0;i<ntrials;i++) {
    srslte_mod_modulate(&mod, input, symbols, num_bits);
  }
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  
  printf("Bit: %d us\n", t[0].tv_usec);
  
  /* Test packed implementation */
  srslte_bit_pack_vector(input, input_bytes, num_bits);
  gettimeofday(&t[1], NULL);
  for (int i=0;i<ntrials;i++) {
    srslte_mod_modulate_bytes(&mod, input_bytes, symbols_bytes, num_bits);
  }
  gettimeofday(&t[2], NULL);
  get_time_interval(t);
  
  printf("Byte: %d us\n", t[0].tv_usec);
  
  for (int i=0;i<num_bits/mod.nbits_x_symbol;i++) {
    if (symbols[i] != symbols_bytes[i]) {
      printf("error in symbol %d\n", i);
      exit(-1);
    }
  }
  printf("Symbols OK\n");  
  /* demodulate */
  gettimeofday(&x, NULL);
  srslte_demod_soft_demodulate(modulation, symbols, llr, num_bits / mod.nbits_x_symbol);
  gettimeofday(&y, NULL);
  printf("\nElapsed time [ns]: %d\n", (int) y.tv_usec - (int) x.tv_usec);
  
  for (i=0;i<num_bits;i++) {
    output[i] = llr[i]>=0 ? 1 : 0;
  }

  /* check errors */
  for (i=0;i<num_bits;i++) {
    if (input[i] != output[i]) {
      fprintf(stderr, "Error in bit %d\n", i);
      exit(-1);
    }
  }

  free(llr);
  free(symbols);
  free(symbols_bytes);
  free(output);
  free(input);
  free(input_bytes);

  srslte_modem_table_free(&mod);

  printf("Ok\n");
  exit(0);
}
Пример #2
0
/* Decodes the PCFICH channel and saves the CFI in the cfi pointer.
 *
 * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error
 */
int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
    uint32_t nsubframe, uint32_t *cfi, float *corr_result) 
{

  /* Set pointers for layermapping & precoding */
  int i;
  cf_t *x[SRSLTE_MAX_LAYERS];
  cf_t *ce_precoding[SRSLTE_MAX_PORTS];

  if (q                 != NULL                 && 
      slot_symbols      != NULL                 && 
      nsubframe         <  SRSLTE_NSUBFRAMES_X_FRAME) 
  {

    /* number of layers equals number of ports */
    for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
      x[i] = q->x[i];
    }
    for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
      ce_precoding[i] = q->ce[i];
    }

    /* extract symbols */
    if (q->nof_symbols
        != srslte_regs_pcfich_get(q->regs, slot_symbols, q->symbols[0])) {
      fprintf(stderr, "There was an error getting the PCFICH symbols\n");
      return SRSLTE_ERROR;
    }

    /* extract channel estimates */
    for (i = 0; i < q->cell.nof_ports; i++) {
      if (q->nof_symbols != srslte_regs_pcfich_get(q->regs, ce[i], q->ce[i])) {
        fprintf(stderr, "There was an error getting the PCFICH symbols\n");
        return SRSLTE_ERROR;
      }
    }

    /* in control channels, 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, q->nof_symbols, noise_estimate);
    } else {
      srslte_predecoding_diversity(q->symbols[0], ce_precoding, x,
          q->cell.nof_ports, q->nof_symbols);
      srslte_layerdemap_diversity(x, q->d, q->cell.nof_ports,
          q->nof_symbols / q->cell.nof_ports);
    }

    /* demodulate symbols */
    srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->data_f, q->nof_symbols);

    /* Scramble with the sequence for slot nslot */
    srslte_scrambling_f(&q->seq[nsubframe], q->data_f);

    /* decode CFI */
    float corr = srslte_pcfich_cfi_decode(q, cfi);
    if (corr_result) {
      *corr_result = corr;
    }
    return 1;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
  
}
Пример #3
0
/* Decodes the phich channel and saves the CFI in the cfi pointer.
 *
 * Returns 1 if successfully decoded the CFI, 0 if not and -1 on error
 */
int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_MAX_PORTS], float noise_estimate,
    uint32_t ngroup, uint32_t nseq, uint32_t subframe, uint8_t *ack, float *distance) {

  /* Set pointers for layermapping & precoding */
  int i, j;
  cf_t *x[SRSLTE_MAX_LAYERS];
  cf_t *ce_precoding[SRSLTE_MAX_PORTS];
  
  if (q == NULL || slot_symbols == NULL) {
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (subframe >= SRSLTE_NSUBFRAMES_X_FRAME) {
    fprintf(stderr, "Invalid nslot %d\n", subframe);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (nseq >= SRSLTE_PHICH_EXT_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  } else {
    if (nseq >= SRSLTE_PHICH_NORM_NSEQUENCES) {
      fprintf(stderr, "Invalid nseq %d\n", nseq);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
  }
  if (ngroup >= srslte_regs_phich_ngroups(q->regs)) {
    fprintf(stderr, "Invalid ngroup %d\n", ngroup);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }

  DEBUG("Decoding PHICH Ngroup: %d, Nseq: %d\n", ngroup, nseq);

  /* number of layers equals number of ports */
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    x[i] = q->x[i];
  }
  for (i = 0; i < SRSLTE_MAX_PORTS; i++) {
    ce_precoding[i] = q->ce[i];
  }

  /* extract symbols */
  if (SRSLTE_PHICH_MAX_NSYMB
      != srslte_regs_phich_get(q->regs, slot_symbols, q->symbols[0], ngroup)) {
    fprintf(stderr, "There was an error getting the phich symbols\n");
    return SRSLTE_ERROR;
  }

  /* extract channel estimates */
  for (i = 0; i < q->cell.nof_ports; i++) {
    if (SRSLTE_PHICH_MAX_NSYMB != srslte_regs_phich_get(q->regs, ce[i], q->ce[i], ngroup)) {
      fprintf(stderr, "There was an error getting the phich symbols\n");
      return SRSLTE_ERROR;
    }
  }

  /* in control channels, 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->d0, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
  } else {
    srslte_predecoding_diversity(&q->precoding, q->symbols[0], ce_precoding, x,
        q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB, noise_estimate);
    srslte_layerdemap_diversity(x, q->d0, q->cell.nof_ports,
    SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports);
  }
  DEBUG("Recv!!: \n", 0);
  DEBUG("d0: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB);

  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    if (ngroup % 2) {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i + 2];
        q->d[2 * i + 1] = q->d0[4 * i + 3];
      }
    } else {
      for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) {
        q->d[2 * i + 0] = q->d0[4 * i];
        q->d[2 * i + 1] = q->d0[4 * i + 1];
      }
    }
  } else {
    memcpy(q->d, q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t));
  }

  DEBUG("d: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->d, SRSLTE_PHICH_EXT_MSYMB);

  srslte_scrambling_c(&q->seq[subframe], q->d);

  /* De-spreading */
  if (SRSLTE_CP_ISEXT(q->cell.cp)) {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_EXT_NSF; j++) {
        q->z[i] += conjf(w_ext[nseq][j])
            * q->d[i * SRSLTE_PHICH_EXT_NSF + j] / SRSLTE_PHICH_EXT_NSF;
      }
    }
  } else {
    for (i = 0; i < SRSLTE_PHICH_NBITS; i++) {
      q->z[i] = 0;
      for (j = 0; j < SRSLTE_PHICH_NORM_NSF; j++) {
        q->z[i] += conjf(w_normal[nseq][j])
            * q->d[i * SRSLTE_PHICH_NORM_NSF + j] / SRSLTE_PHICH_NORM_NSF;
      }
    }
  }

  DEBUG("z: ", 0);
  if (SRSLTE_VERBOSE_ISDEBUG())
    srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS);

  srslte_demod_soft_demodulate(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS);

  if (ack) {
    *ack = srslte_phich_ack_decode(q->data_rx, distance);    
  }

  return SRSLTE_SUCCESS;
}