Commit 3aca18cb authored by Raymond Knopp's avatar Raymond Knopp Committed by Robert Schmidt

encoder32

parent d9b70289
......@@ -12,6 +12,7 @@ target_link_libraries(coding PRIVATE log_headers)
add_library(ldpc_orig MODULE
nrLDPC_decoder/nrLDPC_decoder.c
nrLDPC_encoder/ldpc_encoder.c
nrLDPC_encoder/ldpc_encoder32.c
)
set_target_properties(ldpc_orig PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries(ldpc_orig PRIVATE ldpc_segment ldpc_gen_HEADERS)
......@@ -19,6 +20,7 @@ target_link_libraries(ldpc_orig PRIVATE ldpc_segment ldpc_gen_HEADERS)
add_library(ldpc MODULE
nrLDPC_decoder/nrLDPC_decoder.c
nrLDPC_encoder/ldpc_encoder_optim8segmulti.c
nrLDPC_encoder/ldpc_encoder32.c
)
set_target_properties(ldpc PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
target_link_libraries(ldpc PRIVATE ldpc_segment ldpc_gen_HEADERS)
......
......@@ -52,6 +52,9 @@
* \param output nrLDPC_coding_segment_encoder with concatenated segments and packed bits
* \param Eoffset offset in number of bits of the first segment of the segment group within output
*/
int nrLDPC_coding_encoder32(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters);
static void write_task_output(uint8_t *f,
uint32_t E,
uint8_t *f2,
......
......@@ -1301,6 +1301,103 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm,
return 0;
}
int nr_rate_matching_ldpc32(uint32_t Tbslbrm,
uint8_t BG,
uint16_t Z,
uint32_t *d,
uint32_t *e,
uint8_t C,
uint32_t F,
uint32_t Foffset,
uint8_t rvidx,
uint32_t E)
{
if (C == 0) {
LOG_E(PHY, "nr_rate_matching: invalid parameter C %d\n", C);
return -1;
}
//Bit selection
uint32_t N = (BG == 1) ? (66 * Z) : (50 * Z);
uint32_t Ncb;
if (Tbslbrm == 0)
Ncb = N;
else {
uint32_t Nref = 3 * Tbslbrm / (2 * C); //R_LBRM = 2/3
Ncb = min(N, Nref);
}
uint32_t ind = (index_k0[BG - 1][rvidx] * Ncb / N) * Z;
#ifdef RM_DEBUG
printf("nr_rate_matching_ldpc: E %u, F %u, Foffset %u, k0 %u, Ncb %u, rvidx %d, Tbslbrm %u\n",
E,
F,
Foffset,
ind,
Ncb,
rvidx,
Tbslbrm);
#endif
if (Foffset > E) {
LOG_E(PHY,
"nr_rate_matching: invalid parameters (Foffset %d > E %d) F %d, k0 %d, Ncb %d, rvidx %d, Tbslbrm %d\n",
Foffset,
E,
F,
ind,
Ncb,
rvidx,
Tbslbrm);
return -1;
}
if (Foffset > Ncb) {
LOG_E(PHY, "nr_rate_matching: invalid parameters (Foffset %d > Ncb %d)\n", Foffset, Ncb);
return -1;
}
if (ind >= Foffset && ind < (F + Foffset))
ind = F + Foffset;
uint32_t k = 0;
if (ind < Foffset) { // case where we have some bits before the filler and the rest after
memcpy((void *)e, (void *)(d + ind), (Foffset - ind)<<2);
if (E + F <= Ncb - ind) { // E+F doesn't contain all coded bits
memcpy((void *)(e + Foffset - ind), (void *)(d + Foffset + F), (E - Foffset + ind)<<2);
k = E;
} else {
memcpy((void *)(e + Foffset - ind), (void *)(d + Foffset + F), (Ncb - Foffset - F)<<2);
k = Ncb - F - ind;
}
} else {
if (E <= Ncb - ind) { // E+F doesn't contain all coded bits
memcpy((void *)(e), (void *)(d + ind), E<<2);
k = E;
} else {
memcpy((void *)(e), (void *)(d + ind), (Ncb - ind)<<2);
k = Ncb - ind;
}
}
while (k < E) { // case where we do repetitions (low mcs)
for (ind = 0; (ind < Ncb) && (k < E); ind++) {
#ifdef RM_DEBUG
printf("RM_TX k%u Ind: %u (%d)\n", k, ind, d[ind]);
#endif
if (ind == Foffset)
ind = F + Foffset; // skip filler bits
e[k++] = d[ind];
}
}
return 0;
}
#define RMLOOP for (;ind<(ind2&7);k+=8,ind+=8) \
simde_mm_storeu_si128(&d[ind],simde_mm_adds_epi16(simde_mm_loadu_si128(&soft_input[k]),simde_mm_loadu_si128(&d[ind])));\
for (; ind<ind2 ; ind++,k++) d[ind] += soft_input[k];
......
......@@ -33,6 +33,15 @@
*/
void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e, uint8_t *f);
/**
* \brief interleave a code segment after encoding and rate matching (32bit)
* \param E size of the code segment in bits
* \param Qm modulation order
* \param e input rate matched segment
* \param f output interleaved segment
*/
void nr_interleaving_ldpc32(uint32_t E, uint8_t Qm, uint32_t *e, uint32_t *f);
/**
* \brief deinterleave a code segment before RX rate matching and decoding
* \param E size of the code segment in bits
......@@ -66,6 +75,30 @@ int nr_rate_matching_ldpc(uint32_t Tbslbrm,
uint8_t rvidx,
uint32_t E);
/**
* \brief rate match a code segment after encoding (32bit)
* \Tbslbrm Transport Block size LBRM
* \param BG LDPC base graph number
* \param Z segment lifting size
* \param d input encoded segment
* \param e output rate matched segment
* \param C number of segments in the Transport Block
* \param F number of filler bits in the segment
* \param Foffset offset of the filler bits in the segment
* \param rvidx redundancy version index
* \param E size of the code segment in bits
*/
int nr_rate_matching_ldpc32(uint32_t Tbslbrm,
uint8_t BG,
uint16_t Z,
uint32_t *d,
uint32_t *e,
uint8_t C,
uint32_t F,
uint32_t Foffset,
uint8_t rvidx,
uint32_t E);
/**
* \brief rate match a code segment before decoding
* \Tbslbrm Transport Block size LBRM
......
......@@ -27,6 +27,7 @@ typedef struct ldpc_interface_s {
LDPC_shutdownfunc_t *LDPCshutdown;
LDPC_decoderfunc_t *LDPCdecoder;
LDPC_encoderfunc_t *LDPCencoder;
LDPC_encoderfunc32_t *LDPCencoder32;
} ldpc_interface_t;
/* functions to load the LDPC shared lib, implemented in openair1/PHY/CODING/nrLDPC_load.c */
......@@ -35,6 +36,7 @@ int free_LDPClib(ldpc_interface_t *ldpc_interface);
LDPC_decoderfunc_t LDPCdecoder;
LDPC_encoderfunc_t LDPCencoder;
LDPC_encoderfunc32_t LDPCencoder32;
// inline functions:
#endif
......@@ -56,14 +56,17 @@ int load_LDPClib(char *version, ldpc_interface_t *itf)
loader_shlibfunc_t shlib_fdesc[] = {{.fname = "LDPCinit"},
{.fname = "LDPCshutdown"},
{.fname = "LDPCdecoder"},
{.fname = "LDPCencoder"}};
{.fname = "LDPCencoder"},
{.fname = "LDPCencoder32"}};
int ret;
ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), NULL);
AssertFatal((ret >= 0), "Error loading ldpc decoder");
LOG_I(NR_PHY,"loading LDPC version %s\n",version);
itf->LDPCinit = (LDPC_initfunc_t *)shlib_fdesc[0].fptr;
itf->LDPCshutdown = (LDPC_shutdownfunc_t *)shlib_fdesc[1].fptr;
itf->LDPCdecoder = (LDPC_decoderfunc_t *)shlib_fdesc[2].fptr;
itf->LDPCencoder = (LDPC_encoderfunc_t *)shlib_fdesc[3].fptr;
itf->LDPCencoder32 = (LDPC_encoderfunc32_t *)shlib_fdesc[4].fptr;
AssertFatal(itf->LDPCinit() == 0, "error starting LDPC library %s %s\n", libname, version);
......
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