Merge remote-tracking branch 'origin/NR_multiplexing_HARQ_CSI_PUCCH' into develop-NR_SA_F1AP_5GRECORDS
# Conflicts: # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c # openair2/LAYER2/NR_MAC_gNB/mac_proto.h
This commit is contained in:
@@ -1599,7 +1599,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
if (pucch_pdu->bit_len_harq>0) {
|
||||
int harq_bytes=pucch_pdu->bit_len_harq>>3;
|
||||
if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++;
|
||||
uci_pdu->pduBitmap|=1;
|
||||
uci_pdu->pduBitmap|=2;
|
||||
uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes);
|
||||
uci_pdu->harq.harq_crc = decoderState;
|
||||
int i=0;
|
||||
@@ -1613,7 +1613,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
if (pucch_pdu->sr_flag == 1) {
|
||||
uci_pdu->pduBitmap|=2;
|
||||
uci_pdu->pduBitmap|=1;
|
||||
uci_pdu->sr.sr_bit_len = 1;
|
||||
uci_pdu->sr.sr_payload = malloc(1);
|
||||
uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1;
|
||||
|
||||
@@ -1227,9 +1227,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
const int delta_PRI=0;
|
||||
int r_pucch = ((CCEIndex<<1)/N_cce)+(delta_PRI<<1);
|
||||
|
||||
nr_acknack_scheduling(module_idP, UE_id, frameP, slotP,r_pucch);
|
||||
harq->feedback_slot = sched_ctrl->sched_pucch->ul_slot;
|
||||
harq->feedback_frame = sched_ctrl->sched_pucch->frame;
|
||||
int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch);
|
||||
AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
|
||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->feedback_frame = pucch->frame;
|
||||
|
||||
// Bytes to be transmitted
|
||||
uint8_t *buf = (uint8_t *) harq->tb;
|
||||
@@ -1417,10 +1419,10 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
dci_payload.harq_pid = current_harq_pid;
|
||||
dci_payload.ndi = harq->ndi;
|
||||
dci_payload.dai[0].val = (sched_ctrl->sched_pucch->dai_c-1)&3;
|
||||
dci_payload.dai[0].val = (pucch->dai_c-1)&3;
|
||||
dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213
|
||||
dci_payload.pucch_resource_indicator = delta_PRI; // This is delta_PRI from 9.2.1 in 38.213
|
||||
dci_payload.pdsch_to_harq_feedback_timing_indicator.val = sched_ctrl->sched_pucch->timing_indicator;
|
||||
dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d pucchres %d harqtiming %d\n",
|
||||
|
||||
@@ -518,8 +518,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
|
||||
if (!alloc) {
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
|
||||
if (alloc<0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
__func__,
|
||||
@@ -535,6 +535,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
sched_ctrl->sched_pdsch.pucch_allocation = alloc;
|
||||
|
||||
/* just reuse from previous scheduling opportunity, set new start RB */
|
||||
sched_ctrl->sched_pdsch = *retInfo;
|
||||
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
||||
@@ -649,9 +651,9 @@ void pf_dl(module_id_t module_id,
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot,-1);
|
||||
if (!alloc) {
|
||||
LOG_W(NR_MAC,
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
|
||||
if (alloc<0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
__func__,
|
||||
UE_id,
|
||||
@@ -683,7 +685,7 @@ void pf_dl(module_id_t module_id,
|
||||
scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
uint32_t TBS = 0;
|
||||
uint16_t rbSize;
|
||||
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
|
||||
@@ -846,7 +848,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
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[sched_pdsch->pucch_allocation];
|
||||
harq->feedback_frame = pucch->frame;
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->is_waiting = true;
|
||||
|
||||
@@ -339,8 +339,8 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
__func__,
|
||||
UE_id);
|
||||
|
||||
const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot,-1);
|
||||
if (!alloc) {
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, -1);
|
||||
if (alloc < 0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
__func__,
|
||||
@@ -355,12 +355,13 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
return;
|
||||
}
|
||||
|
||||
AssertFatal(alloc,
|
||||
"could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
|
||||
rnti, frame, slot);
|
||||
//AssertFatal(alloc,
|
||||
// "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
|
||||
// rnti, frame, slot);
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
sched_pdsch->rbStart = rbStart;
|
||||
sched_pdsch->rbSize = rbSize;
|
||||
const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
|
||||
|
||||
@@ -557,9 +557,6 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
for (int i = start; i < start + len; ++i) {
|
||||
vrb_map_UL[i] |= mask;
|
||||
}
|
||||
AssertFatal(!curr_pucch->simultaneous_harqcsi,
|
||||
"UE %04x has simultaneous HARQ/CSI configured, but we don't support that\n",
|
||||
UE_info->rnti[UE_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1097,11 +1094,15 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
|
||||
|
||||
// function to update pucch scheduling parameters in UE list when a USS DL is scheduled
|
||||
bool nr_acknack_scheduling(int mod_id,
|
||||
int UE_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int r_pucch)
|
||||
// this function returns an index to NR_sched_pucch structure
|
||||
// currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1
|
||||
// if the function returns -1 it was not possible to schedule acknack
|
||||
// when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called
|
||||
int nr_acknack_scheduling(int mod_id,
|
||||
int UE_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int r_pucch)
|
||||
{
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
@@ -1111,6 +1112,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
|
||||
const int first_ul_slot_tdd = tdd->nrofDownlinkSlots + nr_slots_period * (slot / nr_slots_period);
|
||||
const int CC_id = 0;
|
||||
NR_sched_pucch_t *csi_pucch;
|
||||
|
||||
AssertFatal(slot < first_ul_slot_tdd + (tdd->nrofUplinkSymbols != 0),
|
||||
"cannot handle multiple TDD periods (yet): slot %d first_ul_slot_tdd %d nrofUplinkSlots %ld\n",
|
||||
@@ -1131,7 +1133,6 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
"%s(): csi_bits %d in sched_pucch[0]\n",
|
||||
__func__,
|
||||
pucch->csi_bits);
|
||||
|
||||
/* if the currently allocated PUCCH of this UE is full, allocate it */
|
||||
if (pucch->dai_c == 2) {
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
@@ -1143,18 +1144,14 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
// we assume that only two indices over the array sched_pucch exist
|
||||
NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
// skip the CSI PUCCH if it is present and if in the next frame/slot
|
||||
// and if we don't multiplex
|
||||
csi_pucch->r_pucch=-1;
|
||||
if (csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == pucch->frame
|
||||
&& csi_pucch->ul_slot == pucch->ul_slot) {
|
||||
AssertFatal(!csi_pucch->simultaneous_harqcsi,
|
||||
"%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n",
|
||||
__func__,
|
||||
pucch->frame,
|
||||
pucch->ul_slot,
|
||||
UE_id);
|
||||
&& csi_pucch->ul_slot == pucch->ul_slot
|
||||
&& !csi_pucch->simultaneous_harqcsi) {
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f;
|
||||
@@ -1169,7 +1166,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
if ((pucch->frame == frame
|
||||
&& (pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots))
|
||||
|| (pucch->frame == frame + 1))
|
||||
return false;
|
||||
return -1;
|
||||
|
||||
// this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common;
|
||||
@@ -1203,7 +1200,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
pucch->timing_indicator = i;
|
||||
pucch->dai_c++;
|
||||
// retain old resource indicator, and we are good
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need to find a new PUCCH occasion */
|
||||
@@ -1226,30 +1223,6 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
// advance ul_slot if it is not reachable by UE
|
||||
pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]);
|
||||
|
||||
// is there already CSI in this slot?
|
||||
NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
// skip the CSI PUCCH if it is present and if in the next frame/slot
|
||||
if (csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == pucch->frame
|
||||
&& csi_pucch->ul_slot == pucch->ul_slot) {
|
||||
AssertFatal(!csi_pucch->simultaneous_harqcsi,
|
||||
"%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n",
|
||||
__func__,
|
||||
pucch->frame,
|
||||
pucch->ul_slot,
|
||||
UE_id);
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
* the same slot again */
|
||||
const int f = pucch->frame;
|
||||
const int s = pucch->ul_slot;
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, -1);
|
||||
}
|
||||
|
||||
// Find the right timing_indicator value.
|
||||
int i = 0;
|
||||
while (i < 8) {
|
||||
@@ -1267,8 +1240,38 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
slot,
|
||||
UE_id,
|
||||
pucch->ul_slot);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// is there already CSI in this slot?
|
||||
csi_pucch = &sched_ctrl->sched_pucch[1];
|
||||
if (csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == pucch->frame
|
||||
&& csi_pucch->ul_slot == pucch->ul_slot) {
|
||||
// skip the CSI PUCCH if it is present and if in the next frame/slot
|
||||
// and if we don't multiplex
|
||||
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case
|
||||
if(!csi_pucch->simultaneous_harqcsi
|
||||
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
* the same slot again */
|
||||
const int f = pucch->frame;
|
||||
const int s = pucch->ul_slot;
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, -1);
|
||||
}
|
||||
// multiplexing harq and csi in a pucch
|
||||
else {
|
||||
csi_pucch->timing_indicator = i;
|
||||
csi_pucch->dai_c++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
pucch->timing_indicator = i; // index in the list of timing indicators
|
||||
|
||||
LOG_D(MAC,"2. DL slot %d, UL_ACK %d (index %d)\n",slot,pucch->ul_slot,i);
|
||||
@@ -1300,7 +1303,7 @@ bool nr_acknack_scheduling(int mod_id,
|
||||
LOG_W(MAC, "symbol 0x%x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d.%d\n", symb, resource->startingPRB, pucch->frame, pucch->ul_slot);
|
||||
vrb_map_UL[resource->startingPRB] |= symb;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
bool nr_acknack_scheduling(int Mod_idP,
|
||||
int nr_acknack_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
|
||||
@@ -390,6 +390,9 @@ typedef struct NR_sched_pdsch {
|
||||
/// DL HARQ PID to use for this UE, or -1 for "any new"
|
||||
int8_t dl_harq_pid;
|
||||
|
||||
// pucch format allocation
|
||||
uint8_t pucch_allocation;
|
||||
|
||||
/// the Time Domain Allocation used for this transmission. Note that this is
|
||||
/// only important for retransmissions; otherwise, the TDA in
|
||||
/// NR_pdsch_semi_static_t has precedence
|
||||
|
||||
@@ -1035,10 +1035,11 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
pucchfmt2->interslotFrequencyHopping=NULL;
|
||||
pucchfmt2->additionalDMRS=NULL;
|
||||
pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate));
|
||||
*pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot25;
|
||||
*pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35;
|
||||
pucchfmt2->nrofSlots=NULL;
|
||||
pucchfmt2->pi2BPSK=NULL;
|
||||
pucchfmt2->simultaneousHARQ_ACK_CSI=NULL;
|
||||
pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI));
|
||||
*pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true;
|
||||
|
||||
// for scheduling requestresource
|
||||
pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList));
|
||||
|
||||
Reference in New Issue
Block a user