Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
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
Michael Black
OpenXG UE
Commits
e28a27a6
Commit
e28a27a6
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
22d48799
Changes
5
Hide 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 @
e28a27a6
...
@@ -207,6 +207,20 @@ void nr_dlsim_preprocessor(module_id_t module_id,
...
@@ -207,6 +207,20 @@ void nr_dlsim_preprocessor(module_id_t module_id,
sched_ctrl
->
mcs
=
g_mcsIndex
;
sched_ctrl
->
mcs
=
g_mcsIndex
;
sched_ctrl
->
time_domain_allocation
=
2
;
sched_ctrl
->
time_domain_allocation
=
2
;
sched_ctrl
->
mcsTableIdx
=
g_mcsTableIdx
;
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
->
rbStart
>=
0
,
"invalid rbStart %d
\n
"
,
sched_ctrl
->
rbStart
);
AssertFatal
(
sched_ctrl
->
rbSize
>
0
,
"invalid rbSize %d
\n
"
,
sched_ctrl
->
rbSize
);
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
);
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 @
e28a27a6
...
@@ -418,14 +418,13 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
...
@@ -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
;
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
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
const
int
current_harq_pid
=
slot
%
8
;
sched_ctrl
->
dl_harq_pid
=
sched_ctrl
->
retrans_dl_harq
.
head
;
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
current_harq_pid
];
NR_UE_ret_info_t
*
retInfo
=
&
sched_ctrl
->
retInfo
[
current_harq_pid
];
const
uint16_t
bwpSize
=
NRRIV2BW
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
MAX_BWP_SIZE
);
const
uint16_t
bwpSize
=
NRRIV2BW
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
MAX_BWP_SIZE
);
int
rbStart
=
NRRIV2PRBOFFSET
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
MAX_BWP_SIZE
);
int
rbStart
=
NRRIV2PRBOFFSET
(
sched_ctrl
->
active_bwp
->
bwp_Common
->
genericParameters
.
locationAndBandwidth
,
MAX_BWP_SIZE
);
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
;
sched_ctrl
->
time_domain_allocation
=
retInfo
->
time_domain_allocation
;
/* ensure that there is a free place for RB 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,
...
@@ -563,11 +562,29 @@ void nr_schedule_ue_spec(module_id_t module_id,
nrOfLayers
)
nrOfLayers
)
>>
3
;
>>
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
];
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
];
NR_sched_pucch_t
*
pucch
=
&
sched_ctrl
->
sched_pucch
[
0
];
harq
->
feedback_slot
=
pucch
->
ul_slot
;
harq
->
feedback_slot
=
pucch
->
ul_slot
;
harq
->
is_waiting
=
1
;
harq
->
is_waiting
=
true
;
UE_info
->
mac_stats
[
UE_id
].
dlsch_rounds
[
harq
->
round
]
++
;
UE_info
->
mac_stats
[
UE_id
].
dlsch_rounds
[
harq
->
round
]
++
;
LOG_D
(
MAC
,
LOG_D
(
MAC
,
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
View file @
e28a27a6
...
@@ -360,6 +360,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
...
@@ -360,6 +360,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
}
}
sched_ctrl
->
mcs
=
9
;
sched_ctrl
->
mcs
=
9
;
sched_ctrl
->
numDmrsCdmGrpsNoData
=
1
;
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 */
/* mark the corresponding RBs as used */
for
(
int
rb
=
0
;
rb
<
sched_ctrl
->
rbSize
;
rb
++
)
for
(
int
rb
=
0
;
rb
<
sched_ctrl
->
rbSize
;
rb
++
)
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
View file @
e28a27a6
...
@@ -290,6 +290,31 @@ void nr_csi_meas_reporting(int Mod_idP,
...
@@ -290,6 +290,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
,
void
handle_nr_uci_pucch_0_1
(
module_id_t
mod_id
,
frame_t
frame
,
frame_t
frame
,
...
@@ -309,50 +334,23 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
...
@@ -309,50 +334,23 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
uci_01
->
ul_cqi
,
uci_01
->
ul_cqi
,
30
);
30
);
// TODO
NR_ServingCellConfigCommon_t
*
scc
=
RC
.
nrmac
[
mod_id
]
->
common_channels
->
ServingCellConfigCommon
;
int
max_harq_rounds
=
4
;
// TODO define macro
const
int
num_slots
=
nr_slots_per_frame
[
*
scc
->
ssbSubcarrierSpacing
];
if
(((
uci_01
->
pduBitmap
>>
1
)
&
0x01
))
{
if
(((
uci_01
->
pduBitmap
>>
1
)
&
0x01
))
{
// handle harq
int
harq_idx_s
=
0
;
// iterate over received harq bits
// iterate over received harq bits
for
(
int
harq_bit
=
0
;
harq_bit
<
uci_01
->
harq
->
num_harq
;
harq_bit
++
)
{
for
(
int
harq_bit
=
0
;
harq_bit
<
uci_01
->
harq
->
num_harq
;
harq_bit
++
)
{
// search for the right harq process
const
uint8_t
harq_value
=
uci_01
->
harq
->
harq_list
[
harq_bit
].
harq_value
;
for
(
int
harq_idx
=
harq_idx_s
;
harq_idx
<
NR_MAX_NB_HARQ_PROCESSES
;
harq_idx
++
)
{
const
uint8_t
harq_confidence
=
uci_01
->
harq
->
harq_confidence_level
;
// if the gNB received ack with a good confidence
const
int8_t
pid
=
sched_ctrl
->
feedback_dl_harq
.
head
;
if
((
slot
-
1
)
==
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
)
{
DevAssert
(
pid
>=
0
);
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
remove_front_nr_list
(
&
sched_ctrl
->
feedback_dl_harq
);
if
((
uci_01
->
harq
->
harq_list
[
harq_bit
].
harq_value
==
1
)
&&
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
pid
];
(
uci_01
->
harq
->
harq_confidence_level
==
0
))
{
const
int
feedback_slot
=
(
slot
-
1
+
num_slots
)
%
num_slots
;
// toggle NDI and reset round
AssertFatal
(
harq
->
feedback_slot
==
feedback_slot
,
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
"expected feedback slot %d, but found %d instead
\n
"
,
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
harq
->
feedback_slot
,
feedback_slot
);
}
DevAssert
(
harq
->
is_waiting
);
else
handle_dl_harq
(
mod_id
,
UE_id
,
pid
,
harq_value
==
1
&&
harq_confidence
==
0
);
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
;
}
}
}
}
}
}
}
}
...
@@ -375,50 +373,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
...
@@ -375,50 +373,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
uci_234
->
ul_cqi
,
uci_234
->
ul_cqi
,
30
);
30
);
// TODO
NR_ServingCellConfigCommon_t
*
scc
=
RC
.
nrmac
[
mod_id
]
->
common_channels
->
ServingCellConfigCommon
;
int
max_harq_rounds
=
4
;
// TODO define macro
const
int
num_slots
=
nr_slots_per_frame
[
*
scc
->
ssbSubcarrierSpacing
];
if
((
uci_234
->
pduBitmap
>>
1
)
&
0x01
)
{
if
((
uci_234
->
pduBitmap
>>
1
)
&
0x01
)
{
int
harq_idx_s
=
0
;
int
acknack
;
// iterate over received harq bits
// iterate over received harq bits
for
(
int
harq_bit
=
0
;
harq_bit
<
uci_234
->
harq
.
harq_bit_len
;
harq_bit
++
)
{
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
;
const
int
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
++
)
{
const
int8_t
pid
=
sched_ctrl
->
feedback_dl_harq
.
head
;
// if the gNB received ack with a good confidence or if the max harq rounds was reached
DevAssert
(
pid
>=
0
);
if
((
slot
-
1
)
==
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
)
{
remove_front_nr_list
(
&
sched_ctrl
->
feedback_dl_harq
);
// TODO add some confidence level for when there is no CRC
NR_UE_harq_t
*
harq
=
&
sched_ctrl
->
harq_processes
[
pid
];
sched_ctrl
->
harq_processes
[
harq_idx
].
feedback_slot
=
-
1
;
const
int
feedback_slot
=
(
slot
-
1
+
num_slots
)
%
num_slots
;
if
((
uci_234
->
harq
.
harq_crc
!=
1
)
&&
acknack
)
{
AssertFatal
(
harq
->
feedback_slot
==
feedback_slot
,
// toggle NDI and reset round
"expected feedback slot %d, but found %d instead
\n
"
,
sched_ctrl
->
harq_processes
[
harq_idx
].
ndi
^=
1
;
harq
->
feedback_slot
,
feedback_slot
);
sched_ctrl
->
harq_processes
[
harq_idx
].
round
=
0
;
handle_dl_harq
(
mod_id
,
UE_id
,
pid
,
uci_234
->
harq
.
harq_crc
!=
1
&&
acknack
);
}
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
;
}
}
}
}
}
}
}
}
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
e28a27a6
...
@@ -75,6 +75,7 @@
...
@@ -75,6 +75,7 @@
#define MAX_NUM_BWP 2
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
#define MAX_NUM_CCE 90
#define MAX_HARQ_ROUNDS 4
/*!\brief Maximum number of random access process */
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
#define MAX_NUM_OF_SSB 64
...
@@ -338,7 +339,7 @@ typedef struct NR_sched_pusch {
...
@@ -338,7 +339,7 @@ typedef struct NR_sched_pusch {
}
NR_sched_pusch_t
;
}
NR_sched_pusch_t
;
typedef
struct
NR_UE_harq
{
typedef
struct
NR_UE_harq
{
uint8_t
is_waiting
;
bool
is_waiting
;
uint8_t
ndi
;
uint8_t
ndi
;
uint8_t
round
;
uint8_t
round
;
uint16_t
feedback_slot
;
uint16_t
feedback_slot
;
...
@@ -425,6 +426,8 @@ typedef struct {
...
@@ -425,6 +426,8 @@ typedef struct {
/// Retransmission-related information
/// Retransmission-related information
NR_UE_ret_info_t
retInfo
[
NR_MAX_NB_HARQ_PROCESSES
];
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
;
uint16_t
ta_frame
;
int16_t
ta_update
;
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