mirror of https://github.com/PentHertz/srsLTE.git
Added DCI Format 0_0 unpacking and more NR-PUSCH procedures
This commit is contained in:
parent
b150e45129
commit
77f0a53abd
|
@ -143,6 +143,7 @@ typedef enum SRSLTE_API {
|
|||
srslte_search_space_type_common_2, ///< configured by pagingSearchSpace in PDCCH-ConfigCommon
|
||||
srslte_search_space_type_common_3, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = common
|
||||
srslte_search_space_type_ue, ///< configured by SearchSpace in PDCCH-Config with searchSpaceType = ue-Specific
|
||||
srslte_search_space_rar ///< No search space associated, used for grants given by Random Access Response (RAR)
|
||||
} srslte_search_space_type_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,11 +62,44 @@ typedef struct SRSLTE_API {
|
|||
|
||||
} srslte_dci_dl_nr_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
// Context information
|
||||
uint16_t rnti;
|
||||
srslte_rnti_type_t rnti_type;
|
||||
srslte_dci_format_nr_t format;
|
||||
srslte_dci_location_t location;
|
||||
srslte_search_space_type_t search_space;
|
||||
uint32_t coreset_id;
|
||||
|
||||
// Common fields
|
||||
uint32_t freq_domain_assigment; ///< Frequency domain resource assignment
|
||||
uint32_t time_domain_assigment; ///< Time domain resource assignment
|
||||
uint32_t freq_hopping_flag; ///< Frequency hopping flag
|
||||
uint32_t mcs; ///< Modulation and coding scheme
|
||||
uint32_t rv; ///< Redundancy version
|
||||
uint32_t reserved; ///< Reserved bits
|
||||
|
||||
// C-RNTI or CS-RNTI or MCS-C-RNTI
|
||||
uint32_t ndi; ///< New data indicator
|
||||
uint32_t pid; ///< HARQ process number
|
||||
uint32_t tpc; ///< TPC command for scheduled PUCCH
|
||||
uint32_t pucch_resource; ///< PUCCH resource indicator
|
||||
uint32_t harq_feedback; ///< PDSCH-to-HARQ_feedback timing indicator
|
||||
|
||||
// Frequency hopping
|
||||
uint32_t frequency_offset; ///< frequency offset
|
||||
|
||||
} srslte_dci_ul_nr_t;
|
||||
|
||||
SRSLTE_API int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
const srslte_dci_dl_nr_t* dci,
|
||||
srslte_dci_msg_nr_t* msg);
|
||||
|
||||
SRSLTE_API int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
srslte_rnti_type_t rnti_type);
|
||||
|
||||
SRSLTE_API SRSLTE_API int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
srslte_rnti_type_t rnti_type);
|
||||
|
@ -81,6 +114,6 @@ SRSLTE_API int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrie
|
|||
srslte_dci_msg_nr_t* msg,
|
||||
srslte_dci_dl_nr_t* dci);
|
||||
|
||||
SRSLTE_API int srslte_dci_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len);
|
||||
SRSLTE_API int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len);
|
||||
|
||||
#endif // SRSLTE_DCI_NR_H
|
||||
|
|
|
@ -82,21 +82,23 @@ typedef struct {
|
|||
} srslte_dmrs_sch_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief flatten PDSCH time domain allocation parameters
|
||||
* @brief Common flatten PDSCH and PUSCH time domain allocation parameters
|
||||
* @remark Described in TS 38.331 V15.10.0 Section PDSCH-TimeDomainResourceAllocationList
|
||||
* @remark Described in TS 38.331 V15.10.0 Section PUSCH-TimeDomainResourceAllocationList
|
||||
*/
|
||||
typedef struct SRSLTE_API {
|
||||
/// Slot offset between DCI and its scheduled PDSCH
|
||||
uint32_t k0;
|
||||
/// For PDSCH Slot offset between DCI and its scheduled PDSCH
|
||||
/// For PUSCH parameter K2
|
||||
uint32_t k;
|
||||
|
||||
/// PDSCH mapping type
|
||||
/// SCH mapping type
|
||||
srslte_sch_mapping_type_t mapping_type;
|
||||
|
||||
/// An index giving valid combinations of start symbol and length (jointly encoded) as start and length indicator
|
||||
/// (SLIV). The network configures the field so that the allocation does not cross the slot boundary
|
||||
uint32_t sliv;
|
||||
|
||||
} srslte_pdsch_time_ra_t;
|
||||
} srslte_sch_time_ra_t;
|
||||
|
||||
/**
|
||||
* @brief PDSCH grant information provided by the Downlink Control Information (DCI)
|
||||
|
@ -144,6 +146,8 @@ typedef struct SRSLTE_API {
|
|||
* @remark Described in TS 38.331 V15.10.0 Section PUSCH-Config
|
||||
*/
|
||||
typedef struct SRSLTE_API {
|
||||
// Serving cell parameters
|
||||
uint32_t scs_cfg; // Subcarrier spacing configuration
|
||||
srslte_dmrs_sch_typeA_pos_t typeA_pos;
|
||||
|
||||
bool scrambling_id_present;
|
||||
|
@ -157,28 +161,35 @@ typedef struct SRSLTE_API {
|
|||
uint32_t scrambling_id0;
|
||||
bool scrambling_id1_present;
|
||||
uint32_t scrambling_id1;
|
||||
bool present;
|
||||
} dmrs_typeA;
|
||||
|
||||
bool dmrs_typeA_present;
|
||||
srslte_dmrs_sch_cfg_t dmrs_typeB;
|
||||
bool dmrs_typeB_present;
|
||||
struct {
|
||||
srslte_dmrs_sch_type_t type;
|
||||
srslte_dmrs_sch_add_pos_t additional_pos;
|
||||
srslte_dmrs_sch_len_t length;
|
||||
bool scrambling_id0_present;
|
||||
uint32_t scrambling_id0;
|
||||
bool scrambling_id1_present;
|
||||
uint32_t scrambling_id1;
|
||||
bool present;
|
||||
} dmrs_typeB;
|
||||
|
||||
srslte_pdsch_time_ra_t common_pdsch_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION];
|
||||
uint32_t nof_common_pdsch_time_ra;
|
||||
srslte_sch_time_ra_t common_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION];
|
||||
uint32_t nof_common_time_ra;
|
||||
|
||||
srslte_pdsch_time_ra_t pdsch_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION];
|
||||
uint32_t nof_pdsch_time_ra;
|
||||
srslte_sch_time_ra_t dedicated_time_ra[SRSLTE_MAX_NOF_DL_ALLOCATION];
|
||||
uint32_t nof_dedicated_time_ra;
|
||||
|
||||
bool rbg_size_cfg_1; ///< RBG size configuration (1 or 2)
|
||||
|
||||
srslte_sch_cfg_t sch_cfg; ///< Common shared channel parameters
|
||||
} srslte_pdsch_cfg_nr_t;
|
||||
} srslte_sch_hl_cfg_nr_t;
|
||||
|
||||
/**
|
||||
* @brief Common NR-SCH (PDSCH and PUSCH for NR) configuration
|
||||
*/
|
||||
typedef struct SRSLTE_API {
|
||||
|
||||
bool scrambling_id_present;
|
||||
uint32_t scambling_id; // Identifier used to initialize data scrambling (0-1023)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* @remark Defined by TS 38.214 V15.10.0 section 5.1.2.1.1 Determination of the resource allocation table to be used for
|
||||
* PDSCH
|
||||
*
|
||||
* @param pdsch_cfg Flattened PDSCH configuration provided from higher layers
|
||||
* @param cfg Flattened PDSCH configuration provided from higher layers
|
||||
* @param rnti_type Type of the RNTI of the corresponding DCI
|
||||
* @param ss_type Type of the SS for PDCCH
|
||||
* @param coreset_id CORESET identifier associated with the PDCCH transmission
|
||||
|
@ -41,7 +41,7 @@
|
|||
* @param[out] Provides grant pointer to fill
|
||||
* @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_dl_nr_time(const srslte_pdsch_cfg_nr_t* cfg,
|
||||
SRSLTE_API int srslte_ra_dl_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_rnti_type_t rnti_type,
|
||||
const srslte_search_space_type_t ss_type,
|
||||
const uint32_t coreset_id,
|
||||
|
@ -85,7 +85,7 @@ SRSLTE_API int srslte_ra_dl_nr_nof_dmrs_cdm_groups_without_data_format_1_0(const
|
|||
* @return SRSLTE_SUCCESS if the provided data is valid, SRSLTE_ERROR code otherwise
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_pdsch_cfg_nr_t* cfg,
|
||||
const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_grant_nr_t* grant);
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ SRSLTE_API int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg,
|
|||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_pdsch_cfg_nr_t* pdsch_cfg,
|
||||
const srslte_sch_hl_cfg_nr_t* pdsch_cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_cfg_nr_t* cfg,
|
||||
srslte_sch_grant_nr_t* pdsch_grant);
|
||||
|
|
|
@ -13,10 +13,59 @@
|
|||
#ifndef SRSLTE_RA_UL_NR_H
|
||||
#define SRSLTE_RA_UL_NR_H
|
||||
|
||||
#include "dci_nr.h"
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/phy/phch/phch_cfg_nr.h"
|
||||
#include "srslte/phy/phch/pucch_cfg_nr.h"
|
||||
#include "uci_cfg_nr.h"
|
||||
|
||||
/**
|
||||
* @brief Calculates the PUSCH time resource allocation and stores it in the provided PUSCH NR grant.
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 section 6.1.2.1.1 Determination of the resource allocation table to be used for
|
||||
* PUSCH
|
||||
*
|
||||
* @param cfg Flattened PUSCH configuration provided from higher layers
|
||||
* @param rnti_type Type of the RNTI of the corresponding DCI
|
||||
* @param ss_type Type of the SS for PDCCH
|
||||
* @param coreset_id CORESET identifier associated with the PDCCH transmission
|
||||
* @param m Time domain resource assignment field value m provided in DCI
|
||||
* @param[out] Provides grant pointer to fill
|
||||
* @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_rnti_type_t rnti_type,
|
||||
const srslte_search_space_type_t ss_type,
|
||||
const uint32_t coreset_id,
|
||||
const uint8_t m,
|
||||
srslte_sch_grant_nr_t* grant);
|
||||
|
||||
/**
|
||||
* @brief Calculates the PUSCH time resource default A and stores it in the provided PUSCH NR grant.
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 Table 6.1.2.1.1-2: Default PUSCH time domain resource allocation A for normal
|
||||
* CP
|
||||
*
|
||||
* @param scs_cfg Sub-carrier spacing configuration for PUSCH (μ)
|
||||
* @param m Time domain resource assignment field value m of the DCI
|
||||
* @param[out] grant PUSCH grant
|
||||
* @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int
|
||||
srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant);
|
||||
|
||||
/**
|
||||
* @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure
|
||||
*
|
||||
* @param cfg PUSCH NR configuration by upper layers
|
||||
* @param[out] grant Provides grant pointer to fill
|
||||
* @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg,
|
||||
srslte_sch_grant_nr_t* grant);
|
||||
|
||||
/**
|
||||
* @brief Calculates the minimum number of PRB required for transmitting NR-PUCCH Format 2, 3 or 4
|
||||
* @remark Based in TS 38.213 9.2.5.1 UE procedure for multiplexing HARQ-ACK or CSI and SR in a PUCCH
|
||||
|
@ -25,4 +74,19 @@
|
|||
SRSLTE_API int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* resource,
|
||||
const srslte_uci_cfg_nr_t* uci_cfg);
|
||||
|
||||
/**
|
||||
* @brief Calculates the PUSCH frequency resource allocation and stores it in the provided PUSCH NR grant.
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 section 5.1.2.2
|
||||
* @param carrier Carrier information
|
||||
* @param cfg PDSCH NR configuration by upper layers
|
||||
* @param dci_dl Unpacked DCI used to schedule the PDSCH grant
|
||||
* @param[out] grant Provides grant pointer to fill
|
||||
* @return SRSLTE_SUCCESS if the provided data is valid, SRSLTE_ERROR code otherwise
|
||||
*/
|
||||
SRSLTE_API int srslte_ra_ul_nr_freq(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_dci_ul_nr_t* dci_ul,
|
||||
srslte_sch_grant_nr_t* grant);
|
||||
|
||||
#endif // SRSLTE_RA_UL_NR_H
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file ue_dl_nr.h
|
||||
*
|
||||
* Description: NR UE uplink physical layer procedures for data
|
||||
*
|
||||
* This module is a frontend to all the uplink data channel processing modules.
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SRSLTE_UE_UL_DATA_H
|
||||
#define SRSLTE_UE_UL_DATA_H
|
||||
|
||||
#include "srslte/phy/common/phy_common_nr.h"
|
||||
#include "srslte/phy/phch/phch_cfg_nr.h"
|
||||
|
||||
#endif // SRSLTE_UE_UL_DATA_H
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* @file ue_dl_nr.h
|
||||
*
|
||||
* Description: NR UE uplink physical layer procedures for data
|
||||
*
|
||||
* This module is a frontend to all the uplink data channel processing modules.
|
||||
*
|
||||
* Reference:
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SRSLTE_UE_UL_DATA_H
|
||||
#define SRSLTE_UE_UL_DATA_H
|
||||
|
||||
#include "srslte/phy/common/phy_common_nr.h"
|
||||
#include "srslte/phy/phch/phch_cfg_nr.h"
|
||||
|
||||
/**
|
||||
* @brief Calculates the PUSCH time resource default A and stores it in the provided PUSCH NR grant.
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 Table 6.1.2.1.1-2: Default PUSCH time domain resource allocation A for normal
|
||||
* CP
|
||||
*
|
||||
* @param m Time domain resource assignment field value m of the DCI
|
||||
* @param[out] grant PUSCH grant
|
||||
* @return Returns SRSLTE_SUCCESS if the provided allocation is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant);
|
||||
|
||||
/**
|
||||
* @brief Calculates the number of PUSCH-DMRS CDM groups without data for DCI format 0_0
|
||||
*
|
||||
* @remark Defined by TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure
|
||||
*
|
||||
* @param cfg PUSCH NR configuration by upper layers
|
||||
* @param[out] grant Provides grant pointer to fill
|
||||
* @return Returns SRSLTE_SUCCESS if the provided data is valid, otherwise it returns SRSLTE_ERROR code
|
||||
*/
|
||||
SRSLTE_API int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg,
|
||||
srslte_sch_grant_nr_t* grant);
|
||||
|
||||
|
||||
#endif // SRSLTE_UE_UL_DATA_H
|
|
@ -14,6 +14,15 @@
|
|||
#include "srslte/phy/utils/bit.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
static int dci_nr_format_0_0_freq_resource_size(const srslte_carrier_nr_t* carrier)
|
||||
{
|
||||
if (carrier == NULL) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return (int)ceil(log2(carrier->nof_prb * (carrier->nof_prb + 1) / 2.0));
|
||||
}
|
||||
|
||||
static int dci_nr_format_1_0_freq_resource_size(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset0,
|
||||
srslte_rnti_type_t rnti_type)
|
||||
|
@ -64,6 +73,222 @@ int srslte_dci_nr_pack(const srslte_carrier_nr_t* carrier,
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_dci_nr_format_0_0_pack(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset0,
|
||||
const srslte_dci_ul_nr_t* dci,
|
||||
srslte_dci_msg_nr_t* msg)
|
||||
{
|
||||
uint32_t trim = 0; // hard-coded bit trimming
|
||||
bool enable_hopping = false; // hard-coded PUSCH hopping
|
||||
uint32_t padding = 0; // Hard-coded padding
|
||||
bool supplementary_uplink = false; // Hard-coded supplementary Uplink
|
||||
uint8_t* y = msg->payload;
|
||||
srslte_rnti_type_t rnti_type = msg->rnti_type;
|
||||
|
||||
if (carrier == NULL) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Check RNTI type
|
||||
if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Identifier for DCI formats – 1 bits
|
||||
*y = 0;
|
||||
y++;
|
||||
|
||||
// For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset
|
||||
int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0;
|
||||
srslte_bit_unpack(dci->frequency_offset, &y, N_UL_hop);
|
||||
|
||||
// Frequency domain resource assignment
|
||||
int N = dci_nr_format_0_0_freq_resource_size(carrier);
|
||||
if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
srslte_bit_unpack(dci->freq_domain_assigment, &y, N - N_UL_hop - trim);
|
||||
|
||||
// Time domain resource assignment – 4 bits
|
||||
srslte_bit_unpack(dci->time_domain_assigment, &y, 4);
|
||||
|
||||
// Frequency hopping flag – 1 bit
|
||||
srslte_bit_unpack(dci->freq_hopping_flag, &y, 1);
|
||||
|
||||
// Modulation and coding scheme – 5 bits
|
||||
srslte_bit_unpack(dci->mcs, &y, 5);
|
||||
|
||||
// New data indicator – 1 bit
|
||||
srslte_bit_unpack(dci->ndi, &y, 1);
|
||||
|
||||
// Redundancy version – 2 bits
|
||||
srslte_bit_unpack(dci->rv, &y, 2);
|
||||
|
||||
// HARQ process number – 4 bits
|
||||
srslte_bit_unpack(dci->pid, &y, 4);
|
||||
|
||||
// TPC command for scheduled PUSCH – 2 bits
|
||||
srslte_bit_unpack(dci->tpc, &y, 2);
|
||||
|
||||
// Padding goes here
|
||||
for (uint32_t i = 0; i < padding; i++) {
|
||||
*(y++) = 0;
|
||||
}
|
||||
|
||||
// UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0
|
||||
if (supplementary_uplink) {
|
||||
*(y++) = 0;
|
||||
}
|
||||
|
||||
msg->nof_bits = srslte_dci_nr_format_0_0_sizeof(carrier, coreset0, rnti_type);
|
||||
if (msg->nof_bits != y - msg->payload) {
|
||||
ERROR("Unpacked bits readed (%d) do NOT match payload size (%d)\n", msg->nof_bits, (int)(y - msg->payload));
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_dci_nr_format_0_0_unpack(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
srslte_dci_msg_nr_t* msg,
|
||||
srslte_dci_ul_nr_t* dci)
|
||||
{
|
||||
uint32_t trim = 0; // hard-coded bit trimming
|
||||
bool enable_hopping = false; // hard-coded PUSCH hopping
|
||||
uint32_t padding = 0; // Hard-coded padding
|
||||
bool supplementary_uplink = false; // Hard-coded supplementary Uplink
|
||||
uint8_t* y = msg->payload;
|
||||
srslte_rnti_type_t rnti_type = msg->rnti_type;
|
||||
|
||||
if (carrier == NULL) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Check RNTI type
|
||||
if (rnti_type != srslte_rnti_type_c && rnti_type != srslte_rnti_type_cs && rnti_type != srslte_rnti_type_mcs_c) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (msg->nof_bits != srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type)) {
|
||||
ERROR("Invalid number of bits %d, expected %d\n",
|
||||
msg->nof_bits,
|
||||
srslte_dci_nr_format_0_0_sizeof(carrier, coreset, rnti_type));
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Identifier for DCI formats – 1 bits
|
||||
if (*(y++) != 0) {
|
||||
ERROR("Wrond DCI format\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset
|
||||
int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0;
|
||||
dci->frequency_offset = srslte_bit_pack(&y, N_UL_hop);
|
||||
|
||||
// Frequency domain resource assignment
|
||||
int N = dci_nr_format_0_0_freq_resource_size(carrier);
|
||||
if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
dci->freq_domain_assigment = srslte_bit_pack(&y, N - N_UL_hop - trim);
|
||||
|
||||
// Time domain resource assignment – 4 bits
|
||||
dci->time_domain_assigment = srslte_bit_pack(&y, 4);
|
||||
|
||||
// Frequency hopping flag – 1 bit
|
||||
dci->freq_hopping_flag = srslte_bit_pack(&y, 1);
|
||||
|
||||
// Modulation and coding scheme – 5 bits
|
||||
dci->mcs = srslte_bit_pack(&y, 5);
|
||||
|
||||
// New data indicator – 1 bit
|
||||
dci->ndi = srslte_bit_pack(&y, 1);
|
||||
|
||||
// Redundancy version – 2 bits
|
||||
dci->rv = srslte_bit_pack(&y, 2);
|
||||
|
||||
// HARQ process number – 4 bits
|
||||
dci->pid = srslte_bit_pack(&y, 4);
|
||||
|
||||
// TPC command for scheduled PUSCH – 2 bits
|
||||
dci->tpc = srslte_bit_pack(&y, 2);
|
||||
|
||||
// Padding goes here
|
||||
for (uint32_t i = 0; i < padding; i++) {
|
||||
y++;
|
||||
}
|
||||
|
||||
// UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0
|
||||
if (supplementary_uplink) {
|
||||
y++;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_dci_nr_format_0_0_sizeof(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
srslte_rnti_type_t rnti_type)
|
||||
{
|
||||
uint32_t trim = 0; // hard-coded bit trimming
|
||||
bool enable_hopping = false; // hard-coded PUSCH hopping
|
||||
uint32_t padding = 0; // Hard-coded padding
|
||||
bool supplementary_uplink = false; // Hard-coded supplementary Uplink
|
||||
int count = 0;
|
||||
|
||||
// Identifier for DCI formats – 1 bits
|
||||
count++;
|
||||
|
||||
// For PUSCH hopping with resource allocation type 1 N UL_hop MSB bits are used to indicate the frequency offset
|
||||
int N_UL_hop = (enable_hopping) ? ((carrier->nof_prb < 50) ? 1 : 2) : 0;
|
||||
count += N_UL_hop;
|
||||
|
||||
// Frequency domain resource assignment
|
||||
int N = dci_nr_format_0_0_freq_resource_size(carrier);
|
||||
if (N < SRSLTE_SUCCESS || N - N_UL_hop <= 0) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
count += N - N_UL_hop - trim;
|
||||
|
||||
// Time domain resource assignment – 4 bits
|
||||
count += 4;
|
||||
|
||||
// Frequency hopping flag – 1 bit
|
||||
count += 1;
|
||||
|
||||
// Modulation and coding scheme – 5 bits
|
||||
count += 5;
|
||||
|
||||
// New data indicator – 1 bit
|
||||
count += 1;
|
||||
|
||||
// Redundancy version – 2 bits
|
||||
count += 2;
|
||||
|
||||
// HARQ process number – 4 bits
|
||||
count += 4;
|
||||
|
||||
// TPC command for scheduled PUSCH – 2 bits
|
||||
count += 2;
|
||||
|
||||
// Padding goes here
|
||||
count += padding;
|
||||
|
||||
// UL/SUL indicator – 1 bit for UEs configured with supplementaryUplink in ServingCellConfig, othwerwise 0
|
||||
if (supplementary_uplink) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int dci_nr_format_0_0_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len)
|
||||
{
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
int srslte_dci_nr_format_1_0_pack(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_coreset_t* coreset,
|
||||
const srslte_dci_dl_nr_t* dci,
|
||||
|
@ -198,11 +423,10 @@ int srslte_dci_nr_format_1_0_unpack(const srslte_carrier_nr_t* carrier,
|
|||
// Identifier for DCI formats – 1 bits
|
||||
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
|
||||
// The value of this bit field is always set to 1, indicating a DL DCI format
|
||||
if (*y != 1) {
|
||||
if (*(y++) != 1) {
|
||||
ERROR("Wrond DCI format\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
if (rnti_type == srslte_rnti_type_p) {
|
||||
|
@ -298,7 +522,7 @@ int srslte_dci_nr_format_1_0_sizeof(const srslte_carrier_nr_t* carrier,
|
|||
const srslte_coreset_t* coreset,
|
||||
srslte_rnti_type_t rnti_type)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
int count = 0;
|
||||
|
||||
// Identifier for DCI formats – 1 bits
|
||||
if (rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_tc) {
|
||||
|
@ -467,7 +691,19 @@ static int dci_nr_format_1_0_to_str(const srslte_dci_dl_nr_t* dci, char* str, ui
|
|||
return len;
|
||||
}
|
||||
|
||||
int srslte_dci_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len)
|
||||
int srslte_dci_ul_nr_to_str(const srslte_dci_ul_nr_t* dci, char* str, uint32_t str_len)
|
||||
{
|
||||
// Pack DCI
|
||||
switch (dci->format) {
|
||||
case srslte_dci_format_nr_0_0:
|
||||
return dci_nr_format_0_0_to_str(dci, str, str_len);
|
||||
default:; // Do nothing
|
||||
}
|
||||
|
||||
return srslte_print_check(str, str_len, 0, "unknown");
|
||||
}
|
||||
|
||||
int srslte_dci_dl_nr_to_str(const srslte_dci_dl_nr_t* dci, char* str, uint32_t str_len)
|
||||
{
|
||||
// Pack DCI
|
||||
switch (dci->format) {
|
||||
|
|
|
@ -10,21 +10,9 @@
|
|||
*
|
||||
*/
|
||||
#include "srslte/phy/phch/ra_dl_nr.h"
|
||||
#include "ra_helper.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
static void compute_s_and_l(uint32_t N, uint32_t v, uint32_t* S, uint32_t* L)
|
||||
{
|
||||
uint32_t low = v % N;
|
||||
uint32_t high = v / N;
|
||||
if (high + 1 + low <= N) {
|
||||
*S = low;
|
||||
*L = high + 1;
|
||||
} else {
|
||||
*S = N - 1 - low;
|
||||
*L = N - high + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate S and L combination for TypeA time domain resource allocation
|
||||
static bool check_time_ra_typeA(uint32_t* S, uint32_t* L)
|
||||
{
|
||||
|
@ -108,7 +96,6 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_
|
|||
|
||||
// Select start symbol (S) and length (L)
|
||||
switch (dmrs_typeA_pos) {
|
||||
|
||||
case srslte_dmrs_sch_typeA_pos_2:
|
||||
grant->S = S_pos2[m];
|
||||
grant->L = L_pos2[m];
|
||||
|
@ -125,23 +112,22 @@ int srslte_ra_dl_nr_time_default_A(uint32_t m, srslte_dmrs_sch_typeA_pos_t dmrs_
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
void srslte_ra_dl_nr_time_hl(const srslte_pdsch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant)
|
||||
static void ra_dl_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
// Compute S and L from SLIV from higher layers
|
||||
compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L);
|
||||
ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L);
|
||||
|
||||
grant->k0 = hl_ra_cfg->k0;
|
||||
grant->k0 = hl_ra_cfg->k;
|
||||
grant->mapping = hl_ra_cfg->mapping_type;
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_time(const srslte_pdsch_cfg_nr_t* cfg,
|
||||
int srslte_ra_dl_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_rnti_type_t rnti_type,
|
||||
const srslte_search_space_type_t ss_type,
|
||||
const uint32_t coreset_id,
|
||||
const uint8_t m,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
if (cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
@ -161,8 +147,8 @@ int srslte_ra_dl_nr_time(const srslte_pdsch_cfg_nr_t* cfg,
|
|||
} else if ((rnti_type == srslte_rnti_type_ra || rnti_type == srslte_rnti_type_tc) &&
|
||||
ss_type == srslte_search_space_type_common_1) {
|
||||
// Row 3
|
||||
if (cfg->nof_common_pdsch_time_ra > 0) {
|
||||
srslte_ra_dl_nr_time_hl(&cfg->common_pdsch_time_ra[m], grant);
|
||||
if (cfg->nof_common_time_ra > 0) {
|
||||
ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
} else {
|
||||
// Note: Only Default A is supported, which corresponds SS/PBCH block and coreset mux pattern 1
|
||||
srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant);
|
||||
|
@ -174,8 +160,8 @@ int srslte_ra_dl_nr_time(const srslte_pdsch_cfg_nr_t* cfg,
|
|||
rnti_type == srslte_rnti_type_cs) &&
|
||||
SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id == 0) {
|
||||
// Row 5
|
||||
if (cfg->nof_common_pdsch_time_ra > 0) {
|
||||
srslte_ra_dl_nr_time_hl(&cfg->common_pdsch_time_ra[m], grant);
|
||||
if (cfg->nof_common_time_ra > 0) {
|
||||
ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
} else {
|
||||
srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant);
|
||||
}
|
||||
|
@ -183,10 +169,10 @@ int srslte_ra_dl_nr_time(const srslte_pdsch_cfg_nr_t* cfg,
|
|||
rnti_type == srslte_rnti_type_cs) &&
|
||||
((SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id != 0) || ss_type == srslte_search_space_type_ue)) {
|
||||
// Row 6
|
||||
if (cfg->nof_pdsch_time_ra > 0) {
|
||||
srslte_ra_dl_nr_time_hl(&cfg->pdsch_time_ra[m], grant);
|
||||
} else if (cfg->nof_common_pdsch_time_ra > 0) {
|
||||
srslte_ra_dl_nr_time_hl(&cfg->common_pdsch_time_ra[m], grant);
|
||||
if (cfg->nof_dedicated_time_ra > 0) {
|
||||
ra_dl_nr_time_hl(&cfg->dedicated_time_ra[m], grant);
|
||||
} else if (cfg->nof_common_time_ra > 0) {
|
||||
ra_dl_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
} else {
|
||||
srslte_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant);
|
||||
}
|
||||
|
@ -240,7 +226,7 @@ uint32_t srslte_ra_dl_nr_type0_P(uint32_t bwp_size, bool config_is_1)
|
|||
}
|
||||
|
||||
static int ra_freq_type0(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_pdsch_cfg_nr_t* cfg,
|
||||
const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
@ -268,44 +254,11 @@ static int ra_freq_type0(const srslte_carrier_nr_t* carrier,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ra_freq_type1(const srslte_carrier_nr_t* carrier, const srslte_dci_dl_nr_t* dci_dl, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
uint32_t riv = dci_dl->freq_domain_assigment;
|
||||
uint32_t N_bwp_size = carrier->nof_prb;
|
||||
|
||||
uint32_t start = 0;
|
||||
uint32_t len = 0;
|
||||
compute_s_and_l(N_bwp_size, riv, &start, &len);
|
||||
|
||||
if (start + len > N_bwp_size) {
|
||||
ERROR("RIV 0x%x for BWP size %d resulted in freq=%d:%d\n", riv, N_bwp_size, start, len);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < start; i++) {
|
||||
grant->prb_idx[i] = false;
|
||||
}
|
||||
|
||||
for (uint32_t i = start; i < start + len; i++) {
|
||||
grant->prb_idx[i] = true;
|
||||
}
|
||||
|
||||
for (uint32_t i = start + len; i < SRSLTE_MAX_PRB_NR; i++) {
|
||||
grant->prb_idx[i] = false;
|
||||
}
|
||||
grant->nof_prb = len;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_pdsch_cfg_nr_t* cfg,
|
||||
const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
|
||||
if (cfg == NULL || grant == NULL || dci_dl == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
@ -313,7 +266,7 @@ int srslte_ra_dl_nr_freq(const srslte_carrier_nr_t* carrier,
|
|||
// RA scheme
|
||||
if (dci_dl->format == srslte_dci_format_nr_1_0) {
|
||||
// when the scheduling grant is received with DCI format 1_0 , then downlink resource allocation type 1 is used.
|
||||
return ra_freq_type1(carrier, dci_dl, grant);
|
||||
return ra_helper_freq_type1(carrier->nof_prb, dci_dl->freq_domain_assigment, grant);
|
||||
}
|
||||
|
||||
ra_freq_type0(carrier, cfg, dci_dl, grant);
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRSLTE_RA_HELPER_H
|
||||
#define SRSLTE_RA_HELPER_H
|
||||
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static inline void ra_helper_compute_s_and_l(uint32_t N, uint32_t v, uint32_t* S, uint32_t* L)
|
||||
{
|
||||
uint32_t low = v % N;
|
||||
uint32_t high = v / N;
|
||||
if (high + 1 + low <= N) {
|
||||
*S = low;
|
||||
*L = high + 1;
|
||||
} else {
|
||||
*S = N - 1 - low;
|
||||
*L = N - high + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int ra_helper_freq_type1(uint32_t N_bwp_size, uint32_t riv, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
uint32_t start = 0;
|
||||
uint32_t len = 0;
|
||||
ra_helper_compute_s_and_l(N_bwp_size, riv, &start, &len);
|
||||
|
||||
if (start + len > N_bwp_size) {
|
||||
ERROR("RIV 0x%x for BWP size %d resulted in freq=%d:%d\n", riv, N_bwp_size, start, len);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < start; i++) {
|
||||
grant->prb_idx[i] = false;
|
||||
}
|
||||
|
||||
for (uint32_t i = start; i < start + len; i++) {
|
||||
grant->prb_idx[i] = true;
|
||||
}
|
||||
|
||||
for (uint32_t i = start + len; i < SRSLTE_MAX_PRB_NR; i++) {
|
||||
grant->prb_idx[i] = false;
|
||||
}
|
||||
grant->nof_prb = len;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
#endif // SRSLTE_RA_HELPER_H
|
|
@ -13,6 +13,7 @@
|
|||
#include "srslte/phy/phch/ra_nr.h"
|
||||
#include "srslte/phy/phch/pdsch_nr.h"
|
||||
#include "srslte/phy/phch/ra_dl_nr.h"
|
||||
#include "srslte/phy/phch/ra_ul_nr.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -215,7 +216,6 @@ static ra_nr_table_t ra_nr_select_table(srslte_mcs_table_t mcs_table,
|
|||
srslte_search_space_type_t search_space_type,
|
||||
srslte_rnti_type_t rnti_type)
|
||||
{
|
||||
|
||||
// Check if it is a PUSCH transmission
|
||||
if (dci_format == srslte_dci_format_nr_0_0 || dci_format == srslte_dci_format_nr_0_1 ||
|
||||
dci_format == srslte_dci_format_nr_rar || dci_format == srslte_dci_format_nr_cg) {
|
||||
|
@ -455,16 +455,15 @@ int srslte_ra_nr_fill_tb(const srslte_sch_cfg_nr_t* pdsch_cfg,
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int ra_dl_dmrs(const srslte_pdsch_cfg_nr_t* pdsch_hl_cfg,
|
||||
static int ra_dl_dmrs(const srslte_sch_hl_cfg_nr_t* pdsch_hl_cfg,
|
||||
srslte_sch_grant_nr_t* pdsch_grant,
|
||||
srslte_dmrs_sch_cfg_t* dmrs_cfg)
|
||||
{
|
||||
const bool dedicated_dmrs_present = (pdsch_grant->mapping == srslte_sch_mapping_type_A)
|
||||
? pdsch_hl_cfg->dmrs_typeA_present
|
||||
: pdsch_hl_cfg->dmrs_typeB_present;
|
||||
? pdsch_hl_cfg->dmrs_typeA.present
|
||||
: pdsch_hl_cfg->dmrs_typeB.present;
|
||||
|
||||
if (pdsch_grant->dci_format == srslte_dci_format_nr_1_0 || !dedicated_dmrs_present) {
|
||||
|
||||
if (pdsch_grant->mapping == srslte_sch_mapping_type_A) {
|
||||
// Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig
|
||||
dmrs_cfg->additional_pos = srslte_dmrs_sch_add_pos_2;
|
||||
|
@ -491,7 +490,7 @@ static int ra_dl_dmrs(const srslte_pdsch_cfg_nr_t* pdsch_hl_cfg,
|
|||
}
|
||||
|
||||
int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_pdsch_cfg_nr_t* pdsch_hl_cfg,
|
||||
const srslte_sch_hl_cfg_nr_t* pdsch_hl_cfg,
|
||||
const srslte_dci_dl_nr_t* dci_dl,
|
||||
srslte_sch_cfg_nr_t* pdsch_cfg,
|
||||
srslte_sch_grant_nr_t* pdsch_grant)
|
||||
|
@ -535,3 +534,49 @@ int srslte_ra_dl_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
|
|||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ra_ul_dci_to_grant_nr(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_sch_hl_cfg_nr_t* pusch_hl_cfg,
|
||||
const srslte_dci_ul_nr_t* dci_ul,
|
||||
srslte_sch_cfg_nr_t* pusch_cfg,
|
||||
srslte_sch_grant_nr_t* pusch_grant)
|
||||
{
|
||||
// 5.2.1.1 Resource allocation in time domain
|
||||
if (srslte_ra_dl_nr_time(pusch_hl_cfg,
|
||||
dci_ul->rnti_type,
|
||||
dci_ul->search_space,
|
||||
dci_ul->coreset_id,
|
||||
dci_ul->time_domain_assigment,
|
||||
pusch_grant) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error computing time domain resource allocation\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// 5.1.2.2 Resource allocation in frequency domain
|
||||
if (srslte_ra_ul_nr_freq(carrier, pusch_hl_cfg, dci_ul, pusch_grant) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error computing frequency domain resource allocation\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// 5.1.2.3 Physical resource block (PRB) bundling
|
||||
// ...
|
||||
|
||||
pusch_grant->nof_layers = 1;
|
||||
pusch_grant->dci_format = dci_ul->format;
|
||||
pusch_grant->rnti = dci_ul->rnti;
|
||||
pusch_grant->rnti_type = dci_ul->rnti_type;
|
||||
|
||||
// 5.1.6.2 DM-RS reception procedure
|
||||
if (ra_dl_dmrs(pusch_hl_cfg, pusch_grant, &pusch_cfg->dmrs) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error selecting DMRS configuration");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// 5.1.3 Modulation order, target code rate, redundancy version and transport block size determination
|
||||
if (srslte_ra_nr_fill_tb(pusch_cfg, pusch_grant, dci_ul->mcs, &pusch_grant->tb[0]) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error filing tb\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -11,10 +11,211 @@
|
|||
*/
|
||||
|
||||
#include "srslte/phy/phch/ra_ul_nr.h"
|
||||
#include "ra_helper.h"
|
||||
#include "srslte/phy/ch_estimation/dmrs_pucch.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
typedef struct {
|
||||
srslte_sch_mapping_type_t mapping;
|
||||
uint32_t K2;
|
||||
uint32_t S;
|
||||
uint32_t L;
|
||||
} ue_ra_time_resource_t;
|
||||
|
||||
static const ue_ra_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mapping_type_A, 0, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 0, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 0, 0, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 2, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 8},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 6},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 10},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 8, 6},
|
||||
{srslte_sch_mapping_type_A, 3, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 3, 0, 10}};
|
||||
|
||||
int srslte_ra_ul_nr_pdsch_time_resource_default_A(uint32_t scs_cfg, uint32_t m, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
uint32_t j[4] = {1, 1, 2, 3};
|
||||
|
||||
if (grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (scs_cfg > 4) {
|
||||
ERROR("Invalid numerology (%d)", scs_cfg);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (m >= 16) {
|
||||
ERROR("m (%d) is out-of-range", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Select mapping
|
||||
grant->mapping = ue_ul_default_A_lut[m].mapping;
|
||||
grant->k2 = ue_ul_default_A_lut[m].K2 + j[scs_cfg];
|
||||
grant->S = ue_ul_default_A_lut[m].S;
|
||||
grant->L = ue_ul_default_A_lut[m].L;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
static void ra_ul_nr_time_hl(const srslte_sch_time_ra_t* hl_ra_cfg, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
// Compute S and L from SLIV from higher layers
|
||||
ra_helper_compute_s_and_l(SRSLTE_NSYMB_PER_SLOT_NR, hl_ra_cfg->sliv, &grant->S, &grant->L);
|
||||
|
||||
grant->k2 = hl_ra_cfg->k;
|
||||
grant->mapping = hl_ra_cfg->mapping_type;
|
||||
}
|
||||
|
||||
// Validate S and L combination for TypeA time domain resource allocation
|
||||
static bool check_time_ra_typeA(uint32_t* S, uint32_t* L)
|
||||
{
|
||||
// Check values using Table 5.1.2.1-1
|
||||
if (*S != 0) {
|
||||
ERROR("S (%d) is out-of-range {0}", *S);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*L < 4 || *L > 14) {
|
||||
ERROR("L (%d) is out-of-range {4,...,14}", *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t sum = *S + *L;
|
||||
if (sum < 4) {
|
||||
ERROR("The sum of S (%d) and L (%d) is lower than 4", *S, *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sum > 14) {
|
||||
ERROR("The sum of S (%d) and L (%d) is greater than 14", *S, *L);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_time_ra_typeB(uint32_t* S, uint32_t* L)
|
||||
{
|
||||
ERROR("Not implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool srslte_ra_ul_nr_time_validate(srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (grant->mapping == srslte_sch_mapping_type_A) {
|
||||
return check_time_ra_typeA(&grant->S, &grant->L);
|
||||
}
|
||||
|
||||
return check_time_ra_typeB(&grant->S, &grant->L);
|
||||
}
|
||||
|
||||
int srslte_ra_ul_nr_time(const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_rnti_type_t rnti_type,
|
||||
const srslte_search_space_type_t ss_type,
|
||||
const uint32_t coreset_id,
|
||||
const uint8_t m,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (m >= SRSLTE_MAX_NOF_DL_ALLOCATION) {
|
||||
ERROR("m (%d) is out-of-range", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Determine which PUSCH Time domain RA configuration to apply (TS 38.214 Table 6.1.2.1.1-1:)
|
||||
if (ss_type == srslte_search_space_rar) {
|
||||
// Row 1
|
||||
if (cfg->nof_common_time_ra == 0) {
|
||||
srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant);
|
||||
} else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION) {
|
||||
ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
}
|
||||
} else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c ||
|
||||
rnti_type == srslte_rnti_type_tc || rnti_type == srslte_rnti_type_cs) &&
|
||||
SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id == 0) {
|
||||
// Row 2
|
||||
if (cfg->nof_common_time_ra == 0) {
|
||||
srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant);
|
||||
} else if (m < SRSLTE_MAX_NOF_DL_ALLOCATION) {
|
||||
ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
}
|
||||
} else if ((rnti_type == srslte_rnti_type_c || rnti_type == srslte_rnti_type_mcs_c ||
|
||||
rnti_type == srslte_rnti_type_tc || rnti_type == srslte_rnti_type_cs ||
|
||||
rnti_type == srslte_rnti_type_sp_csi) &&
|
||||
((SRSLTE_SEARCH_SPACE_IS_COMMON(ss_type) && coreset_id != 0) || ss_type == srslte_search_space_type_ue)) {
|
||||
// Row 3
|
||||
if (cfg->nof_dedicated_time_ra > 0) {
|
||||
ra_ul_nr_time_hl(&cfg->dedicated_time_ra[m], grant);
|
||||
} else if (cfg->nof_common_time_ra > 0) {
|
||||
ra_ul_nr_time_hl(&cfg->common_time_ra[m], grant);
|
||||
} else {
|
||||
srslte_ra_ul_nr_pdsch_time_resource_default_A(cfg->scs_cfg, m, grant);
|
||||
}
|
||||
} else {
|
||||
ERROR("Unhandled case");
|
||||
}
|
||||
|
||||
// Table 6.1.2.1.1-5 defines the additional subcarrier spacing specific slot delay value for the first transmission of
|
||||
// PUSCH scheduled by the RAR. When the UE transmits a PUSCH scheduled by RAR, the Δ value specific to the PUSCH
|
||||
// subcarrier spacing μ PUSCH is applied in addition to the K 2 value.
|
||||
if (ss_type == srslte_search_space_rar) {
|
||||
uint32_t delta[4] = {2, 3, 4, 6};
|
||||
if (cfg->scs_cfg <= 4) {
|
||||
ERROR("Invalid numerology");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
grant->k2 += delta[cfg->scs_cfg];
|
||||
}
|
||||
|
||||
// Validate S and L parameters
|
||||
if (!srslte_ra_ul_nr_time_validate(grant)) {
|
||||
ERROR("Invalid Time RA S=%d; L=%d; m=%d", grant->S, grant->L, m);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
/* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure:
|
||||
* For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE
|
||||
* shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of
|
||||
* PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume
|
||||
* that the number of DM-RS CDM groups without data is 3 which corresponds to CDM group {0,1,2} for the case of PUSCH
|
||||
* scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH
|
||||
* allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups
|
||||
* without data is 2 which corresponds to CDM group {0,1} for all other cases.
|
||||
*/
|
||||
if (grant->L <= 2 && !cfg->enable_transform_precoder) {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 1;
|
||||
// } else if (grant->L > 2 && cfg->dmrs_cg.type == srslte_dmrs_sch_type_2){
|
||||
// grant->nof_dmrs_cdm_groups_without_data = 3;
|
||||
} else {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 2;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
#define RA_UL_PUCCH_CODE_RATE_N 8
|
||||
#define RA_UL_PUCCH_CODE_RATE_RESERVED NAN
|
||||
|
||||
|
@ -25,7 +226,7 @@ static const double ra_ul_pucch_code_rate_table[RA_UL_PUCCH_CODE_RATE_N] =
|
|||
static double ra_ul_nr_pucch_code_rate_r(const srslte_pucch_nr_resource_t* resource)
|
||||
{
|
||||
if (resource->max_code_rate >= RA_UL_PUCCH_CODE_RATE_RESERVED) {
|
||||
ERROR("Invalid code rate\n");
|
||||
ERROR("Invalid code rate");
|
||||
return RA_UL_PUCCH_CODE_RATE_RESERVED;
|
||||
}
|
||||
|
||||
|
@ -42,7 +243,7 @@ static double ra_ul_nr_pucch_code_rate_r(const srslte_pucch_nr_resource_t* resou
|
|||
// case SRSLTE_PUCCH_NR_FORMAT_4:
|
||||
// return SRSLTE_PUCCH_NR_FORMAT4_NPRB;
|
||||
// default:
|
||||
// ERROR("Invalid case\n");
|
||||
// ERROR("Invalid case");
|
||||
// break;
|
||||
// }
|
||||
// return SRSLTE_ERROR;
|
||||
|
@ -59,7 +260,7 @@ static int ra_ul_nr_pucch_nre(const srslte_pucch_nr_resource_t* resource)
|
|||
case SRSLTE_PUCCH_NR_FORMAT_4:
|
||||
return SRSLTE_NRE / resource->occ_lenth;
|
||||
default:
|
||||
ERROR("Invalid case\n");
|
||||
ERROR("Invalid case");
|
||||
break;
|
||||
}
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -84,7 +285,7 @@ static int ra_ul_nr_pucch_nsymb(const srslte_pucch_nr_resource_t* resource)
|
|||
return (int)resource->nof_symbols - nsymb_dmrs;
|
||||
}
|
||||
default:
|
||||
ERROR("Invalid case\n");
|
||||
ERROR("Invalid case");
|
||||
break;
|
||||
}
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -100,7 +301,7 @@ static int ra_ul_nr_pucch_qm(const srslte_pucch_nr_resource_t* resource)
|
|||
case SRSLTE_PUCCH_NR_FORMAT_4:
|
||||
return resource->enable_pi_bpsk ? 1 : 2;
|
||||
default:
|
||||
ERROR("Invalid case\n");
|
||||
ERROR("Invalid case");
|
||||
break;
|
||||
}
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -116,28 +317,28 @@ int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* r
|
|||
// Get maximum allowed code rate
|
||||
double r = ra_ul_nr_pucch_code_rate_r(resource);
|
||||
if (!isnormal(r)) {
|
||||
ERROR("Invalid coderate %f\n", r);
|
||||
ERROR("Invalid coderate %f", r);
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Get number of RE/PRB
|
||||
int nre = ra_ul_nr_pucch_nre(resource);
|
||||
if (nre < SRSLTE_SUCCESS) {
|
||||
ERROR("Getting nre\n");
|
||||
ERROR("Getting nre");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Get number of symbols
|
||||
int nsymb = ra_ul_nr_pucch_nsymb(resource);
|
||||
if (nsymb < SRSLTE_SUCCESS) {
|
||||
ERROR("Getting nsymb\n");
|
||||
ERROR("Getting nsymb");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// Get modulation order
|
||||
int qm = ra_ul_nr_pucch_qm(resource);
|
||||
if (qm < SRSLTE_SUCCESS) {
|
||||
ERROR("Getting qm\n");
|
||||
ERROR("Getting qm");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
|
@ -156,3 +357,22 @@ int srslte_ra_ul_nr_pucch_format_2_3_min_prb(const srslte_pucch_nr_resource_t* r
|
|||
// Return the minimum
|
||||
return (int)ceil(O_total / nof_bits_rb);
|
||||
}
|
||||
|
||||
int srslte_ra_ul_nr_freq(const srslte_carrier_nr_t* carrier,
|
||||
const srslte_sch_hl_cfg_nr_t* cfg,
|
||||
const srslte_dci_ul_nr_t* dci_ul,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (cfg == NULL || grant == NULL || dci_ul == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// RA scheme
|
||||
if (dci_ul->format == srslte_dci_format_nr_0_0) {
|
||||
// when the scheduling grant is received with DCI format 1_0 , then downlink resource allocation type 1 is used.
|
||||
return ra_helper_freq_type1(carrier->nof_prb, dci_ul->freq_domain_assigment, grant);
|
||||
}
|
||||
|
||||
ERROR("Only DCI Format 0_0 is supported");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "srslte/phy/phch/pusch_nr.h"
|
||||
#include "srslte/phy/phch/ra_nr.h"
|
||||
#include "srslte/phy/ue/ue_ul_nr_data.h"
|
||||
#include "srslte/phy/phch/ra_ul_nr.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include "srslte/phy/utils/random.h"
|
||||
#include "srslte/phy/utils/vector.h"
|
||||
|
@ -152,13 +152,13 @@ int main(int argc, char** argv)
|
|||
}
|
||||
|
||||
// Use grant default A time resources with m=0
|
||||
if (srslte_ue_ul_nr_pdsch_time_resource_default_A(0, &pusch_grant) < SRSLTE_SUCCESS) {
|
||||
if (srslte_ra_ul_nr_pdsch_time_resource_default_A(carrier.numerology, 0, &pusch_grant) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error loading default grant\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
// Load number of DMRS CDM groups without data
|
||||
if (srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) {
|
||||
if (srslte_ra_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(&pusch_cfg, &pusch_grant) < SRSLTE_SUCCESS) {
|
||||
ERROR("Error loading number of DMRS CDM groups without data\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
@ -188,7 +188,6 @@ int main(int argc, char** argv)
|
|||
|
||||
for (n_prb = n_prb_start; n_prb < n_prb_end; n_prb++) {
|
||||
for (mcs = mcs_start; mcs < mcs_end; mcs++) {
|
||||
|
||||
for (uint32_t n = 0; n < SRSLTE_MAX_PRB_NR; n++) {
|
||||
pusch_grant.prb_idx[n] = (n < n_prb);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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 "srslte/phy/ue/ue_ul_nr.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2020 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 "srslte/phy/ue/ue_ul_nr_data.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
|
||||
typedef struct {
|
||||
srslte_sch_mapping_type_t mapping;
|
||||
uint32_t K2;
|
||||
uint32_t S;
|
||||
uint32_t L;
|
||||
} ue_ul_time_resource_t;
|
||||
|
||||
static const ue_ul_time_resource_t ue_ul_default_A_lut[16] = {{srslte_sch_mapping_type_A, 0, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 0, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 0, 0, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 2, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 8},
|
||||
{srslte_sch_mapping_type_B, 0, 4, 6},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 1, 0, 10},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 12},
|
||||
{srslte_sch_mapping_type_A, 2, 0, 10},
|
||||
{srslte_sch_mapping_type_B, 0, 8, 6},
|
||||
{srslte_sch_mapping_type_A, 3, 0, 14},
|
||||
{srslte_sch_mapping_type_A, 3, 0, 10}};
|
||||
|
||||
int srslte_ue_ul_nr_pdsch_time_resource_default_A(uint32_t m, srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
if (m >= 16) {
|
||||
ERROR("m (%d) is out-of-range\n", m);
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
// Select mapping
|
||||
grant->mapping = ue_ul_default_A_lut[m].mapping;
|
||||
grant->k2 = ue_ul_default_A_lut[m].K2;
|
||||
grant->S = ue_ul_default_A_lut[m].S;
|
||||
grant->L = ue_ul_default_A_lut[m].L;
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_ue_ul_nr_nof_dmrs_cdm_groups_without_data_format_0_0(const srslte_sch_cfg_nr_t* cfg,
|
||||
srslte_sch_grant_nr_t* grant)
|
||||
{
|
||||
if (cfg == NULL || grant == NULL) {
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
/* According to TS 38.214 V15.10.0 6.2.2 UE DM-RS transmission procedure:
|
||||
* For PUSCH scheduled by DCI format 0_0 or by activation DCI format 0_0 with CRC scrambled by CS-RNTI, the UE
|
||||
* shall assume the number of DM-RS CDM groups without data is 1 which corresponds to CDM group 0 for the case of
|
||||
* PUSCH with allocation duration of 2 or less OFDM symbols with transform precoding disabled, the UE shall assume
|
||||
* that the number of DM-RS CDM groups without data is 3 which corresponds to CDM group {0,1,2} for the case of PUSCH
|
||||
* scheduled by activation DCI format 0_0 and the dmrs-Type in cg-DMRS-Configuration equal to 'type2' and the PUSCH
|
||||
* allocation duration being more than 2 OFDM symbols, and the UE shall assume that the number of DM-RS CDM groups
|
||||
* without data is 2 which corresponds to CDM group {0,1} for all other cases.
|
||||
*/
|
||||
if (grant->L <= 2 && !cfg->enable_transform_precoder) {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 1;
|
||||
// } else if (grant->L > 2 && cfg->dmrs_cg.type == srslte_dmrs_sch_type_2){
|
||||
// grant->nof_dmrs_cdm_groups_without_data = 3;
|
||||
} else {
|
||||
grant->nof_dmrs_cdm_groups_without_data = 2;
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
|
@ -29,7 +29,7 @@ typedef struct {
|
|||
} phy_nr_args_t;
|
||||
|
||||
typedef struct {
|
||||
srslte_pdsch_cfg_nr_t pdsch;
|
||||
srslte_sch_hl_cfg_nr_t pdsch;
|
||||
} phy_nr_cfg_t;
|
||||
|
||||
class phy_nr_state
|
||||
|
|
|
@ -121,7 +121,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_nr::dl_sched_grant_t* grants, ui
|
|||
for (uint32_t i = 0; i < nof_grants; i++) {
|
||||
// Get PHY config for UE
|
||||
// ...
|
||||
srslte_pdsch_cfg_nr_t pdsch_hl_cfg = {};
|
||||
srslte_sch_hl_cfg_nr_t pdsch_hl_cfg = {};
|
||||
srslte_sch_cfg_nr_t pdsch_cfg = {};
|
||||
|
||||
// Compute DL grant
|
||||
|
|
|
@ -29,7 +29,7 @@ typedef struct {
|
|||
} phy_nr_args_t;
|
||||
|
||||
typedef struct {
|
||||
srslte_pdsch_cfg_nr_t pdsch;
|
||||
srslte_sch_hl_cfg_nr_t pdsch;
|
||||
srslte_prach_cfg_t prach;
|
||||
srslte_ue_dl_nr_cfg_t pdcch;
|
||||
} phy_nr_cfg_t;
|
||||
|
@ -128,11 +128,11 @@ public:
|
|||
// PDSCH-TimeDomainResourceAllocation
|
||||
// mappingType: typeA (0)
|
||||
// startSymbolAndLength: 57
|
||||
cfg.pdsch.common_pdsch_time_ra[0].mapping_type = srslte_sch_mapping_type_A;
|
||||
cfg.pdsch.common_pdsch_time_ra[0].sliv = 40;
|
||||
cfg.pdsch.common_pdsch_time_ra[1].mapping_type = srslte_sch_mapping_type_A;
|
||||
cfg.pdsch.common_pdsch_time_ra[1].sliv = 57;
|
||||
cfg.pdsch.nof_common_pdsch_time_ra = 2;
|
||||
cfg.pdsch.common_time_ra[0].mapping_type = srslte_sch_mapping_type_A;
|
||||
cfg.pdsch.common_time_ra[0].sliv = 40;
|
||||
cfg.pdsch.common_time_ra[1].mapping_type = srslte_sch_mapping_type_A;
|
||||
cfg.pdsch.common_time_ra[1].sliv = 57;
|
||||
cfg.pdsch.nof_common_time_ra = 2;
|
||||
}
|
||||
};
|
||||
} // namespace nr
|
||||
|
|
|
@ -96,7 +96,7 @@ uint32_t cc_worker::get_buffer_len()
|
|||
|
||||
bool cc_worker::work_dl()
|
||||
{
|
||||
srslte_pdsch_cfg_nr_t pdsch_hl_cfg = phy->cfg.pdsch;
|
||||
srslte_sch_hl_cfg_nr_t pdsch_hl_cfg = phy->cfg.pdsch;
|
||||
|
||||
// Run FFT
|
||||
srslte_ue_dl_nr_estimate_fft(&ue_dl, &dl_slot_cfg);
|
||||
|
@ -144,7 +144,7 @@ bool cc_worker::work_dl()
|
|||
// Log found DCI
|
||||
if (logger.info.enabled()) {
|
||||
std::array<char, 512> str;
|
||||
srslte_dci_nr_to_str(dci_dl, str.data(), str.size());
|
||||
srslte_dci_dl_nr_to_str(dci_dl, str.data(), str.size());
|
||||
logger.info("PDCCH: cc=%d, %s", cc_idx, str.data());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue