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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
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
spbro
OpenXG-RAN
Commits
d8572d55
Commit
d8572d55
authored
Jun 19, 2024
by
Bartosz Podrygajlo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed MPR application conditions.
Fixed delta MPR. Fixed an error in PUCCH PC_MAX calculation.
parent
707aab3a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
226 additions
and
87 deletions
+226
-87
common/utils/nr/nr_common.c
common/utils/nr/nr_common.c
+2
-2
openair2/LAYER2/NR_MAC_UE/mac_proto.h
openair2/LAYER2/NR_MAC_UE/mac_proto.h
+10
-10
openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
+92
-62
openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
...r2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
+122
-13
No files found.
common/utils/nr/nr_common.c
View file @
d8572d55
...
...
@@ -356,8 +356,8 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_
int
band_size_khz
=
get_supported_bw_mhz
(
nr_band
>
256
?
FR2
:
FR1
,
scs
,
nb_ul
)
*
1000
;
float
limit
=
frame_type
==
TDD
?
0
.
04
:
0
.
03
;
float
rel_bw
=
(
float
)
(
2
*
band_size_khz
)
/
(
float
)
(
nr_bandtable
[
index
].
ul_max
+
nr_bandtable
[
index
].
ul_min
);
return
rel_bw
<=
limit
;
float
rel_bw
=
(
float
)
(
band_size_khz
)
/
(
float
)
(
nr_bandtable
[
index
].
ul_max
-
nr_bandtable
[
index
].
ul_min
);
return
rel_bw
>
limit
;
}
uint16_t
get_band
(
uint64_t
downlink_frequency
,
int32_t
delta_duplex
)
...
...
openair2/LAYER2/NR_MAC_UE/mac_proto.h
View file @
d8572d55
...
...
@@ -227,16 +227,16 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t
*
pucch
,
fapi_nr_ul_config_pucch_pdu
*
pucch_pdu
);
in
t
nr_get_Pcmax
(
int
p_Max
,
uint16_t
nr_band
,
frequency_range_t
frequency_range
,
int
Qm
,
bool
powerBoostPi2BPSK
,
int
scs
,
int
N_RB_UL
,
bool
is_transform_precoding
,
int
n_prbs
,
int
start_prb
);
floa
t
nr_get_Pcmax
(
int
p_Max
,
uint16_t
nr_band
,
frequency_range_t
frequency_range
,
int
Qm
,
bool
powerBoostPi2BPSK
,
int
scs
,
int
N_RB_UL
,
bool
is_transform_precoding
,
int
n_prbs
,
int
start_prb
);
int
get_sum_delta_pucch
(
NR_UE_MAC_INST_t
*
mac
,
int
slot
,
frame_t
frame
);
...
...
openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
View file @
d8572d55
...
...
@@ -65,62 +65,34 @@ static int get_deltatf(uint16_t nb_of_prbs,
int
N_sc_ctrl_RB
,
int
O_UCI
);
// Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3
// -- no additional MPR (A_MPR_c)
int
nr_get_Pcmax
(
int
p_Max
,
uint16_t
nr_band
,
frequency_range_t
frequency_range
,
int
Qm
,
bool
powerBoostPi2BPSK
,
int
scs
,
int
N_RB_UL
,
bool
is_transform_precoding
,
int
n_prbs
,
int
start_prb
)
// ∆MPR according to Table 6.2.2-3 38.101-1
static
float
get_delta_mpr
(
uint16_t
nr_band
,
int
scs
,
int
N_RB_UL
,
int
n_prbs
,
int
start_prb
,
int
power_class
)
{
if
(
frequency_range
==
FR1
)
{
// TODO configure P-MAX from the upper layers according to 38.331
int
p_powerclass
=
23
;
// dBm assuming poweclass 3 UE
int
p_emax
=
p_Max
!=
INT_MIN
?
p_Max
:
p_powerclass
;
int
delta_P_powerclass
=
0
;
// for powerclass 2 needs to be changed
if
(
p_Max
&&
Qm
==
1
&&
powerBoostPi2BPSK
&&
(
nr_band
==
40
||
nr_band
==
41
||
nr_band
==
77
||
nr_band
==
78
||
nr_band
==
79
))
{
p_emax
+=
3
;
delta_P_powerclass
-=
3
;
frame_type_t
frame_type
=
get_frame_type
(
nr_band
,
scs
);
if
(
compare_relative_ul_channel_bw
(
nr_band
,
scs
,
N_RB_UL
,
frame_type
))
{
if
(
power_class
==
3
)
{
if
((
nr_band
==
28
||
nr_band
==
83
)
&&
get_supported_bw_mhz
(
nr_band
>
256
?
FR2
:
FR1
,
scs
,
N_RB_UL
)
==
30
)
{
return
0
.
5
f
;
}
}
if
(
power_class
==
3
||
power_class
==
2
)
{
if
((
nr_band
==
40
||
nr_band
==
97
)
&&
get_supported_bw_mhz
(
nr_band
>
256
?
FR2
:
FR1
,
scs
,
N_RB_UL
)
==
100
)
{
return
1
.
0
f
;
}
}
}
return
0
;
}
// TODO to be set for CA and DC
int
delta_T_IB
=
0
;
// TODO in case of band 41 and PRB allocation within 4MHz of the upper or lower limit of the band -> delta_TC = 1.5
if
(
nr_band
==
41
)
LOG_E
(
NR_MAC
,
"Need to implement delta_TC for band 41
\n
"
);
int
delta_TC
=
0
;
float
MPR
=
0
;
frame_type_t
frame_type
=
get_frame_type
(
nr_band
,
scs
);
if
(
compare_relative_ul_channel_bw
(
nr_band
,
scs
,
N_RB_UL
,
frame_type
))
{
int
rb_low
=
(
n_prbs
/
2
)
>
1
?
(
n_prbs
/
2
)
:
1
;
int
rb_high
=
N_RB_UL
-
rb_low
-
n_prbs
;
bool
is_inner_rb
=
start_prb
>=
rb_low
&&
start_prb
<=
rb_high
&&
n_prbs
<=
((
N_RB_UL
/
2
)
+
(
N_RB_UL
&
1
));
// MPR according to 38-101 6.2.2
static
float
get_mpr
(
int
Qm
,
int
N_RB_UL
,
bool
is_transform_precoding
,
int
n_prbs
,
int
start_prb
,
int
power_class
)
{
float
MPR
=
0
;
int
rb_low
=
(
n_prbs
/
2
)
>
1
?
(
n_prbs
/
2
)
:
1
;
int
rb_high
=
N_RB_UL
-
rb_low
-
n_prbs
;
bool
is_inner_rb
=
start_prb
>=
rb_low
&&
start_prb
<=
rb_high
&&
n_prbs
<=
((
N_RB_UL
/
2
)
+
(
N_RB_UL
&
1
));
switch
(
power_class
)
{
case
3
:
// Table 6.2.2-1 in 38.101
switch
(
Qm
)
{
case
1
:
...
...
@@ -166,16 +138,73 @@ int nr_get_Pcmax(int p_Max,
default:
AssertFatal
(
false
,
"Invalid Qm %d
\n
"
,
Qm
);
}
break
;
default:
AssertFatal
(
false
,
"PowerClass != 3 not implemented
\n
"
);
}
return
MPR
;
}
// Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3
// -- no additional MPR (A_MPR_c)
float
nr_get_Pcmax
(
int
p_Max
,
uint16_t
nr_band
,
frequency_range_t
frequency_range
,
int
Qm
,
bool
powerBoostPi2BPSK
,
int
scs
,
int
N_RB_UL
,
bool
is_transform_precoding
,
int
n_prbs
,
int
start_prb
)
{
const
int
power_class
=
3
;
// Assume power class 3
if
(
frequency_range
==
FR1
)
{
// TODO configure P-MAX from the upper layers according to 38.331
int
p_powerclass
=
23
;
// dBm assuming poweclass 3 UE
int
p_emax
=
p_Max
!=
INT_MIN
?
p_Max
:
p_powerclass
;
int
delta_P_powerclass
=
0
;
// for powerclass 2 needs to be changed
if
(
p_Max
&&
Qm
==
1
&&
powerBoostPi2BPSK
&&
(
nr_band
==
40
||
nr_band
==
41
||
nr_band
==
77
||
nr_band
==
78
||
nr_band
==
79
))
{
p_emax
+=
3
;
delta_P_powerclass
-=
3
;
}
// TODO to be set for CA and DC
int
delta_T_IB
=
0
;
// TODO in case of band 41 and PRB allocation within 4MHz of the upper or lower limit of the band -> delta_TC = 1.5
if
(
nr_band
==
41
)
LOG_E
(
NR_MAC
,
"Need to implement delta_TC for band 41
\n
"
);
int
delta_TC
=
0
;
float
MPR
=
get_mpr
(
Qm
,
N_RB_UL
,
is_transform_precoding
,
n_prbs
,
start_prb
,
power_class
);
float
delta_MPR
=
get_delta_mpr
(
nr_band
,
scs
,
N_RB_UL
,
n_prbs
,
start_prb
,
power_class
);
int
A_MPR
=
0
;
// TODO too complicated to implement for now (see 6.2.3 in 38.101-1)
int
delta_rx_SRS
=
0
;
// TODO for SRS
int
P_MPR
=
0
;
// to ensure compliance with applicable electromagnetic energy absorption requirements
float
total_reduction
=
(
MPR
>
A_MPR
?
MPR
:
A_MPR
)
+
delta_T_IB
+
delta_TC
+
delta_rx_SRS
;
if
(
P_MPR
>
total_reduction
)
total_reduction
=
P_MPR
;
int
pcmax_high
,
pcmax_low
;
float
total_reduction
=
max
(
max
(
MPR
+
delta_MPR
,
A_MPR
)
+
delta_T_IB
+
delta_TC
+
delta_rx_SRS
,
P_MPR
);
float
pcmax_high
,
pcmax_low
;
if
(
p_Max
)
{
pcmax_high
=
p_emax
<
(
p_powerclass
-
delta_P_powerclass
)
?
p_emax
:
(
p_powerclass
-
delta_P_powerclass
);
pcmax_low
=
(
p_emax
-
delta_TC
)
<
(
p_powerclass
-
delta_P_powerclass
-
total_reduction
)
...
...
@@ -186,8 +215,8 @@ int nr_get_Pcmax(int p_Max,
pcmax_low
=
p_powerclass
-
delta_P_powerclass
-
total_reduction
;
}
// TODO we need a strategy to select a value between minimum and maximum allowed PC_max
in
t
pcmax
=
(
pcmax_low
+
pcmax_high
)
/
2
;
LOG_D
(
MAC
,
"Configured maximum output power: %
d dBm <= PCMAX %d dBm <= %d
dBm
\n
"
,
pcmax_low
,
pcmax
,
pcmax_high
);
floa
t
pcmax
=
(
pcmax_low
+
pcmax_high
)
/
2
;
LOG_D
(
MAC
,
"Configured maximum output power: %
f dBm <= PCMAX %f dBm <= %f
dBm
\n
"
,
pcmax_low
,
pcmax
,
pcmax_high
);
return
pcmax
;
}
else
{
// FR2 TODO it is even more complex because it is radiated power
...
...
@@ -297,8 +326,9 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
delta_F_PUCCH
=
*
delta_F_PUCCH_config
;
}
// PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
// TODO: P_CMAX for format 2
// 38.101-1: The allowed MPR for SRS, PUCCH formats 0, 1, 3 and 4, and PRACH shall be as specified for QPSK modulated DFT-
// s-OFDM of equivalent RB allocation. The allowed MPR for PUCCH format 2 shall be as specified for QPSK
// modulated CP-OFDM of equivalent RB allocation.
int
P_CMAX
=
nr_get_Pcmax
(
mac
->
p_Max
,
mac
->
nr_band
,
mac
->
frequency_range
,
...
...
@@ -306,7 +336,7 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
false
,
mac
->
current_UL_BWP
->
scs
,
mac
->
current_UL_BWP
->
BWPSize
,
true
,
format_type
==
2
,
1
,
start_prb
);
int
P_CMIN
=
-
40
;
// TODO: minimum TX power, possibly 38.101-1 6.3.1
...
...
openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
View file @
d8572d55
...
...
@@ -19,43 +19,152 @@
* contact@openairinterface.org
*/
#include "gtest/gtest.h"
extern
"C"
{
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "executables/softmodem-common.h"
uint64_t
get_softmodem_optmask
(
void
)
{
return
0
;}
uint64_t
get_softmodem_optmask
(
void
)
{
return
0
;
}
static
softmodem_params_t
softmodem_params
;
softmodem_params_t
*
get_softmodem_params
(
void
)
{
softmodem_params_t
*
get_softmodem_params
(
void
)
{
return
&
softmodem_params
;
}
}
#include <cstdio>
#include "common/utils/LOG/log.h"
TEST
(
power_procedures_fr1
,
test_prach_max_tx_power
_mpr
)
TEST
(
test_pcmax
,
test
_mpr
)
{
// Inner PRB, MPR = 1.5
// Inner PRB, MPR = 1.5
, no delta MPR
int
prb_start
=
4
;
int
N_RB_UL
=
51
;
// 10Mhz
EXPECT_EQ
(
22
,
nr_get_Pcmax
(
23
,
20
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
6
,
prb_start
));
int
nr_band
=
20
;
float
expected_power
=
23
-
(
1.5
/
2
);
EXPECT_EQ
(
expected_power
,
nr_get_Pcmax
(
23
,
nr_band
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
6
,
prb_start
));
// Outer PRB, MPR = 3
// Outer PRB, MPR = 3
, no delta MPR
prb_start
=
0
;
EXPECT_EQ
(
21
,
nr_get_Pcmax
(
23
,
20
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
6
,
prb_start
));
expected_power
=
23
-
(
3.0
/
2
);
EXPECT_EQ
(
expected_power
,
nr_get_Pcmax
(
23
,
nr_band
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
6
,
prb_start
));
// Channel bandwidth conditon not met, no MPR
N_RB_UL
=
106
;
EXPECT_EQ
(
23
,
nr_get_Pcmax
(
23
,
20
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
6
,
prb_start
));
// Outer PRB on band 28, MPR = 3, delta MPR = 0.5 dB
N_RB_UL
=
78
;
nr_band
=
28
;
expected_power
=
23
-
((
3.0
+
0.5
)
/
2
);
EXPECT_EQ
(
expected_power
,
nr_get_Pcmax
(
23
,
nr_band
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
100
,
prb_start
));
}
TEST
(
power_procedures_fr1
,
test_not_implemented
)
TEST
(
test_pcmax
,
test_not_implemented
)
{
int
N_RB_UL
=
51
;
EXPECT_DEATH
(
nr_get_Pcmax
(
23
,
20
,
FR1
,
1
,
false
,
1
,
N_RB_UL
,
false
,
6
,
0
),
"MPR for Pi/2 BPSK not implemented yet"
);
}
TEST
(
test_pcmax
,
test_pucch_max_power
)
{
// Format 2, transform precoding, MPR = 1
int
prb_start
=
0
;
int
N_RB_UL
=
51
;
// 10Mhz
float
expected_power
=
23
-
(
1.0
/
2
);
EXPECT_EQ
(
expected_power
,
nr_get_Pcmax
(
23
,
20
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
true
,
1
,
prb_start
));
// Other fromats, no transform precoding, MPR = 3
expected_power
=
23
-
(
3.0
/
2
);
EXPECT_EQ
(
expected_power
,
nr_get_Pcmax
(
23
,
20
,
FR1
,
2
,
false
,
1
,
N_RB_UL
,
false
,
1
,
prb_start
));
}
TEST
(
test_pucch_power_state
,
test_accumulated_delta_pucch
)
{
NR_UE_MAC_INST_t
mac
=
{
0
};
NR_UE_UL_BWP_t
current_UL_BWP
=
{
0
};
current_UL_BWP
.
scs
=
1
;
current_UL_BWP
.
BWPSize
=
106
;
NR_PUCCH_ConfigCommon_t
pucch_ConfigCommon
=
{
0
};
mac
.
current_UL_BWP
=
&
current_UL_BWP
;
mac
.
current_UL_BWP
->
pucch_ConfigCommon
=
&
pucch_ConfigCommon
;
mac
.
nr_band
=
20
;
NR_PUCCH_Config_t
pucch_Config
=
{
0
};
struct
NR_PUCCH_PowerControl
power_config
;
pucch_Config
.
pucch_PowerControl
=
&
power_config
;
mac
.
G_b_f_c
=
0
;
mac
.
pucch_power_control_initialized
=
true
;
int
scs
=
1
;
int
sum_delta_pucch
=
3
;
uint8_t
format_type
=
1
;
uint16_t
nb_of_prbs
=
1
;
uint8_t
freq_hop_flag
=
0
;
uint8_t
add_dmrs_flag
=
0
;
uint8_t
N_symb_PUCCH
=
12
;
int
subframe_number
=
0
;
int
O_uci
=
2
;
uint16_t
start_prb
=
0
;
int
P_CMAX
=
nr_get_Pcmax
(
23
,
mac
.
nr_band
,
FR1
,
2
,
false
,
current_UL_BWP
.
scs
,
current_UL_BWP
.
BWPSize
,
false
,
nb_of_prbs
,
start_prb
);
int
pucch_power_prev
=
get_pucch_tx_power_ue
(
&
mac
,
scs
,
&
pucch_Config
,
sum_delta_pucch
,
format_type
,
nb_of_prbs
,
freq_hop_flag
,
add_dmrs_flag
,
N_symb_PUCCH
,
subframe_number
,
O_uci
,
start_prb
);
EXPECT_LT
(
pucch_power_prev
,
P_CMAX
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
int
pucch_power_state
=
mac
.
G_b_f_c
;
int
pucch_power
=
get_pucch_tx_power_ue
(
&
mac
,
scs
,
&
pucch_Config
,
sum_delta_pucch
,
format_type
,
nb_of_prbs
,
freq_hop_flag
,
add_dmrs_flag
,
N_symb_PUCCH
,
subframe_number
,
O_uci
,
start_prb
);
if
(
pucch_power_prev
==
P_CMAX
)
{
EXPECT_EQ
(
pucch_power_state
,
mac
.
G_b_f_c
)
<<
"PUCCH power control state increased after reaching max TX power"
;
}
EXPECT_LE
(
pucch_power
,
P_CMAX
)
<<
"PUUCH TX power above P_CMAX"
;
EXPECT_EQ
(
std
::
min
(
P_CMAX
,
pucch_power_prev
+
sum_delta_pucch
),
pucch_power
)
<<
"PUCCH power expected to change by delta pucch only, between P_CMAX and P_CMIN"
;
pucch_power_prev
=
pucch_power
;
if
(
i
>
5
)
{
EXPECT_EQ
(
pucch_power
,
P_CMAX
)
<<
"Expected to reach MAX PUCCH TX power"
;
}
}
sum_delta_pucch
=
-
15
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
int
pucch_power_state
=
mac
.
G_b_f_c
;
int
pucch_power
=
get_pucch_tx_power_ue
(
&
mac
,
scs
,
&
pucch_Config
,
sum_delta_pucch
,
format_type
,
nb_of_prbs
,
freq_hop_flag
,
add_dmrs_flag
,
N_symb_PUCCH
,
subframe_number
,
O_uci
,
start_prb
);
EXPECT_LE
(
mac
.
G_b_f_c
,
pucch_power_state
)
<<
"PUCCH power control state increased with negative delta pucch"
;
pucch_power_prev
=
pucch_power
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
logInit
();
...
...
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