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
7264f9e0
Commit
7264f9e0
authored
Jun 28, 2024
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/nr-ue-pusch-power-control' into integration_2024_w26b
parents
5af81bbc
8ea2e77a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
569 additions
and
88 deletions
+569
-88
common/utils/nr/nr_common.c
common/utils/nr/nr_common.c
+2
-2
nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+1
-0
openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+1
-0
openair2/LAYER2/NR_MAC_UE/config_ue.c
openair2/LAYER2/NR_MAC_UE/config_ue.c
+5
-0
openair2/LAYER2/NR_MAC_UE/mac_proto.h
openair2/LAYER2/NR_MAC_UE/mac_proto.h
+26
-10
openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c
+234
-63
openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+16
-0
openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
...r2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
+284
-13
No files found.
common/utils/nr/nr_common.c
View file @
7264f9e0
...
...
@@ -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
)
...
...
nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
View file @
7264f9e0
...
...
@@ -359,6 +359,7 @@ typedef struct
nfapi_nr_ue_ul_beamforming_t
beamforming
;
//OAI specific
int8_t
absolute_delta_PUSCH
;
int16_t
tx_power
;
fapi_nr_tx_request_body_t
tx_request_body
;
}
nfapi_nr_ue_pusch_pdu_t
;
...
...
openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
View file @
7264f9e0
...
...
@@ -571,6 +571,7 @@ typedef struct NR_UE_UL_BWP {
uint8_t
mcs_table
;
nr_dci_format_t
dci_format
;
int
max_fb_time
;
long
*
p0_NominalWithGrant
;
}
NR_UE_UL_BWP_t
;
// non-BWP serving cell configuration
...
...
openair2/LAYER2/NR_MAC_UE/config_ue.c
View file @
7264f9e0
...
...
@@ -1409,11 +1409,14 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up
ul_common
->
pusch_ConfigCommon
->
choice
.
setup
->
pusch_TimeDomainAllocationList
,
NR_PUSCH_TimeDomainResourceAllocationList_t
);
UPDATE_IE
(
bwp
->
msg3_DeltaPreamble
,
ul_common
->
pusch_ConfigCommon
->
choice
.
setup
->
msg3_DeltaPreamble
,
long
);
UPDATE_IE
(
bwp
->
p0_NominalWithGrant
,
ul_common
->
pusch_ConfigCommon
->
choice
.
setup
->
p0_NominalWithGrant
,
long
);
}
if
(
ul_common
->
pusch_ConfigCommon
->
present
==
NR_SetupRelease_PUSCH_ConfigCommon_PR_release
)
{
asn1cFreeStruc
(
asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList
,
bwp
->
tdaList_Common
);
free
(
bwp
->
msg3_DeltaPreamble
);
bwp
->
msg3_DeltaPreamble
=
NULL
;
free
(
bwp
->
p0_NominalWithGrant
);
bwp
->
p0_NominalWithGrant
=
NULL
;
}
}
}
...
...
@@ -2130,6 +2133,8 @@ void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index)
asn1cFreeStruc
(
asn_DEF_NR_SRS_Config
,
bwp
->
srs_Config
);
free
(
bwp
->
msg3_DeltaPreamble
);
bwp
->
msg3_DeltaPreamble
=
NULL
;
free
(
bwp
->
p0_NominalWithGrant
);
bwp
->
p0_NominalWithGrant
=
NULL
;
free
(
bwp
);
}
...
...
openair2/LAYER2/NR_MAC_UE/mac_proto.h
View file @
7264f9e0
...
...
@@ -219,6 +219,20 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int
subframe_number
,
int
O_uci
,
uint16_t
start_prb
);
int
get_pusch_tx_power_ue
(
NR_UE_MAC_INST_t
*
mac
,
int
num_rb
,
int
start_prb
,
uint16_t
nb_symb_sch
,
uint16_t
nb_dmrs_prb
,
uint16_t
nb_ptrs_prb
,
uint16_t
qm
,
uint16_t
R
,
uint16_t
beta_offset_csi1
,
uint32_t
sum_bits_in_codeblocks
,
int
delta_pusch
,
bool
is_rar_tx_retx
,
bool
transform_precoding
);
int
nr_ue_configure_pucch
(
NR_UE_MAC_INST_t
*
mac
,
int
slot
,
...
...
@@ -227,16 +241,18 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t
*
pucch
,
fapi_nr_ul_config_pucch_pdu
*
pucch_pdu
);
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
);
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
);
float
nr_get_Pcmin
(
int
scs
,
int
nr_band
,
int
N_RB_UL
);
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 @
7264f9e0
...
...
@@ -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
...
...
@@ -195,6 +224,14 @@ int nr_get_Pcmax(int p_Max,
}
}
float
nr_get_Pcmin
(
int
scs
,
int
nr_band
,
int
N_RB_UL
)
{
int
band_index
=
get_supported_band_index
(
nr_band
>
256
?
FR2
:
FR1
,
scs
,
N_RB_UL
);
const
float
table_38101_6_3_1_1
[]
=
{
-
40
,
-
40
,
-
40
,
-
40
,
-
39
,
-
38
.
2
,
-
37
.
5
,
-
37
,
-
36
.
5
,
-
35
.
2
,
-
34
.
6
,
-
34
,
-
33
.
5
,
-
33
};
return
table_38101_6_3_1_1
[
band_index
];
}
// This is not entirely correct. In certain k2/k1/k0 settings we might postpone accumulating delta_PUCCH until next HARQ feedback
// slot. The correct way to do this would be to calculate the K_PUCCH (delta_PUCCH summation window end) for each PUCCH occasion and
// compare PUCCH transmission symbol with the reception symbol of the DCI containing delta_PUCCH to determine if the delta_PUCCH
...
...
@@ -297,8 +334,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,10 +344,10 @@ 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
int
P_CMIN
=
nr_get_Pcmin
(
mac
->
current_UL_BWP
->
scs
,
mac
->
nr_band
,
mac
->
current_UL_BWP
->
BWPSize
);
int16_t
pathloss
=
compute_nr_SSB_PL
(
mac
,
mac
->
ssb_measurements
.
ssb_rsrp_dBm
);
if
(
power_config
->
twoPUCCH_PC_AdjustmentStates
&&
*
power_config
->
twoPUCCH_PC_AdjustmentStates
>
1
)
{
...
...
@@ -396,3 +434,136 @@ int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
return
pathloss
;
}
// PUSCH transmission power according to 38.213 7.1
int
get_pusch_tx_power_ue
(
NR_UE_MAC_INST_t
*
mac
,
int
num_rb
,
int
start_prb
,
uint16_t
nb_symb_sch
,
uint16_t
nb_dmrs_prb
,
uint16_t
nb_ptrs_prb
,
uint16_t
qm
,
uint16_t
R
,
uint16_t
beta_offset_csi1
,
uint32_t
sum_bits_in_codeblocks
,
int
delta_pusch
,
bool
is_rar_tx_retx
,
bool
transform_precoding
)
{
LOG_D
(
NR_MAC
,
"PUSCH tx power determination num_rb=%d start_prb=%d nb_symb_sch=%u nb_dmrs_prb=%u nb_ptrs_prb=%u Qm=%u R= %u "
"beta_offset_cs1=%u sum_bits_in_codeblocks=%u delta_pusch=%d is_rar_tx_retx=%d transform_precoding=%d
\n
"
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
qm
,
R
,
beta_offset_csi1
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
transform_precoding
);
NR_UE_UL_BWP_t
*
current_UL_BWP
=
mac
->
current_UL_BWP
;
AssertFatal
(
current_UL_BWP
,
"Missing configuration: need UL_BWP to calculate PUSCH tx power
\n
"
);
NR_PUSCH_Config_t
*
pusch_Config
=
current_UL_BWP
->
pusch_Config
;
bool
has_pusch_config
=
pusch_Config
!=
NULL
;
bool
has_pusch_power_control_config
=
has_pusch_config
&&
pusch_Config
->
pusch_PowerControl
!=
NULL
;
bool
is_provided_alpha_sets
=
has_pusch_power_control_config
&&
pusch_Config
->
pusch_PowerControl
->
p0_AlphaSets
!=
NULL
;
AssertFatal
(
!
has_pusch_power_control_config
||
pusch_Config
->
pusch_PowerControl
->
sri_PUSCH_MappingToAddModList
==
NULL
,
"SRI-PUSCH-PowerControl handling not implemented
\n
"
);
int
P_O_NOMINAL_PUSCH
;
float
alpha
;
const
float
alpha_factor_table
[
8
]
=
{
0
.
0
f
,
0
.
4
f
,
0
.
5
f
,
0
.
6
f
,
0
.
7
f
,
0
.
8
f
,
0
.
9
f
,
1
.
0
f
};
if
(
is_rar_tx_retx
||
!
is_provided_alpha_sets
||
current_UL_BWP
->
p0_NominalWithGrant
==
NULL
)
{
int
DELTA_PREAMBLE_MSG3
=
0
;
if
(
current_UL_BWP
->
msg3_DeltaPreamble
)
{
DELTA_PREAMBLE_MSG3
=
*
current_UL_BWP
->
msg3_DeltaPreamble
;
}
NR_RACH_ConfigCommon_t
*
nr_rach_ConfigCommon
=
current_UL_BWP
->
rach_ConfigCommon
;
long
preambleReceivedTargetPower
=
nr_rach_ConfigCommon
->
rach_ConfigGeneric
.
preambleReceivedTargetPower
;
int
P_O_PRE
=
preambleReceivedTargetPower
;
P_O_NOMINAL_PUSCH
=
P_O_PRE
+
DELTA_PREAMBLE_MSG3
;
if
(
has_pusch_power_control_config
&&
pusch_Config
->
pusch_PowerControl
->
msg3_Alpha
)
{
alpha
=
alpha_factor_table
[
*
pusch_Config
->
pusch_PowerControl
->
msg3_Alpha
];
}
else
{
alpha
=
1
.
0
f
;
}
}
else
{
P_O_NOMINAL_PUSCH
=
*
current_UL_BWP
->
p0_NominalWithGrant
;
if
(
pusch_Config
->
pusch_PowerControl
->
p0_AlphaSets
->
list
.
array
[
0
]
->
alpha
)
{
alpha
=
alpha_factor_table
[
*
pusch_Config
->
pusch_PowerControl
->
p0_AlphaSets
->
list
.
array
[
0
]
->
alpha
];
}
else
{
// Default according to 38.331 P0-PUSCH-AlphaSet field descriptions
alpha
=
1
.
0
f
;
}
}
int
P_O_UE_PUSCH
;
if
(
is_rar_tx_retx
||
!
is_provided_alpha_sets
)
{
P_O_UE_PUSCH
=
0
;
}
else
{
if
(
pusch_Config
->
pusch_PowerControl
->
p0_AlphaSets
->
list
.
array
[
0
]
->
p0
)
{
P_O_UE_PUSCH
=
*
pusch_Config
->
pusch_PowerControl
->
p0_AlphaSets
->
list
.
array
[
0
]
->
p0
;
}
else
{
// Default according to 38.331 P0-PUSCH-AlphaSet field descriptions
P_O_UE_PUSCH
=
0
;
}
}
int
mu
=
current_UL_BWP
->
scs
;
int
M_pusch_component
=
10
*
log10
((
pow
(
2
,
mu
))
*
num_rb
);
int
P_CMAX
=
nr_get_Pcmax
(
mac
->
p_Max
,
mac
->
nr_band
,
mac
->
frequency_range
,
2
,
false
,
mac
->
current_UL_BWP
->
scs
,
mac
->
current_UL_BWP
->
BWPSize
,
transform_precoding
,
1
,
start_prb
);
int
P_O_PUSCH
=
P_O_NOMINAL_PUSCH
+
P_O_UE_PUSCH
;
float
DELTA_TF
=
0
;
if
(
has_pusch_power_control_config
&&
pusch_Config
->
pusch_PowerControl
->
deltaMCS
)
{
float
beta_offset
=
1
;
float
BPRE
;
if
(
sum_bits_in_codeblocks
==
0
)
{
float
table_38_213_9_3_2
[]
=
{
1
.
125
,
11
.
250
,
21
.
375
,
31
.
625
,
41
.
750
,
52
.
000
,
62
.
250
,
72
.
500
,
82
.
875
,
93
.
125
,
103
.
500
,
114
.
000
,
125
.
000
,
136
.
250
,
148
.
000
,
1510
.
000
,
1612
.
625
,
1715
.
875
,
1820
.
000
,
};
beta_offset
=
table_38_213_9_3_2
[
beta_offset_csi1
];
BPRE
=
(
qm
*
R
/
beta_offset
)
/
1024
;
}
else
{
const
int
nb_subcarrier_per_rb
=
12
;
const
uint32_t
N_RE
=
nb_subcarrier_per_rb
*
nb_symb_sch
-
nb_dmrs_prb
-
nb_ptrs_prb
;
BPRE
=
sum_bits_in_codeblocks
/
(
float
)(
N_RE
*
num_rb
);
}
DELTA_TF
=
10
*
log10
(
pow
(
2
,
BPRE
*
1
.
25
f
)
*
beta_offset
);
}
// TODO: compute pathoss using correct reference
int16_t
pathloss
=
compute_nr_SSB_PL
(
mac
,
mac
->
ssb_measurements
.
ssb_rsrp_dBm
);
int
f_b_f_c
=
0
;
if
(
has_pusch_power_control_config
&&
pusch_Config
->
pusch_PowerControl
->
tpc_Accumulation
)
{
f_b_f_c
=
delta_pusch
;
}
else
{
// TODO: PUSCH power control state
}
LOG_D
(
NR_MAC
,
"PUSCH tx power components P_O_PUSCH=%d, M_pusch_component=%d, alpha*pathloss=%f, delta_TF=%f, f_b_f_c=%d
\n
"
,
P_O_PUSCH
,
M_pusch_component
,
alpha
*
pathloss
,
DELTA_TF
,
f_b_f_c
);
return
min
(
P_CMAX
,
P_O_PUSCH
+
M_pusch_component
+
alpha
*
pathloss
+
DELTA_TF
+
f_b_f_c
);
}
openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
View file @
7264f9e0
...
...
@@ -913,6 +913,22 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu
->
pusch_data
.
tb_size
=
mac
->
ul_harq_info
[
pid
].
TBS
;
}
bool
is_rar_tx_retx
=
rnti_type
==
TYPE_TC_RNTI_
;
pusch_config_pdu
->
tx_power
=
get_pusch_tx_power_ue
(
mac
,
pusch_config_pdu
->
rb_size
,
pusch_config_pdu
->
rb_start
,
pusch_config_pdu
->
nr_of_symbols
,
nb_dmrs_re_per_rb
*
number_dmrs_symbols
,
0
,
//TODO: count PTRS per RB
pusch_config_pdu
->
qam_mod_order
,
pusch_config_pdu
->
target_code_rate
,
pusch_config_pdu
->
pusch_uci
.
beta_offset_csi1
,
pusch_config_pdu
->
pusch_data
.
tb_size
<<
3
,
pusch_config_pdu
->
absolute_delta_PUSCH
,
is_rar_tx_retx
,
pusch_config_pdu
->
transform_precoding
);
pusch_config_pdu
->
ldpcBaseGraph
=
get_BG
(
pusch_config_pdu
->
pusch_data
.
tb_size
<<
3
,
pusch_config_pdu
->
target_code_rate
);
//The MAC entity shall restart retxBSR-Timer upon reception of a grant for transmission of new data on any UL-SCH
...
...
openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp
View file @
7264f9e0
...
...
@@ -19,43 +19,314 @@
* 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
;
}
}
TEST
(
pc_min
,
check_all_bw_indexes
)
{
const
int
NB_RB_UL
[]
=
{
11
,
24
,
38
,
51
,
65
,
78
,
106
,
133
,
162
,
217
,
245
,
273
};
for
(
auto
i
=
0U
;
i
<
sizeof
(
NB_RB_UL
)
/
sizeof
(
NB_RB_UL
[
0
]);
i
++
)
{
(
void
)
nr_get_Pcmin
(
1
,
20
,
NB_RB_UL
[
i
]);
}
}
TEST
(
pusch_power_control
,
pusch_power_control_msg3
)
{
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
;
mac
.
current_UL_BWP
=
&
current_UL_BWP
;
NR_RACH_ConfigCommon_t
nr_rach_ConfigCommon
=
{
0
};
current_UL_BWP
.
rach_ConfigCommon
=
&
nr_rach_ConfigCommon
;
mac
.
nr_band
=
78
;
NR_PUSCH_Config_t
pusch_Config
=
{
0
};
current_UL_BWP
.
pusch_Config
=
&
pusch_Config
;
NR_PUSCH_PowerControl
pusch_PowerControl
=
{
0
};
pusch_Config
.
pusch_PowerControl
=
&
pusch_PowerControl
;
pusch_PowerControl
.
tpc_Accumulation
=
(
long
*
)
1
;
// msg3 cofiguration as in 5g_rfsimulator testcase
int
num_rb
=
8
;
int
start_prb
=
0
;
uint16_t
nb_symb_sch
=
3
;
uint16_t
nb_dmrs_prb
=
12
;
uint16_t
nb_ptrs_prb
=
0
;
uint16_t
Qm
=
2
;
uint16_t
R
=
1570
;
uint16_t
beta_offset_csi1
=
0
;
uint32_t
sum_bits_in_codeblocks
=
56
;
int
delta_pusch
=
0
;
bool
is_rar_tx_retx
=
true
;
int
P_CMAX
=
nr_get_Pcmax
(
23
,
mac
.
nr_band
,
FR1
,
Qm
,
false
,
current_UL_BWP
.
scs
,
current_UL_BWP
.
BWPSize
,
false
,
num_rb
,
start_prb
);
long
preambleReceivedTargetPower
=
-
96
;
nr_rach_ConfigCommon
.
rach_ConfigGeneric
.
preambleReceivedTargetPower
=
preambleReceivedTargetPower
;
int
power
=
get_pusch_tx_power_ue
(
&
mac
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
Qm
,
R
,
beta_offset_csi1
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
false
);
EXPECT_EQ
(
power
,
-
84
);
EXPECT_LT
(
power
,
P_CMAX
);
nr_rach_ConfigCommon
.
rach_ConfigGeneric
.
preambleReceivedTargetPower
-=
2
;
int
reduced_power
=
get_pusch_tx_power_ue
(
&
mac
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
Qm
,
R
,
beta_offset_csi1
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
false
);
EXPECT_EQ
(
std
::
min
(
P_CMAX
,
power
-
2
),
reduced_power
)
<<
"Incorrect handling of preambleReceivedTargetPower"
;
EXPECT_LT
(
reduced_power
,
P_CMAX
)
<<
"Power above P_CMAX"
;
delta_pusch
=
4
;
int
increased_power
=
get_pusch_tx_power_ue
(
&
mac
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
Qm
,
R
,
beta_offset_csi1
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
false
);
EXPECT_EQ
(
std
::
min
(
P_CMAX
,
reduced_power
+
delta_pusch
),
increased_power
)
<<
"delta_pusch should increase tx power"
;
EXPECT_LT
(
increased_power
,
P_CMAX
)
<<
"Power above P_CMAX"
;
}
TEST
(
pusch_power_control
,
pusch_power_data
)
{
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
;
mac
.
current_UL_BWP
=
&
current_UL_BWP
;
NR_RACH_ConfigCommon_t
nr_rach_ConfigCommon
=
{
0
};
current_UL_BWP
.
rach_ConfigCommon
=
&
nr_rach_ConfigCommon
;
mac
.
nr_band
=
78
;
bool
is_rar_tx_retx
=
false
;
int
num_rb
=
5
;
int
start_prb
=
0
;
uint16_t
nb_symb_sch
=
3
;
uint16_t
nb_dmrs_prb
=
6
;
uint16_t
nb_ptrs_prb
=
0
;
uint16_t
Qm
=
2
;
uint16_t
R
=
6790
;
uint16_t
beta_offset_csi1
=
0
;
uint32_t
sum_bits_in_codeblocks
=
192
;
int
delta_pusch
=
4
;
bool
transform_precoding
=
false
;
NR_PUSCH_Config_t
pusch_Config
=
{
0
};
current_UL_BWP
.
pusch_Config
=
&
pusch_Config
;
NR_PUSCH_PowerControl
pusch_PowerControl
=
{
0
};
pusch_Config
.
pusch_PowerControl
=
&
pusch_PowerControl
;
pusch_PowerControl
.
tpc_Accumulation
=
(
long
*
)
1
;
long
p0_NominalWithGrant
=
0
;
current_UL_BWP
.
p0_NominalWithGrant
=
&
p0_NominalWithGrant
;
pusch_PowerControl
.
deltaMCS
=
(
long
*
)
1
;
int
P_CMAX
=
nr_get_Pcmax
(
23
,
mac
.
nr_band
,
FR1
,
Qm
,
false
,
current_UL_BWP
.
scs
,
current_UL_BWP
.
BWPSize
,
transform_precoding
,
num_rb
,
start_prb
);
int
power
=
get_pusch_tx_power_ue
(
&
mac
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
Qm
,
R
,
beta_offset_csi1
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
transform_precoding
);
EXPECT_LE
(
power
,
P_CMAX
);
EXPECT_EQ
(
power
,
18
);
const
int
BETA_OFFSET_CSI1_DEFAULT
=
13
;
sum_bits_in_codeblocks
=
0
;
// CSI-only
power
=
get_pusch_tx_power_ue
(
&
mac
,
num_rb
,
start_prb
,
nb_symb_sch
,
nb_dmrs_prb
,
nb_ptrs_prb
,
Qm
,
R
,
BETA_OFFSET_CSI1_DEFAULT
,
sum_bits_in_codeblocks
,
delta_pusch
,
is_rar_tx_retx
,
transform_precoding
);
EXPECT_EQ
(
power
,
P_CMAX
)
<<
"Expecting max tx power because of deltaMCS with CSI-only"
;
}
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