Added GNB MAC UL info initial interface and fix PHY implementation

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent cf496e75eb
commit 5307fec2f0

@ -258,9 +258,22 @@ public:
srsran::bounded_vector<pucch_t, MAX_GRANTS> pucch;
};
virtual int slot_indication(const srsran_slot_cfg_t& slot_cfg) = 0;
virtual int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) = 0;
virtual int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) = 0;
struct pucch_info_t {
srsran_uci_data_nr_t uci_data; ///< RNTI is available under cfg->pucch->rnti
// ... add signal measurements here
};
struct pusch_info_t {
uint16_t rnti;
srsran_pusch_res_nr_t pusch_data;
// ... add signal measurements here
};
virtual int slot_indication(const srsran_slot_cfg_t& slot_cfg) = 0;
virtual int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) = 0;
virtual int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) = 0;
virtual int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) = 0;
virtual int pusch_info(const srsran_slot_cfg_t& slot_cfg, const pusch_info_t& pusch_info) = 0;
};
class stack_interface_phy_nr : public mac_interface_phy_nr, public srsran::stack_interface_phy_nr

@ -188,6 +188,7 @@ SRSRAN_API int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t*
* @param[in] slot_symbols Resource grid of the given slot
* @param[out] b Bits to decode
* @param[in] nof_bits Number of bits to decode in the message
* @param[out] norm_corr Normalised correlation
* @return SRSRAN_SUCCESS if successful, SRSRAN_ERROR code otherwise
*/
SRSRAN_API int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q,
@ -197,7 +198,8 @@ SRSRAN_API int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t*
srsran_chest_ul_res_t* chest_res,
cf_t* slot_symbols,
uint8_t b[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS],
uint32_t nof_bits);
uint32_t nof_bits,
float* norm_corr);
/**
* @brief Encoder NR-PUCCH formats 2, 3 and 4. The NR-PUCCH format is selected by resource->format.

@ -228,7 +228,7 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg)
switch (reference_cfg.pucch) {
case reference_cfg_t::R_PUCCH_CUSTOM_ONE:
make_pusch_default(pusch);
make_pucch_custom_one(pucch);
break;
}

@ -194,18 +194,25 @@ static int gnb_ul_decode_pucch_format1(srsran_gnb_ul_t* q,
nof_bits = 1;
}
// Channel estimation
if (srsran_dmrs_pucch_format1_estimate(&q->pucch, cfg, slot_cfg, resource, q->sf_symbols[0], &q->chest_pucch) <
SRSRAN_SUCCESS) {
ERROR("Error in PUCCH format 1 estimation");
return SRSRAN_ERROR;
}
// Actual decode
float norm_corr = 0.0f;
if (srsran_pucch_nr_format1_decode(
&q->pucch, cfg, slot_cfg, resource, &q->chest_pucch, q->sf_symbols[0], b, nof_bits) < SRSRAN_SUCCESS) {
&q->pucch, cfg, slot_cfg, resource, &q->chest_pucch, q->sf_symbols[0], b, nof_bits, &norm_corr) <
SRSRAN_SUCCESS) {
ERROR("Error in PUCCH format 1 decoding");
return SRSRAN_ERROR;
}
// Take valid decision
uci_value->valid = (norm_corr > 0.5f);
// De-multiplex ACK bits
for (uint32_t i = 0; i < nof_bits; i++) {
uci_value->ack[i] = b[i];

@ -452,7 +452,8 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q,
srsran_chest_ul_res_t* chest_res,
cf_t* slot_symbols,
uint8_t b[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS],
uint32_t nof_bits)
uint32_t nof_bits,
float* norm_corr)
{
uint32_t m_cs = 0;
@ -524,8 +525,14 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q,
srsran_demod_soft_demodulate((nof_bits == 1) ? SRSRAN_MOD_BPSK : SRSRAN_MOD_QPSK, &d, llr, 1);
// Hard decision
float corr = 0.0f;
for (uint32_t i = 0; i < nof_bits; i++) {
b[i] = llr[i] > 0.0f ? 1 : 0;
corr += fabsf(llr[i]);
}
if (norm_corr != NULL && nof_bits > 0) {
*norm_corr = corr / nof_bits;
}
return SRSRAN_SUCCESS;

@ -139,7 +139,7 @@ static int test_pucch_format1(srsran_pucch_nr_t* pucch,
// Decode PUCCH
uint8_t b_rx[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS];
TESTASSERT(srsran_pucch_nr_format1_decode(
pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits) ==
pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits, NULL) ==
SRSRAN_SUCCESS);
// Check received bits

@ -75,6 +75,8 @@ public:
int slot_indication(const srsran_slot_cfg_t& slot_cfg) override;
int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override;
int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override;
int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override;
int pusch_info(const srsran_slot_cfg_t& slot_cfg, const pusch_info_t& pusch_info) override;
private:
void run_thread() final;

@ -68,6 +68,8 @@ public:
int slot_indication(const srsran_slot_cfg_t& slot_cfg) override;
int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override;
int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override;
int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override;
int pusch_info(const srsran_slot_cfg_t& slot_cfg, const pusch_info_t& pusch_info) override;
private:
void get_dl_config(const uint32_t tti,

@ -159,17 +159,30 @@ bool slot_worker::work_ul()
// Decode PUCCH
for (stack_interface_phy_nr::pucch_t& pucch : ul_sched.pucch) {
srsran_uci_value_nr_t uci_value;
if (srsran_gnb_ul_get_pucch(&gnb_ul, &ul_slot_cfg, &pucch.pucch_cfg, &pucch.resource, &pucch.uci_cfg, &uci_value) <
SRSRAN_SUCCESS) {
stack_interface_phy_nr::pucch_info_t pucch_info = {};
pucch_info.uci_data.cfg = pucch.uci_cfg;
// Decode PUCCH
if (srsran_gnb_ul_get_pucch(&gnb_ul,
&ul_slot_cfg,
&pucch.pucch_cfg,
&pucch.resource,
&pucch_info.uci_data.cfg,
&pucch_info.uci_data.value) < SRSRAN_SUCCESS) {
logger.error("Error getting PUCCH");
return false;
}
// Inform stack
if (stack.pucch_info(ul_slot_cfg, pucch_info) < SRSRAN_SUCCESS) {
logger.error("Error pushing PUCCH information to stack");
return false;
}
// Log PUCCH decoding
if (logger.info.enabled()) {
std::array<char, 512> str;
srsran_uci_data_nr_t uci_data = {.cfg = pucch.uci_cfg, .value = uci_value};
srsran_gnb_ul_pucch_info(&gnb_ul, &pucch.resource, &uci_data, str.data(), (uint32_t)str.size());
srsran_gnb_ul_pucch_info(&gnb_ul, &pucch.resource, &pucch_info.uci_data, str.data(), (uint32_t)str.size());
logger.info("PUCCH: %s", str.data());
}

@ -189,5 +189,13 @@ int gnb_stack_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul
{
return m_mac->get_ul_sched(slot_cfg, ul_sched);
}
int gnb_stack_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info)
{
return m_mac->pucch_info(slot_cfg, pucch_info);
}
int gnb_stack_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pusch_info_t& pusch_info)
{
return m_mac->pusch_info(slot_cfg, pusch_info);
}
} // namespace srsenb

@ -276,5 +276,13 @@ int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched
{
return 0;
}
int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info)
{
return 0;
}
int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pusch_info_t& pusch_info)
{
return 0;
}
} // namespace srsenb

@ -14,8 +14,10 @@
#define SRSRAN_DUMMY_GNB_STACK_H
#include <mutex>
#include <srsenb/hdr/stack/mac/mac_metrics.h>
#include <srsran/adt/circular_array.h>
#include <srsran/common/phy_cfg_nr.h>
#include <srsran/common/standard_streams.h>
#include <srsran/interfaces/gnb_interfaces.h>
class gnb_dummy_stack : public srsenb::stack_interface_phy_nr
@ -36,6 +38,9 @@ private:
srsran::phy_cfg_nr_t phy_cfg = {};
bool valid = false;
std::mutex mac_metrics_mutex;
srsenb::mac_ue_metrics_t mac_metrics = {};
// HARQ feedback
class pending_ack_t
{
@ -61,21 +66,15 @@ private:
srsran_pdsch_ack_nr_t get_ack()
{
std::unique_lock<std::mutex> lock(mutex);
return ack;
srsran_pdsch_ack_nr_t ret = ack;
ack = {};
return ret;
}
uint32_t get_dai()
{
std::unique_lock<std::mutex> lock(mutex);
return ack.cc[0].M % 4;
}
void reset()
{
std::unique_lock<std::mutex> lock(mutex);
ack = {};
}
};
srsran::circular_array<pending_ack_t, TTIMOD_SZ> pending_ack;
@ -264,7 +263,6 @@ public:
logger.set_context(slot_cfg.idx);
srsran_pdsch_ack_nr_t ack = pending_ack[slot_cfg.idx].get_ack();
pending_ack[slot_cfg.idx].reset();
if (ack.nof_cc > 0) {
mac_interface_phy_nr::pucch_t pucch = {};
@ -286,6 +284,36 @@ public:
return 0;
}
int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override
{
std::unique_lock<std::mutex> lock(mac_metrics_mutex);
for (uint32_t i = 0; i < pucch_info.uci_data.cfg.ack.count; i++) {
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_pkts += tb_count;
if (not is_ok) {
mac_metrics.tx_errors += tb_count;
logger.debug("NACK received!");
}
}
return SRSRAN_SUCCESS;
}
int pusch_info(const srsran_slot_cfg_t& slot_cfg, const pusch_info_t& pusch_info) override
{
// ... Not implemented
return SRSRAN_ERROR;
}
srsenb::mac_ue_metrics_t get_metrics()
{
std::unique_lock<std::mutex> lock(mac_metrics_mutex);
return mac_metrics;
}
};
#endif // SRSRAN_DUMMY_GNB_STACK_H

@ -120,10 +120,38 @@ int main(int argc, char** argv)
// Assert bench is initialised correctly
TESTASSERT(tb.is_initialised());
for (uint32_t i = 0; i < 20; i++) {
// Run per TTI basis
for (uint32_t i = 0; i < 1000; i++) {
TESTASSERT(tb.run_tti());
}
// Stop test bench
tb.stop();
// Flush log
srslog::flush();
// Retrieve MAC metrics
srsenb::mac_ue_metrics_t mac_metrics = gnb_stack.get_metrics();
// Print metrics
float pdsch_bler = 0.0f;
if (mac_metrics.tx_pkts != 0) {
pdsch_bler = (float)mac_metrics.tx_errors / (float)mac_metrics.tx_pkts;
}
float pdsch_rate = 0.0f;
if (mac_metrics.tx_pkts != 0) {
pdsch_rate = (float)mac_metrics.tx_brate / (float)mac_metrics.tx_pkts / 1000.0f;
}
srsran::console("PDSCH:\n");
srsran::console(" Count: %d\n", mac_metrics.tx_pkts);
srsran::console(" BLER: %f\n", pdsch_bler);
srsran::console(" Rate: %f Mbps\n", pdsch_rate);
// Assert metrics
TESTASSERT(mac_metrics.tx_errors == 0);
// If reached here, the test is successful
return SRSRAN_SUCCESS;
}

@ -75,7 +75,7 @@ public:
initialised = true;
}
~test_bench()
void stop()
{
ue_phy_com.stop();
gnb_phy_com.stop();
@ -83,6 +83,8 @@ public:
ue_phy.stop();
}
~test_bench() = default;
bool is_initialised() const { return initialised; }
bool run_tti()

Loading…
Cancel
Save