/* * 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.1 (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 nrLDPC_mPass.h * \brief Defines the functions for message passing * \author Sebastian Wagner (TCL Communications) Email: * \date 27-03-2018 * \version 1.0 * \note * \warning */ #ifndef __NR_LDPC_MPASS__H__ #define __NR_LDPC_MPASS__H__ #include #include "nrLDPC_defs.h" /** \brief Copies the input LLRs to their corresponding place in the LLR processing buffer. \param p_lut Pointer to decoder LUTs \param llr Pointer to input LLRs \param Z Lifting size \param BG Base graph */ static inline void nrLDPC_llr2llrProcBuf(t_nrLDPC_lut* p_lut, int8_t* llr, uint16_t Z, uint8_t BG) { const uint16_t* lut_llr2llrProcBuf = p_lut->llr2llrProcBuf; uint32_t i; const uint8_t numBn2CnG1 = p_lut->numBnInBnGroups[0]; uint32_t colG1 = NR_LDPC_START_COL_PARITY_BG1*Z; if (BG == 2) { colG1 = NR_LDPC_START_COL_PARITY_BG2*Z; } // Copy LLRs connected to 1 CN if (numBn2CnG1 > 0) { memcpy(&llrProcBuf[0], &llr[colG1], numBn2CnG1*Z); } // First 2 columns might be set to zero directly if it's true they always belong to the groups with highest number of connected CNs... for (i=0; illr2CnProcBuf; const uint8_t* lut_numEdgesPerBn = p_lut->numEdgesPerBn; int8_t curLLR; uint8_t numEdges; uint32_t i; uint32_t j; uint32_t k; uint8_t startColParity = NR_LDPC_START_COL_PARITY_BG1; uint32_t colG1; const uint32_t* p_lutEntry = lut_llr2CnProcBuf; if (BG == 2) { startColParity = NR_LDPC_START_COL_PARITY_BG2; } colG1 = startColParity*Z; // BNs connected to more than 1 CN for (k=0; kcn2bnProcBuf; 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; icn2bnProcBuf; 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_BG1_R13[0]*NR_LDPC_ZMAX; for (j=0; j<3; j++) { p_cnProcBufRes = &cnProcBufRes[lut_startAddrCnGroups[0] + j*bitOffsetInGroup]; for (i=0; icn2bnProcBuf; 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; icn2bnProcBuf; 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 19 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_BG1_R13[0]*NR_LDPC_ZMAX; for (j=0; j<2; j++) { p_cnProcBuf = &cnProcBuf[lut_startAddrCnGroups[0] + j*bitOffsetInGroup]; for (i=0; illr2llrProcBuf; uint32_t i; for (i=0; i