int main(int argc, char **argv) { int frame_cnt; float *llr; uint16_t *llr_s; uint8_t *llr_c; uint8_t *data_tx, *data_rx, *data_rx2, *symbols; int i, j; float var[SNR_POINTS], varunc[SNR_POINTS]; int snr_points; uint32_t errors; #ifdef TEST_SSE uint32_t errors2; srslte_viterbi_t dec_sse; #endif srslte_viterbi_t dec; srslte_convcoder_t cod; int coded_length; parse_args(argc, argv); if (!seed) { seed = time(NULL); } srand(seed); cod.poly[0] = 0x6D; cod.poly[1] = 0x4F; cod.poly[2] = 0x57; cod.K = 7; cod.tail_biting = tail_biting; cod.R = 3; coded_length = cod.R * (frame_length + ((cod.tail_biting) ? 0 : cod.K - 1)); srslte_viterbi_init(&dec, SRSLTE_VITERBI_37, cod.poly, frame_length, cod.tail_biting); printf("Convolutional Code 1/3 K=%d Tail bitting: %s\n", cod.K, cod.tail_biting ? "yes" : "no"); #ifdef TEST_SSE srslte_viterbi_init_sse(&dec_sse, SRSLTE_VITERBI_37, cod.poly, frame_length, cod.tail_biting); #endif printf(" Frame length: %d\n", frame_length); if (ebno_db < 100.0) { printf(" EbNo: %.2f\n", ebno_db); } data_tx = malloc(frame_length * sizeof(uint8_t)); if (!data_tx) { perror("malloc"); exit(-1); } data_rx = malloc(frame_length * sizeof(uint8_t)); if (!data_rx) { perror("malloc"); exit(-1); } data_rx2 = malloc(frame_length * sizeof(uint8_t)); if (!data_rx2) { perror("malloc"); exit(-1); } symbols = malloc(coded_length * sizeof(uint8_t)); if (!symbols) { perror("malloc"); exit(-1); } llr = malloc(coded_length * sizeof(float)); if (!llr) { perror("malloc"); exit(-1); } llr_s = malloc(2 * coded_length * sizeof(uint16_t)); if (!llr_s) { perror("malloc"); exit(-1); } llr_c = malloc(2 * coded_length * sizeof(uint8_t)); if (!llr_c) { perror("malloc"); exit(-1); } float ebno_inc, esno_db; ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS; if (ebno_db == 100.0) { snr_points = SNR_POINTS; for (i = 0; i < snr_points; i++) { ebno_db = SNR_MIN + i * ebno_inc; esno_db = ebno_db + 10 * log10((double) 1 / 3); var[i] = sqrt(1 / (pow(10, esno_db / 10))); varunc[i] = sqrt(1 / (pow(10, ebno_db / 10))); } } else { esno_db = ebno_db + 10 * log10((double) 1 / 3); var[0] = sqrt(1 / (pow(10, esno_db / 10))); varunc[0] = sqrt(1 / (pow(10, ebno_db / 10))); snr_points = 1; } for (i = 0; i < snr_points; i++) { frame_cnt = 0; errors = 0; #ifdef TEST_SSE errors2 = 0; #endif while (frame_cnt < nof_frames) { /* generate data_tx */ for (j = 0; j < frame_length; j++) { data_tx[j] = rand() % 2; } /* uncoded BER */ for (j = 0; j < frame_length; j++) { llr[j] = data_tx[j] ? sqrt(2) : -sqrt(2); } srslte_ch_awgn_f(llr, llr, varunc[i], frame_length); /* coded BER */ srslte_convcoder_encode(&cod, data_tx, symbols, frame_length); for (j = 0; j < coded_length; j++) { llr[j] = symbols[j] ? sqrt(2) : -sqrt(2); } srslte_ch_awgn_f(llr, llr, var[i], coded_length); //srslte_vec_fprint_f(stdout, llr, 100); srslte_vec_quant_fuc(llr, llr_c, 32, 127.5, 255, coded_length); srslte_vec_quant_fus(llr, llr_s, 8192, 32767.5, 65535, coded_length); struct timeval t[3]; gettimeofday(&t[1], NULL); int M = 1; for (int i=0;i<M;i++) { #ifdef VITERBI_16 srslte_viterbi_decode_us(&dec, llr_s, data_rx, frame_length); #else srslte_viterbi_decode_uc(&dec, llr_c, data_rx, frame_length); #endif } #ifdef TEST_SSE gettimeofday(&t[2], NULL); get_time_interval(t); //printf("Execution time:\t\t%.1f us\n", (float) t[0].tv_usec/M); gettimeofday(&t[1], NULL); for (int i=0;i<M;i++) { srslte_viterbi_decode_uc(&dec_sse, llr_c, data_rx2, frame_length); } gettimeofday(&t[2], NULL); get_time_interval(t); //printf("Execution time SIMD:\t%.1f us\n", (float) t[0].tv_usec/M); #endif /* check errors */ errors += srslte_bit_diff(data_tx, data_rx, frame_length); #ifdef TEST_SSE errors2 += srslte_bit_diff(data_tx, data_rx2, frame_length); #endif frame_cnt++; printf("Eb/No: %3.2f %10d/%d ", SNR_MIN + i * ebno_inc,frame_cnt,nof_frames); printf("BER: %.2e ", (float) errors / (frame_cnt * frame_length)); #ifdef TEST_SSE printf("BER2: %.2e ", (float) errors2 / (frame_cnt * frame_length)); #endif printf("\r"); } printf("\n"); if (snr_points == 1) { printf("BER : %g\t%u errors\n", (float) errors / (frame_cnt * frame_length), errors); #ifdef TEST_SSE printf("BER SSE: %g\t%u errors\n", (float) errors2 / (frame_cnt * frame_length), errors2); #endif } } srslte_viterbi_free(&dec); #ifdef TEST_SSE srslte_viterbi_free(&dec_sse); #endif free(data_tx); free(symbols); free(llr); free(llr_c); free(llr_s); free(data_rx); free(data_rx2); if (snr_points == 1) { int expected_errors = get_expected_errors(nof_frames, seed, frame_length, tail_biting, ebno_db); if (expected_errors == -1) { fprintf(stderr, "Test parameters not defined in test_results.h\n"); exit(-1); } else { printf("errors =%d, expected =%d\n", errors, expected_errors); exit(errors > expected_errors); } } else { printf("\n"); printf("Done\n"); exit(0); } }
int main(int argc, char **argv) { int frame_cnt; float *llr; uint8_t *llr_c; uint8_t *data_tx, *data_rx[NTYPES], *symbols; int i, j; float var[SNR_POINTS], varunc[SNR_POINTS]; int snr_points; float ber[NTYPES][SNR_POINTS]; uint32_t errors[NTYPES]; srslte_viterbi_type_t srslte_viterbi_type[NCODS]; srslte_viterbi_t dec[NCODS]; srslte_convcoder_t cod[NCODS]; int coded_length[NCODS]; int n, ncods, max_coded_length; parse_args(argc, argv); if (!seed) { seed = time(NULL); } srand(seed); switch (K) { case 9: cod[0].poly[0] = 0x1ed; cod[0].poly[1] = 0x19b; cod[0].poly[2] = 0x127; cod[0].tail_biting = false; cod[0].K = 9; srslte_viterbi_type[0] = SRSLTE_VITERBI_39; ncods=1; break; case 7: cod[0].poly[0] = 0x6D; cod[0].poly[1] = 0x4F; cod[0].poly[2] = 0x57; cod[0].K = 7; cod[0].tail_biting = tail_biting; srslte_viterbi_type[0] = SRSLTE_VITERBI_37; ncods=1; break; default: cod[0].poly[0] = 0x1ed; cod[0].poly[1] = 0x19b; cod[0].poly[2] = 0x127; cod[0].tail_biting = false; cod[0].K = 9; srslte_viterbi_type[0] = SRSLTE_VITERBI_39; cod[1].poly[0] = 0x6D; cod[1].poly[1] = 0x4F; cod[1].poly[2] = 0x57; cod[1].tail_biting = false; cod[1].K = 7; srslte_viterbi_type[1] = SRSLTE_VITERBI_37; cod[2].poly[0] = 0x6D; cod[2].poly[1] = 0x4F; cod[2].poly[2] = 0x57; cod[2].tail_biting = true; cod[2].K = 7; srslte_viterbi_type[2] = SRSLTE_VITERBI_37; ncods=3; } max_coded_length = 0; for (i=0; i<ncods; i++) { cod[i].R = 3; coded_length[i] = cod[i].R * (frame_length + ((cod[i].tail_biting) ? 0 : cod[i].K - 1)); if (coded_length[i] > max_coded_length) { max_coded_length = coded_length[i]; } srslte_viterbi_init(&dec[i], srslte_viterbi_type[i], cod[i].poly, frame_length, cod[i].tail_biting); printf("Convolutional Code 1/3 K=%d Tail bitting: %s\n", cod[i].K, cod[i].tail_biting ? "yes" : "no"); } printf(" Frame length: %d\n", frame_length); if (ebno_db < 100.0) { printf(" EbNo: %.2f\n", ebno_db); } data_tx = malloc(frame_length * sizeof(uint8_t)); if (!data_tx) { perror("malloc"); exit(-1); } for (i = 0; i < NTYPES; i++) { data_rx[i] = malloc(frame_length * sizeof(uint8_t)); if (!data_rx[i]) { perror("malloc"); exit(-1); } } symbols = malloc(max_coded_length * sizeof(uint8_t)); if (!symbols) { perror("malloc"); exit(-1); } llr = malloc(max_coded_length * sizeof(float)); if (!llr) { perror("malloc"); exit(-1); } llr_c = malloc(2 * max_coded_length * sizeof(uint8_t)); if (!llr_c) { perror("malloc"); exit(-1); } float ebno_inc, esno_db; ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS; if (ebno_db == 100.0) { snr_points = SNR_POINTS; for (i = 0; i < snr_points; i++) { ebno_db = SNR_MIN + i * ebno_inc; esno_db = ebno_db + 10 * log10((double) 1 / 3); var[i] = sqrt(1 / (pow(10, esno_db / 10))); varunc[i] = sqrt(1 / (pow(10, ebno_db / 10))); } } else { esno_db = ebno_db + 10 * log10((double) 1 / 3); var[0] = sqrt(1 / (pow(10, esno_db / 10))); varunc[0] = sqrt(1 / (pow(10, ebno_db / 10))); snr_points = 1; } float Gain = 32; for (i = 0; i < snr_points; i++) { frame_cnt = 0; for (j = 0; j < NTYPES; j++) { errors[j] = 0; } while (frame_cnt < nof_frames) { /* generate data_tx */ for (j = 0; j < frame_length; j++) { data_tx[j] = rand() % 2; } /* uncoded BER */ for (j = 0; j < frame_length; j++) { llr[j] = data_tx[j] ? sqrt(2) : -sqrt(2); } srslte_ch_awgn_f(llr, llr, varunc[i], frame_length); for (j = 0; j < frame_length; j++) { data_rx[0][j] = llr[j] > 0 ? 1 : 0; } /* coded BER */ for (n=0; n<ncods; n++) { srslte_convcoder_encode(&cod[n], data_tx, symbols, frame_length); for (j = 0; j < coded_length[n]; j++) { llr[j] = symbols[j] ? sqrt(2) : -sqrt(2); } srslte_ch_awgn_f(llr, llr, var[i], coded_length[n]); srslte_vec_quant_fuc(llr, llr_c, Gain, 127.5, 255, coded_length[n]); /* decoder 1 */ srslte_viterbi_decode_uc(&dec[n], llr_c, data_rx[1+n], frame_length); } /* check errors */ for (j = 0; j < 1+ncods; j++) { errors[j] += srslte_bit_diff(data_tx, data_rx[j], frame_length); } frame_cnt++; printf("Eb/No: %3.2f %10d/%d ", SNR_MIN + i * ebno_inc,frame_cnt,nof_frames); for (n=0; n<1+ncods; n++) { printf("BER: %.2e ",(float) errors[n] / (frame_cnt * frame_length)); } printf("\r"); } printf("\n"); for (j = 0; j < 1+ncods; j++) { ber[j][i] = (float) errors[j] / (frame_cnt * frame_length); } if (snr_points == 1) { printf("BER uncoded: %g\t%u errors\n", (float) errors[0] / (frame_cnt * frame_length), errors[0]); for (n=0; n<ncods; n++) { printf("BER K=%d: %g\t%u errors\n",cod[n].K, (float) errors[1+n] / (frame_cnt * frame_length), errors[1+n]); } } } for (n=0; n<ncods; n++) { srslte_viterbi_free(&dec[n]); } free(data_tx); free(symbols); free(llr); free(llr_c); for (i = 0; i < NTYPES; i++) { free(data_rx[i]); } if (snr_points == 1) { int expected_errors = get_expected_errors(nof_frames, seed, frame_length, K, tail_biting, ebno_db); if (expected_errors == -1) { fprintf(stderr, "Test parameters not defined in test_results.h\n"); exit(-1); } else { printf("errors =%d, expected =%d\n", errors[1], expected_errors); exit(errors[1] > expected_errors); } } else { printf("\n"); output_matlab(ber, snr_points, cod, ncods); printf("Done\n"); exit(0); } }