Commit 15fc2984 authored by Romain Beurdouche's avatar Romain Beurdouche

fix(nrLDPC_coding): cleanup the naming of the K, Kprime and Zc variables to...

fix(nrLDPC_coding): cleanup the naming of the K, Kprime and Zc variables to comply with the standard 38.212-5.2.2
parent 9586db6b
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
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