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
1b974c6a
Commit
1b974c6a
authored
Oct 22, 2025
by
Rakesh Mundlamuri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
merge timing_advance_offset and timing_advance_offset_ns computation
parent
b378acf2
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
134 additions
and
60 deletions
+134
-60
common/utils/nr/nr_common.h
common/utils/nr/nr_common.h
+1
-0
openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
+58
-37
openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+7
-3
openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+3
-1
openair1/PHY/defs_gNB.h
openair1/PHY/defs_gNB.h
+1
-0
openair1/SCHED_NR/phy_procedures_nr_gNB.c
openair1/SCHED_NR/phy_procedures_nr_gNB.c
+23
-9
openair1/SIMULATION/NR_PHY/srssim.c
openair1/SIMULATION/NR_PHY/srssim.c
+41
-10
No files found.
common/utils/nr/nr_common.h
View file @
1b974c6a
...
...
@@ -346,6 +346,7 @@ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
static
const
char
*
const
duplex_mode_txt
[]
=
{
"FDD"
,
"TDD"
};
...
...
openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c
View file @
1b974c6a
...
...
@@ -36,52 +36,73 @@
#define I0_SKIP_DC 1
int
nr_est_timing_advance_srs
(
const
NR_DL_FRAME_PARMS
*
frame_parms
,
const
c16_t
srs_estimated_channel_time
[][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
frame_parms
->
ofdm_symbol_size
])
void
nr_est_srs_timing_advance_offset
(
uint16_t
ofdm_symbol_size
,
const
c16_t
srs_estimated_channel_time
[][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
ofdm_symbol_size
],
uint8_t
ant
,
uint8_t
N_ap
,
uint32_t
samples_per_frame
,
uint16_t
*
ta_offset
,
int16_t
*
ta_offset_nsec
)
{
int
timing_advance
=
0
;
int
max_val
=
0
;
for
(
int
i
=
0
;
i
<
NR_SRS_IDFT_OVERSAMP_FACTOR
*
frame_parms
->
ofdm_symbol_size
;
i
++
)
{
int
temp
=
0
;
for
(
int
aa
=
0
;
aa
<
frame_parms
->
nb_antennas_rx
;
aa
++
)
{
int
Re
=
((
c16_t
*
)
srs_estimated_channel_time
[
aa
])[
i
].
r
;
int
Im
=
((
c16_t
*
)
srs_estimated_channel_time
[
aa
])[
i
].
i
;
temp
+=
(
Re
*
Re
/
2
)
+
(
Im
*
Im
/
2
);
int
64_t
mean_val
=
0
;
int
64_t
max_val
=
0
;
int32_t
max_idx
=
0
;
int16_t
srs_toa
=
0
;
int16_t
ofdm_os_size
=
NR_SRS_IDFT_OVERSAMP_FACTOR
*
ofdm_symbol_size
;
for
(
int
k
=
0
;
k
<
ofdm_os_size
;
k
++
)
{
int64_t
abs_val
=
0
;
for
(
int
p_index
=
0
;
p_index
<
N_ap
;
p_index
++
)
{
abs_val
+=
squaredMod
(
srs_estimated_channel_time
[
p_index
][
k
]
);
}
if
(
temp
>
max_val
)
{
timing_advance
=
i
;
max_val
=
temp
;
mean_val
+=
abs_val
;
if
(
abs_val
>
max_val
)
{
max_val
=
abs_val
;
max_idx
=
k
;
}
}
max_val
=
max_val
/
N_ap
;
mean_val
=
mean_val
/
(
N_ap
*
ofdm_os_size
);
if
(
max_idx
>
ofdm_os_size
>>
1
)
max_idx
=
max_idx
-
ofdm_os_size
;
// Check for detection threshold
if
((
mean_val
!=
0
)
&&
(
max_val
/
mean_val
>
NR_SRS_DETECTION_THRESHOLD
))
{
srs_toa
=
max_idx
/
NR_SRS_IDFT_OVERSAMP_FACTOR
;
// restrict the computation of ta_offset to antenna 0
if
(
ant
==
0
)
{
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const
uint16_t
bw_scaling
=
ofdm_symbol_size
>>
7
;
// do some integer rounding to improve TA accuracy
int
sync_pos_rounded
;
if
(
srs_toa
>
0
)
{
sync_pos_rounded
=
srs_toa
+
(
bw_scaling
>>
1
)
-
1
;
}
else
{
sync_pos_rounded
=
srs_toa
-
(
bw_scaling
>>
1
)
+
1
;
}
if
(
timing_advance
>
(
NR_SRS_IDFT_OVERSAMP_FACTOR
*
frame_parms
->
ofdm_symbol_size
)
/
2
)
{
timing_advance
=
timing_advance
-
(
NR_SRS_IDFT_OVERSAMP_FACTOR
*
frame_parms
->
ofdm_symbol_size
);
}
timing_advance
=
timing_advance
/
NR_SRS_IDFT_OVERSAMP_FACTOR
;
LOG_I
(
NR_PHY
,
"Estimated SRS ToA %d
\n
"
,
timing_advance
);
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const
uint16_t
bw_scaling
=
frame_parms
->
ofdm_symbol_size
>>
7
;
*
ta_offset
=
sync_pos_rounded
/
bw_scaling
;
// do some integer rounding to improve TA accuracy
int
sync_pos_rounded
;
if
(
timing_advance
>
0
)
{
sync_pos_rounded
=
timing_advance
+
(
bw_scaling
>>
1
)
-
1
;
// put timing advance command in 0..63 range
*
ta_offset
=
BOUNDED_EVAL
(
0
,
*
ta_offset
+
31
,
63
)
;
}
*
ta_offset_nsec
=
(
max_idx
*
1e9
)
/
(
NR_SRS_IDFT_OVERSAMP_FACTOR
*
samples_per_frame
*
100
)
;
}
else
{
sync_pos_rounded
=
timing_advance
-
(
bw_scaling
>>
1
)
+
1
;
*
ta_offset
=
0xFFFF
;
*
ta_offset_nsec
=
0x8000
;
}
int
timing_advance_update
=
sync_pos_rounded
/
bw_scaling
;
// put timing advance command in 0..63 range
timing_advance_update
+=
31
;
if
(
timing_advance_update
<
0
)
timing_advance_update
=
0
;
if
(
timing_advance_update
>
63
)
timing_advance_update
=
63
;
return
timing_advance_update
;
LOG_D
(
NR_PHY
,
"SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)
\n
"
,
srs_toa
,
ant
,
*
ta_offset
,
*
ta_offset_nsec
,
max_val
,
mean_val
,
max_idx
)
;
}
void
dump_nr_I0_stats
(
FILE
*
fd
,
PHY_VARS_gNB
*
gNB
)
{
...
...
openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
View file @
1b974c6a
...
...
@@ -59,9 +59,13 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void
gNB_I0_measurements
(
PHY_VARS_gNB
*
gNB
,
int
slot
,
int
first_symb
,
int
num_symb
,
uint32_t
rb_mask_ul
[
14
][
9
]);
int
nr_est_timing_advance_srs
(
const
NR_DL_FRAME_PARMS
*
frame_parms
,
const
c16_t
srs_estimated_channel_time
[][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
frame_parms
->
ofdm_symbol_size
]);
void
nr_est_srs_timing_advance_offset
(
uint16_t
ofdm_symbol_size
,
const
c16_t
srs_estimated_channel_time
[][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
ofdm_symbol_size
],
uint8_t
ant
,
uint8_t
N_ap
,
uint32_t
samples_per_frame
,
uint16_t
*
timing_advance_offset
,
int16_t
*
timing_advance_offset_nsec
);
void
nr_pusch_ptrs_processing
(
PHY_VARS_gNB
*
gNB
,
NR_DL_FRAME_PARMS
*
frame_parms
,
...
...
openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
View file @
1b974c6a
...
...
@@ -243,7 +243,9 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
int
*
srs_est
,
c16_t
srs_estimated_channel_freq
[][
N_ap
][
ofdm_symbol_size
*
N_symb_SRS
],
c16_t
srs_estimated_channel_time
[][
N_ap
][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
ofdm_symbol_size
],
int16_t
*
snr_per_rb
);
int16_t
*
snr_per_rb
,
uint16_t
*
timing_advance_offset
,
int16_t
*
timing_advance_offset_nsec
);
int
get_nr_prach_duration
(
uint8_t
prach_format
);
...
...
openair1/PHY/defs_gNB.h
View file @
1b974c6a
...
...
@@ -47,6 +47,7 @@
#define MAX_NUM_RU_PER_gNB 8
#define MAX_PUCCH0_NID 8
#define NR_SRS_IDFT_OVERSAMP_FACTOR 2
#define NR_SRS_DETECTION_THRESHOLD 10
typedef
struct
{
int
nb_id
;
...
...
openair1/SCHED_NR/phy_procedures_nr_gNB.c
View file @
1b974c6a
...
...
@@ -869,7 +869,9 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
int
*
srs_est
,
c16_t
srs_estimated_channel_freq
[][
N_ap
][
ofdm_symbol_size
*
N_symb_SRS
],
c16_t
srs_estimated_channel_time
[][
N_ap
][
NR_SRS_IDFT_OVERSAMP_FACTOR
*
ofdm_symbol_size
],
int16_t
*
snr_per_rb
)
int16_t
*
snr_per_rb
,
uint16_t
*
timing_advance_offset
,
int16_t
*
timing_advance_offset_nsec
)
{
NR_DL_FRAME_PARMS
*
frame_parms
=
&
gNB
->
frame_parms
;
nfapi_nr_srs_pdu_t
*
srs_pdu
=
&
srs
->
srs_pdu
;
...
...
@@ -930,6 +932,18 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
snr_per_rb
[
rb
]
=
dB_fixed
(
signal_power_avg
)
-
dB_fixed
(
max
(
noise_power_per_rb
[
rb
]
/
nb_antennas_rx
,
1
));
}
stop_meas
(
&
gNB
->
srs_channel_estimation_stats
);
start_meas
(
&
gNB
->
srs_timing_advance_stats
);
for
(
int
ant_rx_ind
=
0
;
ant_rx_ind
<
nb_antennas_rx
;
ant_rx_ind
++
)
{
nr_est_srs_timing_advance_offset
(
ofdm_symbol_size
,
srs_estimated_channel_time
[
ant_rx_ind
],
ant_rx_ind
,
N_ap
,
frame_parms
->
samples_per_frame
,
timing_advance_offset
,
&
timing_advance_offset_nsec
[
ant_rx_ind
]);
}
stop_meas
(
&
gNB
->
srs_timing_advance_stats
);
}
T
(
T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
,
...
...
@@ -1168,6 +1182,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
uint8_t
N_ap
=
1
<<
srs
->
srs_pdu
.
num_ant_ports
;
int16_t
snr_per_rb
[
srs
->
srs_pdu
.
bwp_size
];
nfapi_nr_srs_pdu_t
*
srs_pdu
=
&
srs
->
srs_pdu
;
uint16_t
timing_advance_offset
;
int16_t
timing_advance_offset_nsec
[
nb_antennas_rx
];
int
srs_est
;
c16_t
srs_estimated_channel_freq
[
nb_antennas_rx
][
N_ap
][
ofdm_symbol_size
*
N_symb_SRS
]
__attribute__
((
aligned
(
32
)));
...
...
@@ -1186,7 +1202,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
&
srs_est
,
srs_estimated_channel_freq
,
srs_estimated_channel_time
,
snr_per_rb
);
snr_per_rb
,
&
timing_advance_offset
,
timing_advance_offset_nsec
);
if
((
gNB
->
srs
->
snr
*
10
)
<
gNB
->
srs_thres
)
{
srs_est
=
-
1
;
...
...
@@ -1200,13 +1218,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N
nfapi_nr_srs_indication_pdu_t
*
srs_indication
=
UL_INFO
->
srs_pdu_list
+
UL_INFO
->
srs_ind
.
number_of_pdus
++
;
srs_indication
->
handle
=
srs_pdu
->
handle
;
srs_indication
->
rnti
=
srs_pdu
->
rnti
;
start_meas
(
&
gNB
->
srs_timing_advance_stats
);
srs_indication
->
timing_advance_offset
=
srs_est
>=
0
?
nr_est_timing_advance_srs
(
frame_parms
,
srs_estimated_channel_time
[
0
])
:
0xFFFF
;
stop_meas
(
&
gNB
->
srs_timing_advance_stats
);
srs_indication
->
timing_advance_offset_nsec
=
srs_est
>=
0
?
(
int16_t
)((((
int32_t
)
srs_indication
->
timing_advance_offset
-
31
)
*
((
int32_t
)
TC_NSEC_x32768
))
>>
15
)
:
0xFFFF
;
srs_indication
->
timing_advance_offset
=
srs_est
>=
0
?
timing_advance_offset
:
0xFFFF
;
// TODO: currently we fill timing_advance_offset_nsec for antenna 0. Need to extend it for other antennas
srs_indication
->
timing_advance_offset_nsec
=
srs_est
>=
0
?
timing_advance_offset_nsec
[
0
]
:
0x8000
;
switch
(
srs_pdu
->
srs_parameters_v4
.
usage
)
{
case
0
:
LOG_W
(
NR_PHY
,
"SRS report was not requested by MAC
\n
"
);
...
...
openair1/SIMULATION/NR_PHY/srssim.c
View file @
1b974c6a
...
...
@@ -88,9 +88,8 @@ int main(int argc, char *argv[])
sigaction
(
SIGINT
,
&
sigint_action
,
&
oldaction
);
double
SNR
,
snr0
=
0
,
snr1
=
20
.
0
;
double
sum_srs_snr
=
0
;
double
sigma
,
sigma_dB
;
double
snr_step
=
5
;
double
snr_step
=
1
;
uint8_t
snr1set
=
0
;
double
**
s_re
,
**
s_im
,
**
r_re
,
**
r_im
;
int
trial
,
n_trials
=
1
,
delay
=
0
;
...
...
@@ -128,7 +127,7 @@ int main(int argc, char *argv[])
InitSinLUT
();
int
c
;
while
((
c
=
getopt
(
argc
,
argv
,
"--:O:a:b:c:d:e:f:g:h:i:k
:
l:m:n:p:s:u:y:z:A:B:C:H:PR:S:L:"
))
!=
-
1
)
{
while
((
c
=
getopt
(
argc
,
argv
,
"--:O:a:b:c:d:e:f:g:h:i:kl:m:n:p:s:u:y:z:A:B:C:H:PR:S:L:"
))
!=
-
1
)
{
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
if
(
c
==
1
||
c
==
'-'
||
c
==
'O'
)
...
...
@@ -570,7 +569,8 @@ int main(int argc, char *argv[])
reset_meas
(
&
gNB
->
srs_channel_estimation_stats
);
reset_meas
(
&
gNB
->
srs_timing_advance_stats
);
sum_srs_snr
=
0
;
double
sum_srs_snr
=
0
;
int
tao_ns_count
=
0
;
for
(
trial
=
0
;
trial
<
n_trials
&&
!
stop
;
trial
++
)
{
// Estimate noise power from the transmitter level and SNR
sigma_dB
=
10
*
log10
(((
double
)
txlev_sum
)
*
((
double
)
ofdm_symbol_size
/
(
12
*
srs_pdu
.
bwp_size
)))
-
SNR
;
...
...
@@ -627,6 +627,8 @@ int main(int argc, char *argv[])
uint8_t
N_ap
=
1
<<
srs
->
srs_pdu
.
num_ant_ports
;
uint8_t
nb_antennas_rx
=
fp
->
nb_antennas_rx
;
int16_t
snr_per_rb
[
srs
->
srs_pdu
.
bwp_size
];
uint16_t
timing_advance_offset
;
int16_t
timing_advance_offset_nsec
[
nb_antennas_rx
];
int
srs_est
;
c16_t
srs_estimated_channel_freq
[
nb_antennas_rx
][
N_ap
][
ofdm_symbol_size
*
N_symb_SRS
]
__attribute__
((
aligned
(
32
)));
c16_t
srs_estimated_channel_time
[
nb_antennas_rx
][
N_ap
][
ofdm_symbol_size
]
__attribute__
((
aligned
(
32
)));
...
...
@@ -643,16 +645,41 @@ int main(int argc, char *argv[])
&
srs_est
,
srs_estimated_channel_freq
,
srs_estimated_channel_time
,
snr_per_rb
);
snr_per_rb
,
&
timing_advance_offset
,
timing_advance_offset_nsec
);
start_meas
(
&
gNB
->
srs_timing_advance_stats
);
nr_est_timing_advance_srs
(
fp
,
srs_estimated_channel_time
[
0
]);
stop_meas
(
&
gNB
->
srs_timing_advance_stats
);
sum_srs_snr
+=
pow
(
10
,
(
double
)
gNB
->
srs
->
snr
/
10
.
0
);
int16_t
delay_ns
=
delay
*
1e9
/
(
fp
->
samples_per_frame
*
100
);
for
(
int
ant_idx
=
0
;
ant_idx
<
nb_antennas_rx
;
ant_idx
++
)
{
if
(
n_trials
==
1
)
printf
(
"[RX ant %d] SRS estimated: TA offset %d, TA offset ns %d
\n
"
,
ant_idx
,
timing_advance_offset
,
timing_advance_offset_nsec
[
ant_idx
]);
if
(
timing_advance_offset_nsec
[
ant_idx
]
==
delay_ns
)
tao_ns_count
++
;
}
stop_meas
(
&
gNB
->
rx_srs_stats
);
}
// trail loop
sum_srs_snr
/=
n_trials
;
printf
(
"Actual SNR : %f, Estimated SNR from SRS %f (dB)
\n
"
,
SNR
,
10
*
log10
(
sum_srs_snr
));
float
tao_ns_rate
=
(
float
)
tao_ns_count
/
(
n_trials
*
n_rx
);
float
SRS_SNR_dB
=
10
*
log10
(
sum_srs_snr
/
n_trials
);
printf
(
"Actual SNR : %f, Estimated SNR from SRS %f (dB), TA offset success rate %f %%
\n
"
,
SNR
,
SRS_SNR_dB
,
tao_ns_rate
*
100
);
int
srs_ret
=
1
;
if
(
SNR
>
30
&&
SRS_SNR_dB
>
30
)
{
srs_ret
=
0
;
}
else
if
(
SNR
>=
SRS_SNR_dB
)
{
srs_ret
=
SRS_SNR_dB
>=
0
.
7
*
SNR
?
0
:
1
;
}
else
if
(
SRS_SNR_dB
>
SNR
)
{
srs_ret
=
SNR
>=
0
.
7
*
SRS_SNR_dB
?
0
:
1
;
}
if
(
tao_ns_rate
>
0
.
9
&&
srs_ret
==
0
)
{
ret
=
0
;
break
;
}
if
(
print_perf
==
1
)
{
printf
(
"
\n
gNB RX
\n
"
);
...
...
@@ -666,6 +693,10 @@ int main(int argc, char *argv[])
}
// SNR loop
printf
(
"*************
\n
"
);
printf
(
"SRS test %s
\n
"
,
ret
==
0
?
"OK"
:
"FAILED"
);
printf
(
"*************
\n
"
);
// free memory
for
(
i
=
0
;
i
<
n_tx
;
i
++
)
{
...
...
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