Commit 6fcfbc49 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

T2 - offload TB for encoding, decoding - on gNB side only, do CRC check on the T2

parent 21172d27
......@@ -90,10 +90,13 @@ typedef struct nrLDPC_dec_params {
uint8_t rv;
uint8_t numMaxIter; /**< Maximum number of iterations */
int E;
uint32_t E_cb[64];
e_nrLDPC_outMode outMode; /**< Output format */
int crc_type;
int (*check_crc)(uint8_t* decoded_bytes, uint32_t n, uint8_t crc_type);
uint8_t setCombIn;
uint8_t setCombIn_cb[64];
uint8_t status_cb[64];
} t_nrLDPC_dec_params;
typedef struct nrLDPCoffload_params {
......@@ -102,10 +105,15 @@ typedef struct nrLDPCoffload_params {
uint16_t Kr;
uint8_t rv;
uint32_t E;
uint32_t E_cb[64];
uint16_t n_cb;
uint16_t F; /**< Filler bits */
uint8_t Qm; /**< Modulation */
uint8_t C;
uint8_t numMaxIter;
uint8_t setCombIn;
uint8_t setCombIn_cb[64];
uint8_t *status_cb[64];
} t_nrLDPCoffload_params;
/**
......
......@@ -60,6 +60,8 @@ typedef struct {
/// Modulation order
uint8_t Qm;
uint32_t E;
uint32_t E_cb[64];
uint8_t status_cb[64];
unsigned int G;
// Redundancy version index
uint8_t rv;
......
......@@ -366,17 +366,14 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
if (gNB->ldpc_offload_flag) {
impp.Qm = rel15->qamModOrder[0];
impp.rv = rel15->rvIndex[0];
int nb_re_dmrs =
(rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? (6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData);
impp.G = nr_get_G(rel15->rbSize, rel15->NrOfSymbols, nb_re_dmrs, get_num_dmrs(rel15->dlDmrsSymbPos), harq->unav_res,
rel15->qamModOrder[0], rel15->nrOfLayers);
int r_offset = 0;
int nb_re_dmrs = (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ?
(6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData);
impp.G = nr_get_G(rel15->rbSize, rel15->NrOfSymbols, nb_re_dmrs, get_num_dmrs(rel15->dlDmrsSymbPos),
harq->unav_res, rel15->qamModOrder[0], rel15->nrOfLayers);
for (int r = 0; r < impp.n_segments; r++) {
impp.E = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r);
uint8_t *f = impp.output + r_offset;
ldpc_interface_offload.LDPCencoder(&harq->c[r], &f, &impp);
r_offset += impp.E;
impp.E_cb[r] = nr_get_E(impp.G, impp.n_segments, impp.Qm, rel15->nrOfLayers, r);
}
ldpc_interface_offload.LDPCencoder(harq->c, &impp.output, &impp);
} else {
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
......
......@@ -232,59 +232,50 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
{
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
int16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
int8_t l_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
uint8_t Qm = pusch_pdu->qam_mod_order;
uint8_t n_layers = pusch_pdu->nrOfLayers;
int16_t z_ol[64 * LDPC_MAX_CB_SIZE] __attribute__((aligned(32)));
int8_t l_ol[64 * LDPC_MAX_CB_SIZE] __attribute__((aligned(32)));
const int kc = decParams->BG == 2 ? 52 : 68;
uint32_t A = (harq_process->TBS) << 3;
const int Kr = harq_process->K;
const int Kr_bytes = Kr >> 3;
uint32_t A = (harq_process->TBS) << 3;
const int kc = decParams->BG == 2 ? 52 : 68;
ulsch->max_ldpc_iterations = 20;
int decodeIterations = 2;
int r_offset = 0, offset = 0;
int8_t decodeIterations = 0;
uint8_t *p_outDec;
int r_offset = 0;
int offset = 0;
p_outDec = calloc(64 * Kr_bytes, sizeof(int8_t));
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);
decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
E,
decParams->BG,
decParams->Z,
&harq_process->llrLen,
harq_process->round);
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;
decParams->E_cb[r] = nr_get_E(G, harq_process->C, decParams->Qm, pusch_pdu->nrOfLayers, r);
memcpy(&z_ol[offset], ulsch_llr + r_offset, decParams->E_cb[r] * sizeof(short));
simde__m128i *pv_ol128 = (simde__m128i *)&z_ol[offset];
simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset];
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]);
}
decParams->E = E;
decParams->rv = pusch_pdu->pusch_data.rv_index;
decParams->F = harq_process->F;
decParams->Qm = Qm;
decodeIterations =
ldpc_interface_offload
.LDPCdecoder(decParams, harq_pid, ULSCH_id, r, (int8_t *)&pl_ol128[0], (int8_t *)harq_process->c[r], NULL, NULL);
if (decodeIterations < 0) {
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
return -1;
}
bool decodeSuccess = check_crc((uint8_t *)harq_process->c[r], lenWithCrc(harq_process->C, A), crcType(harq_process->C, A));
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);
r_offset += decParams->E_cb[r];
offset += LDPC_MAX_CB_SIZE;
}
decodeIterations = ldpc_interface_offload.LDPCdecoder(decParams, harq_pid, ULSCH_id, harq_process->C, (int8_t *)l_ol, (int8_t *)p_outDec, NULL, NULL);
if (decodeIterations < 0) {
LOG_E(PHY, "ulsch_decoding.c: Problem in LDPC decoder offload\n");
return -1;
}
int offset_b = 0;
for (int r = 0; r < harq_process->C; r++) {
if (decParams->status_cb[r] == 0) {
memcpy(harq_process->b + offset_b, &p_outDec[offset_b], Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
}
r_offset += E;
offset_b += (Kr_bytes - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
harq_process->processedSegments++;
}
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
//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
if (decodeIterations < ulsch->max_ldpc_iterations) {
crc_valid = true;
if (harq_process->C > 1) {
crc_valid = check_crc(harq_process->b, lenWithCrc(1, A), crcType(1, A));
......@@ -419,6 +410,8 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
decParams.Z = harq_process->Z;
decParams.numMaxIter = ulsch->max_ldpc_iterations;
decParams.Qm = Qm;
decParams.rv = pusch_pdu->pusch_data.rv_index;
decParams.outMode = 0;
decParams.setCombIn = !harq_process->harq_to_be_cleared;
if (harq_process->harq_to_be_cleared) {
......
......@@ -154,7 +154,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
}
start_meas(&ue->ulsch_ldpc_encoding_stats);
if (ldpc_interface_offload.LDPCencoder) {
if (0) {
for (int j = 0; j < impp.n_segments; j++) {
impp.E = nr_get_E(G, impp.n_segments, impp.Qm, ulsch->pusch_pdu.nrOfLayers, j);
uint8_t *f = harq_process->f + r_offset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment