NR-PUSCH RE mapping correction and NR-SCH detailed grant information

master
Xavier Arteaga 4 years ago committed by Andre Puschmann
parent 52bf973981
commit 01ce0718be

@ -245,4 +245,6 @@ typedef struct SRSRAN_API {
bool freq_hopping_enabled;
} srsran_sch_cfg_nr_t;
SRSRAN_API uint32_t srsran_phch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len);
#endif // SRSRAN_PHCH_CFG_NR_H

@ -50,6 +50,7 @@ typedef struct SRSRAN_API {
srsran_evm_buffer_t* evm_buffer;
bool meas_time_en;
uint32_t meas_time_us;
srsran_re_pattern_t dmrs_re_pattern;
srsran_uci_cfg_nr_t uci_cfg; ///< Internal UCI bits configuration
uint8_t* g_ulsch; ///< Temporal Encoded UL-SCH data
uint8_t* g_ack; ///< Temporal Encoded HARQ-ACK bits

@ -307,11 +307,11 @@ uint32_t srsran_csi_str(const srsran_csi_report_cfg_t* report_cfg,
for (uint32_t i = 0; i < nof_reports; i++) {
if (report_cfg[i].freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND &&
report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI) {
len = srsran_print_check(str, str_len, len, ", cqi=%d", report_value[i].wideband_cri_ri_pmi_cqi.cqi);
len = srsran_print_check(str, str_len, len, "cqi=%d ", report_value[i].wideband_cri_ri_pmi_cqi.cqi);
} else if (report_cfg[i].quantity == SRSRAN_CSI_REPORT_QUANTITY_NONE) {
char tmp[20] = {};
srsran_vec_sprint_bin(tmp, sizeof(tmp), report_value[i].none, report_cfg->K_csi_rs);
len = srsran_print_check(str, str_len, len, ", csi=%s", tmp);
len = srsran_print_check(str, str_len, len, "csi=%s ", tmp);
}
}
return len;

@ -185,6 +185,8 @@ void srsran_pdsch_nr_free(srsran_pdsch_nr_t* q)
if (q->evm_buffer != NULL) {
srsran_evm_free(q->evm_buffer);
}
SRSRAN_MEM_ZERO(q, srsran_pdsch_nr_t, 1);
}
static inline uint32_t pdsch_nr_put_rb(cf_t* dst, cf_t* src, bool* rvd_mask)
@ -575,7 +577,6 @@ static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q,
uint32_t str_len)
{
uint32_t len = 0;
len = srsran_print_check(str, str_len, len, "rnti=0x%x ", grant->rnti);
uint32_t first_prb = SRSRAN_MAX_PRB_NR;
for (uint32_t i = 0; i < SRSRAN_MAX_PRB_NR && first_prb == SRSRAN_MAX_PRB_NR; i++) {
@ -585,27 +586,8 @@ static uint32_t pdsch_nr_grant_info(const srsran_pdsch_nr_t* q,
}
// Append time-domain resource mapping
len = srsran_print_check(str,
str_len,
len,
"beta_dmrs=%.3f CDM-grp=%d k0=%d prb=%d:%d symb=%d:%d mapping=%s ",
isnormal(grant->beta_dmrs) ? grant->beta_dmrs : 1.0f,
grant->nof_dmrs_cdm_groups_without_data,
grant->k,
first_prb,
grant->nof_prb,
grant->S,
grant->L,
srsran_sch_mapping_type_to_str(grant->mapping));
// Skip frequency domain resources...
// ...
// Append spatial resources
len = srsran_print_check(str, str_len, len, "Nl=%d ", grant->nof_layers);
// Append scrambling ID
len = srsran_print_check(str, str_len, len, "n_scid=%d ", grant->n_scid);
len = srsran_print_check(
str, str_len, len, "rnti=0x%x prb=%d:%d symb=%d:%d ", grant->rnti, first_prb, grant->nof_prb, grant->S, grant->L);
// Append TB info
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
@ -634,11 +616,6 @@ uint32_t srsran_pdsch_nr_rx_info(const srsran_pdsch_nr_t* q,
len += pdsch_nr_grant_info(q, cfg, grant, res, &str[len], str_len - len);
if (cfg->rvd_re.count != 0) {
len = srsran_print_check(str, str_len, len, "Reserved: ");
len += srsran_re_pattern_list_info(&cfg->rvd_re, &str[len], str_len - len);
}
if (q->meas_time_en) {
len = srsran_print_check(str, str_len, len, " t=%d us", q->meas_time_us);
}

@ -0,0 +1,247 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srsran/phy/phch/phch_cfg_nr.h"
#include "srsran/phy/ch_estimation/dmrs_sch.h"
#include "srsran/phy/phch/uci_nr.h"
static const char* dmrs_sch_type_to_str(srsran_dmrs_sch_type_t type)
{
switch (type) {
case srsran_dmrs_sch_type_1:
return "1";
case srsran_dmrs_sch_type_2:
return "2";
default:; // Do nothing
}
return "invalid";
}
static const char* dmrs_sch_add_pos_to_str(srsran_dmrs_sch_add_pos_t add_pos)
{
switch (add_pos) {
case srsran_dmrs_sch_add_pos_2:
return "2";
case srsran_dmrs_sch_add_pos_0:
return "0";
case srsran_dmrs_sch_add_pos_1:
return "1";
case srsran_dmrs_sch_add_pos_3:
return "3";
default:; // Do nothing
}
return "invalid";
}
static const char* dmrs_sch_len_to_str(srsran_dmrs_sch_len_t len)
{
switch (len) {
case srsran_dmrs_sch_len_1:
return "single";
case srsran_dmrs_sch_len_2:
return "double";
default:; // Do nothing
}
return "invalid";
}
static const char* dmrs_sch_typeApos_to_str(srsran_dmrs_sch_typeA_pos_t typeA_pos)
{
switch (typeA_pos) {
case srsran_dmrs_sch_typeA_pos_2:
return "2";
case srsran_dmrs_sch_typeA_pos_3:
return "3";
default:; // Do nothing
}
return "invalid";
}
static uint32_t phch_cfg_nr_dmrs_to_str(const srsran_dmrs_sch_cfg_t* dmrs,
const srsran_sch_grant_nr_t* grant,
char* str,
uint32_t str_len)
{
uint32_t len = 0;
len = srsran_print_check(str, str_len, len, " DMRS:\n");
len = srsran_print_check(str, str_len, len, " type=%s\n", dmrs_sch_type_to_str(dmrs->type));
len = srsran_print_check(str, str_len, len, " add_pos=%s\n", dmrs_sch_add_pos_to_str(dmrs->additional_pos));
len = srsran_print_check(str, str_len, len, " len=%s\n", dmrs_sch_len_to_str(dmrs->length));
len = srsran_print_check(str, str_len, len, " typeA_pos=%s\n", dmrs_sch_typeApos_to_str(dmrs->typeA_pos));
if (dmrs->scrambling_id0_present) {
len = srsran_print_check(str, str_len, len, " scrambling_id_0=%03x\n", dmrs->scrambling_id0);
}
if (dmrs->scrambling_id1_present) {
len = srsran_print_check(str, str_len, len, " scrambling_id_1=%03x\n", dmrs->scrambling_id1);
}
if (dmrs->lte_CRS_to_match_around) {
len = srsran_print_check(str, str_len, len, " lte_CRS_to_match_around=y\n");
}
if (dmrs->additional_DMRS_DL_Alt) {
len = srsran_print_check(str, str_len, len, " additional_DMRS_DL_Alt=y\n");
}
srsran_re_pattern_t pattern = {};
if (srsran_dmrs_sch_rvd_re_pattern(dmrs, grant, &pattern) == SRSRAN_SUCCESS) {
len = srsran_print_check(str, str_len, len, " rvd_pattern: ");
len += srsran_re_pattern_info(&pattern, &str[len], str_len - len);
len = srsran_print_check(str, str_len, len, "\n");
}
return len;
}
static const char* sch_mapping_to_str(srsran_sch_mapping_type_t mapping)
{
switch (mapping) {
case srsran_sch_mapping_type_A:
return "A";
case srsran_sch_mapping_type_B:
return "B";
default:; // Do nothing
}
return "invalid";
}
static const char* sch_xoverhead_to_str(srsran_xoverhead_t xoverhead)
{
switch (xoverhead) {
case srsran_xoverhead_0:
return "0";
case srsran_xoverhead_6:
return "6";
case srsran_xoverhead_12:
return "12";
case srsran_xoverhead_18:
return "18";
default:; // Do nothing
}
return "invalid";
}
static uint32_t phch_cfg_tb_to_str(const srsran_sch_tb_t* tb, char* str, uint32_t str_len)
{
uint32_t len = 0;
if (!tb->enabled) {
return len;
}
len = srsran_print_check(str, str_len, len, " CW%d:\n", tb->cw_idx);
len = srsran_print_check(str, str_len, len, " mod=%s\n", srsran_mod_string(tb->mod));
len = srsran_print_check(str, str_len, len, " nof_layers=%d\n", tb->N_L);
len = srsran_print_check(str, str_len, len, " mcs=%d\n", tb->mcs);
len = srsran_print_check(str, str_len, len, " tbs=%d\n", tb->tbs);
len = srsran_print_check(str, str_len, len, " R=%.3f\n", tb->R);
len = srsran_print_check(str, str_len, len, " rv=%d\n", tb->rv);
len = srsran_print_check(str, str_len, len, " ndi=%d\n", tb->ndi);
len = srsran_print_check(str, str_len, len, " pid=%d\n", tb->pid);
len = srsran_print_check(str, str_len, len, " nof_re=%d\n", tb->nof_re);
len = srsran_print_check(str, str_len, len, " nof_bits=%d\n", tb->nof_bits);
return len;
}
static uint32_t phch_cfg_grant_to_str(const srsran_sch_grant_nr_t* grant, char* str, uint32_t str_len)
{
uint32_t len = 0;
uint32_t first_prb = SRSRAN_MAX_PRB_NR;
for (uint32_t i = 0; i < SRSRAN_MAX_PRB_NR && first_prb == SRSRAN_MAX_PRB_NR; i++) {
if (grant->prb_idx[i]) {
first_prb = i;
}
}
len = srsran_print_check(str, str_len, len, " Grant:\n");
len = srsran_print_check(str, str_len, len, " rnti=0x%x\n", grant->rnti);
len = srsran_print_check(str, str_len, len, " rnti_type=%s\n", srsran_rnti_type_str(grant->rnti_type));
len = srsran_print_check(str, str_len, len, " k=%d\n", grant->k);
len = srsran_print_check(str, str_len, len, " mapping=%s\n", sch_mapping_to_str(grant->mapping));
len = srsran_print_check(str, str_len, len, " t_alloc=%d:%d\n", grant->S, grant->L);
len = srsran_print_check(str, str_len, len, " f_alloc=%d:%d\n", first_prb, grant->nof_prb);
len = srsran_print_check(str, str_len, len, " nof_dmrs_cdm_grps=%d\n", grant->nof_dmrs_cdm_groups_without_data);
len = srsran_print_check(str, str_len, len, " beta_dmrs=%f\n", grant->beta_dmrs);
len = srsran_print_check(str, str_len, len, " nof_layers=%d\n", grant->nof_layers);
len = srsran_print_check(str, str_len, len, " n_scid=%d\n", grant->n_scid);
len = srsran_print_check(str, str_len, len, " tb_scaling_field=%d\n", grant->tb_scaling_field);
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
len += phch_cfg_tb_to_str(&grant->tb[i], &str[len], str_len - len);
}
return len;
}
static uint32_t phch_cfg_sch_to_str(const srsran_sch_cfg_t* sch, char* str, uint32_t str_len)
{
uint32_t len = 0;
len = srsran_print_check(str, str_len, len, " SCH:\n");
len = srsran_print_check(str, str_len, len, " mcs_table=%s\n", srsran_mcs_table_to_str(sch->mcs_table));
len = srsran_print_check(str, str_len, len, " xoverhead=%s\n", sch_xoverhead_to_str(sch->xoverhead));
return len;
}
static uint32_t phch_cfg_rvd_to_str(const srsran_re_pattern_list_t* pattern_list, char* str, uint32_t str_len)
{
uint32_t len = 0;
if (pattern_list->count == 0) {
return len;
}
len = srsran_print_check(str, str_len, len, " Reserved:\n");
for (uint32_t i = 0; i < pattern_list->count; i++) {
len = srsran_print_check(str, str_len, len, " %d=", i);
len += srsran_re_pattern_info(&pattern_list->data[i], &str[len], str_len - len);
len = srsran_print_check(str, str_len, len, "\n");
}
return len;
}
uint32_t srsran_phch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, uint32_t str_len)
{
uint32_t len = 0;
if (sch_cfg->scambling_id) {
len = srsran_print_check(str, str_len, len, " scrambling_id=0x%03x\n", sch_cfg->scrambling_id_present);
}
// Append DMRS information
len += phch_cfg_nr_dmrs_to_str(&sch_cfg->dmrs, &sch_cfg->grant, &str[len], str_len - len);
// Append grant information
len += phch_cfg_grant_to_str(&sch_cfg->grant, &str[len], str_len - len);
// Append SCH information
len += phch_cfg_sch_to_str(&sch_cfg->sch_cfg, &str[len], str_len - len);
// Append SCH information
len += phch_cfg_rvd_to_str(&sch_cfg->rvd_re, &str[len], str_len - len);
// UCI configuration
if (srsran_uci_nr_total_bits(&sch_cfg->uci)) {
len = srsran_print_check(str, str_len, len, " scaling=%.2f\n", sch_cfg->scaling);
len = srsran_print_check(str, str_len, len, " beta_csi_part1_offset=%.2f\n", sch_cfg->beta_csi_part1_offset);
len = srsran_print_check(str, str_len, len, " beta_csi_part2_offset=%.2f\n", sch_cfg->beta_csi_part2_offset);
len = srsran_print_check(str, str_len, len, " beta_harq_ack_offset=%.2f\n", sch_cfg->beta_harq_ack_offset);
}
return len;
}

@ -227,171 +227,25 @@ void srsran_pusch_nr_free(srsran_pusch_nr_t* q)
SRSRAN_MEM_ZERO(q, srsran_pusch_nr_t, 1);
}
/**
* @brief copies a number of countiguous Resource Elements
* @param sf_symbols slot symbols in frequency domain
* @param symbols resource elements
* @param count number of resource elements to copy
* @param put Direction, symbols are copied into sf_symbols if put is true, otherwise sf_symbols are copied into symbols
*/
static void srsran_pusch_re_cp(cf_t* sf_symbols, cf_t* symbols, uint32_t count, bool put)
{
if (put) {
srsran_vec_cf_copy(sf_symbols, symbols, count);
} else {
srsran_vec_cf_copy(symbols, sf_symbols, count);
}
}
/*
* As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with group 2:
*
* +---+---+---+---+---+---+---+---+---+---+---+---+
* | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 | 1 | 1 | 2 | 2 |
* +---+---+---+---+---+---+---+---+---+---+---+---+
* -- k -->
*
* If the number of DMRS CDM groups without data is set to:
* - 1, data is mapped in RE marked as 2
* - Otherwise, no data is mapped in this symbol
*/
static uint32_t srsran_pusch_nr_cp_dmrs_type1(const srsran_pusch_nr_t* q,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
static inline uint32_t pusch_nr_put_rb(cf_t* dst, cf_t* src, bool* rvd_mask)
{
uint32_t count = 0;
uint32_t delta = 0;
if (grant->nof_dmrs_cdm_groups_without_data != 1) {
return count;
}
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
if (grant->prb_idx[i]) {
for (uint32_t j = 0; j < SRSRAN_NRE; j += 2) {
if (put) {
sf_symbols[i * SRSRAN_NRE + delta + j + 1] = symbols[count++];
} else {
symbols[count++] = sf_symbols[i * SRSRAN_NRE + delta + j + 1];
}
}
for (uint32_t i = 0; i < SRSRAN_NRE; i++) {
if (!rvd_mask[i]) {
dst[i] = src[count++];
}
}
return count;
}
/*
* As a RB is 12 RE wide, positions marked as 1 will be used for the 1st CDM group, and the same with groups 2 and 3:
*
* +---+---+---+---+---+---+---+---+---+---+---+---+
* | 1 | 1 | 2 | 2 | 3 | 3 | 1 | 1 | 2 | 2 | 3 | 3 |
* +---+---+---+---+---+---+---+---+---+---+---+---+
* -- k -->
*
* If the number of DMRS CDM groups without data is set to:
* - 1, data is mapped in RE marked as 2 and 3
* - 2, data is mapped in RE marked as 3
* - otherwise, no data is mapped in this symbol
*/
static uint32_t srsran_pusch_nr_cp_dmrs_type2(const srsran_pusch_nr_t* q,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
static inline uint32_t pusch_nr_get_rb(cf_t* dst, cf_t* src, bool* rvd_mask)
{
uint32_t count = 0;
if (grant->nof_dmrs_cdm_groups_without_data != 1 && grant->nof_dmrs_cdm_groups_without_data != 2) {
return count;
}
uint32_t re_offset = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 2 : 4;
uint32_t re_count = (grant->nof_dmrs_cdm_groups_without_data == 1) ? 4 : 2;
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
if (grant->prb_idx[i]) {
// Copy RE between pilot pairs
srsran_pusch_re_cp(&sf_symbols[i * SRSRAN_NRE + re_offset], &symbols[count], re_count, put);
count += re_count;
// Copy RE after second pilot
srsran_pusch_re_cp(&sf_symbols[(i + 1) * SRSRAN_NRE - re_count], &symbols[count], re_count, put);
count += re_count;
for (uint32_t i = 0; i < SRSRAN_NRE; i++) {
if (!rvd_mask[i]) {
dst[count++] = src[i];
}
}
return count;
}
static uint32_t srsran_pusch_nr_cp_dmrs(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
const srsran_dmrs_sch_cfg_t* dmrs_cfg = &cfg->dmrs;
switch (dmrs_cfg->type) {
case srsran_dmrs_sch_type_1:
count = srsran_pusch_nr_cp_dmrs_type1(q, grant, symbols, sf_symbols, put);
break;
case srsran_dmrs_sch_type_2:
count = srsran_pusch_nr_cp_dmrs_type2(q, grant, symbols, sf_symbols, put);
break;
}
return count;
}
static uint32_t srsran_pusch_nr_cp_clean(const srsran_pusch_nr_t* q,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
uint32_t start = 0; // Index of the start of continuous data
uint32_t length = 0; // End of continuous RE
for (uint32_t i = 0; i < q->carrier.nof_prb; i++) {
if (grant->prb_idx[i]) {
// If fist continuous block, save start
if (length == 0) {
start = i * SRSRAN_NRE;
}
length += SRSRAN_NRE;
} else {
// Consecutive block is finished
if (put) {
srsran_vec_cf_copy(&sf_symbols[start], &symbols[count], length);
} else {
srsran_vec_cf_copy(&symbols[count], &sf_symbols[start], length);
}
// Increase RE count
count += length;
// Reset consecutive block
length = 0;
}
}
// Copy last contiguous block
if (length > 0) {
if (put) {
srsran_vec_cf_copy(&sf_symbols[start], &symbols[count], length);
} else {
srsran_vec_cf_copy(&symbols[count], &sf_symbols[start], length);
}
count += length;
}
return count;
}
@ -402,55 +256,60 @@ static int srsran_pusch_nr_cp(const srsran_pusch_nr_t* q,
cf_t* sf_symbols,
bool put)
{
uint32_t count = 0;
uint32_t dmrs_l_idx[SRSRAN_DMRS_SCH_MAX_SYMBOLS] = {};
uint32_t dmrs_l_count = 0;
uint32_t count = 0;
// Get symbol indexes carrying DMRS
int32_t nof_dmrs_symbols = srsran_dmrs_sch_get_symbols_idx(&cfg->dmrs, grant, dmrs_l_idx);
if (nof_dmrs_symbols < SRSRAN_SUCCESS) {
return SRSRAN_ERROR;
}
for (uint32_t l = grant->S; l < grant->S + grant->L; l++) {
// Initialise reserved RE mask to all false
bool rvd_mask[SRSRAN_NRE * SRSRAN_MAX_PRB_NR] = {};
if (SRSRAN_DEBUG_ENABLED && srsran_verbose >= SRSRAN_VERBOSE_DEBUG && !handler_registered) {
DEBUG("dmrs_l_idx=");
srsran_vec_fprint_i(stdout, (int32_t*)dmrs_l_idx, nof_dmrs_symbols);
}
// Reserve DMRS
if (srsran_re_pattern_to_symbol_mask(&q->dmrs_re_pattern, l, rvd_mask) < SRSRAN_SUCCESS) {
ERROR("Error generating DMRS reserved RE mask");
return SRSRAN_ERROR;
}
for (uint32_t l = grant->S; l < grant->S + grant->L; l++) {
// Advance DMRS symbol counter until:
// - the current DMRS symbol index is greater or equal than current symbol l
// - no more DMRS symbols
while (dmrs_l_idx[dmrs_l_count] < l && dmrs_l_count < nof_dmrs_symbols) {
dmrs_l_count++;
// Reserve RE from configuration
if (srsran_re_pattern_list_to_symbol_mask(&cfg->rvd_re, l, rvd_mask) < SRSRAN_SUCCESS) {
ERROR("Error generating reserved RE mask");
return SRSRAN_ERROR;
}
if (l == dmrs_l_idx[dmrs_l_count]) {
count += srsran_pusch_nr_cp_dmrs(
q, cfg, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSRAN_NRE], put);
} else {
count +=
srsran_pusch_nr_cp_clean(q, grant, &symbols[count], &sf_symbols[l * q->carrier.nof_prb * SRSRAN_NRE], put);
// Actual copy
for (uint32_t rb = 0; rb < q->carrier.nof_prb; rb++) {
// Skip PRB if not available in grant
if (!grant->prb_idx[rb]) {
continue;
}
// Calculate RE index at the begin of the symbol
uint32_t re_idx = (q->carrier.nof_prb * l + rb) * SRSRAN_NRE;
// Put or get
if (put) {
count += pusch_nr_put_rb(&sf_symbols[re_idx], &symbols[count], &rvd_mask[rb * SRSRAN_NRE]);
} else {
count += pusch_nr_get_rb(&symbols[count], &sf_symbols[re_idx], &rvd_mask[rb * SRSRAN_NRE]);
}
}
}
return count;
}
static int srsran_pusch_nr_put(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols)
static int pusch_nr_put(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols)
{
return srsran_pusch_nr_cp(q, cfg, grant, symbols, sf_symbols, true);
}
static int srsran_pusch_nr_get(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols)
static int pusch_nr_get(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
cf_t* symbols,
cf_t* sf_symbols)
{
return srsran_pusch_nr_cp(q, cfg, grant, symbols, sf_symbols, false);
}
@ -950,6 +809,12 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q,
return SRSRAN_ERROR;
}
// Compute DMRS pattern
if (srsran_dmrs_sch_rvd_re_pattern(&cfg->dmrs, grant, &q->dmrs_re_pattern) < SRSRAN_SUCCESS) {
ERROR("Error computing DMRS pattern");
return SRSRAN_ERROR;
}
// Fill UCI configuration for PUSCH configuration
if (pusch_nr_fill_uci_cfg(q, cfg) < SRSRAN_SUCCESS) {
ERROR("Error filling UCI configuration for PUSCH");
@ -982,7 +847,7 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q,
// ... Not implemented
// 7.3.1.6 Mapping from virtual to physical resource blocks
int n = srsran_pusch_nr_put(q, cfg, grant, x[0], sf_symbols[0]);
int n = pusch_nr_put(q, cfg, grant, x[0], sf_symbols[0]);
if (n < SRSRAN_SUCCESS) {
ERROR("Putting NR PUSCH resources");
return SRSRAN_ERROR;
@ -1166,6 +1031,12 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
return SRSRAN_ERROR;
}
// Compute DMRS pattern
if (srsran_dmrs_sch_rvd_re_pattern(&cfg->dmrs, grant, &q->dmrs_re_pattern) < SRSRAN_SUCCESS) {
ERROR("Error computing DMRS pattern");
return SRSRAN_ERROR;
}
// Fill UCI configuration for PUSCH configuration
if (pusch_nr_fill_uci_cfg(q, cfg) < SRSRAN_SUCCESS) {
ERROR("Error filling UCI configuration for PUSCH");
@ -1185,7 +1056,7 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
}
// Demapping from virtual to physical resource blocks
uint32_t nof_re_get = srsran_pusch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]);
uint32_t nof_re_get = pusch_nr_get(q, cfg, grant, q->x[0], sf_symbols[0]);
if (nof_re_get != nof_re) {
ERROR("Inconsistent number of RE (%d!=%d)", nof_re_get, nof_re);
return SRSRAN_ERROR;
@ -1230,14 +1101,14 @@ int srsran_pusch_nr_decode(srsran_pusch_nr_t* q,
return SRSRAN_SUCCESS;
}
static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
const srsran_pusch_res_nr_t* res,
char* str,
uint32_t str_len)
static uint32_t pusch_nr_grant_info(const srsran_pusch_nr_t* q,
const srsran_sch_cfg_nr_t* cfg,
const srsran_sch_grant_nr_t* grant,
const srsran_pusch_res_nr_t* res,
char* str,
uint32_t str_len)
{
uint32_t len = 0;
len = srsran_print_check(str, str_len, len, "rnti=0x%x", grant->rnti);
uint32_t first_prb = SRSRAN_MAX_PRB_NR;
for (uint32_t i = 0; i < SRSRAN_MAX_PRB_NR && first_prb == SRSRAN_MAX_PRB_NR; i++) {
@ -1247,29 +1118,20 @@ static uint32_t srsran_pusch_nr_grant_info(const srsran_sch_cfg_nr_t* cfg,
}
// Append time-domain resource mapping
len = srsran_print_check(str,
str_len,
len,
",k2=%d,prb=%d:%d,S=%d,L=%d,mapping=%s",
grant->k,
first_prb,
grant->nof_prb,
grant->S,
grant->L,
srsran_sch_mapping_type_to_str(grant->mapping));
// Skip frequency domain resources...
// ...
// Append spatial resources
len = srsran_print_check(str, str_len, len, ",Nl=%d", grant->nof_layers);
// Append scrambling ID
len = srsran_print_check(str, str_len, len, ",n_scid=%d,", grant->n_scid);
len = srsran_print_check(
str, str_len, len, "rnti=0x%x prb=%d:%d symb=%d:%d ", grant->rnti, first_prb, grant->nof_prb, grant->S, grant->L);
// Append TB info
for (uint32_t i = 0; i < SRSRAN_MAX_TB; i++) {
len += srsran_sch_nr_tb_info(&grant->tb[i], &res->tb[i], &str[len], str_len - len);
if (res != NULL) {
if (grant->tb[i].enabled && !isnan(res->evm[i])) {
len = srsran_print_check(str, str_len, len, "evm=%.2f ", res->evm[i]);
if (i < SRSRAN_MAX_CODEWORDS - 1) {
}
}
}
}
return len;
@ -1288,45 +1150,18 @@ uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q,
return 0;
}
len += srsran_pusch_nr_grant_info(cfg, grant, res, &str[len], str_len - len);
len += pusch_nr_grant_info(q, cfg, grant, res, &str[len], str_len - len);
if (q->evm_buffer != NULL) {
len = srsran_print_check(str, str_len, len, ",evm={", 0);
for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) {
if (grant->tb[i].enabled && !isnan(res->evm[i])) {
len = srsran_print_check(str, str_len, len, "%.2f", res[i].evm);
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, "}", 0);
}
if (res != NULL) {
if (res != NULL && srsran_uci_nr_total_bits(&cfg->uci) > 0) {
len = srsran_print_check(str, str_len, len, "UCI: ");
srsran_uci_data_nr_t uci_data = {};
uci_data.cfg = cfg->uci;
uci_data.value = res[0].uci;
uci_data.value = res->uci;
len += srsran_uci_nr_info(&uci_data, &str[len], str_len - len);
len = srsran_print_check(str, str_len, len, ",crc={", 0);
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->tb[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, "}", 0);
}
if (q->meas_time_en) {
len = srsran_print_check(str, str_len, len, ", t=%d us", q->meas_time_us);
len = srsran_print_check(str, str_len, len, " t=%d us", q->meas_time_us);
}
return len;
@ -1345,7 +1180,7 @@ uint32_t srsran_pusch_nr_tx_info(const srsran_pusch_nr_t* q,
return 0;
}
len += srsran_pusch_nr_grant_info(cfg, grant, NULL, &str[len], str_len - len);
len += pusch_nr_grant_info(q, cfg, grant, NULL, &str[len], str_len - len);
if (uci_value != NULL) {
srsran_uci_data_nr_t uci_data = {};

@ -734,15 +734,12 @@ int srsran_sch_nr_tb_info(const srsran_sch_tb_t* tb, const srsran_sch_tb_res_nr_
len = srsran_print_check(str,
str_len,
len,
"CW%d: mod=%s Nl=%d tbs=%d R=%.3f rv=%d Nre=%d Nbit=%d ",
"CW%d: mod=%s tbs=%d R=%.3f rv=%d ",
tb->cw_idx,
srsran_mod_string(tb->mod),
tb->N_L,
tb->tbs / 8,
tb->R,
tb->rv,
tb->nof_re,
tb->nof_bits);
tb->rv);
if (res != NULL) {
len = srsran_print_check(str, str_len, len, "CRC=%s iter=%.1f ", res->crc ? "OK" : "KO", res->avg_iter);

@ -340,6 +340,15 @@ int main(int argc, char** argv)
}
}
if (srsran_verbose >= SRSRAN_VERBOSE_INFO) {
char str[512];
srsran_pusch_nr_rx_info(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &data_rx, str, (uint32_t)sizeof(str));
char str_extra[2048];
srsran_phch_cfg_nr_info(&pusch_cfg, str_extra, (uint32_t)sizeof(str_extra));
INFO("PUSCH: %s\n%s", str, str_extra);
}
printf("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!\n", n_prb, mcs, pusch_cfg.grant.tb[0].tbs, data_rx.evm[0]);
}
}

@ -986,9 +986,9 @@ uint32_t srsran_uci_nr_info(const srsran_uci_data_nr_t* uci_data, char* str, uin
uint32_t len = 0;
if (uci_data->cfg.o_ack > 0) {
char str2[10];
srsran_vec_sprint_bin(str2, 10, uci_data->value.ack, uci_data->cfg.o_ack);
len = srsran_print_check(str, str_len, len, ", ack=%s", str2);
char str_ack[10];
srsran_vec_sprint_bin(str_ack, (uint32_t)sizeof(str_ack), uci_data->value.ack, uci_data->cfg.o_ack);
len = srsran_print_check(str, str_len, len, "ack=%s ", str_ack);
}
if (uci_data->cfg.nof_csi > 0) {
@ -996,7 +996,7 @@ uint32_t srsran_uci_nr_info(const srsran_uci_data_nr_t* uci_data, char* str, uin
}
if (uci_data->cfg.o_sr > 0) {
len = srsran_print_check(str, str_len, len, ", sr=%d", uci_data->value.sr);
len = srsran_print_check(str, str_len, len, "sr=%d ", uci_data->value.sr);
}
return len;

@ -448,6 +448,15 @@ int main(int argc, char** argv)
}
}
if (srsran_verbose >= SRSRAN_VERBOSE_INFO) {
char str[512];
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str, (uint32_t)sizeof(str));
char str_extra[2048];
srsran_phch_cfg_nr_info(&pdsch_cfg, str_extra, (uint32_t)sizeof(str_extra));
INFO("PDSCH: %s\n%s", str, str_extra);
}
INFO("n_prb=%d; mcs=%d; TBS=%d; EVM=%f; PASSED!", n_prb, mcs, pdsch_cfg.grant.tb[0].tbs, pdsch_res.evm[0]);
// Count the Tx/Rx'd number of bits

@ -39,6 +39,10 @@ public:
int read_pdsch_d(cf_t* pdsch_d);
private:
// PHY lib temporal logger types
typedef std::array<char, 512> str_info_t;
typedef std::array<char, 2048> str_extra_t;
bool configured = false;
srsran_slot_cfg_t dl_slot_cfg = {};
srsran_slot_cfg_t ul_slot_cfg = {};
@ -51,7 +55,7 @@ private:
srsran_ue_ul_nr_t ue_ul = {};
srslog::basic_logger& logger;
// Methods for DL...
// Methods for DCI blind search
void decode_pdcch_ul();
void decode_pdcch_dl();
};

@ -271,9 +271,21 @@ bool cc_worker::work_dl()
// Logging
if (logger.info.enabled()) {
std::array<char, 512> str;
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str.data(), str.size());
logger.info(pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d, %s", cc_idx, str.data());
str_info_t str;
srsran_ue_dl_nr_pdsch_info(&ue_dl, &pdsch_cfg, &pdsch_res, str.data(), (uint32_t)str.size());
if (logger.debug.enabled()) {
str_extra_t str_extra;
srsran_phch_cfg_nr_info(&pdsch_cfg, str_extra.data(), (uint32_t)str_extra.size());
logger.info(pdsch_res.tb[0].payload,
pdsch_cfg.grant.tb[0].tbs / 8,
"PDSCH: cc=%d, %s\n%s",
cc_idx,
str.data(),
str_extra.data());
} else {
logger.info(pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8, "PDSCH: cc=%d, %s", cc_idx, str.data());
}
}
// Enqueue PDSCH ACK information only if the RNTI is type C
@ -398,14 +410,21 @@ bool cc_worker::work_ul()
// PUSCH Logging
if (logger.info.enabled()) {
std::array<char, 512> str;
str_info_t str;
srsran_ue_ul_nr_pusch_info(&ue_ul, &pusch_cfg, &data.uci, str.data(), str.size());
logger.info(ul_action.tb.payload->msg,
pusch_cfg.grant.tb[0].tbs / 8,
"PUSCH: cc=%d, %s, tti_tx=%d",
cc_idx,
str.data(),
ul_slot_cfg.idx);
if (logger.debug.enabled()) {
str_extra_t str_extra;
srsran_phch_cfg_nr_info(&pusch_cfg, str_extra.data(), (uint32_t)str_extra.size());
logger.info(ul_action.tb.payload->msg,
pusch_cfg.grant.tb[0].tbs / 8,
"PUSCH: cc=%d, %s\n%s",
cc_idx,
str.data(),
str_extra.data());
} else {
logger.info(ul_action.tb.payload->msg, pusch_cfg.grant.tb[0].tbs / 8, "PUSCH: cc=%d, %s", cc_idx, str.data());
}
}
// Set metrics

Loading…
Cancel
Save