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); }
/** Converts the MIB message to symbols mapped to SLOT #1 ready for transmission */ int pbch_encode(pbch_t *q, pbch_mib_t *mib, cf_t *slot1_symbols[MAX_PORTS]) { int i; int nof_bits; cf_t *x[MAX_LAYERS]; if (q != NULL && mib != NULL) { for (i=0;i<q->cell.nof_ports;i++) { if (slot1_symbols[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 < q->cell.nof_ports; i++) { x[i] = q->pbch_x[i]; } memset(&x[q->cell.nof_ports], 0, sizeof(cf_t*) * (MAX_LAYERS - q->cell.nof_ports)); if (q->frame_idx == 0) { /* pack MIB */ pbch_mib_pack(mib, q->data); /* encode & modulate */ crc_attach(&q->crc, q->data, 24); crc_set_mask(q->data, q->cell.nof_ports); convcoder_encode(&q->encoder, q->data, q->data_enc, 40); rm_conv_tx(q->data_enc, 120, q->pbch_rm_b, 4 * nof_bits); } scrambling_b_offset(&q->seq_pbch, &q->pbch_rm_b[q->frame_idx * nof_bits], q->frame_idx * nof_bits, nof_bits); mod_modulate(&q->mod, &q->pbch_rm_b[q->frame_idx * nof_bits], q->pbch_d, nof_bits); /* layer mapping & precoding */ if (q->cell.nof_ports > 1) { layermap_diversity(q->pbch_d, x, q->cell.nof_ports, q->nof_symbols); precoding_diversity(x, q->pbch_symbols, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); } else { memcpy(q->pbch_symbols[0], q->pbch_d, q->nof_symbols * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { pbch_put(q->pbch_symbols[i], slot1_symbols[i], q->cell); } q->frame_idx++; if (q->frame_idx == 4) { q->frame_idx = 0; } return LIBLTE_SUCCESS; } else { return LIBLTE_ERROR_INVALID_INPUTS; } }
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); }