restructuring of UE DLSCH code to handle 2 codewords

even if 2 codewords are currently not supported and not tested, the way UE handled the possibility of having 2 codewords was messy, in between support and non-support
the intention of this MR is to cleanup the code more than extend the support

Signed-off-by: Francesco Mani <email@francescomani.it>
This commit is contained in:
francescomani
2026-09-14 22:56:26 +09:00
committed by maki
parent 08349f246b
commit 04ee4ea8e5
28 changed files with 747 additions and 879 deletions
+2 -2
View File
@@ -558,8 +558,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
if (phy_data->dlsch[0].active
&& (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) {
// indicate to tx thread to wait for DLSCH decoding
if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % fp->slots_per_frame;
if (phy_data->dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH
const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch_config.k1_feedback) % fp->slots_per_frame;
tx_wait_for_dlsch[ack_nack_slot]++;
}
}
@@ -118,6 +118,7 @@ typedef struct {
typedef struct {
uint8_t harq_pid;
uint8_t cw_idx;
uint8_t ack_nack;
uint32_t pdu_length;
uint8_t* pdu;
@@ -466,6 +467,17 @@ typedef struct {
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
typedef struct {
uint8_t mcs;
bool new_data_indicator;
uint8_t rv;
uint16_t targetCodeRate;
uint8_t qamModOrder;
uint32_t TBS;
uint8_t ldpcBaseGraph;
uint8_t Nl;
} fapi_nr_dl_cw_info_t;
typedef struct {
uint16_t BWPSize;
uint16_t BWPStart;
@@ -482,15 +494,8 @@ typedef struct {
uint8_t prb_bundling_size_ind;
uint8_t rate_matching_ind;
uint8_t zp_csi_rs_trigger;
uint8_t mcs;
bool new_data_indicator;
uint8_t rv;
uint16_t targetCodeRate;
uint8_t qamModOrder;
uint32_t TBS;
uint8_t tb2_mcs;
bool tb2_new_data_indicator;
uint8_t tb2_rv;
uint8_t n_codewords;
fapi_nr_dl_cw_info_t cw_info[2];
uint8_t harq_process_nbr;
vrb_to_prb_mapping_t vrb_to_prb_mapping;
uint8_t dai;
@@ -523,7 +528,6 @@ typedef struct {
uint16_t dlDataScramblingId;
uint16_t pduBitmap;
uint32_t k1_feedback;
uint8_t ldpcBaseGraph;
uint8_t numCsiRsForRateMatching;
fapi_nr_dl_config_csirs_pdu_rel15_t csiRsForRateMatching[NFAPI_MAX_NUM_CSI_RATEMATCH];
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
@@ -1374,92 +1374,60 @@ void nr_pdsch_ptrs_processing(int nbRx,
int nl,
c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
uint8_t nr_slot_rx,
unsigned char symbol,
int nb_rb,
uint16_t rnti,
NR_UE_DLSCH_t dlsch[2])
uint16_t *ptrsSymbPos,
uint8_t *ptrsSymbIdx)
{
//#define DEBUG_DL_PTRS 1
int32_t *ptrs_re_symbol = NULL;
int8_t ret = 0;
/* harq specific variables */
uint8_t symbInSlot = 0;
uint16_t *startSymbIndex = NULL;
uint16_t *nbSymb = NULL;
uint8_t *L_ptrs = NULL;
uint8_t *K_ptrs = NULL;
uint16_t *dmrsSymbPos = NULL;
uint16_t *ptrsSymbPos = NULL;
uint8_t *ptrsSymbIdx = NULL;
uint8_t *ptrsReOffset = NULL;
int nscid = 0;
int symbInSlot = dlsch_config->start_symbol + dlsch_config->number_symbols;
int startSymbIndex = dlsch_config->start_symbol;
int nbSymb = dlsch_config->number_symbols;
int L_ptrs = dlsch_config->PTRSTimeDensity;
int K_ptrs = dlsch_config->PTRSFreqDensity;
int dmrsSymbPos = dlsch_config->dlDmrsSymbPos;
int ptrsReOffset = dlsch_config->PTRSReOffset;
int nscid = dlsch_config->nscid;
if(dlsch0_harq->status == NR_ACTIVE) {
symbInSlot = dlsch[0].dlsch_config.start_symbol + dlsch[0].dlsch_config.number_symbols;
startSymbIndex = &dlsch[0].dlsch_config.start_symbol;
nbSymb = &dlsch[0].dlsch_config.number_symbols;
L_ptrs = &dlsch[0].dlsch_config.PTRSTimeDensity;
K_ptrs = &dlsch[0].dlsch_config.PTRSFreqDensity;
dmrsSymbPos = &dlsch[0].dlsch_config.dlDmrsSymbPos;
ptrsReOffset = &dlsch[0].dlsch_config.PTRSReOffset;
ptrsSymbPos = &dlsch[0].ptrs_symbols;
ptrsSymbIdx = &dlsch[0].ptrs_symbol_index;
nscid = dlsch[0].dlsch_config.nscid;
}
if(dlsch1_harq) {
symbInSlot = dlsch[1].dlsch_config.start_symbol + dlsch[1].dlsch_config.number_symbols;
startSymbIndex = &dlsch[1].dlsch_config.start_symbol;
nbSymb = &dlsch[1].dlsch_config.number_symbols;
L_ptrs = &dlsch[1].dlsch_config.PTRSTimeDensity;
K_ptrs = &dlsch[1].dlsch_config.PTRSFreqDensity;
dmrsSymbPos = &dlsch[1].dlsch_config.dlDmrsSymbPos;
ptrsReOffset = &dlsch[1].dlsch_config.PTRSReOffset;
ptrsSymbPos = &dlsch[1].ptrs_symbols;
ptrsSymbIdx = &dlsch[1].ptrs_symbol_index;
nscid = dlsch[1].dlsch_config.nscid;
}
/* loop over antennas */
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
c16_t *phase_per_symbol = (c16_t*)ptrs_phase_per_slot[aarx];
ptrs_re_symbol = (int32_t*)ptrs_re_per_slot[aarx];
ptrs_re_symbol[symbol] = 0;
phase_per_symbol[symbol].i = 0; // Imag
/* set DMRS estimates to 0 angle with magnitude 1 */
if(is_dmrs_symbol(symbol,*dmrsSymbPos)) {
if(is_dmrs_symbol(symbol, dmrsSymbPos)) {
/* set DMRS real estimation to 32767 */
phase_per_symbol[symbol].r=INT16_MAX; // 32767
#ifdef DEBUG_DL_PTRS
printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i);
#endif
}
else { // real ptrs value is set to 0
} else { // real ptrs value is set to 0
phase_per_symbol[symbol].r = 0; // Real
}
if(dlsch0_harq->status == NR_ACTIVE) {
if(symbol == *startSymbIndex) {
if (symbol == startSymbIndex) {
*ptrsSymbPos = 0;
set_ptrs_symb_idx(ptrsSymbPos,
*nbSymb,
*startSymbIndex,
1<< *L_ptrs,
*dmrsSymbPos);
set_ptrs_symb_idx(ptrsSymbPos, nbSymb, startSymbIndex, 1 << L_ptrs, dmrsSymbPos);
}
/* if not PTRS symbol set current ptrs symbol index to zero*/
*ptrsSymbIdx = 0;
/* Check if current symbol contains PTRS */
if(is_ptrs_symbol(symbol, *ptrsSymbPos)) {
if (is_ptrs_symbol(symbol, *ptrsSymbPos)) {
*ptrsSymbIdx = symbol;
/*------------------------------------------------------------------------------------------------------- */
/* 1) Estimate common phase error per PTRS symbol */
/*------------------------------------------------------------------------------------------------------- */
const uint32_t *gold =
nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, frame_parms->Nid_cell, nscid, nr_slot_rx, symbol);
nr_ptrs_cpe_estimation(*K_ptrs,
*ptrsReOffset,
nr_ptrs_cpe_estimation(K_ptrs,
ptrsReOffset,
nb_rb,
rnti,
frame_parms->ofdm_symbol_size,
@@ -1468,33 +1436,32 @@ void nr_pdsch_ptrs_processing(int nbRx,
(int16_t *)&phase_per_symbol[symbol],
&ptrs_re_symbol[symbol]);
}
}// HARQ 0
/* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
if(symbol == (symbInSlot -1)) {
if (symbol == (symbInSlot -1)) {
/*------------------------------------------------------------------------------------------------------- */
/* 2) Interpolate PTRS estimated value in TD */
/*------------------------------------------------------------------------------------------------------- */
/* If L-PTRS is > 0 then we need interpolation */
if(*L_ptrs > 0) {
ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb);
if (L_ptrs > 0) {
ret = nr_ptrs_process_slot(dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, startSymbIndex, nbSymb);
if(ret != 0) {
LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n");
}
}
#ifdef DEBUG_DL_PTRS
LOG_M("ptrsEst.m","est",ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + (*startSymbIndex) * rx_size_symbol, rx_size_symbol * (*nbSymb), 1, 1);
LOG_M("ptrsEst.m","est", ptrs_phase_per_slot[aarx], frame_parms->symbols_per_slot, 1, 1);
LOG_M("rxdataF_bf_ptrs_comp.m", "bf_ptrs_cmp", rxdataF_comp[0][aarx] + startSymbIndex * rx_size_symbol, rx_size_symbol * nbSymb, 1, 1);
#endif
/*------------------------------------------------------------------------------------------------------- */
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
/*--------------------------------------------------------------------------------------------------------*/
for(uint8_t i = *startSymbIndex; i < symbInSlot; i++) {
for(uint8_t i = startSymbIndex; i < symbInSlot; i++) {
/* DMRS Symbol has 0 phase so no need to rotate the respective symbol */
/* Skip rotation if the slot processing is wrong */
if((!is_dmrs_symbol(i, *dmrsSymbPos)) && (ret == 0)) {
if((!is_dmrs_symbol(i, dmrsSymbPos)) && (ret == 0)) {
#ifdef DEBUG_DL_PTRS
printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r, phase_per_symbol[i].i);
#endif
rotate_cpx_vector(rxdataF_comp[i][0][aarx], &phase_per_symbol[i], rxdataF_comp[i][0][aarx], nb_rb * NR_NB_SC_PER_RB, 15);
}// if not DMRS Symbol
@@ -126,13 +126,13 @@ void nr_pdsch_ptrs_processing(int nbRx,
int nl,
c16_t rxdataF_comp[][nl][nbRx][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
uint8_t nr_slot_rx,
unsigned char symbol,
int nb_rb,
uint16_t rnti,
NR_UE_DLSCH_t dlsch[2]);
uint16_t *ptrsSymbPos,
uint8_t *ptrsSymbIdx);
int nr_sl_psbch_rsrp_measurements(PHY_VARS_NR_UE *ue,
sl_nr_ue_phy_params_t *sl_phy_params,
@@ -170,7 +170,7 @@ static void send_ssb_rsrp_meas(PHY_VARS_NR_UE *ue,
nr_downlink_indication_t dl_indication = {0};
fapi_nr_rx_indication_t rx_ind = {0};
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, NULL, NULL, 1, proc, &l1_measurements, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, 0, 0, NULL, 1, proc, &l1_measurements, NULL);
ue->if_inst->dl_indication(&dl_indication);
}
+1 -1
View File
@@ -961,6 +961,6 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind = {0};
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, NULL, NULL, 1, proc, (void *)&l1_measurements, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_MEAS_IND, ue, 0, 0, NULL, 1, proc, (void *)&l1_measurements, NULL);
ue->if_inst->dl_indication(&dl_indication);
}
+84 -143
View File
@@ -43,169 +43,135 @@ void nr_dlsch_unscrambling(int16_t *llr, uint32_t size, uint8_t q, uint32_t Nid,
void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
int16_t **dlsch_llr,
uint8_t **b,
int *G,
int nb_dlsch,
int cw_idx,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
int16_t *dlsch_llr,
uint8_t *b,
int number_rbs,
uint8_t *DLSCH_ids)
int G)
{
nrLDPC_TB_decoding_parameters_t TBs[nb_dlsch];
memset(TBs, 0, sizeof(TBs));
nrLDPC_TB_decoding_parameters_t TB_parameters = {0};
nrLDPC_slot_decoding_parameters_t slot_parameters = {
.frame = proc->frame_rx,
.slot = proc->nr_slot_rx,
.nb_TBs = nb_dlsch,
.nb_TBs = 1,
.threadPool = &get_nrUE_params()->Tpool,
.TBs = TBs
.TBs = &TB_parameters
};
int max_num_segments = 0;
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
int harq_pid = dlsch_config->harq_process_nbr;
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
fapi_nr_dl_cw_info_t *cw_info = &dlsch->cw_info;
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[cw_idx][dlsch_config->harq_process_nbr];
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, cw_info->rv);
uint8_t nb_re_dmrs;
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
else
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
if (!harq_process) {
LOG_E(PHY, "dlsch_decoding_slot.c: NULL harq_process pointer\n");
return;
}
TB_parameters.harq_unique_pid = 2 * harq_pid + cw_idx;
TB_parameters.G = G;
TB_parameters.nb_rb = number_rbs;
TB_parameters.Qm = cw_info->qamModOrder;
TB_parameters.mcs = cw_info->mcs;
TB_parameters.nb_layers = cw_info->Nl;
TB_parameters.BG = cw_info->ldpcBaseGraph;
TB_parameters.A = cw_info->TBS;
TB_parameters.processedSegments = &harq_process->processedSegments;
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
float Coderate = (float)cw_info->targetCodeRate / 10240.0f;
/* Neither harq_pid nor DLSCH_id are unique in the instance
* but their combination is.
* Since DLSCH_id < 2
* then 2 * harq_pid + DLSCH_id is unique.
*/
TB_parameters->harq_unique_pid = 2 * harq_pid + DLSCH_id;
// ------------------------------------------------------------------
TB_parameters->G = G[DLSCH_id];
TB_parameters->nb_rb = number_rbs;
TB_parameters->Qm = dlsch_config->qamModOrder;
TB_parameters->mcs = dlsch_config->mcs;
TB_parameters->nb_layers = dlsch[DLSCH_id].Nl;
TB_parameters->BG = dlsch_config->ldpcBaseGraph;
TB_parameters->A = dlsch_config->TBS;
// ------------------------------------------------------------------
TB_parameters->processedSegments = &harq_process->processedSegments;
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
LOG_D(
PHY,
LOG_D(PHY,
"%d.%d DLSCH %d Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d Qm %d "
"Coderate %f\n",
slot_parameters.frame,
slot_parameters.slot,
DLSCH_id,
cw_idx,
harq_pid,
dlsch_config->TBS,
TB_parameters->G,
cw_info->TBS,
G,
nb_re_dmrs,
dmrs_length,
TB_parameters->mcs,
TB_parameters->nb_layers,
TB_parameters.mcs,
TB_parameters.nb_layers,
dlsch_config->number_symbols,
TB_parameters->nb_rb,
TB_parameters->Qm,
TB_parameters.nb_rb,
TB_parameters.Qm,
Coderate);
if (harq_process->first_rx == 1) {
// This is a new packet, so compute quantities regarding segmentation
nr_segmentation(NULL,
NULL,
lenWithCrc(1, TB_parameters->A), // We give a max size in case of 1 segment
&TB_parameters->C,
&TB_parameters->K,
&TB_parameters->Z, // [hna] Z is Zc
&TB_parameters->F,
TB_parameters->BG);
harq_process->C = TB_parameters->C;
harq_process->K = TB_parameters->K;
harq_process->Z = TB_parameters->Z;
harq_process->F = TB_parameters->F;
lenWithCrc(1, TB_parameters.A), // We give a max size in case of 1 segment
&TB_parameters.C,
&TB_parameters.K,
&TB_parameters.Z, // [hna] Z is Zc
&TB_parameters.F,
TB_parameters.BG);
harq_process->C = TB_parameters.C;
harq_process->K = TB_parameters.K;
harq_process->Z = TB_parameters.Z;
harq_process->F = TB_parameters.F;
if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * TB_parameters->nb_layers) {
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters->A);
if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * TB_parameters.nb_layers) {
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB_parameters.A);
return;
}
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!slot_parameters.frame % 100))
LOG_I(PHY, "K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, TB_parameters->nb_layers);
LOG_I(PHY, "K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, harq_process->Z, TB_parameters.nb_layers);
// clear HARQ buffer
for (int i = 0; i < harq_process->C; i++)
memset(harq_process->d[i], 0, 5 * 8448 * sizeof(int16_t));
} else {
// This is not a new packet, so retrieve previously computed quantities regarding segmentation
TB_parameters->C = harq_process->C;
TB_parameters->K = harq_process->K;
TB_parameters->Z = harq_process->Z;
TB_parameters->F = harq_process->F;
TB_parameters.C = harq_process->C;
TB_parameters.K = harq_process->K;
TB_parameters.Z = harq_process->Z;
TB_parameters.F = harq_process->F;
}
max_num_segments = max(max_num_segments, TB_parameters->C);
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
LOG_I(PHY, "Segmentation: C %d, K %d\n", harq_process->C, harq_process->K);
TB_parameters->max_ldpc_iterations = dlsch[DLSCH_id].max_ldpc_iterations;
TB_parameters->rv_index = dlsch_config->rv;
TB_parameters->tbslbrm = dlsch_config->tbslbrm;
TB_parameters->abort_decode = &harq_process->abort_decode;
TB_parameters.max_ldpc_iterations = dlsch->max_ldpc_iterations;
TB_parameters.rv_index = cw_info->rv;
TB_parameters.tbslbrm = dlsch_config->tbslbrm;
TB_parameters.abort_decode = &harq_process->abort_decode;
set_abort(&harq_process->abort_decode, false);
}
nrLDPC_segment_decoding_parameters_t segments[nb_dlsch][max_num_segments];
nrLDPC_segment_decoding_parameters_t segments[TB_parameters.C];
memset(segments, 0, sizeof(segments));
bool d_to_be_cleared[nb_dlsch][max_num_segments];
bool d_to_be_cleared[TB_parameters.C];
memset(d_to_be_cleared, 0, sizeof(d_to_be_cleared));
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
int harq_pid = dlsch_config->harq_process_nbr;
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
TB_parameters->segments = segments[pdsch_id];
TB_parameters.segments = segments;
uint32_t r_offset = 0;
for (int r = 0; r < TB_parameters->C; r++) {
for (int r = 0; r < TB_parameters.C; r++) {
if (harq_process->first_rx == 1)
d_to_be_cleared[pdsch_id][r] = true;
d_to_be_cleared[r] = true;
else
d_to_be_cleared[pdsch_id][r] = false;
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
segment_parameters->E = nr_get_E(TB_parameters->G,
TB_parameters->C,
TB_parameters->Qm,
TB_parameters->nb_layers,
d_to_be_cleared[r] = false;
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters.segments[r];
segment_parameters->E = nr_get_E(TB_parameters.G,
TB_parameters.C,
TB_parameters.Qm,
TB_parameters.nb_layers,
r);
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters->rv_index,
segment_parameters->R = nr_get_R_ldpc_decoder(TB_parameters.rv_index,
segment_parameters->E,
TB_parameters->BG,
TB_parameters->Z,
TB_parameters.BG,
TB_parameters.Z,
&harq_process->llrLen,
harq_process->DLround);
segment_parameters->llr = dlsch_llr[DLSCH_id] + r_offset;
segment_parameters->llr = dlsch_llr + r_offset;
segment_parameters->d = harq_process->d[r];
segment_parameters->d_to_be_cleared = &d_to_be_cleared[pdsch_id][r];
segment_parameters->d_to_be_cleared = &d_to_be_cleared[r];
segment_parameters->c = harq_process->c[r];
segment_parameters->decodeSuccess = false;
@@ -215,7 +181,6 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
r_offset += segment_parameters->E;
}
}
int ret_decoder = phy_vars_ue->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
@@ -224,27 +189,14 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
return;
}
// post decode
for (uint8_t pdsch_id = 0; pdsch_id < nb_dlsch; pdsch_id++) {
uint8_t DLSCH_id = DLSCH_ids[pdsch_id];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
int harq_pid = dlsch_config->harq_process_nbr;
NR_DL_UE_HARQ_t *harq_process = &phy_vars_ue->dl_harq_processes[DLSCH_id][harq_pid];
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pdsch_id];
uint32_t offset = 0;
for (int r = 0; r < TB_parameters->C; r++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters->segments[r];
for (int r = 0; r < TB_parameters.C; r++) {
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB_parameters.segments[r];
if (segment_parameters->decodeSuccess) {
memcpy(b[DLSCH_id] + offset,
harq_process->c[r],
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
memcpy(b + offset, harq_process->c[r], (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
} else {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[DLSCH_id].dlsch_config;
LOG_D(PHY, "frame=%d, slot=%d, first_rx=%d, rv_index=%d\n", proc->frame_rx, proc->nr_slot_rx, harq_process->first_rx, dlsch_config->rv);
LOG_D(PHY, "frame=%d, slot=%d, first_rx=%d, rv_index=%d\n", proc->frame_rx, proc->nr_slot_rx, harq_process->first_rx, cw_info->rv);
LOG_D(PHY, "downlink segment error %d/%d\n", r, harq_process->C);
LOG_D(PHY, "DLSCH %d in error\n", DLSCH_id);
}
offset += (harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0);
@@ -255,17 +207,16 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
kpiStructure.nb_total++;
kpiStructure.blockSize = dlsch_config->TBS;
kpiStructure.dl_mcs = dlsch_config->mcs;
kpiStructure.blockSize = cw_info->TBS;
kpiStructure.dl_mcs = cw_info->mcs;
kpiStructure.nofRBs = number_rbs;
harq_process->decodeResult = harq_process->processedSegments == harq_process->C;
if (harq_process->decodeResult && harq_process->C > 1) {
/* check global CRC */
int A = dlsch->dlsch_config.TBS;
// we have regrouped the transport block
if (!check_crc(b[DLSCH_id], lenWithCrc(1, A), crcType(1, A))) {
if (!check_crc(b, lenWithCrc(1, cw_info->TBS), crcType(1, cw_info->TBS))) {
LOG_E(PHY,
" Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n",
proc->frame_rx,
@@ -277,11 +228,11 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
if (harq_process->decodeResult) {
// We search only a reccuring OAI error that propagates all 0 packets with a 0 CRC, so we
const int sz = dlsch->dlsch_config.TBS / 8;
if (b[DLSCH_id][sz] == 0 && b[DLSCH_id][sz + 1] == 0) {
const int sz = cw_info->TBS / 8;
if (b[sz] == 0 && b[sz + 1] == 0) {
// do the check only if the 2 first bytes of the CRC are 0 (it can be CRC16 or CRC24)
int i = 0;
while (b[DLSCH_id][i] == 0 && i < sz)
while (b[i] == 0 && i < sz)
i++;
if (i == sz) {
LOG_E(PHY,
@@ -303,35 +254,25 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
UEdumpScopeData(phy_vars_ue, proc->nr_slot_rx, proc->frame_rx, "DLSCH_NACK");
}
uint8_t dmrs_Type = dlsch_config->dmrsConfigType;
uint8_t nb_re_dmrs;
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
else
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
uint16_t dmrs_length = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
float Coderate = (float)dlsch->dlsch_config.targetCodeRate / 10240.0f;
LOG_D(PHY,
"%d.%d DLSCH Decoded, harq_pid %d, round %d, result: %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d "
"%d.%d DLSCH Decoded, harq_pid %d, cw_idx %d round %d, result: %d TBS %d (%d) G %d nb_re_dmrs %d length dmrs %d mcs %d Nl %d "
"nb_symb_sch %d "
"nb_rb %d Qm %d Coderate %f\n",
proc->frame_rx,
proc->nr_slot_rx,
harq_pid,
cw_idx,
harq_process->DLround,
harq_process->decodeResult,
dlsch->dlsch_config.TBS,
dlsch->dlsch_config.TBS / 8,
G[DLSCH_id],
cw_info->TBS,
cw_info->TBS / 8,
G,
nb_re_dmrs,
dmrs_length,
dlsch->dlsch_config.mcs,
dlsch->Nl,
cw_info->mcs,
cw_info->Nl,
dlsch_config->number_symbols,
number_rbs,
dlsch_config->qamModOrder,
cw_info->qamModOrder,
Coderate);
}
}
@@ -856,12 +856,12 @@ static void nr_dlsch_layer_demapping(const uint8_t Nl,
const uint8_t mod_order,
const int llrLayerSize,
const int16_t llr_layers[NR_SYMBOLS_PER_SLOT][Nl][llrLayerSize],
const NR_UE_DLSCH_t *dlsch,
const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
const uint32_t re_len[NR_SYMBOLS_PER_SLOT],
int16_t *llr)
{
const int s0 = dlsch->dlsch_config.start_symbol;
const int s1 = dlsch->dlsch_config.number_symbols;
const int s0 = dlsch_config->start_symbol;
const int s1 = dlsch_config->number_symbols;
int k = 0;
switch (Nl) {
@@ -901,28 +901,28 @@ static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch,
const c16_t dl_ch_magb[rx_size_symbol],
const c16_t dl_ch_magr[rx_size_symbol],
const int nb_antennas_rx,
const c16_t rxdataF_comp[dlsch->Nl][nb_antennas_rx][rx_size_symbol],
const c16_t rxdataF_comp[dlsch->cw_info.Nl][nb_antennas_rx][rx_size_symbol],
const int llrSize,
int16_t layer_llr[dlsch->Nl][llrSize])
int16_t layer_llr[dlsch->cw_info.Nl][llrSize])
{
switch (dlsch->dlsch_config.qamModOrder) {
switch (dlsch->cw_info.qamModOrder) {
case 2 :
for (int l = 0; l < dlsch[0].Nl; l++)
for (int l = 0; l < dlsch->cw_info.Nl; l++)
nr_qpsk_llr(rxdataF_comp[l][0], layer_llr[l], len);
break;
case 4 :
for (int l = 0; l < dlsch[0].Nl; l++)
for (int l = 0; l < dlsch->cw_info.Nl; l++)
nr_16qam_llr(rxdataF_comp[l][0], dl_ch_mag, layer_llr[l], len);
break;
case 6 :
for(int l=0; l < dlsch[0].Nl; l++)
for(int l=0; l < dlsch->cw_info.Nl; l++)
nr_64qam_llr(rxdataF_comp[l][0], dl_ch_mag, dl_ch_magb, layer_llr[l], len);
break;
case 8:
for(int l=0; l < dlsch[0].Nl; l++)
for(int l=0; l < dlsch->cw_info.Nl; l++)
nr_256qam_llr(rxdataF_comp[l][0],
dl_ch_mag,
dl_ch_magb,
@@ -943,23 +943,25 @@ static int nr_dlsch_llr(const NR_UE_DLSCH_t *dlsch,
/* Main Function */
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
NR_UE_DLSCH_t *dlsch,
const freq_alloc_bitmap_t *freq_alloc,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
NR_DL_UE_HARQ_t *dlsch_harq,
unsigned char symbol,
bool first_symbol_flag,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int16_t *llr[2],
int16_t *llr,
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
int32_t *log2_maxh,
int rx_size_symbol,
int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t rxdataF_comp[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
@@ -967,7 +969,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
pdsch_scope_req_t *scope_req)
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
const int nl = dlsch[0].Nl;
const int nl = dlsch->cw_info.Nl;
const int n_rx = fp->nb_antennas_rx;
const int matrixSz = n_rx * nl;
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
@@ -979,72 +981,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const int gNB_id = proc->gNB_id;
uint8_t slot = 0;
int32_t codeword_TB0 = -1;
int32_t codeword_TB1 = -1;
uint32_t nb_re_pdsch = -1;
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
if (NR_MAX_NB_LAYERS>4)
dlsch1_harq = &ue->dl_harq_processes[1][harq_pid];
if (dlsch0_harq && dlsch1_harq){
LOG_D(PHY,
"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
frame,
nr_slot_rx,
symbol,
harq_pid,
dlsch0_harq->status,
dlsch1_harq->status);
if ((dlsch0_harq->status == NR_ACTIVE) && (dlsch1_harq->status == NR_ACTIVE)){
codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO.
codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid];
DEBUG_HARQ("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1);
} else if ((dlsch0_harq->status == NR_ACTIVE) && (dlsch1_harq->status != NR_ACTIVE) ) {
codeword_TB0 = dlsch0_harq->codeword;
dlsch0_harq = &ue->dl_harq_processes[codeword_TB0][harq_pid];
dlsch1_harq = NULL;
DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0);
} else if ((dlsch0_harq->status != NR_ACTIVE) && (dlsch1_harq->status == NR_ACTIVE)){
codeword_TB1 = dlsch1_harq->codeword;
dlsch0_harq = NULL;
dlsch1_harq = &ue->dl_harq_processes[codeword_TB1][harq_pid];
DEBUG_HARQ("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1);
LOG_E(PHY, "[DEMOD] slot %d TB0 not active and TB1 active case is not supported\n", nr_slot_rx);
return -1;
} else {
LOG_E(PHY, "[DEMOD] slot %d: no active DLSCH (2 layers case)\n", nr_slot_rx);
return (-1);
}
} else if (dlsch0_harq) {
if (dlsch0_harq->status == NR_ACTIVE) {
codeword_TB0 = dlsch0_harq->codeword;
dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
DEBUG_HARQ("[DEMOD] I am assuming only TB0 is active\n");
} else {
LOG_E(PHY, "[DEMOD] slot %d nr_rx_pdsch no active DLSCH (one layer case)\n", nr_slot_rx);
return (-1);
}
} else {
LOG_E(PHY, "[DEMOD] slot %d Inconsistent call to nr_rx_pdsch (no layer 0)\n", nr_slot_rx);
return -1;
}
DEBUG_HARQ("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config;
DevAssert(dlsch0_harq);
DevAssert(dlsch_harq);
if (gNB_id > 2) {
LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id);
@@ -1229,7 +1167,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
fp,
symbol,
nb_re_pdsch,
dlsch_config->qamModOrder,
dlsch->cw_info.qamModOrder,
nb_rb_pdsch,
*log2_maxh); // log2_maxh+I0_shift
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS);
@@ -1286,7 +1224,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dl_ch_magb[symbol],
dl_ch_magr[symbol],
dl_ch_estimates_ext,
dlsch_config->qamModOrder,
dlsch->cw_info.qamModOrder,
*log2_maxh,
symbol,
nb_re_pdsch,
@@ -1312,14 +1250,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int nbSymb = 0;
int pduBitmap = 0;
if(dlsch0_harq->status == NR_ACTIVE) {
if(dlsch_harq->status == NR_ACTIVE) {
startSymbIdx = dlsch_config->start_symbol;
nbSymb = dlsch_config->number_symbols;
pduBitmap = dlsch_config->pduBitmap;
}
/* Check for PTRS bitmap and process it respectively */
if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) {
if((pduBitmap & 0x1) && (dlsch->rnti_type == TYPE_C_RNTI_)) {
nr_pdsch_ptrs_processing(nbRx,
ptrs_phase_per_slot,
ptrs_re_per_slot,
@@ -1327,13 +1265,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
nl,
rxdataF_comp,
fp,
dlsch0_harq,
dlsch1_harq,
dlsch_config,
nr_slot_rx,
symbol,
freq_alloc->num_rbs,
dlsch[0].rnti,
dlsch);
dlsch->rnti,
&dlsch->ptrs_symbols,
&dlsch->ptrs_symbol_index);
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol];
}
/* at last symbol in a slot calculate LLR's for whole slot */
@@ -1341,7 +1279,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
/* create LLR layer buffer */
int max_symb_re = 0;
GET_ARRAY_MAX(dl_valid_re, NR_SYMBOLS_PER_SLOT, max_symb_re);
const int llr_per_symbol = max_symb_re * dlsch->dlsch_config.qamModOrder;
const int llr_per_symbol = max_symb_re * dlsch->cw_info.qamModOrder;
__attribute__((aligned(32))) int16_t layer_llr[NR_SYMBOLS_PER_SLOT][nl][llr_per_symbol];
// Generate LLR from PTRS compensated signal
@@ -1360,14 +1298,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
}
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
nr_dlsch_layer_demapping(nl, dlsch_config->qamModOrder, llr_per_symbol, layer_llr, dlsch, dl_valid_re, llr[0]);
nr_dlsch_layer_demapping(nl, dlsch->cw_info.qamModOrder, llr_per_symbol, layer_llr, dlsch_config, dl_valid_re, llr);
stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
/*
for (int i=0; i < 2; i++){
snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
}
*/
if (UEScopeHasTryLock(ue)) {
metadata mt = {.frame = proc->frame_rx, .slot = proc->nr_slot_rx };
int total_valid_res = 0;
@@ -446,7 +446,8 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
nr_fill_rx_indication(&rx_ind,
FAPI_NR_RX_PDU_TYPE_SSB,
ue,
NULL,
0,
0,
NULL,
number_pdus,
proc,
+2 -2
View File
@@ -404,7 +404,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
if (decoderState) {
if (ue) { // decoding failed in synced state
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, 0, 0, NULL, number_pdus, proc, NULL, NULL);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication);
}
@@ -464,7 +464,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
if (ue) {
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL);
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, 0, 0, NULL, number_pdus, proc, (void *)result, NULL);
if (ue->if_inst && ue->if_inst->dl_indication)
ue->if_inst->dl_indication(&dl_indication);
@@ -60,19 +60,17 @@ int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int nb_symb
@param[in] dlsch_llr Pointers to LLR values computed by dlsch_demodulation
@param[in] b
@param[in] G array of Gs
@param[in] nb_dlsch number of active downlink shared channels
@param[in] DLSCH_ids array of active downlink shared channels
@returns 0 on success, 1 on unsuccessful decoding
*/
void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
short **dlsch_llr,
uint8_t **b,
int *G,
int nb_dlsch,
int cw_idx,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
int16_t *dlsch_llr,
uint8_t *b,
int number_rbs,
uint8_t *DLSCH_ids);
int G);
int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
const NR_UE_ULSCH_t *ulsch,
@@ -278,23 +276,25 @@ void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue,
*/
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
NR_UE_DLSCH_t *dlsch,
const freq_alloc_bitmap_t *freq_alloc,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
NR_DL_UE_HARQ_t *dlsch_harq,
unsigned char symbol,
bool first_symbol_flag,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int16_t *llr[2],
int16_t *llr,
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
int32_t *log2_maxh,
int rx_size_symbol,
int nbRx,
c16_t rxdataF_comp[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->Nl][nbRx][rx_size_symbol],
c16_t rxdataF_comp[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_mag[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][dlsch->cw_info.Nl][nbRx][rx_size_symbol],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
@@ -97,16 +97,13 @@ typedef struct {
} NR_DL_UE_HARQ_t;
typedef struct {
fapi_nr_dl_cw_info_t cw_info;
/// RNTI
uint16_t rnti;
/// RNTI type
uint8_t rnti_type;
/// Active flag for DLSCH demodulation
bool active;
/// Structure to hold dlsch config from MAC
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
/// Number of MIMO layers (streams)
uint8_t Nl;
/// Maximum number of LDPC iterations
uint8_t max_ldpc_iterations;
/// number of iterations used in last turbo decoding
+2 -1
View File
@@ -521,8 +521,9 @@ typedef struct nr_phy_data_tx_s {
typedef struct nr_phy_data_s {
NR_UE_PDCCH_CONFIG phy_pdcch_config;
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
NR_UE_DLSCH_t dlsch[2];
int n_dlsch_codewords;
// Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t sl_rx_action;
NR_UE_CSI_RS csirs_vars;
+3 -2
View File
@@ -102,8 +102,9 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t pdu_type,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
int cw_idx,
int harq_pid,
NR_UE_DLSCH_t *dlsch,
uint16_t n_pdus,
const UE_nr_rxtx_proc_t *proc,
void *typeSpecific,
+35 -34
View File
@@ -21,48 +21,44 @@ extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
const char *const dl_pdu_type[] = {"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM", "TA"};
const char *const ul_pdu_type[] = {"PRACH", "PUCCH", "PUSCH", "SRS"};
static void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
static void configure_dlsch(NR_UE_DLSCH_t *dlsch,
NR_DL_UE_HARQ_t *harq_list,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
NR_UE_MAC_INST_t *mac,
int cw_idx,
int rnti)
{
const uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
dlsch0->active = true;
dlsch0->rnti = rnti;
dlsch->active = true;
dlsch->rnti = rnti;
LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid);
LOG_D(PHY,"Configure DLSCH for pid = %d\n", current_harq_pid);
NR_DL_UE_HARQ_t *dlsch0_harq = &harq_list[current_harq_pid];
NR_DL_UE_HARQ_t *dlsch_harq = &harq_list[current_harq_pid];
dlsch->cw_info = dlsch_config_pdu->cw_info[cw_idx];
//get nrOfLayers from DCI info
uint8_t Nl = 0;
for (int i = 0; i < 12; i++) { // max 12 ports
if ((dlsch_config_pdu->dmrs_ports >> i) & 0x01)
Nl += 1;
}
if (Nl == 0) {
LOG_E(PHY, "Invalid number of layers %d for DLSCH\n", Nl);
if (dlsch->cw_info.Nl == 0) {
LOG_E(PHY, "Invalid number of layers %d for DLSCH\n", dlsch->cw_info.Nl);
// setting NACK for this TB
dlsch0->active = false;
update_harq_status(mac, current_harq_pid, 0);
dlsch->active = false;
update_harq_status(mac, current_harq_pid, cw_idx, 0);
return;
}
dlsch0->Nl = Nl;
if (dlsch_config_pdu->new_data_indicator) {
dlsch0_harq->first_rx = true;
dlsch0_harq->DLround = 0;
if (dlsch->cw_info.new_data_indicator) {
dlsch_harq->first_rx = true;
dlsch_harq->DLround = 0;
} else {
dlsch0_harq->first_rx = false;
dlsch0_harq->DLround++;
dlsch_harq->first_rx = false;
dlsch_harq->DLround++;
}
downlink_harq_process(dlsch0_harq, current_harq_pid, dlsch_config_pdu->new_data_indicator, dlsch_config_pdu->rv, dlsch0->rnti_type);
if (dlsch0_harq->status != NR_ACTIVE) {
// dlsch0_harq->status not ACTIVE due to false retransmission
downlink_harq_process(dlsch_harq, current_harq_pid, dlsch->cw_info.new_data_indicator, dlsch->cw_info.rv, dlsch->rnti_type);
if (dlsch_harq->status != NR_ACTIVE) {
// dlsch_harq->status not ACTIVE due to false retransmission
// Reset the following flag to skip PDSCH procedures in that case and retrasmit harq status
dlsch0->active = false;
dlsch->active = false;
LOG_W(NR_MAC, "dlsch0_harq->status not ACTIVE due to false retransmission harq pid: %d\n", current_harq_pid);
update_harq_status(mac, current_harq_pid, dlsch0_harq->decodeResult);
update_harq_status(mac, current_harq_pid, cw_idx, dlsch_harq->decodeResult);
}
}
@@ -161,23 +157,28 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac,
case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH: {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &pdu->dlsch_config_pdu.dlsch_config_rel15;
NR_UE_DLSCH_t *dlsch0 = phy_data->dlsch + 0;
phy_data->n_dlsch_codewords = dlsch_config_pdu->n_codewords;
phy_data->dlsch_config = *dlsch_config_pdu;
dlsch0->rnti_type = TYPE_RA_RNTI_;
dlsch0->dlsch_config = *dlsch_config_pdu;
configure_dlsch(dlsch0, phy->dl_harq_processes[0], dlsch_config_pdu, mac, pdu->dlsch_config_pdu.rnti);
configure_dlsch(dlsch0, phy->dl_harq_processes[0], dlsch_config_pdu, mac, 0, pdu->dlsch_config_pdu.rnti);
} break;
case FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH: {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &pdu->dlsch_config_pdu.dlsch_config_rel15;
NR_UE_DLSCH_t *dlsch0 = phy_data->dlsch + 0;
phy_data->n_dlsch_codewords = dlsch_config_pdu->n_codewords;
phy_data->dlsch_config = *dlsch_config_pdu;
dlsch0->rnti_type = TYPE_SI_RNTI_;
dlsch0->dlsch_config = *dlsch_config_pdu;
configure_dlsch(dlsch0, phy->dl_harq_processes[0], dlsch_config_pdu, mac, pdu->dlsch_config_pdu.rnti);
configure_dlsch(dlsch0, phy->dl_harq_processes[0], dlsch_config_pdu, mac, 0, pdu->dlsch_config_pdu.rnti);
} break;
case FAPI_NR_DL_CONFIG_TYPE_DLSCH: {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &pdu->dlsch_config_pdu.dlsch_config_rel15;
NR_UE_DLSCH_t *dlsch0 = &phy_data->dlsch[0];
dlsch0->rnti_type = TYPE_C_RNTI_;
dlsch0->dlsch_config = *dlsch_config_pdu;
configure_dlsch(dlsch0, phy->dl_harq_processes[0], dlsch_config_pdu, mac, pdu->dlsch_config_pdu.rnti);
phy_data->n_dlsch_codewords = dlsch_config_pdu->n_codewords;
phy_data->dlsch_config = *dlsch_config_pdu;
for (int c = 0; c < dlsch_config_pdu->n_codewords; c++) {
NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[c];
dlsch->rnti_type = TYPE_C_RNTI_;
configure_dlsch(dlsch, phy->dl_harq_processes[c], dlsch_config_pdu, mac, c, pdu->dlsch_config_pdu.rnti);
}
} break;
case FAPI_NR_CONFIG_TA_COMMAND:
configure_ta_command(phy, &pdu->ta_command_pdu);
+1 -1
View File
@@ -29,6 +29,6 @@ void nr_ue_sl_phy_config_request(nr_sl_phy_config_t *phy_config);
\param synch_request including target_Nid_cell*/
void nr_ue_synch_request(nr_synch_request_t *synch_request);
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nack);
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, int cw_idx, uint8_t ack_nack);
#endif
+79 -103
View File
@@ -94,31 +94,35 @@ static uint32_t get_ssb_arfcn(NR_DL_FRAME_PARMS *frame_parms)
uint64_t ssb_freq = frame_parms->dl_CarrierFreq - (band_size_hz / 2) + frame_parms->subcarrier_spacing * ssb_center_sc;
return to_nrarfcn(ssb_freq);
}
void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t pdu_type,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
int cw_idx,
int harq_pid,
NR_UE_DLSCH_t *dlsch,
uint16_t n_pdus,
const UE_nr_rxtx_proc_t *proc,
void *typeSpecific,
uint8_t *b)
{
if (n_pdus > 1){
LOG_E(PHY, "In %s: multiple number of DL PDUs not supported yet...\n", __FUNCTION__);
if (n_pdus > 1) {
LOG_E(PHY, "Multiple number of DL PDUs not supported yet...\n");
return;
}
fapi_nr_rx_indication_body_t *rx = rx_ind->rx_indication_body + n_pdus - 1;
switch (pdu_type){
case FAPI_NR_RX_PDU_TYPE_SIB:
case FAPI_NR_RX_PDU_TYPE_RAR:
case FAPI_NR_RX_PDU_TYPE_DLSCH:
if(dlsch0) {
NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr];
rx->pdsch_pdu.harq_pid = dlsch0->dlsch_config.harq_process_nbr;
rx->pdsch_pdu.ack_nack = dl_harq0->decodeResult;
if(dlsch) {
NR_DL_UE_HARQ_t *dl_harq = &ue->dl_harq_processes[cw_idx][harq_pid];
rx->pdsch_pdu.harq_pid = harq_pid;
rx->pdsch_pdu.cw_idx = cw_idx;
rx->pdsch_pdu.ack_nack = dl_harq->decodeResult;
rx->pdsch_pdu.pdu = b;
rx->pdsch_pdu.pdu_length = dlsch0->dlsch_config.TBS / 8;
if (dl_harq0->decodeResult) {
rx->pdsch_pdu.pdu_length = dlsch->cw_info.TBS / 8;
if (dl_harq->decodeResult) {
int t = WS_C_RNTI;
if (pdu_type == FAPI_NR_RX_PDU_TYPE_RAR)
t = WS_RA_RNTI;
@@ -130,16 +134,13 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
.pdu_buffer_size = rx->pdsch_pdu.pdu_length,
.ueid = 0,
.rntiType = t,
.rnti = dlsch0->rnti,
.rnti = dlsch->rnti,
.sysFrame = proc->frame_rx,
.subframe = proc->nr_slot_rx,
.harq_pid = dlsch0->dlsch_config.harq_process_nbr};
.harq_pid = harq_pid};
trace_pdu(&tmp);
}
}
if(dlsch1) {
AssertFatal(1==0,"Second codeword currently not supported\n");
}
break;
case FAPI_NR_RX_PDU_TYPE_SSB: {
if (typeSpecific) {
@@ -168,7 +169,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
rx->pdu_type = pdu_type;
rx_ind->number_pdus = n_pdus;
}
int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){
@@ -488,8 +488,10 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t *llr[2],
NR_UE_DLSCH_t *dlsch,
NR_DL_UE_HARQ_t *dlsch_harq,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlschCfg,
int16_t *llr,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
int G,
freq_alloc_bitmap_t *freq_alloc)
@@ -502,11 +504,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
LOG_E(NR_PHY, "Handling of more than one CW not implemented\n");
return -1;
}
NR_UE_DLSCH_t *dlsch0 = &dlsch[0];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlschCfg = &dlsch0->dlsch_config;
int harq_pid = dlschCfg->harq_process_nbr;
// dlsch0_harq contains the previous transmissions data for this harq pid
NR_DL_UE_HARQ_t *dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
LOG_D(PHY,
"[UE %d] frame_rx %d, nr_slot_rx %d, harq_pid %d (%d), BWP start %d, start RB %d, end RB %d, symbol_start %d, nb_symbols "
@@ -516,18 +515,18 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
frame_rx,
nr_slot_rx,
harq_pid,
dlsch0_harq->status,
dlsch_harq->status,
dlschCfg->BWPStart,
freq_alloc->first_rb,
freq_alloc->last_rb,
dlschCfg->start_symbol,
dlschCfg->number_symbols,
dlschCfg->dlDmrsSymbPos,
dlsch0->Nl);
dlsch->cw_info.Nl);
const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16;
fourDimArray_t *toFree = NULL;
allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch0->Nl, pdsch_est_size, false);
allocCast2D(pdsch_dl_ch_estimates, int32_t, toFree, ue->frame_parms.nb_antennas_rx * dlsch->cw_info.Nl, pdsch_est_size, false);
c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot));
@@ -541,7 +540,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
c16_t,
toFree2,
ue->frame_parms.symbols_per_slot,
dlsch[0].Nl,
dlsch->cw_info.Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
@@ -551,7 +550,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS);
for (int m = dlschCfg->start_symbol; m < (dlschCfg->start_symbol + dlschCfg->number_symbols); m++) {
if (dlschCfg->dlDmrsSymbPos & (1 << m)) {
for (int nl = 0; nl < dlsch0->Nl; nl++) { // for MIMO Config: it shall loop over no_layers
for (int nl = 0; nl < dlsch->cw_info.Nl; nl++) { // for MIMO Config: it shall loop over no_layers
LOG_D(PHY, "PDSCH Channel estimation layer %d, slot %d, symbol %d\n", nl, nr_slot_rx, m);
uint32_t nvar_tmp = 0;
nr_pdsch_channel_estimation(ue,
@@ -580,7 +579,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
}
}
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_ESTIMATION_STATS);
nvar /= (dlschCfg->number_symbols * dlsch0->Nl * ue->frame_parms.nb_antennas_rx);
nvar /= (dlschCfg->number_symbols * dlsch->cw_info.Nl * ue->frame_parms.nb_antennas_rx);
nr_ue_measurement_procedures(2, ue, proc, freq_alloc->num_rbs, pdsch_est_size, pdsch_dl_ch_estimates);
if (ue->chest_time == 1) { // averaging time domain channel estimates
@@ -589,7 +588,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
dlschCfg->number_symbols,
dlschCfg->start_symbol,
dlschCfg->dlDmrsSymbPos,
freq_alloc->num_rbs);
freq_alloc->num_rbs,
dlsch->cw_info.Nl);
}
uint16_t first_symbol_with_data = dlschCfg->start_symbol;
@@ -630,7 +630,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
c16_t,
toFree3,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
dlsch->cw_info.Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
@@ -639,7 +639,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
c16_t,
toFree4,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
dlsch->cw_info.Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
@@ -648,7 +648,7 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
c16_t,
toFree5,
NR_SYMBOLS_PER_SLOT,
dlsch[0].Nl,
dlsch->cw_info.Nl,
ue->frame_parms.nb_antennas_rx,
rx_size_symbol,
false);
@@ -663,6 +663,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
proc,
dlsch,
freq_alloc,
dlschCfg,
dlsch_harq,
m,
first_symbol_flag,
harq_pid,
@@ -760,90 +762,68 @@ static uint32_t compute_csi_rm_unav_res(fapi_nr_dl_config_dlsch_pdu_rel15_t *dls
*/
static void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
int16_t *llr[2],
int G[2],
freq_alloc_bitmap_t *freq_alloc)
NR_UE_DLSCH_t *dlsch,
int cw_idx,
int G,
freq_alloc_bitmap_t *freq_alloc,
fapi_nr_dl_config_dlsch_pdu_rel15_t *config,
int16_t *llr)
{
if (dlsch[0].active == false) {
if (dlsch->active == false) {
LOG_E(PHY, "DLSCH should be active when calling this function\n");
return;
}
int harq_pid = dlsch[0].dlsch_config.harq_process_nbr;
int harq_pid = config->harq_process_nbr;
int frame_rx = proc->frame_rx;
int nr_slot_rx = proc->nr_slot_rx;
NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][harq_pid];
NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[1][harq_pid];
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind = {0};
uint16_t number_pdus = 1;
uint8_t is_cw0_active = dl_harq0->status;
uint8_t is_cw1_active = dl_harq1->status;
int nb_dlsch = 0;
nb_dlsch += (is_cw0_active == NR_ACTIVE) ? 1 : 0;
nb_dlsch += (is_cw1_active == NR_ACTIVE) ? 1 : 0;
LOG_D(PHY, "AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx % 1024, nr_slot_rx, harq_pid, is_cw0_active);
LOG_D(PHY, "AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx % 1024, nr_slot_rx, harq_pid, is_cw1_active);
LOG_D(PHY, "AbsSubframe %d.%d Start LDPC Decoder for CW%d [harq_pid %d]\n", frame_rx % 1024, nr_slot_rx, cw_idx, harq_pid);
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
// exit dlsch procedures as there are no active dlsch
if (is_cw0_active != ACTIVE && is_cw1_active != NR_ACTIVE) {
NR_DL_UE_HARQ_t *dl_harq = &ue->dl_harq_processes[cw_idx][harq_pid];
if (dl_harq->status != NR_ACTIVE) {
// don't wait anymore
LOG_E(NR_PHY, "Internal error nr_ue_dlsch_procedure() called but no active cw on slot %d, harq %d\n", nr_slot_rx, harq_pid);
if (dlsch[0].dlsch_config.k1_feedback) {
const int ack_nack_slot_and_frame =
(proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame;
if (config->k1_feedback) {
const int ack_nack_slot_and_frame = (proc->nr_slot_rx + config->k1_feedback) + proc->frame_rx * fp->slots_per_frame;
dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]);
}
return;
}
uint8_t DLSCH_ids[nb_dlsch];
int pdsch_id = 0;
uint8_t *p_b[2] = {NULL};
for (uint8_t DLSCH_id = 0; DLSCH_id < 2; DLSCH_id++) {
NR_DL_UE_HARQ_t *dl_harq = &ue->dl_harq_processes[DLSCH_id][harq_pid];
if (dl_harq->status != NR_ACTIVE)
continue;
DLSCH_ids[pdsch_id++] = DLSCH_id;
start_meas_nr_ue_phy(ue, DLSCH_UNSCRAMBLING_STATS);
nr_dlsch_unscrambling(llr[DLSCH_id], G[DLSCH_id], 0, dlsch[DLSCH_id].dlsch_config.dlDataScramblingId, dlsch[DLSCH_id].rnti);
nr_dlsch_unscrambling(llr, G, 0, config->dlDataScramblingId, dlsch->rnti);
stop_meas_nr_ue_phy(ue, DLSCH_UNSCRAMBLING_STATS);
p_b[DLSCH_id] = dl_harq->b;
}
start_meas_nr_ue_phy(ue, DLSCH_DECODING_STATS);
nr_dlsch_decoding(ue, proc, dlsch, llr, p_b, G, nb_dlsch, freq_alloc->num_rbs, DLSCH_ids);
nr_dlsch_decoding(ue, proc, dlsch, cw_idx, config, llr, dl_harq->b, freq_alloc->num_rbs, G);
stop_meas_nr_ue_phy(ue, DLSCH_DECODING_STATS);
int ind_type = -1;
switch (dlsch[0].rnti_type) {
switch (dlsch->rnti_type) {
case TYPE_RA_RNTI_:
ind_type = FAPI_NR_RX_PDU_TYPE_RAR;
break;
case TYPE_SI_RNTI_:
ind_type = FAPI_NR_RX_PDU_TYPE_SIB;
break;
case TYPE_C_RNTI_:
ind_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
break;
default:
AssertFatal(true, "Invalid DLSCH type %d\n", dlsch[0].rnti_type);
AssertFatal(false, "Invalid DLSCH type %d\n", dlsch->rnti_type);
break;
}
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL, p_b[0]);
nr_fill_rx_indication(&rx_ind, ind_type, ue, cw_idx, harq_pid, dlsch, number_pdus, proc, NULL, dl_harq->b);
LOG_D(PHY, "DL PDU length in bits: %d, in bytes: %d \n", dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8);
LOG_D(PHY, "DL PDU length in bits: %d, in bytes: %d \n", dlsch->cw_info.TBS, dlsch->cw_info.TBS / 8);
if (cpumeas(CPUMEAS_GETSTATE)) {
LOG_D(PHY,
" --> Unscrambling %5.3f\n",
@@ -861,9 +841,8 @@ static void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
// DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH
if ((dlsch[0].rnti_type == TYPE_C_RNTI_ || dlsch[0].rnti_type == TYPE_RA_RNTI_) && dlsch[0].dlsch_config.k1_feedback) {
const int ack_nack_slot_and_frame =
(proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame;
if ((dlsch->rnti_type == TYPE_C_RNTI_ || dlsch->rnti_type == TYPE_RA_RNTI_) && config->k1_feedback) {
const int ack_nack_slot_and_frame = (proc->nr_slot_rx + config->k1_feedback) + proc->frame_rx * fp->slots_per_frame;
dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]);
}
@@ -874,11 +853,8 @@ static void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
}
uint32_t dlsch_bytes = a_segments * 1056; // allocated bytes per segment
if (ue->phy_sim_dlsch_b && is_cw0_active == NR_ACTIVE)
memcpy(ue->phy_sim_dlsch_b, p_b[0], dlsch_bytes);
else if (ue->phy_sim_dlsch_b && is_cw1_active == NR_ACTIVE)
memcpy(ue->phy_sim_dlsch_b, p_b[1], dlsch_bytes);
if (ue->phy_sim_dlsch_b)
memcpy(ue->phy_sim_dlsch_b, dl_harq->b, dlsch_bytes);
}
static bool check_meas_to_perform(PHY_VARS_NR_UE *ue, int nr_slot_rx)
@@ -1150,7 +1126,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
int nr_slot_rx = proc->nr_slot_rx;
int gNB_id = proc->gNB_id;
NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[0];
// do procedures for C-RNTI
bool slot_fep_map[14] = {0};
@@ -1182,9 +1157,13 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
nr_ue_csi_rs_procedures(ue, proc, rxdataF, &phy_data->csirs_vars.csirs_config_pdu);
}
int G[2] = {0};
if (dlsch[0].active) {
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config;
int16_t *llr[2];
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &phy_data->dlsch_config;
for (int c = 0; c < phy_data->n_dlsch_codewords; c++) {
NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[c];
if (!dlsch->active)
continue;
uint16_t nb_symb_sch = dlsch_config->number_symbols;
uint16_t start_symb_sch = dlsch_config->start_symbol;
@@ -1219,32 +1198,30 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
unav_res = n_ptrs * ptrsSymbPerSlot;
}
unav_res += compute_csi_rm_unav_res(dlsch_config);
G[0] = nr_get_G(freq_alloc.num_rbs,
int G = nr_get_G(freq_alloc.num_rbs,
dlsch_config->number_symbols,
nb_re_dmrs,
dmrs_len,
unav_res,
dlsch_config->qamModOrder,
dlsch[0].Nl);
const uint32_t rx_llr_buf_sz = ALIGNARRAYSIZE(G[0], 32); // each LLR is 2 bytes hence 64 byte aligned
const uint32_t nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
int16_t* llr[2];
for (int i = 0; i < nb_codewords; i++)
llr[i] = (int16_t *)malloc16_clear(rx_llr_buf_sz * sizeof(int16_t));
dlsch->cw_info.qamModOrder,
dlsch->cw_info.Nl);
const uint32_t rx_llr_buf_sz = ALIGNARRAYSIZE(G, 32); // each LLR is 2 bytes hence 64 byte aligned
llr[c] = (int16_t *)malloc16_clear(rx_llr_buf_sz * sizeof(int16_t));
// dlsch_harq contains the previous transmissions data for this harq pid
NR_DL_UE_HARQ_t *harq = &ue->dl_harq_processes[c][dlsch_config->harq_process_nbr];
// it returns -1 in case of internal failure, or 0 in case of normal result
int ret_pdsch = nr_ue_pdsch_procedures(ue, proc, dlsch, llr, rxdataF, G[0], &freq_alloc);
TracyCPlot("pdsch mcs", dlsch->dlsch_config.mcs);
int ret_pdsch = nr_ue_pdsch_procedures(ue, proc, dlsch, harq, dlsch_config, llr[c], rxdataF, &freq_alloc);
TracyCPlot("pdsch mcs", dlsch->cw_info.mcs);
UEscopeCopy(ue, pdschLlr, llr[0], sizeof(int16_t), 1, G[0], 0);
UEscopeCopy(ue, pdschLlr, llr[c], sizeof(int16_t), 1, G, 0);
LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d\n", nr_slot_rx);
start_meas_nr_ue_phy(ue, DLSCH_PROCEDURES_STATS);
if (ret_pdsch >= 0) {
nr_ue_dlsch_procedures(ue, proc, dlsch, llr, G, &freq_alloc);
}
else {
nr_ue_dlsch_procedures(ue, proc, dlsch, c, G, &freq_alloc, dlsch_config, llr[c]);
} else {
LOG_E(NR_PHY, "Demodulation impossible, internal error\n");
if (dlsch_config->k1_feedback) {
const int ack_nack_slot_and_frame =
@@ -1264,10 +1241,9 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
&rxdataF[0][start_symb_sch * ue->frame_parms.ofdm_symbol_size],
sizeof(int32_t) * nb_symb_sch * ue->frame_parms.ofdm_symbol_size);
if (ue->phy_sim_pdsch_llr)
memcpy(ue->phy_sim_pdsch_llr, llr[0], sizeof(int16_t) * rx_llr_buf_sz);
memcpy(ue->phy_sim_pdsch_llr, llr[c], sizeof(int16_t) * rx_llr_buf_sz);
for (int i=0; i<nb_codewords; i++)
free(llr[i]);
free(llr[c]);
}
if (nr_slot_rx==9) {
+23 -26
View File
@@ -457,20 +457,22 @@ int main(int argc, char **argv)
NR_UE_DLSCH_t *dlsch0_ue = &dlsch_ue[0];
NR_DL_UE_HARQ_t *harq_process = &UE->dl_harq_processes[0][harq_pid];
harq_process->first_rx = 1;
dlsch0_ue->dlsch_config.mcs = Imcs;
dlsch0_ue->dlsch_config.mcs_table = mcs_table;
dlsch0_ue->Nl = Nl;
dlsch0_ue->dlsch_config.number_rbs = nb_rb;
dlsch0_ue->dlsch_config.qamModOrder = mod_order;
dlsch0_ue->dlsch_config.rv = rvidx;
dlsch0_ue->dlsch_config.targetCodeRate = rate;
dlsch0_ue->dlsch_config.TBS = TBS;
dlsch0_ue->dlsch_config.ldpcBaseGraph = get_BG(TBS, rate);
dlsch0_ue->dlsch_config.dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
dlsch0_ue->dlsch_config.dlDmrsSymbPos = 4;
dlsch0_ue->dlsch_config.n_dmrs_cdm_groups = 1;
dlsch0_ue->dlsch_config.tbslbrm = Tbslbrm;
printf("harq process ue mcs = %d Qm = %d, symb %d\n", dlsch0_ue->dlsch_config.mcs, dlsch0_ue->dlsch_config.qamModOrder, nb_symb_sch);
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config;
dlsch_config.cw_info[0].mcs = Imcs;
dlsch_config.mcs_table = mcs_table;
dlsch_config.number_rbs = nb_rb;
dlsch_config.cw_info[0].Nl = Nl;
dlsch_config.cw_info[0].qamModOrder = mod_order;
dlsch_config.cw_info[0].rv = rvidx;
dlsch_config.cw_info[0].targetCodeRate = rate;
dlsch_config.cw_info[0].TBS = TBS;
dlsch_config.cw_info[0].ldpcBaseGraph = get_BG(TBS, rate);
dlsch_config.dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
dlsch_config.dlDmrsSymbPos = 4;
dlsch_config.n_dmrs_cdm_groups = 1;
dlsch_config.tbslbrm = Tbslbrm;
dlsch0_ue->cw_info = dlsch_config.cw_info[0];
printf("harq process ue mcs = %d Qm = %d, symb %d\n", dlsch_config.cw_info[0].mcs, dlsch_config.cw_info[0].qamModOrder, nb_symb_sch);
uint8_t test_input[TBS / 8 + 4]; // + 3 for CRC + 1 additional byte, see nr_dlsch_encoding()
dlsch->pdu = test_input;
@@ -536,27 +538,23 @@ int main(int argc, char **argv)
exit(-1);
#endif
int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
int num_rb = dlsch0_ue->dlsch_config.number_rbs;
int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; // number of segments to be allocated
int num_rb = dlsch_config.number_rbs;
if (num_rb != 273) {
a_segments = a_segments*num_rb;
a_segments = (a_segments/273)+1;
}
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
__attribute__ ((aligned(32))) uint8_t b[dlsch_bytes];
uint8_t DLSCH_ids[1] = {0};
short *p_channel_output_fixed = channel_output_fixed;
uint8_t *p_b = b;
int available_bits_array[1] = { available_bits };
nr_dlsch_decoding(UE,
&proc,
dlsch0_ue,
&p_channel_output_fixed,
&p_b,
available_bits_array,
1,
0,
&dlsch_config,
channel_output_fixed,
b,
num_rb,
DLSCH_ids);
available_bits);
if (dlsch0_ue->last_iteration_cnt > dlsch0_ue->max_ldpc_iterations)
n_errors++;
@@ -634,4 +632,3 @@ int main(int argc, char **argv)
return (n_errors);
}
+12 -10
View File
@@ -1310,12 +1310,14 @@ int main(int argc, char **argv)
int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr;
TBS = dlsch0->dlsch_config.TBS;
uint16_t length_dmrs = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos);
uint16_t nb_rb = dlsch0->dlsch_config.number_rbs;
uint8_t nb_re_dmrs = dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
uint8_t mod_order = dlsch0->dlsch_config.qamModOrder;
uint8_t nb_symb_sch = dlsch0->dlsch_config.number_symbols;
TBS = phy_data.dlsch_config.cw_info[0].TBS;
uint16_t length_dmrs = get_num_dmrs(phy_data.dlsch_config.dlDmrsSymbPos);
uint16_t nb_rb = phy_data.dlsch_config.number_rbs;
uint8_t nb_re_dmrs = phy_data.dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ?
6 * phy_data.dlsch_config.n_dmrs_cdm_groups :
4 * phy_data.dlsch_config.n_dmrs_cdm_groups;
uint8_t mod_order = phy_data.dlsch_config.cw_info[0].qamModOrder;
uint8_t nb_symb_sch = phy_data.dlsch_config.number_symbols;
uint32_t unav_res = ptrsSymbPerSlot * ptrsRePerSymb;
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, pdsch_pdu_rel15->nrOfLayers);
if (pdu_bit_map & 0x1) {
@@ -1457,10 +1459,10 @@ int main(int argc, char **argv)
const int s = pdsch_pdu_rel15->StartSymbolIndex;
const int n = pdsch_pdu_rel15->NrOfSymbols;
for (int i = s; i < s + n; i++) {
const uint32_t dmrsBitMap = phy_data.dlsch[0].dlsch_config.dlDmrsSymbPos;
const uint32_t dmrsCfg = phy_data.dlsch[0].dlsch_config.dmrsConfigType;
const uint32_t nrb = phy_data.dlsch[0].dlsch_config.number_rbs;
const uint32_t ncdmg = phy_data.dlsch[0].dlsch_config.n_dmrs_cdm_groups;
const uint32_t dmrsBitMap = phy_data.dlsch_config.dlDmrsSymbPos;
const uint32_t dmrsCfg = phy_data.dlsch_config.dmrsConfigType;
const uint32_t nrb = phy_data.dlsch_config.number_rbs;
const uint32_t ncdmg = phy_data.dlsch_config.n_dmrs_cdm_groups;
const uint32_t numValidReSym = ((dmrsBitMap >> i) & 1)
? ((dmrsCfg == NFAPI_NR_DMRS_TYPE1) ? nrb * (12 - 6 * ncdmg) : nrb * (12 - 4 * ncdmg))
: (nrb * 12);
+3 -2
View File
@@ -83,8 +83,9 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
uint8_t pdu_type,
PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t *dlsch0,
NR_UE_DLSCH_t *dlsch1,
int cw_idx,
int harq_pid,
NR_UE_DLSCH_t *dlsch,
uint16_t n_pdus,
const UE_nr_rxtx_proc_t *proc,
void *typeSpecific,
@@ -3033,7 +3033,7 @@ uint16_t nr_dci_size(const NR_UE_DL_BWP_t *DL_BWP,
size += 8;
// TB2
long *maxCWperDCI = pdsch_Config ? pdsch_Config->maxNrofCodeWordsScheduledByDCI : NULL;
if ((maxCWperDCI != NULL) && (*maxCWperDCI == 2)) {
if (maxCWperDCI && (*maxCWperDCI == NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n2)) {
size += 8;
}
// HARQ process number – 5 bits if higher layer parameter harq-ProcessNumberSizeDCI-1-1 is configured;
+1 -1
View File
@@ -595,7 +595,7 @@ typedef struct NR_UE_MAC_INST_s {
// Defined for abstracted mode
nr_downlink_indication_t dl_info;
NR_UE_DL_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES];
NR_UE_DL_HARQ_STATUS_t dl_harq_info[NR_MAX_HARQ_PROCESSES][2]; // one harq process for each codeword
NR_UE_UL_HARQ_INFO_t ul_harq_info[NR_MAX_HARQ_PROCESSES];
NR_TAG_Id_t tag_Id;
+6 -4
View File
@@ -200,12 +200,14 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac)
nr_mac->scheduling_info.phr_info.phr_reporting = 0;
nr_mac->scheduling_info.phr_info.was_mac_reset = true;
for (int c = 0; c < 2; c++) {
// flush the soft buffers for all DL HARQ processes
memset(nr_mac->dl_harq_info, 0, sizeof(nr_mac->dl_harq_info));
// for each DL HARQ process, consider the next received transmission for a TB as the very first transmission
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
nr_mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
memset(&nr_mac->dl_harq_info[k][c], 0, sizeof(NR_UE_DL_HARQ_STATUS_t));
nr_mac->dl_harq_info[k][c].last_ndi = -1; // initialize to invalid value
}
}
// release, if any, Temporary C-RNTI
nr_mac->ra.t_crnti = 0;
+1 -1
View File
@@ -1190,7 +1190,7 @@ void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *pdcch_order)
void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
{
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid][0]; // single cw for MSG4
int sched_slot = current_harq->ul_slot;
int sched_frame = current_harq->ul_frame;
PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE,
@@ -218,9 +218,11 @@ int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame)
const int num_dl_harq = get_nrofHARQ_ProcessesForPDSCH(&mac->sc_info);
for (int i = 0; i < num_dl_harq; i++) {
if (mac->dl_harq_info[i].active && mac->dl_harq_info[i].ul_slot == slot && mac->dl_harq_info[i].ul_frame == frame) {
delta_tpc_sum += mac->dl_harq_info[i].delta_pucch;
mac->dl_harq_info[i].delta_pucch = 0;
for (int c = 0; c < 2; c++) {
if (mac->dl_harq_info[i][c].active && mac->dl_harq_info[i][c].ul_slot == slot && mac->dl_harq_info[i][c].ul_frame == frame) {
delta_tpc_sum += mac->dl_harq_info[i][c].delta_pucch;
mac->dl_harq_info[i][c].delta_pucch = 0;
}
}
}
return delta_tpc_sum;
+241 -202
View File
@@ -435,6 +435,7 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
static void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t pucch_id,
uint8_t harq_id,
int cw_id,
int8_t delta_pucch,
uint16_t data_toul_fb,
uint8_t dai,
@@ -443,7 +444,7 @@ static void set_harq_status(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot)
{
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_id][cw_id];
current_harq->active = true;
current_harq->ack_received = false;
current_harq->pucch_resource_indicator = pucch_id;
@@ -469,7 +470,8 @@ static void set_harq_status(NR_UE_MAC_INST_t *mac,
// looking for other active HARQ processes with feedback in the same frame/slot
if (i == harq_id)
continue;
NR_UE_DL_HARQ_STATUS_t *harq = &mac->dl_harq_info[i];
for (int c = 0; c < 2; c++) {
NR_UE_DL_HARQ_STATUS_t *harq = &mac->dl_harq_info[i][c];
if (harq->active &&
harq->ul_frame == current_harq->ul_frame &&
harq->ul_slot == current_harq->ul_slot) {
@@ -478,6 +480,7 @@ static void set_harq_status(NR_UE_MAC_INST_t *mac,
highest_dai = harq->dai_cumul - 1;
}
}
}
current_harq->dai_cumul = temp_dai + 1; // DAI = 0 (temp_dai) corresponds to 1st assignment and so on
// if temp_dai is less or equal than cumulative highest dai for given slot
@@ -667,6 +670,99 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
return ret;
}
// Table 7.3.1.3-1 of 38.211
static int get_nl_for_cw(int Nl, int cw_idx)
{
AssertFatal(Nl >= 0 && Nl <= 8, "Invalid number of layers %d\n", Nl);
if (Nl < 5)
return Nl;
else {
if (cw_idx == 0)
return Nl / 2;
else
return Nl / 2 + Nl % 2;
}
}
static bool get_cw_info(NR_UE_DL_HARQ_STATUS_t *current_harq,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu,
uint8_t pdu_type,
fapi_nr_dl_cw_info_t *cw_info,
int number_rbs,
int nb_re_dmrs,
int nb_rb_oh,
int rv,
int mcs,
int ndi,
int cw_idx)
{
uint8_t Nl = 0;
for (int i = 0; i < 12; i++) { // max 12 ports
if ((dlsch_pdu->dmrs_ports >> i) & 0x01)
Nl += 1;
}
cw_info->mcs = mcs;
/* RV for transport block */
cw_info->rv = rv;
/* NDI for transport block*/
if (pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH || pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH || ndi != current_harq->last_ndi) {
// new data
cw_info->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
} else
cw_info->new_data_indicator = false;
if (pdu_type != FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH && pdu_type != FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH) {
current_harq->last_ndi = ndi;
if (cw_info->new_data_indicator)
current_harq->round = 0;
else
current_harq->round++;
}
cw_info->qamModOrder = nr_get_Qm_dl(cw_info->mcs, dlsch_pdu->mcs_table);
if (cw_info->qamModOrder == 0) {
LOG_W(NR_MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI\n");
return false;
}
cw_info->Nl = get_nl_for_cw(Nl, cw_idx);
int R = nr_get_code_rate_dl(cw_info->mcs, dlsch_pdu->mcs_table);
if (R > 0) {
cw_info->targetCodeRate = R;
cw_info->TBS = nr_compute_tbs(cw_info->qamModOrder,
R,
number_rbs,
dlsch_pdu->number_symbols,
nb_re_dmrs * get_num_dmrs(dlsch_pdu->dlDmrsSymbPos),
nb_rb_oh,
0,
cw_info->Nl);
// storing for possible retransmissions
if (!cw_info->new_data_indicator && current_harq->TBS != cw_info->TBS) {
LOG_W(NR_MAC,
"NDI indicates re-transmission but computed TBS %d doesn't match with what previously stored %d\n",
cw_info->TBS,
current_harq->TBS);
cw_info->new_data_indicator = true; // treated as new data
}
current_harq->R = cw_info->targetCodeRate;
current_harq->TBS = cw_info->TBS;
}
else {
cw_info->targetCodeRate = current_harq->R;
cw_info->TBS = current_harq->TBS;
}
if (cw_info->TBS == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
return false;
}
cw_info->ldpcBaseGraph = get_BG(cw_info->TBS, cw_info->targetCodeRate);
return true;
}
static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot,
@@ -789,7 +885,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
0,
dci->frequency_domain_assignment)
< 0) {
LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
LOG_W(NR_MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
return -1;
}
@@ -873,76 +969,28 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
NULL, // SPS not implemented,
false, // as above
NULL); // MCS-C-RNTI not implemented
/* MCS */
dlsch_pdu->mcs = dci->mcs;
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
/* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
if (dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH ||
dl_conf_req->pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH ||
dci->ndi != current_harq->last_ndi) {
// new data
dlsch_pdu->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
} else {
dlsch_pdu->new_data_indicator = false;
}
if (dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH &&
dl_conf_req->pdu_type != FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH) {
current_harq->last_ndi = dci->ndi;
}
dlsch_pdu->qamModOrder = nr_get_Qm_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (dlsch_pdu->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
int R = nr_get_code_rate_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (R > 0) {
dlsch_pdu->targetCodeRate = R;
int nb_rb_oh;
if (mac->sc_info.xOverhead_PDSCH)
nb_rb_oh = 6 * (1 + *mac->sc_info.xOverhead_PDSCH);
else
nb_rb_oh = 0;
int nb_re_dmrs = ((dlsch_pdu->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups;
dlsch_pdu->TBS = nr_compute_tbs(dlsch_pdu->qamModOrder,
R,
int nb_rb_oh = mac->sc_info.xOverhead_PDSCH ? nb_rb_oh = 6 * (1 + *mac->sc_info.xOverhead_PDSCH) : 0;
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val][0];
if (!get_cw_info(current_harq,
dlsch_pdu,
dl_conf_req->pdu_type,
&dlsch_pdu->cw_info[0],
dlsch_pdu->number_rbs,
dlsch_pdu->number_symbols,
nb_re_dmrs * get_num_dmrs(dlsch_pdu->dlDmrsSymbPos),
nb_re_dmrs,
nb_rb_oh,
0,
1);
// storing for possible retransmissions
current_harq->R = dlsch_pdu->targetCodeRate;
if (!dlsch_pdu->new_data_indicator && current_harq->TBS != dlsch_pdu->TBS) {
LOG_W(NR_MAC, "NDI indicates re-transmission but computed TBS %d doesn't match with what previously stored %d\n",
dlsch_pdu->TBS, current_harq->TBS);
dlsch_pdu->new_data_indicator = true; // treated as new data
}
current_harq->TBS = dlsch_pdu->TBS;
}
else {
dlsch_pdu->targetCodeRate = current_harq->R;
dlsch_pdu->TBS = current_harq->TBS;
}
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
if (dlsch_pdu->TBS == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
dci->rv,
dci->mcs,
dci->ndi,
0))
return -1;
}
dlsch_pdu->n_codewords = 1;
int bw_tbslbrm = current_DL_BWP ? mac->sc_info.dl_bw_tbslbrm : dlsch_pdu->BWPSize;
dlsch_pdu->tbslbrm = nr_compute_tbslbrm(dlsch_pdu->mcs_table, bw_tbslbrm, 1);
/* RV (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
dlsch_pdu->rv = dci->rv;
/* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/
dlsch_pdu->harq_process_nbr = dci->harq_pid.val;
/* TB_SCALING (only if CRC scrambled by P-RNTI or RA-RNTI) */
@@ -1009,6 +1057,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
set_harq_status(mac,
dci->pucch_resource_indicator,
dci->harq_pid.val,
0,
tpc[dci->tpc],
feedback_ti,
dci->dai[0].val,
@@ -1017,10 +1066,6 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
frame,
slot);
}
if (dlsch_pdu->new_data_indicator)
current_harq->round = 0;
else
current_harq->round++;
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
}
@@ -1043,9 +1088,9 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
"(nr_ue_procedures.c) vrb_to_prb_mapping=%d \n>>> mcs=%d\n>>> ndi=%d\n>>> rv=%d\n>>> harq_process_nbr=%d\n>>> dai=%d\n>>> "
"scaling_factor_S=%f\n>>> tpc_pucch=%d\n>>> pucch_res_ind=%d\n>>> pdsch_to_harq_feedback_time_ind=%d\n",
dlsch_pdu->vrb_to_prb_mapping,
dlsch_pdu->mcs,
dlsch_pdu->new_data_indicator,
dlsch_pdu->rv,
dlsch_pdu->cw_info[0].mcs,
dlsch_pdu->cw_info[0].new_data_indicator,
dlsch_pdu->cw_info[0].rv,
dlsch_pdu->harq_process_nbr,
dci->dai[0].val,
dlsch_pdu->scaling_factor_S,
@@ -1055,7 +1100,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
dlsch_pdu->k1_feedback = feedback_ti;
LOG_D(MAC, "(nr_ue_procedures.c) pdu_type=%d\n\n", dl_conf_req->pdu_type);
LOG_D(MAC, "(nr_ue_procedures.c) pdu_type=%d\n", dl_conf_req->pdu_type);
// the prepared dci is valid, we add it in the list
dl_config->number_pdus++;
@@ -1213,9 +1258,6 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
dlsch_pdu->dmrsConfigType = dl_dmrs_config->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2;
/* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */
dlsch_pdu->n_dmrs_cdm_groups = 1;
/* VRB_TO_PRB_MAPPING */
if ((pdsch_Config->resourceAllocation == 1) && (pdsch_Config->vrb_ToPRB_Interleaver != NULL))
dlsch_pdu->vrb_to_prb_mapping =
@@ -1226,28 +1268,7 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
dlsch_pdu->rate_matching_ind = dci->rate_matching_indicator.val;
/* ZP_CSI_RS_TRIGGER */
dlsch_pdu->zp_csi_rs_trigger = dci->zp_csi_rs_trigger.val;
/* MCS (for transport block 1)*/
dlsch_pdu->mcs = dci->mcs;
/* NDI (for transport block 1)*/
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dci->harq_pid.val];
if (dci->ndi != current_harq->last_ndi) {
// new data
dlsch_pdu->new_data_indicator = true;
current_harq->R = 0;
current_harq->TBS = 0;
}
else {
dlsch_pdu->new_data_indicator = false;
}
current_harq->last_ndi = dci->ndi;
/* RV (for transport block 1)*/
dlsch_pdu->rv = dci->rv;
/* MCS (for transport block 2)*/
dlsch_pdu->tb2_mcs = dci->mcs2.val;
/* NDI (for transport block 2)*/
dlsch_pdu->tb2_new_data_indicator = dci->ndi2.val;
/* RV (for transport block 2)*/
dlsch_pdu->tb2_rv = dci->rv2.val;
/* HARQ_PROCESS_NUMBER */
dlsch_pdu->harq_process_nbr = dci->harq_pid.val;
/* TPC_PUCCH */
@@ -1276,13 +1297,32 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
return -1;
}
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
int nb_rb_oh;
if (sc_info->xOverhead_PDSCH)
nb_rb_oh = 6 * (1 + *sc_info->xOverhead_PDSCH);
else
nb_rb_oh = 0;
/* ANTENNA_PORTS */
uint8_t n_codewords = 1; // FIXME!!!
long *max_length = dl_dmrs_config->maxLength;
long *dmrs_type = dl_dmrs_config->dmrs_Type;
// In case the higher layer parameter maxNrofCodeWordsScheduledByDCI indicates that two codeword transmission is enabled,
// then one of the two transport blocks is disabled by DCI format 1_1
// if IMCS = 26 and if rvid = 1 for the corresponding transport block
bool cw0 = true;
bool cw1 = true;
if (pdsch_Config->maxNrofCodeWordsScheduledByDCI
&& *pdsch_Config->maxNrofCodeWordsScheduledByDCI == NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n2) {
cw0 = dci->rv != 1 || dci->mcs != 26;
cw1 = dci->rv2.val != 1 || dci->mcs2.val != 26;
} else
cw1 = false;
dlsch_pdu->n_front_load_symb = 1; // default value
set_antenna_port_parameters(dlsch_pdu, n_codewords, max_length, dmrs_type, dci->antenna_ports.val);
set_antenna_port_parameters(dlsch_pdu, cw0 + cw1, max_length, dmrs_type, dci->antenna_ports.val);
int nb_re_dmrs = ((dmrs_type == NULL) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups;
/* dmrs symbol positions*/
dlsch_pdu->dlDmrsSymbPos = fill_dmrs_mask(pdsch_Config,
@@ -1293,6 +1333,105 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
tda_info.mapping_type,
dlsch_pdu->n_front_load_symb);
dlsch_pdu->mcs_table = get_dlsch_mcs_table(NR_DL_DCI_FORMAT_1_1,
rnti_type,
dci_ind->ss_type,
pdsch_Config ? pdsch_Config->mcs_Table : NULL,
NULL, // SPS not implemented,
false, // as above
NULL); // MCS-C-RNTI not implemented
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
// according to TS 38.213 Table 9.2.3-1
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing);
uint16_t feedback_ti = 0;
const int tpc[] = {-1, 0, 1, 3};
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset;
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing),
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config "
"file (min_rxtxtime).\n",
feedback_ti,
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing));
}
int number_rbs;
if (dlsch_pdu->resource_alloc == 1) {
number_rbs = dlsch_pdu->number_rbs;
} else {
uint32_t temp_bitmap[9];
memcpy(temp_bitmap, dlsch_pdu->rb_bitmap, 36);
number_rbs = count_bits(temp_bitmap, 9);
}
int cw_idx = 0;
NR_UE_DL_HARQ_STATUS_t *current_harq = NULL;
if (cw0) {
current_harq = &mac->dl_harq_info[dci->harq_pid.val][0];
if (get_cw_info(current_harq,
dlsch_pdu,
dl_conf_req->pdu_type,
&dlsch_pdu->cw_info[0],
number_rbs,
nb_re_dmrs,
nb_rb_oh,
dci->rv,
dci->mcs,
dci->ndi,
cw_idx)) {
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
// set the harq status at MAC for feedback
set_harq_status(mac,
dci->pucch_resource_indicator,
dci->harq_pid.val,
0,
tpc[dci->tpc],
feedback_ti,
dci->dai[0].val,
dci_ind->n_CCE,
dci_ind->N_CCE,
frame,
slot);
cw_idx++;
} else
return -1;
}
if (cw1) {
current_harq = &mac->dl_harq_info[dci->harq_pid.val][cw_idx];
if (get_cw_info(current_harq,
dlsch_pdu,
dl_conf_req->pdu_type,
&dlsch_pdu->cw_info[1],
number_rbs,
nb_re_dmrs,
nb_rb_oh,
dci->rv2.val,
dci->mcs2.val,
dci->ndi2.val,
cw_idx)) {
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
// set the harq status at MAC for feedback
set_harq_status(mac,
dci->pucch_resource_indicator,
dci->harq_pid.val,
1,
tpc[dci->tpc],
feedback_ti,
dci->dai[0].val,
dci_ind->n_CCE,
dci_ind->N_CCE,
frame,
slot);
cw_idx++;
} else
return -1;
}
dlsch_pdu->n_codewords = cw_idx;
/* TCI */
if (dl_conf_req->dci_config_pdu.dci_config_rel15.coreset.tci_present_in_dci == 1) {
// 0 bit if higher layer parameter tci-PresentInDCI is not enabled
@@ -1311,107 +1450,9 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
/* DMRS_SEQ_INI */
// FIXME!!!
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
// according to TS 38.213 Table 9.2.3-1
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing);
uint16_t feedback_ti = 0;
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset;
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing),
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config "
"file (min_rxtxtime).\n",
feedback_ti,
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing));
// set the harq status at MAC for feedback
const int tpc[] = {-1, 0, 1, 3};
set_harq_status(mac,
dci->pucch_resource_indicator,
dci->harq_pid.val,
tpc[dci->tpc],
feedback_ti,
dci->dai[0].val,
dci_ind->n_CCE,
dci_ind->N_CCE,
frame,
slot);
}
if (dlsch_pdu->new_data_indicator)
current_harq->round = 0;
else
current_harq->round++;
if (current_harq->round < sizeofArray(mac->stats.dl.rounds))
mac->stats.dl.rounds[current_harq->round]++;
// send the ack/nack slot number to phy to indicate tx thread to wait for DLSCH decoding
dlsch_pdu->k1_feedback = feedback_ti;
dlsch_pdu->mcs_table = get_dlsch_mcs_table(NR_DL_DCI_FORMAT_1_1,
rnti_type,
dci_ind->ss_type,
pdsch_Config ? pdsch_Config->mcs_Table : NULL,
NULL, // SPS not implemented,
false, // as above
NULL); // MCS-C-RNTI not implemented
dlsch_pdu->qamModOrder = nr_get_Qm_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (dlsch_pdu->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
uint8_t Nl = 0;
for (int i = 0; i < 12; i++) { // max 12 ports
if ((dlsch_pdu->dmrs_ports >> i) & 0x01)
Nl += 1;
}
NR_UE_ServingCell_Info_t *sc_info = &mac->sc_info;
int nb_rb_oh;
if (sc_info->xOverhead_PDSCH)
nb_rb_oh = 6 * (1 + *sc_info->xOverhead_PDSCH);
else
nb_rb_oh = 0;
int nb_re_dmrs = ((dmrs_type == NULL) ? 6 : 4) * dlsch_pdu->n_dmrs_cdm_groups;
int number_rbs;
if (dlsch_pdu->resource_alloc == 1) {
number_rbs = dlsch_pdu->number_rbs;
} else {
uint32_t temp_bitmap[9];
memcpy(temp_bitmap, dlsch_pdu->rb_bitmap, 36);
number_rbs = count_bits(temp_bitmap, 9);
}
int R = nr_get_code_rate_dl(dlsch_pdu->mcs, dlsch_pdu->mcs_table);
if (R > 0) {
dlsch_pdu->targetCodeRate = R;
dlsch_pdu->TBS = nr_compute_tbs(dlsch_pdu->qamModOrder,
R,
number_rbs,
dlsch_pdu->number_symbols,
nb_re_dmrs * get_num_dmrs(dlsch_pdu->dlDmrsSymbPos),
nb_rb_oh,
0,
Nl);
// storing for possible retransmissions
if (!dlsch_pdu->new_data_indicator && current_harq->TBS != dlsch_pdu->TBS) {
LOG_W(NR_MAC, "NDI indicates re-transmission but computed TBS %d doesn't match with what previously stored %d\n",
dlsch_pdu->TBS, current_harq->TBS);
dlsch_pdu->new_data_indicator = true; // treated as new data
}
current_harq->R = dlsch_pdu->targetCodeRate;
current_harq->TBS = dlsch_pdu->TBS;
}
else {
dlsch_pdu->targetCodeRate = current_harq->R;
dlsch_pdu->TBS = current_harq->TBS;
}
dlsch_pdu->ldpcBaseGraph = get_BG(dlsch_pdu->TBS, dlsch_pdu->targetCodeRate);
if (dlsch_pdu->TBS == 0) {
LOG_E(MAC, "Invalid TBS = 0. Probably caused by missed detection of DCI\n");
return -1;
}
// TBS_LBRM according to section 5.4.2.1 of 38.212
int max_mimo_layers = 0;
if (sc_info->maxMIMO_Layers_PDSCH)
@@ -1424,10 +1465,11 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
/*PTRS configuration */
dlsch_pdu->pduBitmap = 0;
if (dl_dmrs_config->phaseTrackingRS != NULL) {
AssertFatal(cw_idx == 1, "Cannot handle PTRS with 2 codewords\n");
bool valid_ptrs_setup =
set_dl_ptrs_values(dl_dmrs_config->phaseTrackingRS->choice.setup,
number_rbs,
dlsch_pdu->mcs,
dlsch_pdu->cw_info[0].mcs,
dlsch_pdu->mcs_table,
&dlsch_pdu->PTRSFreqDensity,
&dlsch_pdu->PTRSTimeDensity,
@@ -2339,11 +2381,8 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche
/* 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 dl_harq_pid = 0; dl_harq_pid < num_dl_harq; dl_harq_pid++) {
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dl_harq_pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[dl_harq_pid][code_word];
if (current_harq->active) {
LOG_D(PHY, "HARQ pid %d is active for %d.%d\n",
dl_harq_pid, current_harq->ul_frame, current_harq->ul_slot);
+14 -12
View File
@@ -116,15 +116,22 @@ static void trigger_regular_bsr(NR_UE_MAC_INST_t *mac, NR_LogicalChannelIdentity
nr_timer_stop(&mac->scheduling_info.sr_DelayTimer);
}
static void flush_harq_buffers(NR_UE_MAC_INST_t *mac)
{
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
for (int c = 0; c < 2; c++) {
memset(&mac->dl_harq_info[k][c], 0, sizeof(NR_UE_DL_HARQ_STATUS_t));
mac->dl_harq_info[k][c].last_ndi = -1; // initialize to invalid value
}
memset(&mac->ul_harq_info[k], 0, sizeof(*mac->ul_harq_info));
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
}
}
void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
{
// flush all HARQ buffers for all Serving Cells
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
memset(&mac->dl_harq_info[k], 0, sizeof(*mac->dl_harq_info));
memset(&mac->ul_harq_info[k], 0, sizeof(*mac->ul_harq_info));
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
}
flush_harq_buffers(mac);
// release PUCCH for all Serving Cells;
// release SRS for all Serving Cells;
release_PUCCH_SRS(mac);
@@ -142,12 +149,7 @@ void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac)
void handle_ulsync_loss(NR_UE_MAC_INST_t *mac)
{
// flush all HARQ buffers for all Serving Cells
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
memset(&mac->dl_harq_info[k], 0, sizeof(*mac->dl_harq_info));
memset(&mac->ul_harq_info[k], 0, sizeof(*mac->ul_harq_info));
mac->dl_harq_info[k].last_ndi = -1; // initialize to invalid value
mac->ul_harq_info[k].last_ndi = -1; // initialize to invalid value
}
flush_harq_buffers(mac);
// clear any configured downlink assignments and uplink grants;
if (mac->dl_config_request)
memset(mac->dl_config_request, 0, sizeof(*mac->dl_config_request));
+3 -2
View File
@@ -145,6 +145,7 @@ static int8_t handle_dlsch(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i
if (mac->ra.ra_state != nrRA_WAIT_RAR) // no HARQ for MSG2
update_harq_status(mac,
dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid,
dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.cw_idx,
dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack);
if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack)
nr_ue_send_sdu(mac, dl_info, pdu_id);
@@ -167,9 +168,9 @@ static int8_t handle_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int s
return 0;
}
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, uint8_t ack_nack)
void update_harq_status(NR_UE_MAC_INST_t *mac, uint8_t harq_pid, int cw_idx, uint8_t ack_nack)
{
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid];
NR_UE_DL_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[harq_pid][cw_idx];
if (current_harq->active) {
LOG_D(PHY,"Updating harq_status for harq_id %d, ack/nak %d\n", harq_pid, current_harq->ack);