Initial NR PHY interface

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 77bd500312
commit 2f453b43ba

@ -70,6 +70,7 @@ typedef struct {
uint8_t* payload; uint8_t* payload;
bool crc; bool crc;
float evm; float evm;
uint32_t fec_iters;
} srsran_pdsch_res_nr_t; } srsran_pdsch_res_nr_t;
SRSRAN_API int srsran_pdsch_nr_init_enb(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* args); SRSRAN_API int srsran_pdsch_nr_init_enb(srsran_pdsch_nr_t* q, const srsran_pdsch_nr_args_t* args);

@ -25,10 +25,11 @@ typedef struct SRSRAN_API {
typedef struct SRSRAN_API { typedef struct SRSRAN_API {
srsran_mod_t mod; srsran_mod_t mod;
uint32_t N_L; ///< the number of transmission layers that the transport block is mapped onto uint32_t N_L; ///< the number of transmission layers that the transport block is mapped onto
int tbs; ///< Payload size, TS 38.212 refers to it as A uint32_t mcs; ///< Modulation Code Scheme (MCS) for debug and trace purpose
double R; ///< Target LDPC rate int tbs; ///< Payload size, TS 38.212 refers to it as A
int rv; double R; ///< Target LDPC rate
int rv; ///< Redundancy version
uint32_t nof_re; ///< Number of available resource elements to send, known as N_RE uint32_t nof_re; ///< Number of available resource elements to send, known as N_RE
uint32_t nof_bits; ///< Number of available bits to send, known as G uint32_t nof_bits; ///< Number of available bits to send, known as G
uint32_t cw_idx; uint32_t cw_idx;

@ -676,6 +676,7 @@ int srsran_ra_dl_dci_to_grant_nr(const srsran_carrier_nr_t* carrier,
pdsch_grant->rnti = dci_dl->ctx.rnti; pdsch_grant->rnti = dci_dl->ctx.rnti;
pdsch_grant->rnti_type = dci_dl->ctx.rnti_type; pdsch_grant->rnti_type = dci_dl->ctx.rnti_type;
pdsch_grant->tb[0].rv = dci_dl->rv; pdsch_grant->tb[0].rv = dci_dl->rv;
pdsch_grant->tb[0].mcs = dci_dl->mcs;
// 5.1.4 PDSCH resource mapping // 5.1.4 PDSCH resource mapping
if (ra_dl_resource_mapping(carrier, slot, pdsch_hl_cfg, pdsch_cfg) < SRSRAN_SUCCESS) { if (ra_dl_resource_mapping(carrier, slot, pdsch_hl_cfg, pdsch_cfg) < SRSRAN_SUCCESS) {
@ -785,6 +786,7 @@ int srsran_ra_ul_dci_to_grant_nr(const srsran_carrier_nr_t* carrier,
pusch_grant->rnti = dci_ul->ctx.rnti; pusch_grant->rnti = dci_ul->ctx.rnti;
pusch_grant->rnti_type = dci_ul->ctx.rnti_type; pusch_grant->rnti_type = dci_ul->ctx.rnti_type;
pusch_grant->tb[0].rv = dci_ul->rv; pusch_grant->tb[0].rv = dci_ul->rv;
pusch_grant->tb[0].mcs = dci_ul->mcs;
// 5.1.6.2 DM-RS reception procedure // 5.1.6.2 DM-RS reception procedure
if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSRAN_SUCCESS) { if (ra_ul_dmrs(pusch_hl_cfg, pusch_grant, pusch_cfg) < SRSRAN_SUCCESS) {

@ -13,6 +13,7 @@
#ifndef SRSRAN_STATE_H #ifndef SRSRAN_STATE_H
#define SRSRAN_STATE_H #define SRSRAN_STATE_H
#include "../phy_metrics.h"
#include "srsran/adt/circular_array.h" #include "srsran/adt/circular_array.h"
#include "srsran/common/common.h" #include "srsran/common/common.h"
#include "srsran/interfaces/ue_nr_interfaces.h" #include "srsran/interfaces/ue_nr_interfaces.h"
@ -47,9 +48,27 @@ private:
srsran::circular_array<srsran_pdsch_ack_nr_t, TTIMOD_SZ> pending_ack = {}; srsran::circular_array<srsran_pdsch_ack_nr_t, TTIMOD_SZ> pending_ack = {};
mutable std::mutex pending_ack_mutex; mutable std::mutex pending_ack_mutex;
info_metrics_t info_metrics = {};
sync_metrics_t sync_metrics = {};
ch_metrics_t ch_metrics = {};
dl_metrics_t dl_metrics = {};
ul_metrics_t ul_metrics = {};
mutable std::mutex metrics_mutex;
/// CSI-RS measurements /// CSI-RS measurements
std::array<srsran_csi_measurements_t, SRSRAN_CSI_MAX_NOF_RESOURCES> csi_measurements = {}; std::array<srsran_csi_measurements_t, SRSRAN_CSI_MAX_NOF_RESOURCES> csi_measurements = {};
/**
* @brief Resets all metrics (unprotected)
*/
void reset_metrics_()
{
sync_metrics.reset();
ch_metrics.reset();
dl_metrics.reset();
ul_metrics.reset();
}
public: public:
mac_interface_phy_nr* stack = nullptr; mac_interface_phy_nr* stack = nullptr;
srsran_carrier_nr_t carrier = {}; srsran_carrier_nr_t carrier = {};
@ -71,6 +90,8 @@ public:
carrier.nof_prb = 100; carrier.nof_prb = 100;
carrier.max_mimo_layers = 1; carrier.max_mimo_layers = 1;
info_metrics.pci = carrier.id;
// Hard-coded values, this should be set when the measurements take place // Hard-coded values, this should be set when the measurements take place
csi_measurements[0].K_csi_rs = 1; csi_measurements[0].K_csi_rs = 1;
csi_measurements[0].nof_ports = 1; csi_measurements[0].nof_ports = 1;
@ -257,7 +278,11 @@ public:
return true; return true;
} }
void reset() { clear_pending_grants(); } void reset()
{
clear_pending_grants();
reset_metrics();
}
bool has_valid_sr_resource(uint32_t sr_id) bool has_valid_sr_resource(uint32_t sr_id)
{ {
@ -323,6 +348,85 @@ public:
uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id; uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(tti).id;
} }
/**
* @brief Sets time and frequency synchronization metrics
* @param m Metrics object
*/
void set_info_metrics(const info_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
info_metrics = m;
}
/**
* @brief Sets time and frequency synchronization metrics
* @param m Metrics object
*/
void set_sync_metrics(const sync_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
sync_metrics.set(m);
}
/**
* @brief Sets DL channel metrics from received CSI-RS resources
* @param m Metrics object
*/
void set_channel_metrics(const ch_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
ch_metrics.set(m);
}
/**
* @brief Sets DL metrics of a given PDSCH transmission
* @param m Metrics object
*/
void set_dl_metrics(const dl_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
dl_metrics.set(m);
}
/**
* @brief Sets UL metrics of a given PUSCH transmission
* @param m Metrics object
*/
void set_ul_metrics(const ul_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
ul_metrics.set(m);
}
/**
* @brief Resets all metrics (protected)
*/
void reset_metrics()
{
std::lock_guard<std::mutex> lock(metrics_mutex);
reset_metrics_();
}
/**
* @brief Appends the NR PHY metrics to the general metric hub
* @param m PHY Metrics object
*/
void get_metrics(phy_metrics_t& m)
{
std::lock_guard<std::mutex> lock(metrics_mutex);
uint32_t cc = m.nof_active_cc;
m.info[cc] = info_metrics;
m.sync[cc] = sync_metrics;
m.ch[cc] = ch_metrics;
m.dl[cc] = dl_metrics;
m.ul[cc] = ul_metrics;
m.nof_active_cc++;
// Reset all metrics
reset_metrics_();
}
}; };
} // namespace nr } // namespace nr
} // namespace srsue } // namespace srsue

@ -42,6 +42,7 @@ public:
bool set_config(const srsran::phy_cfg_nr_t& cfg); bool set_config(const srsran::phy_cfg_nr_t& cfg);
bool has_valid_sr_resource(uint32_t sr_id); bool has_valid_sr_resource(uint32_t sr_id);
void clear_pending_grants(); void clear_pending_grants();
void get_metrics(phy_metrics_t& m);
}; };
} // namespace nr } // namespace nr

@ -136,16 +136,16 @@ public:
srsran::radio_interface_phy* get_radio(); srsran::radio_interface_phy* get_radio();
void set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m); void set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m);
void get_dl_metrics(dl_metrics_t m[SRSRAN_MAX_CARRIERS]); void get_dl_metrics(dl_metrics_t::array_t& m);
void set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m); void set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m);
void get_ch_metrics(ch_metrics_t m[SRSRAN_MAX_CARRIERS]); void get_ch_metrics(ch_metrics_t::array_t& m);
void set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m); void set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m);
void get_ul_metrics(ul_metrics_t m[SRSRAN_MAX_CARRIERS]); void get_ul_metrics(ul_metrics_t::array_t& m);
void set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m); void set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m);
void get_sync_metrics(sync_metrics_t m[SRSRAN_MAX_CARRIERS]); void get_sync_metrics(sync_metrics_t::array_t& m);
void reset(); void reset();
void reset_radio(); void reset_radio();
@ -302,14 +302,10 @@ private:
std::mutex metrics_mutex; std::mutex metrics_mutex;
ch_metrics_t ch_metrics[SRSRAN_MAX_CARRIERS] = {}; ch_metrics_t::array_t ch_metrics = {};
uint32_t ch_metrics_count[SRSRAN_MAX_CARRIERS] = {}; dl_metrics_t::array_t dl_metrics = {};
dl_metrics_t dl_metrics[SRSRAN_MAX_CARRIERS] = {}; ul_metrics_t::array_t ul_metrics = {};
uint32_t dl_metrics_count[SRSRAN_MAX_CARRIERS] = {}; sync_metrics_t::array_t sync_metrics = {};
ul_metrics_t ul_metrics[SRSRAN_MAX_CARRIERS] = {};
uint32_t ul_metrics_count[SRSRAN_MAX_CARRIERS] = {};
sync_metrics_t sync_metrics[SRSRAN_MAX_CARRIERS] = {};
uint32_t sync_metrics_count[SRSRAN_MAX_CARRIERS] = {};
// MBSFN // MBSFN
bool sib13_configured = false; bool sib13_configured = false;

@ -14,23 +14,58 @@
#define SRSUE_PHY_METRICS_H #define SRSUE_PHY_METRICS_H
#include "srsran/srsran.h" #include "srsran/srsran.h"
#include <srsran/adt/circular_array.h>
namespace srsue { namespace srsue {
struct info_metrics_t { struct info_metrics_t {
typedef srsran::circular_array<info_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
uint32_t pci; uint32_t pci;
uint32_t dl_earfcn; uint32_t dl_earfcn;
}; };
#define PHY_METRICS_SET(PARAM) \
do { \
PARAM = PARAM + (other.PARAM - PARAM) / count; \
} while (false)
struct sync_metrics_t { struct sync_metrics_t {
typedef srsran::circular_array<sync_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float ta_us; float ta_us;
float distance_km; float distance_km;
float speed_kmph; float speed_kmph;
float cfo; float cfo;
float sfo; float sfo;
void set(const sync_metrics_t& other)
{
count++;
ta_us = other.ta_us;
distance_km = other.distance_km;
speed_kmph = other.speed_kmph;
PHY_METRICS_SET(cfo);
PHY_METRICS_SET(sfo);
}
void reset()
{
count = 0;
ta_us = 0.0f;
distance_km = 0.0f;
speed_kmph = 0.0f;
cfo = 0.0f;
sfo = 0.0f;
}
private:
uint32_t count = 0;
}; };
struct ch_metrics_t { struct ch_metrics_t {
typedef srsran::circular_array<ch_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float n; float n;
float sinr; float sinr;
float rsrp; float rsrp;
@ -39,25 +74,97 @@ struct ch_metrics_t {
float ri; float ri;
float pathloss; float pathloss;
float sync_err; float sync_err;
void set(const ch_metrics_t& other)
{
count++;
PHY_METRICS_SET(n);
PHY_METRICS_SET(sinr);
PHY_METRICS_SET(rsrp);
PHY_METRICS_SET(rsrq);
PHY_METRICS_SET(rssi);
PHY_METRICS_SET(ri);
PHY_METRICS_SET(pathloss);
PHY_METRICS_SET(sync_err);
}
void reset()
{
count = 0;
n = 0.0;
sinr = 0.0;
rsrp = 0.0;
rsrq = 0.0;
rssi = 0.0;
ri = 0.0;
pathloss = 0.0;
sync_err = 0.0;
}
private:
uint32_t count = 0;
}; };
struct dl_metrics_t { struct dl_metrics_t {
float turbo_iters; typedef srsran::circular_array<dl_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float fec_iters;
float mcs; float mcs;
float evm;
void set(const dl_metrics_t& other)
{
count++;
PHY_METRICS_SET(fec_iters);
PHY_METRICS_SET(mcs);
PHY_METRICS_SET(evm);
}
void reset()
{
count = 0;
fec_iters = 0.0f;
mcs = 0.0f;
evm = 0.0f;
}
private:
uint32_t count = 0;
}; };
struct ul_metrics_t { struct ul_metrics_t {
typedef srsran::circular_array<ul_metrics_t, SRSRAN_MAX_CARRIERS> array_t;
float mcs; float mcs;
float power; float power;
void set(const ul_metrics_t& other)
{
count++;
PHY_METRICS_SET(mcs);
PHY_METRICS_SET(power);
}
void reset()
{
count = 0;
mcs = 0.0f;
power = 0.0f;
}
private:
uint32_t count = 0;
}; };
#undef PHY_METRICS_SET
struct phy_metrics_t { struct phy_metrics_t {
info_metrics_t info[SRSRAN_MAX_CARRIERS]; info_metrics_t::array_t info = {};
sync_metrics_t sync[SRSRAN_MAX_CARRIERS]; sync_metrics_t::array_t sync = {};
ch_metrics_t ch[SRSRAN_MAX_CARRIERS]; ch_metrics_t::array_t ch = {};
dl_metrics_t dl[SRSRAN_MAX_CARRIERS]; dl_metrics_t::array_t dl = {};
ul_metrics_t ul[SRSRAN_MAX_CARRIERS]; ul_metrics_t::array_t ul = {};
uint32_t nof_active_cc; uint32_t nof_active_cc = 0;
}; };
} // namespace srsue } // namespace srsue

@ -40,7 +40,6 @@ typedef struct {
typedef struct { typedef struct {
srsran::rf_metrics_t rf; srsran::rf_metrics_t rf;
phy_metrics_t phy; phy_metrics_t phy;
phy_metrics_t phy_nr;
gw_metrics_t gw; gw_metrics_t gw;
stack_metrics_t stack; stack_metrics_t stack;
srsran::sys_metrics_t sys; srsran::sys_metrics_t sys;

@ -70,7 +70,7 @@ void metrics_csv::set_metrics_helper(const srsran::rf_metrics_t rf,
const phy_metrics_t phy, const phy_metrics_t phy,
const mac_metrics_t mac[SRSRAN_MAX_CARRIERS], const mac_metrics_t mac[SRSRAN_MAX_CARRIERS],
const rrc_metrics_t rrc, const rrc_metrics_t rrc,
const uint32_t cc, const uint32_t cc,
const uint32_t r) const uint32_t r)
{ {
if (not file.is_open()) { if (not file.is_open()) {
@ -108,7 +108,7 @@ void metrics_csv::set_metrics_helper(const srsran::rf_metrics_t rf,
file << float_to_string(phy.dl[r].mcs, 2); file << float_to_string(phy.dl[r].mcs, 2);
file << float_to_string(phy.ch[r].sinr, 2); file << float_to_string(phy.ch[r].sinr, 2);
file << float_to_string(phy.dl[r].turbo_iters, 2); file << float_to_string(phy.dl[r].fec_iters, 2);
if (mac[r].rx_brate > 0) { if (mac[r].rx_brate > 0) {
file << float_to_string(mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2); file << float_to_string(mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2);
@ -191,16 +191,16 @@ void metrics_csv::set_metrics(const ue_metrics_t& metrics, const uint32_t period
file << "\n"; file << "\n";
} }
// Metrics for LTE carrier // Metrics for LTE carrier
for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) { for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) {
set_metrics_helper(metrics.rf, metrics.sys, metrics.phy, metrics.stack.mac, metrics.stack.rrc, r, r); set_metrics_helper(metrics.rf, metrics.sys, metrics.phy, metrics.stack.mac, metrics.stack.rrc, r, r);
} }
// Metrics for NR carrier // Metrics for NR carrier
for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) { for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) {
set_metrics_helper(metrics.rf, set_metrics_helper(metrics.rf,
metrics.sys, metrics.sys,
metrics.phy_nr, metrics.phy,
metrics.stack.mac_nr, metrics.stack.mac_nr,
metrics.stack.rrc, metrics.stack.rrc,
metrics.phy.nof_active_cc + r, // NR carrier offset metrics.phy.nof_active_cc + r, // NR carrier offset

@ -110,7 +110,7 @@ void metrics_stdout::set_metrics_helper(const phy_metrics_t phy,
cout << float_to_string(phy.dl[r].mcs, 2); cout << float_to_string(phy.dl[r].mcs, 2);
cout << float_to_string(phy.ch[r].sinr, 2); cout << float_to_string(phy.ch[r].sinr, 2);
cout << float_to_string(phy.dl[r].turbo_iters, 2); cout << float_to_string(phy.dl[r].fec_iters, 2);
cout << float_to_eng_string((float)mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2); cout << float_to_eng_string((float)mac[r].rx_brate / (mac[r].nof_tti * 1e-3), 2);
if (mac[r].rx_pkts > 0) { if (mac[r].rx_pkts > 0) {
@ -174,12 +174,6 @@ void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t per
set_metrics_helper(metrics.phy, metrics.stack.mac, metrics.stack.rrc, display_neighbours, r); set_metrics_helper(metrics.phy, metrics.stack.mac, metrics.stack.rrc, display_neighbours, r);
} }
for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) {
// Assumption LTE is followed by the NR carriers.
cout << std::setw(2) << metrics.phy.nof_active_cc + r;
set_metrics_helper(metrics.phy_nr, metrics.stack.mac_nr, metrics.stack.rrc, display_neighbours, r);
}
if (metrics.rf.rf_error) { if (metrics.rf.rf_error) {
printf("RF status: O=%d, U=%d, L=%d\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); printf("RF status: O=%d, U=%d, L=%d\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l);
} }

@ -473,7 +473,7 @@ int cc_worker::decode_pdsch(srsran_pdsch_ack_resource_t ack_resource,
} else { } else {
dl_metrics.mcs = (ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx + ue_dl_cfg.cfg.pdsch.grant.tb[1].mcs_idx) / 2; dl_metrics.mcs = (ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx + ue_dl_cfg.cfg.pdsch.grant.tb[1].mcs_idx) / 2;
} }
dl_metrics.turbo_iters = pdsch_dec->avg_iterations_block / 2; dl_metrics.fec_iters = pdsch_dec->avg_iterations_block / 2;
phy->set_dl_metrics(cc_idx, dl_metrics); phy->set_dl_metrics(cc_idx, dl_metrics);
// Logging // Logging
@ -507,7 +507,7 @@ int cc_worker::decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srsran
// Metrics // Metrics
dl_metrics_t dl_metrics = {}; dl_metrics_t dl_metrics = {};
dl_metrics.mcs = ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx; dl_metrics.mcs = ue_dl_cfg.cfg.pdsch.grant.tb[0].mcs_idx;
dl_metrics.turbo_iters = pmch_dec.avg_iterations_block / 2; dl_metrics.fec_iters = pmch_dec.avg_iterations_block / 2;
phy->set_dl_metrics(cc_idx, dl_metrics); phy->set_dl_metrics(cc_idx, dl_metrics);
Info("PMCH: l_crb=%2d, tbs=%d, mcs=%d, crc=%s, snr=%.1f dB, n_iter=%.1f", Info("PMCH: l_crb=%2d, tbs=%d, mcs=%d, crc=%s, snr=%.1f dB, n_iter=%.1f",

@ -307,7 +307,7 @@ int sf_worker::read_pdsch_d(cf_t* pdsch_d)
float sf_worker::get_cfo() float sf_worker::get_cfo()
{ {
sync_metrics_t sync_metrics[SRSRAN_MAX_CARRIERS] = {}; sync_metrics_t::array_t sync_metrics = {};
phy->get_sync_metrics(sync_metrics); phy->get_sync_metrics(sync_metrics);
return sync_metrics[0].cfo; return sync_metrics[0].cfo;
} }

@ -290,6 +290,26 @@ bool cc_worker::work_dl()
// Send data to MAC // Send data to MAC
phy->stack->tb_decoded(cc_idx, mac_nr_grant); phy->stack->tb_decoded(cc_idx, mac_nr_grant);
// Generate DL metrics
dl_metrics_t dl_m = {};
dl_m.mcs = pdsch_cfg.grant.tb[0].mcs;
dl_m.fec_iters = pdsch_res[0].fec_iters;
dl_m.evm = pdsch_res[0].evm;
phy->set_dl_metrics(dl_m);
// Generate Synch metrics
sync_metrics_t sync_m = {};
sync_m.cfo = ue_dl.chest.cfo;
phy->set_sync_metrics(sync_m);
// Generate channel metrics
ch_metrics_t ch_m = {};
ch_m.n = ue_dl.chest.noise_estimate;
ch_m.sinr = ue_dl.chest.snr_db;
ch_m.rsrp = ue_dl.chest.rsrp_dbm;
ch_m.sync_err = ue_dl.chest.sync_error;
phy->set_channel_metrics(ch_m);
} }
} }
@ -377,6 +397,13 @@ bool cc_worker::work_ul()
str.data(), str.data(),
ul_slot_cfg.idx); ul_slot_cfg.idx);
} }
// Set metrics
ul_metrics_t ul_m = {};
ul_m.mcs = pusch_cfg.grant.tb[0].mcs;
ul_m.power = srsran_convert_power_to_dB(srsran_vec_avg_power_cf(tx_buffer[0], ue_ul.ifft.sf_sz));
phy->set_ul_metrics(ul_m);
} else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) { } else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) {
// Get PUCCH resource // Get PUCCH resource
srsran_pucch_nr_resource_t resource = {}; srsran_pucch_nr_resource_t resource = {};

@ -155,5 +155,10 @@ void worker_pool::clear_pending_grants()
phy_state.clear_pending_grants(); phy_state.clear_pending_grants();
} }
void worker_pool::get_metrics(phy_metrics_t& m)
{
phy_state.get_metrics(m);
}
} // namespace nr } // namespace nr
} // namespace srsue } // namespace srsue

@ -202,6 +202,11 @@ void phy::get_metrics(phy_metrics_t* m)
common.get_ul_metrics(m->ul); common.get_ul_metrics(m->ul);
common.get_sync_metrics(m->sync); common.get_sync_metrics(m->sync);
m->nof_active_cc = args.nof_lte_carriers; m->nof_active_cc = args.nof_lte_carriers;
// Get NR metrics
if (args.nof_nr_carriers > 0) {
nr_workers.get_metrics(*m);
}
} }
void phy::set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) void phy::set_timeadv_rar(uint32_t tti, uint32_t ta_cmd)

@ -792,91 +792,64 @@ void phy_common::update_measurements(uint32_t cc_idx,
void phy_common::set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m) void phy_common::set_dl_metrics(uint32_t cc_idx, const dl_metrics_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
dl_metrics[cc_idx].set(m);
dl_metrics_count[cc_idx]++;
dl_metrics[cc_idx].mcs = dl_metrics[cc_idx].mcs + (m.mcs - dl_metrics[cc_idx].mcs) / dl_metrics_count[cc_idx];
dl_metrics[cc_idx].turbo_iters =
dl_metrics[cc_idx].turbo_iters + (m.turbo_iters - dl_metrics[cc_idx].turbo_iters) / dl_metrics_count[cc_idx];
} }
void phy_common::get_dl_metrics(dl_metrics_t m[SRSRAN_MAX_CARRIERS]) void phy_common::get_dl_metrics(dl_metrics_t::array_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { for (uint32_t i = 0; i < args->nof_lte_carriers; i++) {
m[i] = dl_metrics[i]; m[i] = dl_metrics[i];
dl_metrics[i] = {}; dl_metrics[i].reset();
dl_metrics_count[i] = 0;
} }
} }
void phy_common::set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m) void phy_common::set_ch_metrics(uint32_t cc_idx, const ch_metrics_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
ch_metrics[cc_idx].set(m);
ch_metrics_count[cc_idx]++;
ch_metrics[cc_idx].n = ch_metrics[cc_idx].n + (m.n - ch_metrics[cc_idx].n) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].rsrq = ch_metrics[cc_idx].rsrq + (m.rsrq - ch_metrics[cc_idx].rsrq) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].rssi = ch_metrics[cc_idx].rssi + (m.rssi - ch_metrics[cc_idx].rssi) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].rsrp = ch_metrics[cc_idx].rsrp + (m.rsrp - ch_metrics[cc_idx].rsrp) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].sinr = ch_metrics[cc_idx].sinr + (m.sinr - ch_metrics[cc_idx].sinr) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].sync_err =
ch_metrics[cc_idx].sync_err + (m.sync_err - ch_metrics[cc_idx].sync_err) / ch_metrics_count[cc_idx];
ch_metrics[cc_idx].pathloss =
ch_metrics[cc_idx].pathloss + (m.pathloss - ch_metrics[cc_idx].pathloss) / ch_metrics_count[cc_idx];
} }
void phy_common::get_ch_metrics(ch_metrics_t m[SRSRAN_MAX_CARRIERS]) void phy_common::get_ch_metrics(ch_metrics_t::array_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { for (uint32_t i = 0; i < args->nof_lte_carriers; i++) {
m[i] = ch_metrics[i]; m[i] = ch_metrics[i];
ch_metrics[i] = {}; ch_metrics[i].reset();
ch_metrics_count[i] = 0;
} }
} }
void phy_common::set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m) void phy_common::set_ul_metrics(uint32_t cc_idx, const ul_metrics_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
ul_metrics[cc_idx].set(m);
ul_metrics_count[cc_idx]++;
ul_metrics[cc_idx].mcs = ul_metrics[cc_idx].mcs + (m.mcs - ul_metrics[cc_idx].mcs) / ul_metrics_count[cc_idx];
ul_metrics[cc_idx].power = ul_metrics[cc_idx].power + (m.power - ul_metrics[cc_idx].power) / ul_metrics_count[cc_idx];
} }
void phy_common::get_ul_metrics(ul_metrics_t m[SRSRAN_MAX_CARRIERS]) void phy_common::get_ul_metrics(ul_metrics_t::array_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { for (uint32_t i = 0; i < args->nof_lte_carriers; i++) {
m[i] = ul_metrics[i]; m[i] = ul_metrics[i];
ul_metrics[i] = {}; ul_metrics[i].reset();
ul_metrics_count[i] = 0;
} }
} }
void phy_common::set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m) void phy_common::set_sync_metrics(const uint32_t& cc_idx, const sync_metrics_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
sync_metrics[cc_idx].set(m);
sync_metrics_count[cc_idx]++;
sync_metrics[cc_idx].cfo = sync_metrics[cc_idx].cfo + (m.cfo - sync_metrics[cc_idx].cfo) / sync_metrics_count[cc_idx];
sync_metrics[cc_idx].sfo = sync_metrics[cc_idx].sfo + (m.sfo - sync_metrics[cc_idx].sfo) / sync_metrics_count[cc_idx];
sync_metrics[cc_idx].ta_us = m.ta_us;
sync_metrics[cc_idx].distance_km = m.distance_km;
sync_metrics[cc_idx].speed_kmph = m.speed_kmph;
} }
void phy_common::get_sync_metrics(sync_metrics_t m[SRSRAN_MAX_CARRIERS]) void phy_common::get_sync_metrics(sync_metrics_t::array_t& m)
{ {
std::unique_lock<std::mutex> lock(metrics_mutex); std::unique_lock<std::mutex> lock(metrics_mutex);
for (uint32_t i = 0; i < args->nof_lte_carriers; i++) { for (uint32_t i = 0; i < args->nof_lte_carriers; i++) {
m[i] = sync_metrics[i]; m[i] = sync_metrics[i];
sync_metrics[i] = {}; sync_metrics[i].reset();
sync_metrics_count[i] = 0;
} }
} }

@ -335,7 +335,6 @@ bool ue::get_metrics(ue_metrics_t* m)
stack->get_metrics(&m->stack); stack->get_metrics(&m->stack);
gw_inst->get_metrics(m->gw, m->stack.mac[0].nof_tti); gw_inst->get_metrics(m->gw, m->stack.mac[0].nof_tti);
m->sys = sys_proc.get_metrics(); m->sys = sys_proc.get_metrics();
m->phy_nr.nof_active_cc = args.phy.nof_nr_carriers; // FIXME: temporary until PHY metrics are complete
return true; return true;
} }

@ -54,15 +54,15 @@ public:
// random neighbour cells // random neighbour cells
if (rand() % 2 == 0) { if (rand() % 2 == 0) {
phy_meas_t neighbor = {}; phy_meas_t neighbor = {};
neighbor.pci = 8; neighbor.pci = 8;
neighbor.rsrp = -33; neighbor.rsrp = -33;
m->stack.rrc.neighbour_cells.push_back(neighbor); m->stack.rrc.neighbour_cells.push_back(neighbor);
m->stack.rrc.neighbour_cells.push_back(neighbor); // need to add twice since we use CA m->stack.rrc.neighbour_cells.push_back(neighbor); // need to add twice since we use CA
} }
m->phy_nr.nof_active_cc = 1; m->phy.nof_active_cc = 1;
m->phy_nr.ch[0].rsrp = -10.0f; m->phy.ch[0].rsrp = -10.0f;
m->phy_nr.ch[0].pathloss = 32; m->phy.ch[0].pathloss = 32;
m->stack.mac_nr[0].rx_pkts = 100; m->stack.mac_nr[0].rx_pkts = 100;
m->stack.mac_nr[0].rx_errors = 2; m->stack.mac_nr[0].rx_errors = 2;
m->stack.mac_nr[0].rx_brate = 223; m->stack.mac_nr[0].rx_brate = 223;

Loading…
Cancel
Save