Commit 36d924d9 authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch 'ldpc_encoder_decoder' of...

Merge branch 'ldpc_encoder_decoder' of https://gitlab.eurecom.fr/hongzhi/openairinterface5g into ldpc_encoder_decoder
parents 81d144ee 226a85ca
This diff is collapsed.
This diff is collapsed.
/*==============================================================================
* nrLDPC_decoder.c
*
* Defines the LDPC decoder
* p_llrOut = output LLRs aligned on 32 byte boundaries
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#include <stdint.h>
#include <immintrin.h>
#include "nrLDPC_defs.h"
#include "nrLDPC_types.h"
#include "nrLDPC_init.h"
#include "nrLDPC_mPass.h"
#include "nrLDPC_cnProc.h"
#include "nrLDPC_bnProc.h"
#ifdef MEAS_TIME
#include <time.h>
#include <string.h>
#endif
static inline void nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_llrOut, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_proc_time* p_procTime);
void nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int16_t* p_llr, int8_t* p_llrOut, t_nrLDPC_proc_time* p_procTime)
{
uint32_t numLLR;
t_nrLDPC_lut lut;
t_nrLDPC_lut* p_lut = &lut;
//int8_t llrOut_inter;
//int8_t* p_llrOut_inter=&llrOut_inter;
// Initialize decoder core(s) with correct LUTs
numLLR = nrLDPC_init(p_decParams, p_lut);
// Launch LDPC decoder core for one segment
nrLDPC_decoder_core((int8_t *)p_llr, p_llrOut, numLLR, p_lut, p_decParams, p_procTime);
//nrLDPC_decoder_core((int8_t *) p_llr, p_llrOut_inter, numLLR, p_lut, p_decParams, p_procTime);
//p_llrOut = (uint8_t *) p_llrOut_inter;
}
static inline void nrLDPC_decoder_core(int8_t* p_llr, int8_t* p_llrOut, uint32_t numLLR, t_nrLDPC_lut* p_lut, t_nrLDPC_dec_params* p_decParams, t_nrLDPC_proc_time* p_procTime)
{
printf("LDPC core p_llr %d\n",*p_llr);
uint16_t Z = p_decParams->Z;
uint8_t numMaxIter = p_decParams->numMaxIter;
uint32_t i = 0;
#ifdef MEAS_TIME
clock_t start_all, end_all, start, end;
memset(p_procTime, 0, sizeof(t_nrLDPC_proc_time));
#endif
#ifdef MEAS_TIME
start_all = clock();
#endif
// Initialization
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_llr2llrProcBuf(p_lut, p_llr, numLLR);
#ifdef MEAS_TIME
end = clock();
p_procTime->llr2llrProcBuf += ((double) (end - start));
#endif
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_llr2CnProcBuf(p_lut, p_llr, numLLR);
#ifdef MEAS_TIME
end = clock();
p_procTime->llr2CnProcBuf += ((double) (end - start));
#endif
// First iteration
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_cnProc(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->cnProc += ((double) (end - start));
#endif
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_cn2bnProcBuf(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->cn2bnProcBuf += ((double) (end - start));
#endif
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_bnProcPc(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->bnProcPc += ((double) (end - start));
#endif
// Parity check should occur here
while (i < numMaxIter)
{
// BN processing
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_bnProc(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->bnProc += ((double) (end - start));
#endif
// BN results to CN processing buffer
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_bn2cnProcBuf(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->bn2cnProcBuf += ((double) (end - start));
#endif
// CN processing
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_cnProc(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->cnProc += ((double) (end - start));
#endif
// Send CN results back to BNs
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_cn2bnProcBuf(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->cn2bnProcBuf += ((double) (end - start));
#endif
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_bnProcPc(p_lut, Z);
#ifdef MEAS_TIME
end = clock();
p_procTime->bnProcPc += ((double) (end - start));
#endif
// Do parity check
i++;
}
// Assign results from processing buffer to output
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_llrRes2llrOut(p_lut, p_llrOut, numLLR);
#ifdef MEAS_TIME
end = clock();
p_procTime->llrRes2llrOut += ((double) (end - start));
#endif
// Hard-decision
#ifdef MEAS_TIME
start = clock();
#endif
nrLDPC_llr2bit(p_llrOut, numLLR);
#ifdef MEAS_TIME
end = clock();
p_procTime->llr2bit += ((double) (end - start));
#endif
#ifdef MEAS_TIME
end_all = clock();
p_procTime->total = ((double) (end_all - start_all));
p_procTime->llr2llrProcBuf /= CLOCKS_PER_SEC;
p_procTime->llr2CnProcBuf /= CLOCKS_PER_SEC;
p_procTime->cnProc /= CLOCKS_PER_SEC;
p_procTime->bnProcPc /= CLOCKS_PER_SEC;
p_procTime->bnProc /= CLOCKS_PER_SEC;
p_procTime->cn2bnProcBuf /= CLOCKS_PER_SEC;
p_procTime->bn2cnProcBuf /= CLOCKS_PER_SEC;
p_procTime->llrRes2llrOut /= CLOCKS_PER_SEC;
p_procTime->llr2bit /= CLOCKS_PER_SEC;
p_procTime->total /= CLOCKS_PER_SEC;
#endif
}
/*==============================================================================
* nrLDPC_decoder.h
*
* Defines the LDPC decoder core prototypes
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef _NR_LDPC_DECODER_
#define _NR_LDPC_DECODER_
#include "nrLDPC_types.h"
void nrLDPC_decoder(t_nrLDPC_dec_params* p_decParams, int16_t* p_llr, int8_t* p_llrOut, t_nrLDPC_proc_time* p_procTime);
#endif
/*==============================================================================
* nrLDPC_defs.h
*
* Defines all constant variables for the LDPC decoder
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef _NR_LDPC_DEFS_
#define _NR_LDPC_DEFS_
// ==============================================================================
// DEFINES
// Maximum lifting size
#define NR_LDPC_ZMAX 384
// Row and column dimensions of BG1 and BG2
#define NR_LDPC_NCOL_BG1 68
#define NR_LDPC_NROW_BG1 46
#define NR_LDPC_NROW_BG2 42
#define NR_LDPC_NCOL_BG2 52
#define NR_LDPC_NUM_EDGE_BG1 316
#define NR_LDPC_NUM_EDGE_BG2 197
#define NR_LDPC_NUM_CN_GROUPS_BG1 9
#define NR_LDPC_NUM_CN_GROUPS_BG2 6
#define NR_LDPC_NCOL_BG2_R15 NR_LDPC_NCOL_BG2
#define NR_LDPC_NCOL_BG2_R13 32
#define NR_LDPC_NCOL_BG2_R23 17
#define NR_LDPC_NUM_BN_GROUPS_BG1 13
#define NR_LDPC_NUM_BN_GROUPS_BG2 23
#define NR_LDPC_SIZE_CN_PROC_BUF NR_LDPC_NUM_EDGE_BG1*NR_LDPC_ZMAX
#define NR_LDPC_SIZE_BN_PROC_BUF NR_LDPC_NUM_EDGE_BG1*NR_LDPC_ZMAX
#define NR_LDPC_MAX_NUM_LLR 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
#define NR_LDPC_NUM_MAX_ITER 1
#define MEAS_TIME
// ==============================================================================
// GLOBAL VARIABLES
// Aligned on 32 bytes = 256 bits for AVX2
static int8_t cnProcBuf [NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32)));
static int8_t cnProcBufRes[NR_LDPC_SIZE_CN_PROC_BUF] __attribute__ ((aligned(32)));
static int8_t bnProcBuf [NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32)));
static int8_t bnProcBufRes[NR_LDPC_SIZE_BN_PROC_BUF] __attribute__ ((aligned(32)));
static int8_t llrRes [NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
static int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
// Start addresses for the cnProcBuf for each CN group
static const uint32_t lut_startAddrCnGroups_BG1[NR_LDPC_NUM_CN_GROUPS_BG1] = {0, 1152, 8832, 43392, 61824, 75264, 81408, 88320, 92160};
static const uint32_t lut_startAddrCnGroups_BG2[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 6912, 37632, 54912, 61824, 67968};
// Number of groups for check node processing
static const uint8_t lut_numCnInCnGroups_BG1[NR_LDPC_NUM_CN_GROUPS_BG1] = {1, 5, 18, 8, 5, 2, 2, 1, 4};
static const uint8_t lut_numBnInCnGroups_BG2_R15[NR_LDPC_NUM_CN_GROUPS_BG2] = {3, 4, 5, 6, 8, 10};
static const uint8_t lut_numCnInCnGroups_BG2_R15[NR_LDPC_NUM_CN_GROUPS_BG2] = {6, 20, 9, 3, 2, 2};
static const uint8_t lut_numCnInCnGroups_BG2_R23[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 1, 0, 2, 2, 2};
static const uint8_t lut_numCnInCnGroups_BG2_R13[NR_LDPC_NUM_CN_GROUPS_BG2] = {0, 8, 7, 3, 2, 2};
// Number of groups for bit node processing
static const uint8_t lut_numBnInBnGroups_BG1[NR_LDPC_NUM_BN_GROUPS_BG1] = {42, 1, 1, 2, 4, 3, 1, 4, 3, 4, 1, 1, 1};
// BG2: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
static const uint8_t lut_numBnInBnGroups_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG2] = {38, 0, 0, 0, 2, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1};
static const uint8_t lut_numBnInBnGroups_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG2] = {18, 1, 0, 2, 1, 5, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0};
static const uint8_t lut_numBnInBnGroups_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG2] = { 3, 3, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Start addresses for the bnProcBuf for each BN group
static const uint32_t lut_startAddrBnGroups_BG1[NR_LDPC_NUM_BN_GROUPS_BG1] = {0, 16128, 17664, 19584, 24192, 34944, 44160, 47616, 62976, 75648, 94080, 99072, 109824};
static const uint32_t lut_startAddrBnGroups_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 14592, 18432, 20736, 23424, 26496, 33408, 37248, 41856, 46848, 52224, 58368, 66816};
static const uint32_t lut_startAddrBnGroups_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 6912, 7680, 10752, 12672, 24192, 26880, 29952, 34944, 40320};
static const uint32_t lut_startAddrBnGroups_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 1152, 3456, 9216, 13824, 17664};
static const uint16_t lut_startAddrBnGroupsLlr_BG2_R15[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 14592, 15360, 15744, 16128, 16512, 17280, 17664, 18048, 18432, 18816, 19200, 19584};
static const uint16_t lut_startAddrBnGroupsLlr_BG2_R13[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 6912, 7296, 8064, 8448, 10368, 10752, 11136, 11520, 11904};
static const uint16_t lut_startAddrBnGroupsLlr_BG2_R23[NR_LDPC_NUM_BN_GROUPS_BG2] = {0, 1152, 2304, 4224, 5376, 6144};
static const int8_t ones256_epi8[32] __attribute__ ((aligned(32))) = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
static const int8_t zeros256_epi8[32] __attribute__ ((aligned(32))) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static const int8_t maxLLR256_epi8[32] __attribute__ ((aligned(32))) = {127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127};
#endif
/*==============================================================================
* nrLDPC_init.h
*
* Defines the function to initialize the LDPC decoder.
* Set correct LUTs
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef _NR_LDPC_INIT_
#define _NR_LDPC_INIT_
#include "./nrLDPC_lut/nrLDPC_lut.h"
#include "nrLDPC_defs.h"
static inline uint32_t nrLDPC_init(t_nrLDPC_dec_params* p_decParams, t_nrLDPC_lut* p_lut)
{
uint32_t numLLR = 0;
uint8_t BG = p_decParams->BG;
uint16_t Z = p_decParams->Z;
uint8_t R = p_decParams->R;
if (BG == 2)
{
// LUT that only depend on BG
p_lut->startAddrCnGroups = lut_startAddrCnGroups_BG2;
// LUT that only depend on R
if (R == 15)
{
p_lut->numCnInCnGroups = lut_numCnInCnGroups_BG2_R15;
p_lut->numBnInBnGroups = lut_numBnInBnGroups_BG2_R15;
p_lut->startAddrBnGroups = lut_startAddrBnGroups_BG2_R15;
p_lut->startAddrBnGroupsLlr = lut_startAddrBnGroupsLlr_BG2_R15;
numLLR = NR_LDPC_NCOL_BG2_R15*Z;
}
else if (R == 13)
{
p_lut->numCnInCnGroups = lut_numCnInCnGroups_BG2_R13;
p_lut->numBnInBnGroups = lut_numBnInBnGroups_BG2_R13;
p_lut->startAddrBnGroups = lut_startAddrBnGroups_BG2_R13;
p_lut->startAddrBnGroupsLlr = lut_startAddrBnGroupsLlr_BG2_R13;
numLLR = NR_LDPC_NCOL_BG2_R13*Z;
}
else if (R == 23)
{
p_lut->numCnInCnGroups = lut_numCnInCnGroups_BG2_R23;
p_lut->numBnInBnGroups = lut_numBnInBnGroups_BG2_R23;
p_lut->startAddrBnGroups = lut_startAddrBnGroups_BG2_R23;
p_lut->startAddrBnGroupsLlr = lut_startAddrBnGroupsLlr_BG2_R23;
numLLR = NR_LDPC_NCOL_BG2_R23*Z;
}
// LUT that depend on Z and R
if (Z == 128)
{
if (R == 15)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z128_R15;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z128_R15;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z128_R15;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z128_R15;
}
else if (R == 13)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z128_R13;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z128_R13;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z128_R13;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z128_R13;
}
else if (R == 23)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z128_R23;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z128_R23;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z128_R23;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z128_R23;
}
}
else if (Z == 384)
{
if (R == 15)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z384_R15;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z384_R15;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z384_R15;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z384_R15;
}
else if (R == 13)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z384_R13;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z384_R13;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z384_R13;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z384_R13;
}
else if (R == 23)
{
p_lut->llr2CnProcBuf = lut_llr2CnProcBuf_BG2_Z384_R23;
p_lut->numEdgesPerBn = lut_numEdgesPerBn_BG2_Z384_R23;
p_lut->cn2bnProcBuf = lut_cn2bnProcBuf_BG2_Z384_R23;
p_lut->llr2llrProcBuf = lut_llr2llrProcBuf_BG2_Z384_R23;
}
}
}
return numLLR;
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
static const uint8_t lut_numEdgesPerBn_BG2_Z128_R23[2176] = {6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
\ No newline at end of file
/*==============================================================================
* nrLDPC_lut.h
*
* Header file loading all look-up tables
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef __NR_LDPC_LUT__
#define __NR_LDPC_LUT__
#include "lut_llr2CnProcBuf_BG2_Z128_R15.h"
#include "lut_numEdgesPerBn_BG2_Z128_R15.h"
#include "lut_cn2bnProcBuf_BG2_Z128_R15.h"
#include "lut_llr2llrProcBuf_BG2_Z128_R15.h"
#include "lut_llr2CnProcBuf_BG2_Z128_R13.h"
#include "lut_numEdgesPerBn_BG2_Z128_R13.h"
#include "lut_cn2bnProcBuf_BG2_Z128_R13.h"
#include "lut_llr2llrProcBuf_BG2_Z128_R13.h"
#include "lut_llr2CnProcBuf_BG2_Z128_R23.h"
#include "lut_numEdgesPerBn_BG2_Z128_R23.h"
#include "lut_cn2bnProcBuf_BG2_Z128_R23.h"
#include "lut_llr2llrProcBuf_BG2_Z128_R23.h"
#include "lut_llr2CnProcBuf_BG2_Z384_R15.h"
#include "lut_numEdgesPerBn_BG2_Z384_R15.h"
#include "lut_cn2bnProcBuf_BG2_Z384_R15.h"
#include "lut_llr2llrProcBuf_BG2_Z384_R15.h"
#include "lut_llr2CnProcBuf_BG2_Z384_R13.h"
#include "lut_numEdgesPerBn_BG2_Z384_R13.h"
#include "lut_cn2bnProcBuf_BG2_Z384_R13.h"
#include "lut_llr2llrProcBuf_BG2_Z384_R13.h"
#include "lut_llr2CnProcBuf_BG2_Z384_R23.h"
#include "lut_numEdgesPerBn_BG2_Z384_R23.h"
#include "lut_cn2bnProcBuf_BG2_Z384_R23.h"
#include "lut_llr2llrProcBuf_BG2_Z384_R23.h"
#endif
/*==============================================================================
* nrLDPC_mPass.h
*
* Defines the functions for message passing
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef _NR_LDPC_MPASS_
#define _NR_LDPC_MPASS_
static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, uint16_t numLLR)
{
const uint16_t* lut_llr2llrProcBuf = p_lut->llr2llrProcBuf;
uint32_t i;
for (i=0; i<numLLR; i++)
{
llrProcBuf[lut_llr2llrProcBuf[i]] = llr[i];
}
}
static inline void nrLDPC_llr2CnProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, uint16_t numLLR)
{
const uint32_t* lut_llr2CnProcBuf = p_lut->llr2CnProcBuf;
const uint8_t* lut_numEdgesPerBn = p_lut->numEdgesPerBn;
uint32_t idxLut = 0;
uint32_t idxCnProcBuf = 0;
int8_t curLLR;
uint32_t i;
uint32_t j;
for (i=0; i<numLLR; i++)
{
curLLR = llr[i];
for (j=0; j<lut_numEdgesPerBn[i]; j++)
{
idxCnProcBuf = lut_llr2CnProcBuf[idxLut];
cnProcBuf[idxCnProcBuf] = curLLR;
idxLut++;
}
}
}
static inline void nrLDPC_cn2bnProcBuf(t_nrLDPC_lut* p_lut, uint16_t Z)
{
const uint32_t* lut_cn2bnProcBuf = p_lut->cn2bnProcBuf;
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
const uint32_t* p_lut_cn2bn;
int8_t* p_cnProcBufRes;
uint32_t bitOffsetInGroup;
uint32_t i;
uint32_t j;
uint32_t M;
// =====================================================================
// CN group with 3 BNs
p_lut_cn2bn = &lut_cn2bnProcBuf[0];
M = lut_numCnInCnGroups[0]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX;
for (j=0; j<3; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[0] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
// =====================================================================
// CN group with 4 BNs
p_lut_cn2bn += (M*3); // Number of elements of previous group
M = lut_numCnInCnGroups[1]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX;
for (j=0; j<4; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[1] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
// =====================================================================
// CN group with 5 BNs
p_lut_cn2bn += (M*4); // Number of elements of previous group
M = lut_numCnInCnGroups[2]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX;
for (j=0; j<5; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
// =====================================================================
// CN group with 6 BNs
p_lut_cn2bn += (M*5); // Number of elements of previous group
M = lut_numCnInCnGroups[3]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX;
for (j=0; j<6; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[3] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
// =====================================================================
// CN group with 8 BNs
p_lut_cn2bn += (M*6); // Number of elements of previous group
M = lut_numCnInCnGroups[4]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX;
for (j=0; j<8; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
// =====================================================================
// CN group with 10 BNs
p_lut_cn2bn += (M*8); // Number of elements of previous group
M = lut_numCnInCnGroups[5]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX;
for (j=0; j<10; j++)
{
p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[5] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
bnProcBuf[p_lut_cn2bn[j*M + i]] = p_cnProcBufRes[i];
}
}
}
static inline void nrLDPC_bn2cnProcBuf(t_nrLDPC_lut* p_lut, uint16_t Z)
{
const uint32_t* lut_cn2bnProcBuf = p_lut->cn2bnProcBuf;
const uint8_t* lut_numCnInCnGroups = p_lut->numCnInCnGroups;
const uint32_t* lut_startAddrCnGroups = p_lut->startAddrCnGroups;
int8_t* p_cnProcBuf;
const uint32_t* p_lut_cn2bn;
uint32_t bitOffsetInGroup;
uint32_t i;
uint32_t j;
uint32_t M;
// For CN groups 3 to 6 no need to send the last BN back since it's single edge
// and BN processing does not change the value already in the CN proc buf
// =====================================================================
// CN group with 3 BNs
p_lut_cn2bn = &lut_cn2bnProcBuf[0];
M = lut_numCnInCnGroups[0]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[0]*NR_LDPC_ZMAX;
for (j=0; j<2; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[0] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
// =====================================================================
// CN group with 4 BNs
p_lut_cn2bn += (M*3); // Number of elements of previous group
M = lut_numCnInCnGroups[1]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[1]*NR_LDPC_ZMAX;
for (j=0; j<3; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[1] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
// =====================================================================
// CN group with 5 BNs
p_lut_cn2bn += (M*4); // Number of elements of previous group
M = lut_numCnInCnGroups[2]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[2]*NR_LDPC_ZMAX;
for (j=0; j<4; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[2] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
// =====================================================================
// CN group with 6 BNs
p_lut_cn2bn += (M*5); // Number of elements of previous group
M = lut_numCnInCnGroups[3]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[3]*NR_LDPC_ZMAX;
for (j=0; j<5; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[3] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
// =====================================================================
// CN group with 8 BNs
p_lut_cn2bn += (M*6); // Number of elements of previous group
M = lut_numCnInCnGroups[4]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[4]*NR_LDPC_ZMAX;
for (j=0; j<8; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[4] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
// =====================================================================
// CN group with 10 BNs
p_lut_cn2bn += (M*8); // Number of elements of previous group
M = lut_numCnInCnGroups[5]*Z;
bitOffsetInGroup = lut_numCnInCnGroups_BG2_R15[5]*NR_LDPC_ZMAX;
for (j=0; j<10; j++)
{
p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[5] + j*bitOffsetInGroup];
for (i=0; i<M; i++)
{
p_cnProcBuf[i] = bnProcBufRes[p_lut_cn2bn[j*M + i]];
}
}
}
static inline void nrLDPC_llrRes2llrOut(t_nrLDPC_lut* p_lut, int8_t* llrOut, uint16_t numLLR)
{
const uint16_t* lut_llr2llrProcBuf = p_lut->llr2llrProcBuf;
uint32_t i;
for (i=0; i<numLLR; i++)
{
llrOut[i] = llrRes[lut_llr2llrProcBuf[i]];
}
}
#endif
/*==============================================================================
* nrLDPC_defs.h
*
* Defines all constant variables for the LDPC decoder
*
* Author: Sebastian Wagner
* Date: 17-11-2017
*
===============================================================================*/
#ifndef _NR_LDPC_TYPES_
#define _NR_LDPC_TYPES_
// ==============================================================================
// TYPES
typedef struct nrLDPC_lut {
const uint32_t* startAddrCnGroups;
const uint8_t* numCnInCnGroups;
const uint8_t* numBnInBnGroups;
const uint32_t* startAddrBnGroups;
const uint16_t* startAddrBnGroupsLlr;
const uint32_t* llr2CnProcBuf;
const uint8_t* numEdgesPerBn;
const uint32_t* cn2bnProcBuf;
const uint16_t* llr2llrProcBuf;
} t_nrLDPC_lut;
typedef struct nrLDPC_dec_params {
uint8_t BG;
uint16_t Z;
uint8_t R; // Format 15,13,... for code rates 1/5, 1/3,...
uint8_t numMaxIter;
} t_nrLDPC_dec_params;
typedef struct nrLDPC_proc_time {
double llr2llrProcBuf;
double llr2CnProcBuf;
double cnProc;
double bnProcPc;
double bnProc;
double cn2bnProcBuf;
double bn2cnProcBuf;
double llrRes2llrOut;
double llr2bit;
double total;
} t_nrLDPC_proc_time;
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* file: nr_segmentation.c
purpose: Procedures for transport block segmentation for NR (LDPC-coded transport channels)
author: Hongzhi WANG (TCL)
date: 12.09.2017
*/
#include "PHY/defs.h"
#include "SCHED/extern.h"
//#define DEBUG_SEGMENTATION
int32_t nr_segmentation(unsigned char *input_buffer,
unsigned char **output_buffers,
unsigned int B,
unsigned int *C,
unsigned int *Kplus,
unsigned int *Kminus,
unsigned int *Zout,
unsigned int *F)
{
unsigned int L,Bprime,Bprime_by_C,Z,r,Kb,k,s,crc,Kprime;
if (B<=8448) {
L=0;
*C=1;
Bprime=B;
} else {
L=24;
*C = B/(8448-L);
if ((8448-L)*(*C) < B)
*C=*C+1;
Bprime = B+((*C)*L);
#ifdef DEBUG_SEGMENTATION
printf("Bprime %d\n",Bprime);
#endif
}
if ((*C)>MAX_NUM_DLSCH_SEGMENTS) {
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
return(-1);
}
// Find K+
Bprime_by_C = Bprime/(*C);
if (Bprime <=192) {
Kb = 6;
} else if (Bprime <=560) {
Kb = 8;
} else if (Bprime <=640) {
Kb = 9;
} else if (Bprime <=3840) {
Kb = 10;;
} else {
Kb = 22;
}
Z = (Bprime_by_C/Kb)+1;
if (Z <= 2) {
*Kplus = 2;
*Kminus = 0;
} else if (Z<=16) { // increase by 1 byte til here
*Kplus = Z;
*Kminus = Z-1;
} else if (Z <=32) { // increase by 2 bytes til here
*Kplus = (Z>>1)<<1;
if (*Kplus < Z)
*Kplus = *Kplus + 2;
*Kminus = (*Kplus - 2);
} else if (Z <= 64) { // increase by 4 bytes til here
*Kplus = (Z>>2)<<2;
if (*Kplus < Z)
*Kplus = *Kplus + 4;
*Kminus = (*Kplus - 4);
} else if (Z <=128 ) { // increase by 8 bytes til here
*Kplus = (Z>>3)<<3;
if (*Kplus < Z)
*Kplus = *Kplus + 8;
#ifdef DEBUG_SEGMENTATION
printf("Z_by_C %d , Kplus2 %d\n",Z,*Kplus);
#endif
*Kminus = (*Kplus - 8);
} else if (Z <= 256) { // increase by 4 bytes til here
*Kplus = (Z>>4)<<4;
if (*Kplus < Z)
*Kplus = *Kplus + 16;
*Kminus = (*Kplus - 16);
} else if (Z <= 384) { // increase by 4 bytes til here
*Kplus = (Z>>5)<<5;
if (*Kplus < Z)
*Kplus = *Kplus + 32;
*Kminus = (*Kplus - 32);
} else {
//msg("nr_segmentation.c: Illegal codeword size !!!\n");
return(-1);
}
*Kplus = *Kplus*Kb;
*Kminus = *Kminus*Kb;
*Zout = Z;
*F = ((*C)*(*Kplus) - (Bprime));
#ifdef DEBUG_SEGMENTATION
printf("C %d, Kplus %d, Kminus %d, Bprime_bytes %d, Bprime %d, F %d\n",*C,*Kplus,*Kminus,Bprime>>3,Bprime,*F);
#endif
if ((input_buffer) && (output_buffers)) {
for (k=0; k<*F>>3; k++) {
output_buffers[0][k] = 0;
}
s=0;
for (r=0; r<*C; r++) {
if (r<(B%(*C)))
Kprime = *Kplus;
else
Kprime = *Kminus;
while (k<((Kprime - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
k++;
s++;
}
if (*C > 1) { // add CRC
crc = crc24b(output_buffers[r],Kprime-24)>>8;
output_buffers[r][(Kprime-24)>>3] = ((uint8_t*)&crc)[2];
output_buffers[r][1+((Kprime-24)>>3)] = ((uint8_t*)&crc)[1];
output_buffers[r][2+((Kprime-24)>>3)] = ((uint8_t*)&crc)[0];
}
k=0;
}
}
return(0);
}
#ifdef MAIN
main()
{
unsigned int Kplus,Kminus,C,F,Bbytes;
for (Bbytes=5; Bbytes<8; Bbytes++) {
nr_segmentation(0,0,Bbytes<<3,&C,&Kplus,&Kminus, &F);
printf("Bbytes %d : C %d, Kplus %d, Kminus %d, F %d\n",
Bbytes, C, Kplus, Kminus, F);
}
}
#endif
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