Separate segmentation from ULSCH encoding function

Segmentation have to be called before UCI mapping to get number of
segments and sumKr values.
This commit is contained in:
Sakthivel Velumani
2025-09-26 11:16:54 +08:00
committed by alexjiao
parent ceda9c1141
commit 5f3a19cb7d
5 changed files with 92 additions and 75 deletions
@@ -95,6 +95,13 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
int nb_dlsch, int nb_dlsch,
uint8_t *DLSCH_ids); uint8_t *DLSCH_ids);
int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
const NR_UE_ULSCH_t *ulsch,
const uint32_t frame,
const uint8_t slot,
const unsigned int *G,
const int nb_ulsch,
const uint8_t *ULSCH_ids);
/** \brief This is the alternative top-level entry point for ULSCH encoding in UE. /** \brief This is the alternative top-level entry point for ULSCH encoding in UE.
It handles all the HARQ processes in only one call. The routine first It handles all the HARQ processes in only one call. The routine first
computes the segmentation information, followed by LDPC encoding algorithm of the computes the segmentation information, followed by LDPC encoding algorithm of the
@@ -55,6 +55,8 @@ typedef struct {
uint32_t C; uint32_t C;
/// Number of bits in code segments /// Number of bits in code segments
uint32_t K; uint32_t K;
///
uint32_t Kb;
/// Number of "Filler" bits /// Number of "Filler" bits
uint32_t F; uint32_t F;
/// Number of soft channel bits /// Number of soft channel bits
+79 -74
View File
@@ -34,56 +34,27 @@
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/log_tools.h" #include "PHY/log_tools.h"
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch, const NR_UE_ULSCH_t *ulsch,
const uint32_t frame, const uint32_t frame,
const uint8_t slot, const uint8_t slot,
unsigned int *G, const unsigned int *G,
int nb_ulsch, const int nb_ulsch,
uint8_t *ULSCH_ids, const uint8_t *ULSCH_ids)
uint16_t number_dmrs_symbols)
{ {
start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS); for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN); const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
nrLDPC_TB_encoding_parameters_t TBs[nb_ulsch];
memset(TBs, 0, sizeof(TBs));
nrLDPC_slot_encoding_parameters_t slot_parameters = {
.frame = frame,
.slot = slot,
.nb_TBs = nb_ulsch,
.threadPool = &get_nrUE_params()->Tpool,
.tinput = NULL,
.tprep = NULL,
.tparity = NULL,
.toutput = NULL,
.TBs = TBs
};
int max_num_segments = 0;
for (uint8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id];
/* Neither harq_pid nor ULSCH_id are unique in the instance
* but their combination is.
* Since ULSCH_id < 2
* then 2 * harq_pid + ULSCH_id is unique.
*/
TB_parameters->harq_unique_pid = 2 * harq_pid + ULSCH_id;
/////////////////////////parameters and variables initialization///////////////////////// /////////////////////////parameters and variables initialization/////////////////////////
unsigned int crc = 1;
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid]; NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu; const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu;
uint16_t nb_rb = pusch_pdu->rb_size; const uint16_t nb_rb = pusch_pdu->rb_size;
uint32_t A = pusch_pdu->pusch_data.tb_size << 3; const uint32_t A = pusch_pdu->pusch_data.tb_size << 3;
uint8_t Qm = pusch_pdu->qam_mod_order; const uint8_t Qm = pusch_pdu->qam_mod_order;
// target_code_rate is in 0.1 units // target_code_rate is in 0.1 units
float Coderate = (float)pusch_pdu->target_code_rate / 10240.0f; const float Coderate = (float)pusch_pdu->target_code_rate / 10240.0f;
LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, pusch_pdu->nrOfLayers); LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, pusch_pdu->nrOfLayers);
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G[pusch_id], Qm, Coderate); LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G[pusch_id], Qm, Coderate);
@@ -91,11 +62,11 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
///////////////////////// a---->| add CRC |---->b ///////////////////////// ///////////////////////// a---->| add CRC |---->b /////////////////////////
int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers * 1056; const int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers * 1056;
int B; int B;
if (A > NR_MAX_PDSCH_TBS) { if (A > NR_MAX_PDSCH_TBS) {
// Add 24-bit crc (polynomial A) to payload // Add 24-bit crc (polynomial A) to payload
crc = crc24a(harq_process->payload_AB, A) >> 8; const unsigned int crc = crc24a(harq_process->payload_AB, A) >> 8;
harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[2]; harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[2];
harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[1]; harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[1];
harq_process->payload_AB[2 + (A >> 3)] = ((uint8_t *)&crc)[0]; harq_process->payload_AB[2 + (A >> 3)] = ((uint8_t *)&crc)[0];
@@ -103,7 +74,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
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); 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);
} else { } else {
// Add 16-bit crc (polynomial A) to payload // Add 16-bit crc (polynomial A) to payload
crc = crc16(harq_process->payload_AB, A) >> 16; const unsigned int crc = crc16(harq_process->payload_AB, A) >> 16;
harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[1]; harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[1];
harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[0]; harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[0];
B = A + 16; B = A + 16;
@@ -151,7 +122,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
T_INT((int)ulsch->pusch_pdu.transform_precoding), // transformPrecoder_enabled = 0, transformPrecoder_disabled = 1 T_INT((int)ulsch->pusch_pdu.transform_precoding), // transformPrecoder_enabled = 0, transformPrecoder_disabled = 1
T_INT((int)ulsch->pusch_pdu.dmrs_config_type), // dmrs_resource_map_config: pusch_dmrs_type1 = 0, pusch_dmrs_type2 = 1 T_INT((int)ulsch->pusch_pdu.dmrs_config_type), // dmrs_resource_map_config: pusch_dmrs_type1 = 0, pusch_dmrs_type2 = 1
T_INT((int)ulsch->pusch_pdu.ul_dmrs_symb_pos), // used to derive the DMRS symbol positions T_INT((int)ulsch->pusch_pdu.ul_dmrs_symb_pos), // used to derive the DMRS symbol positions
T_INT((int)number_dmrs_symbols), T_INT((int)get_num_dmrs(ulsch->pusch_pdu.ul_dmrs_symb_pos)),
// dmrs_start_ofdm_symbol // dmrs_start_ofdm_symbol
// dmrs_duration_num_ofdm_symbols // dmrs_duration_num_ofdm_symbols
// dmrs_num_add_positions // dmrs_num_add_positions
@@ -168,36 +139,55 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
start_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS); start_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS);
TB_parameters->Kb = nr_segmentation(harq_process->payload_AB, harq_process->Kb = nr_segmentation(harq_process->payload_AB,
harq_process->c, harq_process->c,
B, B,
&harq_process->C, &harq_process->C,
&harq_process->K, &harq_process->K,
&harq_process->Z, &harq_process->Z,
&harq_process->F, &harq_process->F,
harq_process->BG); harq_process->BG);
TB_parameters->C = harq_process->C; if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers) {
TB_parameters->K = harq_process->K; LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", harq_process->C, B);
TB_parameters->Z = harq_process->Z;
TB_parameters->F = harq_process->F;
TB_parameters->BG = harq_process->BG;
if (TB_parameters->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers) {
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B);
return (-1); return (-1);
} }
stop_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS); stop_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
max_num_segments = max(max_num_segments, TB_parameters->C);
TB_parameters->nb_rb = nb_rb;
TB_parameters->Qm = Qm;
TB_parameters->mcs = pusch_pdu->mcs_index;
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
TB_parameters->G = G[pusch_id];
TB_parameters->tbslbrm = pusch_pdu->tbslbrm;
TB_parameters->A = A;
} // pusch_id } // pusch_id
return 0;
}
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
const uint32_t frame,
const uint8_t slot,
unsigned int *G,
int nb_ulsch,
uint8_t *ULSCH_ids,
uint16_t number_dmrs_symbols)
{
start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
nrLDPC_TB_encoding_parameters_t TBs[nb_ulsch];
memset(TBs, 0, sizeof(TBs));
nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
.slot = slot,
.nb_TBs = nb_ulsch,
.threadPool = &get_nrUE_params()->Tpool,
.tinput = NULL,
.tprep = NULL,
.tparity = NULL,
.toutput = NULL,
.TBs = TBs};
int max_num_segments = 0;
for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
max_num_segments = max(max_num_segments, harq_process->C);
}
nrLDPC_segment_encoding_parameters_t segments[nb_ulsch][max_num_segments]; nrLDPC_segment_encoding_parameters_t segments[nb_ulsch][max_num_segments];
memset(segments, 0, sizeof(segments)); memset(segments, 0, sizeof(segments));
@@ -208,10 +198,25 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id]; nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id];
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid]; NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch[ULSCH_id].pusch_pdu;
const uint16_t nb_rb = pusch_pdu->rb_size;
TB_parameters->harq_unique_pid = 2 * harq_pid + ULSCH_id;
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->BG = harq_process->BG;
TB_parameters->Kb = harq_process->Kb;
TB_parameters->nb_rb = nb_rb;
TB_parameters->Qm = pusch_pdu->qam_mod_order;
TB_parameters->mcs = pusch_pdu->mcs_index;
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
TB_parameters->G = G[pusch_id];
TB_parameters->tbslbrm = pusch_pdu->tbslbrm;
TB_parameters->A = pusch_pdu->pusch_data.tb_size / 8;
TB_parameters->segments = segments[pusch_id]; TB_parameters->segments = segments[pusch_id];
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu;
uint16_t nb_rb = pusch_pdu->rb_size;
memset(harq_process->f, 0, 14 * nb_rb * 12 * 16); memset(harq_process->f, 0, 14 * nb_rb * 12 * 16);
TB_parameters->output = harq_process->f; TB_parameters->output = harq_process->f;
+3 -1
View File
@@ -1092,7 +1092,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////ULSCH coding///////////////////////// /////////////////////////ULSCH coding/////////////////////////
if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids, number_dmrs_symbols) == -1) { int enc_ret = nr_ulsch_pre_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids);
enc_ret += nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids, number_dmrs_symbols);
if (enc_ret != 0) {
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
return; return;
} }
+1
View File
@@ -513,6 +513,7 @@ int main(int argc, char **argv)
if (input_fd == NULL) { if (input_fd == NULL) {
uint8_t ULSCH_ids[] = {0}; uint8_t ULSCH_ids[] = {0};
nr_ulsch_pre_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids);
nr_ulsch_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids, 0); nr_ulsch_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids, 0);
} }