fix(nrLDPC_coding): cleanup the naming of the K, Kprime and Zc variables to comply with the standard 38.212-5.2.2
This commit is contained in:
@@ -259,7 +259,7 @@ one_measurement_t test_ldpc(short max_iterations,
|
||||
printf("To: %d\n", (Kb + nrows - no_punctured_columns) * Zc - removed_bit);
|
||||
printf("number of undecoded bits: %d\n", (Kb + nrows - no_punctured_columns - 2) * Zc - removed_bit);
|
||||
|
||||
encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .Kr = block_length, .K = block_length};
|
||||
encoder_implemparams_t impp = {.Zc = Zc, .Kb = Kb, .BG = BG, .K = block_length};
|
||||
impp.gen_code = 2;
|
||||
|
||||
if (ntrials==0)
|
||||
|
||||
@@ -173,7 +173,7 @@ typedef struct nrLDPC_segment_encoding_parameters_s{
|
||||
* \var G Available radio resource bits
|
||||
* \var tbslbrm Transport block size LBRM
|
||||
* \var A Transport block size (This is A from 38.212 V15.4.0 section 5.1)
|
||||
* \var Kb Code block size divided by lifting size
|
||||
* \var Kb Number of time the lifting size needed to fit the payload of a code block
|
||||
* \var K Code block size at input of encoder
|
||||
* \var Z lifting size
|
||||
* \var F filler bits size
|
||||
|
||||
+12
-12
@@ -64,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
|
||||
@@ -127,14 +128,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)));
|
||||
|
||||
@@ -177,7 +177,7 @@ 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);
|
||||
@@ -191,7 +191,7 @@ static void nr_process_decode_segment(void *arg)
|
||||
|
||||
*rdata->d_to_be_cleared = false;
|
||||
|
||||
memset(rdata->c, 0, Kr_bytes);
|
||||
memset(rdata->c, 0, K >> 3);
|
||||
p_decoderParms->crc_type = crcType(rdata->C, A);
|
||||
p_decoderParms->Kprime = lenWithCrc(rdata->C, A);
|
||||
|
||||
@@ -203,16 +203,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]);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -226,7 +226,7 @@ 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 {
|
||||
*rdata->decodeSuccess = false;
|
||||
|
||||
+3
-3
@@ -61,7 +61,7 @@ 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",
|
||||
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"
|
||||
@@ -123,7 +123,7 @@ static void ldpc8blocks_coding_segment(void *p)
|
||||
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",
|
||||
"dlsch coding A %d K %d G %d (nb_rb %d, mod_order %d)\n",
|
||||
A,
|
||||
impp->K,
|
||||
G,
|
||||
@@ -131,7 +131,7 @@ static void ldpc8blocks_coding_segment(void *p)
|
||||
(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,
|
||||
|
||||
@@ -83,8 +83,8 @@ typedef struct args_fpga_decode_prepare_s {
|
||||
uint32_t r_span; /*!< number of blocks to be prepared within this function */
|
||||
int r_offset; /*!< r index expressed in bits */
|
||||
int input_CBoffset; /*!< */
|
||||
int kc; /*!< */
|
||||
int K_bits_F; /*!< */
|
||||
int Kc; /*!< ratio between the number of columns in the parity check graph and the lifting size */
|
||||
int Kprime; /*!< size of payload and CRC bits in a code block */
|
||||
task_ans_t *ans; /*!< pointer to the answer that is used by thread pool to detect job completion */
|
||||
} args_fpga_decode_prepare_t;
|
||||
|
||||
@@ -143,11 +143,10 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
int slot_rx,
|
||||
tpool_t *ldpc_threadPool)
|
||||
{
|
||||
const uint32_t Kr = TB_params->K;
|
||||
const uint32_t Kr_bytes = Kr >> 3;
|
||||
const int kc = TB_params->BG == 2 ? 52 : 68;
|
||||
const uint32_t K = TB_params->K;
|
||||
const int Kc = TB_params->BG == 2 ? 52 : 68;
|
||||
int r_offset = 0, offset = 0;
|
||||
int K_bits_F = Kr - TB_params->F;
|
||||
int Kprime = K - TB_params->F;
|
||||
|
||||
// FPGA parameter preprocessing
|
||||
static uint8_t multi_indata[27000 * 25]; // FPGA input data
|
||||
@@ -156,7 +155,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
int bg_len = TB_params->BG == 1 ? 22 : 10;
|
||||
|
||||
// Calc input CB offset
|
||||
int input_CBoffset = TB_params->Z * kc * 8;
|
||||
int input_CBoffset = TB_params->Z * Kc * 8;
|
||||
if ((input_CBoffset & 0x7F) == 0)
|
||||
input_CBoffset = input_CBoffset / 8;
|
||||
else
|
||||
@@ -168,7 +167,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
dec_conf.max_iter = TB_params->max_ldpc_iterations;
|
||||
dec_conf.numCB = TB_params->C;
|
||||
// input soft bits length, Zc x 66 - length of filler bits
|
||||
dec_conf.numChannelLls = (K_bits_F - 2 * TB_params->Z) + (kc * TB_params->Z - Kr);
|
||||
dec_conf.numChannelLls = (Kprime - 2 * TB_params->Z) + (Kc * TB_params->Z - K);
|
||||
// filler bits length
|
||||
dec_conf.numFillerBits = TB_params->F;
|
||||
dec_conf.max_schedule = 0;
|
||||
@@ -196,11 +195,11 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
printf("TB_params->F: %d\n", TB_params->F);
|
||||
printf("numChannelLls:\t %d = (%d - 2 * %d) + (%d * %d - %d)\n",
|
||||
dec_conf.numChannelLls,
|
||||
K_bits_F,
|
||||
Kprime,
|
||||
TB_params->Z,
|
||||
kc,
|
||||
Kc,
|
||||
TB_params->Z,
|
||||
Kr);
|
||||
K);
|
||||
printf("numFillerBits:\t %d\n", TB_params->F);
|
||||
printf("------------------------\n");
|
||||
// ===================================
|
||||
@@ -265,8 +264,8 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
args->r_span = r_span;
|
||||
args->r_offset = r_offset;
|
||||
args->input_CBoffset = input_CBoffset;
|
||||
args->kc = kc;
|
||||
args->K_bits_F = K_bits_F;
|
||||
args->Kc = Kc;
|
||||
args->Kprime = Kprime;
|
||||
|
||||
r_remaining = r_span;
|
||||
|
||||
@@ -276,7 +275,7 @@ int decoder_xdma(nrLDPC_TB_decoding_parameters_t *TB_params,
|
||||
LOG_D(PHY, "Added %d block(s) to prepare for decoding, in pipe: %d to %d\n", r_span, r, r + r_span - 1);
|
||||
}
|
||||
r_offset += segment_params->E;
|
||||
offset += (Kr_bytes - (TB_params->F >> 3) - ((TB_params->C > 1) ? 3 : 0));
|
||||
offset += ((K >> 3) - (TB_params->F >> 3) - ((TB_params->C > 1) ? 3 : 0));
|
||||
r_remaining -= 1;
|
||||
}
|
||||
|
||||
@@ -353,7 +352,7 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args)
|
||||
uint8_t max_ldpc_iterations = TB_params->max_ldpc_iterations;
|
||||
|
||||
uint32_t tbslbrm = TB_params->tbslbrm;
|
||||
uint32_t Kr = TB_params->K;
|
||||
uint32_t K = TB_params->K;
|
||||
uint32_t Z = TB_params->Z;
|
||||
uint32_t F = TB_params->F;
|
||||
|
||||
@@ -369,8 +368,8 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args)
|
||||
uint32_t r_span = arguments->r_span;
|
||||
int r_offset = arguments->r_offset;
|
||||
int input_CBoffset = arguments->input_CBoffset;
|
||||
int kc = arguments->kc;
|
||||
int K_bits_F = arguments->K_bits_F;
|
||||
int Kc = arguments->Kc;
|
||||
int Kprime = arguments->Kprime;
|
||||
|
||||
int16_t z[68 * 384 + 16] __attribute__((aligned(16)));
|
||||
simde__m128i *pv = (simde__m128i *)&z;
|
||||
@@ -405,7 +404,7 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args)
|
||||
*segment_params->d_to_be_cleared,
|
||||
segment_params->E,
|
||||
F,
|
||||
Kr - F - 2 * Z)
|
||||
K - F - 2 * Z)
|
||||
== -1) {
|
||||
stop_meas(&segment_params->ts_rate_unmatch);
|
||||
LOG_E(PHY, "ulsch_decoding.c: Problem in rate_matching\n");
|
||||
@@ -418,33 +417,33 @@ void nr_ulsch_FPGA_decoding_prepare_blocks(void *args)
|
||||
|
||||
*segment_params->d_to_be_cleared = false;
|
||||
|
||||
memset(segment_params->c, 0, Kr >> 3);
|
||||
memset(segment_params->c, 0, K >> 3);
|
||||
|
||||
// set first 2*Z_c bits to zeros
|
||||
memset(&z[0], 0, 2 * Z * sizeof(int16_t));
|
||||
// set Filler bits
|
||||
memset((&z[0] + K_bits_F), 127, F * sizeof(int16_t));
|
||||
memset((&z[0] + Kprime), 127, F * sizeof(int16_t));
|
||||
// Move coded bits before filler bits
|
||||
memcpy((&z[0] + 2 * Z), segment_params->d, (K_bits_F - 2 * Z) * sizeof(int16_t));
|
||||
memcpy((&z[0] + 2 * Z), segment_params->d, (Kprime - 2 * Z) * sizeof(int16_t));
|
||||
// skip filler bits
|
||||
memcpy((&z[0] + Kr), segment_params->d + (Kr - 2 * Z), (kc * Z - Kr) * sizeof(int16_t));
|
||||
memcpy((&z[0] + K), segment_params->d + (K - 2 * Z), (Kc * Z - K) * sizeof(int16_t));
|
||||
|
||||
// Saturate coded bits before decoding into 8 bits values
|
||||
for (int i = 0, j = 0; j < ((kc * Z) >> 4); i += 2, j++) {
|
||||
for (int i = 0, j = 0; j < ((Kc * Z) >> 4); i += 2, j++) {
|
||||
temp_multi_indata[j] =
|
||||
simde_mm_xor_si128(simde_mm_packs_epi16(pv[i], pv[i + 1]),
|
||||
simde_mm_cmpeq_epi32(ones,
|
||||
ones)); // Perform NOT operation and write the result to temp_multi_indata[j]
|
||||
}
|
||||
|
||||
// the last bytes before reaching "kc * harq_process->Z" should not be written 128 bits at a time to avoid overwritting the
|
||||
// the last bytes before reaching "Kc * harq_process->Z" should not be written 128 bits at a time to avoid overwritting the
|
||||
// following block in multi_indata
|
||||
simde__m128i tmp =
|
||||
simde_mm_xor_si128(simde_mm_packs_epi16(pv[2 * ((kc * Z) >> 4)], pv[2 * ((kc * Z) >> 4) + 1]),
|
||||
simde_mm_xor_si128(simde_mm_packs_epi16(pv[2 * ((Kc * Z) >> 4)], pv[2 * ((Kc * Z) >> 4) + 1]),
|
||||
simde_mm_cmpeq_epi32(ones,
|
||||
ones)); // Perform NOT operation and write the result to temp_multi_indata[j]
|
||||
uint8_t *tmp_p = (uint8_t *)&tmp;
|
||||
for (int i = 0, j = ((kc * Z) & 0xfffffff0); j < kc * Z; i++, j++) {
|
||||
for (int i = 0, j = ((Kc * Z) & 0xfffffff0); j < Kc * Z; i++, j++) {
|
||||
multi_indata[r * input_CBoffset + j] = tmp_p[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -26,37 +26,51 @@
|
||||
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
|
||||
|
||||
/**
|
||||
\brief LDPC encoder
|
||||
\param 1 input
|
||||
\param 2 channel_input
|
||||
\param 3 int Zc
|
||||
\param 4 int Kb
|
||||
\param 5 short block_length
|
||||
\param 6 short BG
|
||||
\param 7 int n_segment
|
||||
\param 8 unsigned int macro_num
|
||||
\param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput
|
||||
\brief LDPC encoder parameter structure
|
||||
\var n_segments number of segments in the transport block
|
||||
\var macro_num index of the subset of segments to encode
|
||||
within the transport block
|
||||
\var gen_code flag to generate parity check code
|
||||
0 -> encoding
|
||||
1 -> generate parity check code with AVX2
|
||||
2 -> generate parity check code without AVX2
|
||||
\var tinput time statistics for data input in the encoder
|
||||
\var tprep time statistics for data preparation in the encoder
|
||||
\var tparity time statistics for adding parity bits
|
||||
\var toutput time statistics for data output from the encoder
|
||||
\var K size of the complete code segment before encoding
|
||||
including payload, CRC bits and filler bit
|
||||
(also known as Kr, see 38.212-5.2.2)
|
||||
\var Kb number of lifting sizes to fit the payload (see 38.212-5.2.2)
|
||||
\var Zc lifting size (see 38.212-5.2.2)
|
||||
\var F number of filler bits (see 38.212-5.2.2)
|
||||
\var harq pointer to the HARQ process structure
|
||||
\var BG base graph index
|
||||
\var output output buffer after INTERLEAVING
|
||||
\var ans pointer to the task answer
|
||||
to notify thread pool about completion of the task
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int n_segments; // optim8seg
|
||||
unsigned int macro_num; // optim8segmulti
|
||||
unsigned char gen_code; //orig
|
||||
unsigned int n_segments; // optim8seg
|
||||
unsigned int macro_num; // optim8segmulti
|
||||
unsigned char gen_code; //orig
|
||||
time_stats_t *tinput;
|
||||
time_stats_t *tprep;
|
||||
time_stats_t *tparity;
|
||||
time_stats_t *toutput;
|
||||
int Kr;
|
||||
/// Size in bits of the code segments
|
||||
uint32_t K;
|
||||
/// Number of lifting sizes to fit the payload
|
||||
uint32_t Kb;
|
||||
/// Lifting size
|
||||
uint32_t Zc;
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
void *harq;
|
||||
/// Encoder BG
|
||||
uint8_t BG;
|
||||
/// Interleaver outputs
|
||||
unsigned char *output;
|
||||
/// Number of bits in "small" code segments
|
||||
uint32_t K;
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
task_ans_t *ans;
|
||||
} encoder_implemparams_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user