merge develop
This commit is contained in:
@@ -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 *)(¶ms->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 *)(¶ms->k3));
|
||||
fold = crc32_reduce_128_to_64(fold, k);
|
||||
|
||||
/**
|
||||
* REDUCTION 64 -> 32
|
||||
*/
|
||||
n = crc32_reduce_64_to_32(fold, k,
|
||||
_mm_load_si128((__m128i *)(¶ms->p)));
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/**
|
||||
* - restore FPU context
|
||||
*/
|
||||
kernel_fpu_end();
|
||||
#endif
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif /* __CRC_H__ */
|
||||
@@ -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,
|
||||
<e_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,
|
||||
<e_crc24b_pclmulqdq);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int crc24c (unsigned char * inptr,
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user