SRSENB/UE: Added NR workers

master
Xavier Arteaga 4 years ago committed by Andre Puschmann
parent ac930003be
commit b501f2eeaf

@ -489,6 +489,7 @@ typedef struct {
uint32_t nof_lte_carriers = 1; uint32_t nof_lte_carriers = 1;
uint32_t nof_nr_carriers = 0; uint32_t nof_nr_carriers = 0;
uint32_t nr_nof_prb = 50; uint32_t nr_nof_prb = 50;
double nr_freq_hz = 2630e6;
uint32_t nof_rx_ant = 1; uint32_t nof_rx_ant = 1;
std::string equalizer_mode = "mmse"; std::string equalizer_mode = "mmse";
int cqi_max = 15; int cqi_max = 15;

@ -53,6 +53,12 @@ SRSLTE_API int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q,
const srslte_pdsch_grant_nr_t* grant, const srslte_pdsch_grant_nr_t* grant,
uint8_t* data[SRSLTE_MAX_TB]); uint8_t* data[SRSLTE_MAX_TB]);
SRSLTE_API int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
char* str,
uint32_t str_len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -149,3 +149,17 @@ int srslte_enb_dl_nr_pdsch_put(srslte_enb_dl_nr_t* q,
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
int srslte_enb_dl_nr_pdsch_info(const srslte_enb_dl_nr_t* q,
const srslte_pdsch_cfg_nr_t* cfg,
const srslte_pdsch_grant_nr_t* grant,
char* str,
uint32_t str_len)
{
int len = 0;
// Append PDSCH info
len += srslte_pdsch_nr_tx_info(&q->pdsch, cfg, grant, &str[len], str_len - len);
return len;
}

@ -49,9 +49,10 @@ public:
phy_nr_state() phy_nr_state()
{ {
args.nof_carriers = 1; args.nof_carriers = 1;
args.max_prb = SRSLTE_MAX_PRB; args.max_prb = 100;
args.dl.nof_tx_antennas = 1; args.dl.nof_tx_antennas = 1;
args.dl.pdsch.measure_evm = true; args.dl.pdsch.measure_evm = true;
args.dl.pdsch.measure_time = true;
args.dl.pdsch.sch.disable_simd = true; args.dl.pdsch.sch.disable_simd = true;
} }
}; };
@ -74,10 +75,11 @@ public:
private: private:
srslte_dl_slot_cfg_t dl_slot_cfg = {}; srslte_dl_slot_cfg_t dl_slot_cfg = {};
uint32_t cc_idx = 0; uint32_t cc_idx = 0;
std::array<std::vector<cf_t>, SRSLTE_MAX_PORTS> tx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> tx_buffer = {};
std::array<std::vector<cf_t>, SRSLTE_MAX_PORTS> rx_buffer = {}; std::array<cf_t*, SRSLTE_MAX_PORTS> rx_buffer = {};
phy_nr_state* phy_state; phy_nr_state* phy_state;
srslte_enb_dl_nr_t enb_dl = {}; srslte_enb_dl_nr_t enb_dl = {};
srslte::log* log_h = nullptr;
// Temporal attributes // Temporal attributes
srslte_softbuffer_tx_t softbuffer_tx = {}; srslte_softbuffer_tx_t softbuffer_tx = {};

@ -81,6 +81,7 @@ private:
std::unique_ptr<srslte::log_filter> log_phy_lib_h = nullptr; std::unique_ptr<srslte::log_filter> log_phy_lib_h = nullptr;
lte::worker_pool lte_workers; lte::worker_pool lte_workers;
nr::worker_pool nr_workers;
phy_common workers_common; phy_common workers_common;
prach_worker_pool prach; prach_worker_pool prach;
txrx tx_rx; txrx tx_rx;

@ -54,8 +54,9 @@ public:
* @param tx_sem_id Semaphore identifier, the worker thread pointer is used * @param tx_sem_id Semaphore identifier, the worker thread pointer is used
* @param buffer baseband IQ sample buffer * @param buffer baseband IQ sample buffer
* @param tx_time timestamp to transmit samples * @param tx_time timestamp to transmit samples
* @param is_nr flag is true if it is called from NR
*/ */
void worker_end(void* tx_sem_id, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time); void worker_end(void* tx_sem_id, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time, bool is_nr = false);
// Common objects // Common objects
phy_args_t params = {}; phy_args_t params = {};
@ -92,7 +93,7 @@ public:
} }
for (auto& cell : cell_list_nr) { for (auto& cell : cell_list_nr) {
count += cell.cell.max_mimo_layers; count += cell.carrier.max_mimo_layers;
} }
return count; return count;
@ -153,13 +154,8 @@ public:
srslte_carrier_nr_t get_cell_nr(uint32_t cc_idx) srslte_carrier_nr_t get_cell_nr(uint32_t cc_idx)
{ {
srslte_carrier_nr_t c = {}; srslte_carrier_nr_t c = {};
if (cc_idx < cell_list_lte.size()) {
return c;
}
cc_idx -= cell_list_lte.size();
if (cc_idx < cell_list_nr.size()) { if (cc_idx < cell_list_nr.size()) {
c = cell_list_nr[cc_idx].cell; c = cell_list_nr[cc_idx].carrier;
} }
return c; return c;
@ -246,6 +242,8 @@ private:
uint32_t mch_period_stop = 0; uint32_t mch_period_stop = 0;
bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); bool is_mch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);
bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti); bool is_mcch_subframe(srslte_mbsfn_cfg_t* cfg, uint32_t phy_tti);
srslte::rf_buffer_t nr_tx_buffer;
bool nr_tx_buffer_ready = false;
}; };
} // namespace srsenb } // namespace srsenb

@ -34,7 +34,7 @@ struct phy_cell_cfg_t {
}; };
struct phy_cell_cfg_nr_t { struct phy_cell_cfg_nr_t {
srslte_carrier_nr_t cell; srslte_carrier_nr_t carrier;
uint32_t rf_port; uint32_t rf_port;
uint32_t cell_id; uint32_t cell_id;
double dl_freq_hz; double dl_freq_hz;

@ -30,7 +30,8 @@ public:
txrx(); txrx();
bool init(stack_interface_phy_lte* stack_, bool init(stack_interface_phy_lte* stack_,
srslte::radio_interface_phy* radio_handler, srslte::radio_interface_phy* radio_handler,
lte::worker_pool* _workers_pool, lte::worker_pool* lte_workers_,
nr::worker_pool* nr_workers_,
phy_common* worker_com, phy_common* worker_com,
prach_worker_pool* prach_, prach_worker_pool* prach_,
srslte::log* log_h, srslte::log* log_h,

@ -59,6 +59,7 @@ struct rrc_cfg_t {
bool meas_cfg_present = false; bool meas_cfg_present = false;
srslte_cell_t cell; srslte_cell_t cell;
cell_list_t cell_list; cell_list_t cell_list;
cell_list_t cell_list_nr;
}; };
constexpr uint32_t UE_PCELL_CC_IDX = 0; constexpr uint32_t UE_PCELL_CC_IDX = 0;

@ -719,9 +719,8 @@ static int parse_scell_list(cell_cfg_t& cell_cfg, Setting& cellroot)
static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
{ {
rrc_cfg->cell_list.resize(root.getLength()); for (uint32_t n = 0; n < (uint32_t)root.getLength(); ++n) {
for (uint32_t n = 0; n < rrc_cfg->cell_list.size(); ++n) { cell_cfg_t cell_cfg = {};
cell_cfg_t& cell_cfg = rrc_cfg->cell_list[n];
auto& cellroot = root[n]; auto& cellroot = root[n];
parse_opt_field(cell_cfg.rf_port, cellroot, "rf_port"); parse_opt_field(cell_cfg.rf_port, cellroot, "rf_port");
@ -744,6 +743,16 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root)
if (cellroot.exists("scell_list")) { if (cellroot.exists("scell_list")) {
parse_scell_list(cell_cfg, cellroot); parse_scell_list(cell_cfg, cellroot);
} }
std::string type = "lte";
if (cellroot.exists("type")) {
cellroot.lookupValue("type", type);
}
if (type == "lte") {
rrc_cfg->cell_list.push_back(cell_cfg);
} else if (type == "nr") {
rrc_cfg->cell_list_nr.push_back(cell_cfg);
}
} }
// Configuration check // Configuration check
@ -961,6 +970,37 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
phy_cfg_->phy_cell_cfg.push_back(phy_cell_cfg); phy_cfg_->phy_cell_cfg.push_back(phy_cell_cfg);
} }
// Create NR dedicated cell configuration from RRC configuration
for (auto it = rrc_cfg_->cell_list_nr.begin(); it != rrc_cfg_->cell_list_nr.end(); ++it) {
auto& cfg = *it;
phy_cell_cfg_nr_t phy_cell_cfg = {};
phy_cell_cfg.carrier.max_mimo_layers = cell_cfg_.nof_ports;
phy_cell_cfg.carrier.nof_prb = cell_cfg_.nof_prb;
phy_cell_cfg.carrier.id = cfg.pci;
phy_cell_cfg.cell_id = cfg.cell_id;
phy_cell_cfg.root_seq_idx = cfg.root_seq_idx;
phy_cell_cfg.rf_port = cfg.rf_port;
phy_cell_cfg.num_ra_preambles =
rrc_cfg_->sibs[1].sib2().rr_cfg_common.rach_cfg_common.preamb_info.nof_ra_preambs.to_number();
if (cfg.dl_freq_hz > 0) {
phy_cell_cfg.dl_freq_hz = cfg.dl_freq_hz;
} else {
phy_cell_cfg.dl_freq_hz = 1e6 * srslte_band_fd(cfg.dl_earfcn);
}
if (cfg.ul_freq_hz > 0) {
phy_cell_cfg.ul_freq_hz = cfg.ul_freq_hz;
} else {
if (cfg.ul_earfcn == 0) {
cfg.ul_earfcn = srslte_band_ul_earfcn(cfg.dl_earfcn);
}
phy_cell_cfg.ul_freq_hz = 1e6 * srslte_band_fu(cfg.ul_earfcn);
}
phy_cfg_->phy_cell_cfg_nr.push_back(phy_cell_cfg);
}
if (args_->enb.transmission_mode == 1) { if (args_->enb.transmission_mode == 1) {
phy_cfg_->pdsch_cnfg.p_b = 0; // Default TM1 phy_cfg_->pdsch_cnfg.p_b = 0; // Default TM1
rrc_cfg_->sibs[1].sib2().rr_cfg_common.pdsch_cfg_common.p_b = 0; rrc_cfg_->sibs[1].sib2().rr_cfg_common.pdsch_cfg_common.p_b = 0;
@ -1080,7 +1120,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
} }
// Patch certain args that are not exposed yet // Patch certain args that are not exposed yet
args_->rf.nof_carriers = rrc_cfg_->cell_list.size(); args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_cfg_->cell_list_nr.size();
args_->rf.nof_antennas = args_->enb.nof_ports; args_->rf.nof_antennas = args_->enb.nof_ports;
// MAC needs to know the cell bandwidth to dimension softbuffers // MAC needs to know the cell bandwidth to dimension softbuffers

@ -101,11 +101,11 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
srslte_vec_cf_zero(signal_buffer_tx[p], 2 * sf_len); srslte_vec_cf_zero(signal_buffer_tx[p], 2 * sf_len);
} }
if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, nof_prb)) { if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, nof_prb)) {
ERROR("Error initiating ENB DL\n"); ERROR("Error initiating ENB DL (cc=%d)\n", cc_idx);
return; return;
} }
if (srslte_enb_dl_set_cell(&enb_dl, cell)) { if (srslte_enb_dl_set_cell(&enb_dl, cell)) {
ERROR("Error initiating ENB DL\n"); ERROR("Error initiating ENB DL (cc=%d)\n", cc_idx);
return; return;
} }
if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], nof_prb)) { if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], nof_prb)) {

@ -70,7 +70,7 @@ void sf_worker::init(phy_common* phy_, srslte::log* log_h_)
log_h = log_h_; log_h = log_h_;
// Initialise each component carrier workers // Initialise each component carrier workers
for (uint32_t i = 0; i < phy->get_nof_carriers(); i++) { for (uint32_t i = 0; i < phy->get_nof_carriers_lte(); i++) {
// Create pointer // Create pointer
auto q = new cc_worker(); auto q = new cc_worker();
@ -164,7 +164,7 @@ void sf_worker::work_imp()
// Get Transmission buffers // Get Transmission buffers
srslte::rf_buffer_t tx_buffer = {}; srslte::rf_buffer_t tx_buffer = {};
for (uint32_t cc = 0; cc < phy->get_nof_carriers(); cc++) { for (uint32_t cc = 0; cc < phy->get_nof_carriers_lte(); cc++) {
for (uint32_t ant = 0; ant < phy->get_nof_ports(0); ant++) { for (uint32_t ant = 0; ant < phy->get_nof_ports(0); ant++) {
tx_buffer.set(cc, ant, phy->get_nof_ports(0), cc_workers[cc]->get_buffer_tx(ant)); tx_buffer.set(cc, ant, phy->get_nof_ports(0), cc_workers[cc]->get_buffer_tx(ant));
} }
@ -184,7 +184,7 @@ void sf_worker::work_imp()
stack_interface_phy_lte::ul_sched_list_t ul_grants_tx = phy->get_ul_grants(t_tx_ul); stack_interface_phy_lte::ul_sched_list_t ul_grants_tx = phy->get_ul_grants(t_tx_ul);
// Downlink grants to transmit this TTI // Downlink grants to transmit this TTI
stack_interface_phy_lte::dl_sched_list_t dl_grants(phy->get_nof_carriers()); stack_interface_phy_lte::dl_sched_list_t dl_grants(phy->get_nof_carriers_lte());
stack_interface_phy_lte* stack = phy->stack; stack_interface_phy_lte* stack = phy->stack;
@ -276,7 +276,7 @@ uint32_t sf_worker::get_metrics(std::vector<phy_metrics_t>& metrics)
{ {
uint32_t cnt = 0; uint32_t cnt = 0;
std::vector<phy_metrics_t> metrics_; std::vector<phy_metrics_t> metrics_;
for (uint32_t cc = 0; cc < phy->get_nof_carriers(); cc++) { for (uint32_t cc = 0; cc < phy->get_nof_carriers_lte(); cc++) {
cnt = cc_workers[cc]->get_metrics(metrics_); cnt = cc_workers[cc]->get_metrics(metrics_);
metrics.resize(std::max(metrics_.size(), metrics.size())); metrics.resize(std::max(metrics_.size(), metrics.size()));
for (uint32_t r = 0; r < cnt; r++) { for (uint32_t r = 0; r < cnt; r++) {
@ -312,7 +312,7 @@ void sf_worker::start_plot()
uint32_t sf_worker::get_nof_carriers() uint32_t sf_worker::get_nof_carriers()
{ {
return phy->get_nof_carriers(); return phy->get_nof_carriers_lte();
} }
int sf_worker::get_carrier_pci(uint32_t cc_idx) int sf_worker::get_carrier_pci(uint32_t cc_idx)
{ {

@ -27,15 +27,16 @@
namespace srsenb { namespace srsenb {
namespace nr { namespace nr {
cc_worker::cc_worker(uint32_t cc_idx_, srslte::log* log, phy_nr_state* phy_state_) : cc_worker::cc_worker(uint32_t cc_idx_, srslte::log* log, phy_nr_state* phy_state_) :
cc_idx(cc_idx_), phy_state(phy_state_) cc_idx(cc_idx_), phy_state(phy_state_), log_h(log)
{ {
cf_t* buffer_c[SRSLTE_MAX_PORTS] = {}; cf_t* buffer_c[SRSLTE_MAX_PORTS] = {};
// Allocate buffers // Allocate buffers
for (uint32_t i = 0; phy_state_->args.dl.nof_tx_antennas; i++) { uint32_t sf_len = SRSLTE_SF_LEN_PRB(phy_state->args.max_prb);
tx_buffer[i].resize(SRSLTE_SF_LEN_PRB(phy_state->args.max_prb)); for (uint32_t i = 0; i < phy_state_->args.dl.nof_tx_antennas; i++) {
rx_buffer[i].resize(SRSLTE_SF_LEN_PRB(phy_state->args.max_prb)); tx_buffer[i] = srslte_vec_cf_malloc(sf_len);
buffer_c[i] = tx_buffer[i].data(); rx_buffer[i] = srslte_vec_cf_malloc(sf_len);
buffer_c[i] = tx_buffer[i];
} }
if (srslte_enb_dl_nr_init(&enb_dl, buffer_c, &phy_state_->args.dl)) { if (srslte_enb_dl_nr_init(&enb_dl, buffer_c, &phy_state_->args.dl)) {
@ -60,6 +61,16 @@ cc_worker::~cc_worker()
{ {
srslte_enb_dl_nr_free(&enb_dl); srslte_enb_dl_nr_free(&enb_dl);
srslte_softbuffer_tx_free(&softbuffer_tx); srslte_softbuffer_tx_free(&softbuffer_tx);
for (cf_t* p : rx_buffer) {
if (p != nullptr) {
free(p);
}
}
for (cf_t* p : tx_buffer) {
if (p != nullptr) {
free(p);
}
}
} }
bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier) bool cc_worker::set_carrier(const srslte_carrier_nr_t* carrier)
@ -82,7 +93,7 @@ cf_t* cc_worker::get_tx_buffer(uint32_t antenna_idx)
return nullptr; return nullptr;
} }
return tx_buffer.at(antenna_idx).data(); return tx_buffer.at(antenna_idx);
} }
cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx) cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
@ -91,7 +102,7 @@ cf_t* cc_worker::get_rx_buffer(uint32_t antenna_idx)
return nullptr; return nullptr;
} }
return rx_buffer.at(antenna_idx).data(); return rx_buffer.at(antenna_idx);
} }
uint32_t cc_worker::get_buffer_len() uint32_t cc_worker::get_buffer_len()
@ -103,7 +114,6 @@ bool cc_worker::work_dl()
{ {
srslte_pdsch_grant_nr_t pdsch_grant = {}; srslte_pdsch_grant_nr_t pdsch_grant = {};
srslte_pdsch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch; srslte_pdsch_cfg_nr_t pdsch_cfg = phy_state->cfg.pdsch;
// Use grant default A time resources with m=0 // Use grant default A time resources with m=0
if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) < if (srslte_ue_dl_nr_pdsch_time_resource_default_A(0, pdsch_cfg.dmrs_cfg_typeA.typeA_pos, &pdsch_grant) <
SRSLTE_SUCCESS) { SRSLTE_SUCCESS) {
@ -112,12 +122,13 @@ bool cc_worker::work_dl()
} }
pdsch_grant.nof_layers = enb_dl.carrier.max_mimo_layers; pdsch_grant.nof_layers = enb_dl.carrier.max_mimo_layers;
pdsch_grant.dci_format = srslte_dci_format_nr_1_0; pdsch_grant.dci_format = srslte_dci_format_nr_1_0;
pdsch_grant.rnti = 0x1234;
for (uint32_t i = 0; i < enb_dl.carrier.nof_prb; i++) { for (uint32_t i = 0; i < enb_dl.carrier.nof_prb; i++) {
pdsch_grant.prb_idx[i] = true; pdsch_grant.prb_idx[i] = true;
} }
if (srslte_ra_nr_fill_tb(&pdsch_cfg, &pdsch_grant, 20, &pdsch_grant.tb[0]) < SRSLTE_SUCCESS) { if (srslte_ra_nr_fill_tb(&pdsch_cfg, &pdsch_grant, 27, &pdsch_grant.tb[0]) < SRSLTE_SUCCESS) {
ERROR("Error filing tb\n"); ERROR("Error filing tb\n");
return false; return false;
} }
@ -131,6 +142,13 @@ bool cc_worker::work_dl()
return false; return false;
} }
// Logging
if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) {
char str[512];
srslte_enb_dl_nr_pdsch_info(&enb_dl, &pdsch_cfg, &pdsch_grant, str, sizeof(str));
log_h->info("PDSCH: cc=%d, %s\n", cc_idx, str);
}
srslte_enb_dl_nr_gen_signal(&enb_dl); srslte_enb_dl_nr_gen_signal(&enb_dl);
return true; return true;

@ -73,10 +73,21 @@ void sf_worker::set_tti(uint32_t tti)
void sf_worker::work_imp() void sf_worker::work_imp()
{ {
// Get Transmission buffers
srslte::rf_buffer_t tx_buffer = {};
srslte::rf_timestamp_t dummy_ts = {};
for (uint32_t cc = 0; cc < phy->get_nof_carriers_nr(); cc++) {
for (uint32_t ant = 0; ant < phy->get_nof_ports(0); ant++) {
tx_buffer.set(cc, ant, phy->get_nof_ports(0), cc_workers[cc]->get_tx_buffer(ant));
}
}
for (auto& w : cc_workers) { for (auto& w : cc_workers) {
w->work_dl(); w->work_dl();
} }
phy->worker_end(this, tx_buffer, dummy_ts, true);
} }
}; // namespace nr } // namespace nr
}; // namespace srsenb } // namespace srsenb

@ -41,9 +41,12 @@ bool worker_pool::init(const phy_args_t& args, phy_common* common, srslte::logge
// Add workers to workers pool and start threads // Add workers to workers pool and start threads
for (uint32_t i = 0; i < args.nof_phy_threads; i++) { for (uint32_t i = 0; i < args.nof_phy_threads; i++) {
auto w = std::unique_ptr<sf_worker>(new sf_worker(common, &phy_state, (srslte::log*)log_vec[i].get())); auto w = new sf_worker(common, &phy_state, (srslte::log*)log_vec[i].get());
pool.init_worker(i, w.get(), prio); pool.init_worker(i, w, prio);
workers.push_back(std::move(w)); workers.push_back(std::unique_ptr<sf_worker>(w));
srslte_carrier_nr_t c = common->get_cell_nr(0);
w->set_carrier_unlocked(0, &c);
} }
return true; return true;
@ -69,5 +72,5 @@ void worker_pool::stop()
pool.stop(); pool.stop();
} }
}; // namespace nr } // namespace nr
}; // namespace srsenb } // namespace srsenb

@ -67,7 +67,9 @@ void phy::srslte_phy_logger(phy_logger_level_t log_level, char* str)
} }
} }
phy::phy(srslte::logger* logger_) : logger(logger_), lte_workers(MAX_WORKERS), workers_common(), nof_workers(0) {} phy::phy(srslte::logger* logger_) :
logger(logger_), lte_workers(MAX_WORKERS), nr_workers(MAX_WORKERS), workers_common(), nof_workers(0)
{}
phy::~phy() phy::~phy()
{ {
@ -125,6 +127,7 @@ int phy::init(const phy_args_t& args,
// Add workers to workers pool and start threads // Add workers to workers pool and start threads
lte_workers.init(args, &workers_common, logger, WORKERS_THREAD_PRIO); lte_workers.init(args, &workers_common, logger, WORKERS_THREAD_PRIO);
nr_workers.init(args, &workers_common, logger, WORKERS_THREAD_PRIO);
// For each carrier, initialise PRACH worker // For each carrier, initialise PRACH worker
for (uint32_t cc = 0; cc < cfg.phy_cell_cfg.size(); cc++) { for (uint32_t cc = 0; cc < cfg.phy_cell_cfg.size(); cc++) {
@ -134,7 +137,7 @@ int phy::init(const phy_args_t& args,
prach.set_max_prach_offset_us(args.max_prach_offset_us); prach.set_max_prach_offset_us(args.max_prach_offset_us);
// Warning this must be initialized after all workers have been added to the pool // Warning this must be initialized after all workers have been added to the pool
tx_rx.init(stack_, radio, &lte_workers, &workers_common, &prach, log_h.get(), SF_RECV_THREAD_PRIO); tx_rx.init(stack_, radio, &lte_workers, &nr_workers, &workers_common, &prach, log_h.get(), SF_RECV_THREAD_PRIO);
initialized = true; initialized = true;
@ -147,6 +150,7 @@ void phy::stop()
tx_rx.stop(); tx_rx.stop();
workers_common.stop(); workers_common.stop();
lte_workers.stop(); lte_workers.stop();
nr_workers.stop();
prach.stop(); prach.stop();
initialized = false; initialized = false;

@ -116,11 +116,29 @@ void phy_common::set_ul_grants(uint32_t tti, const stack_interface_phy_lte::ul_s
* Each worker uses this function to indicate that all processing is done and data is ready for transmission or * Each worker uses this function to indicate that all processing is done and data is ready for transmission or
* there is no transmission at all (tx_enable). In that case, the end of burst message will be sent to the radio * there is no transmission at all (tx_enable). In that case, the end of burst message will be sent to the radio
*/ */
void phy_common::worker_end(void* tx_sem_id, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time) void phy_common::worker_end(void* tx_sem_id, srslte::rf_buffer_t& buffer, srslte::rf_timestamp_t& tx_time, bool is_nr)
{ {
// Wait for the green light to transmit in the current TTI // Wait for the green light to transmit in the current TTI
semaphore.wait(tx_sem_id); semaphore.wait(tx_sem_id);
// If this is for NR, save Tx buffers...
if (is_nr) {
nr_tx_buffer = buffer;
nr_tx_buffer_ready = true;
semaphore.release();
return;
} else if (nr_tx_buffer_ready) {
// ... otherwise, append NR baseband from saved buffer if available
uint32_t j = 0;
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
if (buffer.get(i) == nullptr) {
buffer.set(i, nr_tx_buffer.get(j));
j++;
}
}
nr_tx_buffer_ready = false;
}
// Run DL channel emulator if created // Run DL channel emulator if created
if (dl_channel) { if (dl_channel) {
dl_channel->run(buffer.to_cf_t(), buffer.to_cf_t(), buffer.get_nof_samples(), tx_time.get(0)); dl_channel->run(buffer.to_cf_t(), buffer.to_cf_t(), buffer.get_nof_samples(), tx_time.get(0));

@ -42,7 +42,8 @@ txrx::txrx() : thread("TXRX")
bool txrx::init(stack_interface_phy_lte* stack_, bool txrx::init(stack_interface_phy_lte* stack_,
srslte::radio_interface_phy* radio_h_, srslte::radio_interface_phy* radio_h_,
lte::worker_pool* workers_pool_, lte::worker_pool* lte_workers_,
nr::worker_pool* nr_workers_,
phy_common* worker_com_, phy_common* worker_com_,
prach_worker_pool* prach_, prach_worker_pool* prach_,
srslte::log* log_h_, srslte::log* log_h_,
@ -51,7 +52,8 @@ bool txrx::init(stack_interface_phy_lte* stack_,
stack = stack_; stack = stack_;
radio_h = radio_h_; radio_h = radio_h_;
log_h = log_h_; log_h = log_h_;
lte_workers = workers_pool_; lte_workers = lte_workers_;
nr_workers = nr_workers_;
worker_com = worker_com_; worker_com = worker_com_;
prach = prach_; prach = prach_;
tx_worker_cnt = 0; tx_worker_cnt = 0;
@ -181,6 +183,12 @@ void txrx::run_thread()
lte_worker->set_time(tti, tx_worker_cnt, timestamp); lte_worker->set_time(tti, tx_worker_cnt, timestamp);
tx_worker_cnt = (tx_worker_cnt + 1) % nof_workers; tx_worker_cnt = (tx_worker_cnt + 1) % nof_workers;
// Launch NR worker only if available
if (nr_worker != nullptr) {
worker_com->semaphore.push(nr_worker);
nr_workers->start_worker(nr_worker);
}
// Trigger phy worker execution // Trigger phy worker execution
worker_com->semaphore.push(lte_worker); worker_com->semaphore.push(lte_worker);
lte_workers->start_worker(lte_worker); lte_workers->start_worker(lte_worker);

@ -428,6 +428,7 @@ static int parse_args(all_args_t* args, int argc, char* argv[])
("vnf.port", bpo::value<uint16_t>(&args->phy.vnf_args.bind_port)->default_value(3334), "Bind port") ("vnf.port", bpo::value<uint16_t>(&args->phy.vnf_args.bind_port)->default_value(3334), "Bind port")
("nr.nof_carriers", bpo::value<uint32_t>(&args->phy.nof_nr_carriers)->default_value(1), "Number of NR carriers") ("nr.nof_carriers", bpo::value<uint32_t>(&args->phy.nof_nr_carriers)->default_value(1), "Number of NR carriers")
("nr.nof_prb", bpo::value<uint32_t>(&args->phy.nr_nof_prb)->default_value(50), "NR carrier bandwidth") ("nr.nof_prb", bpo::value<uint32_t>(&args->phy.nr_nof_prb)->default_value(50), "NR carrier bandwidth")
("nr.freq", bpo::value<double>(&args->phy.nr_freq_hz)->default_value(2630e6), "NR carrier bandwidth")
; ;
// Positional options - config file location // Positional options - config file location

@ -855,6 +855,11 @@ bool sync::set_frequency()
radio_h->set_rx_freq(0, set_dl_freq); radio_h->set_rx_freq(0, set_dl_freq);
radio_h->set_tx_freq(0, set_ul_freq); radio_h->set_tx_freq(0, set_ul_freq);
for (uint32_t i = 0; i < worker_com->args->nof_nr_carriers; i++) {
radio_h->set_rx_freq(i + worker_com->args->nof_lte_carriers, worker_com->args->nr_freq_hz);
// radio_h->set_tx_freq(0, set_ul_freq);
}
ul_dl_factor = (float)(set_ul_freq / set_dl_freq); ul_dl_factor = (float)(set_ul_freq / set_dl_freq);
srslte_ue_sync_reset(&ue_sync); srslte_ue_sync_reset(&ue_sync);

Loading…
Cancel
Save