/* Encode PUCCH bits according to Table 5.4.1-1 in Section 5.4.1 of 36.211 */ static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_format_t format, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], uint32_t sf_idx) { uint8_t tmp[2]; switch(format) { case SRSLTE_PUCCH_FORMAT_1: q->d[0] = uci_encode_format1(); break; case SRSLTE_PUCCH_FORMAT_1A: q->d[0] = uci_encode_format1a(bits[0]); break; case SRSLTE_PUCCH_FORMAT_1B: tmp[0] = bits[0]; tmp[1] = bits[1]; q->d[0] = uci_encode_format1b(tmp); break; case SRSLTE_PUCCH_FORMAT_2: case SRSLTE_PUCCH_FORMAT_2A: case SRSLTE_PUCCH_FORMAT_2B: memcpy(q->bits_scram, bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t)); srslte_scrambling_b(&q->seq_f2[sf_idx], q->bits_scram); srslte_mod_modulate(&q->mod, q->bits_scram, q->d, SRSLTE_PUCCH_MAX_BITS); break; default: fprintf(stderr, "PUCCH format 2 not supported\n"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; }
/** Encodes CFI and maps symbols to the slot */ int srslte_pcfich_encode(srslte_pcfich_t *q, uint32_t cfi, cf_t *slot_symbols[SRSLTE_MAX_PORTS], uint32_t subframe) { int i; if (q != NULL && cfi < 3 && slot_symbols != NULL && subframe < SRSLTE_NSUBFRAMES_X_FRAME) { /* Set pointers for layermapping & precoding */ cf_t *x[SRSLTE_MAX_LAYERS]; cf_t *symbols_precoding[SRSLTE_MAX_PORTS]; /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { x[i] = q->x[i]; } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { symbols_precoding[i] = q->symbols[i]; } /* pack CFI */ srslte_pcfich_cfi_encode(cfi, q->data); /* scramble for slot sequence nslot */ srslte_scrambling_b(&q->seq[subframe], q->data); srslte_mod_modulate(&q->mod, q->data, q->d, PCFICH_CFI_LEN); /* layer mapping & precoding */ if (q->cell.nof_ports > 1) { srslte_layermap_diversity(q->d, x, q->cell.nof_ports, q->nof_symbols); srslte_precoding_diversity(x, symbols_precoding, q->cell.nof_ports, q->nof_symbols / q->cell.nof_ports); } else { memcpy(q->symbols[0], q->d, q->nof_symbols * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { if (srslte_regs_pcfich_put(q->regs, q->symbols[i], slot_symbols[i]) < 0) { fprintf(stderr, "Error putting PCHICH resource elements\n"); return SRSLTE_ERROR; } } return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; } }
int mod_work(srslte_mod_hl* hl) { int ret = srslte_mod_modulate(&hl->obj,hl->input,hl->output,hl->in_len); hl->out_len = ret; return 0; }
int main(int argc, char **argv) { int sf_idx=0, N_id_2=0; cf_t pss_signal[SRSLTE_PSS_LEN]; float sss_signal0[SRSLTE_SSS_LEN]; // for subframe 0 float sss_signal5[SRSLTE_SSS_LEN]; // for subframe 5 int i; #ifdef DISABLE_UHD if (argc < 3) { usage(argv[0]); exit(-1); } #endif parse_args(argc, argv); N_id_2 = cell.id % 3; sf_n_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE; sf_n_samples = 2 * SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb)); cell.phich_length = SRSLTE_PHICH_NORM; cell.phich_resources = SRSLTE_PHICH_R_1; /* this *must* be called after setting slot_len_* */ base_init(); /* Generate PSS/SSS signals */ srslte_pss_generate(pss_signal, N_id_2); srslte_sss_generate(sss_signal0, sss_signal5, cell.id); printf("Set TX rate: %.2f MHz\n", cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000); printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain)); printf("Set TX freq: %.2f MHz\n", cuhd_set_tx_freq(uhd, uhd_freq) / 1000000); uint32_t nbits; srslte_modem_table_t modulator; srslte_modem_table_init(&modulator); srslte_modem_table_lte(&modulator, modulation); srslte_tcod_t turbocoder; srslte_tcod_init(&turbocoder, SRSLTE_TCOD_MAX_LEN_CB); srslte_dft_precoding_t dft_precod; srslte_dft_precoding_init(&dft_precod, 12); nbits = srslte_cbsegm_cbindex(sf_n_samples/8/srslte_mod_bits_x_symbol(modulation)/3 - 12); uint32_t ncoded_bits = sf_n_samples/8/srslte_mod_bits_x_symbol(modulation); uint8_t *data = malloc(sizeof(uint8_t)*nbits); uint8_t *data_enc = malloc(sizeof(uint8_t)*ncoded_bits); cf_t *symbols = malloc(sizeof(cf_t)*sf_n_samples); bzero(data_enc, sizeof(uint8_t)*ncoded_bits); while (1) { for (sf_idx = 0; sf_idx < SRSLTE_NSUBFRAMES_X_FRAME; sf_idx++) { bzero(sf_buffer, sizeof(cf_t) * sf_n_re); #ifdef kk if (sf_idx == 0 || sf_idx == 5) { srslte_pss_put_slot(pss_signal, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM); srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM); /* Transform to OFDM symbols */ srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer); float norm_factor = (float) sqrtf(cell.nof_prb)/15; srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); } else { #endif /* Generate random data */ for (i=0;i<nbits;i++) { data[i] = rand()%2; } srslte_tcod_encode(&turbocoder, data, data_enc, nbits); srslte_mod_modulate(&modulator, data_enc, symbols, ncoded_bits); srslte_interp_linear_offset_cabs(symbols, output_buffer, 8, sf_n_samples/8, 0, 0); // } /* send to usrp */ srslte_vec_sc_prod_cfc(output_buffer, uhd_amp, output_buffer, sf_n_samples); cuhd_send(uhd, output_buffer, sf_n_samples, true); } } base_free(); printf("Done\n"); exit(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); }
/** Encodes ACK/NACK bits, modulates and inserts into resource. * The parameter ack is an array of srslte_phich_ngroups() pointers to buffers of nof_sequences uint8_ts */ int srslte_phich_encode(srslte_phich_t *q, uint8_t ack, uint32_t ngroup, uint32_t nseq, uint32_t subframe, cf_t *slot_symbols[SRSLTE_MAX_PORTS]) { int i; 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; } /* Set pointers for layermapping & precoding */ cf_t *x[SRSLTE_MAX_LAYERS]; cf_t *symbols_precoding[SRSLTE_MAX_PORTS]; /* number of layers equals number of ports */ for (i = 0; i < q->cell.nof_ports; i++) { x[i] = q->x[i]; } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { symbols_precoding[i] = q->symbols[i]; } /* encode ACK/NACK bit */ srslte_phich_ack_encode(ack, q->data); srslte_mod_modulate(&q->mod, q->data, q->z, SRSLTE_PHICH_NBITS); DEBUG("data: ", 0); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS); /* Spread with w */ if (SRSLTE_CP_ISEXT(q->cell.cp)) { for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB; i++) { q->d[i] = w_ext[nseq][i % SRSLTE_PHICH_EXT_NSF] * q->z[i / SRSLTE_PHICH_EXT_NSF]; } } else { for (i = 0; i < SRSLTE_PHICH_NORM_MSYMB; i++) { q->d[i] = w_normal[nseq][i % SRSLTE_PHICH_NORM_NSF] * q->z[i / SRSLTE_PHICH_NORM_NSF]; } } 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); /* align to REG */ if (SRSLTE_CP_ISEXT(q->cell.cp)) { if (ngroup % 2) { for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) { q->d0[4 * i + 0] = 0; q->d0[4 * i + 1] = 0; q->d0[4 * i + 2] = q->d[2 * i]; q->d0[4 * i + 3] = q->d[2 * i + 1]; } } else { for (i = 0; i < SRSLTE_PHICH_EXT_MSYMB / 2; i++) { q->d0[4 * i + 0] = q->d[2 * i]; q->d0[4 * i + 1] = q->d[2 * i + 1]; q->d0[4 * i + 2] = 0; q->d0[4 * i + 3] = 0; } } } else { memcpy(q->d0, q->d, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); } DEBUG("d0: ", 0); if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->d0, SRSLTE_PHICH_MAX_NSYMB); /* layer mapping & precoding */ if (q->cell.nof_ports > 1) { srslte_layermap_diversity(q->d0, x, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB); srslte_precoding_diversity(&q->precoding, x, symbols_precoding, q->cell.nof_ports, SRSLTE_PHICH_MAX_NSYMB / q->cell.nof_ports); /**FIXME: According to 6.9.2, Precoding for 4 tx ports is different! */ } else { memcpy(q->symbols[0], q->d0, SRSLTE_PHICH_MAX_NSYMB * sizeof(cf_t)); } /* mapping to resource elements */ for (i = 0; i < q->cell.nof_ports; i++) { if (srslte_regs_phich_add(q->regs, q->symbols[i], ngroup, slot_symbols[i]) < 0) { fprintf(stderr, "Error putting PCHICH resource elements\n"); return SRSLTE_ERROR; } } return SRSLTE_SUCCESS; }