Example #1
0
int main(int argc, char **argv) {
	viterbi_t dec;
	convcoder_t cod;
	modem_table_t modem;
	demod_soft_t demod;
	int frame_cnt;
	float *llr;
	char *data_tx, *data_rx, *symbols;
	cf_t *iq;
	int i;

	parse_args(argc,argv);

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

	int coded_length = 3 * (frame_length + ((tail_biting)?0:6));

	printf("Convolutional Code 1/3 K=7 Test\n");
	printf("  Frame length: %d\n", frame_length);
	printf("  Codeword length: %d\n", coded_length);
	printf("  Tail bitting: %s\n", tail_biting?"yes":"no");
	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);
	}

	iq = malloc(coded_length * sizeof(cf_t));
	if (!iq) {
		perror("malloc");
		exit(-1);
	}

	cod.K = 7;
	cod.R = 3;
	cod.tail_biting = tail_biting;
	cod.framelength = frame_length;
	cod.poly[0] = 0x6D;
	cod.poly[1] = 0x4F;
	cod.poly[2] = 0x57;

	float var = sqrt(pow(10,-ebno_db/10));

	modem_table_init(&modem);
	modem_table_std(&modem, LTE_QPSK, true);
	demod_soft_init(&demod);
	demod_soft_table_set(&demod, &modem);
	demod_soft_alg_set(&demod, APPROX);
	demod_soft_sigma_set(&demod, var);

	viterbi_init(&dec, viterbi_37, cod.poly, frame_length, tail_biting);

	/* read all file or nof_frames */
	frame_cnt = 0;
	unsigned int errors=0;
	while (frame_cnt < nof_slots) {

		/* generate data_tx */
		for (i=0;i<frame_length;i++) {
			data_tx[i] = message[i];
		}

		convcoder_encode(&cod, data_tx, symbols);

		bit_fprint(stdout, symbols, 120);

		mod_modulate(&modem, symbols, iq, coded_length);

		if (ebno_db < 100.0) {
			ch_awgn(iq, iq, var, coded_length/2);
		}

		demod_soft_demodulate(&demod, iq, llr, coded_length/2);

		viterbi_decode(&dec, llr, data_rx);

		errors += bit_diff(data_tx, data_rx, frame_length);
		frame_cnt++;
	}

	printf("BER:\t%g\t%u errors\n", (float) errors/(frame_cnt*frame_length), errors);

	viterbi_free(&dec);

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

	printf("Done\n");
	exit(0);
}
Example #2
0
/* Decodes the PBCH channel
 *
 * The PBCH spans in 40 ms. This function is called every 10 ms. It tries to decode the MIB
 * given the symbols of a subframe (1 ms). Successive calls will use more subframes
 * to help the decoding process.
 *
 * Returns 1 if successfully decoded MIB, 0 if not and -1 on error
 */
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[MAX_PORTS], pbch_mib_t *mib) {
  uint32_t src, dst, nb;
  uint32_t nant_[3] = { 1, 2, 4 };
  uint32_t na, nant;
  int i;
  int nof_bits;
  cf_t *x[MAX_LAYERS];
  
  int ret = LIBLTE_ERROR_INVALID_INPUTS;
  
  if (q                 != NULL &&
      slot1_symbols        != NULL && 
      mib               != NULL)
  {
    for (i=0;i<q->cell.nof_ports;i++) {
      if (ce_slot1[i] == NULL) {
        return LIBLTE_ERROR_INVALID_INPUTS;
      } 
    }

    /* Set pointers for layermapping & precoding */
    nof_bits = 2 * q->nof_symbols;

    /* number of layers equals number of ports */
    for (i = 0; i < MAX_PORTS; i++) {
      x[i] = q->pbch_x[i];
    }
    memset(&x[MAX_PORTS], 0, sizeof(cf_t*) * (MAX_LAYERS - MAX_PORTS));
    
    /* extract symbols */
    if (q->nof_symbols != pbch_get(slot1_symbols, q->pbch_symbols[0], q->cell)) {
      fprintf(stderr, "There was an error getting the PBCH symbols\n");
      return LIBLTE_ERROR;
    }

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

    q->frame_idx++;
    ret = 0;

    /* Try decoding for 1 to cell.nof_ports antennas */
    for (na = 0; na < q->cell.nof_ports && !ret; na++) {
      nant = nant_[na];

      DEBUG("Trying %d TX antennas with %d frames\n", nant, q->frame_idx);

      /* in conctrol channels, only diversity is supported */
      if (nant == 1) {
        /* no need for layer demapping */
        predecoding_single_zf(q->pbch_symbols[0], q->ce[0], q->pbch_d,
            q->nof_symbols);
      } else {
        predecoding_diversity_zf(q->pbch_symbols[0], q->ce, x, nant,
            q->nof_symbols);
        layerdemap_diversity(x, q->pbch_d, nant, q->nof_symbols / nant);
      }

      /* demodulate symbols */
      demod_soft_sigma_set(&q->demod, 1.0);
      demod_soft_demodulate(&q->demod, q->pbch_d,
          &q->pbch_llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols);

      /* We don't know where the 40 ms begin, so we try all combinations. E.g. if we received
      * 4 frames, try 1,2,3,4 individually, 12, 23, 34 in pairs, 123, 234 and finally 1234.
      * We know they are ordered.
      *
      * FIXME: There are unnecessary checks because 2,3,4 have already been processed in the previous
      * calls.
      */
      for (nb = 0; nb < q->frame_idx && !ret; nb++) {
        for (dst = 0; (dst < 4 - nb) && !ret; dst++) {
          for (src = 0; src < q->frame_idx - nb && !ret; src++) {
            ret = pbch_decode_frame(q, mib, src, dst, nb + 1, nof_bits, nant);
            
          }
        }
      }
    }

    /* If not found, make room for the next packet of radio frame symbols */
    if (q->frame_idx == 4) {
      memmove(q->pbch_llr, &q->pbch_llr[nof_bits], nof_bits * 3 * sizeof(float));
      q->frame_idx = 3;
    }
  }
  return ret;
}
Example #3
0
int main(int argc, char **argv) {
  int i;
  modem_table_t mod;
  demod_soft_t demod_soft;
  char *input, *output;
  cf_t *symbols;
  float *llr_exact, *llr_approx;

  parse_args(argc, argv);

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

  /* check that num_bits is multiple of num_bits x symbol */
  num_bits = mod.nbits_x_symbol * (num_bits / mod.nbits_x_symbol);

  demod_soft_init(&demod_soft);
  demod_soft_table_set(&demod_soft, &mod);
  demod_soft_sigma_set(&demod_soft, 2.0 / mod.nbits_x_symbol);


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

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

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

  /* generate random data */
  srand(0);
  
  int ret = -1;
  double mse;
  struct timeval t[3]; 
  float mean_texec = 0.0; 
  for (int n=0;n<nof_frames;n++) {
    for (i=0;i<num_bits;i++) {
      input[i] = rand()%2;
    }

    /* modulate */
    mod_modulate(&mod, input, symbols, num_bits);

    /* add noise */
    ch_awgn_c(symbols, symbols, ch_awgn_get_variance(5.0, mod.nbits_x_symbol), num_bits / mod.nbits_x_symbol);
    
    /* Compare exact with approximation algorithms */
    demod_soft_alg_set(&demod_soft, EXACT);
    demod_soft_demodulate(&demod_soft, symbols, llr_exact, num_bits / mod.nbits_x_symbol);
    
    demod_soft_alg_set(&demod_soft, APPROX);
    gettimeofday(&t[1], NULL);
    demod_soft_demodulate(&demod_soft, symbols, llr_approx, num_bits / mod.nbits_x_symbol);
    gettimeofday(&t[2], NULL);
    get_time_interval(t);
    
    /* compute exponentially averaged execution time */
    if (n > 0) {
      mean_texec = EXPAVERAGE((float) t[0].tv_usec, mean_texec, n-1);      
    }
    
    /* check MSE */
    mse = 0.0;
    for (i=0;i<num_bits;i++) {
      float e = llr_exact[i] - llr_approx[i];
      mse += e*e;
    }
    mse/=num_bits;

    if (VERBOSE_ISDEBUG()) {
      printf("exact=");
      vec_fprint_f(stdout, llr_exact, num_bits);

      printf("approx=");
      vec_fprint_f(stdout, llr_approx, num_bits);
    }
    
    if (mse > mse_threshold()) {
        goto clean_exit; 
    }
  }
  ret = 0; 

clean_exit:  
  free(llr_exact);
  free(llr_approx);
  free(symbols);
  free(output);
  free(input);

  modem_table_free(&mod);

  if (ret == 0) {
    printf("Ok Mean Throughput: %.2f. Mbps ExTime: %.2f us\n", num_bits/mean_texec, mean_texec);    
  } else {
    printf("Error: MSE too large (%f > %f)\n", mse, mse_threshold());
  }
  exit(ret);
}