mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 05:00:31 +00:00
Compare commits
11 Commits
develop
...
tx_symbol_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99cec62618 | ||
|
|
adfdaf269a | ||
|
|
80fb76a779 | ||
|
|
04b9b37fc7 | ||
|
|
61082b0126 | ||
|
|
3b5ed67e60 | ||
|
|
beb248f8e5 | ||
|
|
dc728854da | ||
|
|
847cf9af06 | ||
|
|
f63f12480f | ||
|
|
42729d86bb |
@@ -24,6 +24,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
|
||||
| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I |
|
||||
| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I |
|
||||
| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I |
|
||||
| `PARAMFLAG_VALUE_OPTIONAL` | Parameter can be specified with a value or without a value to set it to 1 | I |
|
||||
| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O |
|
||||
| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O |
|
||||
| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O |
|
||||
|
||||
@@ -80,7 +80,7 @@ static int processoption(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
|
||||
char defbool[2]="1";
|
||||
|
||||
if ( value == NULL) {
|
||||
if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
|
||||
if( (cfgoptions->paramflags & (PARAMFLAG_BOOL | PARAMFLAG_VALUE_OPTIONAL)) == 0 ) { /* not a boolean, argument required */
|
||||
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
|
||||
AssertFatal(false, "[CONFIG] command line, requires an argument\n");
|
||||
} else { /* boolean value option without argument, set value to true*/
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
|
||||
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
|
||||
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
|
||||
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
|
||||
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
|
||||
#define PARAMFLAG_VALUE_OPTIONAL (1 << 7) // integer param is 1 if no value provided
|
||||
|
||||
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
|
||||
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
|
||||
|
||||
@@ -51,6 +51,11 @@ double get_cpu_freq_GHz(void)
|
||||
}
|
||||
|
||||
|
||||
static double StdDev(time_stats_t *ptr)
|
||||
{
|
||||
return sqrt((double)ptr->diff_square * 1e-6 / ptr->trials - pow((double)ptr->diff / ptr->trials / 1000, 2));
|
||||
}
|
||||
|
||||
|
||||
void print_meas_now(time_stats_t *ts,
|
||||
const char *name,
|
||||
@@ -110,6 +115,45 @@ void print_meas(time_stats_t *ts,
|
||||
}
|
||||
}
|
||||
|
||||
size_t print_meas_log_header(time_stats_t *total_exec_time,
|
||||
time_stats_t *sf_exec_time,
|
||||
char *output,
|
||||
size_t outputlen)
|
||||
{
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %18s %18s %18s %15s %18s %18s %18s %18s %18s %18s %9s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Max",
|
||||
"Std",
|
||||
"Num Trials",
|
||||
"min",
|
||||
"d1",
|
||||
"q1",
|
||||
"median",
|
||||
"q3",
|
||||
"d9",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
else
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %18s %18s %15s %9s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Average/Frame",
|
||||
"Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
|
||||
return output - begin;
|
||||
}
|
||||
|
||||
size_t print_meas_log(time_stats_t *ts,
|
||||
const char *name,
|
||||
time_stats_t *total_exec_time,
|
||||
@@ -119,46 +163,38 @@ size_t print_meas_log(time_stats_t *ts,
|
||||
{
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
static int first_time = 0;
|
||||
static double cpu_freq_GHz = 0.0;
|
||||
|
||||
if (cpu_freq_GHz == 0.0)
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
|
||||
if (first_time == 0) {
|
||||
first_time=1;
|
||||
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %25s %25s %25s %25s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Per Trials",
|
||||
"Num Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
else
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %25s %25s %20s %15s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Average/Frame",
|
||||
"Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
}
|
||||
|
||||
if (ts->trials>0) {
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15d; %15.3f us;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / cpu_freq_GHz / 1000.0,
|
||||
ts->trials,
|
||||
ts->max / cpu_freq_GHz / 1000.0);
|
||||
if (is_enabled_time_stats_sorted_list(&ts->time_stats_sorted_list)) {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / 1000.0,
|
||||
ts->max / 1000.0,
|
||||
StdDev(ts),
|
||||
ts->trials,
|
||||
get_min(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_d1(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_q1(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_median(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_q3(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_d9(&ts->time_stats_sorted_list) / 1000.0);
|
||||
} else {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / 1000.0,
|
||||
ts->max / 1000.0,
|
||||
StdDev(ts),
|
||||
ts->trials);
|
||||
}
|
||||
} else {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
@@ -302,3 +338,198 @@ void end_meas(void) {
|
||||
msg->msgid = TIMESTAT_MSGID_END ;
|
||||
pushNotifiedFIFO(&measur_fifo, nfe);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief initializes sorted list
|
||||
* if dst is already initialized then asserts
|
||||
* \param time_stats_sorted_list sorted list to be initialized
|
||||
* \param size size of the sorted list
|
||||
*/
|
||||
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size)
|
||||
{
|
||||
if (time_stats_sorted_list->size == 0) {
|
||||
time_stats_sorted_list->list = calloc(size, sizeof(oai_cputime_t));
|
||||
time_stats_sorted_list->size = size;
|
||||
time_stats_sorted_list->nb_elm = 0;
|
||||
} else {
|
||||
AssertFatal(time_stats_sorted_list->size == 0, "Calling init_time_stats_sorted_list on initialized sorted list\n");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief free sorted list
|
||||
* if dst is already free then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be freed
|
||||
*/
|
||||
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
free(time_stats_sorted_list->list);
|
||||
time_stats_sorted_list->size = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief returns true if the sorted list is enabled and false otherwise
|
||||
* \param time_stats_sorted_list sorted list to be tested
|
||||
*/
|
||||
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
return (time_stats_sorted_list->size > 0);
|
||||
}
|
||||
/**
|
||||
* \brief empties sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be emptied
|
||||
*/
|
||||
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
time_stats_sorted_list->nb_elm = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief inserts value sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* if dst is full then does nothing
|
||||
* \param time_stats_sorted_list sorted list to insert in
|
||||
* \param time time value to insert
|
||||
*/
|
||||
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
if (time_stats_sorted_list->nb_elm < time_stats_sorted_list->size) {
|
||||
unsigned int i = 0;
|
||||
#ifdef DICHOTOMY
|
||||
//TODO
|
||||
#else
|
||||
for (; i < time_stats_sorted_list->nb_elm && time_stats_sorted_list->list[i] < time; i++);
|
||||
#endif
|
||||
// dst and src may overlap => use memmove rather than memcpy
|
||||
memmove(&time_stats_sorted_list->list[i+1], &time_stats_sorted_list->list[i], (time_stats_sorted_list->nb_elm - i) * sizeof(oai_cputime_t));
|
||||
time_stats_sorted_list->list[i] = time;
|
||||
time_stats_sorted_list->nb_elm++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief copy sorted list src into dst, freeing and replacing dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* \param dst destination sorted list
|
||||
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
|
||||
{
|
||||
if (dst->size > 0 && src->size > 0) {
|
||||
if (dst->size != src->size) {
|
||||
free_time_stats_sorted_list(dst);
|
||||
init_time_stats_sorted_list(dst, src->size);
|
||||
}
|
||||
memcpy(dst->list, src->list, src->nb_elm * sizeof(oai_cputime_t));
|
||||
dst->nb_elm = src->nb_elm;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief inserts the content of sorted list src into dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* if dst is not large enough to copy src then does nothing
|
||||
* \param dst destination sorted list
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
|
||||
{
|
||||
if (dst->size > 0 && src->size > 0) {
|
||||
if ((dst->size - dst->nb_elm) >= src->nb_elm) {
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 0; i < src->nb_elm; i++) {
|
||||
#ifdef DICHOTOMY
|
||||
//TODO
|
||||
#else
|
||||
for (; j < dst->nb_elm && dst->list[j] < src->list[i]; j++);
|
||||
#endif
|
||||
// dst and src may overlap => use memmove rather than memcpy
|
||||
memmove(&dst->list[j+1], &dst->list[j], (dst->nb_elm - j) * sizeof(oai_cputime_t));
|
||||
dst->list[j] = src->list[i];
|
||||
dst->nb_elm++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the minimum from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[0];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the median from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 2];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the first quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 4];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the third quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[3 * time_stats_sorted_list->nb_elm / 4];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the first decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 10];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the nineth decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[9 * time_stats_sorted_list->nb_elm / 10];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,20 +55,121 @@ typedef struct {
|
||||
meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/
|
||||
} time_stats_msg_t;
|
||||
|
||||
/**
|
||||
* \typedef time_stats_sorted_list_t
|
||||
* \brief sorted list of time stats to get med, q1, q2
|
||||
* it can be left disabled by leaving size equal to 0
|
||||
* \var size allocated size of the list
|
||||
* 0 is the sorted list is disabled
|
||||
* \var nb_elm number of elements in the list
|
||||
* \var list pointer to the list
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
unsigned int nb_elm;
|
||||
oai_cputime_t *list;
|
||||
} time_stats_sorted_list_t;
|
||||
|
||||
/**
|
||||
* \brief initializes sorted list
|
||||
* if dst is already initialized then asserts
|
||||
* \param time_stats_sorted_list sorted list to be initialized
|
||||
* \param size size of the sorted list
|
||||
*/
|
||||
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size);
|
||||
/**
|
||||
* \brief free sorted list
|
||||
* if dst is already free then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be freed
|
||||
*/
|
||||
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief returns true if the sorted list is enabled and false otherwise
|
||||
* \param time_stats_sorted_list sorted list to be tested
|
||||
*/
|
||||
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief empties sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be emptied
|
||||
*/
|
||||
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief inserts value sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* if dst is full then does nothing
|
||||
* \param time_stats_sorted_list sorted list to insert in
|
||||
* \param time time value to insert
|
||||
*/
|
||||
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time);
|
||||
/**
|
||||
* \brief copy sorted list src into dst, freeing and replacing dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* \param dst destination sorted list
|
||||
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
|
||||
/**
|
||||
* \brief inserts the content of sorted list src into dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* if dst is not large enough to copy src then does nothing
|
||||
* \param dst destination sorted list
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
|
||||
/**
|
||||
* \brief get the minimum from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the median from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the first quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the third quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the first decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the nineth decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
|
||||
struct notifiedFIFO_elt_s;
|
||||
typedef struct time_stats {
|
||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||
double diff_square; /*!< \brief process duration square */
|
||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
int trials; /*!< \brief number of start point - end point iterations */
|
||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
|
||||
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
|
||||
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
|
||||
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/
|
||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||
double diff_square; /*!< \brief process duration square */
|
||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
int trials; /*!< \brief number of start point - end point iterations */
|
||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
|
||||
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
|
||||
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
|
||||
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations */
|
||||
time_stats_sorted_list_t time_stats_sorted_list; /*!< \brief optional sorted list to get med, q1, q2 */
|
||||
} time_stats_t;
|
||||
#define MEASURE_ENABLED(X) (X->meas_enabled)
|
||||
|
||||
@@ -77,6 +178,10 @@ static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
|
||||
|
||||
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name);
|
||||
void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time);
|
||||
size_t print_meas_log_header(time_stats_t *total_exec_time,
|
||||
time_stats_t *sf_exec_time,
|
||||
char *output,
|
||||
size_t outputlen);
|
||||
size_t print_meas_log(time_stats_t *ts,
|
||||
const char *name,
|
||||
time_stats_t *total_exec_time,
|
||||
@@ -118,6 +223,19 @@ static inline uint32_t rdtsc_oai(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline long long clock_gettime_oai()
|
||||
{
|
||||
struct timespec time;
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
// CLOCK_MONOTONIC_RAW only on linux
|
||||
// See clock_getres(2)
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &time);
|
||||
#endif
|
||||
return 1e+9 * time.tv_sec + time.tv_nsec;
|
||||
}
|
||||
|
||||
#define CPUMEAS_DISABLE 0
|
||||
#define CPUMEAS_ENABLE 1
|
||||
#define CPUMEAS_GETSTATE 2
|
||||
@@ -143,10 +261,10 @@ static inline void start_meas(time_stats_t *ts) {
|
||||
if (cpu_meas_enabled) {
|
||||
if (ts->meas_flag==0) {
|
||||
ts->trials++;
|
||||
ts->in = rdtsc_oai();
|
||||
ts->in = clock_gettime_oai();
|
||||
ts->meas_flag=1;
|
||||
} else {
|
||||
ts->in = rdtsc_oai();
|
||||
ts->in = clock_gettime_oai();
|
||||
}
|
||||
if ((ts->trials&16383)<10) ts->max=0;
|
||||
}
|
||||
@@ -154,7 +272,7 @@ static inline void start_meas(time_stats_t *ts) {
|
||||
|
||||
static inline void stop_meas(time_stats_t *ts) {
|
||||
if (cpu_meas_enabled) {
|
||||
long long out = rdtsc_oai();
|
||||
long long out = clock_gettime_oai();
|
||||
if (ts->in) {
|
||||
ts->diff += (out - ts->in);
|
||||
/// process duration is the difference between two clock points
|
||||
@@ -164,6 +282,7 @@ static inline void stop_meas(time_stats_t *ts) {
|
||||
if ((out - ts->in) > ts->max)
|
||||
ts->max = out - ts->in;
|
||||
|
||||
insert_in_time_stats_sorted_list(&ts->time_stats_sorted_list, (out - ts->in));
|
||||
ts->meas_flag = 0;
|
||||
}
|
||||
}
|
||||
@@ -177,6 +296,7 @@ static inline void reset_meas(time_stats_t *ts) {
|
||||
ts->max=0;
|
||||
ts->trials=0;
|
||||
ts->meas_flag=0;
|
||||
reset_time_stats_sorted_list(&ts->time_stats_sorted_list);
|
||||
}
|
||||
|
||||
static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
|
||||
@@ -184,6 +304,7 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
|
||||
dst_ts->trials=src_ts->trials;
|
||||
dst_ts->diff=src_ts->diff;
|
||||
dst_ts->max=src_ts->max;
|
||||
copy_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +317,23 @@ static inline void merge_meas(time_stats_t *dst_ts, const time_stats_t *src_ts)
|
||||
dst_ts->diff_square += src_ts->diff_square;
|
||||
if (src_ts->max > dst_ts->max)
|
||||
dst_ts->max = src_ts->max;
|
||||
if (is_enabled_time_stats_sorted_list(&src_ts->time_stats_sorted_list)) {
|
||||
merge_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
|
||||
} else if (src_ts->trials == 1) {
|
||||
insert_in_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, src_ts->max);
|
||||
}
|
||||
}
|
||||
|
||||
#define TIME_STATS_ADVANCED_MODE 2
|
||||
|
||||
static inline void init_sorted_list_meas(time_stats_t *ts, unsigned int size)
|
||||
{
|
||||
init_time_stats_sorted_list(&ts->time_stats_sorted_list, size);
|
||||
}
|
||||
|
||||
static inline void free_sorted_list_meas(time_stats_t *ts)
|
||||
{
|
||||
free_time_stats_sorted_list(&ts->time_stats_sorted_list);
|
||||
}
|
||||
|
||||
#define CPUMEASUR_SECTION "cpumeasur"
|
||||
|
||||
@@ -120,7 +120,9 @@ static void tx_func(processingData_L1tx_t *info)
|
||||
// TODO check for analog_bf_vendor_ext set to 1 is a workaround while no beam API for beam selection is implemented
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx
|
||||
|| IS_SOFTMODEM_RFSIM || cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) {
|
||||
start_meas(&info->gNB->phy_proc_tx);
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(&info->gNB->phy_proc_tx);
|
||||
}
|
||||
phy_procedures_gNB_TX(info->gNB,
|
||||
&sched_response.DL_req,
|
||||
&sched_response.TX_req,
|
||||
@@ -137,7 +139,9 @@ static void tx_func(processingData_L1tx_t *info)
|
||||
syncMsgRU.timestamp_tx = info->timestamp_tx;
|
||||
LOG_D(PHY, "gNB: %d.%d : calling RU TX function\n", syncMsgRU.frame_tx, syncMsgRU.slot_tx);
|
||||
ru_tx_func((void *)&syncMsgRU);
|
||||
stop_meas(&info->gNB->phy_proc_tx);
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(&info->gNB->phy_proc_tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,9 +154,14 @@ void *L1_rx_thread(void *arg)
|
||||
if (res == NULL)
|
||||
break;
|
||||
processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res);
|
||||
start_meas(&gNB->l1_rx_proc);
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, info->frame_rx, info->slot_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
start_meas(&gNB->l1_rx_proc);
|
||||
}
|
||||
rx_func(info);
|
||||
stop_meas(&gNB->l1_rx_proc);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
stop_meas(&gNB->l1_rx_proc);
|
||||
}
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
return NULL;
|
||||
@@ -166,9 +175,14 @@ void *L1_tx_thread(void *arg) {
|
||||
if (res == NULL) // stopping condition, happens only when queue is freed
|
||||
break;
|
||||
processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
start_meas(&gNB->l1_tx_proc);
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, info->frame, info->slot);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(&gNB->l1_tx_proc);
|
||||
}
|
||||
tx_func(info);
|
||||
stop_meas(&gNB->l1_tx_proc);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(&gNB->l1_tx_proc);
|
||||
}
|
||||
delNotifiedFIFO_elt(res);
|
||||
}
|
||||
return NULL;
|
||||
@@ -214,9 +228,13 @@ static void rx_func(processingData_L1_t *info)
|
||||
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx, &UL_INFO);
|
||||
|
||||
// Call the scheduler
|
||||
start_meas(&gNB->ul_indication_stats);
|
||||
if (rx_slot_type == NR_UPLINK_SLOT) {
|
||||
start_meas(&gNB->ul_indication_stats);
|
||||
}
|
||||
gNB->if_inst->NR_UL_indication(&UL_INFO);
|
||||
stop_meas(&gNB->ul_indication_stats);
|
||||
if (rx_slot_type == NR_UPLINK_SLOT) {
|
||||
stop_meas(&gNB->ul_indication_stats);
|
||||
}
|
||||
|
||||
notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL);
|
||||
processingData_L1_t *syncMsg = NotifiedFifoData(res);
|
||||
@@ -233,15 +251,24 @@ static void rx_func(processingData_L1_t *info)
|
||||
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
output += print_meas_log_header(NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->l1_tx_proc, "L1 Tx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->l1_rx_proc, "L1 Rx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_segmentation_stats, "DL segment segmentation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tinput, "DL encoding input", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tprep, "DL encoding preparation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tparity, "DL encoding parity", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->toutput, "DL encoding output", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_rate_matching_stats, "DL rate matching", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_interleaving_stats, "DL interleaving", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_scrambling_stats, "DLSCH scrambling", NULL, NULL, output, end-output);
|
||||
output += print_meas_log(&gNB->dlsch_modulation_stats, "DLSCH modulation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_resource_mapping_stats, "DLSCH resource mapping", NULL, NULL, output,end-output);
|
||||
output += print_meas_log(&gNB->dlsch_precoding_stats, "DLSCH precoding", NULL, NULL, output,end-output);
|
||||
output += print_meas_log(&gNB->dlsch_pdsch_generation_stats, "DLSCH generation", NULL, NULL, output,end-output);
|
||||
output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ulsch_decoding_stats, "ULSCH decoding", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_deinterleave, "UL segment deinterleaving", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_rate_unmatch, "UL segment rate recovery", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_ldpc_decode, "UL segments decoding", NULL, NULL, output, end - output);
|
||||
@@ -249,8 +276,9 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output);
|
||||
if (ru->feprx)
|
||||
if (ru->feprx) {
|
||||
output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
|
||||
}
|
||||
|
||||
bool full_slot = ru->half_slot_parallelization == 0;
|
||||
if (ru->feptx_prec) {
|
||||
@@ -274,8 +302,9 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&ru->txdataF_copy_stats, "txdataF_copy", NULL, NULL, output, end - output);
|
||||
}
|
||||
|
||||
if (ru->fh_north_asynch_in)
|
||||
if (ru->fh_north_asynch_in) {
|
||||
output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output);
|
||||
}
|
||||
|
||||
output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output);
|
||||
|
||||
@@ -283,9 +312,62 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output);
|
||||
output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output);
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
reset_meas(&gNB->l1_tx_proc);
|
||||
reset_meas(&gNB->l1_rx_proc);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_segmentation_stats);
|
||||
reset_meas(&gNB->tinput);
|
||||
reset_meas(&gNB->tprep);
|
||||
reset_meas(&gNB->tparity);
|
||||
reset_meas(&gNB->toutput);
|
||||
reset_meas(&gNB->dlsch_rate_matching_stats);
|
||||
reset_meas(&gNB->dlsch_interleaving_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
reset_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ts_deinterleave);
|
||||
reset_meas(&gNB->ts_rate_unmatch);
|
||||
reset_meas(&gNB->ts_ldpc_decode);
|
||||
reset_meas(&gNB->ul_indication_stats);
|
||||
reset_meas(&gNB->slot_indication_stats);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->rx_prach);
|
||||
if (ru->feprx) {
|
||||
reset_meas(&ru->ofdm_demod_stats);
|
||||
}
|
||||
|
||||
if (ru->feptx_prec) {
|
||||
reset_meas(&ru->precoding_stats);
|
||||
}
|
||||
|
||||
if (ru->feptx_ofdm) {
|
||||
reset_meas(&ru->txdataF_copy_stats);
|
||||
reset_meas(&ru->ofdm_mod_stats);
|
||||
reset_meas(&ru->ofdm_total_stats);
|
||||
reset_meas(&ru->txdataF_copy_stats);
|
||||
}
|
||||
|
||||
if (ru->fh_north_asynch_in) {
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
}
|
||||
|
||||
reset_meas(&ru->tx_fhaul);
|
||||
|
||||
if (ru->fh_north_out) {
|
||||
reset_meas(&ru->compression);
|
||||
reset_meas(&ru->transport);
|
||||
}
|
||||
}
|
||||
return output - begin;
|
||||
}
|
||||
|
||||
#define SORTED_LIST_SIZE 2048
|
||||
void *nrL1_stats_thread(void *param) {
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
RU_t *ru = RC.ru[0];
|
||||
@@ -298,21 +380,95 @@ void *nrL1_stats_thread(void *param) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
init_sorted_list_meas(&gNB->l1_tx_proc, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->l1_rx_proc, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->phy_proc_tx, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_encoding_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->tinput, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->tprep, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->tparity, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->toutput, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_segmentation_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_rate_matching_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_interleaving_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_scrambling_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_modulation_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->phy_proc_rx, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ulsch_decoding_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ts_deinterleave, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ts_rate_unmatch, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ts_ldpc_decode, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ul_indication_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->slot_indication_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->rx_pusch_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->rx_prach, SORTED_LIST_SIZE);
|
||||
if (ru->feprx) {
|
||||
init_sorted_list_meas(&ru->ofdm_demod_stats, SORTED_LIST_SIZE);
|
||||
}
|
||||
if (ru->feptx_prec) {
|
||||
init_sorted_list_meas(&ru->precoding_stats, SORTED_LIST_SIZE);
|
||||
}
|
||||
if (ru->feptx_ofdm) {
|
||||
init_sorted_list_meas(&ru->txdataF_copy_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&ru->ofdm_mod_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&ru->ofdm_total_stats, SORTED_LIST_SIZE);
|
||||
}
|
||||
if (ru->fh_north_asynch_in) {
|
||||
init_sorted_list_meas(&ru->rx_fhaul, SORTED_LIST_SIZE);
|
||||
}
|
||||
init_sorted_list_meas(&ru->tx_fhaul, SORTED_LIST_SIZE);
|
||||
if (ru->fh_north_out) {
|
||||
init_sorted_list_meas(&ru->compression, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&ru->transport, SORTED_LIST_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
reset_meas(&gNB->l1_tx_proc);
|
||||
reset_meas(&gNB->l1_rx_proc);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_segmentation_stats);
|
||||
reset_meas(&gNB->tinput);
|
||||
reset_meas(&gNB->tprep);
|
||||
reset_meas(&gNB->tparity);
|
||||
reset_meas(&gNB->toutput);
|
||||
reset_meas(&gNB->dlsch_rate_matching_stats);
|
||||
reset_meas(&gNB->dlsch_interleaving_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ts_deinterleave);
|
||||
reset_meas(&gNB->ts_rate_unmatch);
|
||||
reset_meas(&gNB->ts_ldpc_decode);
|
||||
reset_meas(&gNB->ul_indication_stats);
|
||||
reset_meas(&gNB->slot_indication_stats);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
reset_meas(&gNB->dlsch_precoding_stats);
|
||||
reset_meas(&gNB->rx_prach);
|
||||
|
||||
if (ru->feprx) {
|
||||
reset_meas(&ru->ofdm_demod_stats);
|
||||
}
|
||||
if (ru->feptx_prec) {
|
||||
reset_meas(&ru->precoding_stats);
|
||||
}
|
||||
if (ru->feptx_ofdm) {
|
||||
reset_meas(&ru->txdataF_copy_stats);
|
||||
reset_meas(&ru->ofdm_mod_stats);
|
||||
reset_meas(&ru->ofdm_total_stats);
|
||||
}
|
||||
if (ru->fh_north_asynch_in) {
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
}
|
||||
reset_meas(&ru->tx_fhaul);
|
||||
if (ru->fh_north_out) {
|
||||
reset_meas(&ru->compression);
|
||||
reset_meas(&ru->transport);
|
||||
}
|
||||
|
||||
while (!oai_exit) {
|
||||
sleep(1);
|
||||
if (ftruncate(fileno(fd), 0) != 0 || fseek(fd, 0, SEEK_SET) != 0) {
|
||||
@@ -326,6 +482,54 @@ void *nrL1_stats_thread(void *param) {
|
||||
fprintf(fd,"%s\n",output);
|
||||
fflush(fd);
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
free_sorted_list_meas(&gNB->l1_tx_proc);
|
||||
free_sorted_list_meas(&gNB->l1_rx_proc);
|
||||
free_sorted_list_meas(&gNB->phy_proc_tx);
|
||||
free_sorted_list_meas(&gNB->dlsch_encoding_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_segmentation_stats);
|
||||
free_sorted_list_meas(&gNB->tinput);
|
||||
free_sorted_list_meas(&gNB->tprep);
|
||||
free_sorted_list_meas(&gNB->tparity);
|
||||
free_sorted_list_meas(&gNB->toutput);
|
||||
free_sorted_list_meas(&gNB->dlsch_rate_matching_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_interleaving_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_scrambling_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_modulation_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
free_sorted_list_meas(&gNB->phy_proc_rx);
|
||||
free_sorted_list_meas(&gNB->ulsch_decoding_stats);
|
||||
free_sorted_list_meas(&gNB->ts_deinterleave);
|
||||
free_sorted_list_meas(&gNB->ts_rate_unmatch);
|
||||
free_sorted_list_meas(&gNB->ts_ldpc_decode);
|
||||
free_sorted_list_meas(&gNB->ul_indication_stats);
|
||||
free_sorted_list_meas(&gNB->slot_indication_stats);
|
||||
free_sorted_list_meas(&gNB->rx_pusch_stats);
|
||||
free_sorted_list_meas(&gNB->rx_prach);
|
||||
|
||||
if (ru->feprx) {
|
||||
free_sorted_list_meas(&ru->ofdm_demod_stats);
|
||||
}
|
||||
if (ru->feptx_prec) {
|
||||
free_sorted_list_meas(&ru->precoding_stats);
|
||||
}
|
||||
if (ru->feptx_ofdm) {
|
||||
free_sorted_list_meas(&ru->txdataF_copy_stats);
|
||||
free_sorted_list_meas(&ru->ofdm_mod_stats);
|
||||
free_sorted_list_meas(&ru->ofdm_total_stats);
|
||||
free_sorted_list_meas(&ru->txdataF_copy_stats);
|
||||
}
|
||||
if (ru->fh_north_asynch_in) {
|
||||
free_sorted_list_meas(&ru->rx_fhaul);
|
||||
}
|
||||
free_sorted_list_meas(&ru->tx_fhaul);
|
||||
if (ru->fh_north_out) {
|
||||
free_sorted_list_meas(&ru->compression);
|
||||
free_sorted_list_meas(&ru->transport);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return(NULL);
|
||||
}
|
||||
@@ -342,6 +546,7 @@ void init_gNB_Tpool(int inst)
|
||||
gNB_L1_proc_t *proc = &gNB->proc;
|
||||
// PUSCH symbols per thread need to be calculated by how many threads we have
|
||||
gNB->num_pusch_symbols_per_thread = 1;
|
||||
gNB->num_pdsch_symbols_per_thread = get_softmodem_params()->num_pdsch_symbols_per_thread;
|
||||
// ULSCH decoding threadpool
|
||||
initTpool(get_softmodem_params()->threadPoolConfig, &gNB->threadPool, cpumeas(CPUMEAS_GETSTATE));
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||
#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLPMI_PHYTEST "Set the downlink Precoding Matrix Index for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
|
||||
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// clang-format off
|
||||
#define CMDLINE_PARAMS_DESC_GNB { \
|
||||
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"l" , CONFIG_HLP_DLNL_PHYTEST, 0, .uptr=&target_dl_Nl, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"L" , CONFIG_HLP_ULNL_PHYTEST, 0, .uptr=&target_ul_Nl, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"p" , CONFIG_HLP_DLPMI_PHYTEST, 0, .uptr=&target_dl_pmi, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"t" , CONFIG_HLP_ULMCS_PHYTEST, 0, .uptr=&target_ul_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"M" , CONFIG_HLP_DLBW_PHYTEST, 0, .uptr=&target_dl_bw, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"T" , CONFIG_HLP_ULBW_PHYTEST, 0, .uptr=&target_ul_bw, .defintval=0, TYPE_UINT, 0}, \
|
||||
@@ -30,9 +31,10 @@
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
extern uint32_t target_dl_mcs;
|
||||
extern uint32_t target_dl_Nl;
|
||||
extern uint32_t target_ul_Nl;
|
||||
extern uint32_t target_dl_pmi;
|
||||
extern uint32_t target_dl_mcs;
|
||||
extern uint32_t target_ul_mcs;
|
||||
extern uint32_t target_dl_bw;
|
||||
extern uint32_t target_ul_bw;
|
||||
|
||||
@@ -47,6 +47,7 @@ extern "C"
|
||||
example: -1,3 launches two working threads one floating, the second set on core 3\n\
|
||||
default 8 floating threads\n\
|
||||
use N for no pool (runs in calling thread) recommended with rfsim.\n"
|
||||
#define CONFIG_HLP_TX_SYM "number of symbols processed per PDSCH generation thread\n"
|
||||
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
||||
#define CONFIG_HLP_CALUERM ""
|
||||
#define CONFIG_HLP_CALUERB ""
|
||||
@@ -107,6 +108,7 @@ extern "C"
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define RF_CONFIG_FILE softmodem_params.rf_config_file
|
||||
#define TP_CONFIG softmodem_params.threadPoolConfig
|
||||
#define TX_SYM softmodem_params.num_pdsch_symbols_per_thread
|
||||
#define CONTINUOUS_TX softmodem_params.continuous_tx
|
||||
#define PHY_TEST softmodem_params.phy_test
|
||||
#define DO_RA softmodem_params.do_ra
|
||||
@@ -132,6 +134,7 @@ extern int usrp_tx_thread;
|
||||
#define CMDLINE_PARAMS_DESC { \
|
||||
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
{"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
|
||||
{"tx-sym", CONFIG_HLP_TX_SYM, 0, .iptr=&TX_SYM, .defintval=0, TYPE_INT, 0}, \
|
||||
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \
|
||||
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
|
||||
{"sl-mode", CONFIG_HLP_SL_MODE, 0, .u8ptr=&SL_MODE, .defintval=0, TYPE_UINT8, 0}, \
|
||||
@@ -142,7 +145,7 @@ extern int usrp_tx_thread;
|
||||
{"CO" , CONFIG_HLP_ULF, 0, .iptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT, 0}, \
|
||||
{"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_VALUE_OPTIONAL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \
|
||||
{"band" , CONFIG_HLP_BAND, 0, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \
|
||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, .strptr=¶llel_config, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
@@ -196,6 +199,7 @@ extern int usrp_tx_thread;
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s5 = { NULL } }, \
|
||||
{ .s3a = { config_checkstr_assign_integer, \
|
||||
{"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
|
||||
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
|
||||
@@ -294,6 +298,7 @@ typedef struct {
|
||||
//THREAD_STRUCT thread_struct;
|
||||
char *rf_config_file;
|
||||
char *threadPoolConfig;
|
||||
int num_pdsch_symbols_per_thread;
|
||||
int phy_test;
|
||||
int do_ra;
|
||||
uint8_t sl_mode;
|
||||
|
||||
@@ -121,7 +121,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
// Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
|
||||
time_stats_t timeEncoder, timeDecoder;
|
||||
time_stats_t timeEncoder = {0};
|
||||
time_stats_t timeDecoder = {0};
|
||||
cpu_meas_enabled = 1;
|
||||
reset_meas(&timeEncoder);
|
||||
reset_meas(&timeDecoder);
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
time_stats_t timeEncoder, timeDecoder;
|
||||
time_stats_t timeEncoder = {0};
|
||||
time_stats_t timeDecoder = {0};
|
||||
cpu_meas_enabled = 1;
|
||||
reset_meas(&timeEncoder);
|
||||
reset_meas(&timeDecoder);
|
||||
|
||||
@@ -337,22 +337,22 @@ static inline void neg_dmrs(c16_t *in, c16_t *out, int sz)
|
||||
*out++ = i % 2 ? (c16_t){-in[i].r, -in[i].i} : in[i];
|
||||
}
|
||||
|
||||
static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot,
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
int layer,
|
||||
c16_t *output,
|
||||
c16_t *txl_start,
|
||||
int start_sc,
|
||||
int symbol_sz,
|
||||
int l_symbol,
|
||||
uint16_t dlPtrsSymPos,
|
||||
int n_ptrs,
|
||||
int amp,
|
||||
int16_t amp_dmrs,
|
||||
int l_prime,
|
||||
nfapi_nr_dmrs_type_e dmrs_Type,
|
||||
c16_t *dmrs_start)
|
||||
static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot,
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
int layer,
|
||||
c16_t *output,
|
||||
c16_t *txl_start,
|
||||
int start_sc,
|
||||
int symbol_sz,
|
||||
int l_symbol,
|
||||
uint16_t dlPtrsSymPos,
|
||||
int n_ptrs,
|
||||
int amp,
|
||||
int16_t amp_dmrs,
|
||||
int l_prime,
|
||||
nfapi_nr_dmrs_type_e dmrs_Type,
|
||||
c16_t *dmrs_start)
|
||||
{
|
||||
c16_t *txl = txl_start;
|
||||
const uint sz = rel15->rbSize * NR_NB_SC_PER_RB;
|
||||
@@ -450,7 +450,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit);
|
||||
txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re);
|
||||
} // no DMRS/PTRS in symbol
|
||||
return txl - txl_start;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void do_txdataF(c16_t **txdataF,
|
||||
@@ -548,28 +548,149 @@ static inline void do_txdataF(c16_t **txdataF,
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
}
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
|
||||
|
||||
typedef struct pdschSymbolProc_s {
|
||||
PHY_VARS_gNB *gNB;
|
||||
NR_DL_FRAME_PARMS *frame_parms;
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15;
|
||||
unsigned int slot;
|
||||
unsigned int startSymbol;
|
||||
unsigned int numSymbols;
|
||||
task_ans_t *ans;
|
||||
unsigned int layerSz2;
|
||||
unsigned int dlPtrsSymPos;
|
||||
unsigned int n_ptrs;
|
||||
unsigned int beam_nb;
|
||||
unsigned int re_beginning_of_symbol[14];
|
||||
c16_t *tx_layers[4];
|
||||
} pdschSymbolProc_t;
|
||||
|
||||
static void nr_pdsch_symbol_processing(void *arg)
|
||||
{
|
||||
pdschSymbolProc_t *rdata = (pdschSymbolProc_t *)arg;
|
||||
|
||||
PHY_VARS_gNB *gNB = rdata->gNB;
|
||||
NR_DL_FRAME_PARMS *frame_parms = rdata->frame_parms;
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = rdata->rel15;
|
||||
int slot = rdata->slot;
|
||||
c16_t *tx_layers[rel15->nrOfLayers];
|
||||
for (int l = 0; l < rel15->nrOfLayers; l++)
|
||||
tx_layers[l] = rdata->tx_layers[l];
|
||||
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
|
||||
// Loop Over OFDM symbols:
|
||||
c16_t mod_dmrs[(n_dmrs + 63) & ~63] __attribute__((aligned(64)));
|
||||
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
const int symbol_sz = frame_parms->ofdm_symbol_size;
|
||||
|
||||
c16_t **txdataF = gNB->common_vars.txdataF[rdata->beam_nb];
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
|
||||
if (start_sc >= symbol_sz)
|
||||
start_sc -= symbol_sz;
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("slot %d PDSCH resource mapping started (start SC %d\tstart symbol %d\tnum symbols %d\tN_PRB %d,nb_layers %d)\n",
|
||||
rdata->slot,
|
||||
start_sc,
|
||||
rdata->startSymbol,
|
||||
rdata->numSymbols,
|
||||
rel15->rbSize,
|
||||
rel15->nrOfLayers);
|
||||
#endif
|
||||
for (int l_symbol = rdata->startSymbol; l_symbol < rdata->startSymbol + rdata->numSymbols; l_symbol++) {
|
||||
start_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
int l_prime = 0; // single symbol layer 0
|
||||
int l_overline = get_l0(rel15->dlDmrsSymbPos);
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping symbol %d\n", l_symbol);
|
||||
#endif
|
||||
/// DMRS QPSK modulation
|
||||
if ((rel15->dlDmrsSymbPos & (1 << l_symbol))) { // DMRS time occasion
|
||||
// The reference point for is subcarrier -1 of the lowest-numbered resource block in CORESET 0 if the corresponding
|
||||
// PDCCH is associated with CORESET -1 and Type0-PDCCH common search space and is addressed to SI-RNTI
|
||||
// 2GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
|
||||
if (l_symbol == (l_overline + 1)) // take into account the double DMRS symbols
|
||||
l_prime = 1;
|
||||
else if (l_symbol > (l_overline + 1)) { // new DMRS pair
|
||||
l_overline = l_symbol;
|
||||
l_prime = 0;
|
||||
}
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("dlDmrsScramblingId %d, SCID %d slot %d l_symbol %d\n", rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol);
|
||||
#endif
|
||||
const uint32_t *gold = nr_gold_pdsch(frame_parms->N_RB_DL,
|
||||
frame_parms->symbols_per_slot,
|
||||
rel15->dlDmrsScramblingId,
|
||||
rel15->SCID,
|
||||
slot,
|
||||
l_symbol);
|
||||
// Qm = 1 as DMRS is QPSK modulated
|
||||
nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs);
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type);
|
||||
for (int i = 0; i < n_dmrs / 2; i += 8) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[i + j].r, mod_dmrs[i + j].i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uint32_t dmrs_idx = rel15->rbStart;
|
||||
if (rel15->refPoint == 0)
|
||||
dmrs_idx += rel15->BWPStart;
|
||||
dmrs_idx *= rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
c16_t txdataF_precoding[rel15->nrOfLayers][symbol_sz] __attribute__((aligned(64)));
|
||||
for (int layer = 0; layer < rel15->nrOfLayers; layer++) {
|
||||
do_onelayer(frame_parms,
|
||||
slot,
|
||||
rel15,
|
||||
layer,
|
||||
txdataF_precoding[layer],
|
||||
tx_layers[layer] + rdata->re_beginning_of_symbol[l_symbol],
|
||||
start_sc,
|
||||
symbol_sz,
|
||||
l_symbol,
|
||||
rdata->dlPtrsSymPos,
|
||||
rdata->n_ptrs,
|
||||
gNB->TX_AMP,
|
||||
min((double)gNB->TX_AMP * sqrt(rel15->numDmrsCdmGrpsNoData), INT16_MAX),
|
||||
l_prime,
|
||||
rel15->dmrsConfigType,
|
||||
mod_dmrs + dmrs_idx);
|
||||
} // layer loop
|
||||
stop_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
|
||||
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
|
||||
}
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
}
|
||||
// Task running in // completed
|
||||
completed_task_ans(rdata->ans);
|
||||
}
|
||||
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int frame, int slot)
|
||||
{
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
|
||||
time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats;
|
||||
time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats;
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
|
||||
const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB;
|
||||
const int symbol_sz=frame_parms->ofdm_symbol_size;
|
||||
const int dmrs_Type = rel15->dmrsConfigType;
|
||||
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
const int16_t amp_dmrs = min((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData), INT16_MAX); // 3GPP TS 38.214 Section 4.1: Table 4.1-1
|
||||
LOG_D(PHY,
|
||||
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n",
|
||||
rel15->BWPStart,
|
||||
rel15->BWPSize,
|
||||
rel15->rbStart,
|
||||
rel15->rbSize);
|
||||
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
|
||||
const int n_dmrs = rel15->rbSize * nb_re_dmrs;
|
||||
|
||||
const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100
|
||||
const int xOverhead = 0;
|
||||
const int nb_re =
|
||||
(12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers;
|
||||
@@ -608,9 +729,12 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
memcpy(dlsch->f, input_ptr, (encoded_length + 7) >> 3);
|
||||
|
||||
c16_t mod_symbs[rel15->NrOfCodewords][encoded_length] __attribute__((aligned(64)));
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, frame, slot);
|
||||
for (int codeWord = 0; codeWord < rel15->NrOfCodewords; codeWord++) {
|
||||
/// scrambling
|
||||
start_meas(dlsch_scrambling_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(dlsch_scrambling_stats);
|
||||
}
|
||||
uint32_t scrambled_output[(encoded_length >> 5) + 4]; // modulator acces by 4 bytes in some cases
|
||||
memset(scrambled_output, 0, sizeof(scrambled_output));
|
||||
nr_pdsch_codeword_scrambling(input_ptr, encoded_length, codeWord, rel15->dataScramblingId, rel15->rnti, scrambled_output);
|
||||
@@ -624,12 +748,18 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
}
|
||||
#endif
|
||||
|
||||
stop_meas(dlsch_scrambling_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(dlsch_scrambling_stats);
|
||||
}
|
||||
/// Modulation
|
||||
start_meas(dlsch_modulation_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(dlsch_modulation_stats);
|
||||
}
|
||||
nr_modulation(scrambled_output, encoded_length, Qm, (int16_t *)mod_symbs[codeWord]);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
|
||||
stop_meas(dlsch_modulation_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(dlsch_modulation_stats);
|
||||
}
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re);
|
||||
for (int i = 0; i < nb_re; i += 8) {
|
||||
@@ -641,29 +771,18 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
#endif
|
||||
}
|
||||
|
||||
start_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
}
|
||||
/// Resource mapping
|
||||
// Non interleaved VRB to PRB mapping
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
|
||||
if (start_sc >= symbol_sz)
|
||||
start_sc -= symbol_sz;
|
||||
|
||||
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
|
||||
start_sc,
|
||||
rel15->StartSymbolIndex,
|
||||
rel15->rbSize,
|
||||
nb_re,
|
||||
rel15->nrOfLayers);
|
||||
#endif
|
||||
|
||||
AssertFatal(n_dmrs, "n_dmrs can't be 0\n");
|
||||
// make a large enough tail to process all re with SIMD regardless a garbadge filler
|
||||
c16_t mod_dmrs[(n_dmrs+63)&~63] __attribute__((aligned(64)));
|
||||
unsigned int re_beginning_of_symbol = 0;
|
||||
|
||||
start_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
}
|
||||
int layerSz2 = (layerSz + 63) & ~63;
|
||||
c16_t tx_layers[rel15->nrOfLayers][layerSz2] __attribute__((aligned(64)));
|
||||
memset(tx_layers, 0, sizeof(tx_layers));
|
||||
@@ -685,86 +804,69 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
bitmap);
|
||||
|
||||
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
|
||||
stop_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
// Loop Over OFDM symbols:
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
|
||||
start_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
int l_prime = 0; // single symbol layer 0
|
||||
int l_overline = get_l0(rel15->dlDmrsSymbPos);
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping symbol %d\n", l_symbol);
|
||||
#endif
|
||||
/// DMRS QPSK modulation
|
||||
if ((dmrs_symbol_map & (1 << l_symbol))) { // DMRS time occasion
|
||||
// The reference point for is subcarrier -1 of the lowest-numbered resource block in CORESET 0 if the corresponding
|
||||
// PDCCH is associated with CORESET -1 and Type0-PDCCH common search space and is addressed to SI-RNTI
|
||||
// 2GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
|
||||
if (l_symbol == (l_overline + 1)) // take into account the double DMRS symbols
|
||||
l_prime = 1;
|
||||
else if (l_symbol > (l_overline + 1)) { // new DMRS pair
|
||||
l_overline = l_symbol;
|
||||
l_prime = 0;
|
||||
}
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("dlDmrsScramblingId %d, SCID %d slot %d l_symbol %d\n", rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol);
|
||||
#endif
|
||||
const uint32_t *gold = nr_gold_pdsch(frame_parms->N_RB_DL,
|
||||
frame_parms->symbols_per_slot,
|
||||
rel15->dlDmrsScramblingId,
|
||||
rel15->SCID,
|
||||
slot,
|
||||
l_symbol);
|
||||
// Qm = 1 as DMRS is QPSK modulated
|
||||
nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs);
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type);
|
||||
for (int i = 0; i < n_dmrs / 2; i += 8) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[i + j].r, mod_dmrs[i + j].i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uint32_t dmrs_idx = rel15->rbStart;
|
||||
if (rel15->refPoint == 0)
|
||||
dmrs_idx += rel15->BWPStart;
|
||||
dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
c16_t txdataF_precoding[rel15->nrOfLayers][symbol_sz] __attribute__((aligned(64)));
|
||||
int layer_sz = 0;
|
||||
for (int layer = 0; layer < rel15->nrOfLayers; layer++) {
|
||||
layer_sz = do_onelayer(frame_parms,
|
||||
slot,
|
||||
rel15,
|
||||
layer,
|
||||
txdataF_precoding[layer],
|
||||
tx_layers[layer] + re_beginning_of_symbol,
|
||||
start_sc,
|
||||
symbol_sz,
|
||||
l_symbol,
|
||||
dlPtrsSymPos,
|
||||
n_ptrs,
|
||||
amp,
|
||||
amp_dmrs,
|
||||
l_prime,
|
||||
dmrs_Type,
|
||||
mod_dmrs + dmrs_idx);
|
||||
} // layer loop
|
||||
re_beginning_of_symbol += layer_sz;
|
||||
stop_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
|
||||
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
|
||||
}
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
}
|
||||
|
||||
// spawn symbol threads
|
||||
|
||||
int nb_tasks = 1;
|
||||
int num_pdsch_symbols_per_task = rel15->NrOfSymbols;
|
||||
if (gNB->num_pdsch_symbols_per_thread > 0) {
|
||||
// symbol processing in thread pool enabled
|
||||
num_pdsch_symbols_per_task = gNB->num_pdsch_symbols_per_thread;
|
||||
nb_tasks = rel15->NrOfSymbols / num_pdsch_symbols_per_task;
|
||||
if ((rel15->NrOfSymbols % num_pdsch_symbols_per_task) > 0)
|
||||
nb_tasks++;
|
||||
}
|
||||
pdschSymbolProc_t arr[nb_tasks];
|
||||
task_ans_t ans;
|
||||
init_task_ans(&ans, nb_tasks);
|
||||
int sz_arr = 0;
|
||||
unsigned int re_beginning_of_symbol = 0;
|
||||
int res = 0;
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols;
|
||||
l_symbol += num_pdsch_symbols_per_task) {
|
||||
pdschSymbolProc_t *rdata = &arr[sz_arr];
|
||||
rdata->ans = &ans;
|
||||
++sz_arr;
|
||||
|
||||
rdata->gNB = gNB;
|
||||
rdata->frame_parms = frame_parms;
|
||||
rdata->rel15 = rel15;
|
||||
rdata->slot = slot;
|
||||
rdata->startSymbol = l_symbol;
|
||||
res = rel15->NrOfSymbols - (l_symbol - rel15->StartSymbolIndex);
|
||||
if (res >= num_pdsch_symbols_per_task)
|
||||
rdata->numSymbols = num_pdsch_symbols_per_task;
|
||||
else
|
||||
rdata->numSymbols = res;
|
||||
rdata->layerSz2 = layerSz2;
|
||||
rdata->dlPtrsSymPos = dlPtrsSymPos;
|
||||
rdata->n_ptrs = n_ptrs;
|
||||
rdata->beam_nb = beam_nb;
|
||||
for (int s = l_symbol; s < l_symbol + rdata->numSymbols; s++) {
|
||||
rdata->re_beginning_of_symbol[s] = re_beginning_of_symbol;
|
||||
re_beginning_of_symbol += rel15->rbSize * NR_NB_SC_PER_RB;
|
||||
if (n_ptrs > 0 && is_ptrs_symbol(s, dlPtrsSymPos)) {
|
||||
re_beginning_of_symbol -= n_ptrs;
|
||||
} else if (rel15->dlDmrsSymbPos & (1 << s)) {
|
||||
re_beginning_of_symbol -= n_dmrs;
|
||||
}
|
||||
}
|
||||
for (int l = 0; l < rel15->nrOfLayers; l++)
|
||||
rdata->tx_layers[l] = tx_layers[l];
|
||||
if (l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols - num_pdsch_symbols_per_task) {
|
||||
task_t t = {.func = &nr_pdsch_symbol_processing, .args = rdata};
|
||||
pushTpool(&gNB->threadPool, t);
|
||||
} else {
|
||||
nr_pdsch_symbol_processing(rdata);
|
||||
}
|
||||
}
|
||||
join_task_ans(&ans);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
}
|
||||
stop_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
|
||||
* should remain a multiple of 8 * 64 with enough offset to fit each dlsch
|
||||
*/
|
||||
@@ -827,7 +929,10 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
|
||||
unsigned char output[size_output >> 3] __attribute__((aligned(64)));
|
||||
bzero(output, sizeof(output));
|
||||
|
||||
start_meas(dlsch_encoding_stats);
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, frame, slot);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(dlsch_encoding_stats);
|
||||
}
|
||||
if (nr_dlsch_encoding(gNB,
|
||||
n_dlsch,
|
||||
dlsch_array,
|
||||
@@ -845,11 +950,13 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
|
||||
== -1) {
|
||||
return;
|
||||
}
|
||||
stop_meas(dlsch_encoding_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(dlsch_encoding_stats);
|
||||
}
|
||||
|
||||
unsigned char *output_ptr = output;
|
||||
for (int i = 0; i < n_dlsch; i++) {
|
||||
output_ptr += do_one_dlsch(output_ptr, gNB, &dlsch_array[i], slot);
|
||||
output_ptr += do_one_dlsch(output_ptr, gNB, &dlsch_array[i], frame, slot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
|
||||
int num_segments = 0;
|
||||
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, frame, slot);
|
||||
for (int i = 0; i < n_dlsch; i++) {
|
||||
NR_gNB_DLSCH_t *dlsch = &dlsch_array[i];
|
||||
|
||||
@@ -190,7 +191,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
TB_parameters->harq_unique_pid = i;
|
||||
TB_parameters->BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
|
||||
TB_parameters->A = A;
|
||||
start_meas(dlsch_segmentation_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(dlsch_segmentation_stats);
|
||||
}
|
||||
TB_parameters->Kb = nr_segmentation(dlsch->b,
|
||||
dlsch->c,
|
||||
B,
|
||||
@@ -199,7 +202,9 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
&TB_parameters->Z,
|
||||
&TB_parameters->F,
|
||||
TB_parameters->BG);
|
||||
stop_meas(dlsch_segmentation_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(dlsch_segmentation_stats);
|
||||
}
|
||||
|
||||
if (TB_parameters->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * rel15->nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B);
|
||||
@@ -286,9 +291,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i];
|
||||
for (int r = 0; r < TB_parameters->C; r++) {
|
||||
nrLDPC_segment_encoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
|
||||
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
|
||||
merge_meas(dlsch_rate_matching_stats, &segment_parameters->ts_rate_match);
|
||||
// merge_meas(, &segment_parameters->ts_ldpc_encode);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
|
||||
merge_meas(dlsch_rate_matching_stats, &segment_parameters->ts_rate_match);
|
||||
// merge_meas(, &segment_parameters->ts_ldpc_encode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,14 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
}
|
||||
|
||||
int slot_type = nr_slot_select(&phy_vars_gNB->gNB_config, frame, nr_tti_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
start_meas(&phy_vars_gNB->ulsch_decoding_stats);
|
||||
}
|
||||
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
stop_meas(&phy_vars_gNB->ulsch_decoding_stats);
|
||||
}
|
||||
|
||||
// post decode
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
@@ -303,9 +310,11 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
|
||||
merge_meas(&phy_vars_gNB->ts_deinterleave, &nrLDPC_segment_decoding_parameters.ts_deinterleave);
|
||||
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &nrLDPC_segment_decoding_parameters.ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &nrLDPC_segment_decoding_parameters.ts_ldpc_decode);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
merge_meas(&phy_vars_gNB->ts_deinterleave, &nrLDPC_segment_decoding_parameters.ts_deinterleave);
|
||||
merge_meas(&phy_vars_gNB->ts_rate_unmatch, &nrLDPC_segment_decoding_parameters.ts_rate_unmatch);
|
||||
merge_meas(&phy_vars_gNB->ts_ldpc_decode, &nrLDPC_segment_decoding_parameters.ts_ldpc_decode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ int cpu_meas_enabled;
|
||||
THREAD_STRUCT thread_struct;
|
||||
uint32_t target_ul_mcs = 9;
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_pmi = 0;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
uint64_t ulsch_slot_bitmap = (1<<8);
|
||||
uint32_t target_ul_bw = 50;
|
||||
|
||||
@@ -493,6 +493,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
notifiedFIFO_t L1_rx_out;
|
||||
tpool_t threadPool;
|
||||
int num_pusch_symbols_per_thread;
|
||||
int num_pdsch_symbols_per_thread;
|
||||
int dmrs_num_antennas_per_thread;
|
||||
pthread_t L1_rx_thread;
|
||||
int L1_rx_thread_core;
|
||||
|
||||
@@ -333,7 +333,10 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
//apply the OFDM symbol rotation here
|
||||
start_meas(&gNB->phase_comp_stats);
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, frame, slot);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
start_meas(&gNB->phase_comp_stats);
|
||||
}
|
||||
for (int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
|
||||
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
if (gNB->phase_comp) {
|
||||
@@ -353,7 +356,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
T_BUFFER(&gNB->common_vars.txdataF[i][aa][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t)));
|
||||
}
|
||||
}
|
||||
stop_meas(&gNB->phase_comp_stats);
|
||||
if (slot_type == NR_DOWNLINK_SLOT) {
|
||||
stop_meas(&gNB->phase_comp_stats);
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0);
|
||||
}
|
||||
@@ -1027,7 +1032,10 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
}
|
||||
|
||||
const int soffset = (slot_rx & 3) * nb_symb * ofdm_symbol_size;
|
||||
start_meas(&gNB->phy_proc_rx);
|
||||
int slot_type = nr_slot_select(&gNB->gNB_config, frame_rx, slot_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
start_meas(&gNB->phy_proc_rx);
|
||||
}
|
||||
|
||||
for (int i = 0; i < gNB->max_nb_pucch; i++) {
|
||||
NR_gNB_PUCCH_t *pucch = &gNB->pucch[i];
|
||||
@@ -1385,7 +1393,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
|
||||
stop_meas(&gNB->rx_srs_stats);
|
||||
}
|
||||
|
||||
stop_meas(&gNB->phy_proc_rx);
|
||||
if (slot_type == NR_UPLINK_SLOT) {
|
||||
stop_meas(&gNB->phy_proc_rx);
|
||||
}
|
||||
|
||||
if (pucch_decode_done || pusch_decode_done) {
|
||||
T(T_GNB_PHY_PUCCH_PUSCH_IQ,
|
||||
|
||||
@@ -394,6 +394,7 @@ int main(int argc, char **argv)
|
||||
uint8_t dlsch_threads = 0;
|
||||
int chest_type[2] = {0};
|
||||
uint8_t max_ldpc_iterations = 5;
|
||||
int num_pdsch_symbols_per_thread = 0;
|
||||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
|
||||
exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -584,6 +585,10 @@ int main(int argc, char **argv)
|
||||
gNBthreads[sizeof(gNBthreads)-1]=0;
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
num_pdsch_symbols_per_thread = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'Z' :
|
||||
filename_csv = strdup(optarg);
|
||||
AssertFatal(filename_csv != NULL, "strdup() error: errno %d\n", errno);
|
||||
@@ -653,6 +658,7 @@ int main(int argc, char **argv)
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
|
||||
printf("-X gNB thread pool configuration, n => no threads\n");
|
||||
printf("-Y Number of symbols processed per PDSCH generation thread\n");
|
||||
printf("-Z Output filename (.csv format) for stats\n");
|
||||
exit (-1);
|
||||
break;
|
||||
@@ -686,6 +692,7 @@ int main(int argc, char **argv)
|
||||
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0)) != NULL, "Cannot register interface");
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
gNB->num_pdsch_symbols_per_thread = num_pdsch_symbols_per_thread;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc));;
|
||||
prepare_scc(scc);
|
||||
|
||||
@@ -51,6 +51,7 @@ static bool is_xlsch_in_slot(uint64_t bitmap, slot_t slot)
|
||||
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_Nl = 1;
|
||||
uint32_t target_dl_pmi = 0;
|
||||
uint32_t target_dl_bw = 50;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
|
||||
@@ -189,7 +190,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
// tbSize further below
|
||||
.dl_harq_pid = sched_ctrl->retrans_dl_harq.head, // PID of HARQ awaiting retransmission, or -1 otherwise
|
||||
.pucch_allocation = alloc,
|
||||
.pm_index = 0,
|
||||
.pm_index = target_dl_pmi,
|
||||
.nrOfLayers = target_dl_Nl,
|
||||
.bwp_info = get_pdsch_bwp_start_size(mac, UE),
|
||||
.dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, target_dl_Nl),
|
||||
|
||||
Reference in New Issue
Block a user