diff --git a/srslte/examples/CMakeLists.txt b/srslte/examples/CMakeLists.txt index 2b7a7696f..c27410a53 100644 --- a/srslte/examples/CMakeLists.txt +++ b/srslte/examples/CMakeLists.txt @@ -23,16 +23,6 @@ IF(UHD_FOUND) LINK_DIRECTORIES(${UHD_LIBRARY_DIRS}) ENDIF(UHD_FOUND) -################################################################# -# EXAMPLES -################################################################# - -add_executable(hl_example hl_example.c) -target_link_libraries(hl_example srslte) - -add_executable(ll_example ll_example.c) -target_link_libraries(ll_example srslte) - ################################################################# # Applications @@ -41,7 +31,6 @@ target_link_libraries(ll_example srslte) add_executable(synch_file synch_file.c) target_link_libraries(synch_file srslte) - ################################################################# # These can be compiled without UHD or graphics support ################################################################# @@ -78,9 +67,6 @@ IF(UHD_FOUND) add_executable(cell_search cell_search.c) target_link_libraries(cell_search srslte srslte_uhd) - add_executable(prach_ue prach_ue.c) - target_link_libraries(prach_ue srslte srslte_uhd) - add_executable(cell_measurement cell_measurement.c) target_link_libraries(cell_measurement srslte srslte_uhd) diff --git a/srslte/examples/hl_example.c b/srslte/examples/hl_example.c deleted file mode 100644 index e344b4907..000000000 --- a/srslte/examples/hl_example.c +++ /dev/null @@ -1,123 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include -#include -#include -#include - -#include "srslte/srslte.h" - -void usage(char *arg) { - printf("Usage: %s nbits snr_db\n",arg); -} - -int main(int argc, char **argv) { - srslte_binsource_hl bs; - srslte_mod_hl mod; - srslte_ch_awgn_hl ch; - srslte_demod_soft_hl demod_s; - srslte_demod_hard_hl demod_h; - - bzero(&bs,sizeof(bs)); - bzero(&mod,sizeof(mod)); - bzero(&ch,sizeof(ch)); - bzero(&demod_s,sizeof(demod_s)); - bzero(&demod_h,sizeof(demod_h)); - - if (argc<3) { - usage(argv[0]); - exit(-1); - } - - int nbits = atoi(argv[1]); - float snr_db = atof(argv[2]); - float var = sqrt(pow(10,-snr_db/10)); - - bs.init.seed = 0; - bs.init.cache_seq_nbits = 0; - bs.ctrl_in.nbits = nbits; - bs.output = malloc(nbits); - - mod.in_len = nbits; - mod.init.std = SRSLTE_MOD_BPSK; - mod.input = bs.output; - mod.output = malloc(nbits*sizeof(_Complex float)); - - ch.in_len = nbits; - ch.input = mod.output; - ch.ctrl_in.variance = var; - ch.output = malloc(nbits*sizeof(_Complex float)); - - demod_h.in_len = nbits; - demod_h.init.std = SRSLTE_MOD_BPSK; - demod_h.input = ch.output; - demod_h.output = malloc(nbits); - - demod_s.in_len = nbits; - demod_s.init.std = SRSLTE_MOD_BPSK; - demod_s.input = ch.output; - demod_s.output = malloc(sizeof(float)*nbits); - demod_s.ctrl_in.alg_type = SRSLTE_DEMOD_SOFT_ALG_APPROX; - demod_s.ctrl_in.sigma = var; - - if ( srslte_binsource_initialize(&bs) || - mod_initialize(&mod) || - srslte_ch_awgn_initialize(&ch) || - srslte_demod_hard_initialize(&demod_h) || - srslte_demod_soft_initialize(&demod_s) - ) { - printf("Error initializing modules\n"); - exit(-1); - } - - srslte_binsource_work(&bs); - mod_work(&mod); - srslte_ch_awgn_work(&ch); - srslte_demod_hard_work(&demod_h); - srslte_demod_soft_work(&demod_s); - - /* hard decision for soft demodulation */ - uint8_t* tmp = malloc(nbits); - for (int i=0;i0?1:0; - } - - printf("Hard errors: %u/%d\n",srslte_bit_diff(bs.output,demod_h.output,nbits),nbits); - printf("Soft errors: %u/%d\n",srslte_bit_diff(bs.output,tmp,nbits),nbits); - - free(bs.output); - free(mod.output); - free(ch.output); - free(demod_h.output); - free(demod_s.output); - free(tmp); - - printf("Exit\n"); - exit(0); -} diff --git a/srslte/examples/ll_example.c b/srslte/examples/ll_example.c deleted file mode 100644 index 2e9c5df90..000000000 --- a/srslte/examples/ll_example.c +++ /dev/null @@ -1,51 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -#include -#include - -#include "srslte/srslte.h" - -int main(int argc, char **argv) { - srslte_binsource_t bs; - uint8_t* output; - - srslte_binsource_init(&bs); - srslte_binsource_seed_time(&bs); - - output = malloc(100); - - if (srslte_binsource_generate(&bs,output,100)) { - printf("Error generating bits\n"); - exit(-1); - } - printf("output: "); - srslte_bit_fprint(stdout,output,100); - printf("Done\n"); - exit(0); -} diff --git a/srslte/examples/prach_ue.c b/srslte/examples/prach_ue.c deleted file mode 100644 index a14d90961..000000000 --- a/srslte/examples/prach_ue.c +++ /dev/null @@ -1,634 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "srslte/srslte.h" - - -#include "srslte/cuhd/cuhd.h" -#include "srslte/cuhd/cuhd_utils.h" - -cell_search_cfg_t cell_detect_config = { - 5000, - 200, // nof_frames_total - 10.0 // threshold -}; - -#define B210_DEFAULT_GAIN 40.0 -#define B210_DEFAULT_GAIN_CORREC 110.0 // Gain of the Rx chain when the gain is set to 40 - -float gain_offset = B210_DEFAULT_GAIN_CORREC; - - -/********************************************************************** - * Program arguments processing - ***********************************************************************/ -typedef struct { - int nof_subframes; - int force_N_id_2; - uint32_t file_nof_prb; - uint32_t preamble_idx; - float beta_prach; - float ta_usec; - float beta_pusch; - char *uhd_args; - float uhd_rx_freq; - float uhd_tx_freq; - float uhd_tx_freq_offset; - float uhd_tx_gain; - float uhd_rx_gain; -}prog_args_t; - -void args_default(prog_args_t *args) { - args->nof_subframes = -1; - args->force_N_id_2 = -1; // Pick the best - args->file_nof_prb = 6; - args->beta_prach = 0.005; - args->beta_pusch = 2.0; - args->ta_usec = -1.0; - args->preamble_idx = 7; - args->uhd_args = ""; - args->uhd_rx_freq = 2112500000.0; - args->uhd_tx_freq = 1922500000.0; - args->uhd_tx_freq_offset = 8000000.0; - args->uhd_tx_gain = 60.0; - args->uhd_rx_gain = 60.0; -} - -void usage(prog_args_t *args, char *prog) { - printf("Usage: %s [agfFbrlpnv]\n", prog); - printf("\t-a UHD args [Default %s]\n", args->uhd_args); - printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_rx_gain); - printf("\t-G UHD TX/RX gain [Default %.2f dB]\n", args->uhd_tx_gain); - printf("\t-f UHD RX freq [Default %.1f MHz]\n", args->uhd_rx_freq/1000000); - printf("\t-F UHD TX freq [Default %.1f MHz]\n", args->uhd_tx_freq/1000000); - printf("\t-b beta PRACH (transmission amplitude) [Default %f]\n",args->beta_prach); - printf("\t-B beta PUSCH (transmission amplitude) [Default %f]\n",args->beta_pusch); - printf("\t-t TA usec (time advance, -1 from RAR) [Default %f]\n",args->ta_usec); - printf("\t-p PRACH preamble idx [Default %d]\n",args->preamble_idx); - printf("\t-l Force N_id_2 [Default best]\n"); - printf("\t-n nof_subframes [Default %d]\n", args->nof_subframes); - printf("\t-v [set srslte_verbose to debug, default none]\n"); -} - -void parse_args(prog_args_t *args, int argc, char **argv) { - int opt; - args_default(args); - while ((opt = getopt(argc, argv, "agGfFplnvbBt")) != -1) { - switch (opt) { - case 'a': - args->uhd_args = argv[optind]; - break; - case 'b': - args->beta_prach = atof(argv[optind]); - break; - case 'B': - args->beta_pusch = atof(argv[optind]); - break; - case 't': - args->ta_usec = atof(argv[optind]); - break; - case 'g': - args->uhd_rx_gain = atof(argv[optind]); - break; - case 'G': - args->uhd_tx_gain = atof(argv[optind]); - break; - case 'f': - args->uhd_rx_freq = atof(argv[optind]); - break; - case 'F': - args->uhd_tx_freq = atof(argv[optind]); - break; - case 'n': - args->nof_subframes = atoi(argv[optind]); - break; - case 'p': - args->preamble_idx = atoi(argv[optind]); - break; - case 'l': - args->force_N_id_2 = atoi(argv[optind]); - break; - case 'v': - srslte_verbose++; - break; - default: - usage(args, argv[0]); - exit(-1); - } - } - if (args->uhd_tx_freq < 0 && args->uhd_rx_freq < 0) { - usage(args, argv[0]); - exit(-1); - } -} -/**********************************************************************/ - -/* TODO: Do something with the output data */ -uint8_t data_rx[20000]; - - -int cuhd_recv_wrapper_timed(void *h, void *data, uint32_t nsamples, srslte_timestamp_t *uhd_time) { - DEBUG(" ---- Receive %d samples ---- \n", nsamples); - return cuhd_recv_with_time(h, data, nsamples, true, &uhd_time->full_secs, &uhd_time->frac_secs); -} - -extern float mean_exec_time; - -enum receiver_state { DECODE_MIB, SEND_PRACH, RECV_RAR, RECV_CONNSETUP} state; - -#define NOF_PRACH_SEQUENCES 52 - -srslte_ue_dl_t ue_dl; -srslte_ue_ul_t ue_ul; -srslte_ue_sync_t ue_sync; -srslte_prach_t prach; -int prach_buffer_len; - -prog_args_t prog_args; - -uint32_t sfn = 0; // system frame number -cf_t *sf_buffer = NULL; - - - -typedef enum{ - rar_tpc_n6dB = 0, - rar_tpc_n4dB, - rar_tpc_n2dB, - rar_tpc_0dB, - rar_tpc_2dB, - rar_tpc_4dB, - rar_tpc_6dB, - rar_tpc_8dB, - rar_tpc_n_items, -}rar_tpc_command_t; -static const char tpc_command_text[rar_tpc_n_items][8] = {"-6dB", "-4dB", "-2dB", "0dB", "2dB", "4dB", "6dB", "8dB"}; -typedef enum{ - rar_header_type_bi = 0, - rar_header_type_rapid, - rar_header_type_n_items, -}rar_header_t; -static const char rar_header_text[rar_header_type_n_items][8] = {"BI", "RAPID"}; - -typedef struct { - rar_header_t hdr_type; - bool hopping_flag; - rar_tpc_command_t tpc_command; - bool ul_delay; - bool csi_req; - uint16_t rba; - uint16_t timing_adv_cmd; - uint16_t temp_c_rnti; - uint8_t mcs; - uint8_t RAPID; - uint8_t BI; -}rar_msg_t; - -char *bool_to_string(bool x) { - if (x) { - return "Enabled"; - } else { - return "Disabled"; - } -} - -void rar_msg_fprint(FILE *stream, rar_msg_t *msg) -{ - fprintf(stream, "Header type: %s\n", rar_header_text[msg->hdr_type]); - fprintf(stream, "Hopping flag: %s\n", bool_to_string(msg->hopping_flag)); - fprintf(stream, "TPC command: %s\n", tpc_command_text[msg->tpc_command]); - fprintf(stream, "UL delay: %s\n", bool_to_string(msg->ul_delay)); - fprintf(stream, "CSI required: %s\n", bool_to_string(msg->csi_req)); - fprintf(stream, "RBA: %d\n", msg->rba); - fprintf(stream, "TA: %d\n", msg->timing_adv_cmd); - fprintf(stream, "T-CRNTI: %d\n", msg->temp_c_rnti); - fprintf(stream, "MCS: %d\n", msg->mcs); - fprintf(stream, "RAPID: %d\n", msg->RAPID); - fprintf(stream, "BI: %d\n", msg->BI); -} - -bool go_exit = false; -void sig_int_handler(int signo) -{ - printf("SIGINT received. Exiting...\n"); - if (signo == SIGINT) { - go_exit = true; - } -} - -int rar_unpack(uint8_t *buffer, rar_msg_t *msg) -{ - int ret = SRSLTE_ERROR; - uint8_t *ptr = buffer; - - if(buffer != NULL && - msg != NULL) - { - ptr++; - msg->hdr_type = *ptr++; - if(msg->hdr_type == rar_header_type_bi) { - ptr += 2; - msg->BI = srslte_bit_pack(&ptr, 4); - ret = SRSLTE_SUCCESS; - } else if (msg->hdr_type == rar_header_type_rapid) { - msg->RAPID = srslte_bit_pack(&ptr, 6); - ptr++; - - msg->timing_adv_cmd = srslte_bit_pack(&ptr, 11); - msg->hopping_flag = *ptr++; - msg->rba = srslte_bit_pack(&ptr, 10); - msg->mcs = srslte_bit_pack(&ptr, 4); - msg->tpc_command = (rar_tpc_command_t) srslte_bit_pack(&ptr, 3); - msg->ul_delay = *ptr++; - msg->csi_req = *ptr++; - msg->temp_c_rnti = srslte_bit_pack(&ptr, 16); - ret = SRSLTE_SUCCESS; - } - } - - return(ret); -} - -int main(int argc, char **argv) { - int ret; - srslte_cell_t cell; - int64_t sf_cnt; - srslte_ue_mib_t ue_mib; - void *uhd; - int n; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; - uint32_t sfn_offset; - rar_msg_t rar_msg; - srslte_ra_ul_dci_t ra_pusch; - srslte_ra_ul_grant_t ra_grant; - uint32_t rar_window_start = 0, rar_trials = 0, rar_window_stop = 0; - srslte_timestamp_t uhd_time; - srslte_timestamp_t next_tx_time; - const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00}; - uint8_t data[1000]; - cf_t *prach_buffer; - - parse_args(&prog_args, argc, argv); - - printf("Opening UHD device...\n"); - if (cuhd_open(prog_args.uhd_args, &uhd)) { - fprintf(stderr, "Error opening uhd\n"); - exit(-1); - } - - sigset_t sigset; - sigemptyset(&sigset); - sigaddset(&sigset, SIGINT); - sigprocmask(SIG_UNBLOCK, &sigset, NULL); - signal(SIGINT, sig_int_handler); - - cuhd_set_master_clock_rate(uhd, 30.72e6); - - /* Set receiver gain */ - float x = cuhd_set_rx_gain(uhd, prog_args.uhd_rx_gain); - printf("Set RX gain to %.1f dB\n", x); - x = cuhd_set_tx_gain(uhd, prog_args.uhd_tx_gain); - printf("Set TX gain to %.1f dB\n", x); - - /* set receiver frequency */ - cuhd_set_rx_freq(uhd, (double) prog_args.uhd_rx_freq); - cuhd_rx_wait_lo_locked(uhd); - printf("Tunning RX receiver to %.3f MHz\n", (double ) prog_args.uhd_rx_freq/1000000); - - cuhd_set_tx_freq_offset(uhd, prog_args.uhd_tx_freq, prog_args.uhd_tx_freq_offset); - printf("Tunning TX receiver to %.3f MHz\n", (double ) prog_args.uhd_tx_freq/1000000); - - - uint32_t ntrial=0; - do { - ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell); - if (ret < 0) { - fprintf(stderr, "Error searching for cell\n"); - exit(-1); - } else if (ret == 0 && !go_exit) { - printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++); - } - } while (ret == 0 && !go_exit); - - if (go_exit) { - exit(0); - } - - /* set sampling frequency */ - int srate = srslte_sampling_freq_hz(cell.nof_prb); - if (srate != -1) { - if (srate < 10e6) { - cuhd_set_master_clock_rate(uhd, 4*srate); - } else { - cuhd_set_master_clock_rate(uhd, srate); - } - printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); - float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate); - if (srate_uhd != srate) { - fprintf(stderr, "Could not set sampling rate\n"); - exit(-1); - } - } else { - fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb); - exit(-1); - } - - INFO("Stopping UHD and flushing buffer...\r",0); - cuhd_stop_rx_stream(uhd); - cuhd_flush_buffer(uhd); - - - if (srslte_ue_mib_init(&ue_mib, cell)) { - fprintf(stderr, "Error initaiting UE MIB decoder\n"); - exit(-1); - } - - if (srslte_prach_init(&prach, srslte_symbol_sz(cell.nof_prb), 0, 0, false, 1)) { - fprintf(stderr, "Error initializing PRACH\n"); - exit(-1); - } - prach_buffer_len = prach.N_seq + prach.N_cp; - prach_buffer = srslte_vec_malloc(prach_buffer_len*sizeof(cf_t)); - if(!prach_buffer) { - perror("maloc"); - exit(-1); - } - if(srslte_prach_gen(&prach, prog_args.preamble_idx, 0, prach_buffer)){ - fprintf(stderr, "Error generating prach sequence\n"); - return -1; - } - - if (srslte_ue_ul_init(&ue_ul, cell)) { - fprintf(stderr, "Error initiating UE UL\n"); - exit(-1); - } - - srslte_ue_ul_set_cfo_enable(&ue_ul, true); - - srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg; - bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - - dmrs_cfg.group_hopping_en = false; - dmrs_cfg.sequence_hopping_en = false; - dmrs_cfg.delta_ss = 0; - dmrs_cfg.cyclic_shift = 0; - srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, NULL, NULL, NULL, NULL, NULL); - - cf_t *ul_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - if (!ul_signal) { - perror("malloc"); - exit(-1); - } - bzero(ul_signal, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); - - if (srslte_ue_dl_init(&ue_dl, cell)) { - fprintf(stderr, "Error initiating UE downlink processing module\n"); - exit(-1); - } - - /* Initialize subframe counter */ - sf_cnt = 0; - - - if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper_timed, uhd)) { - fprintf(stderr, "Error initiating ue_sync\n"); - exit(-1); - } - - cuhd_start_rx_stream(uhd); - - uint16_t ra_rnti; - uint32_t conn_setup_trial = 0; - uint32_t ul_sf_idx = 0; - - state = DECODE_MIB; - - /* Main loop */ - while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) { - - ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); - if (ret < 0) { - fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); - } - - /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ - if (ret == 1) { - - if (state != RECV_RAR) { - /* Run FFT for all subframe data */ - srslte_ofdm_rx_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols); - - /* Get channel estimates for each port */ - srslte_chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, srslte_ue_sync_get_sfidx(&ue_sync)); - } - - if (sf_cnt > 1000) { - switch (state) { - case DECODE_MIB: - if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { - srslte_pbch_decode_reset(&ue_mib.pbch); - n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); - if (n < 0) { - fprintf(stderr, "Error decoding UE MIB\n"); - exit(-1); - } else if (n == SRSLTE_UE_MIB_FOUND) { - srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); - srslte_cell_fprint(stdout, &cell, sfn); - printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); - sfn = (sfn + sfn_offset)%1024; - state = SEND_PRACH; - } - } - break; - case SEND_PRACH: - - if (((sfn%2) == 1) && (srslte_ue_sync_get_sfidx(&ue_sync) == 1)) { - srslte_ue_sync_get_last_timestamp(&ue_sync, &uhd_time); - - srslte_timestamp_copy(&next_tx_time, &uhd_time); - srslte_timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms) - printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n", - sfn, srslte_timestamp_real(&uhd_time), srslte_timestamp_real(&next_tx_time)); - - cuhd_send_timed(uhd, prach_buffer, prach_buffer_len, - next_tx_time.full_secs, next_tx_time.frac_secs); - - srslte_vec_save_file("prach_ue.dat", prach_buffer, prach_buffer_len*sizeof(cf_t)); - - ra_rnti = 2; - rar_window_start = sfn+1; - rar_window_stop = sfn+3; - state = RECV_RAR; - } - break; - case RECV_RAR: - - if ((sfn == rar_window_start && srslte_ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) { - printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, srslte_ue_sync_get_sfidx(&ue_sync)); - n = srslte_ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, srslte_ue_sync_get_sfidx(&ue_sync), ra_rnti); - if (n < 0) { - fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); - } else if (n > 0) { - - rar_unpack(data_rx, &rar_msg); - rar_msg_fprint(stdout, &rar_msg); - srslte_dci_rar_grant_t rar_grant; - rar_grant.hopping_flag = rar_msg.hopping_flag; - rar_grant.rba = rar_msg.rba; - rar_grant.trunc_mcs = rar_msg.mcs; - srslte_dci_rar_to_ul_grant(&rar_grant, cell.nof_prb, 0, &ra_pusch, &ra_grant); - srslte_ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb); - - srslte_ue_sync_get_last_timestamp(&ue_sync, &uhd_time); - - srslte_bit_unpack_vector((uint8_t*) conn_request_msg, data, ra_grant.mcs.tbs); - - uint32_t n_ta = srslte_N_ta_new_rar(rar_msg.timing_adv_cmd); - printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta); - float time_adv_sec = SRSLTE_TA_OFFSET+((float) n_ta)*SRSLTE_LTE_TS; - if (prog_args.ta_usec >= 0) { - time_adv_sec = prog_args.ta_usec*1e-6; - } -#define N_TX 1 - const uint32_t rv[N_TX]={0}; - for (int i=0; i= rar_window_stop) { - state = SEND_PRACH; - rar_trials++; - if (rar_trials >= 1) { - go_exit = 1; - } - } - } - break; - - case RECV_CONNSETUP: - if (srslte_ue_sync_get_sfidx(&ue_sync) == (ul_sf_idx+4)%10) { - //srslte_verbose=SRSLTE_VERBOSE_DEBUG; - srslte_vec_save_file("connsetup",sf_buffer,SRSLTE_SF_LEN_PRB(cell.nof_prb)*sizeof(cf_t)); - } else { - //srslte_verbose=SRSLTE_VERBOSE_NONE; - } - printf("Looking for ConnectionSetup in sfn: %d sf_idx: %d, RNTI: %d\n", sfn, srslte_ue_sync_get_sfidx(&ue_sync),rar_msg.temp_c_rnti); - n = srslte_ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, srslte_ue_sync_get_sfidx(&ue_sync), rar_msg.temp_c_rnti); - if (n < 0) { - fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); - } else if (n > 0) { - printf("Received ConnectionSetup len: %d.\n", n); - srslte_vec_fprint_hex(stdout, data_rx, n); - exit(0); - } else { - conn_setup_trial++; - if (conn_setup_trial == 20) { - go_exit = 1; - } - } - - break; - } - if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) { - sfn++; - if (sfn == 1024) { - sfn = 0; - } - } - - } - - } else if (ret == 0) { - printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", - srslte_sync_get_peak_value(&ue_sync.sfind), - ue_sync.frame_total_cnt, ue_sync.state); - } - - sf_cnt++; - } // Main loop - - srslte_ue_dl_free(&ue_dl); - srslte_ue_sync_free(&ue_sync); - - srslte_ue_mib_free(&ue_mib); - cuhd_close(uhd); - printf("\nBye\n"); - exit(0); -} - - - - - - - diff --git a/srslte/examples/tutorial_examples/simple_tx.c b/srslte/examples/tutorial_examples/simple_tx.c index 83bd9373a..8a84ed1e9 100644 --- a/srslte/examples/tutorial_examples/simple_tx.c +++ b/srslte/examples/tutorial_examples/simple_tx.c @@ -206,7 +206,7 @@ int main(int argc, char **argv) { srslte_modem_table_t modulator; srslte_modem_table_init(&modulator); - srslte_modem_table_lte(&modulator, modulation, false); + srslte_modem_table_lte(&modulator, modulation); srslte_tcod_t turbocoder; srslte_tcod_init(&turbocoder, SRSLTE_TCOD_MAX_LEN_CB); diff --git a/srslte/include/srslte/modem/demod_soft.h b/srslte/include/srslte/modem/demod_soft.h index 917c5dc50..80f63b3b5 100644 --- a/srslte/include/srslte/modem/demod_soft.h +++ b/srslte/include/srslte/modem/demod_soft.h @@ -43,47 +43,14 @@ #include "srslte/config.h" #include "modem_table.h" -typedef enum SRSLTE_API { - SRSLTE_DEMOD_SOFT_ALG_EXACT, - SRSLTE_DEMOD_SOFT_ALG_APPROX -} srslte_demod_soft_alg_t; -typedef struct SRSLTE_API { - float sigma; // noise power - srslte_demod_soft_alg_t alg_type; // soft demapping algorithm (SRSLTE_DEMOD_SOFT_ALG_EXACT or SRSLTE_DEMOD_SOFT_ALG_APPROX) - srslte_modem_table_t *table; // symbol mapping table (see modem_table.h) - uint32_t *zones; - float *dd; - uint32_t max_symbols; -} srslte_demod_soft_t; - -SRSLTE_API int srslte_demod_soft_init(srslte_demod_soft_t *q, - uint32_t max_symbols); - -SRSLTE_API void srslte_demod_soft_free(srslte_demod_soft_t *q); - -SRSLTE_API void srslte_demod_soft_table_set(srslte_demod_soft_t *q, - srslte_modem_table_t *table); - -SRSLTE_API void srslte_demod_soft_alg_set(srslte_demod_soft_t *q, - srslte_demod_soft_alg_t alg_type); - -SRSLTE_API void srslte_demod_soft_sigma_set(srslte_demod_soft_t *q, - float sigma); - -SRSLTE_API int srslte_demod_soft_demodulate(srslte_demod_soft_t *q, +SRSLTE_API int srslte_demod_soft_demodulate(srslte_mod_t modulation, const cf_t* symbols, float* llr, - int nsymbols); - -SRSLTE_API int srslte_demod_soft_demodulate_lte(srslte_mod_t modulation, - const cf_t* symbols, - float* llr, - int nsymbols); + int nsymbols); /* High-level API */ typedef struct SRSLTE_API { - srslte_demod_soft_t obj; srslte_modem_table_t table; struct srslte_demod_soft_init{ @@ -95,7 +62,6 @@ typedef struct SRSLTE_API { struct srslte_demod_soft_ctrl_in { float sigma; // Estimated noise variance - srslte_demod_soft_alg_t alg_type; // soft demapping algorithm (SRSLTE_DEMOD_SOFT_ALG_EXACT or SRSLTE_DEMOD_SOFT_ALG_APPROX) }ctrl_in; float* output; diff --git a/srslte/include/srslte/modem/modem_table.h b/srslte/include/srslte/modem/modem_table.h index bba4e7355..1860c743d 100644 --- a/srslte/include/srslte/modem/modem_table.h +++ b/srslte/include/srslte/modem/modem_table.h @@ -44,14 +44,6 @@ #include "srslte/common/phy_common.h" #include "srslte/config.h" -typedef struct SRSLTE_API { - uint32_t idx[2][6][32]; - uint32_t min_idx[2][64][6]; /* NEW: for each constellation point zone (2, 4, 16, 64 for BPSK, QPSK, 16QAM, 64QAM) the 2x(1, 2, 4, and 6 closest constellation points) for each bit, respectively. */ - uint32_t d_idx[64][7]; /* NEW: for each constellation point zone (2, 4, 16, 64 for BPSK, QPSK, 16QAM, 64QAM) the 2, 3, 5 and 7 indices to constellation points that need to be computed for any recevied symbol modulated as BPSK, QPSK, 16QAM, and 64QAM, respectively. */ - -}srslte_soft_table_t; - - typedef struct { cf_t symbol[8]; } bpsk_packed_t; @@ -66,7 +58,6 @@ typedef struct { typedef struct SRSLTE_API { cf_t* symbol_table; // bit-to-symbol mapping - srslte_soft_table_t soft_table; // symbol-to-bit mapping (used in soft demodulating) uint32_t nsymbols; // number of modulation symbols uint32_t nbits_x_symbol; // number of bits per symbol @@ -85,13 +76,11 @@ SRSLTE_API void srslte_modem_table_reset(srslte_modem_table_t* q); SRSLTE_API int srslte_modem_table_set(srslte_modem_table_t* q, cf_t* table, - srslte_soft_table_t *soft_table, uint32_t nsymbols, uint32_t nbits_x_symbol); SRSLTE_API int srslte_modem_table_lte(srslte_modem_table_t* q, - srslte_mod_t modulation, - bool compute_soft_demod); + srslte_mod_t modulation); SRSLTE_API void srslte_modem_table_bytes(srslte_modem_table_t* q); diff --git a/srslte/include/srslte/phch/ra.h b/srslte/include/srslte/phch/ra.h index 0f2f78254..c8282ed1b 100644 --- a/srslte/include/srslte/phch/ra.h +++ b/srslte/include/srslte/phch/ra.h @@ -50,6 +50,7 @@ typedef struct SRSLTE_API { srslte_mod_t mod; int tbs; + uint32_t idx; } srslte_ra_mcs_t; diff --git a/srslte/include/srslte/phch/sch.h b/srslte/include/srslte/phch/sch.h index 8e396fad1..fd8cdf18f 100644 --- a/srslte/include/srslte/phch/sch.h +++ b/srslte/include/srslte/phch/sch.h @@ -46,7 +46,7 @@ #include "srslte/phch/pusch_cfg.h" #include "srslte/phch/uci.h" -#define SRSLTE_PDSCH_MAX_TDEC_ITERS 6 +#define SRSLTE_PDSCH_MAX_TDEC_ITERS 3 #ifndef SRSLTE_RX_NULL diff --git a/srslte/lib/ch_estimation/test/chest_test_dl_mex.c b/srslte/lib/ch_estimation/test/chest_test_dl_mex.c index 7383359f2..c8713c47e 100644 --- a/srslte/lib/ch_estimation/test/chest_test_dl_mex.c +++ b/srslte/lib/ch_estimation/test/chest_test_dl_mex.c @@ -27,10 +27,7 @@ #include #include "srslte/srslte.h" -#ifdef UNDEF_BOOL -#undef bool -#endif -#include "mex.h" +#include "srslte/mex/mexutils.h" /** MEX function to be called from MATLAB to test the channel estimator diff --git a/srslte/lib/modem/src/demod_soft.c b/srslte/lib/modem/src/demod_soft.c index 0097a9288..8f362b15d 100644 --- a/srslte/lib/modem/src/demod_soft.c +++ b/srslte/lib/modem/src/demod_soft.c @@ -32,57 +32,9 @@ #include "srslte/utils/vector.h" #include "srslte/utils/bit.h" #include "srslte/modem/demod_soft.h" -#include "soft_algs.h" -//#define SCALE_DEMOD16QAM +#define SCALE_DEMOD16QAM -int srslte_demod_soft_init(srslte_demod_soft_t *q, uint32_t max_symbols) { - int ret = SRSLTE_ERROR; - - bzero((void*)q,sizeof(srslte_demod_soft_t)); - q->sigma = 1.0; - q->zones = srslte_vec_malloc(sizeof(uint32_t) * max_symbols); - if (!q->zones) { - perror("malloc"); - goto clean_exit; - } - q->dd = srslte_vec_malloc(sizeof(float*) * max_symbols * 7); - if (!q->dd) { - perror("malloc"); - goto clean_exit; - } - q->max_symbols = max_symbols; - - ret = SRSLTE_SUCCESS; - -clean_exit: - if (ret != SRSLTE_SUCCESS) { - srslte_demod_soft_free(q); - } - return ret; -} - -void srslte_demod_soft_free(srslte_demod_soft_t *q) { - if (q->zones) { - free(q->zones); - } - if (q->dd) { - free(q->dd); - } - bzero((void*)q,sizeof(srslte_demod_soft_t)); -} - -void srslte_demod_soft_table_set(srslte_demod_soft_t *q, srslte_modem_table_t *table) { - q->table = table; -} - -void srslte_demod_soft_alg_set(srslte_demod_soft_t *q, srslte_demod_soft_alg_t alg_type) { - q->alg_type = alg_type; -} - -void srslte_demod_soft_sigma_set(srslte_demod_soft_t *q, float sigma) { - q->sigma = 2*sigma; -} void demod_bpsk_lte(const cf_t *symbols, float *llr, int nsymbols) { for (int i=0;ialg_type) { - case SRSLTE_DEMOD_SOFT_ALG_EXACT: - llr_exact(symbols, llr, nsymbols, q->table->nsymbols, q->table->nbits_x_symbol, - q->table->symbol_table, q->table->soft_table.idx, q->sigma); - break; - case SRSLTE_DEMOD_SOFT_ALG_APPROX: - if (nsymbols <= q->max_symbols) { - llr_approx(symbols, llr, nsymbols, q->table->nsymbols, - q->table->nbits_x_symbol, - q->table->symbol_table, q->table->soft_table.idx, - q->table->soft_table.d_idx, q->table->soft_table.min_idx, q->sigma, - q->zones, q->dd); - } else { - fprintf(stderr, "Too many symbols (%d>%d)\n", nsymbols, q->max_symbols); - return -1; - } - break; - } - return nsymbols*q->table->nbits_x_symbol; -} - - - - /* High-Level API */ int srslte_demod_soft_initialize(srslte_demod_soft_hl* hl) { - srslte_modem_table_init(&hl->table); - if (srslte_modem_table_lte(&hl->table,hl->init.std,true)) { - return -1; - } - srslte_demod_soft_init(&hl->obj, 10000); - hl->obj.table = &hl->table; - return 0; } int srslte_demod_soft_work(srslte_demod_soft_hl* hl) { - hl->obj.sigma = hl->ctrl_in.sigma; - hl->obj.alg_type = hl->ctrl_in.alg_type; - int ret = srslte_demod_soft_demodulate(&hl->obj,hl->input,hl->output,hl->in_len); + int ret = srslte_demod_soft_demodulate(hl->init.std,hl->input,hl->output,hl->in_len); hl->out_len = ret; return 0; } int srslte_demod_soft_stop(srslte_demod_soft_hl* hl) { - srslte_modem_table_free(&hl->table); return 0; } diff --git a/srslte/lib/modem/src/lte_tables.c b/srslte/lib/modem/src/lte_tables.c index b89f0446c..9e4585954 100644 --- a/srslte/lib/modem/src/lte_tables.c +++ b/srslte/lib/modem/src/lte_tables.c @@ -34,11 +34,9 @@ #include "srslte/modem/modem_table.h" #include "lte_tables.h" -void LLR_approx_params(const cf_t* table, srslte_soft_table_t *soft_table, int B); - /** * Set the BPSK modulation table */ -void set_BPSKtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_soft_demod) +void set_BPSKtable(cf_t* table) { // LTE-BPSK constellation: // Q @@ -48,32 +46,12 @@ void set_BPSKtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_so table[0] = BPSK_LEVEL + BPSK_LEVEL*_Complex_I; table[1] = -BPSK_LEVEL -BPSK_LEVEL*_Complex_I; - if (!compute_soft_demod) { - return; - } - - /* BSPK symbols containing a '0' and a '1' (only two symbols, 1 bit) */ - soft_table->idx[0][0][0] = 0; - soft_table->idx[1][0][0] = 1; - - /* set two matrices for LLR approx. calculation */ - soft_table->min_idx[0][0][0] = 0; - soft_table->min_idx[0][1][0] = 0; - soft_table->min_idx[1][0][0] = 1; - soft_table->min_idx[1][1][0] = 1; - - soft_table->d_idx[0][0] = 0; - soft_table->d_idx[0][1] = 1; - soft_table->d_idx[1][0] = 0; - soft_table->d_idx[1][1] = 1; - } /** * Set the QPSK modulation table */ -void set_QPSKtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_soft_demod) +void set_QPSKtable(cf_t* table) { - uint32_t i,j; // LTE-QPSK constellation: // Q @@ -84,36 +62,12 @@ void set_QPSKtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_so table[1] = QPSK_LEVEL - QPSK_LEVEL*_Complex_I; table[2] = -QPSK_LEVEL + QPSK_LEVEL*_Complex_I; table[3] = -QPSK_LEVEL - QPSK_LEVEL*_Complex_I; - for (i=0;i<6;i++) { - for (j=0;j<32;j++) { - soft_table->idx[0][i][j] = 0; - soft_table->idx[1][i][j] = 0; - } - } - - if (!compute_soft_demod) { - return; - } - - /* QSPK symbols containing a '0' at the different bit positions */ - soft_table->idx[0][0][0] = 0; - soft_table->idx[0][0][1] = 1; - soft_table->idx[0][1][0] = 0; - soft_table->idx[0][1][1] = 2; - /* QSPK symbols containing a '1' at the different bit positions */ - soft_table->idx[1][0][0] = 2; - soft_table->idx[1][0][1] = 3; - soft_table->idx[1][1][0] = 1; - soft_table->idx[1][1][1] = 3; - - LLR_approx_params(table, soft_table, 2); /* last param indicating B (bits per symbol) */ } /** * Set the 16QAM modulation table */ -void set_16QAMtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_soft_demod) +void set_16QAMtable(cf_t* table) { - uint32_t i,j; // LTE-16QAM constellation: // Q // 1011 1001 | 0001 0011 @@ -137,50 +91,12 @@ void set_16QAMtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_s table[13] = -QAM16_LEVEL_1 - QAM16_LEVEL_2*_Complex_I; table[14] = -QAM16_LEVEL_2 - QAM16_LEVEL_1*_Complex_I; table[15] = -QAM16_LEVEL_2 - QAM16_LEVEL_2*_Complex_I; - for (i=0;i<6;i++) { - for (j=0;j<32;j++) { - soft_table->idx[0][i][j] = 0; - soft_table->idx[1][i][j] = 0; - } - } - if (!compute_soft_demod) { - return; - } - - - /* Matrices identifying the zeros and ones of LTE-16QAM constellation */ - for (i=0;i<8;i++) { - soft_table->idx[0][0][i] = i; /* symbols with a '0' at the bit0 (leftmost)*/ - soft_table->idx[1][0][i] = i+8; /* symbols with a '1' at the bit0 (leftmost)*/ - } - /* symbols with a '0' ans '1' at the bit position 1: */ - for (i=0;i<4;i++) { - soft_table->idx[0][1][i] = i; - soft_table->idx[0][1][i+4] = i+8; - soft_table->idx[1][1][i] = i+4; - soft_table->idx[1][1][i+4] = i+12; - } - /* symbols with a '0' ans '1' at the bit position 2: */ - for (j=0;j<4;j++) { - for (i=0;i<2;i++) { - soft_table->idx[0][2][i+2*j] = i + 4*j; - soft_table->idx[1][2][i+2*j] = i+2 + 4*j; - } - } - /* symbols with a '0' ans '1' at the bit position 3: */ - for (i=0;i<8;i++) { - soft_table->idx[0][3][i] = 2*i; - soft_table->idx[1][3][i] = 2*i+1; - } - - LLR_approx_params(table, soft_table, 4); /* last param indication B (bits per symbol) */ } /** * Set the 64QAM modulation table */ -void set_64QAMtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_soft_demod) +void set_64QAMtable(cf_t* table) { - uint32_t i,j; // LTE-64QAM constellation: // see [3GPP TS 36.211 version 10.5.0 Release 10, Section 7.1.4] table[0] = QAM64_LEVEL_2 + QAM64_LEVEL_2*_Complex_I; @@ -247,144 +163,5 @@ void set_64QAMtable(cf_t* table, srslte_soft_table_t *soft_table, bool compute_s table[61] = -QAM64_LEVEL_3 - QAM64_LEVEL_4*_Complex_I; table[62] = -QAM64_LEVEL_4 - QAM64_LEVEL_3*_Complex_I; table[63] = -QAM64_LEVEL_4 - QAM64_LEVEL_4*_Complex_I; - - if (!compute_soft_demod) { - return; - } - - /* Matrices identifying the zeros and ones of LTE-64QAM constellation */ - - for (i=0;i<32;i++) { - soft_table->idx[0][0][i] = i; /* symbols with a '0' at the bit0 (leftmost)*/ - soft_table->idx[1][0][i] = i+32; /* symbols with a '1' at the bit0 (leftmost)*/ - } - /* symbols with a '0' ans '1' at the bit position 1: */ - for (i=0;i<16;i++) { - soft_table->idx[0][1][i] = i; - soft_table->idx[0][1][i+16] = i+32; - soft_table->idx[1][1][i] = i+16; - soft_table->idx[1][1][i+16] = i+48; - } - /* symbols with a '0' ans '1' at the bit position 2: */ - for (i=0;i<8;i++) { - soft_table->idx[0][2][i] = i; - soft_table->idx[0][2][i+8] = i+16; - soft_table->idx[0][2][i+16] = i+32; - soft_table->idx[0][2][i+24] = i+48; - soft_table->idx[1][2][i] = i+8; - soft_table->idx[1][2][i+8] = i+24; - soft_table->idx[1][2][i+16] = i+40; - soft_table->idx[1][2][i+24] = i+56; - } - /* symbols with a '0' ans '1' at the bit position 3: */ - for (j=0;j<8;j++) { - for (i=0;i<4;i++) { - soft_table->idx[0][3][i+4*j] = i + 8*j; - soft_table->idx[1][3][i+4*j] = i+4 + 8*j; - } - } - /* symbols with a '0' ans '1' at the bit position 4: */ - for (j=0;j<16;j++) { - for (i=0;i<2;i++) { - soft_table->idx[0][4][i+2*j] = i + 4*j; - soft_table->idx[1][4][i+2*j] = i+2 + 4*j; - } - } - /* symbols with a '0' ans '1' at the bit position 5: */ - for (i=0;i<32;i++) { - soft_table->idx[0][5][i] = 2*i; - soft_table->idx[1][5][i] = 2*i+1; - } - - LLR_approx_params(table, soft_table, 6); /* last param indication modulation */ -} - -/* Precompute two tables for calculating the distances based on the received symbol location relative to the constellation points */ -void LLR_approx_params(const cf_t* table, srslte_soft_table_t *soft_table, int B) { - - int i, j, b, k; - float x, y, d0, d1, min_d0, min_d1; - int M, D; - uint32_t min_idx0[64][6], min_idx1[64][6]; - uint32_t count; - int flag; - - - D = B+1; /* number of different distances to be computed */ - //M = pow(2,B); /* number of constellation points */ - switch (B) { - case 1: {M = 2; break;} /* BPSK */ - case 2: {M = 4; break;} /* QPSK */ - case 4: {M = 16; break;} /* 16QAM */ - case 6: {M = 64; break;} /* 64QAM */ - default: {M = 4; break;} /* QPSK */ - } - - for (i=0;iidx[0][b][j]]; - y = __imag__ table[i] - __imag__ table[soft_table->idx[0][b][j]]; - d0 = x*x + y*y; - if (d0 < min_d0) { - min_d0 = d0; - min_idx0[i][b] = soft_table->idx[0][b][j]; - } - - x = __real__ table[i] - __real__ table[soft_table->idx[1][b][j]]; - y = __imag__ table[i] - __imag__ table[soft_table->idx[1][b][j]]; - d1 = x*x + y*y; - if (d1 < min_d1) { - min_d1 = d1; - min_idx1[i][b] = soft_table->idx[1][b][j]; - } - } - } - } - - for (i=0;id_idx[i][j] = -1; /* intialization */ - } - } - - for (i=0;id_idx[i][k]) { - soft_table->min_idx[0][i][b] = k; - flag = 1; /* no new entry to idxdx */ - break; - } - } - - if (flag == 0) { /* new entry to min and d_idx */ - soft_table->d_idx[i][count] = min_idx0[i][b]; - soft_table->min_idx[0][i][b] = count; - count++; - } - } - for (b=0;bd_idx[i][k]) { - soft_table->min_idx[1][i][b] = k; - flag = 1; /* no new entry to d_idx */ - break; - } - } - - if (flag == 0) { /* new entry to min and d_idx */ - soft_table->d_idx[i][count] = min_idx1[i][b]; - soft_table->min_idx[1][i][b] = count; - count++; - } - } - } } diff --git a/srslte/lib/modem/src/lte_tables.h b/srslte/lib/modem/src/lte_tables.h index 2cf5ac3c4..31489c0a2 100644 --- a/srslte/lib/modem/src/lte_tables.h +++ b/srslte/lib/modem/src/lte_tables.h @@ -38,12 +38,11 @@ #define QAM64_LEVEL_3 5/sqrt(42) #define QAM64_LEVEL_4 7/sqrt(42) -//////////////// NUEVO ////////////////////// /* HARD DEMODULATION Thresholds, necessary for obtaining the zone of received symbol for optimized LLR approx implementation */ -#define QAM16_THRESHOLD 2/sqrt(10) -#define QAM64_THRESHOLD_1 2/sqrt(42) -#define QAM64_THRESHOLD_2 4/sqrt(42) -#define QAM64_THRESHOLD_3 6/sqrt(42) +#define QAM16_THRESHOLD 2/sqrt(10) +#define QAM64_THRESHOLD_1 2/sqrt(42) +#define QAM64_THRESHOLD_2 4/sqrt(42) +#define QAM64_THRESHOLD_3 6/sqrt(42) //=========================================// #define QAM64_LEVEL_x 2/sqrt(42) @@ -53,18 +52,10 @@ -void set_BPSKtable(cf_t* table, - srslte_soft_table_t *soft_table, - bool compute_soft_demod); +void set_BPSKtable(cf_t* table); -void set_QPSKtable(cf_t* table, - srslte_soft_table_t *soft_table, - bool compute_soft_demod); +void set_QPSKtable(cf_t* table); -void set_16QAMtable(cf_t* table, - srslte_soft_table_t *soft_table, - bool compute_soft_demod); +void set_16QAMtable(cf_t* table); -void set_64QAMtable(cf_t* table, - srslte_soft_table_t *soft_table, - bool compute_soft_demod); +void set_64QAMtable(cf_t* table); diff --git a/srslte/lib/modem/src/mod.c b/srslte/lib/modem/src/mod.c index b097f0ec7..34b4d5aff 100644 --- a/srslte/lib/modem/src/mod.c +++ b/srslte/lib/modem/src/mod.c @@ -157,7 +157,7 @@ int srslte_mod_modulate_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symb /* High-Level API */ int mod_initialize(srslte_mod_hl* hl) { srslte_modem_table_init(&hl->obj); - if (srslte_modem_table_lte(&hl->obj,hl->init.std,false)) { + if (srslte_modem_table_lte(&hl->obj,hl->init.std)) { return -1; } diff --git a/srslte/lib/modem/src/modem_table.c b/srslte/lib/modem/src/modem_table.c index 61b144a78..292465276 100644 --- a/srslte/lib/modem/src/modem_table.c +++ b/srslte/lib/modem/src/modem_table.c @@ -67,7 +67,7 @@ void srslte_modem_table_reset(srslte_modem_table_t* q) { srslte_modem_table_init(q); } -int srslte_modem_table_set(srslte_modem_table_t* q, cf_t* table, srslte_soft_table_t *soft_table, uint32_t nsymbols, uint32_t nbits_x_symbol) { +int srslte_modem_table_set(srslte_modem_table_t* q, cf_t* table, uint32_t nsymbols, uint32_t nbits_x_symbol) { if (q->nsymbols) { return SRSLTE_ERROR; } @@ -76,12 +76,11 @@ int srslte_modem_table_set(srslte_modem_table_t* q, cf_t* table, srslte_soft_tab return SRSLTE_ERROR; } memcpy(q->symbol_table,table,q->nsymbols*sizeof(cf_t)); - memcpy(&q->soft_table,soft_table,sizeof(srslte_soft_table_t)); q->nbits_x_symbol = nbits_x_symbol; return SRSLTE_SUCCESS; } -int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation, bool compute_soft_demod) { +int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation) { srslte_modem_table_init(q); switch(modulation) { case SRSLTE_MOD_BPSK: @@ -90,7 +89,7 @@ int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation, boo if (table_create(q)) { return SRSLTE_ERROR; } - set_BPSKtable(q->symbol_table, &q->soft_table, compute_soft_demod); + set_BPSKtable(q->symbol_table); break; case SRSLTE_MOD_QPSK: q->nbits_x_symbol = 2; @@ -98,7 +97,7 @@ int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation, boo if (table_create(q)) { return SRSLTE_ERROR; } - set_QPSKtable(q->symbol_table, &q->soft_table, compute_soft_demod); + set_QPSKtable(q->symbol_table); break; case SRSLTE_MOD_16QAM: q->nbits_x_symbol = 4; @@ -106,7 +105,7 @@ int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation, boo if (table_create(q)) { return SRSLTE_ERROR; } - set_16QAMtable(q->symbol_table, &q->soft_table, compute_soft_demod); + set_16QAMtable(q->symbol_table); break; case SRSLTE_MOD_64QAM: q->nbits_x_symbol = 6; @@ -114,7 +113,7 @@ int srslte_modem_table_lte(srslte_modem_table_t* q, srslte_mod_t modulation, boo if (table_create(q)) { return SRSLTE_ERROR; } - set_64QAMtable(q->symbol_table, &q->soft_table, compute_soft_demod); + set_64QAMtable(q->symbol_table); break; } return SRSLTE_SUCCESS; diff --git a/srslte/lib/modem/src/soft_algs.c b/srslte/lib/modem/src/soft_algs.c deleted file mode 100644 index b021d3f2b..000000000 --- a/srslte/lib/modem/src/soft_algs.c +++ /dev/null @@ -1,696 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - - -#include -#include -#include -#include -#include - -#include "soft_algs.h" -#include "srslte/utils/vector.h" - -#define QAM16_THRESHOLD 2/sqrt(10) -#define QAM64_THRESHOLD_1 2/sqrt(42) -#define QAM64_THRESHOLD_2 4/sqrt(42) -#define QAM64_THRESHOLD_3 6/sqrt(42) - - - - -// There are 3 implemenations: 1 - based on zones; 2 - using volk, 3 - straightforward C -#define LLR_SRSLTE_DEMOD_SOFT_ALG_APPROX_IMPLEMENTATION 1 - -#if LLR_SRSLTE_DEMOD_SOFT_ALG_APPROX_IMPLEMENTATION == 1 - - -/** - * @ingroup Received modulation symbol zone - * Determine location of received modulation symbol - * - * \param in input symbol (_Complex float) - * \param z associated zone in constellation diagram (int) - * \param N number of symbols - */ -static void zone_QPSK(const cf_t * in, uint32_t * z, int N) -{ - - int s; - float re, im; - - for (s = 0; s < N; s++) { - - re = __real__ in[s]; - im = __imag__ in[s]; - - if (re > 0) { - if (im > 0) { /* 1st Quadrand (upper-right) */ - z[s] = 0; - } else { /* 4th Quadrand (lower-right) */ - z[s] = 1; - } - } else { - if (im > 0) { /* 2nd Quadrand (upper-left) */ - z[s] = 2; - } else { /* 3rd Quadrand (lower-left) */ - z[s] = 3; - } - } - } -} - -/** - * @ingroup Received modulation symbol zone - * Determine location of received modulation symbol - * - * \param in input symbol (_Complex float) - * \param z associated zone in constellation diagram (int) - * \param N number of symbols - */ -static void zone_QAM16(const cf_t * in, uint32_t * z, int N) -{ - - int s; - float re, im; - - for (s = 0; s < N; s++) { - - re = __real__ in[s]; - im = __imag__ in[s]; - - if (re > 0) { - if (im > 0) { /* 1st Quadrand (upper-right) */ - if (re > QAM16_THRESHOLD) { - if (im > QAM16_THRESHOLD) { - z[s] = 3; - } else { - z[s] = 2; - } - } else { - if (im > QAM16_THRESHOLD) { - z[s] = 1; - } else { - z[s] = 0; - } - } - } else { /* 4th Quadrand (lower-right) */ - if (re > QAM16_THRESHOLD) { - if (im < -QAM16_THRESHOLD) { - z[s] = 7; - } else { - z[s] = 6; - } - } else { - if (im < -QAM16_THRESHOLD) { - z[s] = 5; - } else { - z[s] = 4; - } - } - } - } else { - if (im > 0) { /* 2nd Quadrand (upper-left) */ - if (re < -QAM16_THRESHOLD) { - if (im > QAM16_THRESHOLD) { - z[s] = 11; - } else { - z[s] = 10; - } - } else { - if (im > QAM16_THRESHOLD) { - z[s] = 9; - } else { - z[s] = 8; - } - } - } else { /* 3rd Quadrand (lower-left) */ - if (re < -QAM16_THRESHOLD) { - if (im < -QAM16_THRESHOLD) { - z[s] = 15; - } else { - z[s] = 14; - } - } else { - if (im < -QAM16_THRESHOLD) { - z[s] = 13; - } else { - z[s] = 12; - } - } - } - } - } -} - -/** - * @ingroup Received modulation symbol zone - * Determine location of received modulation symbol - * - * \param in input symbol (_Complex float) - * \param z associated zone in constellation diagram (int) - * \param N number of symbols - */ - -static void zone_QAM64(const cf_t * in, uint32_t * z, int N) -{ - - int s; - float re, im; - - for (s = 0; s < N; s++) { - - re = __real__ in[s]; - im = __imag__ in[s]; - - if (re > 0) { - - if (im > 0) { - - if (re > QAM64_THRESHOLD_2) { - - if (re > QAM64_THRESHOLD_3) { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 15; - } else { - z[s] = 14; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 10; - } else { - z[s] = 11; - } - - } else { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 13; - } else { - z[s] = 12; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 8; - } else { - z[s] = 9; - } - } - - } else if (re > QAM64_THRESHOLD_1) { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 5; - } else { - z[s] = 4; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 0; - } else { - z[s] = 1; - } - - } else { - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 7; - } else { - z[s] = 6; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 2; - } else { - z[s] = 3; - } - } - - } else { /* forth quadrant (lower-right) */ - - if (re > QAM64_THRESHOLD_2) { - - if (re > QAM64_THRESHOLD_3) { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 31; - } else { - z[s] = 30; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 26; - } else { - z[s] = 27; - } - - } else { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 29; - } else { - z[s] = 28; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 24; - } else { - z[s] = 25; - } - } - - } else if (re > QAM64_THRESHOLD_1) { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 21; - } else { - z[s] = 20; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 16; - } else { - z[s] = 17; - } - - } else { - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 23; - } else { - z[s] = 22; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 18; - } else { - z[s] = 19; - } - } - } - - } else { /* re < 0 */ - - if (im > 0) { /* second quadrant (upper-left) */ - - if (re < -QAM64_THRESHOLD_2) { - - if (re < -QAM64_THRESHOLD_3) { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 47; - } else { - z[s] = 46; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 42; - } else { - z[s] = 43; - } - - } else { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 45; - } else { - z[s] = 44; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 40; - } else { - z[s] = 41; - } - } - - } else if (re < -QAM64_THRESHOLD_1) { - - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 37; - } else { - z[s] = 36; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 32; - } else { - z[s] = 33; - } - - } else { - if (im > QAM64_THRESHOLD_2) { - if (im > QAM64_THRESHOLD_3) { - z[s] = 39; - } else { - z[s] = 38; - } - } else if (im > QAM64_THRESHOLD_1) { - z[s] = 34; - } else { - z[s] = 35; - } - } - } else { /* third quadrant (lower-left) */ - if (re < -QAM64_THRESHOLD_2) { - - if (re < -QAM64_THRESHOLD_3) { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 63; - } else { - z[s] = 62; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 58; - } else { - z[s] = 59; - } - - } else { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 61; - } else { - z[s] = 60; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 56; - } else { - z[s] = 57; - } - } - - } else if (re < -QAM64_THRESHOLD_1) { - - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 53; - } else { - z[s] = 52; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 48; - } else { - z[s] = 49; - } - - } else { - if (im < -QAM64_THRESHOLD_2) { - if (im < -QAM64_THRESHOLD_3) { - z[s] = 55; - } else { - z[s] = 54; - } - } else if (im < -QAM64_THRESHOLD_1) { - z[s] = 50; - } else { - z[s] = 51; - } - } - - } - } - } -} - -static void compute_zone(const cf_t * in, uint32_t * z, int N, int B) -{ - switch (B) { - case 1:{ - memset(z, 0, N * sizeof(uint32_t)); - break; - } /* BPSK */ - case 2:{ - zone_QPSK(in, z, N); - break; - } /* QPSK */ - case 4:{ - zone_QAM16(in, z, N); - break; - } /* 16QAM */ - case 6:{ - zone_QAM64(in, z, N); - break; - } /* 64QAM */ - } -} - -static void compute_square_dist(uint32_t *zone, float *dd, const cf_t * in, cf_t * symbols, - uint32_t(*idx)[7], int N, int B) -{ - int s, b; - float *d_ptr; - cf_t symbols_extract[7]; - - for (s = 0; s < N; s++) { /* N: number of received symbols */ - d_ptr = &dd[7*s]; - for (b = 0; b < B + 1; b++) { - symbols_extract[b] = symbols[idx[zone[s]][b]]; - /* only subset of distances to constellation points needed for LLR approx */ - } - srslte_vec_square_dist(in[s], symbols_extract, d_ptr, B + 1); /* B+1 distances to be computed */ - } -} - -static void compute_llr(uint32_t *zone, float *dd, int N, int B, uint32_t(*min)[64][6], float sigma2, - float *out) -{ - int s, b; - for (s = 0; s < N; s++) { - for (b = 0; b < B; b++) { /* bits per symbol */ - out[s * B + b] = - (dd[7*s+min[0][zone[s]][b]] - dd[7*s+min[1][zone[s]][b]]) / sigma2; - } - } -} - -void llr_approx(const _Complex float *in, float *out, int N, int M, int B, - _Complex float *symbols, uint32_t(*S)[6][32], uint32_t(*idx)[7], - uint32_t(*min)[64][6], float sigma2, uint32_t *zone, float *dd) -{ - if ((M == 1) || (M == 2) || (M == 4) || (M == 16) || (M == 64)) { - compute_zone(in, zone, N, B); - compute_square_dist(zone, dd, in, symbols, idx, N, B); - compute_llr(zone, dd, N, B, min, sigma2, out); - } -} - -#elif LLR_SRSLTE_DEMOD_SOFT_ALG_APPROX_IMPLEMENTATION == 2 - -float d[10000][64]; -float num[10000], den[10000]; - -static void compute_square_dist(const cf_t * in, cf_t * symbols, int N, int M) -{ - int s; - float *d_ptr; - for (s = 0; s < N; s++) { - d_ptr = d[s]; - srslte_vec_square_dist(in[s], symbols, d_ptr, M); - } -} - -static void compute_min_dist(uint32_t(*S)[6][32], int N, int B, int M) -{ - int s, b, i; - for (s = 0; s < N; s++) { - for (b = 0; b < B; b++) { /* bits per symbol */ - /* initiate num[b] and den[b] */ - num[s * B + b] = 1e10; - den[s * B + b] = 1e10; - - for (i = 0; i < M / 2; i++) { - if (d[s][S[0][b][i]] < num[s * B + b]) { - num[s * B + b] = d[s][S[0][b][i]]; - } - if (d[s][S[1][b][i]] < den[s * B + b]) { - den[s * B + b] = d[s][S[1][b][i]]; - } - } - } - } -} - -static void compute_llr(int N, int B, float sigma2, float *out) -{ - int s, b; - for (s = 0; s < N; s++) { - for (b = 0; b < B; b++) { /* bits per symbol */ - out[s * B + b] = (num[s * B + b] - den[s * B + b]) / sigma2; - } - } -} - -void llr_approx(const _Complex float *in, float *out, int N, int M, int B, - _Complex float *symbols, uint32_t(*S)[6][32], float sigma2) -{ - - if (M <= 64) { - compute_square_dist(in, symbols, N, M); - - compute_min_dist(S, N, B, M); - - compute_llr(N, B, sigma2, out); - } - for (b = 0; b < B; b++) { /* bits per symbol */ - out[s * B + b] = (num[s * B + b] - den[s * B + b]) / sigma2; - } -} - -void llr_approx(const _Complex float *in, float *out, int N, int M, int B, - _Complex float *symbols, uint32_t(*S)[6][32], uint32_t(*idx)[7], - uint32_t(*min)[64][6], float sigma2) -{ - - if (M <= 64) { - compute_square_dist(in, symbols, N, M); - - compute_min_dist(S, N, B, M); - - compute_llr(N, B, sigma2, out); - } -} - -#else - -/** - * @ingroup Soft Modulation Demapping based on the approximate - * log-likelihood algorithm - * Common algorithm that approximates the log-likelihood ratio. It takes - * only the two closest constellation symbols into account, one with a '0' - * and the other with a '1' at the given bit position. - * - * \param in input symbols (_Complex float) - * \param out output symbols (float) - * \param N Number of input symbols - * \param M Number of constellation points - * \param B Number of bits per symbol - * \param symbols constellation symbols - * \param S Soft demapping auxiliary matrix - * \param sigma2 Noise vatiance - */ -void llr_approx(const _Complex float *in, float *out, int N, int M, int B, - _Complex float *symbols, uint32_t(*S)[6][32], uint32_t(*idx)[7], - uint32_t(*min)[64][6], float sigma2) -{ - int i, s, b; - float num, den; - int change_sign = -1; - float x, y, d[64]; - - for (s = 0; s < N; s++) { /* recevied symbols */ - /* Compute the distances squared d[i] between the received symbol and all constellation points */ - for (i = 0; i < M; i++) { - x = __real__ in[s] - __real__ symbols[i]; - y = __imag__ in[s] - __imag__ symbols[i]; - d[i] = x * x + y * y; - } - - for (b = 0; b < B; b++) { /* bits per symbol */ - /* initiate num[b] and den[b] */ - num = d[S[0][b][0]]; - den = d[S[1][b][0]]; - - /* Minimum distance squared search between recevied symbol and a constellation point with a - '1' and a '0' for each bit position */ - for (i = 1; i < M / 2; i++) { /* half the constellation points have '1'|'0' at any given bit position */ - if (d[S[0][b][i]] < num) { - num = d[S[0][b][i]]; - } - if (d[S[1][b][i]] < den) { - den = d[S[1][b][i]]; - } - } - /* Theoretical LLR and approximate LLR values are positive if - * symbol(s) with '0' is/are closer and negative if symbol(s) - * with '1' are closer. - * Change sign if mapping negative to '0' and positive to '1' */ - out[s * B + b] = change_sign * (den - num) / sigma2; - if (s < 10) - printf("out[%d]=%f=%f/%f\n", s * B + b, out[s * B + b], num, den); - } -/* if (s<10) - printf("out[%d]=%f=%f/%f\n",s*B+b,out[s*B+b], num,den); - */ } - -} - -#endif - -/** - * @ingroup Soft Modulation Demapping based on the approximate - * log-likelihood ratio algorithm - * Common algorithm that approximates the log-likelihood ratio. It takes - * only the two closest constellation symbols into account, one with a '0' - * and the other with a '1' at the given bit position. - * - * \param in input symbols (_Complex float) - * \param out output symbols (float) - * \param N Number of input symbols - * \param M Number of constellation points - * \param B Number of bits per symbol - * \param symbols constellation symbols - * \param S Soft demapping auxiliary matrix - * \param sigma2 Noise vatiance - */ -void llr_exact(const _Complex float *in, float *out, int N, int M, int B, - _Complex float *symbols, uint32_t(*S)[6][32], float sigma2) -{ - int i, s, b; - float num, den; - int change_sign = -1; - float x, y, d[64]; - - for (s = 0; s < N; s++) { /* recevied symbols */ - /* Compute exp{ยท} of the distances squared d[i] between the received symbol and all constellation points */ - for (i = 0; i < M; i++) { - x = __real__ in[s] - __real__ symbols[i]; - y = __imag__ in[s] - __imag__ symbols[i]; - d[i] = exp(-1 * (x * x + y * y) / sigma2); - } - - /* Sum up the corresponding d[i]'s for each bit position */ - for (b = 0; b < B; b++) { /* bits per symbol */ - /* initiate num[b] and den[b] */ - num = 0; - den = 0; - - for (i = 0; i < M / 2; i++) { /* half the constellation points have '1'|'0' at any given bit position */ - num += d[S[0][b][i]]; - den += d[S[1][b][i]]; - } - /* Theoretical LLR and approximate LLR values are positive if - * symbol(s) with '0' is/are closer and negative if symbol(s) - * with '1' are closer. - * Change sign if mapping negative to '0' and positive to '1' */ - out[s * B + b] = change_sign * log(num / den); - } - } -} diff --git a/srslte/lib/modem/src/soft_algs.h b/srslte/lib/modem/src/soft_algs.h deleted file mode 100644 index 0d387b425..000000000 --- a/srslte/lib/modem/src/soft_algs.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2015 The srsLTE Developers. See the - * COPYRIGHT file at the top-level directory of this distribution. - * - * \section LICENSE - * - * This file is part of the srsLTE library. - * - * srsLTE is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * srsLTE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * A copy of the GNU Affero General Public License can be found in - * the LICENSE file in the top-level directory of this distribution - * and at http://www.gnu.org/licenses/. - * - */ - - -/*void llr_approx(const _Complex float *in, - float *out, - int N, - int M, - int B, - _Complex float *symbols, - uint32_t (*S)[6][32], - float sigma2); -*/ -void llr_approx(const _Complex float *in, - float *out, - int N, - int M, - int B, - _Complex float *symbols, - uint32_t (*S)[6][32], - uint32_t (*idx)[7], /*64x7 table of integers [0..63], indices to 7 distances to be computed */ - uint32_t (*min)[64][6], /*2x64x6 table of integers [0..6], indices to 2x6 nearest symbols */ - float sigma2, - uint32_t *zone, - float *dd); - -void llr_exact(const _Complex float *in, - float *out, - int N, - int M, - int B, - _Complex float *symbols, - uint32_t (*S)[6][32], - float sigma2); - diff --git a/srslte/lib/modem/test/CMakeLists.txt b/srslte/lib/modem/test/CMakeLists.txt index e6db30470..c8ea5b161 100644 --- a/srslte/lib/modem/test/CMakeLists.txt +++ b/srslte/lib/modem/test/CMakeLists.txt @@ -31,18 +31,14 @@ ADD_TEST(modem_qpsk modem_test -n 1024 -m 2) ADD_TEST(modem_qam16 modem_test -n 1024 -m 4) ADD_TEST(modem_qam64 modem_test -n 1008 -m 6) -ADD_TEST(modem_bpsk_soft modem_test -n 1024 -m 1 -s) -ADD_TEST(modem_qpsk_soft modem_test -n 1024 -m 2 -s) -ADD_TEST(modem_qam16_soft modem_test -n 1024 -m 4 -s) -ADD_TEST(modem_qam64_soft modem_test -n 1008 -m 6 -s) +ADD_TEST(modem_bpsk_soft modem_test -n 1024 -m 1) +ADD_TEST(modem_qpsk_soft modem_test -n 1024 -m 2) +ADD_TEST(modem_qam16_soft modem_test -n 1024 -m 4) +ADD_TEST(modem_qam64_soft modem_test -n 1008 -m 6) ADD_EXECUTABLE(soft_demod_test soft_demod_test.c) TARGET_LINK_LIBRARIES(soft_demod_test srslte) -ADD_TEST(modem_bpsk_soft_approx soft_demod_test -n 1024 -m 1) -ADD_TEST(modem_qpsk_soft_approx soft_demod_test -n 1024 -m 2) -ADD_TEST(modem_qam16_soft_approx soft_demod_test -n 1024 -m 4) -ADD_TEST(modem_qam64_soft_approx soft_demod_test -n 1008 -m 6) diff --git a/srslte/lib/modem/test/modem_test.c b/srslte/lib/modem/test/modem_test.c index e879cf394..e7d269ad1 100644 --- a/srslte/lib/modem/test/modem_test.c +++ b/srslte/lib/modem/test/modem_test.c @@ -41,29 +41,20 @@ struct timeval x, y; int num_bits = 1000; srslte_mod_t modulation = SRSLTE_MOD_BPSK; -bool soft_output = true, soft_exact = false; void usage(char *prog) { printf("Usage: %s [nmse]\n", prog); printf("\t-n num_bits [Default %d]\n", num_bits); - printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n"); - printf("\t-s soft outputs [Default %s]\n", soft_output?"soft":"hard"); - printf("\t-e soft outputs exact algorithm [Default approx]\n"); + printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "nmse")) != -1) { + while ((opt = getopt(argc, argv, "nm")) != -1) { switch (opt) { case 'n': num_bits = atoi(argv[optind]); break; - case 's': - soft_output = true; - break; - case 'e': - soft_exact = true; - break; case 'm': switch(atoi(argv[optind])) { case 1: @@ -95,7 +86,6 @@ void parse_args(int argc, char **argv) { int main(int argc, char **argv) { int i; srslte_modem_table_t mod; - srslte_demod_hard_t demod_hard; uint8_t *input, *input_bytes, *output; cf_t *symbols, *symbols_bytes; float *llr, *llr2; @@ -103,7 +93,7 @@ int main(int argc, char **argv) { parse_args(argc, argv); /* initialize objects */ - if (srslte_modem_table_lte(&mod, modulation, soft_output)) { + if (srslte_modem_table_lte(&mod, modulation)) { fprintf(stderr, "Error initializing modem table\n"); exit(-1); } @@ -116,11 +106,6 @@ int main(int argc, char **argv) { exit(-1); } - if (!soft_output) { - srslte_demod_hard_init(&demod_hard); - srslte_demod_hard_table_set(&demod_hard, modulation); - } - /* allocate buffers */ input = srslte_vec_malloc(sizeof(uint8_t) * num_bits); if (!input) { @@ -196,18 +181,13 @@ int main(int argc, char **argv) { } printf("Symbols OK\n"); /* demodulate */ - if (soft_output) { - - gettimeofday(&x, NULL); - srslte_demod_soft_demodulate_lte(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=0 ? 1 : 0; - } - } else { - srslte_demod_hard_demodulate(&demod_hard, symbols, output, num_bits / mod.nbits_x_symbol); + 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=0 ? 1 : 0; } /* check errors */ diff --git a/srslte/lib/modem/test/soft_demod_test.c b/srslte/lib/modem/test/soft_demod_test.c index 06c68d888..e69026b55 100644 --- a/srslte/lib/modem/test/soft_demod_test.c +++ b/srslte/lib/modem/test/soft_demod_test.c @@ -116,7 +116,7 @@ int main(int argc, char **argv) { parse_args(argc, argv); /* initialize objects */ - if (srslte_modem_table_lte(&mod, modulation, true)) { + if (srslte_modem_table_lte(&mod, modulation)) { fprintf(stderr, "Error initializing modem table\n"); exit(-1); } @@ -162,7 +162,7 @@ int main(int argc, char **argv) { srslte_mod_modulate(&mod, input, symbols, num_bits); gettimeofday(&t[1], NULL); - srslte_demod_soft_demodulate_lte(modulation, symbols, llr, num_bits / mod.nbits_x_symbol); + srslte_demod_soft_demodulate(modulation, symbols, llr, num_bits / mod.nbits_x_symbol); gettimeofday(&t[2], NULL); get_time_interval(t); diff --git a/srslte/lib/phch/src/pbch.c b/srslte/lib/phch/src/pbch.c index 2e483a31f..dc9af7588 100644 --- a/srslte/lib/phch/src/pbch.c +++ b/srslte/lib/phch/src/pbch.c @@ -156,7 +156,7 @@ int srslte_pbch_init(srslte_pbch_t *q, srslte_cell_t cell) { fprintf(stderr, "Error initializing precoding\n"); } - if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK, true)) { + if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; } if (srslte_sequence_pbch(&q->seq, q->cell.cp, q->cell.id)) { @@ -479,7 +479,7 @@ int srslte_pbch_decode(srslte_pbch_t *q, cf_t *slot1_symbols, cf_t *ce_slot1[SRS } /* demodulate symbols */ - srslte_demod_soft_demodulate_lte(SRSLTE_MOD_QPSK, q->d, &q->llr[nof_bits * (q->frame_idx - 1)], q->nof_symbols); + srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, &q->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. diff --git a/srslte/lib/phch/src/pcfich.c b/srslte/lib/phch/src/pcfich.c index 353d89de1..317fc6602 100644 --- a/srslte/lib/phch/src/pcfich.c +++ b/srslte/lib/phch/src/pcfich.c @@ -79,7 +79,7 @@ int srslte_pcfich_init(srslte_pcfich_t *q, srslte_regs_t *regs, srslte_cell_t ce fprintf(stderr, "Error initializing precoding\n"); } - if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK, true)) { + if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; } @@ -203,7 +203,7 @@ int srslte_pcfich_decode(srslte_pcfich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE } /* demodulate symbols */ - srslte_demod_soft_demodulate_lte(SRSLTE_MOD_QPSK, q->d, q->data_f, q->nof_symbols); + srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->data_f, q->nof_symbols); /* Scramble with the sequence for slot nslot */ srslte_scrambling_f(&q->seq[nsubframe], q->data_f); diff --git a/srslte/lib/phch/src/pdcch.c b/srslte/lib/phch/src/pdcch.c index 1702efd85..7b5755a80 100644 --- a/srslte/lib/phch/src/pdcch.c +++ b/srslte/lib/phch/src/pdcch.c @@ -78,7 +78,7 @@ int srslte_pdcch_init(srslte_pdcch_t *q, srslte_regs_t *regs, srslte_cell_t cell INFO("Init PDCCH: Max bits: %d, %d ports.\n", q->max_bits, q->cell.nof_ports); - if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK, true)) { + if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { goto clean; } if (srslte_crc_init(&q->crc, SRSLTE_LTE_CRC16, 16)) { @@ -420,7 +420,7 @@ int srslte_pdcch_extract_llr(srslte_pdcch_t *q, cf_t *sf_symbols, cf_t *ce[SRSLT } /* demodulate symbols */ - srslte_demod_soft_demodulate_lte(SRSLTE_MOD_QPSK, q->d, q->llr, nof_symbols); + srslte_demod_soft_demodulate(SRSLTE_MOD_QPSK, q->d, q->llr, nof_symbols); /* descramble */ srslte_scrambling_f_offset(&q->seq[nsubframe], q->llr, 0, e_bits); diff --git a/srslte/lib/phch/src/pdsch.c b/srslte/lib/phch/src/pdsch.c index 6f2338fa0..b2e765b49 100644 --- a/srslte/lib/phch/src/pdsch.c +++ b/srslte/lib/phch/src/pdsch.c @@ -219,7 +219,7 @@ int srslte_pdsch_init(srslte_pdsch_t *q, srslte_cell_t cell) { } for (i = 0; i < 4; i++) { - if (srslte_modem_table_lte(&q->mod[i], modulations[i], true)) { + if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); @@ -417,7 +417,7 @@ int srslte_pdsch_decode_rnti(srslte_pdsch_t *q, * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * thus we don't need tot set it in the LLRs normalization */ - srslte_demod_soft_demodulate_lte(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re); + srslte_demod_soft_demodulate(cfg->grant.mcs.mod, q->d, q->e, cfg->nbits.nof_re); /* descramble */ if (rnti != q->rnti) { @@ -535,4 +535,16 @@ int srslte_pdsch_encode_rnti(srslte_pdsch_t *q, } return ret; } + +float srslte_pdsch_average_noi(srslte_pdsch_t *q) +{ + return q->dl_sch.average_nof_iterations; +} + +uint32_t srslte_pdsch_last_noi(srslte_pdsch_t *q) { + return q->dl_sch.nof_iterations; +} + + + \ No newline at end of file diff --git a/srslte/lib/phch/src/phich.c b/srslte/lib/phch/src/phich.c index 38bc780b0..7807f947a 100644 --- a/srslte/lib/phch/src/phich.c +++ b/srslte/lib/phch/src/phich.c @@ -87,7 +87,7 @@ int srslte_phich_init(srslte_phich_t *q, srslte_regs_t *regs, srslte_cell_t cell fprintf(stderr, "Error initializing precoding\n"); } - if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_BPSK, true)) { + if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_BPSK)) { goto clean; } @@ -274,7 +274,7 @@ int srslte_phich_decode(srslte_phich_t *q, cf_t *slot_symbols, cf_t *ce[SRSLTE_M if (SRSLTE_VERBOSE_ISDEBUG()) srslte_vec_fprint_c(stdout, q->z, SRSLTE_PHICH_NBITS); - srslte_demod_soft_demodulate_lte(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS); + srslte_demod_soft_demodulate(SRSLTE_MOD_BPSK, q->z, q->data_rx, SRSLTE_PHICH_NBITS); if (ack) { *ack = srslte_phich_ack_decode(q->data_rx, distance); diff --git a/srslte/lib/phch/src/pucch.c b/srslte/lib/phch/src/pucch.c index 6e435afeb..9dc1512d8 100644 --- a/srslte/lib/phch/src/pucch.c +++ b/srslte/lib/phch/src/pucch.c @@ -329,7 +329,7 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) { srslte_pucch_cfg_default(&q->pucch_cfg); - if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK, false)) { + if (srslte_modem_table_lte(&q->mod, SRSLTE_MOD_QPSK)) { return SRSLTE_ERROR; } diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index 448ed70cc..1416cfb78 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -200,7 +200,7 @@ int srslte_pusch_init(srslte_pusch_t *q, srslte_cell_t cell) { q->cell.nof_prb, q->max_re); for (i = 0; i < 4; i++) { - if (srslte_modem_table_lte(&q->mod[i], modulations[i], true)) { + if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); @@ -447,7 +447,7 @@ int srslte_pusch_decode(srslte_pusch_t *q, * The MAX-log-MAP algorithm used in turbo decoding is unsensitive to SNR estimation, * thus we don't need tot set it in the LLRs normalization */ - srslte_demod_soft_demodulate_lte(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); + srslte_demod_soft_demodulate(cfg->grant.mcs.mod, q->d, q->q, cfg->nbits.nof_re); /* descramble */ srslte_scrambling_f_offset(&q->seq[cfg->sf_idx], q->q, 0, cfg->nbits.nof_bits); diff --git a/srslte/lib/phch/src/ra.c b/srslte/lib/phch/src/ra.c index 7613ec0f8..29eb3f334 100644 --- a/srslte/lib/phch/src/ra.c +++ b/srslte/lib/phch/src/ra.c @@ -228,6 +228,7 @@ int srslte_ra_ul_dci_to_grant(srslte_ra_ul_dci_t *dci, uint32_t nof_prb, uint32_ if (!ul_dci_to_grant_mcs(dci, grant)) { // Fill rest of grant structure + grant->mcs.idx = dci->mcs_idx; grant->M_sc = grant->L_prb*SRSLTE_NRE; grant->M_sc_init = grant->M_sc; // FIXME: What should M_sc_init be? grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); @@ -455,6 +456,7 @@ int srslte_ra_dl_dci_to_grant(srslte_ra_dl_dci_t *dci, uint32_t nof_prb, bool cr // Compute MCS if (!dl_dci_to_grant_mcs(dci, grant, crc_is_crnti)) { // Fill rest of grant structure + grant->mcs.idx = dci->mcs_idx; grant->Qm = srslte_mod_bits_x_symbol(grant->mcs.mod); } else { return SRSLTE_ERROR;