int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && nof_rx_antennas <= SRSLTE_MAX_PORTS) { bzero(q, sizeof(srslte_pmch_t)); ret = SRSLTE_ERROR; q->cell.nof_prb = max_prb; q->cell.nof_ports = 1; q->max_re = max_prb * MAX_PMCH_RE; q->nof_rx_antennas = nof_rx_antennas; INFO("Init PMCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); } srslte_sch_init(&q->dl_sch); // Allocate int16_t for reception (LLRs) q->e = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->e) { goto clean; } q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->d) { goto clean; } for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; } for (int j=0;j<q->nof_rx_antennas;j++) { q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i][j]) { goto clean; } } } for (int j=0;j<q->nof_rx_antennas;j++) { q->symbols[j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->symbols[j]) { goto clean; } } q->seqs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_pmch_seq_t*)); if (!q->seqs) { perror("calloc"); goto clean; } ret = SRSLTE_SUCCESS; } clean: if (ret == SRSLTE_ERROR) { srslte_pmch_free(q); } return ret; }
/** Initializes the PDCCH transmitter and receiver */ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; int i; if (q != NULL && srslte_cell_isvalid(&cell)) { bzero(q, sizeof(srslte_pdsch_t)); ret = SRSLTE_ERROR; q->cell = cell; q->max_re = q->cell.nof_prb * MAX_PDSCH_RE(q->cell.cp); INFO("Init PDSCH: %d ports %d PRBs, max_symbols: %d\n", q->cell.nof_ports, q->cell.nof_prb, q->max_re); if (srslte_precoding_init(&q->precoding, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp))) { fprintf(stderr, "Error initializing precoding\n"); goto clean; } for (i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); } srslte_sch_init(&q->dl_sch); q->rnti_is_set = false; // Allocate int16_t for reception (LLRs) q->e = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->e) { goto clean; } q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->d) { goto clean; } for (i = 0; i < q->cell.nof_ports; i++) { q->ce[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i]) { goto clean; } q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; } q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->symbols[i]) { goto clean; } } ret = SRSLTE_SUCCESS; } clean: if (ret == SRSLTE_ERROR) { srslte_pdsch_free(q); } return ret; }
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); }
/** Initializes the PDSCH transmitter and receiver */ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t nof_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { bzero(q, sizeof(srslte_pdsch_t)); ret = SRSLTE_ERROR; q->max_re = max_prb * MAX_PDSCH_RE(q->cell.cp); q->is_ue = is_ue; q->nof_rx_antennas = nof_antennas; INFO("Init PDSCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); } if (srslte_sch_init(&q->dl_sch)) { ERROR("Initiating DL SCH"); goto clean; } for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { // Allocate int16_t for reception (LLRs) q->e[i] = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->e[i]) { goto clean; } q->d[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->d[i]) { goto clean; } } for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; } q->symbols[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->symbols[i]) { goto clean; } if (q->is_ue) { for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i][j]) { goto clean; } } } } q->users = calloc(sizeof(srslte_pdsch_user_t*), q->is_ue?1:(1+SRSLTE_SIRNTI)); if (!q->users) { perror("malloc"); goto clean; } if (srslte_sequence_init(&q->tmp_seq, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { goto clean; } ret = SRSLTE_SUCCESS; } clean: if (ret == SRSLTE_ERROR) { srslte_pdsch_free(q); } return ret; }