Merge remote-tracking branch 'origin/nrLDPC_coding_improvements_2' into integration_2025_w02 (!3187)

nrLDPC_coding: Fix naming, comments, superfluous variables and documentation typos in coding library interfaces

This MR is clarifying the interfaces to the LDPC coding libraries.  It
aims to improve the readability of the interfaces and compliance of
naming with specification 38.212.
This commit is contained in:
Robert Schmidt
2025-01-10 18:00:35 +01:00
10 changed files with 139 additions and 153 deletions
@@ -20,9 +20,8 @@
*/
/*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c
* \brief Top-level routines for decoding LDPC transport channels
*/
* \brief Top-level routines for decoding LDPC transport channels
*/
// [from gNB coding]
#include "nr_rate_matching.h"
@@ -46,10 +45,10 @@
#include <stdint.h>
#include <syscall.h>
#include <time.h>
//#define gNB_DEBUG_TRACE
// #define gNB_DEBUG_TRACE
#define OAI_LDPC_DECODER_MAX_NUM_LLR 27000 //26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
//#define DEBUG_CRC
#define OAI_LDPC_DECODER_MAX_NUM_LLR 27000 // 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
// #define DEBUG_CRC
#ifdef DEBUG_CRC
#define PRINT_CRC_CHECK(a) a
#else
@@ -65,7 +64,8 @@
* \brief decoding parameter of transport blocks
* \var decoderParms decoder parameters
* \var Qm modulation order
* \var Kc size of base graph input
* \var Kc ratio between the number of columns in the parity check matrix and the lifting size
* it is fixed for a given base graph while the lifting size is chosen to have a sufficient number of columns
* \var rv_index
* \var max_number_iterations maximum number of LDPC iterations
* \var abort_decode pointer to decode abort flag
@@ -76,7 +76,7 @@
* \var F filler bits size
* \var r segment index in TB
* \var E input llr segment size
* \var C number of segments
* \var C number of segments
* \var llr input llr segment array
* \var d Pointers to code blocks before LDPC decoding (38.212 V15.4.0 section 5.3.2)
* \var d_to_be_cleared
@@ -89,8 +89,7 @@
* \var p_ts_rate_unmatch pointer to rate unmatching time stats
* \var p_ts_ldpc_decode pointer to decoding time stats
*/
typedef struct nrLDPC_decoding_parameters_s{
typedef struct nrLDPC_decoding_parameters_s {
t_nrLDPC_dec_params decoderParms;
uint8_t Qm;
@@ -128,14 +127,13 @@ static void nr_process_decode_segment(void *arg)
{
nrLDPC_decoding_parameters_t *rdata = (nrLDPC_decoding_parameters_t *)arg;
t_nrLDPC_dec_params *p_decoderParms = &rdata->decoderParms;
const int Kr = rdata->K;
const int Kr_bytes = Kr >> 3;
const int K_bits_F = Kr - rdata->F;
const int K = rdata->K;
const int Kprime = K - rdata->F;
const int A = rdata->A;
const int E = rdata->E;
const int Qm = rdata->Qm;
const int rv_index = rdata->rv_index;
const uint8_t kc = rdata->Kc;
const uint8_t Kc = rdata->Kc;
short *ulsch_llr = rdata->llr;
int8_t llrProcBuf[OAI_LDPC_DECODER_MAX_NUM_LLR] __attribute__((aligned(32)));
@@ -167,7 +165,6 @@ static void nr_process_decode_segment(void *arg)
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
if (nr_rate_matching_ldpc_rx(rdata->tbslbrm,
p_decoderParms->BG,
p_decoderParms->Z,
@@ -178,9 +175,8 @@ static void nr_process_decode_segment(void *arg)
*rdata->d_to_be_cleared,
E,
rdata->F,
Kr - rdata->F - 2 * (p_decoderParms->Z))
K - rdata->F - 2 * (p_decoderParms->Z))
== -1) {
stop_meas(rdata->p_ts_rate_unmatch);
LOG_E(PHY, "nrLDPC_coding_segment_decoder.c: Problem in rate_matching\n");
@@ -192,9 +188,8 @@ static void nr_process_decode_segment(void *arg)
*rdata->d_to_be_cleared = false;
memset(rdata->c, 0, Kr_bytes);
p_decoderParms->crc_type = crcType(rdata->C, A);
p_decoderParms->E = lenWithCrc(rdata->C, A);
p_decoderParms->Kprime = lenWithCrc(rdata->C, A);
// set first 2*Z_c bits to zeros
@@ -204,16 +199,16 @@ static void nr_process_decode_segment(void *arg)
memset(z, 0, 2 * rdata->Z * sizeof(*z));
// set Filler bits
memset(z + K_bits_F, 127, rdata->F * sizeof(*z));
memset(z + Kprime, 127, rdata->F * sizeof(*z));
// Move coded bits before filler bits
memcpy(z + 2 * rdata->Z, rdata->d, (K_bits_F - 2 * rdata->Z) * sizeof(*z));
memcpy(z + 2 * rdata->Z, rdata->d, (Kprime - 2 * rdata->Z) * sizeof(*z));
// skip filler bits
memcpy(z + Kr, rdata->d + (Kr - 2 * rdata->Z), (kc * rdata->Z - Kr) * sizeof(*z));
memcpy(z + K, rdata->d + (K - 2 * rdata->Z), (Kc * rdata->Z - K) * sizeof(*z));
// Saturate coded bits before decoding into 8 bits values
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 * rdata->Z) >> 4) + 1; i += 2, j++) {
for (int i = 0, j = 0; j < ((Kc * rdata->Z) >> 4) + 1; i += 2, j++) {
pl[j] = simde_mm_packs_epi16(pv[i], pv[i + 1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -227,9 +222,10 @@ static void nr_process_decode_segment(void *arg)
ldpc_interface_segment.LDPCdecoder(p_decoderParms, 0, 0, 0, l, llrProcBuf, p_procTime, rdata->abort_decode);
if (decodeIterations <= p_decoderParms->numMaxIter) {
memcpy(rdata->c,llrProcBuf, Kr>>3);
memcpy(rdata->c, llrProcBuf, K >> 3);
*rdata->decodeSuccess = true;
} else {
memset(rdata->c, 0, K >> 3);
*rdata->decodeSuccess = false;
}
stop_meas(rdata->p_ts_ldpc_decode);
@@ -238,9 +234,10 @@ static void nr_process_decode_segment(void *arg)
completed_task_ans(rdata->ans);
}
int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int pusch_id, thread_info_tm_t *t_info)
int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters,
int pusch_id,
thread_info_tm_t *t_info)
{
nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id];
*nrLDPC_TB_decoding_parameters->processedSegments = 0;
@@ -251,14 +248,12 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
decParams.outMode = 0;
for (int r = 0; r < nrLDPC_TB_decoding_parameters->C; r++) {
nrLDPC_decoding_parameters_t *rdata = &((nrLDPC_decoding_parameters_t *)t_info->buf)[t_info->len];
DevAssert(t_info->len < t_info->cap);
rdata->ans = &t_info->ans[t_info->len];
t_info->len += 1;
decParams.R = nrLDPC_TB_decoding_parameters->segments[r].R;
decParams.setCombIn = !nrLDPC_TB_decoding_parameters->segments[r].d_to_be_cleared;
rdata->decoderParms = decParams;
rdata->llr = nrLDPC_TB_decoding_parameters->segments[r].llr;
rdata->Kc = decParams.BG == 2 ? 52 : 68;
@@ -288,29 +283,26 @@ int nrLDPC_prepare_TB_decoding(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_de
return nrLDPC_TB_decoding_parameters->C;
}
int32_t nrLDPC_coding_init(void){
int32_t nrLDPC_coding_init(void)
{
char *segment_shlibversion = NULL;
paramdef_t LoaderParams[] = {
{"segment_shlibversion", NULL, 0, .strptr = &segment_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL}
};
{"segment_shlibversion", NULL, 0, .strptr = &segment_shlibversion, .defstrval = "_optim8segmulti", TYPE_STRING, 0, NULL}};
config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_segment");
load_LDPClib(segment_shlibversion, &ldpc_interface_segment);
return 0;
}
int32_t nrLDPC_coding_shutdown(void){
int32_t nrLDPC_coding_shutdown(void)
{
free_LDPClib(&ldpc_interface_segment);
return 0;
}
int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters){
int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters)
{
int nbSegments = 0;
for (int pusch_id = 0; pusch_id < nrLDPC_slot_decoding_parameters->nb_TBs; pusch_id++) {
nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[pusch_id];
@@ -340,6 +332,4 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
}
}
return 0;
}
@@ -20,8 +20,8 @@
*/
/*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c
* \brief Top-level routines for implementing LDPC encoding of transport channels
*/
* \brief Top-level routines for implementing LDPC encoding of transport channels
*/
#include "nr_rate_matching.h"
#include "PHY/defs_gNB.h"
@@ -41,8 +41,8 @@
#include <syscall.h>
//#define DEBUG_LDPC_ENCODING
//#define DEBUG_LDPC_ENCODING_FREE 1
// #define DEBUG_LDPC_ENCODING
// #define DEBUG_LDPC_ENCODING_FREE 1
extern ldpc_interface_t ldpc_interface_segment;
@@ -62,35 +62,34 @@ static void ldpc8blocks_coding_segment(void *p)
uint32_t A = nrLDPC_TB_encoding_parameters->A;
unsigned int G = nrLDPC_TB_encoding_parameters->G;
LOG_D(PHY,"dlsch coding A %d Kr %d G %d (nb_rb %d, mod_order %d)\n",
A,impp->K,G, nb_rb,(int)mod_order);
LOG_D(PHY, "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp->K, G, nb_rb, (int)mod_order);
// nrLDPC_encoder output is in "d"
// let's make this interface happy!
uint8_t tmp[8][68 * 384]__attribute__((aligned(32)));
uint8_t tmp[8][68 * 384] __attribute__((aligned(32)));
uint8_t *d[impp->n_segments];
for (int rr=impp->macro_num*8, i=0; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++,i++ )
for (int rr = impp->macro_num * 8, i = 0; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++, i++)
d[rr] = tmp[i];
uint8_t *c[nrLDPC_TB_encoding_parameters->C];
for (int r = 0; r < nrLDPC_TB_encoding_parameters->C; r++)
c[r]=nrLDPC_TB_encoding_parameters->segments[r].c;
start_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode);
c[r] = nrLDPC_TB_encoding_parameters->segments[r].c;
start_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num * 8].ts_ldpc_encode);
ldpc_interface_segment.LDPCencoder(c, d, impp);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num*8].ts_ldpc_encode);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[impp->macro_num * 8].ts_ldpc_encode);
// Compute where to place in output buffer that is concatenation of all segments
uint32_t r_offset=0;
for (int i=0; i < impp->macro_num*8; i++ )
r_offset+=nrLDPC_TB_encoding_parameters->segments[i].E;
for (int rr=impp->macro_num*8; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++ ) {
if (impp->F>0) {
uint32_t r_offset = 0;
for (int i = 0; i < impp->macro_num * 8; i++)
r_offset += nrLDPC_TB_encoding_parameters->segments[i].E;
for (int rr = impp->macro_num * 8; rr < impp->n_segments && rr < (impp->macro_num + 1) * 8; rr++) {
if (impp->F > 0) {
// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
memset(&d[rr][impp->K - impp->F - 2 * impp->Zc], NR_NULL, impp->F);
}
#ifdef DEBUG_LDPC_ENCODING
LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
LOG_D(PHY, "rvidx in encoding = %d\n", rel15->rvIndex[0]);
#endif
uint32_t E = nrLDPC_TB_encoding_parameters->segments[rr].E;
LOG_D(NR_PHY,
@@ -109,7 +108,7 @@ static void ldpc8blocks_coding_segment(void *p)
uint32_t Tbslbrm = nrLDPC_TB_encoding_parameters->tbslbrm;
uint8_t e[E];
bzero (e, E);
bzero(e, E);
start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match);
nr_rate_matching_ldpc(Tbslbrm,
impp->BG,
@@ -123,16 +122,10 @@ static void ldpc8blocks_coding_segment(void *p)
E);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_rate_match);
if (impp->K - impp->F - 2 * impp->Zc > E) {
LOG_E(PHY,
"dlsch coding A %d Kr %d G %d (nb_rb %d, mod_order %d)\n",
A,
impp->K,
G,
nb_rb,
(int)mod_order);
LOG_E(PHY, "dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n", A, impp->K, G, nb_rb, (int)mod_order);
LOG_E(NR_PHY,
"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Kr %d, Filler bits %d, Filler offset %d mod_order %d, "
"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, K %d, Filler bits %d, Filler offset %d mod_order %d, "
"nb_rb %d)...\n",
rr,
impp->n_segments,
@@ -146,23 +139,20 @@ static void ldpc8blocks_coding_segment(void *p)
}
#ifdef DEBUG_LDPC_ENCODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i,e[i], r_offset);
for (int i = 0; i < 16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i, e[i], r_offset);
#endif
start_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave);
nr_interleaving_ldpc(E,
mod_order,
e,
impp->output+r_offset);
nr_interleaving_ldpc(E, mod_order, e, impp->output + r_offset);
stop_meas(&nrLDPC_TB_encoding_parameters->segments[rr].ts_interleave);
#ifdef DEBUG_LDPC_ENCODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %u\n", i,impp->output[i+r_offset], r_offset);
for (int i = 0; i < 16; i++)
printf("output interleaving f[%d]= %d r_offset %u\n", i, impp->output[i + r_offset], r_offset);
if (r==impp->n_segments-1)
write_output("enc_output.m","enc",impp->output,G,1,4);
if (r == impp->n_segments - 1)
write_output("enc_output.m", "enc", impp->output, G, 1, 4);
#endif
r_offset += E;
@@ -172,7 +162,9 @@ static void ldpc8blocks_coding_segment(void *p)
completed_task_ans(impp->ans);
}
static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, int dlsch_id, thread_info_tm_t *t_info)
static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters,
int dlsch_id,
thread_info_tm_t *t_info)
{
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
@@ -212,7 +204,6 @@ static int nrLDPC_prepare_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_
int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
{
int nbTasks = 0;
for (int dlsch_id = 0; dlsch_id < nrLDPC_slot_encoding_parameters->nb_TBs; dlsch_id++) {
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[dlsch_id];
@@ -235,5 +226,4 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
join_task_ans(ans, nbEncode);
return 0;
}