Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-RAN
Commits
d448e99e
Commit
d448e99e
authored
Mar 07, 2026
by
Gabriele Gemmi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
read DBT from csv
parent
3f3576bb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
196 additions
and
3 deletions
+196
-3
openair2/GNB_APP/MACRLC_nr_paramdef.h
openair2/GNB_APP/MACRLC_nr_paramdef.h
+8
-3
openair2/GNB_APP/gnb_config.c
openair2/GNB_APP/gnb_config.c
+104
-0
openair2/LAYER2/NR_MAC_gNB/config.c
openair2/LAYER2/NR_MAC_gNB/config.c
+75
-0
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+9
-0
No files found.
openair2/GNB_APP/MACRLC_nr_paramdef.h
View file @
d448e99e
...
...
@@ -77,6 +77,7 @@
#define CONFIG_STRING_MACRLC_BEAM_DURATION "beam_duration"
#define CONFIG_STRING_MACRLC_BEAMS_PERIOD "beams_per_period"
#define CONFIG_STRING_MACRLC_BEAM_WEIGHTS_LIST "beam_weights"
#define CONFIG_STRING_MACRLC_DBT_FILE "dbt_file"
#define CONFIG_STRING_MACRLC_PUSCH_RSSI_THRESHOLD "pusch_RSSI_Threshold"
#define CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD "pucch_RSSI_Threshold"
#define CONFIG_STRING_MACRLC_STATS_MAX_UE "stats_max_ue"
...
...
@@ -97,6 +98,7 @@
#define HLP_MACRLC_AB "Flag to enable analog beamforming"
#define HLP_MACRLC_BEAM_DURATION "number of consecutive slots for a given set of beams"
#define HLP_MACRLC_BEAMS_PERIOD "set of beams that can be simultaneously allocated in a period"
#define HLP_MACRLC_DBT_FILE "File path to CSV file to read digital beamforming table"
#define HLP_MACRLC_PUSCH_RSSI_THRESHOLD "Limits PUSCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS"
#define HLP_MACRLC_PUCCH_RSSI_THRESHOLD "Limits PUCCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS"
#define HLP_MACRLC_STATS_MAX_UE "Maximum number of UEs before disabling periodical output (0 to disable)"
...
...
@@ -147,6 +149,7 @@
{CONFIG_STRING_MACRLC_BEAM_DURATION, HLP_MACRLC_BEAM_DURATION, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_BEAMS_PERIOD, HLP_MACRLC_BEAMS_PERIOD, 0, .u8ptr=NULL, .defintval=1, TYPE_UINT8, 0}, \
{CONFIG_STRING_MACRLC_BEAM_WEIGHTS_LIST, NULL, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY,0}, \
{CONFIG_STRING_MACRLC_DBT_FILE, HLP_MACRLC_DBT_FILE, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \
{CONFIG_STRING_MACRLC_PUSCH_RSSI_THRESHOLD, HLP_MACRLC_PUSCH_RSSI_THRESHOLD, \
0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \
{CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, \
...
...
@@ -195,9 +198,10 @@
#define MACRLC_ANALOG_BEAM_DURATION_IDX 37
#define MACRLC_ANALOG_BEAMS_PERIOD_IDX 38
#define MACRLC_BEAMWEIGHTS_IDX 39
#define MACRLC_PUSCH_RSSI_THRES_IDX 40
#define MACRLC_PUCCH_RSSI_THRES_IDX 41
#define MACRLC_STATS_MAX_UE_IDX 42
#define MACRLC_DBT_FILE_IDX 40
#define MACRLC_PUSCH_RSSI_THRES_IDX 41
#define MACRLC_PUCCH_RSSI_THRES_IDX 42
#define MACRLC_STATS_MAX_UE_IDX 43
#define MACRLCPARAMS_CHECK { \
{ .s5 = { NULL } }, \
...
...
@@ -243,6 +247,7 @@
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s2 = { config_check_intrange, {-1280, 0}} },
/* PUSCH RSSI threshold range */
\
{ .s2 = { config_check_intrange, {-1280, 0}} },
/* PUCCH RSSI threshold range */
\
{ .s5 = { NULL } }, \
...
...
openair2/GNB_APP/gnb_config.c
View file @
d448e99e
...
...
@@ -28,6 +28,9 @@
*/
#include "gnb_config.h"
#include <ctype.h>
#include <complex.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
...
...
@@ -1361,6 +1364,97 @@ static void get_bwp_config(nr_mac_config_t *configuration, const NR_ServingCellC
}
}
static
bool
parse_complex_token
(
const
char
*
tok
,
double
complex
*
out
)
{
double
re
=
0
.
0
;
double
im
=
0
.
0
;
if
(
sscanf
(
tok
,
"%lf%lfi"
,
&
re
,
&
im
)
==
2
||
sscanf
(
tok
,
"%lf%lfj"
,
&
re
,
&
im
)
==
2
)
{
*
out
=
re
+
I
*
im
;
return
true
;
}
if
(
sscanf
(
tok
,
"%lfi"
,
&
im
)
==
1
||
sscanf
(
tok
,
"%lfj"
,
&
im
)
==
1
)
{
*
out
=
I
*
im
;
return
true
;
}
if
(
sscanf
(
tok
,
"%lf"
,
&
re
)
==
1
)
{
*
out
=
re
;
return
true
;
}
return
false
;
}
static
double
complex
**
read_dbt_from_csv
(
const
char
*
filename
,
int
*
num_beams
,
int
*
num_weights_per_beam
,
uint16_t
**
beam_ids
)
{
FILE
*
fp
=
fopen
(
filename
,
"r"
);
AssertFatal
(
fp
!=
NULL
,
"Failed to open DBT CSV file '%s'
\n
"
,
filename
);
char
line
[
16384
];
AssertFatal
(
fgets
(
line
,
sizeof
(
line
),
fp
)
!=
NULL
,
"Failed to read DBT CSV header from '%s'
\n
"
,
filename
);
int
weights
=
1
;
for
(
char
*
p
=
line
;
*
p
;
++
p
)
if
(
*
p
==
','
)
weights
++
;
weights
-=
1
;
// first column is beam ID
AssertFatal
(
weights
>
0
,
"DBT CSV '%s' has no weight columns
\n
"
,
filename
);
int
beams
=
0
;
while
(
fgets
(
line
,
sizeof
(
line
),
fp
))
beams
++
;
AssertFatal
(
beams
>
0
,
"No DBT beam rows found in CSV file '%s'
\n
"
,
filename
);
rewind
(
fp
);
AssertFatal
(
fgets
(
line
,
sizeof
(
line
),
fp
)
!=
NULL
,
"Failed to reread DBT CSV header from '%s'
\n
"
,
filename
);
double
complex
**
table
=
calloc_or_fail
(
beams
,
sizeof
(
*
table
));
uint16_t
*
ids
=
calloc_or_fail
(
beams
,
sizeof
(
*
ids
));
int
b
=
0
;
while
(
fgets
(
line
,
sizeof
(
line
),
fp
))
{
line
[
strcspn
(
line
,
"
\r\n
"
)]
=
'\0'
;
char
*
saveptr
=
NULL
;
char
*
tok
=
strtok_r
(
line
,
","
,
&
saveptr
);
AssertFatal
(
tok
!=
NULL
,
"Malformed DBT row %d in '%s'
\n
"
,
b
+
1
,
filename
);
errno
=
0
;
char
*
endptr
=
NULL
;
long
beam_id
=
strtol
(
tok
,
&
endptr
,
10
);
AssertFatal
(
endptr
!=
tok
&&
errno
!=
ERANGE
&&
*
endptr
==
'\0'
&&
beam_id
>=
0
&&
beam_id
<=
UINT16_MAX
,
"Invalid DBT beam id '%s' in file '%s', beam row %d
\n
"
,
tok
,
filename
,
b
+
1
);
ids
[
b
]
=
(
uint16_t
)
beam_id
;
table
[
b
]
=
calloc_or_fail
(
weights
,
sizeof
(
*
table
[
b
]));
for
(
int
w
=
0
;
w
<
weights
;
++
w
)
{
tok
=
strtok_r
(
NULL
,
","
,
&
saveptr
);
AssertFatal
(
tok
!=
NULL
,
"Missing DBT weight in file '%s', beam row %d column %d
\n
"
,
filename
,
b
+
1
,
w
+
1
);
AssertFatal
(
parse_complex_token
(
tok
,
&
table
[
b
][
w
]),
"Invalid DBT complex weight '%s' in file '%s', beam row %d column %d
\n
"
,
tok
,
filename
,
b
+
1
,
w
+
1
);
}
AssertFatal
(
strtok_r
(
NULL
,
","
,
&
saveptr
)
==
NULL
,
"Too many DBT columns in file '%s', beam row %d
\n
"
,
filename
,
b
+
1
);
b
++
;
}
AssertFatal
(
b
==
beams
,
"Parsed %d DBT rows but counted %d in file '%s'
\n
"
,
b
,
beams
,
filename
);
fclose
(
fp
);
*
num_beams
=
beams
;
*
num_weights_per_beam
=
weights
;
*
beam_ids
=
ids
;
return
table
;
}
void
RCconfig_nr_macrlc
(
configmodule_interface_t
*
cfg
)
{
int
j
=
0
;
...
...
@@ -1620,6 +1714,16 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
for
(
int
b
=
0
;
b
<
n
;
b
++
)
config
.
bw_list
[
b
]
=
MacRLC_ParamList
.
paramarray
[
j
][
MACRLC_BEAMWEIGHTS_IDX
].
iptr
[
b
];
}
config
.
bt
.
num_beams
=
0
;
config
.
bt
.
num_weights_per_beam
=
0
;
config
.
bt
.
beam_ids
=
NULL
;
config
.
bt
.
beam_weights
=
NULL
;
char
**
fptr
=
MacRLC_ParamList
.
paramarray
[
j
][
MACRLC_DBT_FILE_IDX
].
strptr
;
if
(
fptr
&&
*
fptr
&&
**
fptr
!=
'\0'
)
{
LOG_I
(
GNB_APP
,
"loading DBT table from file %s
\n
"
,
*
fptr
);
config
.
bt
.
beam_weights
=
read_dbt_from_csv
(
*
fptr
,
&
config
.
bt
.
num_beams
,
&
config
.
bt
.
num_weights_per_beam
,
&
config
.
bt
.
beam_ids
);
}
// triggers also PHY initialization in case we have L1 via FAPI
nr_mac_config_scc
(
RC
.
nrmac
[
j
],
scc
,
&
config
);
}
// for (j=0;j<RC.nb_nr_macrlc_inst;j++)
...
...
openair2/LAYER2/NR_MAC_gNB/config.c
View file @
d448e99e
...
...
@@ -31,6 +31,7 @@
*/
#include <complex.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
...
...
@@ -64,6 +65,41 @@ c16_t convert_precoder_weight(double complex c_in)
return
(
c16_t
)
{.
r
=
round
(
SHRT_MAX
*
creal
(
c_in
)),
.
i
=
round
(
SHRT_MAX
*
cimag
(
c_in
))};
}
static
void
free_dbt_config
(
nfapi_nr_dbt_pdu_t
*
dbt
)
{
if
(
!
dbt
||
!
dbt
->
dig_beam_list
)
return
;
for
(
int
i
=
0
;
i
<
dbt
->
num_dig_beams
;
++
i
)
free
(
dbt
->
dig_beam_list
[
i
].
txru_list
);
free
(
dbt
->
dig_beam_list
);
dbt
->
dig_beam_list
=
NULL
;
dbt
->
num_dig_beams
=
0
;
dbt
->
num_txrus
=
0
;
}
static
void
log_dbt_table
(
const
nr_beam_table_t
*
bt
)
{
if
(
!
bt
||
bt
->
num_beams
<=
0
||
bt
->
num_weights_per_beam
<=
0
||
!
bt
->
beam_weights
)
return
;
LOG_I
(
NR_MAC
,
"DBT dump: num_beams=%d num_weights_per_beam=%d
\n
"
,
bt
->
num_beams
,
bt
->
num_weights_per_beam
);
for
(
int
b
=
0
;
b
<
bt
->
num_beams
;
++
b
)
{
uint16_t
beam_id
=
bt
->
beam_ids
?
bt
->
beam_ids
[
b
]
:
b
;
const
int
max_line
=
2048
;
char
line
[
max_line
];
int
off
=
snprintf
(
line
,
sizeof
(
line
),
"DBT beam[%d] id=%u:"
,
b
,
beam_id
);
for
(
int
w
=
0
;
w
<
bt
->
num_weights_per_beam
&&
off
>
-
1
&&
off
<
max_line
-
1
;
++
w
)
off
+=
snprintf
(
line
+
off
,
sizeof
(
line
)
-
off
,
" w[%d]=(%0.6f,%0.6f)"
,
w
,
creal
(
bt
->
beam_weights
[
b
][
w
]),
cimag
(
bt
->
beam_weights
[
b
][
w
]));
LOG_I
(
NR_MAC
,
"%s
\n
"
,
line
);
}
}
void
get_K1_K2
(
int
N1
,
int
N2
,
int
*
K1
,
int
*
K2
,
int
layers
)
{
// num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214
...
...
@@ -395,6 +431,45 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR
{
nfapi_nr_config_request_scf_t
*
cfg
=
&
nrmac
->
config
[
0
];
nrmac
->
common_channels
[
0
].
ServingCellConfigCommon
=
scc
;
free_dbt_config
(
&
cfg
->
dbt_config
);
if
(
config
->
bt
.
num_beams
>
0
)
{
AssertFatal
(
config
->
bt
.
beam_weights
!=
NULL
,
"DBT config invalid: num_beams=%d but beam_weights is NULL
\n
"
,
config
->
bt
.
num_beams
);
AssertFatal
(
config
->
bt
.
num_weights_per_beam
>
0
,
"DBT config invalid: num_weights_per_beam=%d
\n
"
,
config
->
bt
.
num_weights_per_beam
);
AssertFatal
(
config
->
bt
.
num_weights_per_beam
<=
UINT16_MAX
,
"DBT num_weights_per_beam %d exceeds uint16 max
\n
"
,
config
->
bt
.
num_weights_per_beam
);
AssertFatal
(
config
->
bt
.
num_beams
<=
UINT16_MAX
,
"DBT num_beams %d exceeds uint16 max
\n
"
,
config
->
bt
.
num_beams
);
cfg
->
dbt_config
.
num_dig_beams
=
(
uint16_t
)
config
->
bt
.
num_beams
;
cfg
->
dbt_config
.
num_txrus
=
(
uint16_t
)
config
->
bt
.
num_weights_per_beam
;
cfg
->
dbt_config
.
dig_beam_list
=
calloc_or_fail
(
cfg
->
dbt_config
.
num_dig_beams
,
sizeof
(
*
cfg
->
dbt_config
.
dig_beam_list
));
for
(
uint16_t
b
=
0
;
b
<
cfg
->
dbt_config
.
num_dig_beams
;
++
b
)
{
nfapi_nr_dig_beam_t
*
beam
=
&
cfg
->
dbt_config
.
dig_beam_list
[
b
];
beam
->
beam_idx
=
config
->
bt
.
beam_ids
?
config
->
bt
.
beam_ids
[
b
]
:
b
;
beam
->
txru_list
=
calloc_or_fail
(
cfg
->
dbt_config
.
num_txrus
,
sizeof
(
*
beam
->
txru_list
));
for
(
uint16_t
w
=
0
;
w
<
cfg
->
dbt_config
.
num_txrus
;
++
w
)
{
float
re
=
crealf
(
config
->
bt
.
beam_weights
[
b
][
w
]);
float
im
=
cimagf
(
config
->
bt
.
beam_weights
[
b
][
w
]);
AssertFatal
(
re
>
-
1
.
0
f
&&
re
<
1
.
0
f
,
"DBT real weight out of range [-1,1]: %f
\n
"
,
re
);
AssertFatal
(
im
>
-
1
.
0
f
&&
im
<
1
.
0
f
,
"DBT imag weight out of range [-1,1]: %f
\n
"
,
im
);
c16_t
q15
=
convert_precoder_weight
(
config
->
bt
.
beam_weights
[
b
][
w
]);
beam
->
txru_list
[
w
].
dig_beam_weight_Re
=
(
uint16_t
)
q15
.
r
;
beam
->
txru_list
[
w
].
dig_beam_weight_Im
=
(
uint16_t
)
q15
.
i
;
}
}
LOG_I
(
NR_MAC
,
"Loaded DBT: num_beams=%d num_weights_per_beam=%d
\n
"
,
config
->
bt
.
num_beams
,
config
->
bt
.
num_weights_per_beam
);
log_dbt_table
(
&
config
->
bt
);
}
// Carrier configuration
NR_FrequencyInfoDL_t
*
frequencyInfoDL
=
scc
->
downlinkConfigCommon
->
frequencyInfoDL
;
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
d448e99e
...
...
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <complex.h>
#include <pthread.h>
#include "common/utils/ds/seq_arr.h"
#include "common/utils/nr/nr_common.h"
...
...
@@ -184,6 +185,13 @@ typedef enum {
SSB_SINR
,
}
nr_config_report_type_t
;
typedef
struct
nr_beam_table
{
int
num_weights_per_beam
;
int
num_beams
;
uint16_t
*
beam_ids
;
double
complex
**
beam_weights
;
}
nr_beam_table_t
;
typedef
struct
nr_mac_config_s
{
nr_pdsch_AntennaPorts_t
pdsch_AntennaPorts
;
int
pusch_AntennaPorts
;
...
...
@@ -213,6 +221,7 @@ typedef struct nr_mac_config_s {
nr_redcap_config_t
*
redcap
;
nr_ptrs_config_t
*
ptrs
;
nr_config_report_type_t
report_type
;
nr_beam_table_t
bt
;
}
nr_mac_config_t
;
typedef
struct
NR_preamble_ue
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment