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
wangjie
OpenXG-RAN
Commits
bdeec18c
Commit
bdeec18c
authored
Dec 22, 2020
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement DL HARQ using NR_list_t
parent
835b1fa3
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
95 additions
and
90 deletions
+95
-90
openair1/SIMULATION/NR_PHY/dlsim.c
openair1/SIMULATION/NR_PHY/dlsim.c
+14
-0
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+24
-7
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+2
-0
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+51
-82
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+4
-1
No files found.
openair1/SIMULATION/NR_PHY/dlsim.c
View file @
bdeec18c
...
...
@@ -181,6 +181,20 @@ void nr_dlsim_preprocessor(module_id_t module_id,
sched_ctrl
->
mcs
=
g_mcsIndex
;
sched_ctrl
->
time_domain_allocation
=
2
;
sched_ctrl
->
mcsTableIdx
=
g_mcsTableIdx
;
/* the simulator assumes the HARQ PID is equal to the slot number */
sched_ctrl
->
dl_harq_pid
=
slot
;
/* The scheduler uses lists to track whether a HARQ process is
* free/busy/awaiting retransmission, and updates the HARQ process states.
* However, in the simulation, we never get ack or nack for any HARQ process,
* thus the list and HARQ states don't match what the scheduler expects.
* Therefore, below lines just "repair" everything so that the scheduler
* won't remark that there is no HARQ feedback */
sched_ctrl
->
feedback_dl_harq
.
head
=
-
1
;
// always overwrite feedback HARQ process
if
(
sched_ctrl
->
harq_processes
[
slot
].
round
==
0
)
// depending on round set in simulation ...
add_front_nr_list
(
&
sched_ctrl
->
available_dl_harq
,
slot
);
// ... make PID available
else
add_front_nr_list
(
&
sched_ctrl
->
retrans_dl_harq
,
slot
);
// ... make PID retransmission
sched_ctrl
->
harq_processes
[
slot
].
is_waiting
=
false
;
AssertFatal
(
sched_ctrl
->
rbStart
>=
0
,
"invalid rbStart %d
\n
"
,
sched_ctrl
->
rbStart
);
AssertFatal
(
sched_ctrl
->
rbSize
>
0
,
"invalid rbSize %d
\n
"
,
sched_ctrl
->
rbSize
);
AssertFatal
(
sched_ctrl
->
mcs
>=
0
,
"invalid sched_ctrl->mcs %d
\n
"
,
sched_ctrl
->
mcs
);
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
View file @
bdeec18c
...
...
@@ -418,14 +418,13 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
}
uint16_t
*
vrb_map
=
RC
.
nrmac
[
module_id
]
->
common_channels
[
CC_id
].
vrb_map
;
// for now HARQ PID is fixed and should be the same as in post-processor
const
int
current_harq_pid
=
slot
%
8
;
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
current_harq_pid
];
NR_UE_ret_info_t
*
retInfo
=
&
sched_ctrl
->
retInfo
[
current_harq_pid
];
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
sched_ctrl
->
dl_harq_pid
=
sched_ctrl
->
retrans_dl_harq
.
head
;
const
uint16_t
bwpSize
=
NRRIV2BW
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
275
);
int
rbStart
=
NRRIV2PRBOFFSET
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
275
);
if
(
harq
->
round
!=
0
)
{
/* retransmission */
if
(
sched_ctrl
->
dl_harq_pid
>=
0
)
{
/* retransmission */
NR_UE_ret_info_t
*
retInfo
=
&
sched_ctrl
->
retInfo
[
sched_ctrl
->
dl_harq_pid
];
sched_ctrl
->
time_domain_allocation
=
retInfo
->
time_domain_allocation
;
/* ensure that there is a free place for RB allocation */
...
...
@@ -563,11 +562,29 @@ void nr_schedule_ue_spec(module_id_t module_id,
nrOfLayers
)
>>
3
;
const
int
current_harq_pid
=
slot
%
8
;
int8_t
current_harq_pid
=
sched_ctrl
->
dl_harq_pid
;
if
(
current_harq_pid
<
0
)
{
/* PP has not selected a specific HARQ Process, get a new one */
current_harq_pid
=
sched_ctrl
->
available_dl_harq
.
head
;
AssertFatal
(
current_harq_pid
>=
0
,
"no free HARQ process available for UE %d
\n
"
,
UE_id
);
remove_front_nr_list
(
&
sched_ctrl
->
available_dl_harq
);
}
else
{
/* PP selected a specific HARQ process. Check whether it will be a new
* transmission or a retransmission, and remove from the corresponding
* list */
if
(
sched_ctrl
->
harq_processes
[
current_harq_pid
].
round
==
0
)
remove_nr_list
(
&
sched_ctrl
->
available_dl_harq
,
current_harq_pid
);
else
remove_nr_list
(
&
sched_ctrl
->
retrans_dl_harq
,
current_harq_pid
);
}
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
current_harq_pid
];
DevAssert
(
!
harq
->
is_waiting
);
add_tail_nr_list
(
&
sched_ctrl
->
feedback_dl_harq
,
current_harq_pid
);
NR_sched_pucch_t
*
pucch
=
&
sched_ctrl
->
sched_pucch
[
0
];
harq
->
feedback_slot
=
pucch
->
ul_slot
;
harq
->
is_waiting
=
1
;
harq
->
is_waiting
=
true
;
UE_info
->
mac_stats
[
UE_id
].
dlsch_rounds
[
harq
->
round
]
++
;
LOG_D
(
MAC
,
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
View file @
bdeec18c
...
...
@@ -360,6 +360,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
}
sched_ctrl
->
mcs
=
9
;
sched_ctrl
->
numDmrsCdmGrpsNoData
=
1
;
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
sched_ctrl
->
dl_harq_pid
=
sched_ctrl
->
retrans_dl_harq
.
head
;
/* mark the corresponding RBs as used */
for
(
int
rb
=
0
;
rb
<
sched_ctrl
->
rbSize
;
rb
++
)
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
View file @
bdeec18c
...
...
@@ -291,6 +291,31 @@ void nr_csi_meas_reporting(int Mod_idP,
}
}
static
void
handle_dl_harq
(
module_id_t
mod_id
,
int
UE_id
,
int8_t
harq_pid
,
bool
success
)
{
NR_UE_info_t
*
UE_info
=
&
RC
.
nrmac
[
mod_id
]
->
UE_info
;
NR_UE_harq_t
*
harq
=
&
UE_info
->
UE_sched_ctrl
[
UE_id
].
harq_processes
[
harq_pid
];
harq
->
feedback_slot
=
-
1
;
harq
->
is_waiting
=
false
;
if
(
success
)
{
add_tail_nr_list
(
&
UE_info
->
UE_sched_ctrl
[
UE_id
].
available_dl_harq
,
harq_pid
);
harq
->
round
=
0
;
harq
->
ndi
^=
1
;
}
else
if
(
harq
->
round
==
MAX_HARQ_ROUNDS
)
{
add_tail_nr_list
(
&
UE_info
->
UE_sched_ctrl
[
UE_id
].
available_dl_harq
,
harq_pid
);
harq
->
round
=
0
;
harq
->
ndi
^=
1
;
NR_mac_stats_t
*
stats
=
&
UE_info
->
mac_stats
[
UE_id
];
stats
->
dlsch_errors
++
;
LOG_D
(
MAC
,
"retransmission error for UE %d (total %d)
\n
"
,
UE_id
,
stats
->
dlsch_errors
);
}
else
{
add_tail_nr_list
(
&
UE_info
->
UE_sched_ctrl
[
UE_id
].
retrans_dl_harq
,
harq_pid
);
harq
->
round
++
;
}
}
void
handle_nr_uci_pucch_0_1
(
module_id_t
mod_id
,
frame_t
frame
,
...
...
@@ -310,50 +335,23 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
uci_01
->
ul_cqi
,
30
);
// TODO
int
max_harq_rounds
=
4
;
// TODO define macro
NR_ServingCellConfigCommon_t
*
scc
=
RC
.
nrmac
[
mod_id
]
->
common_channels
->
ServingCellConfigCommon
;
const
int
num_slots
=
nr_slots_per_frame
[
*
scc
->
ssbSubcarrierSpacing
];
if
(((
uci_01
->
pduBitmap
>>
1
)
&
0x01
))
{
// handle harq
int
harq_idx_s
=
0
;
// iterate over received harq bits
for
(
int
harq_bit
=
0
;
harq_bit
<
uci_01
->
harq
->
num_harq
;
harq_bit
++
)
{
// search for the right harq process
for
(
int
harq_idx
=
harq_idx_s
;
harq_idx
<
NR_MAX_NB_HARQ_PROCESSES
;
harq_idx
++
)
{
// if the gNB received ack with a good confidence
if
((
slot
-
1
)
==
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
if
((
uci_01
->
harq
->
harq_list
[
harq_bit
].
harq_value
==
1
)
&&
(
uci_01
->
harq
->
harq_confidence_level
==
0
))
{
// toggle NDI and reset round
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
}
else
sched_ctrl
->
harq_processes
[
harq_idx
].
round
++
;
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
=
0
;
harq_idx_s
=
harq_idx
+
1
;
// if the max harq rounds was reached
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
round
==
max_harq_rounds
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
UE_info
->
mac_stats
[
UE_id
].
dlsch_errors
++
;
}
break
;
}
// if feedback slot processing is aborted
else
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
!=
-
1
&&
(
slot
-
1
)
>
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
&&
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
++
;
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
round
==
max_harq_rounds
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
}
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
=
0
;
}
}
const
uint8_t
harq_value
=
uci_01
->
harq
->
harq_list
[
harq_bit
].
harq_value
;
const
uint8_t
harq_confidence
=
uci_01
->
harq
->
harq_confidence_level
;
const
int8_t
pid
=
sched_ctrl
->
feedback_dl_harq
.
head
;
DevAssert
(
pid
>=
0
);
remove_front_nr_list
(
&
sched_ctrl
->
feedback_dl_harq
);
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
pid
];
const
int
feedback_slot
=
(
slot
-
1
+
num_slots
)
%
num_slots
;
AssertFatal
(
harq
->
feedback_slot
==
feedback_slot
,
"expected feedback slot %d, but found %d instead
\n
"
,
harq
->
feedback_slot
,
feedback_slot
);
DevAssert
(
harq
->
is_waiting
);
handle_dl_harq
(
mod_id
,
UE_id
,
pid
,
harq_value
==
1
&&
harq_confidence
==
0
);
}
}
}
...
...
@@ -376,50 +374,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
uci_234
->
ul_cqi
,
30
);
// TODO
int
max_harq_rounds
=
4
;
// TODO define macro
NR_ServingCellConfigCommon_t
*
scc
=
RC
.
nrmac
[
mod_id
]
->
common_channels
->
ServingCellConfigCommon
;
const
int
num_slots
=
nr_slots_per_frame
[
*
scc
->
ssbSubcarrierSpacing
];
if
((
uci_234
->
pduBitmap
>>
1
)
&
0x01
)
{
int
harq_idx_s
=
0
;
int
acknack
;
// iterate over received harq bits
for
(
int
harq_bit
=
0
;
harq_bit
<
uci_234
->
harq
.
harq_bit_len
;
harq_bit
++
)
{
acknack
=
((
uci_234
->
harq
.
harq_payload
[
harq_bit
>>
3
])
>>
harq_bit
)
&
0x01
;
for
(
int
harq_idx
=
harq_idx_s
;
harq_idx
<
NR_MAX_NB_HARQ_PROCESSES
-
1
;
harq_idx
++
)
{
// if the gNB received ack with a good confidence or if the max harq rounds was reached
if
((
slot
-
1
)
==
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
)
{
// TODO add some confidence level for when there is no CRC
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
if
((
uci_234
->
harq
.
harq_crc
!=
1
)
&&
acknack
)
{
// toggle NDI and reset round
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
}
else
sched_ctrl
->
harq_processes
[
harq_idx
].
round
++
;
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
=
0
;
harq_idx_s
=
harq_idx
+
1
;
// if the max harq rounds was reached
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
round
==
max_harq_rounds
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
UE_info
->
mac_stats
[
UE_id
].
dlsch_errors
++
;
}
break
;
}
// if feedback slot processing is aborted
else
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
!=
-
1
&&
(
slot
-
1
)
>
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
&&
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
++
;
if
(
sched_ctrl
->
harq_processes
[
harq_idx
].
round
==
max_harq_rounds
)
{
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
}
sched_ctrl
->
harq_processes
[
harq_idx
].
is_waiting
=
0
;
}
}
const
int
acknack
=
((
uci_234
->
harq
.
harq_payload
[
harq_bit
>>
3
])
>>
harq_bit
)
&
0x01
;
const
int8_t
pid
=
sched_ctrl
->
feedback_dl_harq
.
head
;
DevAssert
(
pid
>=
0
);
remove_front_nr_list
(
&
sched_ctrl
->
feedback_dl_harq
);
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
pid
];
const
int
feedback_slot
=
(
slot
-
1
+
num_slots
)
%
num_slots
;
AssertFatal
(
harq
->
feedback_slot
==
feedback_slot
,
"expected feedback slot %d, but found %d instead
\n
"
,
harq
->
feedback_slot
,
feedback_slot
);
handle_dl_harq
(
mod_id
,
UE_id
,
pid
,
uci_234
->
harq
.
harq_crc
!=
1
&&
acknack
);
}
}
}
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
bdeec18c
...
...
@@ -75,6 +75,7 @@
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
#define MAX_HARQ_ROUNDS 4
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
...
...
@@ -338,7 +339,7 @@ typedef struct NR_sched_pusch {
}
NR_sched_pusch_t
;
typedef
struct
NR_UE_harq
{
uint8_t
is_waiting
;
bool
is_waiting
;
uint8_t
ndi
;
uint8_t
round
;
uint16_t
feedback_slot
;
...
...
@@ -425,6 +426,8 @@ typedef struct {
/// Retransmission-related information
NR_UE_ret_info_t
retInfo
[
NR_MAX_NB_HARQ_PROCESSES
];
/// DL HARQ PID to use for this UE, or -1 for "any new"
int8_t
dl_harq_pid
;
uint16_t
ta_frame
;
int16_t
ta_update
;
...
...
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