one-step-cleaning-gNB-ulsch-decoding
This commit is contained in:
@@ -125,34 +125,20 @@ static void nr_processULSegment(void *arg)
|
|||||||
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
|
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
|
||||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||||
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
||||||
int length_dec;
|
const int Kr = ulsch_harq->K;
|
||||||
int Kr;
|
const int Kr_bytes = Kr >> 3;
|
||||||
int Kr_bytes;
|
const int K_bits_F = Kr - ulsch_harq->F;
|
||||||
int K_bits_F;
|
const int r = rdata->segment_r;
|
||||||
uint8_t crc_type;
|
const int A = rdata->A;
|
||||||
int i;
|
const int E = rdata->E;
|
||||||
int j;
|
const int Qm = rdata->Qm;
|
||||||
int r = rdata->segment_r;
|
const int rv_index = rdata->rv_index;
|
||||||
int A = rdata->A;
|
const int r_offset = rdata->r_offset;
|
||||||
int E = rdata->E;
|
const uint8_t kc = rdata->Kc;
|
||||||
int Qm = rdata->Qm;
|
|
||||||
int rv_index = rdata->rv_index;
|
|
||||||
int r_offset = rdata->r_offset;
|
|
||||||
uint8_t kc = rdata->Kc;
|
|
||||||
short *ulsch_llr = rdata->ulsch_llr;
|
short *ulsch_llr = rdata->ulsch_llr;
|
||||||
int max_ldpc_iterations = p_decoderParms->numMaxIter;
|
const int max_ldpc_iterations = p_decoderParms->numMaxIter;
|
||||||
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32)));
|
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__((aligned(32)));
|
||||||
|
|
||||||
int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
|
|
||||||
int8_t l[68 * 384 + 16] __attribute__((aligned(16)));
|
|
||||||
|
|
||||||
simde__m128i *pv = (simde__m128i *)&z;
|
|
||||||
simde__m128i *pl = (simde__m128i *)&l;
|
|
||||||
|
|
||||||
Kr = ulsch_harq->K;
|
|
||||||
Kr_bytes = Kr >> 3;
|
|
||||||
K_bits_F = Kr - ulsch_harq->F;
|
|
||||||
|
|
||||||
t_nrLDPC_time_stats procTime = {0};
|
t_nrLDPC_time_stats procTime = {0};
|
||||||
t_nrLDPC_time_stats *p_procTime = &procTime;
|
t_nrLDPC_time_stats *p_procTime = &procTime;
|
||||||
|
|
||||||
@@ -211,28 +197,33 @@ static void nr_processULSegment(void *arg)
|
|||||||
|
|
||||||
if (ulsch_harq->C == 1) {
|
if (ulsch_harq->C == 1) {
|
||||||
if (A > 3824)
|
if (A > 3824)
|
||||||
crc_type = CRC24_A;
|
p_decoderParms->crc_type = CRC24_A;
|
||||||
else
|
else
|
||||||
crc_type = CRC16;
|
p_decoderParms->crc_type = CRC16;
|
||||||
|
p_decoderParms->block_length = ulsch_harq->B;
|
||||||
length_dec = ulsch_harq->B;
|
|
||||||
} else {
|
} else {
|
||||||
crc_type = CRC24_B;
|
p_decoderParms->crc_type = CRC24_B;
|
||||||
length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C;
|
p_decoderParms->block_length = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
// start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||||
|
|
||||||
// set first 2*Z_c bits to zeros
|
// set first 2*Z_c bits to zeros
|
||||||
memset(&z[0], 0, 2 * ulsch_harq->Z * sizeof(int16_t));
|
|
||||||
|
int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
|
||||||
|
|
||||||
|
memset(z, 0, 2 * ulsch_harq->Z * sizeof(*z));
|
||||||
// set Filler bits
|
// set Filler bits
|
||||||
memset((&z[0] + K_bits_F), 127, ulsch_harq->F * sizeof(int16_t));
|
memset(z + K_bits_F, 127, ulsch_harq->F * sizeof(*z));
|
||||||
// Move coded bits before filler bits
|
// Move coded bits before filler bits
|
||||||
memcpy((&z[0] + 2 * ulsch_harq->Z), ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(int16_t));
|
memcpy(z + 2 * ulsch_harq->Z, ulsch_harq->d[r], (K_bits_F - 2 * ulsch_harq->Z) * sizeof(*z));
|
||||||
// skip filler bits
|
// skip filler bits
|
||||||
memcpy((&z[0] + Kr), ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(int16_t));
|
memcpy(z + Kr, ulsch_harq->d[r] + (Kr - 2 * ulsch_harq->Z), (kc * ulsch_harq->Z - Kr) * sizeof(*z));
|
||||||
// Saturate coded bits before decoding into 8 bits values
|
// Saturate coded bits before decoding into 8 bits values
|
||||||
for (i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) {
|
simde__m128i *pv = (simde__m128i *)&z;
|
||||||
|
int8_t l[68 * 384 + 16] __attribute__((aligned(16)));
|
||||||
|
simde__m128i *pl = (simde__m128i *)&l;
|
||||||
|
for (int i = 0, j = 0; j < ((kc * ulsch_harq->Z) >> 4) + 1; i += 2, j++) {
|
||||||
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
|
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -242,73 +233,194 @@ static void nr_processULSegment(void *arg)
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||||
p_decoderParms->block_length = length_dec;
|
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
|
||||||
p_decoderParms->crc_type = crc_type;
|
|
||||||
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)pl, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
|
|
||||||
|
|
||||||
if (rdata->decodeIterations <= p_decoderParms->numMaxIter)
|
if (rdata->decodeIterations <= p_decoderParms->numMaxIter)
|
||||||
memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3);
|
memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3);
|
||||||
//stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
//stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
|
||||||
uint8_t ULSCH_id,
|
uint8_t ULSCH_id,
|
||||||
short *ulsch_llr,
|
short *ulsch_llr,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
t_nrLDPC_dec_params *decParams,
|
||||||
uint32_t frame,
|
uint8_t harq_pid,
|
||||||
uint8_t nr_tti_rx,
|
uint32_t G)
|
||||||
uint8_t harq_pid,
|
{
|
||||||
uint32_t G)
|
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||||
{
|
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
|
||||||
if (!ulsch_llr) {
|
int8_t llrProcBuf[22 * 384] __attribute__((aligned(32)));
|
||||||
LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
int16_t z_ol[68 * 384] __attribute__((aligned(32)));
|
||||||
return -1;
|
int8_t l_ol[68 * 384] __attribute__((aligned(32)));
|
||||||
}
|
int crc_type;
|
||||||
|
int length_dec;
|
||||||
|
uint8_t Qm = pusch_pdu->qam_mod_order;
|
||||||
|
uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||||
|
const int Kr = harq_process->K;
|
||||||
|
const int Kr_bytes = Kr >> 3;
|
||||||
|
const int kc = decParams->BG == 2 ? 52 : 68;
|
||||||
|
const uint32_t A = (harq_process->TBS) << 3;
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
|
if (harq_process->C == 1) {
|
||||||
|
if (A > 3824)
|
||||||
|
crc_type = CRC24_A;
|
||||||
|
else
|
||||||
|
crc_type = CRC16;
|
||||||
|
|
||||||
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
length_dec = harq_process->B;
|
||||||
NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
|
} else {
|
||||||
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
|
crc_type = CRC24_B;
|
||||||
|
length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C;
|
||||||
if (!harq_process) {
|
|
||||||
LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
uint8_t dtx_det = 0;
|
int decodeIterations = 2;
|
||||||
|
int dtx_det = 0;
|
||||||
|
int r_offset = 0, offset = 0;
|
||||||
|
for (int r = 0; r < harq_process->C; r++) {
|
||||||
|
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
||||||
|
memset(harq_process->c[r], 0, Kr_bytes);
|
||||||
|
|
||||||
int Kr;
|
decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
|
||||||
int Kr_bytes;
|
E,
|
||||||
|
decParams->BG,
|
||||||
|
decParams->Z,
|
||||||
|
&harq_process->llrLen,
|
||||||
|
harq_process->round);
|
||||||
|
|
||||||
|
if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) {
|
||||||
|
memcpy(z_ol, ulsch_llr + r_offset, E * sizeof(short));
|
||||||
|
simde__m128i *pv_ol128 = (simde__m128i *)&z_ol;
|
||||||
|
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol;
|
||||||
|
for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
|
||||||
|
pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = nrLDPC_decoder_offload(decParams,
|
||||||
|
harq_pid,
|
||||||
|
ULSCH_id,
|
||||||
|
r,
|
||||||
|
pusch_pdu->pusch_data.rv_index,
|
||||||
|
harq_process->F,
|
||||||
|
E,
|
||||||
|
Qm,
|
||||||
|
(int8_t *)&pl_ol128[0],
|
||||||
|
llrProcBuf,
|
||||||
|
1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
|
||||||
|
|
||||||
|
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (int m = 0; m < Kr >> 3; m++) {
|
||||||
|
harq_process->c[r][m] = (uint8_t)llrProcBuf[m];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) {
|
||||||
|
PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r));
|
||||||
|
decodeIterations = 2;
|
||||||
|
} else {
|
||||||
|
PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r));
|
||||||
|
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
r_offset += E;
|
||||||
|
|
||||||
|
/*for (int k=0;k<8;k++)
|
||||||
|
{
|
||||||
|
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||||
|
printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
dtx_det = 0;
|
||||||
|
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
||||||
|
}
|
||||||
|
bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations);
|
||||||
|
if (decodeSuccess) {
|
||||||
|
memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||||
|
offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||||
|
harq_process->processedSegments++;
|
||||||
|
} else {
|
||||||
|
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
|
||||||
|
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||||
|
break; // don't even attempt to decode other segments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0);
|
||||||
|
|
||||||
|
if (harq_process->processedSegments == harq_process->C) {
|
||||||
|
LOG_D(PHY, "ULSCH: Setting ACK for slot %d TBS %d\n", ulsch->slot, harq_process->TBS);
|
||||||
|
ulsch->active = false;
|
||||||
|
harq_process->round = 0;
|
||||||
|
|
||||||
|
LOG_D(PHY, "ULSCH received ok \n");
|
||||||
|
nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LOG_D(PHY,
|
||||||
|
"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n",
|
||||||
|
phy_vars_gNB->Mod_id,
|
||||||
|
ulsch->frame,
|
||||||
|
ulsch->slot,
|
||||||
|
harq_pid,
|
||||||
|
ulsch->active,
|
||||||
|
harq_process->round,
|
||||||
|
harq_process->TBS);
|
||||||
|
ulsch->handled = 1;
|
||||||
|
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
||||||
|
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
||||||
|
nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0);
|
||||||
|
}
|
||||||
|
ulsch->last_iteration_cnt = decodeIterations;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||||
|
uint8_t ULSCH_id,
|
||||||
|
short *ulsch_llr,
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
|
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||||
|
uint32_t frame,
|
||||||
|
uint8_t nr_tti_rx,
|
||||||
|
uint8_t harq_pid,
|
||||||
|
uint32_t G)
|
||||||
|
{
|
||||||
|
if (!ulsch_llr) {
|
||||||
|
LOG_E(PHY, "ulsch_decoding.c: NULL ulsch_llr pointer\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 1);
|
||||||
|
|
||||||
|
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
|
||||||
|
NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
|
||||||
|
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
|
||||||
|
|
||||||
|
if (!harq_process) {
|
||||||
|
LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
const uint16_t nb_rb = pusch_pdu->rb_size;
|
||||||
|
const uint8_t Qm = pusch_pdu->qam_mod_order;
|
||||||
|
const uint8_t mcs = pusch_pdu->mcs_index;
|
||||||
|
const uint8_t n_layers = pusch_pdu->nrOfLayers;
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
harq_process->processedSegments = 0;
|
harq_process->processedSegments = 0;
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
|
||||||
uint8_t Qm = pusch_pdu->qam_mod_order;
|
|
||||||
uint8_t mcs = pusch_pdu->mcs_index;
|
|
||||||
uint8_t n_layers = pusch_pdu->nrOfLayers;
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
|
|
||||||
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
|
||||||
|
|
||||||
dtx_det = 0;
|
|
||||||
|
|
||||||
uint32_t A = (harq_process->TBS) << 3;
|
|
||||||
|
|
||||||
// target_code_rate is in 0.1 units
|
|
||||||
float Coderate = (float) pusch_pdu->target_code_rate / 10240.0f;
|
|
||||||
|
|
||||||
LOG_D(PHY,"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
|
|
||||||
harq_pid, ulsch->rnti, A, G, mcs, n_layers, nb_rb, Qm, Coderate, pusch_pdu->pusch_data.rv_index, harq_process->round, harq_process->harq_to_be_cleared);
|
|
||||||
t_nrLDPC_dec_params decParams = {0};
|
t_nrLDPC_dec_params decParams = {0};
|
||||||
decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
||||||
int kc;
|
const uint32_t A = (harq_process->TBS) << 3;
|
||||||
if (decParams.BG == 2) {
|
if (A > 3824)
|
||||||
kc = 52;
|
harq_process->B = A + 24;
|
||||||
} else {
|
else
|
||||||
kc = 68;
|
harq_process->B = A + 16;
|
||||||
}
|
|
||||||
|
|
||||||
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
|
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
|
||||||
if (stats) {
|
if (stats) {
|
||||||
@@ -324,10 +436,21 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
|
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (A > 3824)
|
|
||||||
harq_process->B = A+24;
|
LOG_D(PHY,
|
||||||
else
|
"ULSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
|
||||||
harq_process->B = A+16;
|
harq_pid,
|
||||||
|
ulsch->rnti,
|
||||||
|
A,
|
||||||
|
G,
|
||||||
|
mcs,
|
||||||
|
n_layers,
|
||||||
|
nb_rb,
|
||||||
|
Qm,
|
||||||
|
pusch_pdu->target_code_rate / 10240.0f,
|
||||||
|
pusch_pdu->pusch_data.rv_index,
|
||||||
|
harq_process->round,
|
||||||
|
harq_process->harq_to_be_cleared);
|
||||||
|
|
||||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||||
nr_segmentation(NULL,
|
nr_segmentation(NULL,
|
||||||
@@ -339,204 +462,75 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
&harq_process->F,
|
&harq_process->F,
|
||||||
decParams.BG);
|
decParams.BG);
|
||||||
|
|
||||||
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*n_layers) {
|
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * n_layers; // number of segments to be allocated
|
||||||
|
if (harq_process->C > a_segments) {
|
||||||
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
|
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_ULSCH_DECODING
|
|
||||||
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
|
|
||||||
if (!frame%100)
|
|
||||||
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
|
|
||||||
#endif
|
|
||||||
decParams.Z = harq_process->Z;
|
|
||||||
|
|
||||||
decParams.numMaxIter = ulsch->max_ldpc_iterations;
|
|
||||||
decParams.outMode = 0;
|
|
||||||
|
|
||||||
uint32_t r_offset = 0;
|
|
||||||
|
|
||||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*n_layers; //number of segments to be allocated
|
|
||||||
|
|
||||||
if (nb_rb != 273) {
|
if (nb_rb != 273) {
|
||||||
a_segments = a_segments*nb_rb;
|
a_segments = a_segments*nb_rb;
|
||||||
a_segments = a_segments/273 +1;
|
a_segments = a_segments/273 +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (harq_process->C > a_segments) {
|
if (harq_process->C > a_segments) {
|
||||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ULSCH_DECODING
|
#ifdef DEBUG_ULSCH_DECODING
|
||||||
|
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
|
||||||
|
if (!frame % 100)
|
||||||
|
printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z);
|
||||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
decParams.Z = harq_process->Z;
|
||||||
|
decParams.numMaxIter = ulsch->max_ldpc_iterations;
|
||||||
|
decParams.outMode = 0;
|
||||||
|
|
||||||
if (harq_process->harq_to_be_cleared) {
|
if (harq_process->harq_to_be_cleared) {
|
||||||
for (int r = 0; r < harq_process->C; r++)
|
for (int r = 0; r < harq_process->C; r++)
|
||||||
harq_process->d_to_be_cleared[r] = true;
|
harq_process->d_to_be_cleared[r] = true;
|
||||||
harq_process->harq_to_be_cleared = false;
|
harq_process->harq_to_be_cleared = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kr = harq_process->K;
|
if (phy_vars_gNB->ldpc_offload_flag && mcs > 9)
|
||||||
Kr_bytes = Kr >> 3;
|
return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G);
|
||||||
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0, r_offset = 0;
|
||||||
if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) {
|
set_abort(&harq_process->abort_decode, false);
|
||||||
int8_t llrProcBuf[22 * 384];
|
for (int r = 0; r < harq_process->C; r++) {
|
||||||
// if (dtx_det==0) {
|
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
||||||
int16_t z_ol[68 * 384];
|
union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}};
|
||||||
int8_t l_ol[68 * 384];
|
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment);
|
||||||
int crc_type;
|
ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req);
|
||||||
int length_dec;
|
decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
|
||||||
|
E,
|
||||||
if (harq_process->C == 1) {
|
decParams.BG,
|
||||||
if (A > 3824)
|
decParams.Z,
|
||||||
crc_type = CRC24_A;
|
&harq_process->llrLen,
|
||||||
else
|
harq_process->round);
|
||||||
crc_type = CRC16;
|
rdata->gNB = phy_vars_gNB;
|
||||||
|
rdata->ulsch_harq = harq_process;
|
||||||
length_dec = harq_process->B;
|
rdata->decoderParms = decParams;
|
||||||
} else {
|
rdata->ulsch_llr = ulsch_llr;
|
||||||
crc_type = CRC24_B;
|
rdata->Kc = decParams.BG == 2 ? 52 : 68;
|
||||||
length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C;
|
rdata->harq_pid = harq_pid;
|
||||||
}
|
rdata->segment_r = r;
|
||||||
int decodeIterations = 2;
|
rdata->nbSegments = harq_process->C;
|
||||||
for (int r = 0; r < harq_process->C; r++) {
|
rdata->E = E;
|
||||||
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
rdata->A = A;
|
||||||
memset(harq_process->c[r], 0, Kr_bytes);
|
rdata->Qm = Qm;
|
||||||
|
rdata->r_offset = r_offset;
|
||||||
decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round);
|
rdata->Kr_bytes = harq_process->K >> 3;
|
||||||
|
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||||
if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) {
|
rdata->offset = offset;
|
||||||
// if (dtx_det==0){
|
rdata->ulsch = ulsch;
|
||||||
memcpy((&z_ol[0]), ulsch_llr + r_offset, E * sizeof(short));
|
rdata->ulsch_id = ULSCH_id;
|
||||||
simde__m128i *pv_ol128 = (simde__m128i *)&z_ol;
|
rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
|
||||||
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol;
|
pushTpool(&phy_vars_gNB->threadPool, req);
|
||||||
for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
|
LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r);
|
||||||
pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
|
r_offset += E;
|
||||||
}
|
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||||
|
|
||||||
int ret = nrLDPC_decoder_offload(&decParams, harq_pid, ULSCH_id, r, pusch_pdu->pusch_data.rv_index, harq_process->F, E, Qm, (int8_t *)&pl_ol128[0], llrProcBuf, 1);
|
|
||||||
if (ret < 0) {
|
|
||||||
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
|
|
||||||
|
|
||||||
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (int m = 0; m < Kr >> 3; m++) {
|
|
||||||
harq_process->c[r][m] = (uint8_t)llrProcBuf[m];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_crc((uint8_t *)llrProcBuf, length_dec, crc_type)) {
|
|
||||||
PRINT_CRC_CHECK(LOG_I(PHY, "Segment %d CRC OK\n", r));
|
|
||||||
decodeIterations = 2;
|
|
||||||
} else {
|
|
||||||
PRINT_CRC_CHECK(LOG_I(PHY, "segment %d CRC NOK\n", r));
|
|
||||||
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
|
|
||||||
r_offset += E;
|
|
||||||
|
|
||||||
/*for (int k=0;k<8;k++)
|
|
||||||
{
|
|
||||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
|
||||||
printf("llrprocbuf [%d] = %x adr %p\n", k, llrProcBuf[k], llrProcBuf+k);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
dtx_det = 0;
|
|
||||||
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
|
||||||
}
|
|
||||||
bool decodeSuccess = (decodeIterations <= ulsch->max_ldpc_iterations);
|
|
||||||
if (decodeSuccess) {
|
|
||||||
memcpy(harq_process->b + offset, harq_process->c[r], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
|
||||||
offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
|
||||||
harq_process->processedSegments++;
|
|
||||||
} else {
|
|
||||||
LOG_D(PHY, "uplink segment error %d/%d\n", r, harq_process->C);
|
|
||||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
|
||||||
break; // don't even attempt to decode other segments
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING, 0);
|
|
||||||
|
|
||||||
bool crc_valid = false;
|
|
||||||
if (harq_process->processedSegments == harq_process->C) {
|
|
||||||
// When the number of code blocks is 1 (C = 1) and ulsch_harq->processedSegments = 1, we can assume a good TB because of the
|
|
||||||
// CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
|
|
||||||
crc_valid = true;
|
|
||||||
if (harq_process->C > 1) {
|
|
||||||
// Check ULSCH transport block CRC
|
|
||||||
crc_type = CRC16;
|
|
||||||
if (A > 3824) {
|
|
||||||
crc_type = CRC24_A;
|
|
||||||
}
|
|
||||||
crc_valid = check_crc(harq_process->b, harq_process->B, crc_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crc_valid) {
|
|
||||||
LOG_D(PHY, "[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n", phy_vars_gNB->Mod_id, ulsch->slot, harq_process->TBS);
|
|
||||||
ulsch->active = false;
|
|
||||||
harq_process->round = 0;
|
|
||||||
|
|
||||||
LOG_D(PHY, "ULSCH received ok \n");
|
|
||||||
nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 0, 0);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
LOG_D(PHY,
|
|
||||||
"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d)\n",
|
|
||||||
phy_vars_gNB->Mod_id,
|
|
||||||
ulsch->frame,
|
|
||||||
ulsch->slot,
|
|
||||||
harq_pid,
|
|
||||||
ulsch->active,
|
|
||||||
harq_process->round,
|
|
||||||
harq_process->TBS);
|
|
||||||
ulsch->handled = 1;
|
|
||||||
decodeIterations = ulsch->max_ldpc_iterations + 1;
|
|
||||||
LOG_D(PHY, "ULSCH %d in error\n", ULSCH_id);
|
|
||||||
nr_fill_indication(phy_vars_gNB, ulsch->frame, ulsch->slot, ULSCH_id, harq_pid, 1, 0);
|
|
||||||
}
|
|
||||||
ulsch->last_iteration_cnt = decodeIterations;
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
dtx_det = 0;
|
|
||||||
set_abort(&harq_process->abort_decode, false);
|
|
||||||
for (int r = 0; r < harq_process->C; r++) {
|
|
||||||
int E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
|
|
||||||
union ldpcReqUnion id = {.s = {ulsch->rnti, frame, nr_tti_rx, 0, 0}};
|
|
||||||
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, &phy_vars_gNB->respDecode, &nr_processULSegment);
|
|
||||||
ldpcDecode_t *rdata = (ldpcDecode_t *)NotifiedFifoData(req);
|
|
||||||
decParams.R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index, E, decParams.BG, decParams.Z, &harq_process->llrLen, harq_process->round);
|
|
||||||
rdata->gNB = phy_vars_gNB;
|
|
||||||
rdata->ulsch_harq = harq_process;
|
|
||||||
rdata->decoderParms = decParams;
|
|
||||||
rdata->ulsch_llr = ulsch_llr;
|
|
||||||
rdata->Kc = kc;
|
|
||||||
rdata->harq_pid = harq_pid;
|
|
||||||
rdata->segment_r = r;
|
|
||||||
rdata->nbSegments = harq_process->C;
|
|
||||||
rdata->E = E;
|
|
||||||
rdata->A = A;
|
|
||||||
rdata->Qm = Qm;
|
|
||||||
rdata->r_offset = r_offset;
|
|
||||||
rdata->Kr_bytes = Kr_bytes;
|
|
||||||
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
|
|
||||||
rdata->offset = offset;
|
|
||||||
rdata->ulsch = ulsch;
|
|
||||||
rdata->ulsch_id = ULSCH_id;
|
|
||||||
rdata->tbslbrm = pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
|
|
||||||
pushTpool(&phy_vars_gNB->threadPool, req);
|
|
||||||
LOG_D(PHY, "Added a block to decode, in pipe: %d\n", r);
|
|
||||||
r_offset += E;
|
|
||||||
offset += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return harq_process->C;
|
return harq_process->C;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -953,7 +953,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
|||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_ULSCH_PROCEDURES_RX, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) {
|
|
||||||
while (totalDecode > 0) {
|
while (totalDecode > 0) {
|
||||||
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
|
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
|
||||||
if (req == NULL)
|
if (req == NULL)
|
||||||
@@ -962,7 +961,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
|||||||
delNotifiedFIFO_elt(req);
|
delNotifiedFIFO_elt(req);
|
||||||
totalDecode--;
|
totalDecode--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (int i = 0; i < gNB->max_nb_srs; i++) {
|
for (int i = 0; i < gNB->max_nb_srs; i++) {
|
||||||
NR_gNB_SRS_t *srs = &gNB->srs[i];
|
NR_gNB_SRS_t *srs = &gNB->srs[i];
|
||||||
if (srs) {
|
if (srs) {
|
||||||
|
|||||||
Reference in New Issue
Block a user