Merge remote-tracking branch 'origin/NR_UE_harq_improvements' into integration_2023_w37
This commit is contained in:
@@ -40,7 +40,6 @@
|
|||||||
#define DL_ACKNACK_NO_SET (2)
|
#define DL_ACKNACK_NO_SET (2)
|
||||||
#define DL_NACK (0)
|
#define DL_NACK (0)
|
||||||
#define DL_ACK (1)
|
#define DL_ACK (1)
|
||||||
#define DL_MAX_NB_FEEDBACK (NR_DL_MAX_DAI * NR_DL_MAX_NB_CW)
|
|
||||||
#define DL_DAI_NO_SET (0xFF)
|
#define DL_DAI_NO_SET (0xFF)
|
||||||
#define UL_DAI_NO_SET (DL_DAI_NO_SET)
|
#define UL_DAI_NO_SET (DL_DAI_NO_SET)
|
||||||
|
|
||||||
|
|||||||
@@ -332,23 +332,21 @@ typedef struct {
|
|||||||
bool active;
|
bool active;
|
||||||
bool ack_received;
|
bool ack_received;
|
||||||
uint8_t pucch_resource_indicator;
|
uint8_t pucch_resource_indicator;
|
||||||
uint16_t feedback_to_ul;
|
frame_t ul_frame;
|
||||||
frame_t dl_frame;
|
int ul_slot;
|
||||||
int dl_slot;
|
|
||||||
uint8_t ack;
|
uint8_t ack;
|
||||||
uint8_t dai;
|
uint8_t dai;
|
||||||
int n_CCE;
|
int n_CCE;
|
||||||
int N_CCE;
|
int N_CCE;
|
||||||
|
int j_dai;
|
||||||
int8_t delta_pucch;
|
int8_t delta_pucch;
|
||||||
} NR_UE_HARQ_STATUS_t;
|
} NR_UE_HARQ_STATUS_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
uint8_t freq_hopping;
|
uint8_t freq_hopping;
|
||||||
uint8_t mcs;
|
uint8_t mcs;
|
||||||
uint8_t Msg3_t_alloc;
|
uint8_t Msg3_t_alloc;
|
||||||
uint16_t Msg3_f_alloc;
|
uint16_t Msg3_f_alloc;
|
||||||
|
|
||||||
} RAR_grant_t;
|
} RAR_grant_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -1182,24 +1182,43 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
|
|||||||
current_harq->active = true;
|
current_harq->active = true;
|
||||||
current_harq->ack_received = false;
|
current_harq->ack_received = false;
|
||||||
current_harq->pucch_resource_indicator = pucch_id;
|
current_harq->pucch_resource_indicator = pucch_id;
|
||||||
current_harq->feedback_to_ul = data_toul_fb;
|
|
||||||
current_harq->dai = dai;
|
current_harq->dai = dai;
|
||||||
|
current_harq->j_dai = 0;
|
||||||
current_harq->n_CCE = n_CCE;
|
current_harq->n_CCE = n_CCE;
|
||||||
current_harq->N_CCE = N_CCE;
|
current_harq->N_CCE = N_CCE;
|
||||||
current_harq->delta_pucch = delta_pucch;
|
current_harq->delta_pucch = delta_pucch;
|
||||||
// FIXME k0 != 0 currently not taken into consideration
|
// FIXME k0 != 0 currently not taken into consideration
|
||||||
current_harq->dl_frame = frame;
|
|
||||||
current_harq->dl_slot = slot;
|
|
||||||
int scs = get_softmodem_params()->numerology;
|
int scs = get_softmodem_params()->numerology;
|
||||||
int slots_per_frame = nr_slots_per_frame[scs];
|
int slots_per_frame = nr_slots_per_frame[scs];
|
||||||
slot += data_toul_fb;
|
current_harq->ul_frame = frame;
|
||||||
if (slot >= slots_per_frame) {
|
current_harq->ul_slot = slot + data_toul_fb;
|
||||||
frame = (frame + 1) % 1024;
|
if (current_harq->ul_slot >= slots_per_frame) {
|
||||||
slot %= slots_per_frame;
|
current_harq->ul_frame = (frame + 1) % 1024;
|
||||||
|
current_harq->ul_slot %= slots_per_frame;
|
||||||
}
|
}
|
||||||
|
// counter DAI in DCI ranges from 0 to 3
|
||||||
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n",
|
// we might have more than 4 HARQ processes to report per PUCCH
|
||||||
harq_id, current_harq->dl_frame, current_harq->dl_slot, frame, slot);
|
// we need to keep track of how many same DAI were received
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
||||||
|
if (i == harq_id)
|
||||||
|
continue;
|
||||||
|
NR_UE_HARQ_STATUS_t *harq = &mac->dl_harq_info[i];
|
||||||
|
if (harq->active &&
|
||||||
|
harq->ul_frame == current_harq->ul_frame &&
|
||||||
|
harq->ul_slot == current_harq->ul_slot) {
|
||||||
|
if (harq->dai == dai) {
|
||||||
|
// need to take into account possible
|
||||||
|
// missed DCI detections
|
||||||
|
int missed_detections = count / (4 * (current_harq->j_dai + 1));
|
||||||
|
current_harq->j_dai += (missed_detections + 1);
|
||||||
|
count += missed_detections;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d fb time %d\n",
|
||||||
|
harq_id, frame, slot, current_harq->ul_frame, current_harq->ul_slot, data_toul_fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
|
||||||
@@ -2099,60 +2118,42 @@ void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int n
|
|||||||
|
|
||||||
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch)
|
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch)
|
||||||
{
|
{
|
||||||
uint32_t ack_data[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}};
|
uint32_t ack_data[NR_DL_MAX_NB_CW][NR_MAX_HARQ_PROCESSES] = {{0},{0}};
|
||||||
uint32_t dai[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for serving cell */
|
uint32_t dai[NR_DL_MAX_NB_CW][NR_MAX_HARQ_PROCESSES] = {{0},{0}}; /* for serving cell */
|
||||||
uint32_t dai_total[NR_DL_MAX_NB_CW][NR_DL_MAX_DAI] = {{0},{0}}; /* for multiple cells */
|
uint32_t dai_total[NR_DL_MAX_NB_CW][NR_MAX_HARQ_PROCESSES] = {{0},{0}}; /* for multiple cells */
|
||||||
int number_harq_feedback = 0;
|
int number_harq_feedback = 0;
|
||||||
uint32_t dai_current = 0;
|
|
||||||
uint32_t dai_max = 0;
|
uint32_t dai_max = 0;
|
||||||
bool two_transport_blocks = false;
|
|
||||||
int number_of_code_word = 1;
|
|
||||||
int U_DAI_c = 0;
|
|
||||||
int N_m_c_rx = 0;
|
|
||||||
int V_DAI_m_DL = 0;
|
|
||||||
NR_UE_HARQ_STATUS_t *current_harq;
|
|
||||||
int sched_frame,sched_slot;
|
|
||||||
int slots_per_frame;
|
|
||||||
|
|
||||||
NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP;
|
NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP;
|
||||||
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
|
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
|
||||||
|
|
||||||
|
bool two_transport_blocks = false;
|
||||||
|
int number_of_code_word = 1;
|
||||||
if (current_DL_BWP && current_DL_BWP->pdsch_Config && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI[0] == 2) {
|
if (current_DL_BWP && current_DL_BWP->pdsch_Config && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI && current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI[0] == 2) {
|
||||||
two_transport_blocks = true;
|
two_transport_blocks = true;
|
||||||
number_of_code_word = 2;
|
number_of_code_word = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scs = current_UL_BWP->scs;
|
|
||||||
|
|
||||||
slots_per_frame = nr_slots_per_frame[scs];
|
|
||||||
int res_ind = -1;
|
int res_ind = -1;
|
||||||
|
|
||||||
/* look for dl acknowledgment which should be done on current uplink slot */
|
/* look for dl acknowledgment which should be done on current uplink slot */
|
||||||
for (int code_word = 0; code_word < number_of_code_word; code_word++) {
|
for (int code_word = 0; code_word < number_of_code_word; code_word++) {
|
||||||
|
|
||||||
for (int dl_harq_pid = 0; dl_harq_pid < 16; dl_harq_pid++) {
|
for (int dl_harq_pid = 0; dl_harq_pid < NR_MAX_HARQ_PROCESSES; dl_harq_pid++) {
|
||||||
|
|
||||||
current_harq = &mac->dl_harq_info[dl_harq_pid];
|
NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dl_harq_pid];
|
||||||
|
|
||||||
if (current_harq->active) {
|
if (current_harq->active) {
|
||||||
|
LOG_D(PHY, "HARQ pid %d is active for %d.%d\n",
|
||||||
sched_slot = current_harq->dl_slot + current_harq->feedback_to_ul;
|
dl_harq_pid, current_harq->ul_frame, current_harq->ul_slot);
|
||||||
sched_frame = current_harq->dl_frame;
|
|
||||||
if (sched_slot >= slots_per_frame) {
|
|
||||||
sched_slot %= slots_per_frame;
|
|
||||||
sched_frame = (sched_frame + 1) % 1024;
|
|
||||||
}
|
|
||||||
AssertFatal(sched_slot < slots_per_frame, "sched_slot was calculated incorrect %d\n", sched_slot);
|
|
||||||
LOG_D(PHY, "HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d\n", dl_harq_pid, sched_frame, sched_slot, current_harq->dl_slot, current_harq->feedback_to_ul);
|
|
||||||
/* check if current tx slot should transmit downlink acknowlegment */
|
/* check if current tx slot should transmit downlink acknowlegment */
|
||||||
if (sched_frame == frame && sched_slot == slot) {
|
if (current_harq->ul_frame == frame && current_harq->ul_slot == slot) {
|
||||||
if (get_softmodem_params()->emulate_l1) {
|
if (get_softmodem_params()->emulate_l1) {
|
||||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active = true;
|
mac->nr_ue_emul_l1.harq[dl_harq_pid].active = true;
|
||||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_sfn = frame;
|
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_sfn = frame;
|
||||||
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_slot = slot;
|
mac->nr_ue_emul_l1.harq[dl_harq_pid].active_dl_harq_slot = slot;
|
||||||
}
|
}
|
||||||
|
if (current_harq->dai >= NR_DL_MAX_DAI) {
|
||||||
if (current_harq->dai > NR_DL_MAX_DAI) {
|
|
||||||
LOG_E(MAC,"PUCCH Downlink DAI has an invalid value of %d\n", current_harq->dai);
|
LOG_E(MAC,"PUCCH Downlink DAI has an invalid value of %d\n", current_harq->dai);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2162,7 +2163,7 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
|
|||||||
current_harq->pucch_resource_indicator,
|
current_harq->pucch_resource_indicator,
|
||||||
res_ind);
|
res_ind);
|
||||||
else{
|
else{
|
||||||
dai_current = current_harq->dai + 1; // DCI DAI to counter DAI conversion
|
int dai_current = current_harq->dai + (current_harq->j_dai * 4) + 1; // DCI DAI to counter DAI conversion
|
||||||
|
|
||||||
if (dai_current == 0) {
|
if (dai_current == 0) {
|
||||||
LOG_E(MAC,"PUCCH Downlink dai is invalid\n");
|
LOG_E(MAC,"PUCCH Downlink dai is invalid\n");
|
||||||
@@ -2177,10 +2178,10 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
|
|||||||
current_harq->active = false;
|
current_harq->active = false;
|
||||||
current_harq->ack_received = false;
|
current_harq->ack_received = false;
|
||||||
} else {
|
} else {
|
||||||
LOG_W(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid);
|
LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid);
|
||||||
ack_data[code_word][dai_current - 1] = 0;
|
ack_data[code_word][dai_current - 1] = 0;
|
||||||
}
|
}
|
||||||
dai[code_word][dai_current - 1] = dai_current;
|
dai[code_word][dai_current - 1] = current_harq->dai + 1;
|
||||||
int temp_ind = current_harq->pucch_resource_indicator;
|
int temp_ind = current_harq->pucch_resource_indicator;
|
||||||
AssertFatal(res_ind == -1 || res_ind == temp_ind,
|
AssertFatal(res_ind == -1 || res_ind == temp_ind,
|
||||||
"Current resource index %d does not match with previous resource index %d\n",
|
"Current resource index %d does not match with previous resource index %d\n",
|
||||||
@@ -2207,37 +2208,11 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for computing n_HARQ_ACK for power */
|
|
||||||
V_DAI_m_DL = dai_max;
|
|
||||||
U_DAI_c = number_harq_feedback/number_of_code_word;
|
|
||||||
N_m_c_rx = number_harq_feedback;
|
|
||||||
int N_SPS_c = 0; /* FFS TODO_NR multicells and SPS are not supported at the moment */
|
|
||||||
int n_HARQ_ACK = 0;
|
|
||||||
if (current_UL_BWP->harq_ACK_SpatialBundlingPUCCH != NULL) {
|
|
||||||
int N_TB_max_DL = current_DL_BWP->pdsch_Config->maxNrofCodeWordsScheduledByDCI[0];
|
|
||||||
n_HARQ_ACK = (((V_DAI_m_DL - U_DAI_c) % 4) * N_TB_max_DL) + N_m_c_rx + N_SPS_c;
|
|
||||||
LOG_D(MAC,
|
|
||||||
"PUCCH power n(%d) = ( V(%d) - U(%d) )mod4 * N_TB(%d) + N(%d) \n",
|
|
||||||
n_HARQ_ACK,
|
|
||||||
V_DAI_m_DL,
|
|
||||||
U_DAI_c,
|
|
||||||
N_TB_max_DL,
|
|
||||||
N_m_c_rx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For a monitoring occasion of a PDCCH with DCI format 1_0 or DCI format 1_1 in at least one serving cell,
|
|
||||||
* when a UE receives a PDSCH with one transport block and the value of higher layer parameter maxNrofCodeWordsScheduledByDCI is 2,
|
|
||||||
* the HARQ-ACK response is associated with the first transport block and the UE generates a NACK for the second transport block
|
|
||||||
* if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = false) and generates HARQ-ACK value of ACK for the second
|
|
||||||
* transport block if spatial bundling is applied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (int code_word = 0; code_word < number_of_code_word; code_word++) {
|
for (int code_word = 0; code_word < number_of_code_word; code_word++) {
|
||||||
for (uint32_t i = 0; i < dai_max ; i++ ) {
|
for (uint32_t i = 0; i < dai_max ; i++ ) {
|
||||||
if (dai[code_word][i] != i + 1) { /* fill table with consistent value for each dai */
|
if (dai[code_word][i] == 0) {
|
||||||
dai[code_word][i] = i + 1; /* it covers case for which PDCCH DCI has not been successfully decoded and so it has been missed */
|
dai[code_word][i] = (i % 4) + 1; // it covers case for which PDCCH DCI has not been successfully decoded and so it has been missed
|
||||||
ack_data[code_word][i] = 0; /* nack data transport block which has been missed */
|
ack_data[code_word][i] = 0; // nack data transport block which has been missed
|
||||||
number_harq_feedback++;
|
number_harq_feedback++;
|
||||||
}
|
}
|
||||||
if (two_transport_blocks == true) {
|
if (two_transport_blocks == true) {
|
||||||
@@ -2256,7 +2231,6 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
|
|||||||
int O_bit_number_cw1 = 0;
|
int O_bit_number_cw1 = 0;
|
||||||
|
|
||||||
for (int m = 0; m < M ; m++) {
|
for (int m = 0; m < M ; m++) {
|
||||||
|
|
||||||
if (dai[0][m] <= V_temp) {
|
if (dai[0][m] <= V_temp) {
|
||||||
j = j + 1;
|
j = j + 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user