merge develop

This commit is contained in:
Laurent THOMAS
2021-12-23 22:52:36 +01:00
124 changed files with 2493 additions and 2761 deletions
+543
View File
@@ -0,0 +1,543 @@
/*******************************************************************************
Copyright (c) 2009-2018, Intel Corporation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* Header file for module with CRC computation methods
*
* PCLMULQDQ implementation is based on work by:
* Erdinc Ozturk
* Vinodh Gopal
* James Guilford
*
* "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction"
* URL: http://download.intel.com/design/intarch/papers/323102.pdf
*/
#ifndef __CRC_H__
#define __CRC_H__
#include <x86intrin.h>
#include "crcext.h"
#include "types.h"
#include <immintrin.h>
#include <wmmintrin.h>
/**
* PCLMULQDQ CRC computation context structure
*/
struct crc_pclmulqdq_ctx {
/**
* K1 = reminder X^128 / P(X) : 0-63
* K2 = reminder X^192 / P(X) : 64-127
*/
uint64_t k1;
uint64_t k2;
/**
* K3 = reminder X^64 / P(X) : 0-63
* q = quotient X^64 / P(X) : 64-127
*/
uint64_t k3;
uint64_t q;
/**
* p = polynomial / P(X) : 0-63
* res = reserved : 64-127
*/
uint64_t p;
uint64_t res;
};
/**
* Functions and prototypes
*/
/**
* @brief Initializes look-up-table (LUT) for given 8 bit polynomial
*
* @param poly CRC polynomial
* @param lut pointer to look-up-table to be initialized
*/
void crc8_init_lut(const uint8_t poly, uint8_t *lut);
/**
* @brief Calculates 8 bit CRC using LUT method.
*
* @param crc CRC initial value
* @param data pointer to data block to calculate CRC for
* @param data_len size of data block
* @param lut 256x8bits look-up-table pointer
*
* @return New CRC value
*/
__forceinline
uint8_t crc8_calc_lut(const uint8_t *data,
uint32_t data_len,
uint8_t crc,
const uint8_t *lut)
{
if (unlikely(data == NULL || lut == NULL))
return crc;
while (data_len--)
crc = lut[*data++ ^ crc];
return crc;
}
/**
* @brief Initializes look-up-table (LUT) for given 16 bit polynomial
*
* @param poly CRC polynomial
* @param lut pointer to 256x16bits look-up-table to be initialized
*/
void crc16_init_lut(const uint16_t poly, uint16_t *lut);
/**
* @brief Calculates 16 bit CRC using LUT method.
*
* @param crc CRC initial value
* @param data pointer to data block to calculate CRC for
* @param data_len size of data block
* @param lut 256x16bits look-up-table pointer
*
* @return New CRC value
*/
__forceinline
uint16_t crc16_calc_lut(const uint8_t *data,
uint32_t data_len,
uint16_t crc,
const uint16_t *lut)
{
if (unlikely(data == NULL || lut == NULL))
return crc;
while (data_len--)
crc = lut[(crc >> 8) ^ *data++] ^ (crc << 8);
return crc;
}
/**
* @brief Initializes look-up-table (LUT) for given 32 bit polynomial
*
* @param poly CRC polynomial
* @param lut pointer to 256x32bits look-up-table to be initialized
*/
void crc32_init_lut(const uint32_t poly, uint32_t *lut);
/**
* @brief Calculates 32 bit CRC using LUT method.
*
* @param crc CRC initial value
* @param data pointer to data block to calculate CRC for
* @param data_len size of data block
* @param lut 256x32bits look-up-table pointer
*
* @return New CRC value
*/
__forceinline
uint32_t crc32_calc_lut(const uint8_t *data,
uint32_t data_len,
uint32_t crc,
const uint32_t *lut)
{
if (unlikely(data == NULL || lut == NULL))
return crc;
while (data_len--)
crc = lut[(crc >> 24) ^ *data++] ^ (crc << 8);
return crc;
}
/**
* @brief Initializes look up tables for slice-By-2 method.
*
* @param poly CRC polynomial
* @param slice1 slice-by-2 look-up-table 1
* @param slice2 slice-by-2 look-up-table 2
*
* @return New CRC value
*/
void crc16_init_slice2(const uint16_t poly,
uint16_t *slice1,
uint16_t *slice2);
/**
* @brief Calculates 16 bit CRC using Slice-By-2 method.
*
* @param crc CRC initial value
* @param data pointer to data block to calculate CRC for
* @param data_len size of data block
* @param slice1 256x16bits slice look-up-table 1
* @param slice2 256x16bits slice look-up-table 2
*
* @return New CRC value
*/
__forceinline
uint16_t crc16_calc_slice2(const uint8_t *data,
uint32_t data_len,
uint16_t crc,
const uint16_t *slice1,
const uint16_t *slice2)
{
uint_fast32_t i;
if (unlikely(data == NULL))
return crc;
if (unlikely(slice1 == NULL || slice2 == NULL))
return crc;
crc = bswap2(crc);
for (i = (data_len & (~1)), data += (data_len & (~1)); i != 0;
i -= sizeof(uint16_t)) {
crc ^= (*((const uint16_t *)(data - i)));
crc = slice2[(uint8_t)crc] ^ slice1[(uint8_t)(crc >> 8)];
}
crc = bswap2(crc);
if (data_len & 1)
crc = (crc << 8) ^ bswap2(slice1[(crc >> 8) ^ *data]);
return crc;
}
/**
* @brief Initializes look up tables for slice-By-4 method.
*
* @param poly CRC polynomial
* @param slice1 256x32bits slice look-up-table 1
* @param slice2 256x32bits slice look-up-table 2
* @param slice3 256x32bits slice look-up-table 3
* @param slice4 256x32bits slice look-up-table 4
*
* @return New CRC value
*/
void crc32_init_slice4(const uint32_t poly,
uint32_t *slice1, uint32_t *slice2,
uint32_t *slice3, uint32_t *slice4);
/**
* @brief Calculates 32 bit CRC using Slice-By-4 method.
*
* @param data pointer to data block to calculate CRC for
* @param data_len size of data block
* @param crc CRC initial value
* @param slice1 256x32bits slice look-up-table 1
* @param slice2 256x32bits slice look-up-table 2
* @param slice3 256x32bits slice look-up-table 3
* @param slice4 256x32bits slice look-up-table 4
*
* @return New CRC value
*/
__forceinline
uint32_t crc32_calc_slice4(const uint8_t *data,
uint32_t data_len, uint32_t crc,
const uint32_t *slice1, const uint32_t *slice2,
const uint32_t *slice3, const uint32_t *slice4)
{
uint_fast32_t i;
if (unlikely(data == NULL))
return crc;
if (unlikely(slice1 == NULL || slice2 == NULL ||
slice3 == NULL || slice4 == NULL))
return crc;
crc = bswap4(crc);
for (i = data_len & (~3), data += (data_len & (~3)); i != 0;
i -= sizeof(uint32_t)) {
crc ^= (*((const uint32_t *)(data - i)));
crc = slice4[(uint8_t)(crc)] ^
slice3[(uint8_t)(crc >> 8)] ^
slice2[(uint8_t)(crc >> 16)] ^
slice1[(uint8_t)(crc >> 24)];
}
crc = bswap4(crc);
for (i = data_len & 3, data += (data_len & 3); i != 0; i--)
crc = (crc << 8) ^
bswap4(slice1[(crc >> 24) ^ *(data - i)]);
return crc;
}
/**
* @brief Performs one folding round
*
* Logically function operates as follows:
* DATA = READ_NEXT_16BYTES();
* F1 = LSB8(FOLD)
* F2 = MSB8(FOLD)
* T1 = CLMUL( F1, K1 )
* T2 = CLMUL( F2, K2 )
* FOLD = XOR( T1, T2, DATA )
*
* @param data_block 16 byte data block
* @param k1_k2 k1 and k2 constanst enclosed in XMM register
* @param fold running 16 byte folded data
*
* @return New 16 byte folded data
*/
__forceinline
__m128i crc32_folding_round(const __m128i data_block,
const __m128i k1_k2,
const __m128i fold)
{
__m128i tmp = _mm_clmulepi64_si128(fold, k1_k2, 0x11);
return _mm_xor_si128(_mm_clmulepi64_si128(fold, k1_k2, 0x00),
_mm_xor_si128(data_block, tmp));
}
/**
* @brief Performs Barret's reduction from 128 bits to 64 bits
*
* @param data128 128 bits data to be reduced
* @param k3_q k3 and Q constants enclosed in XMM register
*
* @return data reduced to 64 bits
*/
__forceinline
__m128i crc32_reduce_128_to_64(__m128i data128, const __m128i k3_q)
{
__m128i tmp;
tmp = _mm_xor_si128(_mm_clmulepi64_si128(data128, k3_q, 0x01 /* k3 */),
data128);
data128 = _mm_xor_si128(_mm_clmulepi64_si128(tmp, k3_q, 0x01 /* k3 */),
data128);
return _mm_srli_si128(_mm_slli_si128(data128, 8), 8);
}
/**
* @brief Performs Barret's reduction from 64 bits to 32 bits
*
* @param data64 64 bits data to be reduced
* @param k3_q k3 and Q constants enclosed in XMM register
* @param p_res P constant enclosed in XMM register
*
* @return data reduced to 32 bits
*/
__forceinline
uint32_t
crc32_reduce_64_to_32(__m128i fold, const __m128i k3_q, const __m128i p_res)
{
__m128i temp;
temp = _mm_clmulepi64_si128(_mm_srli_si128(fold, 4),
k3_q, 0x10 /* Q */);
temp = _mm_srli_si128(_mm_xor_si128(temp, fold), 4);
temp = _mm_clmulepi64_si128(temp, p_res, 0 /* P */);
return _mm_extract_epi32(_mm_xor_si128(temp, fold), 0);
}
/**
* @brief Calculates 32 bit CRC for given \a data block by applying folding and
* reduction methods.
*
* Algorithm operates on 32 bit CRCs so polynomials and initial values may
* need to be promoted to 32 bits where required.
*
* @param crc initial CRC value (32 bit value)
* @param data pointer to data block
* @param data_len length of \a data block in bytes
* @param params pointer to PCLMULQDQ CRC calculation context
*
* @return CRC for given \a data block (32 bits wide).
*/
__forceinline
uint32_t
crc32_calc_pclmulqdq(const uint8_t *data,
uint32_t data_len, uint32_t crc,
const struct crc_pclmulqdq_ctx *params)
{
__m128i temp, fold, k, swap;
uint32_t n;
if (unlikely(data == NULL || data_len == 0 || params == NULL))
return crc;
#ifdef __KERNEL__
/**
* Preserve FPU context
*/
kernel_fpu_begin();
#endif
/**
* Add 4 bytes to data block size
* This is to secure the following:
* CRC32 = M(X)^32 mod P(X)
* M(X) - message to compute CRC on
* P(X) - CRC polynomial
*/
data_len += 4;
/**
* Load first 16 data bytes in \a fold and
* set \a swap BE<->LE 16 byte conversion variable
*/
fold = _mm_loadu_si128((__m128i *)data);
swap = crc_xmm_be_le_swap128;
/**
* -------------------------------------------------
* Folding all data into single 16 byte data block
* Assumes: \a fold holds first 16 bytes of data
*/
if (unlikely(data_len <= 16)) {
/**
* Data block fits into 16 byte block
* - adjust data block
* - 4 least significant bytes need to be zero
*/
fold = _mm_shuffle_epi8(fold, swap);
fold = _mm_slli_si128(xmm_shift_right(fold, 20 - data_len), 4);
/**
* Apply CRC init value
*/
temp = _mm_insert_epi32(_mm_setzero_si128(), bswap4(crc), 0);
temp = xmm_shift_left(temp, data_len - 4);
fold = _mm_xor_si128(fold, temp);
} else {
/**
* There are 2x16 data blocks or more
*/
__m128i next_data;
/**
* n = number of bytes required to align \a data_len
* to multiple of 16
*/
n = ((~data_len) + 1) & 15;
/**
* Apply CRC initial value and
* get \a fold to BE format
*/
fold = _mm_xor_si128(fold,
_mm_insert_epi32(_mm_setzero_si128(),
crc, 0));
fold = _mm_shuffle_epi8(fold, swap);
/**
* Load next 16 bytes of data and
* adjust \a fold & \a next_data as follows:
*
* CONCAT(fold,next_data) >> (n*8)
*/
next_data = _mm_loadu_si128((__m128i *)&data[16]);
next_data = _mm_shuffle_epi8(next_data, swap);
next_data = _mm_or_si128(xmm_shift_right(next_data, n),
xmm_shift_left(fold, 16 - n));
fold = xmm_shift_right(fold, n);
if (unlikely(data_len <= 32))
/**
* In such unlikely case clear 4 least significant bytes
*/
next_data =
_mm_slli_si128(_mm_srli_si128(next_data, 4), 4);
/**
* Do the initial folding round on 2 first 16 byte chunks
*/
k = _mm_load_si128((__m128i *)(&params->k1));
fold = crc32_folding_round(next_data, k, fold);
if (likely(data_len > 32)) {
/**
* \a data_block needs to be at least 48 bytes long
* in order to get here
*/
__m128i new_data;
/**
* Main folding loop
* - n is adjusted to point to next 16 data block
* to read
* (16+16) = 2x16; represents 2 first data blocks
* processed above
* (- n) is the number of zero bytes padded to
* the message in order to align it to 16 bytes
* - the last 16 bytes is processed separately
*/
for (n = 16 + 16 - n; n < (data_len - 16); n += 16) {
new_data = _mm_loadu_si128((__m128i *)&data[n]);
new_data = _mm_shuffle_epi8(new_data, swap);
fold = crc32_folding_round(new_data, k, fold);
}
/**
* The last folding round works always on 12 bytes
* (12 bytes of data and 4 zero bytes)
* Read from offset -4 is to avoid one
* shift right operation.
*/
new_data = _mm_loadu_si128((__m128i *)&data[n - 4]);
new_data = _mm_shuffle_epi8(new_data, swap);
new_data = _mm_slli_si128(new_data, 4);
fold = crc32_folding_round(new_data, k, fold);
} /* if (data_len > 32) */
}
/**
* -------------------------------------------------
* Reduction 128 -> 32
* Assumes: \a fold holds 128bit folded data
*/
/**
* REDUCTION 128 -> 64
*/
k = _mm_load_si128((__m128i *)(&params->k3));
fold = crc32_reduce_128_to_64(fold, k);
/**
* REDUCTION 64 -> 32
*/
n = crc32_reduce_64_to_32(fold, k,
_mm_load_si128((__m128i *)(&params->p)));
#ifdef __KERNEL__
/**
* - restore FPU context
*/
kernel_fpu_end();
#endif
return n;
}
#endif /* __CRC_H__ */
+73 -13
View File
@@ -30,10 +30,17 @@
Modified in June, 2001, to include the length non multiple of 8
*/
#ifndef __SSE4_1__
#define USE_INTEL_CRC 0
#else
#define USE_INTEL_CRC __SSE4_1__
#endif
#include "coding_defs.h"
#include "assertions.h"
#if USE_INTEL_CRC
#include "crc.h"
#endif
/*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */
@@ -94,6 +101,28 @@ static unsigned short crc11Table[256];
static unsigned char crc8Table[256];
static unsigned char crc6Table[256];
#if USE_INTEL_CRC
static DECLARE_ALIGNED(struct crc_pclmulqdq_ctx lte_crc24a_pclmulqdq, 16) = {
0x64e4d700, /**< k1 */
0x2c8c9d00, /**< k2 */
0xd9fe8c00, /**< k3 */
0xf845fe24, /**< q */
0x864cfb00, /**< p */
0ULL /**< res */
};
__m128i crc_xmm_be_le_swap128;
DECLARE_ALIGNED(const uint8_t crc_xmm_shift_tab[48], 16) = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
#endif
void crcTableInit (void)
{
unsigned char c = 0;
@@ -108,23 +137,29 @@ void crcTableInit (void)
crc8Table[c] = (unsigned char) (crcbit (&c, 1, poly8) >> 24);
crc6Table[c] = (unsigned char) (crcbit (&c, 1, poly6) >> 24);
} while (++c);
#if USE_INTEL_CRC
crc_xmm_be_le_swap128 = _mm_setr_epi32(0x0c0d0e0f, 0x08090a0b,
0x04050607, 0x00010203);
#endif
}
/*********************************************************
Byte by byte implementations,
Byte by byte LUT implementations,
assuming initial byte is 0 padded (in MSB) if necessary
can use SIMD optimized Intel CRC for LTE/NR 24a/24b variants
*********************************************************/
unsigned int crc24a (unsigned char * inptr,
int bitlen)
{
int octetlen = bitlen / 8; /* Change in octets */
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
if ( bitlen % 8 || !USE_INTEL_CRC ) {
unsigned int crc = 0;
int resbit= (bitlen % 8);
while (octetlen-- > 0) {
// printf("crc24a: in %x => crc %x\n",crc,*inptr);
crc = (crc << 8) ^ crc24aTable[(*inptr++) ^ (crc >> 24)];
@@ -132,17 +167,35 @@ unsigned int crc24a (unsigned char * inptr,
if (resbit > 0)
crc = (crc << resbit) ^ crc24aTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
#if USE_INTEL_CRC
else {
return crc32_calc_pclmulqdq(inptr, octetlen, 0,
&lte_crc24a_pclmulqdq);
}
#endif
}
#if USE_INTEL_CRC
static DECLARE_ALIGNED(struct crc_pclmulqdq_ctx lte_crc24b_pclmulqdq, 16) = {
0x80140500, /**< k1 */
0x42000100, /**< k2 */
0x90042100, /**< k3 */
0xffff83ff, /**< q */
0x80006300, /**< p */
0ULL /**< res */
};
#endif
unsigned int crc24b (unsigned char * inptr,
int bitlen)
int bitlen)
{
int octetlen, resbit;
int octetlen = bitlen / 8; /* Change in octets */
if ( bitlen % 8 || !USE_INTEL_CRC ) {
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
int resbit = (bitlen % 8);
while (octetlen-- > 0) {
// printf("crc24b: in %x => crc %x (%x)\n",crc,*inptr,crc24bTable[(*inptr) ^ (crc >> 24)]);
@@ -153,6 +206,13 @@ unsigned int crc24b (unsigned char * inptr,
crc = (crc << resbit) ^ crc24bTable[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
#if USE_INTEL_CRC
else {
return crc32_calc_pclmulqdq(inptr, octetlen, 0,
&lte_crc24b_pclmulqdq);
}
#endif
}
unsigned int crc24c (unsigned char * inptr,
+89
View File
@@ -0,0 +1,89 @@
/*******************************************************************************
Copyright (c) 2009-2018, Intel Corporation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* Header file with CRC external definitions
*
*/
#ifndef __CRCEXT_H__
#define __CRCEXT_H__
#include <x86intrin.h>
#include "types.h"
/**
* Flag indicating availability of PCLMULQDQ instruction
* Only valid after running CRCInit() function.
*/
extern int pclmulqdq_available;
/**
* Flag indicating availability of PCLMULQDQ instruction
* Only valid after running CRCInit() function.
*/
extern __m128i crc_xmm_be_le_swap128;
extern const uint8_t crc_xmm_shift_tab[48];
/**
* @brief Shifts right 128 bit register by specified number of bytes
*
* @param reg 128 bit value
* @param num number of bytes to shift right \a reg by (0-16)
*
* @return \a reg >> (\a num * 8)
*/
__forceinline
__m128i xmm_shift_right(__m128i reg, const unsigned int num)
{
const __m128i *p = (const __m128i *)(crc_xmm_shift_tab + 16 + num);
return _mm_shuffle_epi8(reg, _mm_loadu_si128(p));
}
/**
* @brief Shifts left 128 bit register by specified number of bytes
*
* @param reg 128 bit value
* @param num number of bytes to shift left \a reg by (0-16)
*
* @return \a reg << (\a num * 8)
*/
__forceinline
__m128i xmm_shift_left(__m128i reg, const unsigned int num)
{
const __m128i *p = (const __m128i *)(crc_xmm_shift_tab + 16 - num);
return _mm_shuffle_epi8(reg, _mm_loadu_si128(p));
}
/**
* @brief Initializes CRC module.
* @note It is mandatory to run it before using any of CRC API's.
*/
extern void CRCInit(void);
#endif /* __CRCEXT_H__ */
+26 -11
View File
@@ -22,6 +22,7 @@
// encoder interface
#ifndef __NRLDPC_DEFS__H__
#define __NRLDPC_DEFS__H__
#include <openair1/PHY/defs_nr_common.h>
#include "openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
/**
\brief LDPC encoder
@@ -36,17 +37,31 @@
\param 9-12 time_stats_t *tinput,*tprep, *tparity,*toutput
*/
typedef struct {
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;
}encoder_implemparams_t;
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;
uint32_t Kb;
uint32_t *Zc;
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;
/// LDPC-code outputs
uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
} encoder_implemparams_t;
#define INIT0_LDPCIMPLEMPARAMS {0,0,0,NULL,NULL,NULL,NULL}
typedef void(*nrLDPC_initcallfunc_t)(t_nrLDPC_dec_params* p_decParams, int8_t* p_llr, int8_t* p_out);
typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t*);
typedef void(*nrLDPC_initcallfunc_t)(t_nrLDPC_dec_params *p_decParams, int8_t *p_llr, int8_t *p_out);
typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,short, short, encoder_implemparams_t *);
//============================================================================================================================
// decoder interface
/**
@@ -56,5 +71,5 @@ typedef int(*nrLDPC_encoderfunc_t)(unsigned char **,unsigned char **,int,int,sho
\param p_llrOut Output vector
\param p_profiler LDPC profiler statistics
*/
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params* , int8_t*, int8_t* , t_nrLDPC_procBuf* , t_nrLDPC_time_stats* );
typedef int32_t(*nrLDPC_decoderfunc_t)(t_nrLDPC_dec_params *, int8_t *, int8_t *, t_nrLDPC_procBuf *, t_nrLDPC_time_stats * );
#endif
@@ -38,8 +38,6 @@
#include "common/utils/LOG/log.h"
//#define DEBUG_LDPC
#include "ldpc384_byte.c"
#include "ldpc352_byte.c"
#include "ldpc320_byte.c"
@@ -73,9 +71,18 @@
static inline void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,short Kb)
static void encode_parity_check_part_optim(uint8_t *cc,uint8_t *d, short BG,short Zc,short Kb, int simd_size, int ncols)
{
unsigned char c[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
for (int i1=0; i1 < ncols; i1++) {
memcpy(&c[2*i1*Zc], &cc[i1*Zc], Zc*sizeof(unsigned char));
memcpy(&c[(2*i1+1)*Zc], &cc[i1*Zc], Zc*sizeof(unsigned char));
}
for (int i1=1;i1<simd_size;i1++) {
memcpy(&c[(2*ncols*Zc*i1)], &c[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
}
if (BG==1)
{
switch (Zc)
@@ -39,8 +39,6 @@
#include "PHY/TOOLS/time_meas.h"
#include "defs.h"
//#define DEBUG_LDPC
#include "ldpc384_byte.c"
#include "ldpc352_byte.c"
#include "ldpc320_byte.c"
@@ -40,9 +40,6 @@
#include "openair1/PHY/CODING/nrLDPC_defs.h"
#include "ldpc_encode_parity_check.c"
#include "ldpc_generate_coefficient.c"
//#define DEBUG_LDPC
@@ -50,7 +47,7 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
{
short nrows=0,ncols=0;
int i,i1,rate=3;
int rate=3;
int no_punctured_columns,removed_bit;
int simd_size;
@@ -86,8 +83,6 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*rate);
@@ -98,7 +93,7 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
memset(d,0,sizeof(unsigned char) * nrows * Zc);
if(impp->tinput != NULL) start_meas(impp->tinput);
for (i=0; i<block_length; i++) {
for (int i=0; i<block_length; i++) {
c[i] = (test_input[0][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
}
@@ -108,24 +103,10 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
// extend matrix
if(impp->tprep != NULL) start_meas(impp->tprep);
for (i1=0; i1 < ncols; i1++)
{
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
}
for (i1=1;i1<simd_size;i1++) {
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
/*
printf("shift %d: ",i1);
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
printf("\n");
*/
}
if(impp->tprep != NULL) stop_meas(impp->tprep);
//parity check part
if(impp->tparity != NULL) start_meas(impp->tparity);
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
encode_parity_check_part_optim(c, d, BG, Zc, Kb,simd_size, ncols);
if(impp->tparity != NULL) stop_meas(impp->tparity);
}
else {
@@ -38,7 +38,6 @@
#include "common/utils/LOG/log.h"
#include "PHY/TOOLS/time_meas.h"
#include "openair1/PHY/CODING/nrLDPC_defs.h"
//#define DEBUG_LDPC
#include "ldpc_encode_parity_check.c"
#include "ldpc_generate_coefficient.c"
@@ -102,7 +101,6 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
@@ -151,24 +149,10 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
// extend matrix
if(impp->tprep != NULL) start_meas(impp->tprep);
for (i1=0; i1 < ncols; i1++)
{
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
}
for (i1=1;i1<simd_size;i1++) {
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
/*
printf("shift %d: ",i1);
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
printf("\n");
*/
}
if(impp->tprep != NULL) stop_meas(impp->tprep);
//parity check part
if(impp->tparity != NULL) start_meas(impp->tparity);
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
encode_parity_check_part_optim(c, d, BG, Zc, Kb, simd_size, ncols);
if(impp->tparity != NULL) stop_meas(impp->tparity);
}
else {
@@ -39,17 +39,17 @@
#include "PHY/TOOLS/time_meas.h"
#include "openair1/PHY/CODING/nrLDPC_defs.h"
//#define DEBUG_LDPC
#include "ldpc_encode_parity_check.c"
#include "ldpc_generate_coefficient.c"
int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
int nrLDPC_encod(unsigned char **input,unsigned char **output,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp)
{
//set_log(PHY, 4);
short nrows=0,ncols=0;
int i,i1,j,rate=3;
int nrows=0,ncols=0;
int rate=3;
int no_punctured_columns,removed_bit;
//Table of possible lifting sizes
char temp;
@@ -95,8 +95,8 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
}
#ifdef DEBUG_LDPC
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,impp->n_segments);
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",input[0][0],input[0][1],input[0][2],input[0][3]);
#endif
AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
@@ -104,10 +104,8 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
if ((Zc&31) > 0) simd_size = 16;
else simd_size = 32;
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
unsigned char cc[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char dd[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*rate)/Zc;
@@ -115,8 +113,8 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
//printf("%d\n",no_punctured_columns);
//printf("%d\n",removed_bit);
// unpack input
memset(c,0,sizeof(unsigned char) * ncols * Zc);
memset(d,0,sizeof(unsigned char) * nrows * Zc);
memset(cc,0,sizeof(unsigned char) * ncols * Zc);
memset(dd,0,sizeof(unsigned char) * nrows * Zc);
if(impp->tinput != NULL) start_meas(impp->tinput);
#if 0
@@ -124,29 +122,29 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
//for (j=0; j<n_segments; j++) {
for (j=macro_segment; j < macro_segment_end; j++) {
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
temp = (input[j][i/8]&(1<<(i&7)))>>(i&7);
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << (j-macro_segment));
}
}
#else
#ifdef __AVX2__
for (i=0; i<block_length>>5; i++) {
c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
for (int i=0; i<block_length>>5; i++) {
c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
//for (j=1; j<n_segments; j++) {
for (j=macro_segment+1; j < macro_segment_end; j++) {
c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j-macro_segment]),c256);
for (int j=macro_segment+1; j < macro_segment_end; j++) {
c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)input[j])[i]), shufmask),andmask),zero256),masks[j-macro_segment]),c256);
}
((__m256i *)c)[i] = c256;
((__m256i *)cc)[i] = c256;
}
for (i=(block_length>>5)<<5;i<block_length;i++) {
for (int i=(block_length>>5)<<5;i<block_length;i++) {
//for (j=0; j<n_segments; j++) {
for (j=macro_segment; j < macro_segment_end; j++) {
for (int j=macro_segment; j < macro_segment_end; j++) {
temp = (test_input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
temp = (input[j][i/8]&(128>>(i&7)))>>(7-(i&7));
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << (j-macro_segment));
cc[i] |= (temp << (j-macro_segment));
}
}
#else
@@ -159,28 +157,14 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
// extend matrix
if(impp->tprep != NULL) start_meas(impp->tprep);
for (i1=0; i1 < ncols; i1++)
{
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
}
for (i1=1;i1<simd_size;i1++) {
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
/*
printf("shift %d: ",i1);
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
printf("\n");
*/
}
if(impp->tprep != NULL) stop_meas(impp->tprep);
//parity check part
if(impp->tparity != NULL) start_meas(impp->tparity);
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
encode_parity_check_part_optim(cc, dd, BG, Zc, Kb, simd_size, ncols);
if(impp->tparity != NULL) stop_meas(impp->tparity);
}
else {
if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
if (encode_parity_check_part_orig(cc, dd, BG, Zc, Kb, block_length)!=0) {
printf("Problem with encoder\n");
return(-1);
}
@@ -188,8 +172,8 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
if(impp->toutput != NULL) start_meas(impp->toutput);
// information part and puncture columns
/*
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
memcpy(&output[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&output[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
*/
#ifdef __AVX2__
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
@@ -197,34 +181,34 @@ int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
uint32_t l1 = (block_length-(2*Zc))>>5;
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
__m256i *c256p = (__m256i *)&c[2*Zc];
__m256i *d256p = (__m256i *)&d[0];
__m256i *c256p = (__m256i *)&cc[2*Zc];
__m256i *d256p = (__m256i *)&dd[0];
// if (((block_length-(2*Zc))&31)>0) l1++;
for (i=0;i<l1;i++)
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
for (int i=0;i<l1;i++)
//for (j=0;j<n_segments;j++) ((__m256i *)output[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
for (int j=macro_segment; j < macro_segment_end; j++) ((__m256i *)output[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
for (i1=0;i1<l2;i1++,i++)
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
for (int i1=0, i=l1;i1<l2;i1++,i++)
//for (j=0;j<n_segments;j++) ((__m256i *)output[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
for (int j=macro_segment; j < macro_segment_end; j++) ((__m256i *)output[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
}
else {
#ifdef DEBUG_LDPC
LOG_W(PHY,"using non-optimized version\n");
#endif
// do non-SIMD version
for (i=0;i<(block_length-2*Zc);i++)
for (int i=0;i<(block_length-2*Zc);i++)
//for (j=0; j<n_segments; j++)
for (j=macro_segment; j < macro_segment_end; j++)
channel_input[j][i] = (c[2*Zc+i]>>(j-macro_segment))&1;
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
for (int j=macro_segment; j < macro_segment_end; j++)
output[j][i] = (cc[2*Zc+i]>>(j-macro_segment))&1;
for (int i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
//for (j=0; j<n_segments; j++)
for (j=macro_segment; j < macro_segment_end; j++)
channel_input[j][block_length-2*Zc+i] = (d[i]>>(j-macro_segment))&1;
for (int j=macro_segment; j < macro_segment_end; j++)
output[j][block_length-2*Zc+i] = (dd[i]>>(j-macro_segment))&1;
}
#else
+98
View File
@@ -0,0 +1,98 @@
/*******************************************************************************
Copyright (c) 2009-2018, Intel Corporation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/* Common data types, macros and functions used across the CRC library */
#ifndef CRC_TYPES_H_
#define CRC_TYPES_H_
#ifdef __KERNEL__
#include <asm/i387.h>
#include <linux/types.h>
typedef uint32_t uint_fast32_t;
typedef uint16_t uint_fast16_t;
typedef uint8_t uint_fast8_t;
#else
#include <stdint.h>
#include <stddef.h>
#endif
/* Declare variable at address aligned to a boundary */
#define DECLARE_ALIGNED(_declaration, _boundary) \
_declaration __attribute__((aligned(_boundary)))
/* Macro to make function to be always inlined */
#ifndef DEBUG
#define __forceinline \
static inline __attribute__((always_inline))
#else
#define __forceinline \
static
#endif
/* Likely & unliekly hints for the compiler */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
/* Macro to get dimension of an array */
#ifndef DIM
#define DIM(x) (sizeof(x)/sizeof(x[0]))
#endif
/**
* Common functions
*/
/**
* @brief Swaps bytes in 16 bit word
*
* @param val 16 bit data value
*
* @return byte swapped value
*/
__forceinline uint16_t bswap2(const uint16_t val)
{
return (uint16_t) ((val >> 8) | (val << 8));
}
/**
* @brief Swaps bytes in 32 bit word
* ABCD -> DCBA
*
* @param val 32 bit data value
*
* @return byte swapped value
*/
__forceinline uint32_t bswap4(const uint32_t val)
{
return ((val >> 24) | /**< A*/
((val & 0xff0000) >> 8) | /**< B*/
((val & 0xff00) << 8) | /**< C*/
(val << 24)); /**< D*/
}
#endif /* CRC_TYPES_H_ */
+1 -1
View File
@@ -458,7 +458,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->decode_SIB = 1;
init_nr_prach_tables(839);
init_symbol_rotation(fp);
return 0;
}
-1
View File
@@ -209,7 +209,6 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp)
return samp_count;
}
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp)
{
uint32_t slot_idx = 0;
+1 -2
View File
@@ -36,8 +36,7 @@
\param reset resets the generator
\return 32 bits of the gold sequence
*/
uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
/*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals.
@param frame_parms LTE DL Frame parameters
@@ -1,75 +0,0 @@
/*
* 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
*/
#include "PHY/types.h"
/**
\brief Gold Sequence Generation defined in 3x.211
\param x1 x1 shift register
\param x2 x2 shift register / cinit if reset is set
\param reset Reset flag / reinitialize the generator
\return c 32 bits of gold output
*/
extern inline uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset)
{
int32_t n;
// 3GPP 3x.211
// Nc = 1600
// c(n) = [x1(n+Nc) + x2(n+Nc)]mod2
// x1(n+31) = [x1(n+3) + x1(n)]mod2
// x2(n+31) = [x2(n+3) + x2(n+2) + x2(n+1) + x2(n)]mod2
if (reset)
{
// Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30
// x1(31) = [x1(3) + x1(0)]mod2 = 1
*x1 = 1 + (1U<<31);
// Init value for x2: cinit = sum_{i=0}^30 x2*2^i
// x2(31) = [x2(3) + x2(2) + x2(1) + x2(0)]mod2
// = (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2
*x2 = *x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
// x1 and x2 contain bits n = 0,1,...,31
// Nc = 1600 bits are skipped at the beginning
// i.e., 1600 / 32 = 50 32bit words
for (n = 1; n < 50; n++)
{
// Compute x1(0),...,x1(27)
*x1 = (*x1>>1) ^ (*x1>>4);
// Compute x1(28),..,x1(31) and xor
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
// Compute x2(0),...,x2(27)
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
// Compute x2(28),..,x2(31) and xor
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
}
}
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
// c(n) = [x1(n+Nc) + x2(n+Nc)]mod2
return(*x1^*x2);
}
+11 -11
View File
@@ -147,10 +147,10 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb) {
}
}
int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe, uint8_t symbol) {
int adjust_G2(int Ncp, int frame_type, int N_RB_DL, uint32_t *rb_alloc, uint8_t mod_order, uint8_t subframe, uint8_t symbol) {
int rb,re_pbch_sss=0;
int rb_alloc_ind,nsymb;
nsymb = (frame_parms->Ncp==NORMAL) ? 14 : 12;
nsymb = (Ncp==NORMAL) ? 14 : 12;
// printf("adjust_G2 : symbol %d, subframe %d\n",symbol,subframe);
if ((subframe!=0) && (subframe!=5) && (subframe!=6)) // if not PBCH/SSS or SSS
@@ -158,12 +158,12 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_o
//first half of slot and TDD (no adjustments in first slot except for subframe 6 - PSS)
if ((symbol<(nsymb>>1))&&
(frame_parms->frame_type == TDD)&&
(frame_type == TDD)&&
(subframe!=6))
return(0);
// after PBCH
if (frame_parms->frame_type==TDD) { //TDD
if (frame_type==TDD) { //TDD
if ((symbol>((nsymb>>1)+3)) &&
(symbol!=(nsymb-1))) ///SSS
return(0);
@@ -185,9 +185,9 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_o
return(0);
}
if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL
for (rb=((frame_parms->N_RB_DL>>1)-3);
rb<=((frame_parms->N_RB_DL>>1)+3);
if ((N_RB_DL&1) == 1) { // ODD N_RB_DL
for (rb=((N_RB_DL>>1)-3);
rb<=((N_RB_DL>>1)+3);
rb++) {
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
@@ -201,16 +201,16 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms, uint32_t *rb_alloc, uint8_t mod_o
rb_alloc_ind = 0;
if (rb_alloc_ind==1) {
if ((rb==(frame_parms->N_RB_DL>>1)-3) ||
(rb==((frame_parms->N_RB_DL>>1)+3))) {
if ((rb==(N_RB_DL>>1)-3) ||
(rb==((N_RB_DL>>1)+3))) {
re_pbch_sss += 6;
} else
re_pbch_sss += 12;
}
}
} else {
for (rb=((frame_parms->N_RB_DL>>1)-3);
rb<((frame_parms->N_RB_DL>>1)+3);
for (rb=((N_RB_DL>>1)-3);
rb<((N_RB_DL>>1)+3);
rb++) {
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
+1 -1
View File
@@ -44,7 +44,7 @@ void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
{
uint32_t i;
uint8_t reset;
uint32_t x1, x2, s=0;
uint32_t x1=0, x2, s=0;
reset = 1;
// x1 is set in lte_gold_generic
+1 -1
View File
@@ -895,7 +895,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
int frame,
uint8_t subframe,
uint8_t pucch1_thres,
uint8_t br_flag
int br_flag
)
//-----------------------------------------------------------------------------
{
@@ -101,7 +101,7 @@ int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint
int get_G_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
int adjust_G2(int Ncp, int frame_type, int N_RB_DL, uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
#ifndef modOrder
+45 -1
View File
@@ -700,7 +700,51 @@ int find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
int find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
static inline uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset)
{
int32_t n;
// 3GPP 3x.211
// Nc = 1600
// c(n) = [x1(n+Nc) + x2(n+Nc)]mod2
// x1(n+31) = [x1(n+3) + x1(n)]mod2
// x2(n+31) = [x2(n+3) + x2(n+2) + x2(n+1) + x2(n)]mod2
if (reset)
{
// Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30
// x1(31) = [x1(3) + x1(0)]mod2 = 1
*x1 = 1 + (1U<<31);
// Init value for x2: cinit = sum_{i=0}^30 x2*2^i
// x2(31) = [x2(3) + x2(2) + x2(1) + x2(0)]mod2
// = (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2
*x2 = *x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
// x1 and x2 contain bits n = 0,1,...,31
// Nc = 1600 bits are skipped at the beginning
// i.e., 1600 / 32 = 50 32bit words
for (n = 1; n < 50; n++)
{
// Compute x1(0),...,x1(27)
*x1 = (*x1>>1) ^ (*x1>>4);
// Compute x1(28),..,x1(31) and xor
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
// Compute x2(0),...,x2(27)
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
// Compute x2(28),..,x2(31) and xor
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
}
}
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
// c(n) = [x1(n+Nc) + x2(n+Nc)]mod2
return(*x1^*x2);
}
/**@}*/
+1 -1
View File
@@ -1293,7 +1293,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
}
granted_re = nb_rb_alloc * (12-crs_re);
pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
pbch_pss_sss_re = adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
data_re = granted_re - pbch_pss_sss_re;
llr_offset = data_re * dlsch0_harq->Qm * 2;
@@ -837,7 +837,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
symbol,
first_symbol_flag,
nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
beamforming_mode);
} else if (codeword_TB0 == -1) {
dlsch_qpsk_llr(frame_parms,
@@ -846,7 +846,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
symbol,
first_symbol_flag,
nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
beamforming_mode);
} else if (rx_type >= rx_IC_single_stream) {
if (dlsch1_harq->Qm == 2) {
@@ -856,7 +856,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -866,7 +866,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else if (dlsch1_harq->Qm == 4) {
@@ -877,7 +877,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -888,7 +888,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else {
@@ -899,7 +899,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -910,7 +910,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
}
@@ -925,7 +925,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->llr[0],
pdsch_vars[eNB_id]->dl_ch_mag0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128,
beamforming_mode);
} else if (codeword_TB0 == -1) {
@@ -934,7 +934,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->llr[1],
pdsch_vars[eNB_id]->dl_ch_mag0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream,
beamforming_mode);
} else if (rx_type >= rx_IC_single_stream) {
@@ -946,7 +946,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -957,7 +957,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else if (dlsch1_harq->Qm == 4) {
@@ -969,7 +969,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -981,7 +981,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else {
@@ -993,7 +993,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -1005,7 +1005,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
}
@@ -1021,7 +1021,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr_offset[symbol],
beamforming_mode);
} else if (codeword_TB0 == -1) {
@@ -1031,7 +1031,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr_offset[symbol],
beamforming_mode);
} else if (rx_type >= rx_IC_single_stream) {
@@ -1043,7 +1043,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -1054,7 +1054,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,2,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else if (dlsch1_harq->Qm == 4) {
@@ -1066,7 +1066,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
pdsch_vars[eNB_id]->llr[0],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr128);
if (rx_type==rx_IC_dual_stream) {
@@ -1078,7 +1078,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
pdsch_vars[eNB_id]->llr[1],
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128_2ndstream);
}
} else {
@@ -1090,7 +1090,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho2_ext,
(int16_t *)pllr_symbol_cw0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr_offset[symbol]);
if (rx_type==rx_IC_dual_stream) {
@@ -1102,7 +1102,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
(int16_t *)pllr_symbol_cw1,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr_offset[symbol]);
}
}
@@ -1124,7 +1124,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->rxdataF_comp0,
(int16_t *)pllr_symbol_cw0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
beamforming_mode);
}
@@ -1137,7 +1137,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->llr[0],
pdsch_vars[eNB_id]->dl_ch_mag0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
pdsch_vars[eNB_id]->llr128,
beamforming_mode);
}
@@ -1152,7 +1152,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
pdsch_vars[eNB_id]->dl_ch_mag0,
pdsch_vars[eNB_id]->dl_ch_magb0,
symbol,first_symbol_flag,nb_rb,
adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
pdsch_vars[eNB_id]->llr_offset[symbol],
beamforming_mode);
}
@@ -746,7 +746,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation
pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol);
pbch_pss_sss_adjust=adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL ,&rb_alloc,2,subframe,symbol);
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
if (frame_parms->nb_antenna_ports_eNB!=1)
@@ -981,7 +981,7 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,4,subframe,symbol);
pbch_pss_sss_adjust=adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,&rb_alloc,4,subframe,symbol);
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
amp_tmp=0x1fff;//dlsch0->sqrt_rho_b; already taken into account
@@ -1281,7 +1281,7 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol);
pbch_pss_sss_adjust=adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,&rb_alloc,6,subframe,symbol);
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
amp_tmp = 0x1fff;//dlsch0->sqrt_rho_b; already taken into account
+2 -2
View File
@@ -336,8 +336,8 @@ void generate_pucch1x(int32_t **txdataF,
inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) {
static inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
static inline void pucch2x_scrambling(LTE_DL_FRAME_PARMS *fp,int subframe,uint16_t rnti,uint32_t B,uint8_t *btilde) {
uint32_t x1, x2, s=0;
int i;
@@ -1303,7 +1303,7 @@ uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
int get_G(LTE_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
int adjust_G(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
#ifndef modOrder
+139 -70
View File
@@ -180,13 +180,15 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
/// CRC, coding, interleaving and rate matching
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
start_meas(dlsch_encoding_stats);
if (nr_dlsch_encoding(gNB,
harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput,
dlsch_rate_matching_stats,
dlsch_interleaving_stats,
dlsch_segmentation_stats) == -1)
return;
nr_dlsch_encoding(gNB,
harq->pdu, frame, slot, dlsch, frame_parms, output,
tinput,tprep,tparity,toutput,
dlsch_rate_matching_stats,
dlsch_interleaving_stats,
dlsch_segmentation_stats);
stop_meas(dlsch_encoding_stats);
#ifdef DEBUG_DLSCH
printf("PDSCH encoding:\nPayload:\n");
@@ -198,7 +200,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
printf("\nEncoded payload:\n");
for (int i=0; i<encoded_length>>3; i++) {
for (int j=0; j<8; j++)
printf("%d", harq->f[(i<<3)+j]);
printf("%d", output[(i<<3)+j]);
printf("\t");
}
printf("\n");
@@ -211,7 +213,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
for (int q=0; q<rel15->NrOfCodewords; q++)
memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t));
for (int q=0; q<rel15->NrOfCodewords; q++)
nr_pdsch_codeword_scrambling_optim(harq->f,
nr_pdsch_codeword_scrambling_optim(output,
encoded_length,
q,
rel15->dataScramblingId,
@@ -248,7 +250,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
}
#endif
start_meas(&gNB->dlsch_layer_mapping_stats);
/// Layer mapping
nr_layer_mapping(mod_symbs,
rel15->nrOfLayers,
@@ -266,6 +268,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
}
#endif
stop_meas(&gNB->dlsch_layer_mapping_stats);
/// Resource mapping
// Non interleaved VRB to PRB mapping
@@ -279,7 +282,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers);
#endif
start_meas(&gNB->dlsch_resource_mapping_stats);
for (int ap=0; ap<rel15->nrOfLayers; ap++) {
// DMRS params for this ap
@@ -321,20 +324,13 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
dmrs_idx = (rel15->rbStart+rel15->BWPStart)*4;
}
}
}
// Update l_prime in the case of double DMRS config
if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion
if (l==(l_overline+1)) //take into account the double DMRS symbols
l_prime = 1;
else if (l>(l_overline+1)) {//new DMRS pair
l_overline = l;
l_prime = 0;
}
}
/// DMRS QPSK modulation
if (rel15->dlDmrsSymbPos & (1 << l)) {
/// DMRS QPSK modulation
nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DLSCH
@@ -355,73 +351,143 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos);
if(ptrs_symbol) {
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
printf("Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs);
nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs);
}
}
uint16_t k = start_sc;
// Loop Over SCs:
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
/* check if cuurent RE is PTRS RE*/
is_ptrs_re=0;
/* check for PTRS symbol and set flag for PTRS RE */
if(ptrs_symbol){
is_ptrs_re = is_ptrs_subcarrier(k,
rel15->rnti,
ap,
rel15->dmrsConfigType,
rel15->PTRSFreqDensity,
rel15->rbSize,
rel15->PTRSReOffset,
start_sc,
frame_parms->ofdm_symbol_size);
}
if (ptrs_symbol || dmrs_symbol_map & (1 << l)) {
/* Map DMRS Symbol */
if ( ( dmrs_symbol_map & (1 << l) ) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
// Loop Over SCs:
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
/* check if cuurent RE is PTRS RE*/
is_ptrs_re = 0;
if (ptrs_symbol)
is_ptrs_re = is_ptrs_subcarrier(k,
rel15->rnti,
ap,
rel15->dmrsConfigType,
rel15->PTRSFreqDensity,
rel15->rbSize,
rel15->PTRSReOffset,
start_sc,
frame_parms->ofdm_symbol_size);
/* Map DMRS Symbol */
if ( (dmrs_symbol_map & (1 << l)) &&
(k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
dmrs_idx, l, k, k_prime, n, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
dmrs_idx++;
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
}
/* Map PTRS Symbol */
else if(is_ptrs_re){
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
dmrs_idx++;
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
}
else if(is_ptrs_re){
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d, mod_ptrs: %d %d\n",
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)],mod_ptrs[ptrs_idx<<1],mod_ptrs[(ptrs_idx<<1)+1]);
#endif
ptrs_idx++;
}
ptrs_idx++;
}
/* Map DATA Symbol */
else if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
else if( ptrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15;
#ifdef DEBUG_DLSCH_MAPPING
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, k, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]);
#endif
m++;
m++;
}
/* mute RE */
else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
} //RE loop
}
else { // no PTRS or DMRS in this symbol
// Loop Over SCs:
int upper_limit=rel15->rbSize*NR_NB_SC_PER_RB;
int remaining_re = 0;
if (start_sc + upper_limit > frame_parms->ofdm_symbol_size) {
remaining_re = upper_limit + start_sc - frame_parms->ofdm_symbol_size;
upper_limit = frame_parms->ofdm_symbol_size - start_sc;
}
// fix the alignment issues later, use 64-bit SIMD below instead of 128.
if (0/*(frame_parms->N_RB_DL&1)==0*/) {
__m128i *txF=(__m128i*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+start_sc+txdataF_offset)<<1)];
__m128i *txl = (__m128i*)&tx_layers[ap][m<<1];
__m128i amp128=_mm_set1_epi16(amp);
for (int i=0; i<(upper_limit>>2); i++) {
txF[i] = _mm_mulhrs_epi16(amp128,txl[i]);
} //RE loop, first part
m+=upper_limit;
if (remaining_re > 0) {
txF = (__m128i*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+txdataF_offset)<<1)];
txl = (__m128i*)&tx_layers[ap][m<<1];
for (int i=0; i<(remaining_re>>2); i++) {
txF[i] = _mm_mulhrs_epi16(amp128,txl[i]);
}
}
}
/* mute RE */
else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
} //RE loop
__m64 *txF=(__m64*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+start_sc+txdataF_offset)<<1)];
__m64 *txl = (__m64*)&tx_layers[ap][m<<1];
__m64 amp64=_mm_set1_pi16(amp);
for (int i=0; i<(upper_limit>>1); i++) {
txF[i] = _mm_mulhrs_pi16(amp64,txl[i]);
#ifdef DEBUG_DLSCH_MAPPING
if ((i&1) > 0)
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, start_sc+(i>>1), txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1) + 1 + (2*txdataF_offset)]);
#endif
/* handle this, mute RE */
/*else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
}*/
} //RE loop, first part
m+=upper_limit;
if (remaining_re > 0) {
txF = (__m64*)&txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size+txdataF_offset)<<1)];
txl = (__m64*)&tx_layers[ap][m<<1];
for (int i=0; i<(remaining_re>>1); i++) {
txF[i] = _mm_mulhrs_pi16(amp64,txl[i]);
#ifdef DEBUG_DLSCH_MAPPING
if ((i&1) > 0)
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
m, l, i>>1, txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) + (2*txdataF_offset)],
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) + 1 + (2*txdataF_offset)]);
#endif
/* handle this, mute RE */
/*else {
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = 0;
txdataF_precoding[ap][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = 0;
}*/
} //RE loop, second part
} //
m+=remaining_re;
} // N_RB_DL even
} // no DMRS/PTRS in symbol
} // symbol loop
}// layer loop
stop_meas(&gNB->dlsch_resource_mapping_stats);
///Layer Precoding and Antenna port mapping
// tx_layers 1-8 are mapped on antenna ports 1000-1007
@@ -430,7 +496,9 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
// The Precoding matrix:
// The Codebook Type I and Type II are not supported yet.
// We adopt the precoding matrices of PUSCH for 4 layers.
// We`adopt the precoding matrices of PUSCH for 4 layers.
start_meas(&gNB->dlsch_precoding_stats);
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
@@ -505,6 +573,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
} // symbol loop
}// port loop
stop_meas(&gNB->dlsch_precoding_stats);
dlsch->slot_tx[slot]=0;
// TODO: handle precoding
+1 -2
View File
@@ -43,8 +43,6 @@ void nr_check_time_alloc(uint8_t S, uint8_t L,nfapi_nr_dl_tti_pdsch_pdu_rel15_t
uint16_t get_RIV(uint16_t rb_start, uint16_t L, uint16_t N_RB);
uint16_t get_SLIV(uint8_t S, uint8_t L);
uint8_t nr_get_S(uint8_t row_idx, uint8_t CP, uint8_t time_alloc_type, uint8_t dmrs_typeA_position);
void nr_get_rbg_parms(NR_BWP_PARMS* bwp, uint8_t config_type);
@@ -85,6 +83,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
NR_DL_FRAME_PARMS* frame_parms,
unsigned char * output,
time_stats_t *tinput,
time_stats_t *tprep,
time_stats_t *tparity,
+165 -224
View File
@@ -50,70 +50,47 @@
//#define DEBUG_DLSCH_FREE 1
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB)
{
void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) {
int r;
NR_gNB_DLSCH_t *dlsch = *dlschptr;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
if (dlsch) {
if (dlsch) {
if (N_RB != 273) {
a_segments = a_segments*N_RB;
a_segments = a_segments/273 +1;
}
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY,"Freeing dlsch %p\n",dlsch);
#endif
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
if (harq->b) {
free16(harq->b, a_segments * 1056);
harq->b = NULL;
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing harq->b (%p)\n", harq->b);
#endif
if (harq->e) {
free16(harq->e, 14 * N_RB * 12 * 8);
harq->e = NULL;
}
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d e (%p)\n", i, harq->e);
LOG_D(PHY, "Freeing dlsch process %d c (%p)\n", i, harq->c);
#endif
}
if (harq->f) {
free16(harq->f, 14 * N_RB * 12 * 8);
harq->f = NULL;
for (r = 0; r < a_segments; r++) {
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d f (%p)\n", i, harq->f);
LOG_D(PHY, "Freeing dlsch process %d c[%d] (%p)\n", i, r, harq->c[r]);
#endif
}
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing dlsch process %d c (%p)\n", i, harq->c);
#endif
for (r = 0; r < a_segments; r++) {
#ifdef DEBUG_DLSCH_FREE
LOG_D(PHY, "Freeing dlsch process %d c[%d] (%p)\n", i, r, harq->c[r]);
#endif
if (harq->c[r]) {
free16(harq->c[r], 1056);
harq->c[r] = NULL;
}
if (harq->d[r]) {
free16(harq->d[r], 3 * 8448);
harq->d[r] = NULL;
}
if (harq->c[r]) {
free16(harq->c[r], 1056);
harq->c[r] = NULL;
}
}
free16(dlsch, sizeof(NR_gNB_DLSCH_t));
*dlschptr = NULL;
}
free16(dlsch, sizeof(NR_gNB_DLSCH_t));
*dlschptr = NULL;
}
NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
@@ -121,8 +98,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
unsigned char Mdlharq,
uint32_t Nsoft,
uint8_t abstraction_flag,
uint16_t N_RB)
{
uint16_t N_RB) {
unsigned char i,r,aa,layer;
int re;
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
@@ -133,10 +109,8 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
}
uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
NR_gNB_DLSCH_t *dlsch = malloc16(sizeof(NR_gNB_DLSCH_t));
AssertFatal(dlsch, "cannot allocate dlsch\n");
bzero(dlsch,sizeof(NR_gNB_DLSCH_t));
dlsch->Kmimo = Kmimo;
dlsch->Mdlharq = Mdlharq;
@@ -144,11 +118,12 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
dlsch->Nsoft = Nsoft;
for (layer=0; layer<NR_MAX_NB_LAYERS; layer++) {
dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*));
dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(64*sizeof(int32_t *));
for (aa=0; aa<64; aa++) {
dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
for (re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) {
dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
}
}
@@ -160,7 +135,8 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
dlsch->calib_dl_ch_estimates = (int32_t **)malloc16(64*sizeof(int32_t *));
for (aa=0; aa<64; aa++) {
dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t));
}
@@ -172,7 +148,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
bzero(harq, sizeof(NR_DL_gNB_HARQ_t));
harq->b = malloc16(dlsch_bytes);
AssertFatal(harq->b, "cannot allocate memory for harq->b\n");
harq->pdu = malloc16(dlsch_bytes);
@@ -188,71 +163,33 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms,
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
harq->c[r] = malloc16(8448);
AssertFatal(harq->c[r], "cannot allocate harq->c[%d]\n", r);
harq->d[r] = malloc16(68 * 384);
AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output
bzero(harq->c[r], 8448);
bzero(harq->d[r], (3 * 8448));
}
harq->e = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
AssertFatal(harq->e, "cannot allocate harq->e\n");
bzero(harq->e, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
AssertFatal(harq->f, "cannot allocate harq->f\n");
bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
return(dlsch);
}
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
{
unsigned char Mdlharq;
unsigned char i,j,r;
void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) {
AssertFatal(dlsch!=NULL,"dlsch is null\n");
Mdlharq = dlsch->Mdlharq;
unsigned char Mdlharq = dlsch->Mdlharq;
dlsch->rnti = 0;
dlsch->active = 0;
NR_DL_gNB_HARQ_t *harq=&dlsch->harq_process;
for (i=0; i<10; i++) {
for (int i=0; i<10; i++) {
dlsch->harq_ids[0][i] = Mdlharq;
dlsch->harq_ids[1][i] = Mdlharq;
}
for (i=0; i<Mdlharq; i++) {
for (j=0; j<96; j++)
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS; r++)
if (harq->d[r])
harq->d[r][j] = NR_NULL;
}
}
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
unsigned char *a,
int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
NR_DL_FRAME_PARMS* frame_parms,
time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats)
{
unsigned int G;
unsigned int crc=1;
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
void ldpc8blocks( void *p) {
encoder_implemparams_t *impp=(encoder_implemparams_t *) p;
NR_DL_gNB_HARQ_t *harq = (NR_DL_gNB_HARQ_t *)impp->harq;
uint16_t Kr= impp->K;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
uint8_t mod_order = rel15->qamModOrder[0];
uint16_t nb_rb = rel15->rbSize;
uint8_t nb_symb_sch = rel15->NrOfSymbols;
uint32_t A, Kb, F=0;
uint32_t *Zc = &dlsch->harq_process.Z;
uint8_t mod_order = rel15->qamModOrder[0];
uint16_t Kr=0,r;
uint32_t r_offset=0;
uint32_t E;
uint8_t Ilbrm = 1;
uint32_t Tbslbrm = 950984; //max tbs
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
uint32_t A = rel15->TBSize[0]<<3;
uint8_t nb_re_dmrs;
if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1)
@@ -260,24 +197,115 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
else
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
uint16_t R=rel15->targetCodeRate[0];
unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
LOG_D(PHY,"dlsch coding A %d Kr %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n",
A,impp->K,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,(int)mod_order);
// nrLDPC_encoder output is in "d"
// let's make this interface happy!
uint8_t tmp[8][68 * 384]__attribute__((aligned(32)));
for (int rr=impp->macro_num*8, i=0; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++,i++ )
impp->d[rr]=tmp[i];
nrLDPC_encoder(harq->c,impp->d,*impp->Zc, impp->Kb,Kr,impp->BG,impp);
// Compute where to place in output buffer that is concatenation of all segments
uint32_t r_offset=0;
for (int i=0; i < impp->macro_num*8; i++ )
r_offset+=nr_get_E(G, impp->n_segments, mod_order, rel15->nrOfLayers, i);
for (int rr=impp->macro_num*8; rr < impp->n_segments && rr < (impp->macro_num+1)*8; rr++ ) {
if (impp->F>0) {
// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
memset(&impp->d[rr][Kr-impp->F-2*(*impp->Zc)], impp->F, NR_NULL);
}
#ifdef DEBUG_DLSCH_CODING
LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
#endif
uint32_t E = nr_get_E(G, impp->n_segments, mod_order, rel15->nrOfLayers, rr);
//#ifdef DEBUG_DLSCH_CODING
LOG_D(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
rr,
impp->n_segments,
G,
E,
impp->F,
Kr-impp->F-2*(*impp->Zc),
mod_order,nb_rb);
// for tbslbrm calculation according to 5.4.2.1 of 38.212
uint8_t Nl = 4;
if (rel15->nrOfLayers < Nl)
Nl = rel15->nrOfLayers;
uint32_t Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
uint8_t Ilbrm = 1;
uint8_t e[E];
bzero (e, E);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
impp->BG,
*impp->Zc,
impp->d[rr],
e,
impp->n_segments,
impp->F,
Kr-impp->F-2*(*impp->Zc),
rel15->rvIndex[0],
E);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i,harq->e[i+r_offset], r_offset);
#endif
nr_interleaving_ldpc(E,
mod_order,
e,
impp->output+r_offset);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %u\n", i,impp->output[i+r_offset], r_offset);
if (r==impp->n_segments-1)
write_output("enc_output.m","enc",impp->output,G,1,4);
#endif
r_offset += E;
}
}
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
unsigned char *a,
int frame,
uint8_t slot,
NR_gNB_DLSCH_t *dlsch,
NR_DL_FRAME_PARMS *frame_parms,
unsigned char * output,
time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
time_stats_t *dlsch_rate_matching_stats,time_stats_t *dlsch_interleaving_stats,
time_stats_t *dlsch_segmentation_stats) {
encoder_implemparams_t impp;
impp.output=output;
unsigned int crc=1;
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
impp.Zc = &dlsch->harq_process.Z;
float Coderate = 0.0;
uint8_t Nl = 4;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
uint32_t A = rel15->TBSize[0]<<3;
A = rel15->TBSize[0]<<3;
if ( dlsch->rnti != SI_RNTI )
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0);
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0);
NR_gNB_SCH_STATS_t *stats=NULL;
int first_free=-1;
for (int i=0;i<NUMBER_OF_NR_SCH_STATS_MAX;i++) {
for (int i=0; i<NUMBER_OF_NR_SCH_STATS_MAX; i++) {
if (gNB->dlsch_stats[i].rnti == 0 && first_free == -1) {
first_free = i;
stats=&gNB->dlsch_stats[i];
}
if (gNB->dlsch_stats[i].rnti == dlsch->rnti) {
stats=&gNB->dlsch_stats[i];
break;
@@ -290,181 +318,94 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
stats->current_RI = rel15->nrOfLayers;
stats->current_Qm = rel15->qamModOrder[0];
}
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers);
LOG_D(PHY,"dlsch coding A %d G %d (nb_rb %d, nb_symb_sch %d, nb_re_dmrs %d, length_dmrs %d, mod_order %d)\n",
A,G, nb_rb,nb_symb_sch,nb_re_dmrs,length_dmrs,(int)mod_order);
if (A > 3824) {
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
a[A>>3] = ((uint8_t *)&crc)[2];
a[1+(A>>3)] = ((uint8_t *)&crc)[1];
a[2+(A>>3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d a2 %d\n", a[A>>3], a[1+(A>>3)], a[2+(A>>3)]);
harq->B = A+24;
// harq->b = a;
AssertFatal((A / 8) + 4 <= MAX_NR_DLSCH_PAYLOAD_BYTES,
"A %d is too big (A/8+4 = %d > %d)\n",
A,
(A / 8) + 4,
MAX_NR_DLSCH_PAYLOAD_BYTES);
memcpy(harq->b, a, (A / 8) + 4); // why is this +4 if the CRC is only 3 bytes?
}
else {
} else {
// Add 16-bit crc (polynomial A) to payload
crc = crc16(a,A)>>16;
a[A>>3] = ((uint8_t*)&crc)[1];
a[1+(A>>3)] = ((uint8_t*)&crc)[0];
a[A>>3] = ((uint8_t *)&crc)[1];
a[1+(A>>3)] = ((uint8_t *)&crc)[0];
//printf("CRC %x (A %d)\n",crc,A);
//printf("a0 %d a1 %d \n", a[A>>3], a[1+(A>>3)]);
harq->B = A+16;
// harq->b = a;
AssertFatal((A / 8) + 3 <= MAX_NR_DLSCH_PAYLOAD_BYTES,
"A %d is too big (A/8+3 = %d > %d)\n",
A,
(A / 8) + 3,
MAX_NR_DLSCH_PAYLOAD_BYTES);
memcpy(harq->b, a, (A / 8) + 3); // using 3 bytes to mimic the case of 24 bit crc
}
if (R<1000)
Coderate = (float) R /(float) 1024;
if (rel15->targetCodeRate[0]<1000)
Coderate = (float)rel15->targetCodeRate[0] /(float) 1024;
else // to scale for mcs 20 and 26 in table 5.1.3.1-2 which are decimal and input 2* in nr_tbs_tools
Coderate = (float) R /(float) 2048;
Coderate = (float)rel15->targetCodeRate[0] /(float) 2048;
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25)
harq->BG = 2;
impp.BG = 2;
else
harq->BG = 1;
impp.BG = 1;
start_meas(dlsch_segmentation_stats);
Kb = nr_segmentation(harq->b, harq->c, harq->B, &harq->C, &harq->K, Zc, &harq->F, harq->BG);
impp.Kb = nr_segmentation(harq->b, harq->c, harq->B, &impp.n_segments, &impp.K, impp.Zc, &impp.F, impp.BG);
stop_meas(dlsch_segmentation_stats);
F = harq->F;
Kr = harq->K;
#ifdef DEBUG_DLSCH_CODING
uint16_t Kr_bytes;
Kr_bytes = Kr>>3;
#endif
//printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,harq->K,Kr,BG,harq->C);
for (r=0; r<harq->C; r++) {
for (int r=0; r<impp.n_segments; r++) {
//d_tmp[r] = &harq->d[r][0];
//channel_input[r] = &harq->d[r][0];
#ifdef DEBUG_DLSCH_CODING
LOG_D(PHY,"Encoder: B %d F %d \n",harq->B, harq->F);
LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,harq->C);
LOG_D(PHY,"Encoder: B %d F %d \n",harq->B, impp->F);
LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,impp.n_segments);
LOG_D(PHY,"input %d %d %d %d %d \n", harq->c[r][0], harq->c[r][1], harq->c[r][2],harq->c[r][3], harq->c[r][4]);
for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){
for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++) {
LOG_D(PHY,"%d ", harq->c[r][cnt]);
}
LOG_D(PHY,"\n");
LOG_D(PHY,"\n");
#endif
//ldpc_encoder_orig((unsigned char*)harq->c[r],harq->d[r],*Zc,Kb,Kr,BG,0);
//ldpc_encoder_optim((unsigned char*)harq->c[r],(unsigned char*)&harq->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL);
}
encoder_implemparams_t impp;
impp.n_segments=harq->C;
impp.tprep = tprep;
impp.tinput = tinput;
impp.tparity = tparity;
impp.toutput = toutput;
for(int j=0;j<(harq->C/8+1);j++) {
impp.macro_num=j;
nrLDPC_encoder(harq->c,harq->d,*Zc,Kb,Kr,harq->BG,&impp);
impp.harq=harq;
notifiedFIFO_t nf;
initNotifiedFIFO(&nf);
int nbJobs=0;
for(int j=0; j<(impp.n_segments/8+((impp.n_segments&7)==0 ? 0 : 1)); j++) {
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(impp), j, &nf, ldpc8blocks);
encoder_implemparams_t* perJobImpp=(encoder_implemparams_t*)NotifiedFifoData(req);
*perJobImpp=impp;
perJobImpp->macro_num=j;
pushTpool(gNB->threadPool,req);
nbJobs++;
}
#ifdef DEBUG_DLSCH_CODING
write_output("enc_input0.m","enc_in0",&harq->c[0][0],Kr_bytes,1,4);
write_output("enc_output0.m","enc0",&harq->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
F = harq->F;
Kr = harq->K;
for (r=0; r<harq->C; r++) {
if (F>0) {
for (int k=(Kr-F-2*(*Zc)); k<Kr-2*(*Zc); k++) {
// writing into positions d[r][k-2Zc] as in clause 5.3.2 step 2) in 38.212
harq->d[r][k] = NR_NULL;
//if (k<(Kr-F+8))
//printf("r %d filler bits [%d] = %d \n", r,k, harq->d[r][k]);
}
}
#ifdef DEBUG_DLSCH_CODING
LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]);
#endif
E = nr_get_E(G, harq->C, mod_order, rel15->nrOfLayers, r);
//#ifdef DEBUG_DLSCH_CODING
LOG_D(NR_PHY,"Rate Matching, Code segment %d/%d (coded bits (G) %u, E %d, Filler bits %d, Filler offset %d mod_order %d, nb_rb %d)...\n",
r,
harq->C,
G,
E,
F,
Kr-F-2*(*Zc),
mod_order,nb_rb);
// for tbslbrm calculation according to 5.4.2.1 of 38.212
if (rel15->nrOfLayers < Nl)
Nl = rel15->nrOfLayers;
Tbslbrm = nr_compute_tbslbrm(rel15->mcsTable[0],nb_rb,Nl);
start_meas(dlsch_rate_matching_stats);
if (nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq->BG,
*Zc,
harq->d[r],
harq->e+r_offset,
harq->C,
F,
Kr-F-2*(*Zc),
rel15->rvIndex[0],
E) == -1)
return -1;
stop_meas(dlsch_rate_matching_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %u\n", i,harq->e[i+r_offset], r_offset);
#endif
start_meas(dlsch_interleaving_stats);
nr_interleaving_ldpc(E,
mod_order,
harq->e+r_offset,
harq->f+r_offset);
stop_meas(dlsch_interleaving_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %u\n", i,harq->f[i+r_offset], r_offset);
if (r==harq->C-1)
write_output("enc_output.m","enc",harq->f,G,1,4);
#endif
r_offset += E;
while(nbJobs) {
notifiedFIFO_elt_t *req=pullTpool(&nf, gNB->threadPool);
delNotifiedFIFO_elt(req);
nbJobs--;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return 0;
}
@@ -96,11 +96,6 @@ void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
}
}
uint16_t get_SLIV(uint8_t S, uint8_t L) {
return ( (uint16_t)(((L-1)<=7)? (14*(L-1)+S) : (14*(15-L)+(13-S))) );
}
static inline uint8_t get_K0(uint8_t row_idx, uint8_t time_alloc_type) {
return ( (time_alloc_type == NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_A)||
(time_alloc_type == NFAPI_NR_PDSCH_TIME_DOMAIN_ALLOC_TYPE_DEFAULT_C)? 0 :
@@ -383,7 +383,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
printf("[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d type %d: Pilot/Data extraction %5.2f \n",
frame,nr_slot_rx,slot,symbol,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
@@ -405,7 +405,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
if (first_symbol_flag==1) {
@@ -466,7 +466,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -518,7 +518,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
@@ -577,7 +577,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
start_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
/* Store the valid DL RE's */
@@ -660,7 +660,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#if DISABLE_LOG_X
printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
#endif
// Please keep it: useful for debugging
@@ -947,7 +947,7 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol);
pbch_pss_sss_adjust=adjust_G2(frame_parms->Ncp,frame_parms->frame_type, frame_parms->N_RB_DL,&rb_alloc,6,subframe,symbol);
if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
amp_tmp = 0x1fff;//dlsch0->sqrt_rho_b; already taken into account
@@ -1286,8 +1286,8 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
*/
uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
//int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
//int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
#ifndef modOrder
@@ -1313,16 +1313,6 @@ uint8_t I_TBS2I_MCS(uint8_t I_TBS);
uint8_t SE2I_TBS(float SE,
uint8_t N_PRB,
uint8_t symbPerRB);
/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 36.211 v8.6.0. If IFFT_FPGA is defined, the SRS is quantized to a QPSK sequence.
@param frame_parms LTE DL Frame Parameters
@param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment
@param txdataF pointer to the frequency domain TX signal
@returns 0 on success*/
int generate_srs(NR_DL_FRAME_PARMS *frame_parms,
SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated,
int *txdataF,
int16_t amp,
uint32_t subframe);
/*!
@@ -1352,12 +1342,6 @@ int32_t generate_drs_pusch(PHY_VARS_NR_UE *phy_vars_ue,
uint32_t nb_rb,
uint8_t ant);
/*!
\brief This function initializes the Group Hopping, Sequence Hopping and nPRS sequences for PUCCH/PUSCH according to 36.211 v8.6.0. It should be called after configuration of UE (reception of SIB2/3) and initial configuration of eNB (or after reconfiguration of cell-specific parameters).
@param frame_parms Pointer to a NR_DL_FRAME_PARMS structure (eNB or UE)*/
void init_ul_hopping(NR_DL_FRAME_PARMS *frame_parms);
/*!
\brief This function implements the initialization of paging parameters for UE (See Section 7, 36.304).It must be called after setting IMSImod1024 during UE startup and after receiving SIB2
@param ue Pointer to UE context
@@ -1422,8 +1406,6 @@ double sinr_eff_cqi_calc(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
void init_transport_channels(uint8_t);
@@ -1513,18 +1495,11 @@ int get_nCCE_offset_l1(int *CCE_table,
const unsigned short rnti,
const unsigned char subframe);
uint16_t get_nCCE(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
uint16_t get_nquad(uint8_t num_pdcch_symbols,NR_DL_FRAME_PARMS *frame_parms,uint8_t mi);
uint8_t get_mi(NR_DL_FRAME_PARMS *frame,uint8_t subframe);
//uint8_t get_mi(NR_DL_FRAME_PARMS *frame,uint8_t subframe);
uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int subframe);
uint8_t get_num_pdcch_symbols(uint8_t num_dci,DCI_ALLOC_t *dci_alloc,NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
void pdcch_interleaving(NR_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi);
void nr_pdcch_unscrambling(int16_t *z,
uint16_t scrambling_RNTI,
uint32_t length,
@@ -1539,7 +1514,6 @@ void dlsch_unscrambling(NR_DL_FRAME_PARMS *frame_parms,
uint8_t q,
uint8_t Ns);
void init_ncs_cell(NR_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
void generate_pucch1x(int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
@@ -1587,7 +1561,7 @@ void init_ulsch_power_LUT(void);
@param subframe subframe index to check
@returns 0 on success
*/
int is_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe);
//int is_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,frame_t frame, uint8_t subframe);
/*!
\brief Generate PRACH waveform
@@ -1653,8 +1627,6 @@ void init_scrambling_lut(void);
@param frame_parms Pointer to frame parameters
@returns 1 if subframe is for MBSFN
*/
int is_pmch_subframe(frame_t frame, int subframe, NR_DL_FRAME_PARMS *frame_parms);
uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2ndpilots);
uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
@@ -1691,8 +1663,7 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_ra_prboffset,
uint8_t tdd_mapindex, uint16_t Nf);
uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
+3 -2
View File
@@ -106,7 +106,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5];
int16_t **tx_layers;
int32_t **txdataF;
int8_t Wf[2], Wt[2], l_prime[2], delta;
int8_t Wf[2], Wt[2];
int l_prime[2], delta;
uint8_t nb_dmrs_re_per_rb;
int ap, i;
int sample_offsetF, N_RE_prime;
@@ -418,7 +419,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (is_dmrs == 1) {
// if transform precoding is enabled
if (pusch_pdu->transform_precoding == 0) {
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
+2 -2
View File
@@ -805,8 +805,8 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
}
#endif //0
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) __attribute__((always_inline));
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) {
static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) __attribute__((always_inline));
static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) {
uint32_t x1, x2, s=0;
int i;
uint8_t c;
+3 -14
View File
@@ -96,20 +96,6 @@ typedef struct {
uint32_t subframe;
/// MIMO mode for this DLSCH
MIMO_mode_t mimo_mode;
/// Concatenated sequences
uint8_t *e;
/// LDPC-code outputs
uint8_t *d[MAX_NUM_NR_DLSCH_SEGMENTS];
/// Interleaver outputs
uint8_t *f;
/// Number of code segments
uint32_t C;
/// Number of bits in "small" code segments
uint32_t K;
/// Number of "Filler" bits
uint32_t F;
/// Encoder BG
uint8_t BG;
/// LDPC lifting size
uint32_t Z;
} NR_DL_gNB_HARQ_t;
@@ -868,6 +854,9 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_encoding_stats;
time_stats_t dlsch_modulation_stats;
time_stats_t dlsch_scrambling_stats;
time_stats_t dlsch_resource_mapping_stats;
time_stats_t dlsch_layer_mapping_stats;
time_stats_t dlsch_precoding_stats;
time_stats_t tinput;
time_stats_t tprep;
time_stats_t tparity;