diff --git a/lib/include/srsran/common/phy_cfg_nr.h b/lib/include/srsran/common/phy_cfg_nr.h index b37e6291d..e3985ce21 100644 --- a/lib/include/srsran/common/phy_cfg_nr.h +++ b/lib/include/srsran/common/phy_cfg_nr.h @@ -127,11 +127,26 @@ struct phy_cfg_nr_t { * @brief Compute UCI configuration for the given slot from the pending PDSCH ACK resources, periodic CSI, * periodic SR resources and so on. */ - bool get_pucch(const srsran_slot_cfg_t& slot_cfg, - const srsran_pdsch_ack_nr_t& pdsch_ack, - srsran_pucch_nr_common_cfg_t& cfg, - srsran_uci_cfg_nr_t& uci_cfg, - srsran_pucch_nr_resource_t& resource) const; + bool get_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_pdsch_ack_nr_t& pdsch_ack, + srsran_uci_cfg_nr_t& uci_cfg) const; + + /** + * @brief Compute UCI configuration for PUCCH for the given slot from the pending PDSCH ACK resources, periodic CSI, + * periodic SR resources and so on. + */ + bool get_pucch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_uci_cfg_nr_t& uci_cfg, + srsran_pucch_nr_common_cfg_t& cfg, + srsran_pucch_nr_resource_t& resource) const; + + /** + * @brief Compute UCI configuration for PUSCH for the given slot from the pending PDSCH ACK resources, periodic CSI, + * periodic SR resources and so on. + */ + bool get_pusch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_uci_cfg_nr_t& uci_cfg, + srsran_sch_cfg_nr_t& pusch_cfg) const; }; } // namespace srsran diff --git a/lib/src/common/phy_cfg_nr.cc b/lib/src/common/phy_cfg_nr.cc index 729839084..1ab321feb 100644 --- a/lib/src/common/phy_cfg_nr.cc +++ b/lib/src/common/phy_cfg_nr.cc @@ -280,17 +280,29 @@ bool phy_cfg_nr_t::get_pdsch_ack_resource(const srsran_dci_dl_nr_t& dci_dl, return srsran_harq_ack_resource(&harq_ack, &dci_dl, &ack_resource) == SRSRAN_SUCCESS; } -bool phy_cfg_nr_t::get_pucch(const srsran_slot_cfg_t& slot_cfg, - const srsran_pdsch_ack_nr_t& ack_info, - srsran_pucch_nr_common_cfg_t& cfg, - srsran_uci_cfg_nr_t& uci_cfg, - srsran_pucch_nr_resource_t& resource) const +bool phy_cfg_nr_t::get_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_pdsch_ack_nr_t& pdsch_ack, + srsran_uci_cfg_nr_t& uci_cfg) const { // Generate configuration for HARQ feedback - if (srsran_harq_ack_gen_uci_cfg(&harq_ack, &ack_info, &uci_cfg) < SRSRAN_SUCCESS) { + if (srsran_harq_ack_gen_uci_cfg(&harq_ack, &pdsch_ack, &uci_cfg) < SRSRAN_SUCCESS) { return false; } + // Generate configuration for SR + // ... + + // Generate configuration for CSI reports + // ... + + return true; +} + +bool phy_cfg_nr_t::get_pucch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_uci_cfg_nr_t& uci_cfg, + srsran_pucch_nr_common_cfg_t& cfg, + srsran_pucch_nr_resource_t& resource) const +{ // Select PUCCH resource if (srsran_ra_ul_nr_pucch_resource(&pucch, &uci_cfg, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); @@ -300,4 +312,16 @@ bool phy_cfg_nr_t::get_pucch(const srsran_slot_cfg_t& slot_cfg, return true; } +bool phy_cfg_nr_t::get_pusch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, + const srsran_uci_cfg_nr_t& uci_cfg, + srsran_sch_cfg_nr_t& pusch_cfg) const +{ + // Generate configuration for PUSCH + if (srsran_ra_ul_set_grant_uci_nr(&carrier, &pusch, &uci_cfg, &pusch_cfg) < SRSRAN_SUCCESS) { + return false; + } + + return true; +} + } // namespace srsran \ No newline at end of file diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index b674ea8d8..ae4226685 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -91,6 +91,11 @@ void phy_cfg_nr_default_t::make_pusch_default(srsran_sch_hl_cfg_nr_t& pusch) // Setup PUSCH DMRS type A position pusch.typeA_pos = srsran_dmrs_sch_typeA_pos_2; + + pusch.scaling = 1.0f; + pusch.beta_offsets.fix_ack = 12.625f; + pusch.beta_offsets.fix_csi1 = 2.25f; + pusch.beta_offsets.fix_csi2 = 2.25f; } void phy_cfg_nr_default_t::make_pucch_custom_one(srsran_pucch_nr_hl_cfg_t& pucch) diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 42c2d9c5d..afc56563c 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -13,6 +13,8 @@ #ifndef SRSRAN_DUMMY_GNB_STACK_H #define SRSRAN_DUMMY_GNB_STACK_H +#include "dummy_rx_harq_proc.h" +#include "dummy_tx_harq_proc.h" #include #include #include @@ -29,14 +31,14 @@ private: srsran::circular_array dci_dl_location; srsran::circular_array dci_ul_location; srsran::circular_array dl_data_to_ul_ack; - uint32_t ss_id = 0; - srsran_dci_format_nr_t dci_format_ul = SRSRAN_DCI_FORMAT_NR_COUNT; - srsran_dci_format_nr_t dci_format_dl = SRSRAN_DCI_FORMAT_NR_COUNT; - uint32_t dl_freq_res = 0; - uint32_t dl_time_res = 0; - srsran_random_t random_gen = nullptr; - srsran::phy_cfg_nr_t phy_cfg = {}; - bool valid = false; + uint32_t ss_id = 0; + uint32_t dl_freq_res = 0; + uint32_t dl_time_res = 0; + uint32_t ul_freq_res = 0; + uint32_t ul_time_res = 0; + srsran_random_t random_gen = nullptr; + srsran::phy_cfg_nr_t phy_cfg = {}; + bool valid = false; std::mutex mac_metrics_mutex; srsenb::mac_ue_metrics_t mac_metrics = {}; @@ -79,26 +81,164 @@ private: }; std::array pending_ack = {}; - struct dummy_harq_proc { - static const uint32_t MAX_TB_SZ = SRSRAN_LDPC_MAX_LEN_CB * SRSRAN_SCH_NR_MAX_NOF_CB_LDPC; - std::vector data; - srsran_softbuffer_tx_t softbuffer = {}; + // PUSCH state + class pending_pusch_t + { + private: + std::mutex mutex; + srsran_sch_cfg_nr_t pusch = {}; + bool valid = false; - dummy_harq_proc() + public: + pending_pusch_t() = default; + void push(const srsran_sch_cfg_nr_t& pusch_) { - // Allocate data - data.resize(MAX_TB_SZ); - - // Initialise softbuffer - if (srsran_softbuffer_tx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < - SRSRAN_SUCCESS) { - ERROR("Error Tx buffer"); - } + std::unique_lock lock(mutex); + pusch = pusch_; + valid = true; } - ~dummy_harq_proc() { srsran_softbuffer_tx_free(&softbuffer); } + bool pop(srsran_sch_cfg_nr_t& pusch_) + { + std::unique_lock lock(mutex); + bool ret = valid; + pusch_ = pusch; + valid = false; + return ret; + } }; - srsran::circular_array tx_harq_proc; + std::array pending_pusch = {}; + + srsran::circular_array tx_harq_proc; + + srsran::circular_array rx_harq_proc; + +private: + bool schedule_pdsch(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) + { + // Instantiate PDCCH and PDSCH + pdcch_dl_t pdcch = {}; + pdsch_t pdsch = {}; + + // Select grant and set data + pdsch.data[0] = tx_harq_proc[slot_cfg.idx].data.data(); + + // Second TB is not used + pdsch.data[1] = nullptr; + + // Fill DCI configuration + pdcch.dci_cfg = phy_cfg.get_dci_cfg(); + + // Fill DCI context + if (not phy_cfg.get_dci_ctx_pdsch_rnti_c(ss_id, dci_dl_location[slot_cfg.idx], rnti, pdcch.dci.ctx)) { + logger.error("Error filling PDSCH DCI context"); + return false; + } + + uint32_t harq_feedback = dl_data_to_ul_ack[slot_cfg.idx]; + uint32_t harq_ack_slot_idx = TTI_ADD(slot_cfg.idx, harq_feedback); + + // Fill DCI fields + srsran_dci_dl_nr_t& dci = pdcch.dci; + dci.freq_domain_assigment = dl_freq_res; + dci.time_domain_assigment = dl_time_res; + dci.mcs = mcs; + dci.rv = 0; + dci.ndi = (slot_cfg.idx / SRSRAN_NOF_SF_X_FRAME) % 2; + dci.pid = slot_cfg.idx % SRSRAN_NOF_SF_X_FRAME; + dci.dai = pending_ack[harq_ack_slot_idx % pending_ack.size()].get_dai(); + dci.tpc = 1; + dci.pucch_resource = 0; + if (dci.ctx.format == srsran_dci_format_nr_1_0) { + dci.harq_feedback = dl_data_to_ul_ack[slot_cfg.idx] - 1; + } else { + dci.harq_feedback = slot_cfg.idx; + } + + // Create PDSCH configuration + if (not phy_cfg.get_pdsch_cfg(slot_cfg, dci, pdsch.sch)) { + logger.error("Error converting DCI to grant"); + return false; + } + + // Generate random data + srsran_random_byte_vector(random_gen, pdsch.data[0], pdsch.sch.grant.tb[0].tbs / 8); + + // Set TBS + tx_harq_proc[slot_cfg.idx].tbs = pdsch.sch.grant.tb[0].tbs; + + // Set softbuffer + pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].softbuffer; + + // Reset Tx softbuffer always + srsran_softbuffer_tx_reset(pdsch.sch.grant.tb[0].softbuffer.tx); + + // Push scheduling results + dl_sched.pdcch_dl.push_back(pdcch); + dl_sched.pdsch.push_back(pdsch); + + // Generate PDSCH HARQ Feedback + srsran_harq_ack_resource_t ack_resource = {}; + if (not phy_cfg.get_pdsch_ack_resource(dci, ack_resource)) { + logger.error("Error getting ack resource"); + return false; + } + + // Calculate PUCCH slot and push resource + pending_ack[harq_ack_slot_idx % pending_ack.size()].push_ack(ack_resource); + + return true; + } + + bool schedule_pusch(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) + { + // Instantiate PDCCH + pdcch_ul_t pdcch = {}; + + // Fill DCI configuration + pdcch.dci_cfg = phy_cfg.get_dci_cfg(); + + // Fill DCI context + if (not phy_cfg.get_dci_ctx_pusch_rnti_c(ss_id, dci_ul_location[slot_cfg.idx], rnti, pdcch.dci.ctx)) { + logger.error("Error filling PDSCH DCI context"); + return false; + } + + // Fill DCI fields + srsran_dci_ul_nr_t& dci = pdcch.dci; + dci.freq_domain_assigment = ul_freq_res; + dci.time_domain_assigment = ul_time_res; + dci.freq_hopping_flag = 0; + dci.mcs = mcs; + dci.rv = 0; + dci.ndi = (slot_cfg.idx / SRSRAN_NOF_SF_X_FRAME) % 2; + dci.pid = slot_cfg.idx % SRSRAN_NOF_SF_X_FRAME; + dci.tpc = 1; + + // Create PDSCH configuration + srsran_sch_cfg_nr_t pusch_cfg = {}; + if (not phy_cfg.get_pusch_cfg(slot_cfg, dci, pusch_cfg)) { + logger.error("Error converting DCI to grant"); + return false; + } + + // Set TBS + rx_harq_proc[slot_cfg.idx].tbs = pusch_cfg.grant.tb[0].tbs; + + // Set softbuffer + pusch_cfg.grant.tb[0].softbuffer.rx = &rx_harq_proc[slot_cfg.idx].softbuffer; + + // Reset Tx softbuffer always + srsran_softbuffer_rx_reset(pusch_cfg.grant.tb[0].softbuffer.rx); + + // Push scheduling results + dl_sched.pdcch_ul.push_back(pdcch); + + // Set pending PUSCH + pending_pusch[TTI_TX(slot_cfg.idx) % pending_pusch.size()].push(pusch_cfg); + + return true; + } public: struct args_t { @@ -110,13 +250,19 @@ public: uint32_t pdcch_dl_candidate_index = 0; ///< PDCCH DL DCI candidate index uint32_t pdcch_ul_candidate_index = 0; ///< PDCCH UL DCI candidate index uint32_t dl_start_rb = 0; ///< Start resource block - uint32_t dl_length_rb = 0l; ///< Number of resource blocks + uint32_t dl_length_rb = 0; ///< Number of resource blocks + uint32_t ul_start_rb = 0; ///< Start resource block + uint32_t ul_length_rb = 0; ///< Number of resource blocks uint32_t dl_time_res = 0; ///< PDSCH time resource std::string log_level = "debug"; }; gnb_dummy_stack(args_t args) : - mcs(args.mcs), rnti(args.rnti), dl_time_res(args.dl_time_res), phy_cfg(args.phy_cfg), ss_id(args.ss_id) + mcs(args.mcs), + rnti(args.rnti), + dl_time_res(args.dl_time_res), + phy_cfg(args.phy_cfg), + ss_id(args.ss_id) { random_gen = srsran_random_init(0x1234); logger.set_level(srslog::str_to_basic_level(args.log_level)); @@ -152,17 +298,12 @@ public: dci_ul_location[slot] = locations[args.pdcch_ul_candidate_index]; } - // Select DCI formats - dci_format_dl = phy_cfg.get_dci_format_pdsch(args.ss_id); - dci_format_ul = phy_cfg.get_dci_format_pusch(args.ss_id); - if (dci_format_dl == SRSRAN_DCI_FORMAT_NR_COUNT or dci_format_ul == SRSRAN_DCI_FORMAT_NR_COUNT) { - logger.error("Missing valid DL or UL DCI format in search space"); - return; - } - // Select DL frequency domain resources dl_freq_res = srsran_ra_nr_type1_riv(args.phy_cfg.carrier.nof_prb, args.dl_start_rb, args.dl_length_rb); + // Select DL frequency domain resources + ul_freq_res = srsran_ra_nr_type1_riv(args.phy_cfg.carrier.nof_prb, args.ul_start_rb, args.ul_length_rb); + // Setup DL Data to ACK timing for (uint32_t i = 0; i < SRSRAN_NOF_SF_X_FRAME; i++) { dl_data_to_ul_ack[i] = args.phy_cfg.harq_ack.dl_data_to_ul_ack[i % SRSRAN_MAX_NOF_DL_DATA_TO_UL]; @@ -188,74 +329,21 @@ public: return SRSRAN_SUCCESS; } - // Instantiate PDCCH and PDSCH - pdcch_dl_t pdcch = {}; - pdsch_t pdsch = {}; - - // Select grant and set data - pdsch.data[0] = tx_harq_proc[slot_cfg.idx].data.data(); - - // Second TB is not used - pdsch.data[1] = nullptr; - - // Fill DCI configuration - pdcch.dci_cfg = phy_cfg.get_dci_cfg(); - - // Fill DCI context - if (not phy_cfg.get_dci_ctx_pdsch_rnti_c(ss_id, dci_dl_location[slot_cfg.idx], rnti, pdcch.dci.ctx)) { - logger.error("Error filling PDSCH DCI context"); + if (not schedule_pdsch(slot_cfg, dl_sched)) { + logger.error("Error scheduling PDSCH"); return SRSRAN_ERROR; } - uint32_t harq_feedback = dl_data_to_ul_ack[slot_cfg.idx]; - uint32_t harq_ack_slot_idx = TTI_ADD(slot_cfg.idx, harq_feedback); - - // Fill DCI fields - srsran_dci_dl_nr_t& dci = pdcch.dci; - dci.freq_domain_assigment = dl_freq_res; - dci.time_domain_assigment = dl_time_res; - dci.mcs = mcs; - dci.rv = 0; - dci.ndi = (slot_cfg.idx / SRSRAN_NOF_SF_X_FRAME) % 2; - dci.pid = slot_cfg.idx % SRSRAN_NOF_SF_X_FRAME; - dci.dai = pending_ack[harq_ack_slot_idx % pending_ack.size()].get_dai(); - dci.tpc = 1; - dci.pucch_resource = 0; - if (dci.ctx.format == srsran_dci_format_nr_1_0) { - dci.harq_feedback = dl_data_to_ul_ack[slot_cfg.idx] - 1; - } else { - dci.harq_feedback = slot_cfg.idx; - } - - // Create PDSCH configuration - if (not phy_cfg.get_pdsch_cfg(slot_cfg, dci, pdsch.sch)) { - logger.error("Error converting DCI to grant"); - return SRSRAN_ERROR; + // Check if the UL slot is valid, if not skip UL scheduling + if (not srsran_tdd_nr_is_ul(&phy_cfg.tdd, phy_cfg.carrier.scs, TTI_TX(slot_cfg.idx))) { + return SRSRAN_SUCCESS; } - // Generate random data - srsran_random_byte_vector(random_gen, pdsch.data[0], pdsch.sch.grant.tb[0].tbs / 8); - - // Set softbuffer - pdsch.sch.grant.tb[0].softbuffer.tx = &tx_harq_proc[slot_cfg.idx].softbuffer; - - // Reset Tx softbuffer always - srsran_softbuffer_tx_reset(pdsch.sch.grant.tb[0].softbuffer.tx); - - // Push scheduling results - dl_sched.pdcch_dl.push_back(pdcch); - dl_sched.pdsch.push_back(pdsch); - - // Generate PDSCH HARQ Feedback - srsran_harq_ack_resource_t ack_resource = {}; - if (not phy_cfg.get_pdsch_ack_resource(dci, ack_resource)) { - logger.error("Error getting ack resource"); + if (not schedule_pusch(slot_cfg, dl_sched)) { + logger.error("Error scheduling PUSCH"); return SRSRAN_ERROR; } - // Calculate PUCCH slot and push resource - pending_ack[harq_ack_slot_idx % pending_ack.size()].push_ack(ack_resource); - return SRSRAN_SUCCESS; } @@ -263,19 +351,39 @@ public: { logger.set_context(slot_cfg.idx); - srsran_pdsch_ack_nr_t ack = pending_ack[slot_cfg.idx % pending_ack.size()].get_ack(); - - if (ack.nof_cc > 0) { - mac_interface_phy_nr::pucch_t pucch = {}; + // Get ACK information + srsran_pdsch_ack_nr_t ack = pending_ack[slot_cfg.idx % pending_ack.size()].get_ack(); + bool has_ack = ack.nof_cc > 0; + if (has_ack) { if (logger.debug.enabled()) { std::array str = {}; if (srsran_harq_ack_info(&ack, str.data(), (uint32_t)str.size()) > 0) { logger.debug("HARQ feedback:\n%s", str.data()); } } + } + mac_interface_phy_nr::pusch_t pusch = {}; + bool has_pusch = pending_pusch[slot_cfg.idx % pending_pusch.size()].pop(pusch.sch); + + srsran_uci_cfg_nr_t uci_cfg = {}; + if (not phy_cfg.get_uci_cfg(slot_cfg, ack, uci_cfg)) { + logger.error("Error getting UCI configuration"); + return SRSRAN_ERROR; + } - if (not phy_cfg.get_pucch(slot_cfg, ack, pucch.pucch_cfg, pucch.uci_cfg, pucch.resource)) { + if (has_pusch) { + if (not phy_cfg.get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { + logger.error("Error setting UCI configuration in PUSCH"); + return SRSRAN_ERROR; + } + + ul_sched.pusch.push_back(pusch); + return SRSRAN_SUCCESS; + } else if (has_ack) { + mac_interface_phy_nr::pucch_t pucch = {}; + pucch.uci_cfg = uci_cfg; + if (not phy_cfg.get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.resource)) { logger.error("Error getting UCI CFG"); return SRSRAN_ERROR; } @@ -294,6 +402,7 @@ public: const srsran_harq_ack_bit_t* ack_bit = &pucch_info.uci_data.cfg.ack.bits[i]; bool is_ok = (pucch_info.uci_data.value.ack[i] == 1) and pucch_info.uci_data.value.valid; uint32_t tb_count = (ack_bit->tb0 ? 1 : 0) + (ack_bit->tb1 ? 1 : 0); + mac_metrics.tx_brate += tx_harq_proc[ack_bit->pid].tbs; mac_metrics.tx_pkts += tb_count; if (not is_ok) { mac_metrics.tx_errors += tb_count; diff --git a/test/phy/dummy_rx_harq_proc.h b/test/phy/dummy_rx_harq_proc.h new file mode 100644 index 000000000..9a5fe85a3 --- /dev/null +++ b/test/phy/dummy_rx_harq_proc.h @@ -0,0 +1,41 @@ +/** + * + * \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. + * + */ + +#ifndef SRSRAN_DUMMY_RX_HARQ_PROC_H +#define SRSRAN_DUMMY_RX_HARQ_PROC_H + +#include +#include +#include +#include +#include +#include + +struct dummy_rx_harq_proc { + static const uint32_t MAX_TB_SZ = SRSRAN_LDPC_MAX_LEN_CB * SRSRAN_SCH_NR_MAX_NOF_CB_LDPC; + srsran::byte_buffer_t data; + srsran_softbuffer_rx_t softbuffer = {}; + std::atomic tbs = {0}; + + dummy_rx_harq_proc() : data(0) + { + // Initialise softbuffer + if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + SRSRAN_SUCCESS) { + ERROR("Error Tx buffer"); + } + } + + ~dummy_rx_harq_proc() { srsran_softbuffer_rx_free(&softbuffer); } +}; + +#endif // SRSRAN_DUMMY_RX_HARQ_PROC_H diff --git a/test/phy/dummy_tx_harq_proc.h b/test/phy/dummy_tx_harq_proc.h new file mode 100644 index 000000000..cbaddc8b5 --- /dev/null +++ b/test/phy/dummy_tx_harq_proc.h @@ -0,0 +1,41 @@ +/** + * + * \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. + * + */ + +#ifndef SRSRAN_TX_DUMMY_HARQ_PROC_H +#define SRSRAN_TX_DUMMY_HARQ_PROC_H + +#include +#include +#include +#include +#include +#include + +struct dummy_tx_harq_proc { + static const uint32_t MAX_TB_SZ = SRSRAN_LDPC_MAX_LEN_CB * SRSRAN_SCH_NR_MAX_NOF_CB_LDPC; + srsran::byte_buffer_t data; + srsran_softbuffer_tx_t softbuffer = {}; + std::atomic tbs = {0}; + + dummy_tx_harq_proc() + { + // Initialise softbuffer + if (srsran_softbuffer_tx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + SRSRAN_SUCCESS) { + ERROR("Error Tx buffer"); + } + } + + ~dummy_tx_harq_proc() { srsran_softbuffer_tx_free(&softbuffer); } +}; + +#endif // SRSRAN_TX_DUMMY_HARQ_PROC_H diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 270e74894..d1115f7cf 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -37,22 +37,8 @@ private: uint16_t rnti = 0; bool valid = false; - struct dummy_harq_proc { - static const uint32_t MAX_TB_SZ = SRSRAN_LDPC_MAX_LEN_CB * SRSRAN_SCH_NR_MAX_NOF_CB_LDPC; - srsran_softbuffer_rx_t softbuffer = {}; - - dummy_harq_proc() - { - // Initialise softbuffer - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < - SRSRAN_SUCCESS) { - ERROR("Error Tx buffer"); - } - } - - ~dummy_harq_proc() { srsran_softbuffer_rx_free(&softbuffer); } - }; - srsran::circular_array rx_harq_proc; + srsran::circular_array tx_harq_proc; + srsran::circular_array rx_harq_proc; public: struct args_t { @@ -71,7 +57,14 @@ public: action->tb.softbuffer = &rx_harq_proc[grant.pid].softbuffer; } void tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_result_t result) override {} - void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) override {} + void new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) override + { + if (action == nullptr) { + return; + } + action->tb.enabled = true; + action->tb.payload = &rx_harq_proc[grant.pid].data; + } void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) override {} bool sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx) override { return false; } bool is_valid() const { return valid; } @@ -109,6 +102,8 @@ int main(int argc, char** argv) gnb_stack_args.phy_cfg = args.phy_cfg; gnb_stack_args.dl_start_rb = 0; gnb_stack_args.dl_length_rb = args.phy_cfg.carrier.nof_prb; + gnb_stack_args.ul_start_rb = 0; + gnb_stack_args.ul_length_rb = args.phy_cfg.carrier.nof_prb; // Create GNB stack gnb_dummy_stack gnb_stack(gnb_stack_args);