Merge remote-tracking branch 'origin/one-step-cleaning-gNB-ulsch-decoding' into integration_2023_w39
This commit is contained in:
@@ -1145,6 +1145,7 @@ add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
|
||||
add_library(PHY_NR ${PHY_NR_SRC})
|
||||
|
||||
add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
|
||||
target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs)
|
||||
|
||||
add_library(PHY_RU ${PHY_SRC_RU})
|
||||
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs)
|
||||
|
||||
@@ -297,7 +297,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
int max_bytes = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers*1056;
|
||||
if (A > 3824) {
|
||||
int B;
|
||||
if (A > NR_MAX_PDSCH_TBS) {
|
||||
// Add 24-bit crc (polynomial A) to payload
|
||||
crc = crc24a(a,A)>>8;
|
||||
a[A>>3] = ((uint8_t *)&crc)[2];
|
||||
@@ -305,7 +306,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
harq->B = A+24;
|
||||
B = A + 24;
|
||||
// harq->b = a;
|
||||
AssertFatal((A / 8) + 4 <= max_bytes,
|
||||
"A %d is too big (A/8+4 = %d > %d)\n",
|
||||
@@ -320,7 +321,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
a[1+(A>>3)] = ((uint8_t *)&crc)[0];
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
|
||||
harq->B = A+16;
|
||||
B = A + 16;
|
||||
// harq->b = a;
|
||||
AssertFatal((A / 8) + 3 <= max_bytes,
|
||||
"A %d is too big (A/8+3 = %d > %d)\n",
|
||||
@@ -333,11 +334,11 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
impp.BG = rel15->maintenance_parms_v3.ldpcBaseGraph;
|
||||
|
||||
start_meas(dlsch_segmentation_stats);
|
||||
impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
|
||||
impp.Kb = nr_segmentation(harq->b, harq->c, B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
|
||||
stop_meas(dlsch_segmentation_stats);
|
||||
|
||||
if (impp.n_segments>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*rel15->nrOfLayers) {
|
||||
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",impp.n_segments,harq->B);
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", impp.n_segments, B);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,34 +124,20 @@ static void nr_processULSegment(void *arg)
|
||||
ldpcDecode_t *rdata = (ldpcDecode_t *)arg;
|
||||
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
|
||||
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
||||
int length_dec;
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
int K_bits_F;
|
||||
uint8_t crc_type;
|
||||
int i;
|
||||
int j;
|
||||
int r = rdata->segment_r;
|
||||
int A = rdata->A;
|
||||
int E = rdata->E;
|
||||
int Qm = rdata->Qm;
|
||||
int rv_index = rdata->rv_index;
|
||||
int r_offset = rdata->r_offset;
|
||||
uint8_t kc = rdata->Kc;
|
||||
const int Kr = ulsch_harq->K;
|
||||
const int Kr_bytes = Kr >> 3;
|
||||
const int K_bits_F = Kr - ulsch_harq->F;
|
||||
const int r = rdata->segment_r;
|
||||
const int A = rdata->A;
|
||||
const int E = rdata->E;
|
||||
const int Qm = rdata->Qm;
|
||||
const int rv_index = rdata->rv_index;
|
||||
const int r_offset = rdata->r_offset;
|
||||
const uint8_t kc = rdata->Kc;
|
||||
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)));
|
||||
|
||||
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 *p_procTime = &procTime;
|
||||
|
||||
@@ -200,30 +186,26 @@ static void nr_processULSegment(void *arg)
|
||||
ulsch_harq->d_to_be_cleared[r] = false;
|
||||
|
||||
memset(ulsch_harq->c[r], 0, Kr_bytes);
|
||||
|
||||
if (ulsch_harq->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = ulsch_harq->B;
|
||||
} else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (ulsch_harq->B + 24 * ulsch_harq->C) / ulsch_harq->C;
|
||||
}
|
||||
|
||||
p_decoderParms->crc_type = crcType(ulsch_harq->C, A);
|
||||
p_decoderParms->block_length = lenWithCrc(ulsch_harq->C, A);
|
||||
// start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -233,73 +215,167 @@ static void nr_processULSegment(void *arg)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
|
||||
p_decoderParms->block_length = length_dec;
|
||||
p_decoderParms->crc_type = crc_type;
|
||||
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)pl, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
|
||||
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, l, llrProcBuf, p_procTime, &ulsch_harq->abort_decode);
|
||||
|
||||
if (rdata->decodeIterations <= p_decoderParms->numMaxIter)
|
||||
memcpy(ulsch_harq->c[r],llrProcBuf, Kr>>3);
|
||||
}
|
||||
|
||||
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;
|
||||
int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
|
||||
uint8_t ULSCH_id,
|
||||
short *ulsch_llr,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
t_nrLDPC_dec_params *decParams,
|
||||
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;
|
||||
int8_t llrProcBuf[22 * 384] __attribute__((aligned(32)));
|
||||
int16_t z_ol[68 * 384] __attribute__((aligned(32)));
|
||||
int8_t l_ol[68 * 384] __attribute__((aligned(32)));
|
||||
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;
|
||||
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);
|
||||
|
||||
decParams->R = nr_get_R_ldpc_decoder(pusch_pdu->pusch_data.rv_index,
|
||||
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, lenWithCrc(harq_process->C, A), crcType(harq_process->C, A))) {
|
||||
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;
|
||||
} 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, 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;
|
||||
}
|
||||
uint8_t dtx_det = 0;
|
||||
|
||||
int Kr;
|
||||
int Kr_bytes;
|
||||
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;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
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};
|
||||
decParams.BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
||||
int kc;
|
||||
if (decParams.BG == 2) {
|
||||
kc = 52;
|
||||
} else {
|
||||
kc = 68;
|
||||
}
|
||||
|
||||
const uint32_t A = (harq_process->TBS) << 3;
|
||||
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
|
||||
if (stats) {
|
||||
stats->frame = frame;
|
||||
@@ -314,219 +390,101 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
|
||||
}
|
||||
}
|
||||
if (A > 3824)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (B, C, K, Z, F)
|
||||
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,
|
||||
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 (C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
harq_process->B,
|
||||
lenWithCrc(1, A), // size in case of 1 segment
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z, // [hna] Z is Zc
|
||||
&harq_process->F,
|
||||
decParams.BG);
|
||||
|
||||
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*n_layers) {
|
||||
LOG_E(PHY,"nr_segmentation.c: too many segments %d, B %d\n",harq_process->C,harq_process->B);
|
||||
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, A %d\n", harq_process->C, A);
|
||||
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) {
|
||||
a_segments = a_segments*nb_rb;
|
||||
a_segments = a_segments/273 +1;
|
||||
}
|
||||
|
||||
if (harq_process->C > a_segments) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
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);
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
|
||||
decParams.Z = harq_process->Z;
|
||||
decParams.numMaxIter = ulsch->max_ldpc_iterations;
|
||||
decParams.outMode = 0;
|
||||
|
||||
if (harq_process->harq_to_be_cleared) {
|
||||
for (int r = 0; r < harq_process->C; r++)
|
||||
harq_process->d_to_be_cleared[r] = true;
|
||||
harq_process->harq_to_be_cleared = false;
|
||||
}
|
||||
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr >> 3;
|
||||
if (phy_vars_gNB->ldpc_offload_flag && mcs > 9)
|
||||
return decode_offload(phy_vars_gNB, ULSCH_id, ulsch_llr, pusch_pdu, &decParams, harq_pid, G);
|
||||
|
||||
uint32_t offset = 0;
|
||||
if (phy_vars_gNB->ldpc_offload_flag && mcs > 9) {
|
||||
int8_t llrProcBuf[22 * 384];
|
||||
// if (dtx_det==0) {
|
||||
int16_t z_ol[68 * 384];
|
||||
int8_t l_ol[68 * 384];
|
||||
int crc_type;
|
||||
int length_dec;
|
||||
|
||||
if (harq_process->C == 1) {
|
||||
if (A > 3824)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = harq_process->B;
|
||||
} else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (harq_process->B + 24 * harq_process->C) / harq_process->C;
|
||||
}
|
||||
int decodeIterations = 2;
|
||||
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);
|
||||
|
||||
if ((dtx_det == 0) && (pusch_pdu->pusch_data.rv_index == 0)) {
|
||||
// if (dtx_det==0){
|
||||
memcpy((&z_ol[0]), 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);
|
||||
|
||||
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));
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
uint32_t offset = 0, r_offset = 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 = decParams.BG == 2 ? 52 : 68;
|
||||
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 = harq_process->K >> 3;
|
||||
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 += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
}
|
||||
return harq_process->C;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||
|
||||
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
|
||||
@@ -116,10 +117,8 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
if (*num_seg_ok == harq_process->C) {
|
||||
if (harq_process->C > 1) {
|
||||
/* check global CRC */
|
||||
int A = tbs;
|
||||
int crc_length = A > 3824 ? 3 : 2;
|
||||
int crc_type = A > 3824 ? CRC24_A : CRC16;
|
||||
if (!check_crc(b, A + crc_length * 8, crc_type)) {
|
||||
// we have regrouped the transport block, so it is "1" segment
|
||||
if (!check_crc(b, lenWithCrc(1, tbs), crcType(1, tbs))) {
|
||||
harq_process->ack = 0;
|
||||
dlsch->last_iteration_cnt = dlsch->max_ldpc_iterations + 1;
|
||||
LOG_E(PHY, " Frame %d.%d LDPC global CRC fails, but individual LDPC CRC succeeded. %d segs\n", proc->frame_rx, proc->nr_slot_rx, harq_process->C);
|
||||
@@ -166,10 +165,8 @@ static void nr_processDLSegment(void *arg)
|
||||
NR_UE_DLSCH_t *dlsch = rdata->dlsch;
|
||||
NR_DL_UE_HARQ_t *harq_process= rdata->harq_process;
|
||||
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
|
||||
int length_dec;
|
||||
int Kr;
|
||||
int K_bits_F;
|
||||
uint8_t crc_type;
|
||||
int r = rdata->segment_r;
|
||||
int A = rdata->A;
|
||||
int E = rdata->E;
|
||||
@@ -240,19 +237,6 @@ static void nr_processDLSegment(void *arg)
|
||||
|
||||
LOG_D(PHY,"\n");
|
||||
}
|
||||
|
||||
if (harq_process->C == 1) {
|
||||
if (A > NR_MAX_PDSCH_TBS)
|
||||
crc_type = CRC24_A;
|
||||
else
|
||||
crc_type = CRC16;
|
||||
|
||||
length_dec = harq_process->B;
|
||||
} else {
|
||||
crc_type = CRC24_B;
|
||||
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
|
||||
}
|
||||
|
||||
{
|
||||
start_meas(&rdata->ts_ldpc_decode);
|
||||
//set first 2*Z_c bits to zeros
|
||||
@@ -272,9 +256,9 @@ static void nr_processDLSegment(void *arg)
|
||||
}
|
||||
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_IN);
|
||||
p_decoderParms->block_length=length_dec;
|
||||
nrLDPC_initcall(p_decoderParms, (int8_t*)&pl[0], LDPCoutput);
|
||||
p_decoderParms->crc_type = crc_type;
|
||||
p_decoderParms->block_length = lenWithCrc(harq_process->C, A);
|
||||
p_decoderParms->crc_type = crcType(harq_process->C, A);
|
||||
nrLDPC_initcall(p_decoderParms, (int8_t *)&pl[0], LDPCoutput);
|
||||
rdata->decodeIterations = nrLDPC_decoder(p_decoderParms, (int8_t *)&pl[0], LDPCoutput, &procTime, &harq_process->abort_decode);
|
||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
|
||||
|
||||
@@ -311,8 +295,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
// HARQ stats
|
||||
phy_vars_ue->dl_stats[harq_process->DLround]++;
|
||||
LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,dlsch->dlsch_config.rv);
|
||||
uint8_t kc;
|
||||
LOG_D(PHY, "Round %d RV idx %d\n", harq_process->DLround, dlsch->dlsch_config.rv);
|
||||
uint16_t nb_rb;// = 30;
|
||||
uint8_t dmrs_Type = dlsch->dlsch_config.dmrsConfigType;
|
||||
AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type);
|
||||
@@ -377,33 +360,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
LOG_D(PHY,"%d.%d DLSCH Decoding, harq_pid %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",
|
||||
frame,nr_slot_rx,harq_pid,A,A/8,G, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.mcs, dlsch->Nl, nb_symb_sch, nb_rb, dlsch->dlsch_config.qamModOrder, Coderate);
|
||||
|
||||
if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
|
||||
p_decParams->BG = 2;
|
||||
kc = 52;
|
||||
} else {
|
||||
p_decParams->BG = 1;
|
||||
kc = 68;
|
||||
}
|
||||
p_decParams->BG = get_BG(A, dlsch->dlsch_config.targetCodeRate);
|
||||
unsigned int kc = p_decParams->BG == 2 ? 52 : 68;
|
||||
|
||||
if (harq_process->first_rx == 1) {
|
||||
// This is a new packet, so compute quantities regarding segmentation
|
||||
if (A > NR_MAX_PDSCH_TBS)
|
||||
harq_process->B = A+24;
|
||||
else
|
||||
harq_process->B = A+16;
|
||||
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
harq_process->B,
|
||||
lenWithCrc(1, A), // We give a max size in case of 1 segment
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z, // [hna] Z is Zc
|
||||
&harq_process->F,
|
||||
p_decParams->BG);
|
||||
|
||||
|
||||
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*dlsch->Nl) {
|
||||
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, A %d\n", harq_process->C, A);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@ typedef struct {
|
||||
SCH_status_t status;
|
||||
/// Last TPC command
|
||||
uint8_t TPC;
|
||||
/// The payload + CRC size in bits, "B" from 36-212
|
||||
uint32_t B;
|
||||
/// Length of ACK information (bits)
|
||||
uint8_t O_ACK;
|
||||
/// Index of current HARQ round for this ULSCH
|
||||
@@ -117,8 +115,6 @@ typedef struct {
|
||||
uint8_t Ndi;
|
||||
/// DLSCH status flag indicating
|
||||
SCH_status_t status;
|
||||
/// The payload + CRC size in bits
|
||||
uint32_t B;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t **c;
|
||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
|
||||
@@ -92,8 +92,8 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
*/
|
||||
|
||||
int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers*1056;
|
||||
|
||||
if (A > 3824) {
|
||||
int B;
|
||||
if (A > NR_MAX_PDSCH_TBS) {
|
||||
// Add 24-bit crc (polynomial A) to payload
|
||||
crc = crc24a(harq_process->a,A)>>8;
|
||||
harq_process->a[A>>3] = ((uint8_t*)&crc)[2];
|
||||
@@ -102,13 +102,12 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
|
||||
|
||||
harq_process->B = A+24;
|
||||
B = A + 24;
|
||||
|
||||
AssertFatal((A/8)+4 <= max_payload_bytes,"A %d is too big (A/8+4 = %d > %d)\n",A,(A/8)+4,max_payload_bytes);
|
||||
|
||||
memcpy(harq_process->b,harq_process->a,(A/8)+4);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Add 16-bit crc (polynomial A) to payload
|
||||
crc = crc16(harq_process->a,A)>>16;
|
||||
harq_process->a[A>>3] = ((uint8_t*)&crc)[1];
|
||||
@@ -116,7 +115,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
//printf("CRC %x (A %d)\n",crc,A);
|
||||
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
|
||||
|
||||
harq_process->B = A+16;
|
||||
B = A + 16;
|
||||
|
||||
AssertFatal((A/8)+3 <= max_payload_bytes,"A %d is too big (A/8+3 = %d > %d)\n",A,(A/8)+3,max_payload_bytes);
|
||||
|
||||
@@ -128,26 +127,25 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
///////////////////////// b---->| block segmentation |---->c /////////////////////////
|
||||
///////////
|
||||
|
||||
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
|
||||
if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) {
|
||||
harq_process->BG = 2;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
harq_process->BG = 1;
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
|
||||
start_meas(&ue->ulsch_segmentation_stats);
|
||||
uint32_t Kb=nr_segmentation(harq_process->b,
|
||||
harq_process->c,
|
||||
harq_process->B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
pz,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
uint32_t Kb = nr_segmentation(harq_process->b,
|
||||
harq_process->c,
|
||||
B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
pz,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
|
||||
if (harq_process->C>MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*ulsch->pusch_pdu.nrOfLayers) {
|
||||
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, B);
|
||||
return(-1);
|
||||
}
|
||||
stop_meas(&ue->ulsch_segmentation_stats);
|
||||
@@ -169,7 +167,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
for (int r=0; r<harq_process->C; r++) {
|
||||
//channel_input[r] = &harq_process->d[r][0];
|
||||
#ifdef DEBUG_ULSCH_CODING
|
||||
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
|
||||
printf("Encoder: B %d F %d \n", B, harq_process->F);
|
||||
printf("start ldpc encoder segment %d/%d\n",r,harq_process->C);
|
||||
printf("input %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int cnt =0 ; cnt < 22*(*pz)/8; cnt ++){
|
||||
|
||||
+12
-4
@@ -75,8 +75,6 @@ typedef struct {
|
||||
nfapi_nr_dl_tti_pdsch_pdu pdsch_pdu;
|
||||
/// pointer to pdu from MAC interface (this is "a" in 36.212)
|
||||
uint8_t *pdu;
|
||||
/// The payload + CRC size in bits, "B" from 36-212
|
||||
uint32_t B;
|
||||
/// Pointer to the payload
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
@@ -199,8 +197,6 @@ typedef struct {
|
||||
uint32_t TBS;
|
||||
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
|
||||
uint8_t *b;
|
||||
/// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1)
|
||||
uint32_t B;
|
||||
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
|
||||
uint8_t **c;
|
||||
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
|
||||
@@ -227,6 +223,18 @@ typedef struct {
|
||||
int llrLen;
|
||||
//////////////////////////////////////////////////////////////
|
||||
} NR_UL_gNB_HARQ_t;
|
||||
static inline int lenWithCrc(int nbSeg, int len)
|
||||
{
|
||||
if (nbSeg > 1)
|
||||
return (len + 24 + 24 * nbSeg) / nbSeg;
|
||||
return len + (len > NR_MAX_PDSCH_TBS ? 24 : 16);
|
||||
}
|
||||
static inline int crcType(int nbSeg, int len)
|
||||
{
|
||||
if (nbSeg > 1)
|
||||
return CRC24_B;
|
||||
return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
//! estimated received spatial signal power (linear)
|
||||
|
||||
@@ -266,12 +266,7 @@ static void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req)
|
||||
// CRC check made by the LDPC for early termination, so, no need to perform CRC check twice for a single code block
|
||||
bool crc_valid = true;
|
||||
if (ulsch_harq->C > 1) {
|
||||
// Check ULSCH transport block CRC
|
||||
int crc_type = CRC16;
|
||||
if (rdata->A > 3824) {
|
||||
crc_type = CRC24_A;
|
||||
}
|
||||
crc_valid = check_crc(ulsch_harq->b, ulsch_harq->B, crc_type);
|
||||
crc_valid = check_crc(ulsch_harq->b, lenWithCrc(1, rdata->A), crcType(1, rdata->A));
|
||||
}
|
||||
|
||||
if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !gNB->pusch_vars[rdata->ulsch_id].DTX) {
|
||||
@@ -941,7 +936,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);
|
||||
}
|
||||
}
|
||||
if (totalDecode > 0 && gNB->ldpc_offload_flag == 0) {
|
||||
while (totalDecode > 0) {
|
||||
notifiedFIFO_elt_t *req = pullTpool(&gNB->respDecode, &gNB->threadPool);
|
||||
if (req == NULL)
|
||||
@@ -950,7 +944,6 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
|
||||
delNotifiedFIFO_elt(req);
|
||||
totalDecode--;
|
||||
}
|
||||
}
|
||||
stop_meas(&gNB->ulsch_decoding_stats);
|
||||
for (int i = 0; i < gNB->max_nb_srs; i++) {
|
||||
NR_gNB_SRS_t *srs = &gNB->srs[i];
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define INDEX_MAX_TBS_TABLE (93)
|
||||
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "openair1/PHY/defs_nr_common.h"
|
||||
#include <math.h>
|
||||
|
||||
//Table 5.1.2.2-2
|
||||
@@ -64,7 +65,7 @@ uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
uint32_t nr_tbs=0;
|
||||
uint32_t Np_info, C, n;
|
||||
|
||||
if (Ninfo <=3824) {
|
||||
if (Ninfo <= NR_MAX_PDSCH_TBS) {
|
||||
n = max(3, floor(log2(Ninfo)) - 6);
|
||||
Np_info = max(24, (Ninfo>>n)<<n);
|
||||
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
|
||||
@@ -123,7 +124,7 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
// Intermediate number of information bits
|
||||
Ninfo = (nb_re * R * Qm * Nl)>>10;
|
||||
|
||||
if (Ninfo <=3824) {
|
||||
if (Ninfo <= NR_MAX_PDSCH_TBS) {
|
||||
n = max(3, floor(log2(Ninfo)) - 6);
|
||||
Np_info = max(24, (Ninfo>>n)<<n);
|
||||
for (int i=0; i<INDEX_MAX_TBS_TABLE; i++) {
|
||||
@@ -132,8 +133,7 @@ uint32_t nr_compute_tbslbrm(uint16_t table,
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
n = log2(Ninfo-24)-5;
|
||||
Np_info = max(3840, (ROUNDIDIV((Ninfo-24),(1<<n)))<<n);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "openair1/PHY/defs_nr_common.h"
|
||||
#include <limits.h>
|
||||
#include <executables/softmodem-common.h>
|
||||
|
||||
@@ -4080,7 +4081,7 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep,
|
||||
uint8_t get_BG(uint32_t A, uint16_t R) {
|
||||
|
||||
float code_rate = (float) R / 10240.0f;
|
||||
if ((A <=292) || ((A<=3824) && (code_rate <= 0.6667)) || code_rate <= 0.25)
|
||||
if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (code_rate <= 0.6667)) || code_rate <= 0.25)
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user