Merge branch 'next' into agpl_next

master
Codebot 4 years ago committed by Your Name
commit c950209902

@ -323,7 +323,7 @@ int main(int argc, char** argv)
// SCI
srsran_sci_t sci;
srsran_sci_init(&sci, cell_sl, sl_comm_resource_pool);
srsran_sci_init(&sci, &cell_sl, &sl_comm_resource_pool);
uint8_t sci_rx[SRSRAN_SCI_MAX_LEN] = {};
char sci_msg[SRSRAN_SCI_MSG_MAX_LEN] = {};
@ -346,7 +346,7 @@ int main(int argc, char** argv)
return SRSRAN_ERROR;
}
if (srsran_pssch_init(&pssch, cell_sl, sl_comm_resource_pool) != SRSRAN_SUCCESS) {
if (srsran_pssch_init(&pssch, &cell_sl, &sl_comm_resource_pool) != SRSRAN_SUCCESS) {
ERROR("Error initializing PSSCH");
return SRSRAN_ERROR;
}

@ -1317,7 +1317,7 @@ private:
bit_ref brefstart;
// bit_ref bref0;
bit_ref* bref_tracker;
uint8_t buffer[1024];
uint8_t buffer[2048];
bool align;
};

@ -54,6 +54,9 @@ struct pusch_time_domain_res_alloc_s;
struct pucch_format_cfg_s;
struct pucch_res_s;
struct sched_request_res_cfg_s;
struct pusch_cfg_s;
struct pdsch_cfg_s;
struct dmrs_dl_cfg_s;
struct dmrs_ul_cfg_s;
struct beta_offsets_s;
struct uci_on_pusch_s;
@ -96,14 +99,22 @@ bool make_phy_res_config(const asn1::rrc_nr::pucch_res_s& pucch_res,
srsran_pucch_nr_resource_t* srsran_pucch_nr_resource);
bool make_phy_sr_resource(const asn1::rrc_nr::sched_request_res_cfg_s& sched_request_res_cfg,
srsran_pucch_nr_sr_resource_t* srsran_pucch_nr_sr_resource);
bool make_phy_dmrs_additional_pos(const asn1::rrc_nr::dmrs_ul_cfg_s& dmrs_ul_cfg,
bool make_phy_pusch_alloc_type(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg,
srsran_resource_alloc_t* in_srsran_resource_alloc);
bool make_phy_pdsch_alloc_type(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg,
srsran_resource_alloc_t* in_srsran_resource_alloc);
bool make_phy_dmrs_dl_additional_pos(const asn1::rrc_nr::dmrs_dl_cfg_s& dmrs_dl_cfg,
srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos);
bool make_phy_dmrs_ul_additional_pos(const asn1::rrc_nr::dmrs_ul_cfg_s& dmrs_ul_cfg,
srsran_dmrs_sch_add_pos_t* srsran_dmrs_sch_add_pos);
bool make_phy_beta_offsets(const asn1::rrc_nr::beta_offsets_s& beta_offsets,
srsran_beta_offsets_t* srsran_beta_offsets);
bool make_phy_pusch_scaling(const asn1::rrc_nr::uci_on_pusch_s& uci_on_pusch, float* scaling);
bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s & zp_csi_rs_res, srsran_csi_rs_zp_resource_t* zp_csi_rs_resource);
bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s & nzp_csi_rs_res, srsran_csi_rs_nzp_resource_t* csi_rs_nzp_resource);
bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s &freq_info_dl, srsran_carrier_nr_t* carrier_nr);
bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_res,
srsran_csi_rs_zp_resource_t* zp_csi_rs_resource);
bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& nzp_csi_rs_res,
srsran_csi_rs_nzp_resource_t* csi_rs_nzp_resource);
bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s& freq_info_dl, srsran_carrier_nr_t* carrier_nr);
/***************************
* MAC Config
**************************/

@ -52,7 +52,7 @@ struct phy_cfg_nr_t {
{
srsran_dci_cfg_nr_t dci_cfg = {};
// Set bandwidths
// Assume BWP bandwidth equals full channel bandwidth
dci_cfg.coreset0_bw = pdcch.coreset_present[0] ? srsran_coreset_get_bw(&pdcch.coreset[0]) : 0;
dci_cfg.bwp_dl_initial_bw = carrier.nof_prb;
dci_cfg.bwp_dl_active_bw = carrier.nof_prb;
@ -88,24 +88,45 @@ struct phy_cfg_nr_t {
// Set Format 0_1 and 1_1 parameters
dci_cfg.carrier_indicator_size = 0;
dci_cfg.harq_ack_codebok = harq_ack.harq_ack_codebook;
dci_cfg.nof_rb_groups = 0;
// Format 0_1 specific configuration (for PUSCH only)
dci_cfg.nof_ul_bwp = 1;
dci_cfg.nof_ul_bwp = 0;
dci_cfg.nof_ul_time_res = (pusch.nof_dedicated_time_ra > 0)
? pusch.nof_dedicated_time_ra
: (pusch.nof_common_time_ra > 0) ? pusch.nof_common_time_ra : SRSRAN_MAX_NOF_TIME_RA;
dci_cfg.nof_srs = 1;
dci_cfg.nof_ul_layers = 1;
dci_cfg.nof_rb_groups = 1;
dci_cfg.pusch_nof_cbg = 0;
dci_cfg.report_trigger_size = 0;
dci_cfg.enable_transform_precoding = false;
dci_cfg.dynamic_dual_harq_ack_codebook = false;
dci_cfg.pusch_tx_config_non_codebook = false;
dci_cfg.pusch_dmrs_type2 = false;
dci_cfg.pusch_dmrs_double = false;
dci_cfg.pusch_ptrs = false;
dci_cfg.pusch_dynamic_betas = false;
dci_cfg.pusch_alloc_type = pusch.alloc;
// Format 1_1 specific configuration (for PDSCH only)
dci_cfg.nof_dl_bwp = 1;
dci_cfg.pdsch_alloc_type = pdsch.alloc;
dci_cfg.nof_dl_bwp = 0;
dci_cfg.nof_dl_time_res = (pdsch.nof_dedicated_time_ra > 0)
? pdsch.nof_dedicated_time_ra
: (pdsch.nof_common_time_ra > 0) ? pdsch.nof_common_time_ra : SRSRAN_MAX_NOF_TIME_RA;
dci_cfg.nof_aperiodic_zp = 0;
dci_cfg.pdsch_nof_cbg = 0;
dci_cfg.nof_dl_to_ul_ack = harq_ack.nof_dl_data_to_ul_ack;
dci_cfg.pdsch_inter_prb_to_prb = false;
dci_cfg.pdsch_rm_pattern1 = false;
dci_cfg.pdsch_rm_pattern2 = false;
dci_cfg.pdsch_2cw = false;
dci_cfg.multiple_scell = false;
dci_cfg.pdsch_dmrs_type2 = false;
dci_cfg.pdsch_dmrs_double = false;
dci_cfg.pdsch_tci = false;
dci_cfg.pdsch_cbg_flush = false;
dci_cfg.pdsch_dynamic_bundling = false;
dci_cfg.pdsch_alloc_type = pdsch.alloc;
return dci_cfg;
};

@ -39,6 +39,11 @@ extern "C" {
*/
#define SRSRAN_SLOT_LEN_RE_NR(nof_prb) (nof_prb * SRSRAN_NRE * SRSRAN_NSYMB_PER_SLOT_NR)
/**
* @brief Minimum subframe length in samples for a given number of PRB
*/
#define SRSRAN_SF_LEN_PRB_NR(nof_prb) (srsran_min_symbol_sz_rb(nof_prb) * 15)
#define SRSRAN_SLOT_MAX_LEN_RE_NR (SRSRAN_SLOT_LEN_RE_NR(SRSRAN_MAX_PRB_NR))
#define SRSRAN_SLOT_MAX_NOF_BITS_NR (SRSRAN_SLOT_MAX_LEN_RE_NR * SRSRAN_MAX_QM)
#define SRSRAN_MAX_LAYERS_NR 8

@ -46,6 +46,14 @@ SRSRAN_API int srsran_csi_generate_reports(const srsran_csi_hl_cfg_t* cfg,
*/
SRSRAN_API int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports);
/**
* @brief Compute number of CSI bits necessary to transmit all the CSI part 2 reports for a PUCCH transmission
* @param report_list Provides the CSI report list
* @param nof_reports Number of CSI reports in the list
* @return The number of bits if the provided list is valid, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_csi_part2_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports);
/**
* @brief Checks if the report list contains part 2 CSI report
* @param report_list Report list

@ -115,8 +115,9 @@ typedef struct SRSRAN_API {
} srsran_pssch_t;
SRSRAN_API int
srsran_pssch_init(srsran_pssch_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool);
SRSRAN_API int srsran_pssch_init(srsran_pssch_t* q,
const srsran_cell_sl_t* cell,
const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool);
SRSRAN_API int srsran_pssch_set_cfg(srsran_pssch_t* q, srsran_pssch_cfg_t pssch_cfg);
SRSRAN_API int srsran_pssch_encode(srsran_pssch_t* q, uint8_t* input, uint32_t input_len, cf_t* sf_buffer);
SRSRAN_API int srsran_pssch_decode(srsran_pssch_t* q, cf_t* equalized_sf_syms, uint8_t* output, uint32_t output_len);

@ -98,8 +98,9 @@ typedef struct SRSRAN_API {
} srsran_sci_t;
SRSRAN_API int
srsran_sci_init(srsran_sci_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool);
SRSRAN_API int srsran_sci_init(srsran_sci_t* q,
const srsran_cell_sl_t* cell,
const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool);
SRSRAN_API int srsran_sci_format0_pack(srsran_sci_t* q, uint8_t* output);
SRSRAN_API int srsran_sci_format1_pack(srsran_sci_t* q, uint8_t* output);
SRSRAN_API int srsran_sci_format0_unpack(srsran_sci_t* q, uint8_t* input);

@ -792,7 +792,79 @@ bool make_phy_sr_resource(const sched_request_res_cfg_s& sched_request_res_cfg,
return true;
}
bool make_phy_dmrs_additional_pos(const dmrs_ul_cfg_s& dmrs_ul_cfg,
bool make_phy_pusch_alloc_type(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg,
srsran_resource_alloc_t* in_srsran_resource_alloc)
{
srsran_resource_alloc_t srsran_resource_alloc = {};
switch (pusch_cfg.res_alloc) {
case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::res_alloc_type0:
srsran_resource_alloc = srsran_resource_alloc_type0;
break;
case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::res_alloc_type1:
srsran_resource_alloc = srsran_resource_alloc_type1;
break;
case asn1::rrc_nr::pusch_cfg_s::res_alloc_e_::dynamic_switch:
srsran_resource_alloc = srsran_resource_alloc_dynamic;
break;
default:
asn1::log_warning("Invalid option for pusch::resource_alloc %s", pusch_cfg.res_alloc.to_string());
return false;
}
*in_srsran_resource_alloc = srsran_resource_alloc;
return true;
}
bool make_phy_pdsch_alloc_type(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg,
srsran_resource_alloc_t* in_srsran_resource_alloc)
{
srsran_resource_alloc_t srsran_resource_alloc = {};
switch (pdsch_cfg.res_alloc) {
case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::res_alloc_type0:
srsran_resource_alloc = srsran_resource_alloc_type0;
break;
case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::res_alloc_type1:
srsran_resource_alloc = srsran_resource_alloc_type1;
break;
case asn1::rrc_nr::pdsch_cfg_s::res_alloc_e_::dynamic_switch:
srsran_resource_alloc = srsran_resource_alloc_dynamic;
break;
default:
asn1::log_warning("Invalid option for pusch::resource_alloc %s", pdsch_cfg.res_alloc.to_string());
return false;
}
*in_srsran_resource_alloc = srsran_resource_alloc;
return true;
}
bool make_phy_dmrs_dl_additional_pos(const dmrs_dl_cfg_s& dmrs_dl_cfg,
srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos)
{
srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos = {};
if (not dmrs_dl_cfg.dmrs_add_position_present) {
asn1::log_warning("dmrs_add_position option not present");
}
switch (dmrs_dl_cfg.dmrs_add_position) {
case dmrs_dl_cfg_s::dmrs_add_position_opts::pos0:
srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_0;
break;
case dmrs_dl_cfg_s::dmrs_add_position_opts::pos1:
srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_1;
break;
case dmrs_dl_cfg_s::dmrs_add_position_opts::pos3:
srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos_3;
break;
default:
asn1::log_warning("Invalid option for dmrs_add_position %s", dmrs_dl_cfg.dmrs_add_position.to_string());
return false;
}
*in_srsran_dmrs_sch_add_pos = srsran_dmrs_sch_add_pos;
return true;
}
bool make_phy_dmrs_ul_additional_pos(const dmrs_ul_cfg_s& dmrs_ul_cfg,
srsran_dmrs_sch_add_pos_t* in_srsran_dmrs_sch_add_pos)
{
srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos = {};

@ -29,6 +29,34 @@ int bands_test_nr()
TESTASSERT(bands.nr_arfcn_to_freq(632628) == 3489.42e6);
TESTASSERT(bands.nr_arfcn_to_freq(633928) == 3508.92e6); // default refPointA
TESTASSERT(bands.nr_arfcn_to_freq(634240) == 3513.6e6); // default ARFCN with freq divisible by 11.52 MHz
// b28 b67
TESTASSERT(bands.nr_arfcn_to_freq(140600) == 703.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(145800) == 729.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(153600) == 768.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(157600) == 788.0e6);
// b20
TESTASSERT(bands.nr_arfcn_to_freq(158200) == 791.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(160200) == 801.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(162200) == 811.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(168400) == 842.0e6);
// b32 b75
TESTASSERT(bands.nr_arfcn_to_freq(290400) == 1452.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(294400) == 1472.0e6);
// b3
TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(361000) == 1805.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6);
// b1
TESTASSERT(bands.nr_arfcn_to_freq(384000) == 1920.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(388030) == 1940.15e6);
TESTASSERT(bands.nr_arfcn_to_freq(391830) == 1959.15e6);
TESTASSERT(bands.nr_arfcn_to_freq(434000) == 2170.0e6);
// b7 b38
TESTASSERT(bands.nr_arfcn_to_freq(500000) == 2500.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(508000) == 2540.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(522000) == 2610.0e6);
TESTASSERT(bands.nr_arfcn_to_freq(538000) == 2690.0e6);
const uint32_t max_valid_nr_arfcn = 3279165;

@ -146,8 +146,22 @@
} \
\
update_ldpc_soft_bits_##SUFFIX(q->ptr, q->var_indices); \
\
if (crc != NULL) { \
extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \
\
if (srsran_crc_match(crc, message, q->liftK - crc->order)) { \
return i_iteration + 1; \
} \
} \
} \
\
/* If reached here, and CRC is being checked, it has failed */ \
if (crc != NULL) { \
return 0; \
} \
\
/* Without CRC, extract message and return the maximum number of iterations */ \
extract_ldpc_message_##SUFFIX(q->ptr, message, q->liftK); \
\
return q->max_nof_iter; \

@ -30,29 +30,6 @@
#ifdef HAVE_NEONv8
#include <arm_neon.h>
inline static uint8x16_t v_load_s8(int i15,
int i14,
int i13,
int i12,
int i11,
int i10,
int i9,
int i8,
int i7,
int i6,
int i5,
int i4,
int i3,
int i2,
int i1,
int i0)
{
uint8_t __attribute__((aligned(16)))
data[16] = {i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15};
return vld1q_u8(data);
}
#define int8x16_to_8x8x2(v) ((int8x8x2_t){{vget_low_s8(v), vget_high_s8(v)}})
#define vshuff_s32_even(a, imm, res) \
do { \

@ -90,6 +90,7 @@ int main(int argc, char** argv)
uint8_t * input, *input_bytes, *output;
cf_t * symbols, *symbols_bytes;
float* llr;
srsran_random_t random_gen = srsran_random_init(0x1234);
parse_args(argc, argv);
@ -142,14 +143,14 @@ int main(int argc, char** argv)
/* generate random data */
for (i = 0; i < num_bits; i++) {
input[i] = rand() % 2;
input[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1);
}
/* modulate */
struct timeval t[3];
gettimeofday(&t[1], NULL);
int ntrials = 100;
for (int i = 0; i < ntrials; i++) {
for (int j = 0; j < ntrials; j++) {
srsran_mod_modulate(&mod, input, symbols, num_bits);
}
gettimeofday(&t[2], NULL);
@ -160,16 +161,16 @@ int main(int argc, char** argv)
/* Test packed implementation */
srsran_bit_pack_vector(input, input_bytes, num_bits);
gettimeofday(&t[1], NULL);
for (int i = 0; i < ntrials; i++) {
for (int j = 0; j < ntrials; j++) {
srsran_mod_modulate_bytes(&mod, input_bytes, symbols_bytes, num_bits);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
printf("Byte: %ld us\n", t[0].tv_usec);
for (int i = 0; i < num_bits / mod.nbits_x_symbol; i++) {
if (symbols[i] != symbols_bytes[i]) {
printf("error in symbol %d\n", i);
for (int j = 0; i < num_bits / mod.nbits_x_symbol; j++) {
if (symbols[j] != symbols_bytes[j]) {
printf("error in symbol %d\n", j);
exit(-1);
}
}
@ -200,7 +201,7 @@ int main(int argc, char** argv)
free(output);
free(input);
free(input_bytes);
srsran_random_free(random_gen);
srsran_modem_table_free(&mod);
exit(ret);

@ -224,6 +224,18 @@ int srsran_csi_part1_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32
return (int)count;
}
int srsran_csi_part2_nof_bits(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports)
{
uint32_t count = 0;
// Check input pointer
if (report_list == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
return (int)count;
}
bool srsran_csi_has_part2(const srsran_csi_report_cfg_t* report_list, uint32_t nof_reports)
{
if (report_list == NULL || nof_reports == 0) {

@ -1645,12 +1645,12 @@ uint32_t srsran_dci_dl_info(const srsran_dci_dl_t* dci_dl, char* info_str, uint3
n = srsran_print_check(info_str, len, n, ", pid=%d", dci_dl->pid);
n = srsran_print_check(info_str, len, n, ", mcs={", 0);
n = srsran_print_check(info_str, len, n, ", mcs={");
n = print_multi(info_str, n, len, dci_dl, 0);
n = srsran_print_check(info_str, len, n, "}", 0);
n = srsran_print_check(info_str, len, n, ", ndi={", 0);
n = srsran_print_check(info_str, len, n, "}");
n = srsran_print_check(info_str, len, n, ", ndi={");
n = print_multi(info_str, n, len, dci_dl, 2);
n = srsran_print_check(info_str, len, n, "}", 0);
n = srsran_print_check(info_str, len, n, "}");
if (dci_dl->format == SRSRAN_DCI_FORMAT1 || dci_dl->format == SRSRAN_DCI_FORMAT1A ||
dci_dl->format == SRSRAN_DCI_FORMAT1B || dci_dl->format == SRSRAN_DCI_FORMAT2 ||

@ -674,16 +674,6 @@ dci_nr_format_0_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci
uint32_t len = 0;
const srsran_dci_cfg_nr_t* cfg = &q->cfg;
// Print format
len = srsran_print_check(str,
str_len,
len,
"rnti=%04x L=%d cce=%d dci=%s ",
dci->ctx.rnti,
dci->ctx.location.L,
dci->ctx.location.ncce,
srsran_dci_format_nr_string(dci->ctx.format));
// Carrier indicator 0 or 3 bits
if (cfg->carrier_indicator_size) {
len = srsran_print_check(str, str_len, len, "cc=%d ", dci->cc_id);
@ -1103,10 +1093,6 @@ static int dci_nr_format_1_0_to_str(const srsran_dci_dl_nr_t* dci, char* str, ui
uint32_t len = 0;
srsran_rnti_type_t rnti_type = dci->ctx.rnti_type;
// Print format
len = srsran_print_check(
str, str_len, len, "rnti=%04x L=%d cce=%d dci=1_0 ", dci->ctx.rnti, dci->ctx.location.L, dci->ctx.location.ncce);
if (rnti_type == srsran_rnti_type_p) {
len = srsran_print_check(str, str_len, len, "smi=%d sm=%d ", dci->smi, dci->sm);
}
@ -1563,10 +1549,6 @@ dci_nr_format_1_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci
uint32_t len = 0;
const srsran_dci_cfg_nr_t* cfg = &q->cfg;
// Print format
len = srsran_print_check(
str, str_len, len, "rnti=%04x L=%d cce=%d dci=0_0 ", dci->ctx.rnti, dci->ctx.location.L, dci->ctx.location.ncce);
// Carrier indicator 0 or 3 bits
if (cfg->carrier_indicator_size > 0) {
len = srsran_print_check(str, str_len, len, "cc=%d ", dci->cc_id);
@ -1578,11 +1560,11 @@ dci_nr_format_1_1_to_str(const srsran_dci_nr_t* q, const srsran_dci_dl_nr_t* dci
}
// Frequency domain resource assignment
len = srsran_print_check(str, str_len, len, "f_alloc=%d ", dci->freq_domain_assigment);
len = srsran_print_check(str, str_len, len, "f_alloc=0x%x ", dci->freq_domain_assigment);
// Time domain resource assignment 0, 1, 2, 3, or 4 bits
if (cfg->nof_dl_time_res > 0) {
len = srsran_print_check(str, str_len, len, "t_alloc=%d ", dci->time_domain_assigment);
len = srsran_print_check(str, str_len, len, "t_alloc=0x%x ", dci->time_domain_assigment);
}
// VRB-to-PRB mapping 0 or 1
@ -1885,9 +1867,6 @@ static int dci_nr_rar_to_str(const srsran_dci_ul_nr_t* dci, char* str, uint32_t
{
uint32_t len = 0;
// Print format
len = srsran_print_check(str, str_len, len, "rnti=%04x dci=rar ", dci->ctx.rnti);
// Frequency hopping flag
len = srsran_print_check(str, str_len, len, "hop=%d ", dci->freq_hopping_flag);
@ -1985,15 +1964,16 @@ int srsran_dci_nr_ul_unpack(const srsran_dci_nr_t* q, srsran_dci_msg_nr_t* msg,
int srsran_dci_ctx_to_str(const srsran_dci_ctx_t* ctx, char* str, uint32_t str_len)
{
// Print format
return srsran_print_check(str,
str_len,
0,
"rnti=%04x L=%d cce=%d dci=%s ",
ctx->rnti,
ctx->location.L,
ctx->location.ncce,
srsran_dci_format_nr_string(ctx->format));
uint32_t len = 0;
// Print base
len = srsran_print_check(str, str_len, len, "rnti=%04x dci=%s ", ctx->rnti, srsran_dci_format_nr_string(ctx->format));
if (ctx->format != srsran_dci_format_nr_rar) {
len = srsran_print_check(str, str_len, len, "L=%d cce=%d ", ctx->location.L, ctx->location.ncce);
}
return len;
}
int srsran_dci_ul_nr_to_str(const srsran_dci_nr_t* q, const srsran_dci_ul_nr_t* dci, char* str, uint32_t str_len)

@ -412,7 +412,7 @@ int srsran_pdcch_decode_msg(srsran_pdcch_t* q, srsran_dl_sf_cfg_t* sf, srsran_dc
INFO("Skipping DCI: nCCE=%d, L=%d, msg_len=%d, mean=%f", msg->location.ncce, msg->location.L, nof_bits, mean);
}
}
} else {
} else if (msg != NULL) {
ERROR("Invalid parameters, location=%d,%d", msg->location.ncce, msg->location.L);
}
return ret;

@ -522,25 +522,9 @@ static float apply_power_allocation(srsran_pdsch_t* q, srsran_pdsch_cfg_t* cfg,
static void csi_correction(srsran_pdsch_t* q, srsran_pdsch_cfg_t* cfg, uint32_t codeword_idx, uint32_t tb_idx, void* e)
{
uint32_t qm = 0;
switch (cfg->grant.tb[tb_idx].mod) {
case SRSRAN_MOD_BPSK:
qm = 1;
break;
case SRSRAN_MOD_QPSK:
qm = 2;
break;
case SRSRAN_MOD_16QAM:
qm = 4;
break;
case SRSRAN_MOD_64QAM:
qm = 6;
break;
case SRSRAN_MOD_256QAM:
qm = 8;
break;
default:
ERROR("No modulation");
uint32_t qm = srsran_mod_bits_x_symbol(cfg->grant.tb[tb_idx].mod);
if (qm == 0) {
return;
}
const uint32_t csi_max_idx = srsran_vec_max_fi(q->csi[codeword_idx], cfg->grant.tb[tb_idx].nof_bits / qm);
@ -1189,18 +1173,18 @@ uint32_t srsran_pdsch_grant_rx_info(srsran_pdsch_grant_t* grant,
{
uint32_t len = srsran_ra_dl_info(grant, str, str_len);
len = srsran_print_check(str, str_len, len, ", crc={", 0);
len = srsran_print_check(str, str_len, len, ", crc={");
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
if (grant->tb[i].enabled) {
len = srsran_print_check(str, str_len, len, "%s", res[i].crc ? "OK" : "KO");
if (i < SRSRAN_MAX_CODEWORDS - 1) {
if (grant->tb[i + 1].enabled) {
len = srsran_print_check(str, str_len, len, "/", 0);
len = srsran_print_check(str, str_len, len, "/");
}
}
}
}
len = srsran_print_check(str, str_len, len, "}", 0);
len = srsran_print_check(str, str_len, len, "}");
// Average iterations between nof TB and divide by 2 to get full decoder iterations
len = srsran_print_check(
@ -1216,7 +1200,7 @@ srsran_pdsch_rx_info(srsran_pdsch_cfg_t* cfg, srsran_pdsch_res_t res[SRSRAN_MAX_
len += srsran_pdsch_grant_rx_info(&cfg->grant, res, &str[len], str_len - len);
if (cfg->meas_evm_en) {
len = srsran_print_check(str, str_len, len, ", evm={", 0);
len = srsran_print_check(str, str_len, len, ", evm={");
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
if (cfg->grant.tb[i].enabled && !isnan(res[i].evm)) {
len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm);
@ -1227,7 +1211,7 @@ srsran_pdsch_rx_info(srsran_pdsch_cfg_t* cfg, srsran_pdsch_res_t res[SRSRAN_MAX_
}
}
}
len = srsran_print_check(str, str_len, len, "}", 0);
len = srsran_print_check(str, str_len, len, "}");
}
if (cfg->meas_time_en) {

@ -488,7 +488,7 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q,
const srsran_sch_grant_nr_t* grant,
srsran_chest_dl_res_t* channel,
cf_t* sf_symbols[SRSRAN_MAX_PORTS],
srsran_pdsch_res_nr_t data[SRSRAN_MAX_TB])
srsran_pdsch_res_nr_t* data)
{
// Check input pointers
if (!q || !cfg || !grant || !data || !sf_symbols) {
@ -547,9 +547,7 @@ int srsran_pdsch_nr_decode(srsran_pdsch_nr_t* q,
// SCH decode
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
nof_cw += grant->tb[tb].enabled ? 1 : 0;
if (pdsch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSRAN_SUCCESS) {
if (pdsch_nr_decode_codeword(q, cfg, &grant->tb[tb], data, grant->rnti) < SRSRAN_SUCCESS) {
ERROR("Error encoding TB %d", tb);
return SRSRAN_ERROR;
}

@ -30,23 +30,25 @@
#include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/vector.h"
int srsran_pssch_init(srsran_pssch_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool)
int srsran_pssch_init(srsran_pssch_t* q,
const srsran_cell_sl_t* cell,
const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool)
{
if (q == NULL) {
if (q == NULL || cell == NULL || sl_comm_resource_pool == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
q->cell = cell;
q->sl_comm_resource_pool = sl_comm_resource_pool;
q->cell = *cell;
q->sl_comm_resource_pool = *sl_comm_resource_pool;
if (cell.tm == SRSRAN_SIDELINK_TM1 || cell.tm == SRSRAN_SIDELINK_TM2) {
if (cell.cp == SRSRAN_CP_NORM) {
if (cell->tm == SRSRAN_SIDELINK_TM1 || cell->tm == SRSRAN_SIDELINK_TM2) {
if (cell->cp == SRSRAN_CP_NORM) {
q->nof_data_symbols = SRSRAN_PSSCH_TM12_NUM_DATA_SYMBOLS;
} else {
q->nof_data_symbols = SRSRAN_PSSCH_TM12_NUM_DATA_SYMBOLS_CP_EXT;
}
} else if (cell.tm == SRSRAN_SIDELINK_TM3 || cell.tm == SRSRAN_SIDELINK_TM4) {
if (cell.cp == SRSRAN_CP_NORM) {
} else if (cell->tm == SRSRAN_SIDELINK_TM3 || cell->tm == SRSRAN_SIDELINK_TM4) {
if (cell->cp == SRSRAN_CP_NORM) {
q->nof_data_symbols = SRSRAN_PSSCH_TM34_NUM_DATA_SYMBOLS;
} else {
ERROR("Invalid CP for PSSCH, SL TM 3/4");

@ -460,6 +460,11 @@ static int encode_signal_format3(srsran_pucch_t* q,
uint32_t N_sf_0 = get_N_sf(cfg->format, 0, sf->shortened);
uint32_t N_sf_1 = get_N_sf(cfg->format, 1, sf->shortened);
if (N_sf_1 == 0) {
ERROR("Invalid N_sf_1");
return SRSRAN_ERROR;
}
uint32_t n_oc_0 = cfg->n_pucch % N_sf_1;
uint32_t n_oc_1 = (N_sf_1 == 5) ? ((3 * cfg->n_pucch) % N_sf_1) : (n_oc_0 % N_sf_1);
@ -507,6 +512,11 @@ static int decode_signal_format3(srsran_pucch_t* q,
uint32_t N_sf_0 = get_N_sf(cfg->format, 0, sf->shortened);
uint32_t N_sf_1 = get_N_sf(cfg->format, 1, sf->shortened);
if (N_sf_1 == 0) {
ERROR("Invalid N_sf_1");
return SRSRAN_ERROR;
}
uint32_t n_oc_0 = cfg->n_pucch % N_sf_1;
uint32_t n_oc_1 = (N_sf_1 == 5) ? ((3 * cfg->n_pucch) % N_sf_1) : (n_oc_0 % N_sf_1);

@ -85,8 +85,7 @@ int srsran_pucch_nr_alpha_idx(const srsran_carrier_nr_t* carrier,
// Generate pseudo-random sequence
uint32_t cinit = cfg->hopping_id_present ? cfg->hopping_id : carrier->pci;
uint8_t cs[SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(SRSRAN_NR_MAX_NUMEROLOGY) * 8U] = {};
srsran_sequence_apply_bit(
cs, cs, SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(carrier->scs) * 8, cinit);
srsran_sequence_apply_bit(cs, cs, SRSRAN_NSYMB_PER_SLOT_NR * SRSRAN_NSLOTS_PER_FRAME_NR(carrier->scs) * 8, cinit);
// Create n_cs parameter
uint32_t n_cs = 0;
@ -400,11 +399,11 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q,
}
// Modulate d
cf_t d = 0;
cf_t d[1] = {};
if (nof_bits == 1) {
srsran_mod_modulate(&q->bpsk, b, &d, nof_bits);
srsran_mod_modulate(&q->bpsk, b, d, 1);
} else {
srsran_mod_modulate(&q->qpsk, b, &d, nof_bits);
srsran_mod_modulate(&q->qpsk, b, d, 2);
}
// Get group sequence
@ -439,7 +438,7 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q,
// Compute y = d(0) * r_uv
cf_t y[SRSRAN_NRE];
srsran_vec_sc_prod_ccc(r_uv, d, y, SRSRAN_NRE);
srsran_vec_sc_prod_ccc(r_uv, d[0], y, SRSRAN_NRE);
// Get w_i_m
cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m);
@ -564,7 +563,12 @@ static int pucch_nr_format2_encode(srsran_pucch_nr_t* q,
}
// Calculate number of encoded symbols
uint32_t E = srsran_uci_nr_pucch_format_2_3_4_E(resource);
int e = srsran_uci_nr_pucch_format_2_3_4_E(resource);
if (e < SRSRAN_SUCCESS) {
ERROR("Error selecting E");
return SRSRAN_ERROR;
}
uint32_t E = (uint32_t)e;
// 6.3.2.5.1 Scrambling
uint32_t cinit = pucch_nr_format2_cinit(carrier, cfg, uci_cfg);

@ -918,7 +918,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
const srsran_sch_grant_nr_t* grant,
srsran_chest_dl_res_t* channel,
cf_t* sf_symbols[SRSRAN_MAX_PORTS],
srsran_pusch_res_nr_t data[SRSRAN_MAX_TB])
srsran_pusch_res_nr_t* data)
{
// Check input pointers
if (!q || !cfg || !grant || !data || !sf_symbols) {
@ -947,7 +947,12 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
nof_cw += grant->tb[tb].enabled ? 1 : 0;
}
uint32_t nof_re = srsran_ra_dl_nr_slot_nof_re(cfg, grant);
int e = srsran_ra_dl_nr_slot_nof_re(cfg, grant);
if (e < SRSRAN_SUCCESS) {
ERROR("Getting number of RE");
return SRSRAN_ERROR;
}
uint32_t nof_re = (uint32_t)e;
if (channel->nof_re != nof_re) {
ERROR("Inconsistent number of RE (%d!=%d)", channel->nof_re, nof_re);
@ -983,9 +988,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
// SCH decode
for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) {
nof_cw += grant->tb[tb].enabled ? 1 : 0;
if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], &data[tb], grant->rnti) < SRSRAN_SUCCESS) {
if (pusch_nr_decode_codeword(q, cfg, &grant->tb[tb], data, grant->rnti) < SRSRAN_SUCCESS) {
ERROR("Error encoding TB %d", tb);
return SRSRAN_ERROR;
}

@ -711,15 +711,15 @@ uint32_t srsran_ra_dl_info(srsran_pdsch_grant_t* grant, char* info_str, uint32_t
n = srsran_print_check(info_str, len, n, ", nof_prb=%d, nof_re=%d", grant->nof_prb, grant->nof_re);
n = srsran_print_check(info_str, len, n, ", tbs={", 0);
n = srsran_print_check(info_str, len, n, ", tbs={");
n = print_multi(info_str, n, len, grant, 1);
n = srsran_print_check(info_str, len, n, "}", 0);
n = srsran_print_check(info_str, len, n, ", mod={", 0);
n = srsran_print_check(info_str, len, n, "}");
n = srsran_print_check(info_str, len, n, ", mod={");
n = print_multi(info_str, n, len, grant, 2);
n = srsran_print_check(info_str, len, n, "}", 0);
n = srsran_print_check(info_str, len, n, ", rv={", 0);
n = srsran_print_check(info_str, len, n, "}");
n = srsran_print_check(info_str, len, n, ", rv={");
n = print_multi(info_str, n, len, grant, 0);
n = srsran_print_check(info_str, len, n, "}", 0);
n = srsran_print_check(info_str, len, n, "}");
if (grant->tx_scheme != SRSRAN_TXSCHEME_PORT0) {
n = srsran_print_check(info_str,

@ -134,7 +134,7 @@ static const float ra_nr_beta_offset_ack_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] =
/**
* TS 38.213 V15.10.0 Table 9.3-2: Mapping of beta_offset values for CSI and the index signalled by higher layers
*/
static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_HARQACK_SIZE] = {
static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_CSI_SIZE] = {
1.125f, 1.250f, 1.375f, 1.625f, 1.750f, 2.000f, 2.250f, 2.500f, 2.875f, 3.125f, 3.500f,
4.000f, 5.000f, 6.250f, 8.000f, 10.000f, 12.625f, 15.875f, 20.000f, NAN, NAN, NAN,
NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN};
@ -148,7 +148,6 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t
{
// Non-implemented parameters
bool mcs_c_rnti = false;
srsran_mcs_table_t configured_grant_table = srsran_mcs_table_64qam;
// - if mcs-Table in pusch-Config is set to 'qam256', and
// - PUSCH is scheduled by a PDCCH with DCI format 0_1 with
@ -171,25 +170,25 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t
// - the UE is configured with MCS-C-RNTI, and
// - the PUSCH is scheduled by a PDCCH with
// - CRC scrambled by MCS-C-RNTI,
if (mcs_c_rnti && dci_format != srsran_dci_format_nr_rar && rnti_type == srsran_rnti_type_mcs_c) {
return ra_nr_table_3;
}
// if (mcs_c_rnti && dci_format != srsran_dci_format_nr_rar && rnti_type == srsran_rnti_type_mcs_c) {
// return ra_nr_table_3;
// }
// - mcs-Table in configuredGrantConfig is set to 'qam256',
// - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or
// - if PUSCH is transmitted with configured grant
if (configured_grant_table == srsran_mcs_table_256qam &&
(rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) {
return ra_nr_table_2;
}
// if (configured_grant_table == srsran_mcs_table_256qam &&
// (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) {
// return ra_nr_table_2;
// }
// - mcs-Table in configuredGrantConfig is set to 'qam64LowSE'
// - if PUSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or
// - if PUSCH is transmitted with configured grant,
if (configured_grant_table == srsran_mcs_table_qam64LowSE &&
(rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) {
return ra_nr_table_3;
}
// if (configured_grant_table == srsran_mcs_table_qam64LowSE &&
// (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) {
// return ra_nr_table_3;
// }
return ra_nr_table_1;
}
@ -201,7 +200,6 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab
{
// Non-implemented parameters
bool sps_config_mcs_table_present = false;
srsran_mcs_table_t sps_config_mcs_table = srsran_mcs_table_64qam;
bool is_pdcch_sps = false;
// - the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam256', and
@ -233,10 +231,10 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab
// - the UE is configured with the higher layer parameter mcs-Table given by SPS-Config set to 'qam64LowSE'
// - if the PDSCH is scheduled by a PDCCH with CRC scrambled by CS-RNTI or
// - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config,
if (sps_config_mcs_table_present && sps_config_mcs_table == srsran_mcs_table_qam64LowSE &&
(rnti_type == srsran_rnti_type_cs || is_pdcch_sps)) {
return ra_nr_table_3;
}
// if (sps_config_mcs_table_present && sps_config_mcs_table == srsran_mcs_table_qam64LowSE &&
// (rnti_type == srsran_rnti_type_cs || is_pdcch_sps)) {
// return ra_nr_table_3;
// }
// else
return ra_nr_table_1;
@ -470,8 +468,6 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg,
uint32_t mcs_idx,
srsran_sch_tb_t* tb)
{
uint32_t cw_idx = 0;
// Get target Rate
double R = srsran_ra_nr_R_from_mcs(
pdsch_cfg->sch_cfg.mcs_table, grant->dci_format, grant->dci_search_space, grant->rnti_type, mcs_idx);
@ -515,11 +511,10 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg,
return SRSRAN_ERROR;
}
// Calculate number of layers accordingly
// Calculate number of layers accordingly, assumes first codeword only
uint32_t nof_cw = grant->nof_layers < 5 ? 1 : 2;
uint32_t nof_layers_cw1 = grant->nof_layers / nof_cw;
uint32_t nof_layers_cw2 = grant->nof_layers - nof_layers_cw1;
tb->N_L = (cw_idx == 0) ? nof_layers_cw1 : nof_layers_cw2;
tb->N_L = nof_layers_cw1;
// Check DMRS and CSI-RS collision according to TS 38.211 7.4.1.5.3 Mapping to physical resources
// If there was a collision, the number of RE in the grant would be wrong
@ -835,7 +830,7 @@ static float ra_ul_beta_offset_ack_semistatic(const srsran_beta_offsets_t* beta_
}
// Protect table boundary
if (beta_offset_index > RA_NR_BETA_OFFSET_HARQACK_SIZE) {
if (beta_offset_index >= RA_NR_BETA_OFFSET_HARQACK_SIZE) {
ERROR("Beta offset index for HARQ-ACK (%d) for O_ack=%d exceeds table size (%d)",
beta_offset_index,
uci_cfg->o_ack,
@ -860,8 +855,15 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_
return fix_beta_offset;
}
int O_csi1 = srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
int O_csi2 = srsran_csi_part2_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
if (O_csi1 < SRSRAN_SUCCESS || O_csi2 < SRSRAN_SUCCESS) {
ERROR("Invalid O_csi1 (%d) or O_csi2(%d)", O_csi1, O_csi2);
return NAN;
}
// Calculate number of CSI bits; CSI part 2 is not supported.
uint32_t O_csi = part2 ? 0 : srsran_csi_part1_nof_bits(uci_cfg->csi, uci_cfg->nof_csi);
uint32_t O_csi = (uint32_t)(part2 ? O_csi2 : O_csi1);
// Select Beta Offset index from the number of HARQ-ACK bits
uint32_t beta_offset_index = part2 ? beta_offsets->csi2_index1 : beta_offsets->csi1_index1;
@ -870,7 +872,7 @@ static float ra_ul_beta_offset_csi_semistatic(const srsran_beta_offsets_t* beta_
}
// Protect table boundary
if (beta_offset_index > RA_NR_BETA_OFFSET_CSI_SIZE) {
if (beta_offset_index >= RA_NR_BETA_OFFSET_CSI_SIZE) {
ERROR("Beta offset index for CSI (%d) for O_csi=%d exceeds table size (%d)",
beta_offset_index,
O_csi,

@ -52,7 +52,7 @@ int srsran_pscch_resources(uint32_t prb_num,
}
}
if (L == 0) {
if (L < 2) {
// ERROR("Invalid PSCCH subframe bitmap");
return SRSRAN_ERROR;
}
@ -199,8 +199,7 @@ int srsran_sci_generate_trp_idx(uint32_t duplex_mode, uint32_t tdd_config, uint3
retval = srsran_sl_N_TRP_6_k_6[srsran_random_uniform_int_dist(random, 0, sizeof(srsran_sl_N_TRP_6_k_6) - 1)];
break;
}
}
else {
} else {
retval = SRSRAN_SUCCESS;
}

@ -60,7 +60,7 @@ int srsran_ra_ul_nr_pusch_time_resource_default_A(uint32_t scs_cfg, uint32_t m,
return SRSRAN_ERROR_INVALID_INPUTS;
}
if (scs_cfg > 4) {
if (scs_cfg >= 4) {
ERROR("Invalid numerology (%d)", scs_cfg);
return SRSRAN_ERROR;
}

@ -258,7 +258,12 @@ static int encode_tb_off(srsran_sch_t* q,
if (cb_segm->C > softbuffer->max_cb) {
ERROR("Error number of CB to encode (%d) exceeds soft buffer size (%d CBs)", cb_segm->C, softbuffer->max_cb);
return -1;
return SRSRAN_ERROR;
}
if (Qm == 0) {
ERROR("Invalid Qm");
return SRSRAN_ERROR;
}
uint32_t Gp = nof_e_bits / Qm;
@ -508,7 +513,7 @@ static int decode_tb(srsran_sch_t* q,
int16_t* e_bits,
uint8_t* data)
{
if (q != NULL && data != NULL && softbuffer != NULL && e_bits != NULL && cb_segm != NULL) {
if (q != NULL && data != NULL && softbuffer != NULL && e_bits != NULL && cb_segm != NULL && Qm != 0) {
if (cb_segm->tbs == 0 || cb_segm->C == 0) {
return SRSRAN_SUCCESS;
}
@ -556,11 +561,12 @@ static int decode_tb(srsran_sch_t* q,
return SRSRAN_ERROR;
}
} else {
ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d",
ERROR("Missing inputs: data=%d, softbuffer=%d, e_bits=%d, cb_segm=%d Qm=%d",
data != 0,
softbuffer != 0,
e_bits != 0,
cb_segm != 0);
cb_segm != 0,
Qm);
return SRSRAN_ERROR_INVALID_INPUTS;
}
}
@ -1027,6 +1033,11 @@ static int uci_decode_ri_ack(srsran_sch_t* q,
uint32_t nb_q = cfg->grant.tb.nof_bits;
uint32_t Qm = srsran_mod_bits_x_symbol(cfg->grant.tb.mod);
if (Qm == 0) {
ERROR("Invalid modulation %s", srsran_mod_string(cfg->grant.tb.mod));
return SRSRAN_ERROR;
}
// If there is RI and CQI, assume RI = 1 for the purpose of RI/ACK decoding (3GPP 36.212 Clause 5.2.4.1. )
if (cfg->uci_cfg.cqi.data_enable) {
if (cfg->uci_cfg.cqi.type == SRSRAN_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_len) {
@ -1040,7 +1051,12 @@ static int uci_decode_ri_ack(srsran_sch_t* q,
if (srsran_uci_cfg_total_ack(&cfg->uci_cfg) > 0) {
float beta = get_beta_harq_offset(cfg->uci_offset.I_offset_ack);
if (cfg->grant.tb.tbs == 0) {
beta /= get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi);
float beta_cqi = get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi);
if (!isnormal(beta_cqi)) {
ERROR("Invalid beta_cqi (%d, %f)", cfg->uci_offset.I_offset_cqi, beta_cqi);
return SRSRAN_ERROR;
}
beta /= beta_cqi;
}
ret = srsran_uci_decode_ack_ri(cfg,
q_bits,
@ -1068,7 +1084,12 @@ static int uci_decode_ri_ack(srsran_sch_t* q,
if (cfg->uci_cfg.cqi.ri_len > 0) {
float beta = get_beta_ri_offset(cfg->uci_offset.I_offset_ri);
if (cfg->grant.tb.tbs == 0) {
beta /= get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi);
float beta_cqi = get_beta_cqi_offset(cfg->uci_offset.I_offset_cqi);
if (!isnormal(beta_cqi)) {
ERROR("Invalid beta_cqi (%d, %f)", cfg->uci_offset.I_offset_cqi, beta_cqi);
return SRSRAN_ERROR;
}
beta /= beta_cqi;
}
ret = srsran_uci_decode_ack_ri(cfg,
q_bits,

@ -120,12 +120,13 @@ int srsran_sch_nr_fill_tb_info(const srsran_carrier_nr_t* carrier,
cfg->Nl = tb->N_L;
// Calculate Nref
uint32_t N_re_lbrm = 156 * sch_nr_n_prb_lbrm(carrier->nof_prb);
uint32_t N_re_lbrm = SRSRAN_MAX_NRE_NR * sch_nr_n_prb_lbrm(carrier->nof_prb);
double TCR_lbrm = 948.0 / 1024.0;
uint32_t Qm_lbrm = (sch_cfg->mcs_table == srsran_mcs_table_256qam) ? 8 : 6;
uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, carrier->max_mimo_layers);
uint32_t max_mimo_layers = SRSRAN_MAX(carrier->max_mimo_layers, 4);
uint32_t TBS_LRBM = srsran_ra_nr_tbs(N_re_lbrm, 1.0, TCR_lbrm, Qm_lbrm, max_mimo_layers);
double R = 2.0 / 3.0;
cfg->Nref = ceil(TBS_LRBM / (cbsegm.C * R));
cfg->Nref = (uint32_t)ceil((double)TBS_LRBM / (double)(cbsegm.C * R));
// Calculate number of code blocks after applying CBGTI... not implemented, activate all CB
for (uint32_t r = 0; r < cbsegm.C; r++) {
@ -614,18 +615,37 @@ static int sch_nr_decode(srsran_sch_nr_t* q,
crc = &q->crc_cb;
}
// Decode
int n_iter = srsran_ldpc_decoder_decode_crc_c(decoder, rm_buffer, q->temp_cb, n_llr, crc);
if (n_iter < SRSRAN_SUCCESS) {
// Decode. if CRC=KO, then ret=0
int ret = srsran_ldpc_decoder_decode_crc_c(decoder, rm_buffer, q->temp_cb, n_llr, crc);
if (ret < SRSRAN_SUCCESS) {
ERROR("Error decoding CB");
return SRSRAN_ERROR;
}
nof_iter_sum += ((n_iter == 0) ? decoder->max_nof_iter : (uint32_t)n_iter);
// Compute CB CRC only if LDPC decoder reached the end
// Compute number of iterations
uint32_t n_iter_cb = (ret == 0) ? decoder->max_nof_iter : (uint32_t)ret;
nof_iter_sum += n_iter_cb;
// Check if CB is all zeros
uint32_t cb_len = cfg.Kp - cfg.L_cb;
tb->softbuffer.rx->cb_crc[r] = (n_iter != 0);
SCH_INFO_RX("CB %d/%d CRC=%s", r, cfg.C, tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO");
bool all_zeros = true;
for (uint32_t i = 0; i < cb_len && all_zeros; i++) {
all_zeros = (q->temp_cb[i] == 0);
}
tb->softbuffer.rx->cb_crc[r] = (ret != 0) && (!all_zeros);
SCH_INFO_RX("CB %d/%d iter=%d CRC=%s all_zeros=%s",
r,
cfg.C,
n_iter_cb,
tb->softbuffer.rx->cb_crc[r] ? "OK" : "KO",
all_zeros ? "yes" : "no");
// CB Debug trace
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
DEBUG("CB %d/%d:", r, cfg.C);
srsran_vec_fprint_hex(stdout, q->temp_cb, cb_len);
}
// Pack and count CRC OK only if CRC is match
if (tb->softbuffer.rx->cb_crc[r]) {
@ -636,6 +656,14 @@ static int sch_nr_decode(srsran_sch_nr_t* q,
input_ptr += E;
}
// Set average number of iterations
if (cfg.C > 0) {
res->avg_iter = (float)nof_iter_sum / (float)cfg.C;
} else {
res->avg_iter = NAN;
}
// Not all CB are decoded, skip TB union and CRC check
if (cb_ok != cfg.C) {
return SRSRAN_SUCCESS;
@ -656,12 +684,6 @@ static int sch_nr_decode(srsran_sch_nr_t* q,
srsran_vec_u8_copy(output_ptr, tb->softbuffer.rx->data[r], cb_len / 8);
output_ptr += cb_len / 8;
// CB Debug trace
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
DEBUG("CB %d/%d:", r, cfg.C);
srsran_vec_fprint_byte(stdout, tb->softbuffer.rx->data[r], cb_len / 8);
}
// Compute TB CRC for last block
if (cfg.C > 1 && r == cfg.C - 1) {
uint8_t tb_crc_unpacked[24] = {};
@ -671,26 +693,17 @@ static int sch_nr_decode(srsran_sch_nr_t* q,
}
}
// Check if TB is all zeros
bool all_zeros = true;
for (uint32_t i = 0; i < tb->tbs / 8 && all_zeros; i++) {
all_zeros = (res->payload[i] == 0);
}
// Calculate TB CRC from packed data
if (cfg.C == 1) {
res->crc = !all_zeros;
SCH_INFO_RX("TB: TBS=%d; CRC=%s", tb->tbs, tb->softbuffer.rx->cb_crc[0] ? "OK" : "KO");
res->crc = true;
} else {
// More than one
uint32_t checksum1 = srsran_crc_checksum_byte(crc_tb, res->payload, tb->tbs);
res->crc = (checksum1 == checksum2 && !all_zeros);
res->crc = (checksum1 == checksum2);
SCH_INFO_RX("TB: TBS=%d; CRC={%06x, %06x}", tb->tbs, checksum1, checksum2);
}
// Set average number of iterations
res->avg_iter = (float)nof_iter_sum / (float)cfg.C;
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
DEBUG("Decode: ");
srsran_vec_fprint_byte(stdout, res->payload, tb->tbs / 8);

@ -24,26 +24,28 @@
#include "srsran/phy/phch/sci.h"
#include "srsran/phy/utils/bit.h"
int srsran_sci_init(srsran_sci_t* q, srsran_cell_sl_t cell, srsran_sl_comm_resource_pool_t sl_comm_resource_pool)
int srsran_sci_init(srsran_sci_t* q,
const srsran_cell_sl_t* cell,
const srsran_sl_comm_resource_pool_t* sl_comm_resource_pool)
{
int ret = SRSRAN_ERROR_INVALID_INPUTS;
if (q != NULL) {
if (q != NULL && cell != NULL && sl_comm_resource_pool != NULL) {
ret = SRSRAN_ERROR;
bzero(q, sizeof(srsran_sci_t));
q->nof_prb = cell.nof_prb;
q->tm = cell.tm;
q->nof_prb = cell->nof_prb;
q->tm = cell->tm;
if (cell.tm == SRSRAN_SIDELINK_TM1 || cell.tm == SRSRAN_SIDELINK_TM2) {
if (cell->tm == SRSRAN_SIDELINK_TM1 || cell->tm == SRSRAN_SIDELINK_TM2) {
q->format = SRSRAN_SCI_FORMAT0;
q->sci_len = srsran_sci_format0_sizeof(cell.nof_prb);
q->sci_len = srsran_sci_format0_sizeof(cell->nof_prb);
} else if (cell.tm == SRSRAN_SIDELINK_TM3 || cell.tm == SRSRAN_SIDELINK_TM4) {
} else if (cell->tm == SRSRAN_SIDELINK_TM3 || cell->tm == SRSRAN_SIDELINK_TM4) {
q->format = SRSRAN_SCI_FORMAT1;
q->sci_len = SRSRAN_SCI_TM34_LEN;
q->size_sub_channel = sl_comm_resource_pool.size_sub_channel;
q->num_sub_channel = sl_comm_resource_pool.num_sub_channel;
q->size_sub_channel = sl_comm_resource_pool->size_sub_channel;
q->num_sub_channel = sl_comm_resource_pool->num_sub_channel;
} else {
return SRSRAN_ERROR;

@ -57,6 +57,8 @@ uint16_t rnti = 1234;
uint16_t i_tbs_val = 0;
char* input_file = NULL;
static srsran_random_t random_gen = NULL;
void usage(char* prog)
{
printf("Usage: %s [fmMlsrRFpnv] \n", prog);
@ -172,7 +174,7 @@ int get_ref_res(srsran_nbiot_cell_t cell, int32_t* re_with_refs)
return num_ref;
}
int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof_re)
int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof_re2)
{
srsran_npdsch_t npdsch;
bzero(&npdsch, sizeof(srsran_npdsch_t));
@ -206,8 +208,8 @@ int extract_re(srsran_nbiot_cell_t cell, uint32_t l_start, uint32_t expected_nof
#endif
// check number of extracted REs
if (nof_ext_syms != expected_nof_re) {
printf("RE extraction failed (expected %d, but got %d)!\n", expected_nof_re, nof_ext_syms);
if (nof_ext_syms != expected_nof_re2) {
printf("RE extraction failed (expected %d, but got %d)!\n", expected_nof_re2, nof_ext_syms);
return SRSRAN_ERROR;
}
@ -243,7 +245,9 @@ int re_extract_test(int argc, char** argv)
// Standalone mode with l_start=0 gives the maximum number of REs
cell.mode = mode;
cell.base.nof_prb = 1;
cell.base.id = (mode == SRSRAN_NBIOT_MODE_INBAND_SAME_PCI) ? n_id_ncell : rand() % SRSRAN_NUM_PCI;
cell.base.id = (mode == SRSRAN_NBIOT_MODE_INBAND_SAME_PCI)
? n_id_ncell
: srsran_random_uniform_int_dist(random_gen, 0, SRSRAN_NUM_PCI - 1);
cell.n_id_ncell = n_id_ncell;
cell.nof_ports = nof_ports_nbiot;
cell.base.nof_ports = nof_ports_lte;
@ -388,9 +392,8 @@ int coding_test(int argc, char** argv)
}
// generate random data
srand(time(NULL));
for (int i = 0; i < grant.mcs[0].tbs / 8; i++) {
data[i] = rand() % 256;
data[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 255);
}
if (!input_file) {
@ -473,7 +476,7 @@ quit:
int main(int argc, char** argv)
{
int ret = SRSRAN_ERROR;
random_gen = srsran_random_init(0x1234);
if (re_extract_test(argc, argv) != SRSRAN_SUCCESS) {
printf("Resource element extraction test failed!\n");
return ret;

@ -81,6 +81,7 @@ int main(int argc, char** argv)
int nof_re;
cf_t* sf_symbols[SRSRAN_MAX_PORTS];
uint32_t nof_rx_ports;
srsran_random_t random_gen = srsran_random_init(0x1234);
parse_args(argc, argv);
@ -109,9 +110,8 @@ int main(int argc, char** argv)
exit(-1);
}
srand(time(NULL));
for (i = 0; i < SRSRAN_BCH_PAYLOAD_LEN; i++) {
bch_payload_tx[i] = rand() % 2;
bch_payload_tx[i] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1);
}
srsran_pbch_encode(&pbch, bch_payload_tx, sf_symbols, 0);
@ -136,6 +136,7 @@ int main(int argc, char** argv)
}
srsran_chest_dl_res_free(&chest_dl_res);
srsran_random_free(random_gen);
printf("Tx ports: %d - Rx ports: %d\n", cell.nof_ports, nof_rx_ports);
printf("Tx payload: ");

@ -173,6 +173,7 @@ int main(int argc, char** argv)
int nof_dcis;
bzero(&testcases, sizeof(testcase_dci_t) * 10);
srsran_random_t random_gen = srsran_random_init(0x1234);
int ret = -1;
@ -233,14 +234,14 @@ int main(int argc, char** argv)
dci.type0_alloc.rbg_bitmask = 0x5;
dci.cif_present = dci_cfg.cif_enabled;
if (dci_cfg.cif_enabled) {
dci.cif = (uint32_t)(random() & 0x7);
dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7);
}
/* Format 1 Test case */
if (cell.nof_ports == 1) {
testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT1;
if (dci_cfg.cif_enabled) {
dci.cif = (uint32_t)(random() & 0x7);
dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7);
}
testcases[nof_dcis].ra_dl_tx = dci;
nof_dcis++;
@ -249,7 +250,7 @@ int main(int argc, char** argv)
dci.tb[0].mcs_idx = 15;
testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT1;
if (dci_cfg.cif_enabled) {
dci.cif = (uint32_t)(random() & 0x7);
dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7);
}
testcases[nof_dcis].ra_dl_tx = dci;
nof_dcis++;
@ -262,7 +263,7 @@ int main(int argc, char** argv)
dci.tb[1].ndi = true;
testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT2A;
if (dci_cfg.cif_enabled) {
dci.cif = (uint32_t)(random() & 0x7);
dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7);
}
testcases[nof_dcis].ra_dl_tx = dci;
nof_dcis++;
@ -275,15 +276,12 @@ int main(int argc, char** argv)
dci.tb[1].ndi = false;
testcases[nof_dcis].dci_format = SRSRAN_DCI_FORMAT2;
if (dci_cfg.cif_enabled) {
dci.cif = (uint32_t)(random() & 0x7);
dci.cif = (uint32_t)srsran_random_uniform_int_dist(random_gen, 0, 7);
}
testcases[nof_dcis].ra_dl_tx = dci;
nof_dcis++;
}
srsran_dci_cfg_t dci_cfg;
ZERO_OBJECT(dci_cfg);
srsran_dl_sf_cfg_t dl_sf;
ZERO_OBJECT(dl_sf);
dl_sf.cfi = cfi;
@ -400,6 +398,7 @@ quit:
srsran_pdcch_free(&pdcch_rx);
srsran_chest_dl_res_free(&chest_dl_res);
srsran_regs_free(&regs);
srsran_random_free(random_gen);
for (i = 0; i < SRSRAN_MAX_PORTS; i++) {
free(slot_symbols[i]);

@ -203,6 +203,7 @@ int main(int argc, char** argv)
srsran_chest_dl_t chest;
srsran_chest_dl_res_t chest_res;
srsran_pdsch_res_t pdsch_res[SRSRAN_MAX_CODEWORDS];
srsran_random_t random_gen = srsran_random_init(0x1234);
/* Initialise to zeros */
ZERO_OBJECT(softbuffers_tx);
@ -395,7 +396,7 @@ int main(int argc, char** argv)
for (int tb = 0; tb < SRSRAN_MAX_CODEWORDS; tb++) {
if (pdsch_cfg.grant.tb[tb].enabled) {
for (int byte = 0; byte < pdsch_cfg.grant.tb[tb].tbs / 8; byte++) {
data_tx[tb][byte] = (uint8_t)(rand() % 256);
data_tx[tb][byte] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 255);
}
}
}
@ -575,6 +576,7 @@ quit:
free(rx_slot_symbols[i]);
}
}
srsran_random_free(random_gen);
if (ret) {
printf("Error\n");
} else {

@ -107,6 +107,7 @@ int main(int argc, char** argv)
uint32_t nsf;
int cid, max_cid;
uint32_t ngroup, nseq, max_nseq;
srsran_random_t random_gen = srsran_random_init(0x1234);
parse_args(argc, argv);
@ -170,7 +171,7 @@ int main(int argc, char** argv)
resource.ngroup = ngroup;
resource.nseq = nseq;
ack[ngroup][nseq] = rand() % 2;
ack[ngroup][nseq] = (uint8_t)srsran_random_uniform_int_dist(random_gen, 0, 1);
srsran_phich_encode(&phich, &dl_sf, resource, ack[ngroup][nseq], slot_symbols);
}
@ -216,7 +217,7 @@ int main(int argc, char** argv)
cid++;
}
srsran_phich_free(&phich);
srsran_random_free(random_gen);
srsran_chest_dl_res_free(&chest_res);
for (i = 0; i < SRSRAN_MAX_PORTS; i++) {

@ -153,9 +153,8 @@ int main(int argc, char** argv)
{
parse_args(argc, argv);
srsran_prach_t prach;
srsran_random_t random_gen = srsran_random_init(0x1234);
bool high_speed_flag = false;
srand(0);
cf_t preamble[MAX_LEN];
memset(preamble, 0, sizeof(cf_t) * MAX_LEN);
cf_t preamble_sum[MAX_LEN];
@ -191,7 +190,7 @@ int main(int argc, char** argv)
printf("limiting number of preambles to 6\n");
if (test_offset_calculation) {
for (int i = 0; i < 6; i++) {
offsets[i] = (rand() % 50);
offsets[i] = srsran_random_uniform_int_dist(random_gen, 0, 49);
}
}
}
@ -261,6 +260,7 @@ int main(int argc, char** argv)
}
srsran_prach_free(&prach);
srsran_random_free(random_gen);
printf("Done\n");
exit(0);
}

@ -107,7 +107,7 @@ int main(int argc, char** argv)
// SCI
srsran_sci_t sci;
srsran_sci_init(&sci, cell, sl_comm_resource_pool);
srsran_sci_init(&sci, &cell, &sl_comm_resource_pool);
sci.mcs_idx = 2;
// PSCCH

@ -160,7 +160,10 @@ int base_init()
}
srsran_vec_cf_zero(input_buffer, sf_n_samples);
srsran_sci_init(&sci, cell, sl_comm_resource_pool);
if (srsran_sci_init(&sci, &cell, &sl_comm_resource_pool) < SRSRAN_SUCCESS) {
ERROR("Error in SCI init");
return SRSRAN_ERROR;
}
if (srsran_pscch_init(&pscch, SRSRAN_MAX_PRB) != SRSRAN_SUCCESS) {
ERROR("Error in PSCCH init");
@ -177,7 +180,7 @@ int base_init()
return SRSRAN_ERROR;
}
if (srsran_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSRAN_SUCCESS) {
if (srsran_pssch_init(&pssch, &cell, &sl_comm_resource_pool) != SRSRAN_SUCCESS) {
ERROR("Error initializing PSSCH");
return SRSRAN_ERROR;
}

@ -92,7 +92,7 @@ int main(int argc, char** argv)
}
srsran_pssch_t pssch = {};
if (srsran_pssch_init(&pssch, cell, sl_comm_resource_pool) != SRSRAN_SUCCESS) {
if (srsran_pssch_init(&pssch, &cell, &sl_comm_resource_pool) != SRSRAN_SUCCESS) {
ERROR("Error initializing PSSCH");
return SRSRAN_ERROR;
}

@ -116,6 +116,9 @@ int main(int argc, char** argv)
srsran_sch_nr_args_t args = {};
args.disable_simd = false;
args.decoder_use_flooded = false;
args.decoder_scaling_factor = 0.8;
args.max_nof_iter = 20;
if (srsran_sch_nr_init_tx(&sch_nr_tx, &args) < SRSRAN_SUCCESS) {
ERROR("Error initiating SCH NR for Tx");
goto clean_exit;
@ -152,10 +155,9 @@ int main(int argc, char** argv)
}
// Use grant default A time resources with m=0
if (srsran_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_cfg.grant) < SRSRAN_SUCCESS) {
ERROR("Error loading default grant");
goto clean_exit;
}
pdsch_cfg.grant.S = 1;
pdsch_cfg.grant.L = 13;
pdsch_cfg.grant.k = 0;
pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers;
pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0;

@ -433,6 +433,11 @@ static uint32_t Q_prime_ri_ack(srsran_pusch_cfg_t* cfg, uint32_t O, uint32_t O_c
}
}
if (K == 0) {
ERROR("K is zero!");
return 0;
}
uint32_t x = (uint32_t)ceilf((float)O * cfg->grant.L_prb * SRSRAN_NRE * cfg->grant.nof_symb * beta / K);
uint32_t Q_prime = SRSRAN_MIN(x, 4 * cfg->grant.L_prb * SRSRAN_NRE);

@ -1106,13 +1106,13 @@ int srsran_uci_nr_decode_pusch_ack(srsran_uci_nr_t* q,
int8_t* llr,
srsran_uci_value_nr_t* value)
{
int A = cfg->o_ack;
// Check inputs
if (q == NULL || cfg == NULL || llr == NULL || value == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
int A = cfg->o_ack;
// 6.3.2.1 UCI bit sequence generation
// 6.3.2.1.1 HARQ-ACK
bool has_csi_part2 = srsran_csi_has_part2(cfg->csi, cfg->nof_csi);

@ -222,9 +222,13 @@ public:
stream_args.channels[i] = i;
}
if (not usrp->get_device()->get_tree()->exists(TREE_DBOARD_RX_FRONTEND_NAME)) {
// Try to get dboard name from property tree
uhd::property_tree::sptr tree = usrp->get_device()->get_tree();
if (tree == nullptr || not tree->exists(TREE_DBOARD_RX_FRONTEND_NAME)) {
// Couldn't find dboard name in property tree
return err;
}
std::string dboard_name = usrp->get_device()->get_tree()->access<std::string>(TREE_DBOARD_RX_FRONTEND_NAME).get();
// Detect if it a AD9361 based device

@ -192,6 +192,10 @@ void srsran_psss_put_sf_buffer(cf_t* psss_signal, cf_t* sf_buffer, uint32_t nof_
*/
int srsran_psss_find(srsran_psss_t* q, cf_t* input, uint32_t nof_prb, srsran_cp_t cp)
{
if (q == NULL || input == NULL) {
return SRSRAN_ERROR_INVALID_INPUTS;
}
// One array for each N_id_2
float corr_peak_value[2] = {};
uint32_t corr_peak_pos[2] = {};

@ -134,7 +134,8 @@ int fdd_tests(uint32_t max_cc)
for (uint32_t i = 0; i < nof_cc; i++) {
TESTASSERT(uci_data.cfg.ack[i].ncce[0] == i + 1);
for (uint32_t j = 0; j < uci_data.cfg.ack[i].nof_acks; j++) {
TESTASSERT(uci_data.value.ack.ack_value[k++]);
TESTASSERT(uci_data.value.ack.ack_value[k]);
k++;
}
}
TESTASSERT(k == srsran_uci_cfg_total_ack(&uci_data.cfg));
@ -152,7 +153,6 @@ int fdd_tests(uint32_t max_cc)
int main(int argc, char** argv)
{
// Test only until Format1B - CS
TESTASSERT(fdd_tests(2) == 0);

@ -19,6 +19,8 @@
*
*/
#include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/random.h"
#include <complex.h>
#include <math.h>
#include <stdio.h>
@ -87,30 +89,42 @@ int test_dft(cf_t* in)
{
int res = 0;
srsran_dft_plan_t plan;
cf_t* out1 = srsran_vec_cf_malloc(N);
cf_t* out2 = srsran_vec_cf_malloc(N);
srsran_vec_cf_zero(out1, N);
srsran_vec_cf_zero(out2, N);
srsran_dft_plan_t plan = {};
if (forward) {
srsran_dft_plan(&plan, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX);
if (srsran_dft_plan(&plan, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) {
ERROR("Error in DFT plan");
goto clean_exit;
}
} else {
srsran_dft_plan(&plan, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX);
if (srsran_dft_plan(&plan, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) {
ERROR("Error in DFT plan");
goto clean_exit;
}
}
srsran_dft_plan_set_mirror(&plan, mirror);
srsran_dft_plan_set_norm(&plan, norm);
srsran_dft_plan_set_dc(&plan, dc);
cf_t* out1 = srsran_vec_cf_malloc(N);
cf_t* out2 = srsran_vec_cf_malloc(N);
srsran_vec_cf_zero(out1, N);
srsran_vec_cf_zero(out2, N);
print(in, N);
srsran_dft_run(&plan, in, out1);
print(out1, N);
srsran_dft_plan_t plan_rev;
if (!forward) {
srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX);
if (srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_FORWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) {
ERROR("Error in DFT plan");
goto clean_exit;
}
} else {
srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX);
if (srsran_dft_plan(&plan_rev, N, SRSRAN_DFT_BACKWARD, SRSRAN_DFT_COMPLEX) != SRSRAN_SUCCESS) {
ERROR("Error in DFT plan");
goto clean_exit;
}
}
srsran_dft_plan_set_mirror(&plan_rev, mirror);
srsran_dft_plan_set_norm(&plan_rev, norm);
@ -131,6 +145,7 @@ int test_dft(cf_t* in)
res = -1;
}
clean_exit:
srsran_dft_plan_free(&plan);
srsran_dft_plan_free(&plan_rev);
free(out1);
@ -141,19 +156,17 @@ int test_dft(cf_t* in)
int main(int argc, char** argv)
{
srsran_random_t random_gen = srsran_random_init(0x1234);
parse_args(argc, argv);
cf_t* in = srsran_vec_cf_malloc(N);
srsran_vec_cf_zero(in, N);
for (int i = 1; i < N - 1; i++) {
float re = 100 * rand() / (float)RAND_MAX;
float im = 100 * rand() / (float)RAND_MAX;
in[i] = re + im * I;
}
in[0] = 0.0f;
srsran_random_uniform_complex_dist_vector(random_gen, &in[1], N - 1, -1, 1);
if (test_dft(in) != 0)
return -1;
free(in);
srsran_random_free(random_gen);
printf("Done\n");
exit(0);
}

@ -133,7 +133,15 @@ TEST(
for (int i = 0; i < block_size; i++) { gold += x[i] * y[i]; }
mse = (gold - z) / abs(gold);
// Check...
float abs_gold = abs(gold);
if (isnormal(abs_gold)) {
// Protected zero division
mse = (gold - z) / abs_gold;
} else {
// Flag error
mse = MAX_MSE;
}
free(x);
free(y);)

@ -430,12 +430,22 @@ void srsran_vec_save_file(char* filename, const void* buffer, const uint32_t len
}
}
#define SAFE_READ(PTR, SIZE, N, FILE) \
do { \
size_t nbytes = SIZE * N; \
if (nbytes != fread(PTR, SIZE, N, FILE)) { \
perror("read"); \
fclose(FILE); \
exit(1); \
} \
} while (false)
void srsran_vec_load_file(char* filename, void* buffer, const uint32_t len)
{
FILE* f;
f = fopen(filename, "r");
if (f) {
fread(buffer, len, 1, f);
SAFE_READ(buffer, len, 1, f);
fclose(f);
} else {
perror("fopen");

@ -539,17 +539,15 @@ void rlc_am_lte::rlc_am_lte_tx::discard_sdu(uint32_t discard_sn)
return false;
});
if (discarded) {
// remove also from undelivered SDUs queue
logger.info("Discarding SDU with PDCP_SN=%d", discard_sn);
// Discard fails when the PDCP PDU is already in Tx window.
logger.info("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn);
// always try remove from undelivered SDUs queue
if (not undelivered_sdu_info_queue.has_pdcp_sn(discard_sn)) {
logger.info("PDCP SDU info does not exists for discarded SDU. PDCP_SN=%d", discard_sn);
} else {
undelivered_sdu_info_queue.clear_pdcp_sdu(discard_sn);
}
} else {
logger.info("Could not find SDU to discard. PDCP_SN=%d", discard_sn);
}
}
bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full()
@ -1308,6 +1306,10 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn)
// Iterate over all PDCP SNs of the same RLC PDU that were TX'ed
for (rlc_am_pdu_segment& acked_segment : acked_pdu) {
uint32_t pdcp_sn = acked_segment.pdcp_sn();
if (pdcp_sn == rlc_am_pdu_segment::invalid_pdcp_sn) {
logger.debug("ACKed segment in RLC_SN=%d already discarded in PDCP. No need to notify the PDCP.", rlc_sn);
continue;
}
pdcp_pdu_info& info = undelivered_sdu_info_queue[pdcp_sn];
// Remove RLC SN from PDCP PDU undelivered list

@ -495,7 +495,7 @@ int make_phy_dmrs_additional_pos_test()
dmrs_ul_cfg.dmrs_add_position_present = true;
dmrs_ul_cfg.dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1;
srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos;
TESTASSERT(make_phy_dmrs_additional_pos(dmrs_ul_cfg, &srsran_dmrs_sch_add_pos) == true);
TESTASSERT(make_phy_dmrs_ul_additional_pos(dmrs_ul_cfg, &srsran_dmrs_sch_add_pos) == true);
TESTASSERT(srsran_dmrs_sch_add_pos == srsran_dmrs_sch_add_pos_1);

@ -64,7 +64,11 @@ add_lte_test(pucch_ca_test pucch_ca_test)
add_executable(phy_dl_nr_test phy_dl_nr_test.c)
target_link_libraries(phy_dl_nr_test srsran_phy srsran_common srsran_phy ${SEC_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
add_nr_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28)
add_nr_test(phy_dl_nr_test phy_dl_nr_test -p 100 -m 28 )
add_nr_test(phy_dl_nr_test_rvd phy_dl_nr_test -P 52 -p 52 -m 0
-R 0 52 1 010010010010 00000000010000
-R 0 52 1 100100100100 00000010000000)
add_nr_test(phy_dl_nr_test_cfo_delay phy_dl_nr_test -P 52 -p 52 -m 27 -C 100.0 -D 4 -n 10)
add_nr_test(phy_dl_nr_test_52prb phy_dl_nr_test -P 52 -p 52 -m 27 -T 256qam -v -d 1 1 -n 10)
add_nr_test(phy_dl_nr_test_270prb phy_dl_nr_test -P 270 -p 270 -m 27 -T 256qam -v -d 1 1 -n 10)

@ -44,17 +44,20 @@ static uint32_t mcs = 30; // Set to 30 for steering
static srsran_sch_cfg_nr_t pdsch_cfg = {};
static uint32_t nof_slots = 10;
static uint32_t rv_idx = 0;
static uint32_t delay_n = 4; // Integer delay
static float cfo_hz = 100.0f; // CFO Hz
static uint32_t delay_n = 0; // Integer delay
static float cfo_hz = 0.0f; // CFO Hz
static srsran_dmrs_sch_type_t dmrs_type = srsran_dmrs_sch_type_1;
static srsran_dmrs_sch_add_pos_t dmrs_add_pos = srsran_dmrs_sch_add_pos_2;
static void usage(char* prog)
{
printf("Usage: %s [pTL] \n", prog);
printf("Usage: %s [rRPdpmnTLDCv] \n", prog);
printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb);
printf("\t-p Number of grant PRB, set to 0 for steering [Default %d]\n", n_prb);
printf("\t-n Number of slots to simulate [Default %d]\n", nof_slots);
printf("\t-m MCS PRB, set to >28 for steering [Default %d]\n", mcs);
printf("\t-r Redundancy version, set to >28 for steering [Default %d]\n", mcs);
printf("\t-d DMRS configuration [type 1-2] [add_pos 2-3] [CDM groups 1-3] [Default %d]\n", mcs);
printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n",
srsran_mcs_table_to_str(pdsch_cfg.sch_cfg.mcs_table));
printf("\t-R Reserve RE: [rb_begin] [rb_end] [rb_stride] [sc_mask] [symbol_mask]\n");
@ -67,7 +70,7 @@ static void usage(char* prog)
static int parse_args(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "rRPpmnTLDCv")) != -1) {
while ((opt = getopt(argc, argv, "rRPdpmnTLDCv")) != -1) {
switch (opt) {
case 'P':
carrier.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10);
@ -84,6 +87,30 @@ static int parse_args(int argc, char** argv)
case 'r':
rv_idx = (uint32_t)strtol(argv[optind], NULL, 10);
break;
case 'd':
switch (strtol(argv[optind++], NULL, 10)) {
case 1:
dmrs_type = srsran_dmrs_sch_type_1;
break;
case 2:
dmrs_type = srsran_dmrs_sch_type_2;
break;
}
switch (strtol(argv[optind], NULL, 10)) {
case 0:
dmrs_add_pos = srsran_dmrs_sch_add_pos_0;
break;
case 1:
dmrs_add_pos = srsran_dmrs_sch_add_pos_1;
break;
case 2:
dmrs_add_pos = srsran_dmrs_sch_add_pos_2;
break;
case 3:
dmrs_add_pos = srsran_dmrs_sch_add_pos_3;
break;
}
break;
case 'T':
pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_from_str(argv[optind]);
break;
@ -211,7 +238,12 @@ int main(int argc, char** argv)
cf_t* buffer_gnb[SRSRAN_MAX_PORTS] = {};
cf_t* buffer_ue[SRSRAN_MAX_PORTS] = {};
uint32_t sf_len = SRSRAN_SF_LEN_PRB(carrier.nof_prb);
// Set default PDSCH configuration
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
uint32_t sf_len = SRSRAN_SF_LEN_PRB_NR(carrier.nof_prb);
buffer_gnb[0] = srsran_vec_cf_malloc(sf_len);
buffer_ue[0] = srsran_vec_cf_malloc(sf_len);
if (buffer_gnb[0] == NULL || buffer_ue[0] == NULL) {
@ -234,18 +266,12 @@ int main(int argc, char** argv)
enb_dl_args.pdcch.disable_simd = false;
enb_dl_args.nof_max_prb = carrier.nof_prb;
// Set default PDSCH configuration
pdsch_cfg.sch_cfg.mcs_table = srsran_mcs_table_64qam;
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
srsran_pdcch_cfg_nr_t pdcch_cfg = {};
// Configure CORESET
srsran_coreset_t* coreset = &pdcch_cfg.coreset[1];
pdcch_cfg.coreset_present[1] = true;
coreset->duration = 2;
coreset->duration = 1;
for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) {
coreset->freq_resources[i] = i < carrier.nof_prb / 6;
}
@ -324,11 +350,11 @@ int main(int argc, char** argv)
}
// Use grant default A time resources with m=0
pdsch_cfg.dmrs.type = dmrs_type;
pdsch_cfg.dmrs.typeA_pos = srsran_dmrs_sch_typeA_pos_2;
if (srsran_ra_dl_nr_time_default_A(0, pdsch_cfg.dmrs.typeA_pos, &pdsch_cfg.grant) < SRSRAN_SUCCESS) {
ERROR("Error loading default grant");
goto clean_exit;
}
pdsch_cfg.dmrs.additional_pos = dmrs_add_pos;
pdsch_cfg.grant.S = 1;
pdsch_cfg.grant.L = 13;
pdsch_cfg.grant.nof_layers = carrier.max_mimo_layers;
pdsch_cfg.grant.dci_format = srsran_dci_format_nr_1_0;
pdsch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1;
@ -380,12 +406,8 @@ int main(int argc, char** argv)
// Compute PDCCH candidate locations
uint32_t L = 1;
uint32_t ncce_candidates[SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR] = {};
int nof_candidates = srsran_pdcch_nr_locations_coreset(coreset,
search_space,
pdsch_cfg.grant.rnti,
L,
SRSRAN_SLOT_NR_MOD(carrier.scs, slot.idx),
ncce_candidates);
int nof_candidates = srsran_pdcch_nr_locations_coreset(
coreset, search_space, pdsch_cfg.grant.rnti, L, SRSRAN_SLOT_NR_MOD(carrier.scs, slot.idx), ncce_candidates);
if (nof_candidates < SRSRAN_SUCCESS) {
ERROR("Error getting PDCCH candidates");
goto clean_exit;

@ -283,11 +283,13 @@ int mac::cell_cfg(const std::vector<sched_interface::cell_cfg_t>& cell_cfg_)
void mac::get_metrics(mac_metrics_t& metrics)
{
srsran::rwlock_read_guard lock(rwlock);
int cnt = 0;
metrics.ues.resize(ue_db.size());
metrics.ues.reserve(ue_db.size());
for (auto& u : ue_db) {
u.second->metrics_read(&metrics.ues[cnt]);
cnt++;
if (not scheduler.ue_exists(u.first)) {
continue;
}
metrics.ues.emplace_back();
u.second->metrics_read(&metrics.ues.back());
}
metrics.cc_rach_counter = detected_rachs;
}

@ -152,8 +152,9 @@ void cc_worker::decode_pdcch_dl()
if (logger.debug.enabled()) {
for (uint32_t i = 0; i < ue_dl.pdcch_info_count; i++) {
const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl.pdcch_info[i];
logger.debug("PDCCH: rnti=0x%x, crst_id=%d, ss_type=%d, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; "
logger.debug("PDCCH: dci=%s, rnti=%x, crst_id=%d, ss_type=%d, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; "
"nof_bits=%d; crc=%s;",
srsran_dci_format_nr_string(info->dci_ctx.format),
info->dci_ctx.rnti,
info->dci_ctx.coreset_id,
info->dci_ctx.ss_type,
@ -361,8 +362,10 @@ bool cc_worker::work_ul()
}
}
// Add SR to UCI data if available
// Add SR to UCI data only if there is no UL grant!
if (!has_ul_ack) {
phy->get_pending_sr(ul_slot_cfg.idx, uci_data);
}
// Add CSI reports to UCI data if available
phy->get_periodic_csi(ul_slot_cfg.idx, uci_data);

@ -615,6 +615,31 @@ bool rrc_nr::apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_
bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_cfg)
{
if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a_present) {
if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.type() == setup_release_c<dmrs_dl_cfg_s>::types_opts::setup) {
srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos;
if (make_phy_dmrs_dl_additional_pos(pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) ==
true) {
phy_cfg.pdsch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos;
phy_cfg.pdsch.dmrs_typeA.present = true;
} else {
logger.warning("Warning while build srsran_dmrs_sch_add_pos structure");
return false;
}
} else {
logger.warning("Option dmrs_dl_for_pdsch_map_type_a not of type setup");
return false;
}
} else {
logger.warning("Option dmrs_dl_for_pdsch_map_type_a not present");
return false;
}
srsran_resource_alloc_t resource_alloc;
if (make_phy_pdsch_alloc_type(pdsch_cfg, &resource_alloc) == true) {
phy_cfg.pdsch.alloc = resource_alloc;
}
if (pdsch_cfg.zp_csi_rs_res_to_add_mod_list_present) {
for (uint32_t i = 0; i < pdsch_cfg.zp_csi_rs_res_to_add_mod_list.size(); i++) {
srsran_csi_rs_zp_resource_t zp_csi_rs_resource;
@ -1000,10 +1025,15 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c
bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg)
{
srsran_resource_alloc_t resource_alloc;
if (make_phy_pusch_alloc_type(pusch_cfg, &resource_alloc) == true) {
phy_cfg.pusch.alloc = resource_alloc;
}
if (pusch_cfg.dmrs_ul_for_pusch_map_type_a_present) {
if (pusch_cfg.dmrs_ul_for_pusch_map_type_a.type() == setup_release_c<dmrs_ul_cfg_s>::types_opts::setup) {
srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos;
if (make_phy_dmrs_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) ==
if (make_phy_dmrs_ul_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) ==
true) {
phy_cfg.pusch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos;
phy_cfg.pusch.dmrs_typeA.present = true;

Loading…
Cancel
Save