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
c5e4bea6
Commit
c5e4bea6
authored
Mar 07, 2024
by
Laurent THOMAS
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make explicit return of the clock drift to shift the corresponding number of samples
remove corresponding global variables
parent
b99e8567
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
318 additions
and
372 deletions
+318
-372
executables/nr-ue.c
executables/nr-ue.c
+88
-84
openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+22
-50
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+9
-10
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+172
-192
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+6
-6
openair1/PHY/defs_nr_UE.h
openair1/PHY/defs_nr_UE.h
+3
-6
openair1/SCHED_NR_UE/defs.h
openair1/SCHED_NR_UE/defs.h
+1
-1
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+5
-11
openair1/SIMULATION/NR_PHY/dlsim.c
openair1/SIMULATION/NR_PHY/dlsim.c
+0
-1
openair1/SIMULATION/NR_PHY/pbchsim.c
openair1/SIMULATION/NR_PHY/pbchsim.c
+12
-11
No files found.
executables/nr-ue.c
View file @
c5e4bea6
...
...
@@ -439,11 +439,13 @@ static void UE_synch(void *arg) {
uint64_t
dl_carrier
,
ul_carrier
;
nr_get_carrier_frequencies
(
UE
,
&
dl_carrier
,
&
ul_carrier
);
if
(
nr_initial_sync
(
&
syncD
->
proc
,
UE
,
2
,
get_softmodem_params
()
->
sa
)
==
0
)
{
nr_initial_sync_t
ret
=
nr_initial_sync
(
&
syncD
->
proc
,
UE
,
2
,
get_softmodem_params
()
->
sa
);
if
(
!
ret
.
cell_notdetected
)
{
syncD
->
rx_offset
=
ret
.
rx_offset
;
freq_offset
=
UE
->
common_vars
.
freq_offset
;
// frequency offset computed with pss in initial sync
hw_slot_offset
=
((
UE
->
rx_offset
<<
1
)
/
UE
->
frame_parms
.
samples_per_subframe
*
UE
->
frame_parms
.
slots_per_subframe
)
+
round
((
float
)((
UE
->
rx_offset
<<
1
)
%
UE
->
frame_parms
.
samples_per_subframe
)
/
UE
->
frame_parms
.
samples_per_slot0
);
hw_slot_offset
=
((
ret
.
rx_offset
<<
1
)
/
UE
->
frame_parms
.
samples_per_subframe
*
UE
->
frame_parms
.
slots_per_subframe
)
+
round
((
float
)((
ret
.
rx_offset
<<
1
)
%
UE
->
frame_parms
.
samples_per_subframe
)
/
UE
->
frame_parms
.
samples_per_slot0
);
// rerun with new cell parameters and frequency-offset
// todo: the freq_offset computed on DL shall be scaled before being applied to UL
...
...
@@ -462,7 +464,6 @@ static void UE_synch(void *arg) {
else
UE
->
is_synchronized
=
1
;
}
else
{
if
(
UE
->
UE_scan_carrier
==
1
)
{
if
(
freq_offset
>=
0
)
...
...
@@ -607,8 +608,9 @@ void processSlotTX(void *arg)
RU_write
(
rxtxD
);
}
static
void
UE_dl_preprocessing
(
PHY_VARS_NR_UE
*
UE
,
const
UE_nr_rxtx_proc_t
*
proc
,
int
*
tx_wait_for_dlsch
,
nr_phy_data_t
*
phy_data
)
static
int
UE_dl_preprocessing
(
PHY_VARS_NR_UE
*
UE
,
const
UE_nr_rxtx_proc_t
*
proc
,
int
*
tx_wait_for_dlsch
,
nr_phy_data_t
*
phy_data
)
{
int
sampleShift
=
0
;
if
(
IS_SOFTMODEM_NOS1
||
get_softmodem_params
()
->
sa
)
{
// Start synchronization with a target gNB
...
...
@@ -636,20 +638,16 @@ static void UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *pro
UE
->
if_inst
->
dl_indication
(
&
dl_indication
);
}
uint64_t
a
=
rdtsc_oai
();
pbch_pdcch_processing
(
UE
,
proc
,
phy_data
);
sampleShift
=
pbch_pdcch_processing
(
UE
,
proc
,
phy_data
);
if
(
phy_data
->
dlsch
[
0
].
active
&&
phy_data
->
dlsch
[
0
].
rnti_type
==
TYPE_C_RNTI_
)
{
// indicate to tx thread to wait for DLSCH decoding
const
int
ack_nack_slot
=
(
proc
->
nr_slot_rx
+
phy_data
->
dlsch
[
0
].
dlsch_config
.
k1_feedback
)
%
UE
->
frame_parms
.
slots_per_frame
;
LOG_D
(
NR_PHY
,
"Adding one event to wait after decoding slot %d, for futre tx slot %d
\n
"
,
proc
->
nr_slot_rx
,
ack_nack_slot
);
tx_wait_for_dlsch
[
ack_nack_slot
]
++
;
}
LOG_D
(
PHY
,
"In %s: slot %d, time %llu
\n
"
,
__FUNCTION__
,
proc
->
nr_slot_rx
,
(
rdtsc_oai
()
-
a
)
/
3500
);
}
ue_ta_procedures
(
UE
,
proc
->
nr_slot_tx
,
proc
->
frame_tx
);
return
;
return
sampleShift
;
}
void
UE_dl_processing
(
void
*
arg
)
{
...
...
@@ -710,34 +708,36 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
}
void
syncInFrame
(
PHY_VARS_NR_UE
*
UE
,
openair0_timestamp
*
timestamp
)
{
LOG_I
(
PHY
,
"Resynchronizing RX by %d samples
\n
"
,
UE
->
rx_offset
);
static
void
syncInFrame
(
PHY_VARS_NR_UE
*
UE
,
openair0_timestamp
*
timestamp
,
int
rx_offset
)
{
LOG_I
(
PHY
,
"Resynchronizing RX by %d samples
\n
"
,
rx_offset
);
if
(
IS_SOFTMODEM_IQPLAYER
||
IS_SOFTMODEM_IQRECORDER
)
{
// Resynchonize by slot (will work with numerology 1 only)
for
(
int
size
=
UE
->
rx_offset
;
size
>
0
;
size
-=
UE
->
frame_parms
.
samples_per_subframe
/
2
)
{
int
unitTransfer
=
size
>
UE
->
frame_parms
.
samples_per_subframe
/
2
?
UE
->
frame_parms
.
samples_per_subframe
/
2
:
size
;
AssertFatal
(
unitTransfer
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
for
(
int
size
=
rx_offset
;
size
>
0
;
size
-=
UE
->
frame_parms
.
samples_per_subframe
/
2
)
{
int
unitTransfer
=
size
>
UE
->
frame_parms
.
samples_per_subframe
/
2
?
UE
->
frame_parms
.
samples_per_subframe
/
2
:
size
;
AssertFatal
(
unitTransfer
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
timestamp
,
(
void
**
)
UE
->
common_vars
.
rxdata
,
unitTransfer
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
}
}
else
{
*
timestamp
+=
UE
->
frame_parms
.
get_samples_per_slot
(
1
,
&
UE
->
frame_parms
);
for
(
int
size
=
UE
->
rx_offset
;
size
>
0
;
size
-=
UE
->
frame_parms
.
samples_per_subframe
)
{
int
unitTransfer
=
size
>
UE
->
frame_parms
.
samples_per_subframe
?
UE
->
frame_parms
.
samples_per_subframe
:
size
;
*
timestamp
+=
UE
->
frame_parms
.
get_samples_per_slot
(
1
,
&
UE
->
frame_parms
);
for
(
int
size
=
rx_offset
;
size
>
0
;
size
-=
UE
->
frame_parms
.
samples_per_subframe
)
{
int
unitTransfer
=
size
>
UE
->
frame_parms
.
samples_per_subframe
?
UE
->
frame_parms
.
samples_per_subframe
:
size
;
// we write before read because gNB waits for UE to write and both executions halt
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
if
(
IS_SOFTMODEM_RFSIM
)
dummyWrite
(
UE
,
*
timestamp
,
unitTransfer
);
AssertFatal
(
unitTransfer
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
if
(
IS_SOFTMODEM_RFSIM
)
dummyWrite
(
UE
,
*
timestamp
,
unitTransfer
);
AssertFatal
(
unitTransfer
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
timestamp
,
(
void
**
)
UE
->
common_vars
.
rxdata
,
unitTransfer
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
*
timestamp
+=
unitTransfer
;
// this does not affect the read but needed for RFSIM write
}
}
...
...
@@ -764,8 +764,6 @@ void *UE_thread(void *arg)
//this thread should be over the processing thread to keep in real time
PHY_VARS_NR_UE
*
UE
=
(
PHY_VARS_NR_UE
*
)
arg
;
// int tx_enabled = 0;
openair0_timestamp
timestamp
=
0
;
openair0_timestamp
writeTimestamp
=
0
;
void
*
rxp
[
NB_ANTENNAS_RX
];
int
start_rx_stream
=
0
;
fapi_nr_config_request_t
*
cfg
=
&
UE
->
nrUE_config
;
...
...
@@ -796,9 +794,10 @@ void *UE_thread(void *arg)
for
(
int
i
=
0
;
i
<
num_ind_fifo
;
i
++
)
{
initNotifiedFIFO
(
UE
->
tx_resume_ind_fifo
+
i
);
}
int
shiftForNextFrame
=
0
;
int
intialSyncOffset
=
0
;
openair0_timestamp
sync_timestamp
;
while
(
!
oai_exit
)
{
if
(
syncRunning
)
{
notifiedFIFO_elt_t
*
res
=
tryPullTpool
(
&
nf
,
&
(
get_nrUE_params
()
->
Tpool
));
...
...
@@ -806,25 +805,28 @@ void *UE_thread(void *arg)
syncRunning
=
false
;
if
(
UE
->
is_synchronized
)
{
decoded_frame_rx
=
mac
->
mib_frame
;
LOG_I
(
PHY
,
"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d
\n
"
,
LOG_A
(
PHY
,
"UE synchronized! decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d
\n
"
,
decoded_frame_rx
,
UE
->
init_sync_frame
,
trashed_frames
);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx
=
(
decoded_frame_rx
+
UE
->
init_sync_frame
+
trashed_frames
)
%
MAX_FRAME_NUMBER
;
syncData_t
*
syncMsg
=
(
syncData_t
*
)
NotifiedFifoData
(
res
);
intialSyncOffset
=
syncMsg
->
rx_offset
;
}
delNotifiedFIFO_elt
(
res
);
start_rx_stream
=
0
;
}
else
{
if
(
IS_SOFTMODEM_IQPLAYER
||
IS_SOFTMODEM_IQRECORDER
)
{
// For IQ recorder
/
player we force synchronization to happen in 280 ms
// For IQ recorder
-
player we force synchronization to happen in 280 ms
while
(
trashed_frames
!=
28
)
{
readFrame
(
UE
,
&
timestamp
,
true
);
trashed_frames
+=
2
;
readFrame
(
UE
,
&
sync_
timestamp
,
true
);
trashed_frames
+=
2
;
}
}
else
{
readFrame
(
UE
,
&
timestamp
,
true
);
trashed_frames
+=
2
;
readFrame
(
UE
,
&
sync_
timestamp
,
true
);
trashed_frames
+=
2
;
}
continue
;
}
...
...
@@ -833,7 +835,7 @@ void *UE_thread(void *arg)
AssertFatal
(
!
syncRunning
,
"At this point synchronization can't be running
\n
"
);
if
(
!
UE
->
is_synchronized
)
{
readFrame
(
UE
,
&
timestamp
,
false
);
readFrame
(
UE
,
&
sync_
timestamp
,
false
);
notifiedFIFO_elt_t
*
Msg
=
newNotifiedFIFO_elt
(
sizeof
(
syncData_t
),
0
,
&
nf
,
UE_synch
);
syncData_t
*
syncMsg
=
(
syncData_t
*
)
NotifiedFifoData
(
Msg
);
syncMsg
->
UE
=
UE
;
...
...
@@ -846,16 +848,16 @@ void *UE_thread(void *arg)
if
(
start_rx_stream
==
0
)
{
start_rx_stream
=
1
;
syncInFrame
(
UE
,
&
timestamp
);
UE
->
rx_offset
=
0
;
UE
->
time_sync_cell
=
0
;
syncInFrame
(
UE
,
&
sync_timestamp
,
intialSyncOffset
);
shiftForNextFrame
=
0
;
// will be used to track clock drift
// read in first symbol
AssertFatal
(
UE
->
frame_parms
.
ofdm_symbol_size
+
UE
->
frame_parms
.
nb_prefix_samples0
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
&
timestamp
,
AssertFatal
(
UE
->
frame_parms
.
ofdm_symbol_size
+
UE
->
frame_parms
.
nb_prefix_samples0
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
&
sync_
timestamp
,
(
void
**
)
UE
->
common_vars
.
rxdata
,
UE
->
frame_parms
.
ofdm_symbol_size
+
UE
->
frame_parms
.
nb_prefix_samples0
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
UE
->
frame_parms
.
ofdm_symbol_size
+
UE
->
frame_parms
.
nb_prefix_samples0
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
// we have the decoded frame index in the return of the synch process
// and we shifted above to the first slot of next frame
decoded_frame_rx
++
;
...
...
@@ -871,7 +873,7 @@ void *UE_thread(void *arg)
continue
;
}
// start of normal case, the UE is in sync
absolute_slot
++
;
int
slot_nr
=
absolute_slot
%
nb_slot_frame
;
...
...
@@ -893,26 +895,21 @@ void *UE_thread(void *arg)
int
firstSymSamp
=
get_firstSymSamp
(
slot_nr
,
&
UE
->
frame_parms
);
for
(
int
i
=
0
;
i
<
UE
->
frame_parms
.
nb_antennas_rx
;
i
++
)
rxp
[
i
]
=
(
void
*
)
&
UE
->
common_vars
.
rxdata
[
i
][
firstSymSamp
+
UE
->
frame_parms
.
get_samples_slot_timestamp
(
slot_nr
,
&
UE
->
frame_parms
,
0
)];
int
readBlockSize
,
writeBlockSize
;
rxp
[
i
]
=
(
void
*
)
&
UE
->
common_vars
.
rxdata
[
i
][
firstSymSamp
+
UE
->
frame_parms
.
get_samples_slot_timestamp
(
slot_nr
,
&
UE
->
frame_parms
,
0
)];
readBlockSize
=
get_readBlockSize
(
slot_nr
,
&
UE
->
frame_parms
);
writeBlockSize
=
UE
->
frame_parms
.
get_samples_per_slot
((
slot_nr
+
DURATION_RX_TO_TX
)
%
nb_slot_frame
,
&
UE
->
frame_parms
);
if
(
UE
->
apply_timing_offset
&&
(
slot_nr
==
nb_slot_frame
-
1
))
{
const
int
sampShift
=
-
(
UE
->
rx_offset
>>
1
);
readBlockSize
-=
sampShift
;
writeBlockSize
-=
sampShift
;
UE
->
apply_timing_offset
=
false
;
int
iq_shift_to_apply
=
0
;
if
(
slot_nr
==
nb_slot_frame
-
1
)
{
// we shift of half of measured drift, at each beginning of frame for both rx and tx
iq_shift_to_apply
=
shiftForNextFrame
;
shiftForNextFrame
=
0
;
// We will get a new measured offset if we decode PBCH
}
AssertFatal
(
readBlockSize
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
&
timestamp
,
rxp
,
readBlockSize
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
const
int
readBlockSize
=
get_readBlockSize
(
slot_nr
,
&
UE
->
frame_parms
)
-
iq_shift_to_apply
;
openair0_timestamp
rx_timestamp
;
AssertFatal
(
readBlockSize
==
UE
->
rfdevice
.
trx_read_func
(
&
UE
->
rfdevice
,
&
rx_timestamp
,
rxp
,
readBlockSize
,
UE
->
frame_parms
.
nb_antennas_rx
),
""
);
if
(
slot_nr
==
(
nb_slot_frame
-
1
))
{
// read in first symbol of next frame and adjust for timing drift
...
...
@@ -931,11 +928,13 @@ void *UE_thread(void *arg)
}
// use previous timing_advance value to compute writeTimestamp
writeTimestamp
=
timestamp
+
UE
->
frame_parms
.
get_samples_slot_timestamp
(
slot_nr
,
&
UE
->
frame_parms
,
DURATION_RX_TO_TX
)
-
firstSymSamp
-
UE
->
N_TA_offset
-
timing_advance
;
const
openair0_timestamp
writeTimestamp
=
rx_timestamp
+
UE
->
frame_parms
.
get_samples_slot_timestamp
(
slot_nr
,
&
UE
->
frame_parms
,
DURATION_RX_TO_TX
)
-
firstSymSamp
-
UE
->
N_TA_offset
-
timing_advance
;
// but use current UE->timing_advance value to compute writeBlockSize
int
writeBlockSize
=
UE
->
frame_parms
.
get_samples_per_slot
((
slot_nr
+
DURATION_RX_TO_TX
)
%
nb_slot_frame
,
&
UE
->
frame_parms
)
-
iq_shift_to_apply
;
if
(
UE
->
timing_advance
!=
timing_advance
)
{
writeBlockSize
-=
UE
->
timing_advance
-
timing_advance
;
timing_advance
=
UE
->
timing_advance
;
...
...
@@ -948,7 +947,12 @@ void *UE_thread(void *arg)
notifiedFIFO_elt_t
*
newRx
=
newNotifiedFIFO_elt
(
sizeof
(
nr_rxtx_thread_data_t
),
curMsg
.
proc
.
nr_slot_rx
,
NULL
,
UE_dl_processing
);
nr_rxtx_thread_data_t
*
curMsgRx
=
(
nr_rxtx_thread_data_t
*
)
NotifiedFifoData
(
newRx
);
*
curMsgRx
=
(
nr_rxtx_thread_data_t
){.
proc
=
curMsg
.
proc
,
.
UE
=
UE
};
UE_dl_preprocessing
(
UE
,
&
curMsgRx
->
proc
,
tx_wait_for_dlsch
,
&
curMsgRx
->
phy_data
);
int
ret
=
UE_dl_preprocessing
(
UE
,
&
curMsgRx
->
proc
,
tx_wait_for_dlsch
,
&
curMsgRx
->
phy_data
);
if
(
ret
)
// if ret is 0, no rx_offset has been computed,
// or the computed value is 0 = no offset to do
// we store it to apply the drift compensation at beginning of next frame
shiftForNextFrame
=
ret
;
pushTpool
(
&
(
get_nrUE_params
()
->
Tpool
),
newRx
);
// Start TX slot processing here. It runs in parallel with RX slot processing
...
...
openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
View file @
c5e4bea6
...
...
@@ -33,29 +33,22 @@
// The adjustment is performed once per frame based on the
// last channel estimate of the receiver
void
nr_adjust_synch_ue
(
NR_DL_FRAME_PARMS
*
frame_parms
,
int
nr_adjust_synch_ue
(
NR_DL_FRAME_PARMS
*
frame_parms
,
PHY_VARS_NR_UE
*
ue
,
module_id_t
gNB_id
,
const
int
estimateSz
,
struct
complex16
dl_ch_estimates_time
[][
estimateSz
],
uint8_t
frame
,
uint8_t
subframe
,
unsigned
char
clear
,
uint8_t
slot
,
short
coef
)
{
static
int
count_max_pos_ok
=
0
;
static
int
first_time
=
1
;
int
max_val
=
0
,
max_pos
=
0
;
const
int
sync_pos
=
0
;
uint8_t
sync_offset
=
0
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH
,
VCD_FUNCTION_IN
);
short
ncoef
=
32767
-
coef
;
LOG_D
(
PHY
,
"AbsSubframe %d: rx_offset (before) = %d
\n
"
,
subframe
,
ue
->
rx_offset
);
// search for maximum position within the cyclic prefix
for
(
int
i
=
-
frame_parms
->
nb_prefix_samples
/
2
;
i
<
frame_parms
->
nb_prefix_samples
/
2
;
i
++
)
{
int
temp
=
0
;
...
...
@@ -74,53 +67,32 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
// filter position to reduce jitter
if
(
clear
==
1
)
ue
->
max_pos_fil
=
max_pos
<<
15
;
else
ue
->
max_pos_fil
=
((
ue
->
max_pos_fil
*
coef
)
>>
15
)
+
(
max_pos
*
ncoef
);
ue
->
max_pos_avg
=
((
ue
->
max_pos_avg
*
coef
)
>>
15
)
+
(
max_pos
*
ncoef
);
// do not filter to have proactive timing adjustment
//ue->max_pos_fil = max_pos << 15;
int
diff
=
(
ue
->
max_pos_fil
>>
15
)
-
sync_pos
;
int
diff
=
ue
->
max_pos_avg
>>
15
;
if
(
frame_parms
->
freq_range
==
nr_FR2
)
sync_offset
=
2
;
else
sync_offset
=
0
;
if
(
abs
(
diff
)
<
(
SYNCH_HYST
+
sync_offset
)
)
ue
->
rx_offset
=
0
;
else
ue
->
rx_offset
=
diff
;
int
sampleShift
=
0
;
if
(
abs
(
diff
)
>
(
NR_SYNCH_HYST
+
sync_offset
))
sampleShift
=
diff
;
const
int
sample_shift
=
-
(
ue
->
rx_offset
>>
1
);
const
int
sample_shift
=
-
(
sampleShift
/
2
);
// reset IIR filter for next offset calculation
ue
->
max_pos_fil
+=
sample_shift
*
32768
;
if
(
abs
(
diff
)
<
5
)
count_max_pos_ok
++
;
else
count_max_pos_ok
=
0
;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if
(
count_max_pos_ok
>
10
&&
first_time
==
1
)
{
first_time
=
0
;
ue
->
time_sync_cell
=
1
;
}
ue
->
max_pos_avg
+=
sample_shift
*
32768
;
#ifdef DEBUG_PHY
LOG_I
(
PHY
,
"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos
%d
\n
"
,
s
ubframe
,
LOG_D
(
PHY
,
"Slot %d: diff = %i, rx_offset (final) = %i : max_pos = %d, max_pos filtered = %ld, max_power =
%d
\n
"
,
s
lot
,
diff
,
ue
->
rx_offset
,
clear
,
sampleShift
,
max_pos
,
ue
->
max_pos_fil
,
max_val
,
sync_pos
);
#endif //DEBUG_PHY
ue
->
max_pos_avg
,
max_val
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH
,
VCD_FUNCTION_OUT
);
return
sample_shift
;
}
openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
View file @
c5e4bea6
...
...
@@ -30,7 +30,7 @@
*/
/*!\brief Timing drift hysterisis in samples*/
#define
SYNCH_HYST 2
#define
NR_SYNCH_HYST 1
/* A function to perform the channel estimation of DL PRS signal */
int
nr_prs_channel_estimation
(
uint8_t
gNB_id
,
...
...
@@ -91,14 +91,13 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
int
rxdataFsize
,
c16_t
rxdataF
[][
rxdataFsize
]);
void
nr_adjust_synch_ue
(
NR_DL_FRAME_PARMS
*
frame_parms
,
int
nr_adjust_synch_ue
(
NR_DL_FRAME_PARMS
*
frame_parms
,
PHY_VARS_NR_UE
*
ue
,
module_id_t
gNB_id
,
int
estimateSz
,
struct
complex16
dl_ch_estimates_time
[][
estimateSz
],
struct
complex16
dl_ch_estimates_time
[][
estimateSz
],
uint8_t
frame
,
uint8_t
subframe
,
unsigned
char
clear
,
short
coef
);
void
nr_ue_measurements
(
PHY_VARS_NR_UE
*
ue
,
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
View file @
c5e4bea6
...
...
@@ -50,7 +50,7 @@ extern openair0_config_t openair0_cfg[];
//static nfapi_nr_config_request_t* config =&config_t;
int
cnt
=
0
;
#define DEBUG_INITIAL_SYNCH
//
#define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0
// create a new node of SSB structure
...
...
@@ -111,11 +111,6 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
NR_UE_SSB
*
best_ssb
=
NULL
;
NR_UE_SSB
*
current_ssb
;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)
\n
"
,
ue
->
Mod_id
,
ue
->
rx_offset
);
#endif
uint8_t
N_L
=
(
frame_parms
->
Lmax
==
4
)
?
4
:
8
;
uint8_t
N_hf
=
(
frame_parms
->
Lmax
==
4
)
?
2
:
1
;
...
...
@@ -129,7 +124,7 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
start_meas
(
&
ue
->
dlsch_channel_estimation_stats
);
// computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
for
(
int
i
=
pbch_initial_symbol
;
i
<
pbch_initial_symbol
+
3
;
i
++
)
nr_pbch_dmrs_correlation
(
ue
,
proc
,
i
,
i
-
pbch_initial_symbol
,
current_ssb
,
rxdataF
);
nr_pbch_dmrs_correlation
(
ue
,
proc
,
i
,
i
-
pbch_initial_symbol
,
current_ssb
,
rxdataF
);
stop_meas
(
&
ue
->
dlsch_channel_estimation_stats
);
current_ssb
->
metric
=
current_ssb
->
c_re
*
current_ssb
->
c_re
+
current_ssb
->
c_im
*
current_ssb
->
c_im
;
...
...
@@ -178,42 +173,30 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
free_list
(
best_ssb
);
if
(
ret
==
0
)
{
frame_parms
->
nb_antenna_ports_gNB
=
1
;
//pbch_tx_ant;
if
(
ret
==
0
)
frame_parms
->
nb_antenna_ports_gNB
=
1
;
// pbch_tx_ant;
// set initial transmission mode to 1 or 2 depending on number of detected TX antennas
//
frame_parms->mode1_flag = (pbch_tx_ant==1);
//
frame_parms->mode1_flag = (pbch_tx_ant==1);
// openair_daq_vars.dlsch_transmission_mode = (pbch_tx_ant>1) ? 2 : 1;
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"[UE%d] Initial sync: pbch decoded sucessfully, ssb index %d
\n
"
,
ue
->
Mod_id
,
frame_parms
->
ssb_index
);
#endif
return
(
0
);
}
else
{
return
(
-
1
);
}
return
ret
;
}
int
nr_initial_sync
(
const
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
ue
,
int
n_frames
,
int
sa
)
nr_initial_sync_t
nr_initial_sync
(
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
ue
,
int
n_frames
,
int
sa
)
{
int32_t
sync_pos
,
sync_pos_frame
;
// k_ssb, N_ssb_crb, sync_pos2,
int32_t
metric_tdd_ncp
=
0
;
int32_t
metric_tdd_ncp
=
0
;
uint8_t
phase_tdd_ncp
;
int
frame_id
;
NR_DL_FRAME_PARMS
*
fp
=
&
ue
->
frame_parms
;
int
ret
=-
1
;
int
rx_power
=
0
;
//aarx,
nr_initial_sync_t
ret
=
{
true
,
0
};
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC
,
VCD_FUNCTION_IN
);
LOG_D
(
PHY
,
"nr_initial sync ue RB_DL %d
\n
"
,
fp
->
N_RB_DL
);
LOG_D
(
PHY
,
"nr_initial sync ue RB_DL %d
\n
"
,
fp
->
N_RB_DL
);
/* Initial synchronisation
*
...
...
@@ -229,10 +212,10 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
*/
const
uint32_t
rxdataF_sz
=
ue
->
frame_parms
.
samples_per_slot_wCP
;
__attribute__
((
aligned
(
32
)))
c16_t
rxdataF
[
ue
->
frame_parms
.
nb_antennas_rx
][
rxdataF_sz
];
__attribute__
((
aligned
(
32
)))
c16_t
rxdataF
[
ue
->
frame_parms
.
nb_antennas_rx
][
rxdataF_sz
];
cnt
++
;
if
(
1
){
// (cnt>100)
cnt
=
0
;
if
(
1
)
{
// (cnt>100)
cnt
=
0
;
// initial sync performed on two successive frames, if pbch passes on first frame, no need to process second frame
// only one frame is used for symulation tools
...
...
@@ -246,22 +229,21 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d
\n
"
,
ue
->
Mod_id
,
sync_pos
,
ue
->
common_vars
.
nid2
);
LOG_I
(
PHY
,
"sync_pos %d ssb_offset %d
\n
"
,
sync_pos
,
ue
->
ssb_offset
);
LOG_I
(
PHY
,
"sync_pos %d ssb_offset %d
\n
"
,
sync_pos
,
ue
->
ssb_offset
);
#endif
/* check that SSS/PBCH block is continuous inside the received buffer */
if
(
ue
->
ssb_offset
+
NR_N_SYMBOLS_SSB
*
(
fp
->
ofdm_symbol_size
+
fp
->
nb_prefix_samples
)
<
fp
->
samples_per_frame
)
{
// digital compensation of FFO for SSB symbols
if
(
ue
->
UE_fo_compensation
)
{
double
s_time
=
1
/
(
1.0e3
*
fp
->
samples_per_subframe
);
// sampling time
double
off_angle
=
-
2
*
M_PI
*
s_time
*
(
ue
->
common_vars
.
freq_offset
);
// offset rotation angle compensation per sample
if
(
ue
->
UE_fo_compensation
)
{
double
s_time
=
1
/
(
1.0e3
*
fp
->
samples_per_subframe
);
// sampling time
double
off_angle
=
-
2
*
M_PI
*
s_time
*
(
ue
->
common_vars
.
freq_offset
);
// offset rotation angle compensation per sample
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
// and we do not know yet in which slot it goes.
for
(
int
n
=
frame_id
*
fp
->
samples_per_frame
;
n
<
(
frame_id
+
1
)
*
fp
->
samples_per_frame
;
n
++
)
{
for
(
int
ar
=
0
;
ar
<
fp
->
nb_antennas_rx
;
ar
++
)
{
for
(
int
ar
=
0
;
ar
<
fp
->
nb_antennas_rx
;
ar
++
)
{
const
double
re
=
ue
->
common_vars
.
rxdata
[
ar
][
n
].
r
;
const
double
im
=
ue
->
common_vars
.
rxdata
[
ar
][
n
].
i
;
ue
->
common_vars
.
rxdata
[
ar
][
n
].
r
=
(
short
)(
round
(
re
*
cos
(
n
*
off_angle
)
-
im
*
sin
(
n
*
off_angle
)));
...
...
@@ -283,21 +265,21 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
nr_slot_fep_init_sync
(
ue
,
proc
,
i
,
frame_id
*
fp
->
samples_per_frame
+
ue
->
ssb_offset
,
false
,
rxdataF
,
link_type_dl
);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"Calling sss detection (normal CP)
\n
"
);
LOG_I
(
PHY
,
"Calling sss detection (normal CP)
\n
"
);
#endif
int
freq_offset_sss
=
0
;
bool
ret_sss
=
rx_sss_nr
(
ue
,
proc
,
&
metric_tdd_ncp
,
&
phase_tdd_ncp
,
&
freq_offset_sss
,
rxdataF
);
ret
=
!
ret_sss
;
ret
.
cell_notdetected
=
!
ret_sss
;
// rx_sss_nr returns true if success
// digital compensation of FFO for SSB symbols
if
(
ue
->
UE_fo_compensation
)
{
double
s_time
=
1
/
(
1.0e3
*
fp
->
samples_per_subframe
);
// sampling time
double
off_angle
=
-
2
*
M_PI
*
s_time
*
freq_offset_sss
;
// offset rotation angle compensation per sample
if
(
ue
->
UE_fo_compensation
)
{
double
s_time
=
1
/
(
1.0e3
*
fp
->
samples_per_subframe
);
// sampling time
double
off_angle
=
-
2
*
M_PI
*
s_time
*
freq_offset_sss
;
// offset rotation angle compensation per sample
// In SA we need to perform frequency offset correction until the end of buffer because we need to decode SIB1
// and we do not know yet in which slot it goes.
for
(
int
n
=
frame_id
*
fp
->
samples_per_frame
;
n
<
(
frame_id
+
1
)
*
fp
->
samples_per_frame
;
n
++
)
{
for
(
int
ar
=
0
;
ar
<
fp
->
nb_antennas_rx
;
ar
++
)
{
for
(
int
ar
=
0
;
ar
<
fp
->
nb_antennas_rx
;
ar
++
)
{
const
double
re
=
ue
->
common_vars
.
rxdata
[
ar
][
n
].
r
;
const
double
im
=
ue
->
common_vars
.
rxdata
[
ar
][
n
].
i
;
ue
->
common_vars
.
rxdata
[
ar
][
n
].
r
=
(
short
)(
round
(
re
*
cos
(
n
*
off_angle
)
-
im
*
sin
(
n
*
off_angle
)));
...
...
@@ -308,49 +290,48 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
ue
->
common_vars
.
freq_offset
+=
freq_offset_sss
;
}
if
(
ret
==
0
)
{
//
we got sss channel
if
(
ret
.
cell_notdetected
==
0
)
{
//
we got sss channel
nr_gold_pbch
(
ue
);
ret
=
nr_pbch_detection
(
proc
,
ue
,
1
,
rxdataF
);
// start pbch detection at first symbol after pss
ret
.
cell_notdetected
=
nr_pbch_detection
(
proc
,
ue
,
1
,
rxdataF
);
// start pbch detection at first symbol after pss
}
if
(
ret
==
0
)
{
if
(
ret
.
cell_notdetected
==
0
)
{
// sync at symbol ue->symbol_offset
// computing the offset wrt the beginning of the frame
int
mu
=
fp
->
numerology_index
;
// number of symbols with different prefix length
// every 7*(1<<mu) symbols there is a different prefix length (38.211 5.3.1)
int
n_symb_prefix0
=
(
ue
->
symbol_offset
/
(
7
*
(
1
<<
mu
)))
+
1
;
sync_pos_frame
=
n_symb_prefix0
*
(
fp
->
ofdm_symbol_size
+
fp
->
nb_prefix_samples0
)
+
(
ue
->
symbol_offset
-
n_symb_prefix0
)
*
(
fp
->
ofdm_symbol_size
+
fp
->
nb_prefix_samples
);
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of the n_frames we got sync
int
n_symb_prefix0
=
(
ue
->
symbol_offset
/
(
7
*
(
1
<<
mu
)))
+
1
;
sync_pos_frame
=
n_symb_prefix0
*
(
fp
->
ofdm_symbol_size
+
fp
->
nb_prefix_samples0
)
+
(
ue
->
symbol_offset
-
n_symb_prefix0
)
*
(
fp
->
ofdm_symbol_size
+
fp
->
nb_prefix_samples
);
// for a correct computation of frame number to sync with the one decoded at MIB we need to take into account in which of
// the n_frames we got sync
ue
->
init_sync_frame
=
n_frames
-
1
-
frame_id
;
// compute the scramblingID_pdcch and the gold pdcch
ue
->
scramblingID_pdcch
=
fp
->
Nid_cell
;
nr_gold_pdcch
(
ue
,
fp
->
Nid_cell
);
nr_gold_pdcch
(
ue
,
fp
->
Nid_cell
);
// compute the scrambling IDs for PDSCH DMRS
for
(
int
i
=
0
;
i
<
NR_NB_NSCID
;
i
++
)
{
ue
->
scramblingID_dlsch
[
i
]
=
fp
->
Nid_cell
;
for
(
int
i
=
0
;
i
<
NR_NB_NSCID
;
i
++
)
{
ue
->
scramblingID_dlsch
[
i
]
=
fp
->
Nid_cell
;
nr_gold_pdsch
(
ue
,
i
,
ue
->
scramblingID_dlsch
[
i
]);
}
nr_init_csi_rs
(
fp
,
ue
->
nr_csi_info
->
nr_gold_csi_rs
,
fp
->
Nid_cell
);
// initialize the pusch dmrs
for
(
int
i
=
0
;
i
<
NR_NB_NSCID
;
i
++
)
{
ue
->
scramblingID_ulsch
[
i
]
=
fp
->
Nid_cell
;
for
(
int
i
=
0
;
i
<
NR_NB_NSCID
;
i
++
)
{
ue
->
scramblingID_ulsch
[
i
]
=
fp
->
Nid_cell
;
nr_init_pusch_dmrs
(
ue
,
ue
->
scramblingID_ulsch
[
i
],
i
);
}
// we also need to take into account the shift by samples_per_frame in case the if is true
if
(
ue
->
ssb_offset
<
sync_pos_frame
)
{
ue
->
rx_offset
=
fp
->
samples_per_frame
-
sync_pos_frame
+
ue
->
ssb_offset
;
if
(
ue
->
ssb_offset
<
sync_pos_frame
)
{
ret
.
rx_offset
=
fp
->
samples_per_frame
-
sync_pos_frame
+
ue
->
ssb_offset
;
ue
->
init_sync_frame
+=
1
;
}
else
ue
->
rx_offset
=
ue
->
ssb_offset
-
sync_pos_frame
;
}
else
ret
.
rx_offset
=
ue
->
ssb_offset
-
sync_pos_frame
;
}
/*
...
...
@@ -368,23 +349,26 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
ue->common_vars.freq_offset );
*/
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch %d
\n
"
,
fp
->
Nid_cell
,
metric_tdd_ncp
,
phase_tdd_ncp
,
ret
);
LOG_I
(
PHY
,
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d
\n
"
,
fp
->
Nid_cell
,
metric_tdd_ncp
,
phase_tdd_ncp
,
!
ret
.
cell_notdetected
,
ret
.
rx_offset
);
#endif
}
else
{
}
else
{
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"TDD Normal prefix: SSS error condition: sync_pos %d
\n
"
,
sync_pos
);
LOG_I
(
PHY
,
"TDD Normal prefix: SSS error condition: sync_pos %d
\n
"
,
sync_pos
);
#endif
}
if
(
ret
==
0
)
break
;
}
if
(
ret
.
cell_notdetected
==
0
)
break
;
}
else
{
ret
=
-
1
;
}
else
{
ret
.
cell_notdetected
=
true
;
}
/* Consider this is a false detection if the offset is > 1000 Hz
...
...
@@ -395,25 +379,24 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
}*/
if
(
ret
==
0
)
{
// PBCH found so indicate sync to higher layers and configure frame parameters
if
(
ret
.
cell_notdetected
==
0
)
{
// PBCH found so indicate sync to higher layers and configure frame parameters
//#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"[UE%d] In synch, rx_offset %d samples
\n
"
,
ue
->
Mod_id
,
ue
->
rx_offset
);
LOG_I
(
PHY
,
"[UE%d] In synch, rx_offset %d samples
\n
"
,
ue
->
Mod_id
,
ret
.
rx_offset
);
//#endif
if
(
ue
->
UE_scan_carrier
==
0
)
{
#if UE_AUTOTEST_TRACE
LOG_I
(
PHY
,
"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d
\n
"
,
#if UE_AUTOTEST_TRACE
LOG_I
(
PHY
,
"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d
\n
"
,
ue
->
Mod_id
,
ue
->
rx_offset
,
ue
->
common_vars
.
freq_offset
);
#endif
// send sync status to higher layers later when timing offset converge to target timing
ue
->
common_vars
.
freq_offset
);
#endif
// send sync status to higher layers later when timing offset converge to target timing
}
LOG_I
(
PHY
,
...
...
@@ -428,15 +411,14 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
LOG_I
(
PHY
,
"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d
\n
"
,
ue
->
Mod_id
,
frame_parms
->
Nid_cell
,
frame_parms
->
frame_type
);
#endif
}
// gain control
if
(
ret
!=
0
)
{
//
we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
rx_power
=
0
;
if
(
ret
.
cell_notdetected
!=
0
)
{
//
we are not synched, so we cannot use rssi measurement (which is based on channel estimates)
int
rx_power
=
0
;
// do a measurement on the best guess of the PSS
//for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
//
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
// rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
// frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
...
...
@@ -453,12 +435,10 @@ int nr_initial_sync(const UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_fra
ue
->
measurements
.
rx_power_avg_dB
[
0
]
=
dB_fixed
(
ue
->
measurements
.
rx_power_avg
[
0
]);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I
(
PHY
,
"[UE%d] Initial sync : Estimated power: %d dB
\n
"
,
ue
->
Mod_id
,
ue
->
measurements
.
rx_power_avg_dB
[
0
]
);
LOG_I
(
PHY
,
"[UE%d] Initial sync : Estimated power: %d dB
\n
"
,
ue
->
Mod_id
,
ue
->
measurements
.
rx_power_avg_dB
[
0
]
);
#endif
}
// exit_fun("debug exit");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC
,
VCD_FUNCTION_OUT
);
return
ret
;
}
openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
View file @
c5e4bea6
...
...
@@ -287,6 +287,7 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
/*! \brief receiver for the PBCH
\returns number of tx antennas or -1 if error
*/
int
nr_rx_pbch
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
const
int
estimateSz
,
...
...
@@ -297,11 +298,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
fapiPbch_t
*
result
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
int
nr_pbch_detection
(
const
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
ue
,
int
pbch_initial_symbol
,
c16_t
rxdataF
[][
ue
->
frame_parms
.
samples_per_slot_wCP
]);
#ifndef modOrder
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
#endif
...
...
@@ -323,7 +319,11 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
@param n_frames
@param sa current running mode
*/
int
nr_initial_sync
(
const
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
n_frames
,
int
sa
);
typedef
struct
{
bool
cell_notdetected
;
int
rx_offset
;
}
nr_initial_sync_t
;
nr_initial_sync_t
nr_initial_sync
(
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
int
n_frames
,
int
sa
);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the
...
...
openair1/PHY/defs_nr_UE.h
View file @
c5e4bea6
...
...
@@ -486,11 +486,7 @@ typedef struct PHY_VARS_NR_UE_s {
/// temporary offset during cell search prior to MIB decoding
int
ssb_offset
;
uint16_t
symbol_offset
;
/// offset in terms of symbols for detected ssb in sync
int
rx_offset
;
/// Timing offset
int
rx_offset_diff
;
/// Timing adjustment for ofdm symbol0 on HW USRP
int64_t
max_pos_fil
;
/// Timing offset IIR filter
bool
apply_timing_offset
;
/// Do time sync for current frame
int
time_sync_cell
;
int64_t
max_pos_avg
;
/// Timing offset IIR filter
/// Timing Advance updates variables
/// Timing advance update computed from the TA command signalled from gNB
...
...
@@ -644,6 +640,7 @@ typedef struct nr_rxtx_thread_data_s {
int
writeBlockSize
;
nr_phy_data_t
phy_data
;
int
tx_wait_for_dlsch
;
int
rx_offset
;
}
nr_rxtx_thread_data_t
;
typedef
struct
LDPCDecode_ue_s
{
...
...
openair1/SCHED_NR_UE/defs.h
View file @
c5e4bea6
...
...
@@ -98,7 +98,7 @@ typedef struct {
*/
void
phy_procedures_nrUE_TX
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_tx_t
*
phy_data
);
void
pbch_pdcch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
);
int
pbch_pdcch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
);
void
pdsch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
);
...
...
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
c5e4bea6
...
...
@@ -826,7 +826,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *
return
dec
;
}
void
pbch_pdcch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
)
int
pbch_pdcch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
)
{
int
frame_rx
=
proc
->
frame_rx
;
int
nr_slot_rx
=
proc
->
nr_slot_rx
;
...
...
@@ -834,6 +834,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
fapi_nr_config_request_t
*
cfg
=
&
ue
->
nrUE_config
;
NR_DL_FRAME_PARMS
*
fp
=
&
ue
->
frame_parms
;
NR_UE_PDCCH_CONFIG
*
phy_pdcch_config
=
&
phy_data
->
phy_pdcch_config
;
int
sampleShift
=
0
;
nr_ue_dlsch_init
(
phy_data
->
dlsch
,
NR_MAX_NB_LAYERS
>
4
?
2
:
1
,
ue
->
max_ldpc_iterations
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX
,
VCD_FUNCTION_IN
);
...
...
@@ -896,17 +897,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
if
(
ue
->
no_timing_correction
==
0
&&
pbchSuccess
==
0
)
{
LOG_D
(
PHY
,
"start adjust sync slot = %d no timing %d
\n
"
,
nr_slot_rx
,
ue
->
no_timing_correction
);
nr_adjust_synch_ue
(
fp
,
ue
,
gNB_id
,
fp
->
ofdm_symbol_size
,
dl_ch_estimates_time
,
frame_rx
,
nr_slot_rx
,
0
,
16384
);
sampleShift
=
nr_adjust_synch_ue
(
fp
,
ue
,
gNB_id
,
fp
->
ofdm_symbol_size
,
dl_ch_estimates_time
,
frame_rx
,
nr_slot_rx
,
16384
);
}
ue
->
apply_timing_offset
=
true
;
}
LOG_D
(
PHY
,
"Doing N0 measurements in %s
\n
"
,
__FUNCTION__
);
nr_ue_rrc_measurements
(
ue
,
proc
,
rxdataF
);
...
...
@@ -996,6 +989,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
LOG_D
(
PHY
,
"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs
\n
"
,
ue
->
Mod_id
,
frame_rx
,
nr_slot_rx
,
dci_cnt
);
phy_pdcch_config
->
nb_search_space
=
0
;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH
,
VCD_FUNCTION_OUT
);
return
sampleShift
;
}
void
pdsch_processing
(
PHY_VARS_NR_UE
*
ue
,
const
UE_nr_rxtx_proc_t
*
proc
,
nr_phy_data_t
*
phy_data
)
...
...
openair1/SIMULATION/NR_PHY/dlsim.c
View file @
c5e4bea6
...
...
@@ -959,7 +959,6 @@ int main(int argc, char **argv)
//multipath channel
//multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0);
UE
->
rx_offset
=
0
;
UE_proc
.
frame_rx
=
frame
;
UE_proc
.
nr_slot_rx
=
slot
;
UE_proc
.
gNB_id
=
0
;
...
...
openair1/SIMULATION/NR_PHY/pbchsim.c
View file @
c5e4bea6
...
...
@@ -766,18 +766,19 @@ int main(int argc, char **argv)
}
if
(
UE
->
is_synchronized
==
0
)
{
UE_nr_rxtx_proc_t
proc
=
{
0
};
ret
=
nr_initial_sync
(
&
proc
,
UE
,
1
,
0
);
printf
(
"nr_initial_sync1 returns %d
\n
"
,
ret
);
if
(
ret
<
0
)
n_errors
++
;
nr_initial_sync_t
ret
=
nr_initial_sync
(
&
proc
,
UE
,
1
,
0
);
printf
(
"nr_initial_sync1 returns %d
\n
"
,
ret
.
cell_notdetected
);
if
(
ret
.
cell_notdetected
)
n_errors
++
;
}
else
{
UE_nr_rxtx_proc_t
proc
=
{
0
};
UE
->
rx_offset
=
0
;
uint8_t
ssb_index
=
0
;
const
int
estimateSz
=
frame_parms
->
symbols_per_slot
*
frame_parms
->
ofdm_symbol_size
;
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates
[
frame_parms
->
nb_antennas_rx
][
estimateSz
];
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_time
[
frame_parms
->
nb_antennas_rx
][
frame_parms
->
ofdm_symbol_size
];
__attribute__
((
aligned
(
32
)))
struct
complex16
dl_ch_estimates_time
[
frame_parms
->
nb_antennas_rx
][
frame_parms
->
ofdm_symbol_size
];
while
(
!
((
SSB_positions
>>
ssb_index
)
&
0x01
))
ssb_index
++
;
// to select the first transmitted ssb
UE
->
symbol_offset
=
nr_get_ssb_start_symbol
(
frame_parms
,
ssb_index
);
...
...
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