diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 850c8f84b..8de64511f 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -79,6 +79,7 @@ int mbsfn_area_id = -1; char *rf_args = ""; char *rf_dev = ""; float rf_amp = 0.8, rf_gain = 60.0, rf_freq = 2400000000; +static bool enable_256qam = false; float output_file_snr = +INFINITY; @@ -145,13 +146,14 @@ void usage(char *prog) { printf("\t-u listen TCP/UDP port for input data (if mbsfn is active then the stream is over mbsfn only) (-1 is random) [Default %d]\n", net_port); printf("\t-v [set srslte_verbose to debug, default none]\n"); printf("\t-s output file SNR [Default %f]\n", output_file_snr); + printf("\t-q Enable/Disable 256QAM modulation (default %s)\n", enable_256qam ? "enabled" : "disabled"); printf("\n"); printf("\t*: See 3GPP 36.212 Table 5.3.3.1.5-4 for more information\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "IadglfmoncpvutxbwMsB")) != -1) { + while ((opt = getopt(argc, argv, "IadglfmoncpqvutxbwMsB")) != -1) { switch (opt) { case 'I': @@ -208,6 +210,9 @@ void parse_args(int argc, char **argv) { case 'B': mbsfn_sf_mask = atoi(argv[optind]); break; + case 'q': + enable_256qam ^= true; + break; default: usage(argv[0]); exit(-1); @@ -920,7 +925,7 @@ int main(int argc, char **argv) { } /* Configure pdsch_cfg parameters */ - if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, transmission_mode, &dci_dl, &pdsch_cfg.grant)) { + if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, transmission_mode, enable_256qam, &dci_dl, &pdsch_cfg.grant)) { ERROR("Error configuring PDSCH\n"); exit(-1); } @@ -955,7 +960,7 @@ int main(int argc, char **argv) { dci_dl.format = SRSLTE_DCI_FORMAT1; /* Configure pdsch_cfg parameters */ - if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, &dci_dl, &pmch_cfg.pdsch_cfg.grant)) { + if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, enable_256qam, &dci_dl, &pmch_cfg.pdsch_cfg.grant)) { ERROR("Error configuring PDSCH\n"); exit(-1); } diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 241955da3..80be1a09d 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -81,12 +81,12 @@ typedef struct { int cpu_affinity; bool disable_plots; bool disable_plots_except_constellation; - bool disable_cfo; - uint32_t time_offset; + bool disable_cfo; + uint32_t time_offset; int force_N_id_2; uint16_t rnti; char *input_file_name; - int file_offset_time; + int file_offset_time; float file_offset_freq; uint32_t file_nof_prb; uint32_t file_nof_ports; @@ -94,13 +94,13 @@ typedef struct { bool enable_cfo_ref; bool average_subframe; char *rf_dev; - char *rf_args; - uint32_t rf_nof_rx_ant; - double rf_freq; + char* rf_args; + uint32_t rf_nof_rx_ant; + double rf_freq; float rf_gain; - int net_port; - char *net_address; - int net_port_signal; + int net_port; + char* net_address; + int net_port_signal; char *net_address_signal; int decimate; int32_t mbsfn_area_id; @@ -109,31 +109,33 @@ typedef struct { int tdd_special_sf; int sf_config; int verbose; + bool enable_256qam; }prog_args_t; void args_default(prog_args_t* args) { args->disable_plots = false; args->disable_plots_except_constellation = false; - args->nof_subframes = -1; - args->rnti = SRSLTE_SIRNTI; - args->force_N_id_2 = -1; // Pick the best + args->nof_subframes = -1; + args->rnti = SRSLTE_SIRNTI; + args->force_N_id_2 = -1; // Pick the best args->tdd_special_sf = -1; args->sf_config = -1; - args->input_file_name = NULL; + args->input_file_name = NULL; args->disable_cfo = false; args->time_offset = 0; args->file_nof_prb = 25; args->file_nof_ports = 1; args->file_cell_id = 0; args->file_offset_time = 0; - args->file_offset_freq = 0; - args->rf_dev = ""; - args->rf_args = ""; - args->rf_freq = -1.0; - args->rf_nof_rx_ant = 1; - args->enable_cfo_ref = false; - args->average_subframe = false; + args->file_offset_freq = 0; + args->rf_dev = ""; + args->rf_args = ""; + args->rf_freq = -1.0; + args->rf_nof_rx_ant = 1; + args->enable_cfo_ref = false; + args->average_subframe = false; + args->enable_256qam = false; #ifdef ENABLE_AGC_DEFAULT args->rf_gain = -1.0; #else @@ -192,6 +194,7 @@ void usage(prog_args_t *args, char *prog) { printf("\t-U remote TCP address to send data [Default %s]\n", args->net_address); printf("\t-M MBSFN area id [Default %d]\n", args->mbsfn_area_id); printf("\t-N Non-MBSFN region [Default %d]\n", args->non_mbsfn_region); + printf("\t-q Enable/Disable 256QAM modulation (default %s)\n", args->enable_256qam ? "enabled" : "disabled"); printf("\t-v [set srslte_verbose to debug, default none]\n"); } @@ -199,7 +202,7 @@ void parse_args(prog_args_t *args, int argc, char **argv) { int opt; args_default(args); - while ((opt = getopt(argc, argv, "adAogliIpPcOCtdDFRnvrfuUsSZyWMNBTG")) != -1) { + while ((opt = getopt(argc, argv, "adAogliIpPcOCtdDFRqnvrfuUsSZyWMNBTG")) != -1) { switch (opt) { case 'i': args->input_file_name = argv[optind]; @@ -301,6 +304,9 @@ void parse_args(prog_args_t *args, int argc, char **argv) { case 'B': args->mbsfn_sf_mask = atoi(argv[optind]); break; + case 'q': + args->enable_256qam ^= true; + break; default: usage(args, argv[0]); exit(-1); @@ -393,7 +399,7 @@ int main(int argc, char **argv) { #endif /* ENABLE_GUI */ for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { - data[i] = srslte_vec_malloc(sizeof(uint8_t) * 1500 * 8); + data[i] = srslte_vec_malloc(sizeof(uint8_t) * 2000 * 8); if (!data[i]) { ERROR("Allocating data"); go_exit = true; @@ -783,6 +789,7 @@ int main(int argc, char **argv) { dl_sf.tti = tti; dl_sf.sf_type = sf_type; ue_dl_cfg.cfg.tm = (srslte_tm_t)tm; + ue_dl_cfg.pdsch_use_tbs_index_alt = prog_args.enable_256qam; if ((ue_dl_cfg.cfg.tm == SRSLTE_TM1 && cell.nof_ports == 1) || (ue_dl_cfg.cfg.tm > SRSLTE_TM1 && cell.nof_ports > 1)) { diff --git a/lib/include/srslte/phy/phch/pdsch.h b/lib/include/srslte/phy/phch/pdsch.h index 7757ed698..c0818c662 100644 --- a/lib/include/srslte/phy/phch/pdsch.h +++ b/lib/include/srslte/phy/phch/pdsch.h @@ -72,8 +72,8 @@ typedef struct SRSLTE_API { float *csi[SRSLTE_MAX_CODEWORDS]; /* Channel Strengh Indicator */ /* tx & rx objects */ - srslte_modem_table_t mod[4]; - + srslte_modem_table_t mod[5]; + // This is to generate the scrambling seq for multiple CRNTIs srslte_pdsch_user_t **users; diff --git a/lib/include/srslte/phy/phch/ra.h b/lib/include/srslte/phy/phch/ra.h index e1d82fc05..3a11295dc 100644 --- a/lib/include/srslte/phy/phch/ra.h +++ b/lib/include/srslte/phy/phch/ra.h @@ -103,6 +103,8 @@ SRSLTE_API int srslte_ra_tbs_idx_from_mcs(uint32_t mcs, bool is_ul); SRSLTE_API srslte_mod_t srslte_ra_dl_mod_from_mcs(uint32_t mcs); +SRSLTE_API srslte_mod_t srslte_ra_dl_mod_from_mcs2(uint32_t mcs); + SRSLTE_API srslte_mod_t srslte_ra_ul_mod_from_mcs(uint32_t mcs); SRSLTE_API int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx, bool is_ul); diff --git a/lib/include/srslte/phy/phch/ra_dl.h b/lib/include/srslte/phy/phch/ra_dl.h index fb311505e..4144d993b 100644 --- a/lib/include/srslte/phy/phch/ra_dl.h +++ b/lib/include/srslte/phy/phch/ra_dl.h @@ -44,10 +44,11 @@ **************************************************/ /** Functions to generate a grant from a received DCI */ -SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_cell_t* cell, - srslte_dl_sf_cfg_t* sf, - srslte_tm_t tm, - srslte_dci_dl_t* dci, +SRSLTE_API int srslte_ra_dl_dci_to_grant(srslte_cell_t* cell, + srslte_dl_sf_cfg_t* sf, + srslte_tm_t tm, + bool pdsch_use_tbs_index_alt, + srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant); SRSLTE_API int srslte_ra_dl_grant_to_grant_prb_allocation(srslte_dci_dl_t* dci, @@ -60,7 +61,7 @@ SRSLTE_API uint32_t srslte_ra_dl_approx_nof_re(srslte_cell_t* cell, uint32_t nof SRSLTE_API uint32_t srslte_ra_dl_grant_nof_re(srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, srslte_pdsch_grant_t* grant); /** Others */ -SRSLTE_API int srslte_dl_fill_ra_mcs(srslte_ra_tb_t* tb, int last_tbs, uint32_t nprb); +SRSLTE_API int srslte_dl_fill_ra_mcs(srslte_ra_tb_t* tb, int last_tbs, uint32_t nprb, bool pdsch_use_tbs_index_alt); SRSLTE_API void srslte_ra_dl_compute_nof_re(srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, srslte_pdsch_grant_t* grant); diff --git a/lib/include/srslte/phy/ue/ue_dl.h b/lib/include/srslte/phy/ue/ue_dl.h index ac1777056..6e74107dd 100644 --- a/lib/include/srslte/phy/ue/ue_dl.h +++ b/lib/include/srslte/phy/ue/ue_dl.h @@ -121,6 +121,7 @@ typedef struct SRSLTE_API { srslte_dci_cfg_t dci_cfg; uint32_t last_ri; float snr_to_cqi_offset; + bool pdsch_use_tbs_index_alt; } srslte_ue_dl_cfg_t; typedef struct { diff --git a/lib/src/phy/common/sequence.c b/lib/src/phy/common/sequence.c index ac333c137..ee4884123 100644 --- a/lib/src/phy/common/sequence.c +++ b/lib/src/phy/common/sequence.c @@ -31,7 +31,7 @@ #define Nc 1600 -#define MAX_SEQ_LEN (128*1024) +#define MAX_SEQ_LEN (256 * 1024) #define static_memory diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index d7703d489..9d0ba07e4 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -43,8 +43,8 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { if (q != NULL) { bzero(q, sizeof(srslte_softbuffer_rx_t)); - - ret = srslte_ra_tbs_from_idx(26, nof_prb); + + ret = srslte_ra_tbs_from_idx(33, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; ret = SRSLTE_ERROR; @@ -154,8 +154,8 @@ int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, uint32_t nof_prb) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_softbuffer_tx_t)); - - ret = srslte_ra_tbs_from_idx(26, nof_prb); + + ret = srslte_ra_tbs_from_idx(33, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; diff --git a/lib/src/phy/modem/hard_demod_lte.c b/lib/src/phy/modem/hard_demod_lte.c index f62bd1400..dc07eed24 100644 --- a/lib/src/phy/modem/hard_demod_lte.c +++ b/lib/src/phy/modem/hard_demod_lte.c @@ -212,32 +212,32 @@ inline void hard_qam256_demod(const cf_t* in, uint8_t* out, uint32_t N) out[8 * s + 4] = 0x1; out[8 * s + 6] = 0x1; } else if ((__real__ in[s] > QAM256_THRESHOLD_6) || (__real__ in[s] < -QAM256_THRESHOLD_6)) { - out[6 * s + 2] = 0x1; - out[6 * s + 4] = 0x1; + out[8 * s + 2] = 0x1; + out[8 * s + 4] = 0x1; out[8 * s + 6] = 0x0; } else if ((__real__ in[s] > QAM256_THRESHOLD_5) || (__real__ in[s] < -QAM256_THRESHOLD_5)) { - out[6 * s + 2] = 0x1; - out[6 * s + 4] = 0x0; + out[8 * s + 2] = 0x1; + out[8 * s + 4] = 0x0; out[8 * s + 6] = 0x0; } else if ((__real__ in[s] > QAM256_THRESHOLD_4) || (__real__ in[s] < -QAM256_THRESHOLD_4)) { - out[6 * s + 2] = 0x1; - out[6 * s + 4] = 0x0; + out[8 * s + 2] = 0x1; + out[8 * s + 4] = 0x0; out[8 * s + 6] = 0x1; } else if ((__real__ in[s] > QAM256_THRESHOLD_3) || (__real__ in[s] < -QAM256_THRESHOLD_3)) { - out[6 * s + 2] = 0x0; - out[6 * s + 4] = 0x0; + out[8 * s + 2] = 0x0; + out[8 * s + 4] = 0x0; out[8 * s + 6] = 0x1; } else if ((__real__ in[s] > QAM256_THRESHOLD_2) || (__real__ in[s] < -QAM256_THRESHOLD_2)) { - out[6 * s + 2] = 0x0; - out[6 * s + 4] = 0x1; + out[8 * s + 2] = 0x0; + out[8 * s + 4] = 0x1; out[8 * s + 6] = 0x1; } else if ((__real__ in[s] > QAM256_THRESHOLD_1) || (__real__ in[s] < -QAM256_THRESHOLD_1)) { - out[6 * s + 2] = 0x0; - out[6 * s + 4] = 0x1; + out[8 * s + 2] = 0x0; + out[8 * s + 4] = 0x1; out[8 * s + 6] = 0x0; } else { - out[6 * s + 2] = 0x0; - out[6 * s + 4] = 0x0; + out[8 * s + 2] = 0x0; + out[8 * s + 4] = 0x0; out[8 * s + 6] = 0x0; } @@ -252,32 +252,32 @@ inline void hard_qam256_demod(const cf_t* in, uint8_t* out, uint32_t N) out[8 * s + 5] = 0x1; out[8 * s + 7] = 0x1; } else if ((__imag__ in[s] > QAM256_THRESHOLD_6) || (__imag__ in[s] < -QAM256_THRESHOLD_6)) { - out[6 * s + 3] = 0x1; - out[6 * s + 5] = 0x1; + out[8 * s + 3] = 0x1; + out[8 * s + 5] = 0x1; out[8 * s + 7] = 0x0; } else if ((__imag__ in[s] > QAM256_THRESHOLD_5) || (__imag__ in[s] < -QAM256_THRESHOLD_5)) { - out[6 * s + 3] = 0x1; - out[6 * s + 5] = 0x0; + out[8 * s + 3] = 0x1; + out[8 * s + 5] = 0x0; out[8 * s + 7] = 0x0; } else if ((__imag__ in[s] > QAM256_THRESHOLD_4) || (__imag__ in[s] < -QAM256_THRESHOLD_4)) { - out[6 * s + 3] = 0x1; - out[6 * s + 5] = 0x0; + out[8 * s + 3] = 0x1; + out[8 * s + 5] = 0x0; out[8 * s + 7] = 0x1; } else if ((__imag__ in[s] > QAM256_THRESHOLD_3) || (__imag__ in[s] < -QAM256_THRESHOLD_3)) { - out[6 * s + 3] = 0x0; - out[6 * s + 5] = 0x0; + out[8 * s + 3] = 0x0; + out[8 * s + 5] = 0x0; out[8 * s + 7] = 0x1; } else if ((__imag__ in[s] > QAM256_THRESHOLD_2) || (__imag__ in[s] < -QAM256_THRESHOLD_2)) { - out[6 * s + 3] = 0x0; - out[6 * s + 5] = 0x1; + out[8 * s + 3] = 0x0; + out[8 * s + 5] = 0x1; out[8 * s + 7] = 0x1; } else if ((__imag__ in[s] > QAM256_THRESHOLD_1) || (__imag__ in[s] < -QAM256_THRESHOLD_1)) { - out[6 * s + 3] = 0x0; - out[6 * s + 5] = 0x1; + out[8 * s + 3] = 0x0; + out[8 * s + 5] = 0x1; out[8 * s + 7] = 0x0; } else { - out[6 * s + 3] = 0x0; - out[6 * s + 5] = 0x0; + out[8 * s + 3] = 0x0; + out[8 * s + 5] = 0x0; out[8 * s + 7] = 0x0; } } diff --git a/lib/src/phy/modem/hard_demod_lte.h b/lib/src/phy/modem/hard_demod_lte.h index 0c6585bf8..e49f1ec30 100644 --- a/lib/src/phy/modem/hard_demod_lte.h +++ b/lib/src/phy/modem/hard_demod_lte.h @@ -23,17 +23,17 @@ /* Assume perfect amplitude and phase alignment. * Check threshold values for real case * or implement dynamic threshold adjustent as a function of received symbol amplitudes */ -#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 QAM256_THRESHOLD_1 2 / sqrt(170) -#define QAM256_THRESHOLD_2 4 / sqrt(170) -#define QAM256_THRESHOLD_3 6 / sqrt(170) -#define QAM256_THRESHOLD_4 8 / sqrt(170) -#define QAM256_THRESHOLD_5 10 / sqrt(170) -#define QAM256_THRESHOLD_6 12 / sqrt(170) -#define QAM256_THRESHOLD_7 14 / sqrt(170) +#define QAM16_THRESHOLD (2 / sqrtf(10)) +#define QAM64_THRESHOLD_1 (2 / sqrtf(42)) +#define QAM64_THRESHOLD_2 (4 / sqrtf(42)) +#define QAM64_THRESHOLD_3 (6 / sqrtf(42)) +#define QAM256_THRESHOLD_1 (2 / sqrtf(170)) +#define QAM256_THRESHOLD_2 (4 / sqrtf(170)) +#define QAM256_THRESHOLD_3 (6 / sqrtf(170)) +#define QAM256_THRESHOLD_4 (8 / sqrtf(170)) +#define QAM256_THRESHOLD_5 (10 / sqrtf(170)) +#define QAM256_THRESHOLD_6 (12 / sqrtf(170)) +#define QAM256_THRESHOLD_7 (14 / sqrtf(170)) void hard_bpsk_demod(const cf_t* in, uint8_t* out, diff --git a/lib/src/phy/modem/test/CMakeLists.txt b/lib/src/phy/modem/test/CMakeLists.txt index 3ee9e56cc..0b5fc8cd6 100644 --- a/lib/src/phy/modem/test/CMakeLists.txt +++ b/lib/src/phy/modem/test/CMakeLists.txt @@ -29,13 +29,13 @@ add_test(modem_bpsk modem_test -n 1024 -m 1) 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_qam256 modem_test -n 1024 -m 8) +add_test(modem_qam256 modem_test -n 1024 -m 8) 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_test(modem_qam256_soft modem_test -n 1024 -m 8) +add_test(modem_qam256_soft modem_test -n 1024 -m 8) add_executable(soft_demod_test soft_demod_test.c) target_link_libraries(soft_demod_test srslte_phy) diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index 783adf9d5..ed2b8efb2 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -39,7 +39,7 @@ srslte_mod_t modulation = SRSLTE_MOD_BPSK; 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-m modulation (1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64, 8: QAM256) [Default BPSK]\n"); } void parse_args(int argc, char **argv) { @@ -68,7 +68,7 @@ void parse_args(int argc, char **argv) { break; default: ERROR("Invalid modulation %d. Possible values: " - "(1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64)\n", + "(1: BPSK, 2: QPSK, 4: QAM16, 6: QAM64, 8: QAM256)\n", atoi(argv[optind])); break; } diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 06ab8b99f..2ebf195a9 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -46,8 +46,8 @@ const static float pdsch_cfg_cell_specific_ratio_table[2][4] = { /* One antenna port */ {1.0f / 1.0f, 4.0f / 5.0f, 3.0f / 5.0f, 2.0f / 5.0f}, /* Two or more antenna port */ {5.0f / 4.0f, 1.0f / 1.0f, 3.0f / 4.0f, 1.0f / 2.0f}}; -const static srslte_mod_t modulations[4] = - { SRSLTE_MOD_BPSK, SRSLTE_MOD_QPSK, SRSLTE_MOD_16QAM, SRSLTE_MOD_64QAM }; +const static srslte_mod_t modulations[5] = { + SRSLTE_MOD_BPSK, SRSLTE_MOD_QPSK, SRSLTE_MOD_16QAM, SRSLTE_MOD_64QAM, SRSLTE_MOD_256QAM}; typedef struct { /* Thread identifier: they must set before thread creation */ @@ -247,7 +247,7 @@ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t INFO("Init PDSCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 5; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } @@ -261,7 +261,7 @@ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t 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)); + q->e[i] = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM)); if (!q->e[i]) { goto clean; } @@ -297,7 +297,7 @@ static int pdsch_init(srslte_pdsch_t *q, uint32_t max_prb, bool is_ue, uint32_t goto clean; } - if (srslte_sequence_init(&q->tmp_seq, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { + if (srslte_sequence_init(&q->tmp_seq, q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM))) { goto clean; } @@ -439,7 +439,7 @@ void srslte_pdsch_free(srslte_pdsch_t *q) { srslte_sequence_free(&q->tmp_seq); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 5; i++) { srslte_modem_table_free(&q->mod[i]); } @@ -485,7 +485,7 @@ int srslte_pdsch_set_rnti(srslte_pdsch_t *q, uint16_t rnti) { j, 2 * i, q->cell.id, - q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM))) { + q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_256QAM))) { ERROR("Error initializing PDSCH scrambling sequence\n"); srslte_pdsch_free_rnti(q, rnti); return SRSLTE_ERROR; @@ -589,6 +589,9 @@ static void csi_correction(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, uint32_t case SRSLTE_MOD_64QAM: qm = 6; break; + case SRSLTE_MOD_256QAM: + qm = 8; + break; default: ERROR("No modulation"); } @@ -656,6 +659,17 @@ static void csi_correction(srslte_pdsch_t *q, srslte_pdsch_cfg_t *cfg, uint32_t break; case SRSLTE_MOD_BPSK: break; + case SRSLTE_MOD_256QAM: + for (; i < cfg->grant.tb[tb_idx].nof_bits - 7; i += 8) { + __m128 _csi = _mm_set1_ps(*(csi_v++)); + + _csi = _mm_mul_ps(_csi, _csi_scale); + + _e[0] = _mm_mulhi_pi16(_e[0], _mm_cvtps_pi16(_csi)); + _e[1] = _mm_mulhi_pi16(_e[1], _mm_cvtps_pi16(_csi)); + _e += 2; + } + break; } i /= qm; diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index 75e788aa0..a046d4965 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -397,8 +397,10 @@ void srslte_configure_pmch(srslte_pmch_cfg_t* pmch_cfg, srslte_cell_t* cell, srs pmch_cfg->pdsch_cfg.grant.tb[0].enabled = mbsfn_cfg->enable; pmch_cfg->pdsch_cfg.grant.tb[0].rv = SRSLTE_PMCH_RV; pmch_cfg->pdsch_cfg.grant.last_tbs[0] = 0; - srslte_dl_fill_ra_mcs( - &pmch_cfg->pdsch_cfg.grant.tb[0], pmch_cfg->pdsch_cfg.grant.last_tbs[0], pmch_cfg->pdsch_cfg.grant.nof_prb); + srslte_dl_fill_ra_mcs(&pmch_cfg->pdsch_cfg.grant.tb[0], + pmch_cfg->pdsch_cfg.grant.last_tbs[0], + pmch_cfg->pdsch_cfg.grant.nof_prb, + false); pmch_cfg->pdsch_cfg.grant.nof_tb = 1; pmch_cfg->pdsch_cfg.grant.nof_layers = 1; for (int i = 0; i < 2; i++) { diff --git a/lib/src/phy/phch/ra.c b/lib/src/phy/phch/ra.c index 848a8ecd6..ecd038b28 100644 --- a/lib/src/phy/phch/ra.c +++ b/lib/src/phy/phch/ra.c @@ -151,7 +151,7 @@ srslte_mod_t srslte_ra_dl_mod_from_mcs(uint32_t mcs) return SRSLTE_MOD_16QAM; } else { return SRSLTE_MOD_64QAM; - } + } } srslte_mod_t srslte_ra_ul_mod_from_mcs(uint32_t mcs) @@ -196,7 +196,7 @@ int srslte_ra_mcs_from_tbs_idx(uint32_t tbs_idx, bool is_ul) /* Table 7.1.7.2.1-1: Transport block size table on 36.213 */ int srslte_ra_tbs_from_idx(uint32_t tbs_idx, uint32_t n_prb) { - if (tbs_idx < 27 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { + if (tbs_idx < 34 && n_prb > 0 && n_prb <= SRSLTE_MAX_PRB) { return tbs_table[tbs_idx][n_prb - 1]; } else { return SRSLTE_ERROR; diff --git a/lib/src/phy/phch/ra_dl.c b/lib/src/phy/phch/ra_dl.c index 85db4a69e..444c5db3c 100644 --- a/lib/src/phy/phch/ra_dl.c +++ b/lib/src/phy/phch/ra_dl.c @@ -26,6 +26,7 @@ #include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/vector.h" #include "srslte/srslte.h" +#include "tbs_tables.h" #include #include #include @@ -316,27 +317,46 @@ int srslte_ra_dl_grant_to_grant_prb_allocation(srslte_dci_dl_t* dci, srslte_pdsc return SRSLTE_SUCCESS; } -int srslte_dl_fill_ra_mcs(srslte_ra_tb_t* tb, int last_tbs, uint32_t nprb) +int srslte_dl_fill_ra_mcs(srslte_ra_tb_t* tb, int last_tbs, uint32_t nprb, bool pdsch_use_tbs_index_alt) { int i_tbs = 0; - if (tb->mcs_idx < 10) { - tb->mod = SRSLTE_MOD_QPSK; - i_tbs = tb->mcs_idx; - } else if (tb->mcs_idx < 17) { - tb->mod = SRSLTE_MOD_16QAM; - i_tbs = tb->mcs_idx - 1; - } else if (tb->mcs_idx < 29) { - tb->mod = SRSLTE_MOD_64QAM; - i_tbs = tb->mcs_idx - 2; - } else if (tb->mcs_idx == 29) { - tb->mod = SRSLTE_MOD_QPSK; - i_tbs = -1; - } else if (tb->mcs_idx == 30) { - tb->mod = SRSLTE_MOD_16QAM; - i_tbs = -1; - } else if (tb->mcs_idx == 31) { - tb->mod = SRSLTE_MOD_64QAM; - i_tbs = -1; + if (!pdsch_use_tbs_index_alt) { + // Implements 3GPP 36.211 Table 3.56.35-431 + if (tb->mcs_idx < 10) { + tb->mod = SRSLTE_MOD_QPSK; + i_tbs = tb->mcs_idx; + } else if (tb->mcs_idx < 17) { + tb->mod = SRSLTE_MOD_16QAM; + i_tbs = tb->mcs_idx - 1; + } else if (tb->mcs_idx < 29) { + tb->mod = SRSLTE_MOD_64QAM; + i_tbs = tb->mcs_idx - 2; + } else if (tb->mcs_idx == 29) { + tb->mod = SRSLTE_MOD_QPSK; + i_tbs = -1; + } else if (tb->mcs_idx == 30) { + tb->mod = SRSLTE_MOD_16QAM; + i_tbs = -1; + } else if (tb->mcs_idx == 31) { + tb->mod = SRSLTE_MOD_64QAM; + i_tbs = -1; + } + } else { + if (tb->mcs_idx < 28) { + i_tbs = dl_mcs_tbs_idx_table2[tb->mcs_idx]; + } else { + i_tbs = SRSLTE_ERROR; + } + + if (tb->mcs_idx < 5 || tb->mcs_idx == 28) { + tb->mod = SRSLTE_MOD_QPSK; + } else if (tb->mcs_idx < 11 || tb->mcs_idx == 29) { + tb->mod = SRSLTE_MOD_16QAM; + } else if (tb->mcs_idx < 20 || tb->mcs_idx == 30) { + tb->mod = SRSLTE_MOD_64QAM; + } else { + tb->mod = SRSLTE_MOD_256QAM; + } } // If i_tbs = -1, TBS is determined from the latest PDCCH for this TB (7.1.7.2 36.213) @@ -353,7 +373,7 @@ int srslte_dl_fill_ra_mcs(srslte_ra_tb_t* tb, int last_tbs, uint32_t nprb) /* Modulation order and transport block size determination 7.1.7 in 36.213 * */ -static int dl_dci_compute_tb(srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) +static int dl_dci_compute_tb(bool pdsch_use_tbs_index_alt, srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) { uint32_t n_prb = 0; int tbs = -1; @@ -408,7 +428,7 @@ static int dl_dci_compute_tb(srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) } for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (grant->tb[i].enabled) { - grant->tb[i].tbs = srslte_dl_fill_ra_mcs(&grant->tb[i], grant->last_tbs[i], n_prb); + grant->tb[i].tbs = srslte_dl_fill_ra_mcs(&grant->tb[i], grant->last_tbs[i], n_prb, pdsch_use_tbs_index_alt); if (grant->tb[i].tbs < 0) { ERROR("Computing TBS from MCS=%d, n_prb=%d\n", grant->tb[i].mcs_idx, n_prb); return SRSLTE_ERROR; @@ -606,8 +626,12 @@ static int config_mimo(srslte_cell_t* cell, srslte_tm_t tm, srslte_dci_dl_t* dci **********/ /** Compute the DL grant parameters */ -int srslte_ra_dl_dci_to_grant( - srslte_cell_t* cell, srslte_dl_sf_cfg_t* sf, srslte_tm_t tm, srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) +int srslte_ra_dl_dci_to_grant(srslte_cell_t* cell, + srslte_dl_sf_cfg_t* sf, + srslte_tm_t tm, + bool pdsch_use_tbs_index_alt, + srslte_dci_dl_t* dci, + srslte_pdsch_grant_t* grant) { bzero(grant, sizeof(srslte_pdsch_grant_t)); @@ -615,7 +639,7 @@ int srslte_ra_dl_dci_to_grant( int ret = srslte_ra_dl_grant_to_grant_prb_allocation(dci, grant, cell->nof_prb); if (ret == SRSLTE_SUCCESS) { // Compute MCS - ret = dl_dci_compute_tb(dci, grant); + ret = dl_dci_compute_tb(pdsch_use_tbs_index_alt, dci, grant); if (ret == SRSLTE_SUCCESS) { // Compute number of RE and number of ack_value in grant srslte_ra_dl_compute_nof_re(cell, sf, grant); diff --git a/lib/src/phy/phch/tbs_tables.h b/lib/src/phy/phch/tbs_tables.h index 98f0c8de0..a0743195f 100644 --- a/lib/src/phy/phch/tbs_tables.h +++ b/lib/src/phy/phch/tbs_tables.h @@ -20,281 +20,248 @@ */ /* Modulation and TBS index table for PDSCH from 3GPP TS 36.213 v10.3.0 table 7.1.7.1-1 */ -const int dl_mcs_tbs_idx_table[29] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, - 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; +static const int dl_mcs_tbs_idx_table[29] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, + 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; -/* Modulation and TBS index table for PUSCH from 3GPP TS 36.213 v10.3.0 table 8.6.1-1 */ -const int ul_mcs_tbs_idx_table[29] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26}; +/* Modulation and TBS index table for PDSCH from 3GPP TS 36.213 v12.13.0 table 7.1.7.1-1A */ +static const int dl_mcs_tbs_idx_table2[28] = {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33}; -/* Transport Block Size from 3GPP TS 36.213 v10.3.0 table 7.1.7.2.1-1 */ -const int tbs_table[27][110] = {{ 16, 32, 56, 88, 120, 152, 176, 208, 224, 256, 288, - 328, 344, 376, 392, 424, 456, 488, 504, 536, 568, 600, - 616, 648, 680, 712, 744, 776, 776, 808, 840, 872, 904, - 936, 968, 1000, 1032, 1032, 1064, 1096, 1128, 1160, 1192, 1224, - 1256, 1256, 1288, 1320, 1352, 1384, 1416, 1416, 1480, 1480, 1544, - 1544, 1608, 1608, 1608, 1672, 1672, 1736, 1736, 1800, 1800, 1800, - 1864, 1864, 1928, 1928, 1992, 1992, 2024, 2088, 2088, 2088, 2152, - 2152, 2216, 2216, 2280, 2280, 2280, 2344, 2344, 2408, 2408, 2472, - 2472, 2536, 2536, 2536, 2600, 2600, 2664, 2664, 2728, 2728, 2728, - 2792, 2792, 2856, 2856, 2856, 2984, 2984, 2984, 2984, 2984, 3112}, - { 24, 56, 88, 144, 176, 208, 224, 256, 328, 344, 376, - 424, 456, 488, 520, 568, 600, 632, 680, 712, 744, 776, - 808, 872, 904, 936, 968, 1000, 1032, 1064, 1128, 1160, 1192, - 1224, 1256, 1288, 1352, 1384, 1416, 1416, 1480, 1544, 1544, 1608, - 1608, 1672, 1736, 1736, 1800, 1800, 1864, 1864, 1928, 1992, 1992, - 2024, 2088, 2088, 2152, 2152, 2216, 2280, 2280, 2344, 2344, 2408, - 2472, 2472, 2536, 2536, 2600, 2600, 2664, 2728, 2728, 2792, 2792, - 2856, 2856, 2856, 2984, 2984, 2984, 3112, 3112, 3112, 3240, 3240, - 3240, 3240, 3368, 3368, 3368, 3496, 3496, 3496, 3496, 3624, 3624, - 3624, 3752, 3752, 3752, 3752, 3880, 3880, 3880, 4008, 4008, 4008}, - { 32, 72, 144, 176, 208, 256, 296, 328, 376, 424, 472, - 520, 568, 616, 648, 696, 744, 776, 840, 872, 936, 968, - 1000, 1064, 1096, 1160, 1192, 1256, 1288, 1320, 1384, 1416, 1480, - 1544, 1544, 1608, 1672, 1672, 1736, 1800, 1800, 1864, 1928, 1992, - 2024, 2088, 2088, 2152, 2216, 2216, 2280, 2344, 2344, 2408, 2472, - 2536, 2536, 2600, 2664, 2664, 2728, 2792, 2856, 2856, 2856, 2984, - 2984, 3112, 3112, 3112, 3240, 3240, 3240, 3368, 3368, 3368, 3496, - 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 3880, 4008, - 4008, 4008, 4136, 4136, 4136, 4264, 4264, 4264, 4392, 4392, 4392, - 4584, 4584, 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968}, - { 40, 104, 176, 208, 256, 328, 392, 440, 504, 568, 616, - 680, 744, 808, 872, 904, 968, 1032, 1096, 1160, 1224, 1256, - 1320, 1384, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, - 1992, 2024, 2088, 2152, 2216, 2280, 2344, 2408, 2472, 2536, 2536, - 2600, 2664, 2728, 2792, 2856, 2856, 2984, 2984, 3112, 3112, 3240, - 3240, 3368, 3368, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, - 3880, 4008, 4008, 4136, 4136, 4264, 4264, 4392, 4392, 4392, 4584, - 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968, 4968, 5160, 5160, - 5160, 5352, 5352, 5352, 5352, 5544, 5544, 5544, 5736, 5736, 5736, - 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, 6200, 6456, 6456}, - { 56, 120, 208, 256, 328, 408, 488, 552, 632, 696, 776, - 840, 904, 1000, 1064, 1128, 1192, 1288, 1352, 1416, 1480, 1544, - 1608, 1736, 1800, 1864, 1928, 1992, 2088, 2152, 2216, 2280, 2344, - 2408, 2472, 2600, 2664, 2728, 2792, 2856, 2984, 2984, 3112, 3112, - 3240, 3240, 3368, 3496, 3496, 3624, 3624, 3752, 3752, 3880, 4008, - 4008, 4136, 4136, 4264, 4264, 4392, 4392, 4584, 4584, 4584, 4776, - 4776, 4968, 4968, 4968, 5160, 5160, 5160, 5352, 5352, 5544, 5544, - 5544, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, - 6456, 6456, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 6968, 6968, - 7224, 7224, 7224, 7480, 7480, 7480, 7480, 7736, 7736, 7736, 7992}, - { 72, 144, 224, 328, 424, 504, 600, 680, 776, 872, 968, - 1032, 1128, 1224, 1320, 1384, 1480, 1544, 1672, 1736, 1864, 1928, - 2024, 2088, 2216, 2280, 2344, 2472, 2536, 2664, 2728, 2792, 2856, - 2984, 3112, 3112, 3240, 3368, 3496, 3496, 3624, 3752, 3752, 3880, - 4008, 4008, 4136, 4264, 4392, 4392, 4584, 4584, 4776, 4776, 4776, - 4968, 4968, 5160, 5160, 5352, 5352, 5544, 5544, 5736, 5736, 5736, - 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6712, 6712, 6712, - 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7736, 7736, - 7736, 7992, 7992, 7992, 8248, 8248, 8248, 8504, 8504, 8760, 8760, - 8760, 8760, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9528}, - { 328, 176, 256, 392, 504, 600, 712, 808, 936, 1032, 1128, - 1224, 1352, 1480, 1544, 1672, 1736, 1864, 1992, 2088, 2216, 2280, - 2408, 2472, 2600, 2728, 2792, 2984, 2984, 3112, 3240, 3368, 3496, - 3496, 3624, 3752, 3880, 4008, 4136, 4136, 4264, 4392, 4584, 4584, - 4776, 4776, 4968, 4968, 5160, 5160, 5352, 5352, 5544, 5736, 5736, - 5992, 5992, 5992, 6200, 6200, 6456, 6456, 6456, 6712, 6712, 6968, - 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7736, 7992, 7992, - 8248, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, - 9144, 9528, 9528, 9528, 9528, 9912, 9912, 9912,10296,10296,10296, - 10296,10680,10680,10680,10680,11064,11064,11064,11448,11448,11448}, - { 104, 224, 328, 472, 584, 712, 840, 968, 1096, 1224, 1320, - 1480, 1608, 1672, 1800, 1928, 2088, 2216, 2344, 2472, 2536, 2664, - 2792, 2984, 3112, 3240, 3368, 3368, 3496, 3624, 3752, 3880, 4008, - 4136, 4264, 4392, 4584, 4584, 4776, 4968, 4968, 5160, 5352, 5352, - 5544, 5736, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, 6712, - 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7992, 7992, - 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9528, - 9528, 9528, 9912, 9912, 9912,10296,10296,10296,10680,10680,10680, - 11064,11064,11064,11448,11448,11448,11448,11832,11832,11832,12216, - 12216,12216,12576,12576,12576,12960,12960,12960,12960,13536,13536}, - { 120, 256, 392, 536, 680, 808, 968, 1096, 1256, 1384, 1544, - 1672, 1800, 1928, 2088, 2216, 2344, 2536, 2664, 2792, 2984, 3112, - 3240, 3368, 3496, 3624, 3752, 3880, 4008, 4264, 4392, 4584, 4584, - 4776, 4968, 4968, 5160, 5352, 5544, 5544, 5736, 5992, 5992, 6200, - 6200, 6456, 6456, 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, - 7736, 7992, 7992, 8248, 8504, 8504, 8760, 8760, 9144, 9144, 9144, - 9528, 9528, 9528, 9912, 9912, 9912,10296,10296,10680,10680,10680, - 11064,11064,11064,11448,11448,11448,11832,11832,12216,12216,12216, - 12576,12576,12576,12960,12960,12960,13536,13536,13536,13536,14112, - 14112,14112,14112,14688,14688,14688,14688,15264,15264,15264,15264}, - { 136, 296, 456, 616, 776, 936, 1096, 1256, 1416, 1544, 1736, - 1864, 2024, 2216, 2344, 2536, 2664, 2856, 2984, 3112, 3368, 3496, - 3624, 3752, 4008, 4136, 4264, 4392, 4584, 4776, 4968, 5160, 5160, - 5352, 5544, 5736, 5736, 5992, 6200, 6200, 6456, 6712, 6712, 6968, - 6968, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8248, 8504, 8760, - 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912,10296,10296,10296, - 10680,10680,11064,11064,11064,11448,11448,11832,11832,11832,12216, - 12216,12576,12576,12960,12960,12960,13536,13536,13536,13536,14112, - 14112,14112,14112,14688,14688,14688,15264,15264,15264,15264,15840, - 15840,15840,16416,16416,16416,16416,16992,16992,16992,16992,17568}, - { 144, 328, 504, 680, 872, 1032, 1224, 1384, 1544, 1736, 1928, - 2088, 2280, 2472, 2664, 2792, 2984, 3112, 3368, 3496, 3752, 3880, - 4008, 4264, 4392, 4584, 4776, 4968, 5160, 5352, 5544, 5736, 5736, - 5992, 6200, 6200, 6456, 6712, 6712, 6968, 7224, 7480, 7480, 7736, - 7992, 7992, 8248, 8504, 8504, 8760, 9144, 9144, 9144, 9528, 9528, - 9912, 9912,10296,10296,10680,10680,11064,11064,11448,11448,11448, - 11832,11832,12216,12216,12576,12576,12960,12960,12960,13536,13536, - 13536,14112,14112,14112,14688,14688,14688,14688,15264,15264,15264, - 15840,15840,15840,16416,16416,16416,16992,16992,16992,16992,17568, - 17568,17568,18336,18336,18336,18336,18336,19080,19080,19080,19080}, - { 176, 376, 584, 776, 1000, 1192, 1384, 1608, 1800, 2024, 2216, - 2408, 2600, 2792, 2984, 3240, 3496, 3624, 3880, 4008, 4264, 4392, - 4584, 4776, 4968, 5352, 5544, 5736, 5992, 5992, 6200, 6456, 6712, - 6968, 6968, 7224, 7480, 7736, 7736, 7992, 8248, 8504, 8760, 8760, - 9144, 9144, 9528, 9528, 9912, 9912,10296,10680,10680,11064,11064, - 11448,11448,11832,11832,12216,12216,12576,12576,12960,12960,13536, - 13536,13536,14112,14112,14112,14688,14688,14688,15264,15264,15840, - 15840,15840,16416,16416,16416,16992,16992,16992,17568,17568,17568, - 18336,18336,18336,18336,19080,19080,19080,19080,19848,19848,19848, - 19848,20616,20616,20616,21384,21384,21384,21384,22152,22152,22152}, - { 208, 440, 680, 904, 1128, 1352, 1608, 1800, 2024, 2280, 2472, - 2728, 2984, 3240, 3368, 3624, 3880, 4136, 4392, 4584, 4776, 4968, - 5352, 5544, 5736, 5992, 6200, 6456, 6712, 6712, 6968, 7224, 7480, - 7736, 7992, 8248, 8504, 8760, 8760, 9144, 9528, 9528, 9912, 9912, - 10296,10680,10680,11064,11064,11448,11832,11832,12216,12216,12576, - 12576,12960,12960,13536,13536,14112,14112,14112,14688,14688,15264, - 15264,15264,15840,15840,16416,16416,16416,16992,16992,17568,17568, - 17568,18336,18336,18336,19080,19080,19080,19080,19848,19848,19848, - 20616,20616,20616,21384,21384,21384,21384,22152,22152,22152,22920, - 22920,22920,23688,23688,23688,23688,24496,24496,24496,24496,25456}, - { 224, 488, 744, 1000, 1256, 1544, 1800, 2024, 2280, 2536, 2856, - 3112, 3368, 3624, 3880, 4136, 4392, 4584, 4968, 5160, 5352, 5736, - 5992, 6200, 6456, 6712, 6968, 7224, 7480, 7736, 7992, 8248, 8504, - 8760, 9144, 9144, 9528, 9912, 9912,10296,10680,10680,11064,11448, - 11448,11832,12216,12216,12576,12960,12960,13536,13536,14112,14112, - 14688,14688,14688,15264,15264,15840,15840,16416,16416,16992,16992, - 16992,17568,17568,18336,18336,18336,19080,19080,19080,19848,19848, - 19848,20616,20616,20616,21384,21384,21384,22152,22152,22152,22920, - 22920,22920,23688,23688,23688,24496,24496,24496,25456,25456,25456, - 25456,26416,26416,26416,26416,27376,27376,27376,27376,28336,28336}, - { 256, 552, 840, 1128, 1416, 1736, 1992, 2280, 2600, 2856, 3112, - 3496, 3752, 4008, 4264, 4584, 4968, 5160, 5544, 5736, 5992, 6200, - 6456, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 9144, 9528, - 9912, 9912,10296,10680,11064,11064,11448,11832,12216,12216,12576, - 12960,12960,13536,13536,14112,14112,14688,14688,15264,15264,15840, - 15840,16416,16416,16992,16992,17568,17568,18336,18336,18336,19080, - 19080,19848,19848,19848,20616,20616,20616,21384,21384,22152,22152, - 22152,22920,22920,22920,23688,23688,24496,24496,24496,25456,25456, - 25456,25456,26416,26416,26416,27376,27376,27376,28336,28336,28336, - 28336,29296,29296,29296,29296,30576,30576,30576,30576,31704,31704}, - { 280, 600, 904, 1224, 1544, 1800, 2152, 2472, 2728, 3112, 3368, - 3624, 4008, 4264, 4584, 4968, 5160, 5544, 5736, 6200, 6456, 6712, - 6968, 7224, 7736, 7992, 8248, 8504, 8760, 9144, 9528, 9912,10296, - 10296,10680,11064,11448,11832,11832,12216,12576,12960,12960,13536, - 13536,14112,14688,14688,15264,15264,15840,15840,16416,16416,16992, - 16992,17568,17568,18336,18336,18336,19080,19080,19848,19848,20616, - 20616,20616,21384,21384,22152,22152,22152,22920,22920,23688,23688, - 23688,24496,24496,24496,25456,25456,25456,26416,26416,26416,27376, - 27376,27376,28336,28336,28336,29296,29296,29296,29296,30576,30576, - 30576,30576,31704,31704,31704,31704,32856,32856,32856,34008,34008}, - { 328, 632, 968, 1288, 1608, 1928, 2280, 2600, 2984, 3240, 3624, - 3880, 4264, 4584, 4968, 5160, 5544, 5992, 6200, 6456, 6712, 7224, - 7480, 7736, 7992, 8504, 8760, 9144, 9528, 9912, 9912,10296,10680, - 11064,11448,11832,12216,12216,12576,12960,13536,13536,14112,14112, - 14688,14688,15264,15840,15840,16416,16416,16992,16992,17568,17568, - 18336,18336,19080,19080,19848,19848,19848,20616,20616,21384,21384, - 22152,22152,22152,22920,22920,23688,23688,24496,24496,24496,25456, - 25456,25456,26416,26416,26416,27376,27376,27376,28336,28336,28336, - 29296,29296,29296,30576,30576,30576,30576,31704,31704,31704,31704, - 32856,32856,32856,34008,34008,34008,34008,35160,35160,35160,35160}, - { 336, 696, 1064, 1416, 1800, 2152, 2536, 2856, 3240, 3624, 4008, - 4392, 4776, 5160, 5352, 5736, 6200, 6456, 6712, 7224, 7480, 7992, - 8248, 8760, 9144, 9528, 9912,10296,10296,10680,11064,11448,11832, - 12216,12576,12960,13536,13536,14112,14688,14688,15264,15264,15840, - 16416,16416,16992,17568,17568,18336,18336,19080,19080,19848,19848, - 20616,20616,20616,21384,21384,22152,22152,22920,22920,23688,23688, - 24496,24496,24496,25456,25456,26416,26416,26416,27376,27376,27376, - 28336,28336,29296,29296,29296,30576,30576,30576,30576,31704,31704, - 31704,32856,32856,32856,34008,34008,34008,35160,35160,35160,35160, - 36696,36696,36696,36696,37888,37888,37888,39232,39232,39232,39232}, - { 376, 776, 1160, 1544, 1992, 2344, 2792, 3112, 3624, 4008, 4392, - 4776, 5160, 5544, 5992, 6200, 6712, 7224, 7480, 7992, 8248, 8760, - 9144, 9528, 9912,10296,10680,11064,11448,11832,12216,12576,12960, - 13536,14112,14112,14688,15264,15264,15840,16416,16416,16992,17568, - 17568,18336,18336,19080,19080,19848,19848,20616,21384,21384,22152, - 22152,22920,22920,23688,23688,24496,24496,24496,25456,25456,26416, - 26416,27376,27376,27376,28336,28336,29296,29296,29296,30576,30576, - 30576,31704,31704,31704,32856,32856,32856,34008,34008,34008,35160, - 35160,35160,36696,36696,36696,37888,37888,37888,37888,39232,39232, - 39232,40576,40576,40576,40576,42368,42368,42368,42368,43816,43816}, - { 408, 840, 1288, 1736, 2152, 2600, 2984, 3496, 3880, 4264, 4776, - 5160, 5544, 5992, 6456, 6968, 7224, 7736, 8248, 8504, 9144, 9528, - 9912,10296,10680,11064,11448,12216,12576,12960,13536,13536,14112, - 14688,15264,15264,15840,16416,16992,16992,17568,18336,18336,19080, - 19080,19848,20616,20616,21384,21384,22152,22152,22920,22920,23688, - 24496,24496,25456,25456,25456,26416,26416,27376,27376,28336,28336, - 29296,29296,29296,30576,30576,30576,31704,31704,32856,32856,32856, - 34008,34008,34008,35160,35160,35160,36696,36696,36696,37888,37888, - 37888,39232,39232,39232,40576,40576,40576,40576,42368,42368,42368, - 43816,43816,43816,43816,45352,45352,45352,46888,46888,46888,46888}, - { 440, 904, 1384, 1864, 2344, 2792, 3240, 3752, 4136, 4584, 5160, - 5544, 5992, 6456, 6968, 7480, 7992, 8248, 8760, 9144, 9912,10296, - 10680,11064,11448,12216,12576,12960,13536,14112,14688,14688,15264, - 15840,16416,16992,16992,17568,18336,18336,19080,19848,19848,20616, - 20616,21384,22152,22152,22920,22920,23688,24496,24496,25456,25456, - 26416,26416,27376,27376,28336,28336,29296,29296,29296,30576,30576, - 31704,31704,31704,32856,32856,34008,34008,34008,35160,35160,35160, - 36696,36696,36696,37888,37888,39232,39232,39232,40576,40576,40576, - 42368,42368,42368,42368,43816,43816,43816,45352,45352,45352,46888, - 46888,46888,46888,48936,48936,48936,48936,48936,51024,51024,51024}, - { 488, 1000, 1480, 1992, 2472, 2984, 3496, 4008, 4584, 4968, 5544, - 5992, 6456, 6968, 7480, 7992, 8504, 9144, 9528, 9912,10680,11064, - 11448,12216,12576,12960,13536,14112,14688,15264,15840,15840,16416, - 16992,17568,18336,18336,19080,19848,19848,20616,21384,21384,22152, - 22920,22920,23688,24496,24496,25456,25456,26416,26416,27376,27376, - 28336,28336,29296,29296,30576,30576,31704,31704,31704,32856,32856, - 34008,34008,35160,35160,35160,36696,36696,36696,37888,37888,39232, - 39232,39232,40576,40576,40576,42368,42368,42368,43816,43816,43816, - 45352,45352,45352,46888,46888,46888,46888,48936,48936,48936,48936, - 51024,51024,51024,51024,52752,52752,52752,52752,55056,55056,55056}, - { 520, 1064, 1608, 2152, 2664, 3240, 3752, 4264, 4776, 5352, 5992, - 6456, 6968, 7480, 7992, 8504, 9144, 9528,10296,10680,11448,11832, - 12576,12960,13536,14112,14688,15264,15840,16416,16992,16992,17568, - 18336,19080,19080,19848,20616,21384,21384,22152,22920,22920,23688, - 24496,24496,25456,25456,26416,27376,27376,28336,28336,29296,29296, - 30576,30576,31704,31704,32856,32856,34008,34008,34008,35160,35160, - 36696,36696,36696,37888,37888,39232,39232,40576,40576,40576,42368, - 42368,42368,43816,43816,43816,45352,45352,45352,46888,46888,46888, - 48936,48936,48936,48936,51024,51024,51024,51024,52752,52752,52752, - 55056,55056,55056,55056,57336,57336,57336,57336,59256,59256,59256}, - { 552, 1128, 1736, 2280, 2856, 3496, 4008, 4584, 5160, 5736, 6200, - 6968, 7480, 7992, 8504, 9144, 9912,10296,11064,11448,12216,12576, - 12960,13536,14112,14688,15264,15840,16416,16992,17568,18336,19080, - 19848,19848,20616,21384,22152,22152,22920,23688,24496,24496,25456, - 25456,26416,27376,27376,28336,28336,29296,29296,30576,30576,31704, - 31704,32856,32856,34008,34008,35160,35160,36696,36696,37888,37888, - 37888,39232,39232,40576,40576,40576,42368,42368,43816,43816,43816, - 45352,45352,45352,46888,46888,46888,48936,48936,48936,51024,51024, - 51024,51024,52752,52752,52752,55056,55056,55056,55056,57336,57336, - 57336,57336,59256,59256,59256,59256,61664,61664,61664,61664,63776}, - { 584, 1192, 1800, 2408, 2984, 3624, 4264, 4968, 5544, 5992, 6712, - 7224, 7992, 8504, 9144, 9912,10296,11064,11448,12216,12960,13536, - 14112,14688,15264,15840,16416,16992,17568,18336,19080,19848,19848, - 20616,21384,22152,22920,22920,23688,24496,25456,25456,26416,26416, - 27376,28336,28336,29296,29296,30576,31704,31704,32856,32856,34008, - 34008,35160,35160,36696,36696,36696,37888,37888,39232,39232,40576, - 40576,42368,42368,42368,43816,43816,45352,45352,45352,46888,46888, - 46888,48936,48936,48936,51024,51024,51024,52752,52752,52752,52752, - 55056,55056,55056,57336,57336,57336,57336,59256,59256,59256,61664, - 61664,61664,61664,63776,63776,63776,63776,66592,66592,66592,66592}, - { 616, 1256, 1864, 2536, 3112, 3752, 4392, 5160, 5736, 6200, 6968, - 7480, 8248, 8760, 9528,10296,10680,11448,12216,12576,13536,14112, - 14688,15264,15840,16416,16992,17568,18336,19080,19848,20616,20616, - 21384,22152,22920,23688,24496,24496,25456,26416,26416,27376,28336, - 28336,29296,29296,30576,31704,31704,32856,32856,34008,34008,35160, - 35160,36696,36696,37888,37888,39232,39232,40576,40576,40576,42368, - 42368,43816,43816,43816,45352,45352,46888,46888,46888,48936,48936, - 48936,51024,51024,51024,52752,52752,52752,55056,55056,55056,55056, - 57336,57336,57336,59256,59256,59256,61664,61664,61664,61664,63776, - 63776,63776,63776,66592,66592,66592,66592,68808,68808,68808,71112}, - { 712, 1480, 2216, 2984, 3752, 4392, 5160, 5992, 6712, 7480, 8248, - 8760, 9528,10296,11064,11832,12576,13536,14112,14688,15264,16416, - 16992,17568,18336,19080,19848,20616,21384,22152,22920,23688,24496, - 25456,25456,26416,27376,28336,29296,29296,30576,30576,31704,32856, - 32856,34008,35160,35160,36696,36696,37888,37888,39232,40576,40576, - 40576,42368,42368,43816,43816,45352,45352,46888,46888,48936,48936, - 48936,51024,51024,52752,52752,52752,55056,55056,55056,55056,57336, - 57336,57336,59256,59256,59256,61664,61664,61664,63776,63776,63776, - 66592,66592,66592,68808,68808,68808,71112,71112,71112,73712,73712, - 75376,75376,75376,75376,75376,75376,75376,75376,75376,75376,75376}}; +/* Modulation and TBS index table for PUSCH from 3GPP TS 36.213 v10.3.0 table 8.6.1-1A */ +static const int ul_mcs_tbs_idx_table[29] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26}; + +/* Transport Block Size from 3GPP TS 36.213 v12.13.0 table 7.1.7.2.1-1 */ +static const int tbs_table[34][110] = { + {16, 32, 56, 88, 120, 152, 176, 208, 224, 256, 288, 328, 344, 376, 392, 424, 456, 488, 504, + 536, 568, 600, 616, 648, 680, 712, 744, 776, 776, 808, 840, 872, 904, 936, 968, 1000, 1032, 1032, + 1064, 1096, 1128, 1160, 1192, 1224, 1256, 1256, 1288, 1320, 1352, 1384, 1416, 1416, 1480, 1480, 1544, 1544, 1608, + 1608, 1608, 1672, 1672, 1736, 1736, 1800, 1800, 1800, 1864, 1864, 1928, 1928, 1992, 1992, 2024, 2088, 2088, 2088, + 2152, 2152, 2216, 2216, 2280, 2280, 2280, 2344, 2344, 2408, 2408, 2472, 2472, 2536, 2536, 2536, 2600, 2600, 2664, + 2664, 2728, 2728, 2728, 2792, 2792, 2856, 2856, 2856, 2984, 2984, 2984, 2984, 2984, 3112}, + {24, 56, 88, 144, 176, 208, 224, 256, 328, 344, 376, 424, 456, 488, 520, 568, 600, 632, 680, + 712, 744, 776, 808, 872, 904, 936, 968, 1000, 1032, 1064, 1128, 1160, 1192, 1224, 1256, 1288, 1352, 1384, + 1416, 1416, 1480, 1544, 1544, 1608, 1608, 1672, 1736, 1736, 1800, 1800, 1864, 1864, 1928, 1992, 1992, 2024, 2088, + 2088, 2152, 2152, 2216, 2280, 2280, 2344, 2344, 2408, 2472, 2472, 2536, 2536, 2600, 2600, 2664, 2728, 2728, 2792, + 2792, 2856, 2856, 2856, 2984, 2984, 2984, 3112, 3112, 3112, 3240, 3240, 3240, 3240, 3368, 3368, 3368, 3496, 3496, + 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3752, 3752, 3880, 3880, 3880, 4008, 4008, 4008}, + {32, 72, 144, 176, 208, 256, 296, 328, 376, 424, 472, 520, 568, 616, 648, 696, 744, 776, 840, + 872, 936, 968, 1000, 1064, 1096, 1160, 1192, 1256, 1288, 1320, 1384, 1416, 1480, 1544, 1544, 1608, 1672, 1672, + 1736, 1800, 1800, 1864, 1928, 1992, 2024, 2088, 2088, 2152, 2216, 2216, 2280, 2344, 2344, 2408, 2472, 2536, 2536, + 2600, 2664, 2664, 2728, 2792, 2856, 2856, 2856, 2984, 2984, 3112, 3112, 3112, 3240, 3240, 3240, 3368, 3368, 3368, + 3496, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 3880, 4008, 4008, 4008, 4136, 4136, 4136, 4264, 4264, + 4264, 4392, 4392, 4392, 4584, 4584, 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968}, + {40, 104, 176, 208, 256, 328, 392, 440, 504, 568, 616, 680, 744, 808, 872, 904, 968, 1032, 1096, + 1160, 1224, 1256, 1320, 1384, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 1992, 2024, 2088, 2152, 2216, + 2280, 2344, 2408, 2472, 2536, 2536, 2600, 2664, 2728, 2792, 2856, 2856, 2984, 2984, 3112, 3112, 3240, 3240, 3368, + 3368, 3496, 3496, 3624, 3624, 3624, 3752, 3752, 3880, 3880, 4008, 4008, 4136, 4136, 4264, 4264, 4392, 4392, 4392, + 4584, 4584, 4584, 4776, 4776, 4776, 4776, 4968, 4968, 4968, 5160, 5160, 5160, 5352, 5352, 5352, 5352, 5544, 5544, + 5544, 5736, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, 6200, 6456, 6456}, + {56, 120, 208, 256, 328, 408, 488, 552, 632, 696, 776, 840, 904, 1000, 1064, 1128, 1192, 1288, 1352, + 1416, 1480, 1544, 1608, 1736, 1800, 1864, 1928, 1992, 2088, 2152, 2216, 2280, 2344, 2408, 2472, 2600, 2664, 2728, + 2792, 2856, 2984, 2984, 3112, 3112, 3240, 3240, 3368, 3496, 3496, 3624, 3624, 3752, 3752, 3880, 4008, 4008, 4136, + 4136, 4264, 4264, 4392, 4392, 4584, 4584, 4584, 4776, 4776, 4968, 4968, 4968, 5160, 5160, 5160, 5352, 5352, 5544, + 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6456, 6456, 6712, 6712, 6712, + 6968, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7480, 7736, 7736, 7736, 7992}, + {72, 144, 224, 328, 424, 504, 600, 680, 776, 872, 968, 1032, 1128, 1224, 1320, 1384, 1480, 1544, 1672, + 1736, 1864, 1928, 2024, 2088, 2216, 2280, 2344, 2472, 2536, 2664, 2728, 2792, 2856, 2984, 3112, 3112, 3240, 3368, + 3496, 3496, 3624, 3752, 3752, 3880, 4008, 4008, 4136, 4264, 4392, 4392, 4584, 4584, 4776, 4776, 4776, 4968, 4968, + 5160, 5160, 5352, 5352, 5544, 5544, 5736, 5736, 5736, 5992, 5992, 5992, 6200, 6200, 6200, 6456, 6456, 6712, 6712, + 6712, 6968, 6968, 6968, 7224, 7224, 7224, 7480, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 7992, 8248, 8248, 8248, + 8504, 8504, 8760, 8760, 8760, 8760, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9528}, + {328, 176, 256, 392, 504, 600, 712, 808, 936, 1032, 1128, 1224, 1352, 1480, 1544, 1672, + 1736, 1864, 1992, 2088, 2216, 2280, 2408, 2472, 2600, 2728, 2792, 2984, 2984, 3112, 3240, 3368, + 3496, 3496, 3624, 3752, 3880, 4008, 4136, 4136, 4264, 4392, 4584, 4584, 4776, 4776, 4968, 4968, + 5160, 5160, 5352, 5352, 5544, 5736, 5736, 5992, 5992, 5992, 6200, 6200, 6456, 6456, 6456, 6712, + 6712, 6968, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7736, 7992, 7992, 8248, 8248, 8248, + 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9144, 9528, 9528, 9528, 9528, 9912, 9912, 9912, + 10296, 10296, 10296, 10296, 10680, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448}, + {104, 224, 328, 472, 584, 712, 840, 968, 1096, 1224, 1320, 1480, 1608, 1672, 1800, 1928, + 2088, 2216, 2344, 2472, 2536, 2664, 2792, 2984, 3112, 3240, 3368, 3368, 3496, 3624, 3752, 3880, + 4008, 4136, 4264, 4392, 4584, 4584, 4776, 4968, 4968, 5160, 5352, 5352, 5544, 5736, 5736, 5992, + 5992, 6200, 6200, 6456, 6456, 6712, 6712, 6712, 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, + 7992, 7992, 8248, 8248, 8504, 8504, 8760, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9528, 9912, + 9912, 9912, 10296, 10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11448, 11448, 11832, + 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 12960, 13536, 13536}, + {120, 256, 392, 536, 680, 808, 968, 1096, 1256, 1384, 1544, 1672, 1800, 1928, 2088, 2216, + 2344, 2536, 2664, 2792, 2984, 3112, 3240, 3368, 3496, 3624, 3752, 3880, 4008, 4264, 4392, 4584, + 4584, 4776, 4968, 4968, 5160, 5352, 5544, 5544, 5736, 5992, 5992, 6200, 6200, 6456, 6456, 6712, + 6968, 6968, 7224, 7224, 7480, 7480, 7736, 7736, 7992, 7992, 8248, 8504, 8504, 8760, 8760, 9144, + 9144, 9144, 9528, 9528, 9528, 9912, 9912, 9912, 10296, 10296, 10680, 10680, 10680, 11064, 11064, 11064, + 11448, 11448, 11448, 11832, 11832, 12216, 12216, 12216, 12576, 12576, 12576, 12960, 12960, 12960, 13536, 13536, + 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15264}, + {136, 296, 456, 616, 776, 936, 1096, 1256, 1416, 1544, 1736, 1864, 2024, 2216, 2344, 2536, + 2664, 2856, 2984, 3112, 3368, 3496, 3624, 3752, 4008, 4136, 4264, 4392, 4584, 4776, 4968, 5160, + 5160, 5352, 5544, 5736, 5736, 5992, 6200, 6200, 6456, 6712, 6712, 6968, 6968, 7224, 7480, 7480, + 7736, 7992, 7992, 8248, 8248, 8504, 8760, 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912, 10296, + 10296, 10296, 10680, 10680, 11064, 11064, 11064, 11448, 11448, 11832, 11832, 11832, 12216, 12216, 12576, 12576, + 12960, 12960, 12960, 13536, 13536, 13536, 13536, 14112, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, + 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16416, 16992, 16992, 16992, 16992, 17568}, + {144, 328, 504, 680, 872, 1032, 1224, 1384, 1544, 1736, 1928, 2088, 2280, 2472, 2664, 2792, + 2984, 3112, 3368, 3496, 3752, 3880, 4008, 4264, 4392, 4584, 4776, 4968, 5160, 5352, 5544, 5736, + 5736, 5992, 6200, 6200, 6456, 6712, 6712, 6968, 7224, 7480, 7480, 7736, 7992, 7992, 8248, 8504, + 8504, 8760, 9144, 9144, 9144, 9528, 9528, 9912, 9912, 10296, 10296, 10680, 10680, 11064, 11064, 11448, + 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 12960, 13536, 13536, 13536, 14112, 14112, + 14112, 14688, 14688, 14688, 14688, 15264, 15264, 15264, 15840, 15840, 15840, 16416, 16416, 16416, 16992, 16992, + 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080}, + {176, 376, 584, 776, 1000, 1192, 1384, 1608, 1800, 2024, 2216, 2408, 2600, 2792, 2984, 3240, + 3496, 3624, 3880, 4008, 4264, 4392, 4584, 4776, 4968, 5352, 5544, 5736, 5992, 5992, 6200, 6456, + 6712, 6968, 6968, 7224, 7480, 7736, 7736, 7992, 8248, 8504, 8760, 8760, 9144, 9144, 9528, 9528, + 9912, 9912, 10296, 10680, 10680, 11064, 11064, 11448, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, + 12960, 13536, 13536, 13536, 14112, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 15840, 16416, + 16416, 16416, 16992, 16992, 16992, 17568, 17568, 17568, 18336, 18336, 18336, 18336, 19080, 19080, 19080, 19080, + 19848, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, 22152, 22152}, + {208, 440, 680, 904, 1128, 1352, 1608, 1800, 2024, 2280, 2472, 2728, 2984, 3240, 3368, 3624, + 3880, 4136, 4392, 4584, 4776, 4968, 5352, 5544, 5736, 5992, 6200, 6456, 6712, 6712, 6968, 7224, + 7480, 7736, 7992, 8248, 8504, 8760, 8760, 9144, 9528, 9528, 9912, 9912, 10296, 10680, 10680, 11064, + 11064, 11448, 11832, 11832, 12216, 12216, 12576, 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14112, 14688, + 14688, 15264, 15264, 15264, 15840, 15840, 16416, 16416, 16416, 16992, 16992, 17568, 17568, 17568, 18336, 18336, + 18336, 19080, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 21384, 21384, 22152, + 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 23688, 24496, 24496, 24496, 24496, 25456}, + {224, 488, 744, 1000, 1256, 1544, 1800, 2024, 2280, 2536, 2856, 3112, 3368, 3624, 3880, 4136, + 4392, 4584, 4968, 5160, 5352, 5736, 5992, 6200, 6456, 6712, 6968, 7224, 7480, 7736, 7992, 8248, + 8504, 8760, 9144, 9144, 9528, 9912, 9912, 10296, 10680, 10680, 11064, 11448, 11448, 11832, 12216, 12216, + 12576, 12960, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, + 16992, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19080, 19848, 19848, 19848, 20616, 20616, + 20616, 21384, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 22920, 23688, 23688, 23688, 24496, 24496, 24496, + 25456, 25456, 25456, 25456, 26416, 26416, 26416, 26416, 27376, 27376, 27376, 27376, 28336, 28336}, + {256, 552, 840, 1128, 1416, 1736, 1992, 2280, 2600, 2856, 3112, 3496, 3752, 4008, 4264, 4584, + 4968, 5160, 5544, 5736, 5992, 6200, 6456, 6968, 7224, 7480, 7736, 7992, 8248, 8504, 8760, 9144, + 9528, 9912, 9912, 10296, 10680, 11064, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 12960, 13536, 13536, + 14112, 14112, 14688, 14688, 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, + 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, + 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, + 28336, 28336, 28336, 28336, 29296, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704}, + {280, 600, 904, 1224, 1544, 1800, 2152, 2472, 2728, 3112, 3368, 3624, 4008, 4264, 4584, 4968, + 5160, 5544, 5736, 6200, 6456, 6712, 6968, 7224, 7736, 7992, 8248, 8504, 8760, 9144, 9528, 9912, + 10296, 10296, 10680, 11064, 11448, 11832, 11832, 12216, 12576, 12960, 12960, 13536, 13536, 14112, 14688, 14688, + 15264, 15264, 15840, 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 18336, 19080, 19080, 19848, + 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 23688, 24496, 24496, + 24496, 25456, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, + 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008}, + {328, 632, 968, 1288, 1608, 1928, 2280, 2600, 2984, 3240, 3624, 3880, 4264, 4584, 4968, 5160, + 5544, 5992, 6200, 6456, 6712, 7224, 7480, 7736, 7992, 8504, 8760, 9144, 9528, 9912, 9912, 10296, + 10680, 11064, 11448, 11832, 12216, 12216, 12576, 12960, 13536, 13536, 14112, 14112, 14688, 14688, 15264, 15840, + 15840, 16416, 16416, 16992, 16992, 17568, 17568, 18336, 18336, 19080, 19080, 19848, 19848, 19848, 20616, 20616, + 21384, 21384, 22152, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, 25456, 25456, 26416, + 26416, 26416, 27376, 27376, 27376, 28336, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 30576, 31704, + 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 34008, 35160, 35160, 35160, 35160}, + {336, 696, 1064, 1416, 1800, 2152, 2536, 2856, 3240, 3624, 4008, 4392, 4776, 5160, 5352, 5736, + 6200, 6456, 6712, 7224, 7480, 7992, 8248, 8760, 9144, 9528, 9912, 10296, 10296, 10680, 11064, 11448, + 11832, 12216, 12576, 12960, 13536, 13536, 14112, 14688, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, + 17568, 18336, 18336, 19080, 19080, 19848, 19848, 20616, 20616, 20616, 21384, 21384, 22152, 22152, 22920, 22920, + 23688, 23688, 24496, 24496, 24496, 25456, 25456, 26416, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, + 29296, 29296, 30576, 30576, 30576, 30576, 31704, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, + 35160, 35160, 35160, 36696, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 39232}, + {376, 776, 1160, 1544, 1992, 2344, 2792, 3112, 3624, 4008, 4392, 4776, 5160, 5544, 5992, 6200, + 6712, 7224, 7480, 7992, 8248, 8760, 9144, 9528, 9912, 10296, 10680, 11064, 11448, 11832, 12216, 12576, + 12960, 13536, 14112, 14112, 14688, 15264, 15264, 15840, 16416, 16416, 16992, 17568, 17568, 18336, 18336, 19080, + 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22152, 22920, 22920, 23688, 23688, 24496, 24496, 24496, 25456, + 25456, 26416, 26416, 27376, 27376, 27376, 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, + 31704, 32856, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, + 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816}, + {408, 840, 1288, 1736, 2152, 2600, 2984, 3496, 3880, 4264, 4776, 5160, 5544, 5992, 6456, 6968, + 7224, 7736, 8248, 8504, 9144, 9528, 9912, 10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 13536, + 14112, 14688, 15264, 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19080, 19848, 20616, 20616, + 21384, 21384, 22152, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, 25456, 26416, 26416, 27376, 27376, + 28336, 28336, 29296, 29296, 29296, 30576, 30576, 30576, 31704, 31704, 32856, 32856, 32856, 34008, 34008, 34008, + 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 40576, + 42368, 42368, 42368, 43816, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888}, + {440, 904, 1384, 1864, 2344, 2792, 3240, 3752, 4136, 4584, 5160, 5544, 5992, 6456, 6968, 7480, + 7992, 8248, 8760, 9144, 9912, 10296, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 14688, + 15264, 15840, 16416, 16992, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 20616, 21384, 22152, 22152, + 22920, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 29296, + 30576, 30576, 31704, 31704, 31704, 32856, 32856, 34008, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, + 37888, 37888, 39232, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 42368, 43816, 43816, 43816, 45352, + 45352, 45352, 46888, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 48936, 51024, 51024, 51024}, + {488, 1000, 1480, 1992, 2472, 2984, 3496, 4008, 4584, 4968, 5544, 5992, 6456, 6968, 7480, 7992, + 8504, 9144, 9528, 9912, 10680, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 15840, + 16416, 16992, 17568, 18336, 18336, 19080, 19848, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, + 24496, 25456, 25456, 26416, 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 31704, + 32856, 32856, 34008, 34008, 35160, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 39232, 40576, + 40576, 40576, 42368, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 46888, 48936, + 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056}, + {520, 1064, 1608, 2152, 2664, 3240, 3752, 4264, 4776, 5352, 5992, 6456, 6968, 7480, 7992, 8504, + 9144, 9528, 10296, 10680, 11448, 11832, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 16992, + 17568, 18336, 19080, 19080, 19848, 20616, 21384, 21384, 22152, 22920, 22920, 23688, 24496, 24496, 25456, 25456, + 26416, 27376, 27376, 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 34008, + 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 42368, 43816, + 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 48936, 51024, 51024, 51024, 51024, + 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256}, + {552, 1128, 1736, 2280, 2856, 3496, 4008, 4584, 5160, 5736, 6200, 6968, 7480, 7992, 8504, 9144, + 9912, 10296, 11064, 11448, 12216, 12576, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, + 19080, 19848, 19848, 20616, 21384, 22152, 22152, 22920, 23688, 24496, 24496, 25456, 25456, 26416, 27376, 27376, + 28336, 28336, 29296, 29296, 30576, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, + 37888, 37888, 37888, 39232, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 45352, + 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, + 55056, 57336, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776}, + {584, 1192, 1800, 2408, 2984, 3624, 4264, 4968, 5544, 5992, 6712, 7224, 7992, 8504, 9144, 9912, + 10296, 11064, 11448, 12216, 12960, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, + 19848, 20616, 21384, 22152, 22920, 22920, 23688, 24496, 25456, 25456, 26416, 26416, 27376, 28336, 28336, 29296, + 29296, 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 36696, 37888, 37888, 39232, + 39232, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 45352, 45352, 45352, 46888, 46888, 46888, 48936, 48936, + 48936, 51024, 51024, 51024, 52752, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 57336, 59256, + 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592}, + {616, 1256, 1864, 2536, 3112, 3752, 4392, 5160, 5736, 6200, 6968, 7480, 8248, 8760, 9528, 10296, + 10680, 11448, 12216, 12576, 13536, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, + 20616, 21384, 22152, 22920, 23688, 24496, 24496, 25456, 26416, 26416, 27376, 28336, 28336, 29296, 29296, 30576, + 31704, 31704, 32856, 32856, 34008, 34008, 35160, 35160, 36696, 36696, 37888, 37888, 39232, 39232, 40576, 40576, + 40576, 42368, 42368, 43816, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, + 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, + 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, 68808, 71112}, + {712, 1480, 2216, 2984, 3752, 4392, 5160, 5992, 6712, 7480, 8248, 8760, 9528, 10296, 11064, 11832, + 12576, 13536, 14112, 14688, 15264, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, + 24496, 25456, 25456, 26416, 27376, 28336, 29296, 29296, 30576, 30576, 31704, 32856, 32856, 34008, 35160, 35160, + 36696, 36696, 37888, 37888, 39232, 40576, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, + 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 55056, 57336, 57336, 57336, 59256, + 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, + 71112, 73712, 73712, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376, 75376}, + {648, 1320, 1992, 2664, 3368, 4008, 4584, 5352, 5992, 6712, 7224, 7992, 8504, 9144, 9912, + 10680, 11448, 11832, 12576, 12960, 14112, 14688, 15264, 15840, 16416, 16992, 17568, 18336, 19080, 19848, + 20616, 21384, 22152, 22920, 22920, 23688, 24496, 25456, 25456, 26416, 27376, 27376, 28336, 29296, 29296, + 30576, 31704, 31704, 32856, 32856, 34008, 34008, 35160, 36696, 37888, 39232, 39232, 40576, 40576, 42368, + 42368, 43816, 43816, 43816, 45352, 46888, 46888, 46888, 48936, 48936, 48936, 51024, 51024, 51024, 52752, + 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 59256, 61664, 61664, 61664, + 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, 71112, 71112, 71112, 71112, 73712}, + {680, 1384, 2088, 2792, 3496, 4264, 4968, 5544, 6200, 6968, 7736, 8504, 9144, 9912, 10680, 11064, + 11832, 12576, 13536, 14112, 14688, 15264, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22152, + 22920, 23668, 24496, 25456, 26416, 26416, 27376, 28336, 29296, 29296, 30576, 31704, 32856, 34008, 34008, 35160, + 35160, 36696, 36696, 37888, 39232, 29232, 40576, 40576, 42368, 42368, 42368, 43816, 43816, 45352, 45352, 46888, + 46888, 46888, 48936, 48936, 48936, 51024, 51024, 52752, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, + 59256, 59256, 59256, 61664, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, + 68808, 71112, 71112, 71112, 73712, 73712, 75376, 75376, 76208, 76208}, + {712, 1480, 2216, 2984, 3752, 4392, 5160, 5992, 6712, 7480, 8248, 4760, 9528, 10296, 11064, 11832, + 12576, 13536, 14112, 14668, 15840, 16416, 16992, 17568, 18336, 19080, 19848, 20616, 61384, 22152, 22920, 23688, + 24496, 25456, 26416, 26416, 27376, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 34008, 34008, 35160, 35160, + 36696, 36696, 37888, 39232, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 45352, 46888, 46888, + 48936, 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, + 61664, 61664, 61664, 63776, 63776, 63776, 63776, 66592, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, + 71112, 73712, 73712, 73712, 75376, 76208, 76208, 76208, 78704, 78704, 78704, 81176, 81176, 81176}, + {776, 1544, 2344, 3112, 3880, 4776, 5544, 3200, 3938, 7736, 8504, 9528, 10296, 11064, 11832, 12576, + 13536, 14112, 14688, 15840, 16416, 16992, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, + 25456, 26416, 27276, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 34008, 34008, 35160, 36696, 36696, 37888, + 37888, 39232, 40576, 40576, 42368, 42368, 43816, 43816, 45352, 45352, 46888, 46888, 46888, 48936, 48936, 51024, + 51024, 52752, 52752, 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 63776, 63776, + 63776, 63776, 66592, 66592, 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73712, 75376, 75376, 76208, + 76208, 78704, 78704, 78704, 81176, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936}, + {808, 1608, 2472, 3240, 4136, 4968, 5736, 6456, 7480, 8248, 9144, 9912, 10680, 11148, 12216, 12960, + 14112, 14688, 15840, 16416, 17568, 18336, 19080, 19848, 20616, 21384, 22152, 22920, 23688, 24496, 25456, 26416, + 27376, 28336, 29296, 29296, 30576, 31704, 31704, 32856, 34008, 35160, 35160, 36696, 36696, 37888, 39232, 39232, + 40576, 40576, 42368, 42368, 43816, 45352, 45352, 46888, 46888, 46888, 48396, 48396, 51024, 51024, 52752, 52752, + 52752, 55056, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 63776, 63776, 63776, 66592, 66592, + 66592, 68808, 68808, 68808, 71112, 71112, 71112, 73712, 73715, 73712, 75376, 76208, 76208, 78704, 78704, 78704, + 81176, 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936, 87936, 87936, 90816, 90816}, + {840, 1672, 2536, 3368, 4264, 5160, 5992, 6712, 7736, 8504, 9528, 10296, 11064, 11832, 12960, 13536, + 14688, 15264, 16416, 16992, 17458, 19080, 19848, 20616, 21348, 22152, 22920, 23688, 24496, 25456, 26416, 27376, + 28336, 29296, 29296, 30576, 31704, 32856, 32856, 34008, 35160, 35160, 36696, 37888, 37888, 39232, 39232, 40576, + 40576, 42368, 42368, 43816, 43816, 45352, 46888, 46888, 46888, 48936, 48936, 51024, 51024, 52752, 52752, 52752, + 55056, 55056, 55056, 57336, 57336, 57336, 59256, 59256, 61664, 61664, 61664, 63776, 63776, 63776, 66592, 66592, + 66592, 68808, 68808, 71112, 71112, 71112, 71112, 73712, 73712, 73712, 75376, 76208, 76208, 78704, 78704, 78704, + 81176, 81176, 81176, 84760, 84760, 84760, 84760, 87936, 87936, 87936, 90816, 90816, 93800, 93800}, + {968, 1992, 2984, 4008, 4968, 5992, 6968, 7992, 8760, 9912, 10680, 11832, 12960, 13536, 14688, 15840, + 16992, 17568, 19080, 19848, 20616, 21384, 22920, 23688, 24496, 25456, 26416, 27376, 28336, 29296, 30576, 31704, + 32856, 34008, 35160, 35160, 36696, 37888, 39232, 39232, 40576, 40576, 42368, 43816, 43816, 45352, 46888, 46888, + 48936, 48936, 51024, 51024, 52752, 52752, 55056, 55056, 57336, 57336, 59256, 59256, 59256, 61664, 61664, 63776, + 63776, 63776, 66592, 66592, 68808, 68808, 71112, 71112, 71112, 73712, 75376, 76208, 73208, 76208, 78704, 78704, + 81176, 81176, 81176, 81176, 84760, 84760, 84760, 87636, 87936, 87936, 90816, 90816, 90816, 93800, 93800, 93800, + 93800, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896, 97896}}; diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 2730b6049..a2391c6d9 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -123,6 +123,14 @@ add_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -n 50) add_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -n 75) add_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -n 100) +# PDSCH test for CDD transmision mode (2 codeword) and 256QAM +add_test(pdsch_test_cdd_6 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 6 -q) +add_test(pdsch_test_cdd_12 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 12 -q) +add_test(pdsch_test_cdd_25 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 25 -q) +add_test(pdsch_test_cdd_50 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 50 -q) +add_test(pdsch_test_cdd_75 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 75 -q) +add_test(pdsch_test_cdd_100 pdsch_test -x 3 -a 2 -t 0 -m 27 -M 27 -n 100 -q) + # PDSCH test for Spatial Multiplex transmision mode with PMI = 0 (1 codeword) add_test(pdsch_test_multiplex1cw_p0_6 pdsch_test -x 4 -a 2 -p 0 -n 6) add_test(pdsch_test_multiplex1cw_p0_12 pdsch_test -x 4 -a 2 -p 0 -n 12) diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index 663c930d1..9077d08eb 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -53,7 +53,7 @@ static bool enable_coworker = false; static uint32_t pmi = 0; static char* input_file = NULL; static int M = 1; - +static bool enable_256qam = false; static bool use_8_bit = false; void usage(char *prog) { @@ -76,11 +76,12 @@ void usage(char *prog) { printf("\t-w Swap Transport Blocks\n"); printf("\t-j Enable PDSCH decoder coworker\n"); printf("\t-v [set srslte_verbose to debug, default none]\n"); + printf("\t-q Enable/Disable 256QAM modulation (default %s)\n", enable_256qam ? "enabled" : "disabled"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "fmMcsbrtRFpnawvXxj")) != -1) { + while ((opt = getopt(argc, argv, "fmMcsbrtRFpnqawvXxj")) != -1) { switch(opt) { case 'f': input_file = argv[optind]; @@ -136,6 +137,9 @@ void parse_args(int argc, char **argv) { case 'v': srslte_verbose++; break; + case 'q': + enable_256qam ^= true; + break; default: usage(argv[0]); exit(-1); @@ -143,6 +147,40 @@ void parse_args(int argc, char **argv) { } } +static int check_softbits( + srslte_pdsch_t* pdsch_enb, srslte_pdsch_t* pdsch_ue, srslte_pdsch_cfg_t* pdsch_cfg, uint32_t sf_idx, int tb) +{ + int ret = SRSLTE_SUCCESS; + + if (!pdsch_ue->llr_is_8bit && !tb_cw_swap) { + + // Generate sequence + srslte_sequence_pdsch(&pdsch_ue->tmp_seq, + rnti, + pdsch_cfg->grant.tb[tb].cw_idx, + 2 * (sf_idx % 10), + cell.id, + pdsch_cfg->grant.tb[tb].nof_bits); + + // Scramble + srslte_scrambling_s_offset(&pdsch_ue->tmp_seq, pdsch_ue->e[tb], 0, pdsch_cfg->grant.tb[tb].nof_bits); + + int16_t* rx = pdsch_ue->e[tb]; + uint8_t* rx_bytes = pdsch_ue->e[tb]; + for (int i = 0, k = 0; i < pdsch_cfg->grant.tb[tb].nof_bits / 8; i++) { + uint8_t w = 0; + for (int j = 0; j < 8; j++, k++) { + w |= (rx[k] > 0) ? (1 << (7 - j)) : 0; + } + rx_bytes[i] = w; + } + if (memcmp(pdsch_ue->e[tb], pdsch_enb->e[tb], pdsch_cfg->grant.tb[tb].nof_bits / 8) != 0) { + ret = SRSLTE_ERROR; + } + } + return ret; +} + int main(int argc, char **argv) { int ret = -1; struct timeval t[3] = {}; @@ -235,7 +273,7 @@ int main(int argc, char **argv) { pdsch_cfg.p_b = (tm > SRSLTE_TM1) ? 1 : 0; // 0 dB /* Generate dci from DCI */ - if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, tm, &dci, &pdsch_cfg.grant)) { + if (srslte_ra_dl_dci_to_grant(&cell, &dl_sf, tm, enable_256qam, &dci, &pdsch_cfg.grant)) { ERROR("Error computing resource allocation\n"); return ret; } @@ -470,17 +508,22 @@ int main(int argc, char **argv) { /* Check Tx and Rx bytes */ for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (pdsch_cfg.grant.tb[tb].enabled) { - for (int byte = 0; byte < pdsch_cfg.grant.tb[tb].tbs / 8; byte++) { - if (data_tx[tb][byte] != data_rx[tb][byte]) { - ERROR("Found BYTE (%d) error in TB %d (%02X != %02X), quiting...", - byte, - tb, - data_tx[tb][byte], - data_rx[tb][byte]); - // printf("Tx: "); srslte_vec_fprint_byte(stdout, data_tx[tb], dci.mcs[tb].tbs / 8); - // printf("Rx: "); srslte_vec_fprint_byte(stdout, data_rx[tb], dci.mcs[tb].tbs / 8); - ret = SRSLTE_ERROR; - goto quit; + if (check_softbits(&pdsch_tx, &pdsch_rx, &pdsch_cfg, subframe, tb)) { + printf("TB%d: The received softbits in subframe %d DO NOT match the encoded bits (crc=%d)\n", + tb, + subframe, + pdsch_res[tb].crc); + } else { + for (int byte = 0; byte < pdsch_cfg.grant.tb[tb].tbs / 8; byte++) { + if (data_tx[tb][byte] != data_rx[tb][byte]) { + ERROR("Found BYTE (%d) error in TB %d (%02X != %02X), quitting...", + byte, + tb, + data_tx[tb][byte], + data_rx[tb][byte]); + ret = SRSLTE_ERROR; + goto quit; + } } } } diff --git a/lib/src/phy/phch/test/pmch_file_test.c b/lib/src/phy/phch/test/pmch_file_test.c index 16d38f202..a4079868f 100644 --- a/lib/src/phy/phch/test/pmch_file_test.c +++ b/lib/src/phy/phch/test/pmch_file_test.c @@ -210,7 +210,7 @@ int main(int argc, char **argv) { dci.type0_alloc.rbg_bitmask = 0xffffffff; dci.tb[0].mcs_idx = 2; SRSLTE_DCI_TB_DISABLE(dci.tb[1]); - srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, &dci, &pmch_cfg.pdsch_cfg.grant); + srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, false, &dci, &pmch_cfg.pdsch_cfg.grant); srslte_pdsch_res_t pdsch_res; pdsch_res.payload = data; diff --git a/lib/src/phy/phch/test/pmch_test.c b/lib/src/phy/phch/test/pmch_test.c index 57412f700..28499b79c 100644 --- a/lib/src/phy/phch/test/pmch_test.c +++ b/lib/src/phy/phch/test/pmch_test.c @@ -246,7 +246,7 @@ int main(int argc, char **argv) { dci.type0_alloc.rbg_bitmask = 0xffffffff; dci.tb[0].mcs_idx = mcs_idx; SRSLTE_DCI_TB_DISABLE(dci.tb[1]); - srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, &dci, &pmch_cfg.pdsch_cfg.grant); + srslte_ra_dl_dci_to_grant(&cell, &dl_sf, SRSLTE_TM1, false, &dci, &pmch_cfg.pdsch_cfg.grant); for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (pmch_cfg.pdsch_cfg.grant.tb[i].enabled) { diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index fe171a248..10cc77485 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -651,7 +651,7 @@ int srslte_ue_dl_dci_to_pdsch_grant(srslte_ue_dl_t* q, srslte_dci_dl_t* dci, srslte_pdsch_grant_t* grant) { - return srslte_ra_dl_dci_to_grant(&q->cell, sf, cfg->cfg.tm, dci, grant); + return srslte_ra_dl_dci_to_grant(&q->cell, sf, cfg->cfg.tm, cfg->pdsch_use_tbs_index_alt, dci, grant); } int srslte_ue_dl_decode_pdsch(srslte_ue_dl_t* q, diff --git a/lib/test/phy/CMakeLists.txt b/lib/test/phy/CMakeLists.txt index 900b290cd..96396ec46 100644 --- a/lib/test/phy/CMakeLists.txt +++ b/lib/test/phy/CMakeLists.txt @@ -31,17 +31,28 @@ set(ue_dl_max_mcs 28) set(ue_dl_step_mcs 7) foreach (cell_n_prb 6 15 25 50 75 100) - foreach (ue_dl_tm 1 2 3 4) - foreach (ue_dl_mcs RANGE ${ue_dl_min_mcs} ${ue_dl_max_mcs} ${ue_dl_step_mcs}) - set(phy_dl_test_args "") + foreach (allow_256 0 1) + foreach (ue_dl_tm 1 2 3 4) + foreach (ue_dl_mcs RANGE ${ue_dl_min_mcs} ${ue_dl_max_mcs} ${ue_dl_step_mcs}) + set(phy_dl_test_args "") - set(phy_dl_test_args ${phy_dl_test_args} -p ${cell_n_prb}) - set(phy_dl_test_args ${phy_dl_test_args} -t ${ue_dl_tm}) - set(phy_dl_test_args ${phy_dl_test_args} -m ${ue_dl_mcs}) + set(phy_dl_test_args ${phy_dl_test_args} -p ${cell_n_prb}) + set(phy_dl_test_args ${phy_dl_test_args} -t ${ue_dl_tm}) + if (${allow_256}) + if (${ue_dl_mcs} EQUAL 28) + if (${cell_n_prb} EQUAL 15) + set(ue_dl_mcs 26) + else (${cell_n_prb} EQUAL 15) + set(ue_dl_mcs 27) + endif (${cell_n_prb} EQUAL 15) + endif (${ue_dl_mcs} EQUAL 28) - string(REGEX REPLACE "\ " "" test_name_args ${phy_dl_test_args}) - - add_test(phy_dl_test${test_name_args} phy_dl_test ${phy_dl_test_args}) - endforeach (ue_dl_mcs) - endforeach(ue_dl_tm) + set(phy_dl_test_args ${phy_dl_test_args} -q) + endif (${allow_256}) + set(phy_dl_test_args ${phy_dl_test_args} -m ${ue_dl_mcs}) + string(REGEX REPLACE "\ " "" test_name_args ${phy_dl_test_args}) + add_test(phy_dl_test${test_name_args} phy_dl_test ${phy_dl_test_args}) + endforeach (ue_dl_mcs) + endforeach (ue_dl_tm) + endforeach (allow_256 0 1) endforeach (cell_n_prb) diff --git a/lib/test/phy/phy_dl_test.c b/lib/test/phy/phy_dl_test.c index 7f1c224f4..112f43e10 100644 --- a/lib/test/phy/phy_dl_test.c +++ b/lib/test/phy/phy_dl_test.c @@ -37,14 +37,15 @@ srslte_cell_t cell = { .phich_length = SRSLTE_PHICH_NORM }; -uint32_t transmission_mode = 1; -uint32_t cfi = 1; -uint32_t nof_rx_ant = 1; -uint32_t nof_subframes = 0; -uint16_t rnti = 0x1234; -bool print_dci_table; -uint32_t mcs = 20; -int cross_carrier_indicator = -1; +static uint32_t transmission_mode = 1; +static uint32_t cfi = 1; +static uint32_t nof_rx_ant = 1; +static uint32_t nof_subframes = 0; +static uint16_t rnti = 0x1234; +static bool print_dci_table; +static uint32_t mcs = 20; +static int cross_carrier_indicator = -1; +static bool enable_256qam = false; void usage(char *prog) { printf("Usage: %s [cfpndvs]\n", prog); @@ -62,6 +63,7 @@ void usage(char *prog) { printf("\t\t-a carrier-indicator [Default none]\n"); } printf("\t-v [set srslte_verbose to debug, default none]\n"); + printf("\t-q Enable/Disable 256QAM modulation (default %s)\n", enable_256qam ? "enabled" : "disabled"); } void parse_extensive_param(char* param, char* arg) @@ -81,7 +83,17 @@ void parse_extensive_param(char* param, char* arg) void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "cfapndvstm")) != -1) { + + // Load default transmission mode to avoid wrong number of ports/antennas + if (transmission_mode == 0) { + cell.nof_ports = 1; + nof_rx_ant = 1; + } else if (transmission_mode < 4) { + cell.nof_ports = 2; + nof_rx_ant = 2; + } + + while ((opt = getopt(argc, argv, "cfapndvqstm")) != -1) { switch (opt) { case 't': transmission_mode = (uint32_t)strtol(argv[optind], NULL, 10) - 1; @@ -118,6 +130,9 @@ void parse_args(int argc, char **argv) { case 'v': srslte_verbose++; break; + case 'q': + enable_256qam = (enable_256qam) ? false : true; + break; default: usage(argv[0]); exit(-1); @@ -145,7 +160,7 @@ int work_enb(srslte_enb_dl_t* enb_dl, // Create pdsch config srslte_pdsch_cfg_t pdsch_cfg; - if (srslte_ra_dl_dci_to_grant(&cell, dl_sf, transmission_mode, dci, &pdsch_cfg.grant)) { + if (srslte_ra_dl_dci_to_grant(&cell, dl_sf, transmission_mode, enable_256qam, dci, &pdsch_cfg.grant)) { ERROR("Computing DL grant sf_idx=%d\n", dl_sf->tti); goto quit; } @@ -211,7 +226,8 @@ int work_ue(srslte_ue_dl_t* ue_dl, srslte_dci_dl_info(&dci_dl[0], str, 512); INFO("UE PDCCH: rnti=0x%x, %s\n", rnti, str); - if (srslte_ra_dl_dci_to_grant(&cell, sf_cfg_dl, transmission_mode, &dci_dl[0], &ue_dl_cfg->cfg.pdsch.grant)) { + if (srslte_ra_dl_dci_to_grant( + &cell, sf_cfg_dl, transmission_mode, enable_256qam, &dci_dl[0], &ue_dl_cfg->cfg.pdsch.grant)) { ERROR("Computing DL grant sf_idx=%d\n", sf_idx); return -1; } @@ -236,34 +252,31 @@ int work_ue(srslte_ue_dl_t* ue_dl, unsigned int reverse(register unsigned int x) { - x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); - x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); - x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); - x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); - return ((x >> 16) | (x << 16)); - + x = (((x & (uint32_t)0xaaaaaaaa) >> (uint32_t)1) | ((x & (uint32_t)0x55555555) << (uint32_t)1)); + x = (((x & (uint32_t)0xcccccccc) >> (uint32_t)2) | ((x & (uint32_t)0x33333333) << (uint32_t)2)); + x = (((x & (uint32_t)0xf0f0f0f0) >> (uint32_t)4) | ((x & (uint32_t)0x0f0f0f0f) << (uint32_t)4)); + x = (((x & (uint32_t)0xff00ff00) >> (uint32_t)8) | ((x & (uint32_t)0x00ff00ff) << (uint32_t)8)); + return ((x >> (uint32_t)16) | (x << (uint32_t)16)); } uint32_t prbset_to_bitmask() { uint32_t mask = 0; - int nb = (int)ceilf((float)cell.nof_prb / srslte_ra_type0_P(cell.nof_prb)); - for (int i = 0; i < nb; i++) { + uint32_t nb = (uint32_t)ceilf((float)cell.nof_prb / srslte_ra_type0_P(cell.nof_prb)); + for (uint32_t i = 0; i < nb; i++) { if (i >= prbset_orig && i < prbset_orig + prbset_num) { - mask = mask | (0x1 << i); + mask = mask | ((uint32_t)0x1 << i); } } - return reverse(mask) >> (32 - nb); + return reverse(mask) >> (uint32_t)(32 - nb); } -static srslte_enb_dl_t enb_dl; -static srslte_ue_dl_t ue_dl; - -static int check_softbits(srslte_ue_dl_cfg_t* ue_dl_cfg, uint32_t sf_idx, int tb) +static int +check_softbits(srslte_enb_dl_t* enb_dl, srslte_ue_dl_t* ue_dl, srslte_ue_dl_cfg_t* ue_dl_cfg, uint32_t sf_idx, int tb) { int ret = SRSLTE_SUCCESS; // Generate sequence - srslte_sequence_pdsch(&ue_dl.pdsch.tmp_seq, + srslte_sequence_pdsch(&ue_dl->pdsch.tmp_seq, rnti, ue_dl_cfg->cfg.pdsch.grant.tb[tb].cw_idx, 2 * (sf_idx % 10), @@ -271,32 +284,35 @@ static int check_softbits(srslte_ue_dl_cfg_t* ue_dl_cfg, uint32_t sf_idx, int tb ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits); // Scramble - if (ue_dl.pdsch.llr_is_8bit) { - srslte_scrambling_sb_offset(&ue_dl.pdsch.tmp_seq, ue_dl.pdsch.e[tb], 0, ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits); + if (ue_dl->pdsch.llr_is_8bit) { + srslte_scrambling_sb_offset( + &ue_dl->pdsch.tmp_seq, ue_dl->pdsch.e[tb], 0, ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits); } else { - srslte_scrambling_s_offset(&ue_dl.pdsch.tmp_seq, ue_dl.pdsch.e[tb], 0, ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits); + srslte_scrambling_s_offset( + &ue_dl->pdsch.tmp_seq, ue_dl->pdsch.e[tb], 0, ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits); } - int16_t* rx = ue_dl.pdsch.e[tb]; - uint8_t* rx_bytes = ue_dl.pdsch.e[tb]; + int16_t* rx = ue_dl->pdsch.e[tb]; + uint8_t* rx_bytes = ue_dl->pdsch.e[tb]; for (int i = 0, k = 0; i < ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits / 8; i++) { uint8_t w = 0; for (int j = 0; j < 8; j++, k++) { - w |= (rx[k] > 0) ? (1 << (7 - j)) : 0; + w |= (rx[k] > 0) ? ((uint32_t)1 << (uint32_t)(7 - j)) : 0; } rx_bytes[i] = w; } - if (memcmp(ue_dl.pdsch.e[tb], enb_dl.pdsch.e[tb], ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits / 8) != 0) { + if (memcmp(ue_dl->pdsch.e[tb], enb_dl->pdsch.e[tb], ue_dl_cfg->cfg.pdsch.grant.tb[tb].nof_bits / 8) != 0) { ret = SRSLTE_ERROR; } return ret; } -static int check_evm(srslte_ue_dl_cfg_t* ue_dl_cfg, int tb) +static int check_evm(srslte_enb_dl_t* enb_dl, srslte_ue_dl_t* ue_dl, srslte_ue_dl_cfg_t* ue_dl_cfg, int tb) { int ret = SRSLTE_SUCCESS; - srslte_vec_sub_ccc(enb_dl.pdsch.d[tb], ue_dl.pdsch.d[tb], enb_dl.pdsch.d[tb], ue_dl_cfg->cfg.pdsch.grant.nof_re); - float evm = srslte_vec_avg_power_cf(enb_dl.pdsch.d[tb], ue_dl_cfg->cfg.pdsch.grant.nof_re); + srslte_vec_sub_ccc(enb_dl->pdsch.d[tb], ue_dl->pdsch.d[tb], enb_dl->pdsch.d[tb], ue_dl_cfg->cfg.pdsch.grant.nof_re); + uint32_t evm_max_i = srslte_vec_max_abs_ci(enb_dl->pdsch.d[tb], ue_dl_cfg->cfg.pdsch.grant.nof_re); + float evm = cabsf(enb_dl->pdsch.d[tb][evm_max_i]); if (evm > 0.1f) { printf("TB%d Constellation EVM (%.3f) is too high\n", tb, evm); @@ -307,6 +323,8 @@ static int check_evm(srslte_ue_dl_cfg_t* ue_dl_cfg, int tb) } int main(int argc, char **argv) { + srslte_enb_dl_t* enb_dl = srslte_vec_malloc(sizeof(srslte_enb_dl_t)); + srslte_ue_dl_t* ue_dl = srslte_vec_malloc(sizeof(srslte_ue_dl_t)); srslte_random_t random = srslte_random_init(0); struct timeval t[3] = {}; size_t tx_nof_bits = 0, rx_nof_bits = 0; @@ -374,17 +392,17 @@ int main(int argc, char **argv) { /* * Initialise eNb */ - if (srslte_enb_dl_init(&enb_dl, signal_buffer, cell.nof_prb)) { + if (srslte_enb_dl_init(enb_dl, signal_buffer, cell.nof_prb)) { ERROR("Error initiating eNb downlink\n"); goto quit; } - if (srslte_enb_dl_set_cell(&enb_dl, cell)) { + if (srslte_enb_dl_set_cell(enb_dl, cell)) { ERROR("Error setting eNb DL cell\n"); goto quit; } - if (srslte_enb_dl_add_rnti(&enb_dl, rnti)) { + if (srslte_enb_dl_add_rnti(enb_dl, rnti)) { ERROR("Error adding RNTI\n"); goto quit; } @@ -392,17 +410,17 @@ int main(int argc, char **argv) { /* * Initialise UE */ - if (srslte_ue_dl_init(&ue_dl, signal_buffer, cell.nof_prb, nof_rx_ant)) { + if (srslte_ue_dl_init(ue_dl, signal_buffer, cell.nof_prb, nof_rx_ant)) { ERROR("Error initiating UE downlink\n"); goto quit; } - if (srslte_ue_dl_set_cell(&ue_dl, cell)) { + if (srslte_ue_dl_set_cell(ue_dl, cell)) { ERROR("Error setting UE downlink cell\n"); goto quit; } - srslte_ue_dl_set_rnti(&ue_dl, rnti); + srslte_ue_dl_set_rnti(ue_dl, rnti); /* * Create PDCCH Allocations @@ -417,7 +435,7 @@ int main(int argc, char **argv) { sf_cfg_dl.cfi = cfi; sf_cfg_dl.sf_type = SRSLTE_SF_NORM; - nof_locations[i] = srslte_pdcch_ue_locations(&enb_dl.pdcch, &sf_cfg_dl, dci_locations[i], MAX_CANDIDATES_UE, rnti); + nof_locations[i] = srslte_pdcch_ue_locations(&enb_dl->pdcch, &sf_cfg_dl, dci_locations[i], MAX_CANDIDATES_UE, rnti); location_counter += nof_locations[i]; } @@ -529,7 +547,7 @@ int main(int argc, char **argv) { INFO("--- Process eNb ---\n"); gettimeofday(&t[1], NULL); - if (work_enb(&enb_dl, &sf_cfg_dl, &dci_cfg, &dci, softbuffer_tx, data_tx)) { + if (work_enb(enb_dl, &sf_cfg_dl, &dci_cfg, &dci, softbuffer_tx, data_tx)) { goto quit; } gettimeofday(&t[2], NULL); @@ -576,6 +594,7 @@ int main(int argc, char **argv) { ue_dl_cfg.chest_cfg.cfo_estimate_sf_mask = false; ue_dl_cfg.chest_cfg.sync_error_enable = false; ue_dl_cfg.dci_cfg = dci_cfg; + ue_dl_cfg.pdsch_use_tbs_index_alt = enable_256qam; srslte_pdsch_res_t pdsch_res[SRSLTE_MAX_CODEWORDS]; for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { @@ -584,7 +603,7 @@ int main(int argc, char **argv) { pdsch_res[i].crc = false; ue_dl_cfg.cfg.pdsch.softbuffers.rx[i] = softbuffer_rx[i]; } - if (work_ue(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, dci_dl, sf_idx, pdsch_res)) { + if (work_ue(ue_dl, &sf_cfg_dl, &ue_dl_cfg, dci_dl, sf_idx, pdsch_res)) { goto quit; } @@ -594,15 +613,15 @@ int main(int argc, char **argv) { for (int i = 0; i < SRSLTE_MAX_TB; i++) { if (ue_dl_cfg.cfg.pdsch.grant.tb[i].enabled) { - if (check_evm(&ue_dl_cfg, i)) { + if (check_evm(enb_dl, ue_dl, &ue_dl_cfg, i)) { count_failures++; - } else if (check_softbits(&ue_dl_cfg, sf_idx, i) != SRSLTE_SUCCESS) { + } else if (check_softbits(enb_dl, ue_dl, &ue_dl_cfg, sf_idx, i) != SRSLTE_SUCCESS) { printf("TB%d: The received softbits in subframe %d DO NOT match the encoded bits (crc=%d)\n", i, sf_idx, pdsch_res[i].crc); - srslte_vec_fprint_byte(stdout, (uint8_t*)enb_dl.pdsch.e[i], ue_dl_cfg.cfg.pdsch.grant.tb[i].nof_bits / 8); - srslte_vec_fprint_byte(stdout, (uint8_t*)ue_dl.pdsch.e[i], ue_dl_cfg.cfg.pdsch.grant.tb[i].nof_bits / 8); + srslte_vec_fprint_byte(stdout, (uint8_t*)enb_dl->pdsch.e[i], ue_dl_cfg.cfg.pdsch.grant.tb[i].nof_bits / 8); + srslte_vec_fprint_byte(stdout, (uint8_t*)ue_dl->pdsch.e[i], ue_dl_cfg.cfg.pdsch.grant.tb[i].nof_bits / 8); count_failures++; } else if (!pdsch_res[i].crc || memcmp(data_tx[i], data_rx[i], (uint32_t)ue_dl_cfg.cfg.pdsch.grant.tb[i].tbs / 8) != 0) { @@ -637,18 +656,14 @@ int main(int argc, char **argv) { printf("BLER: %5.1f%%\n", (float) count_failures / (float) count_tbs * 100.0f); quit: - srslte_enb_dl_free(&enb_dl); - srslte_ue_dl_free(&ue_dl); - srslte_random_free(random); + srslte_enb_dl_free(enb_dl); + srslte_ue_dl_free(ue_dl); + srslte_random_free(random); - for ( - int i = 0; - i < cell. - nof_ports; - i++) { - if (signal_buffer[i]) { - free(signal_buffer[i]); - } + for (int i = 0; i < cell.nof_ports; i++) { + if (signal_buffer[i]) { + free(signal_buffer[i]); + } } for ( @@ -672,6 +687,12 @@ int main(int argc, char **argv) { free(data_rx[i]); } } + if (enb_dl) { + free(enb_dl); + } + if (ue_dl) { + free(ue_dl); + } if (ret) { printf("Error\n"); diff --git a/srsenb/src/phy/sf_worker.cc b/srsenb/src/phy/sf_worker.cc index 45a07ce4c..5af9add6f 100644 --- a/srsenb/src/phy/sf_worker.cc +++ b/srsenb/src/phy/sf_worker.cc @@ -779,7 +779,7 @@ int sf_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u // Compute DL grant if (srslte_ra_dl_dci_to_grant( - &phy->cell, &dl_sf, ue_db[rnti]->dl_cfg.tm, &grants[i].dci, &ue_db[rnti]->dl_cfg.pdsch.grant)) { + &phy->cell, &dl_sf, ue_db[rnti]->dl_cfg.tm, false, &grants[i].dci, &ue_db[rnti]->dl_cfg.pdsch.grant)) { Error("Computing DL grant\n"); } diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 409775b80..9c316471c 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -696,8 +696,8 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res) srslte_ra_tb_t mcs_data; mcs.mcs_idx = this->sib13.mbsfn_area_info_list_r9[0].mcch_cfg_r9.sig_mcs_r9; mcs_data.mcs_idx = this->mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].pmch_cfg_r9.data_mcs_r9; - srslte_dl_fill_ra_mcs(&mcs, 0, this->cell_config.cell.nof_prb); - srslte_dl_fill_ra_mcs(&mcs_data, 0, this->cell_config.cell.nof_prb); + srslte_dl_fill_ra_mcs(&mcs, 0, this->cell_config.cell.nof_prb, false); + srslte_dl_fill_ra_mcs(&mcs_data, 0, this->cell_config.cell.nof_prb, false); if (is_mcch) { build_mch_sched(mcs_data.tbs); diff --git a/srsenb/test/mac/scheduler_test_rand.cc b/srsenb/test/mac/scheduler_test_rand.cc index 7a458ba7e..5f498e30d 100644 --- a/srsenb/test/mac/scheduler_test_rand.cc +++ b/srsenb/test/mac/scheduler_test_rand.cc @@ -772,8 +772,8 @@ void sched_tester::test_collisions() for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_data_elems; ++i) { alloc_mask.reset(); srslte_pdsch_grant_t grant; - CondError(srslte_ra_dl_dci_to_grant(&cfg.cell, &dl_sf, SRSLTE_TM1, &tti_data.sched_result_dl.data[i].dci, &grant) == - SRSLTE_ERROR, + CondError(srslte_ra_dl_dci_to_grant( + &cfg.cell, &dl_sf, SRSLTE_TM1, false, &tti_data.sched_result_dl.data[i].dci, &grant) == SRSLTE_ERROR, "Failed to decode PDSCH grant\n"); for (uint32_t i = 0; i < alloc_mask.size(); ++i) { if (grant.prb_idx[0][i]) { @@ -792,8 +792,8 @@ void sched_tester::test_collisions() } for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_bc_elems; ++i) { srslte_pdsch_grant_t grant; - CondError(srslte_ra_dl_dci_to_grant(&cfg.cell, &dl_sf, SRSLTE_TM1, &tti_data.sched_result_dl.bc[i].dci, &grant) == - SRSLTE_ERROR, + CondError(srslte_ra_dl_dci_to_grant( + &cfg.cell, &dl_sf, SRSLTE_TM1, false, &tti_data.sched_result_dl.bc[i].dci, &grant) == SRSLTE_ERROR, "Failed to decode PDSCH grant\n"); alloc_mask.reset(); for (uint32_t i = 0; i < alloc_mask.size(); ++i) { @@ -811,8 +811,8 @@ void sched_tester::test_collisions() for (uint32_t i = 0; i < tti_data.sched_result_dl.nof_rar_elems; ++i) { alloc_mask.reset(); srslte_pdsch_grant_t grant; - CondError(srslte_ra_dl_dci_to_grant(&cfg.cell, &dl_sf, SRSLTE_TM1, &tti_data.sched_result_dl.rar[i].dci, &grant) == - SRSLTE_ERROR, + CondError(srslte_ra_dl_dci_to_grant( + &cfg.cell, &dl_sf, SRSLTE_TM1, false, &tti_data.sched_result_dl.rar[i].dci, &grant) == SRSLTE_ERROR, "Failed to decode PDSCH grant\n"); for (uint32_t i = 0; i < alloc_mask.size(); ++i) { if (grant.prb_idx[0][i]) { diff --git a/srsue/src/phy/cc_worker.cc b/srsue/src/phy/cc_worker.cc index d15e7cd29..06a4c274c 100644 --- a/srsue/src/phy/cc_worker.cc +++ b/srsue/src/phy/cc_worker.cc @@ -1230,6 +1230,14 @@ void cc_worker::set_pcell_config(phy_interface_rrc_lte::phy_cfg_t* phy_cfg) ue_dl_cfg.cfg.cqi_report.aperiodic_configured = true; ue_dl_cfg.cfg.cqi_report.aperiodic_mode = aperiodic_mode(dedicated->cqi_report_cfg.cqi_report_mode_aperiodic); } + if (dedicated->cqi_report_cfg_pcell_v1250_present) { + auto cqi_report_cfg_pcell_v1250 = dedicated->cqi_report_cfg_pcell_v1250.get(); + if (cqi_report_cfg_pcell_v1250->alt_cqi_table_r12_present) { + ue_dl_cfg.pdsch_use_tbs_index_alt = true; + } + } else { + ue_dl_cfg.pdsch_use_tbs_index_alt = false; + } if (pregen_enabled) { Info("Pre-generating UL signals...\n"); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 41eb1467f..ac83b555d 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2620,7 +2620,7 @@ void rrc::send_rrc_ue_cap_info() for (uint32_t i = 0; i < args.nof_supported_bands; i++) { supported_band_eutra_v1250_s supported_band_eutra_v1250; // According to 3GPP 36.306 v12 Table 4.1A-1, 256QAM is supported for ue_category_dl 11-16 - supported_band_eutra_v1250.dl_minus256_qam_r12_present = false; + supported_band_eutra_v1250.dl_minus256_qam_r12_present = true; // According to 3GPP 36.331 v12 UE-EUTRA-Capability field descriptions // This field is only present when the field ue-CategoryUL is considered to 5 or 13. @@ -2901,6 +2901,11 @@ void rrc::apply_phy_config_dedicated(const phys_cfg_ded_s& phy_cnfg) current_cfg->pucch_cfg_ded = phy_cnfg.pucch_cfg_ded; } + if (phy_cnfg.cqi_report_cfg_pcell_v1250_present) { + current_cfg->cqi_report_cfg_pcell_v1250_present = true; + current_cfg->cqi_report_cfg_pcell_v1250 = phy_cnfg.cqi_report_cfg_pcell_v1250; + } + if (phy_cnfg.pucch_cfg_ded_v1020_present) { current_cfg->pucch_cfg_ded_v1020_present = true; current_cfg->pucch_cfg_ded_v1020 = phy_cnfg.pucch_cfg_ded_v1020;