Add polar interleaver

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 3662210842
commit 99ca2d2f14

@ -0,0 +1,67 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSLTE_POLAR_INTERLEAVER_H
#define SRSLTE_POLAR_INTERLEAVER_H
#include "srslte/config.h"
#include <stdbool.h>
#include <stdint.h>
#define SRSLTE_POLAR_INTERLEAVER_K_MAX_IL 164
/**
* * @brief Implements generic Polar code interleaver as described in TS 38.212 V15.9.0 Section 5.3.1.1
*
* @attention The input and output data cannot be the same.
*
* @param in Input data pointer
* @param out Output data pointer
* @param S Data element size in bytes
* @param K Number of elements
* @param dir Set to true for encoder and false for decoder
*/
SRSLTE_API void srslte_polar_interleaver_run(const void* in, void* out, uint32_t S, uint32_t K, bool dir);
#define SRSLTE_POLAR_INTERLEAVE_GEN(NAME, TYPE) \
static inline void srslte_polar_interleaver_run_##NAME(const TYPE* in, void* out, uint32_t K, bool dir) \
{ \
srslte_polar_interleaver_run(in, out, (uint32_t)sizeof(TYPE), K, dir); \
}
/**
* @brief Implements Polar code interleaver as described in TS 38.212 V15.9.0 Section 5.3.1.1
*
* @attention The input and output data cannot be the same.
*
* @param in unsigned 16 bit Input data
* @param out unsigned 16 bit Output data
* @param K Number of elements
* @param dir Set to true for encoder and false for decoder
*/
SRSLTE_POLAR_INTERLEAVE_GEN(u16, uint16_t)
/**
* @brief Implements Polar code interleaver as described in TS 38.212 V15.9.0 Section 5.3.1.1
*
* @attention The input and output data cannot be the same.
*
* @param in unsigned 8 bit Input data
* @param out unsigned 8 bit Output data
* @param K Number of elements
* @param dir Set to true for encoder and false for decoder
*/
SRSLTE_POLAR_INTERLEAVE_GEN(u8, uint8_t)
#undef SRSLTE_POLAR_INTERLEAVE_GEN
#endif // SRSLTE_POLAR_INTERLEAVER_H

@ -25,6 +25,7 @@ set(FEC_SOURCES ${FEC_SOURCES} ${AVX2_SOURCES}
polar/polar_decoder_ssc_s.c polar/polar_decoder_ssc_s.c
polar/polar_decoder_ssc_c.c polar/polar_decoder_ssc_c.c
polar/polar_decoder_vector.c polar/polar_decoder_vector.c
polar/polar_interleaver.c
polar/polar_rm.c polar/polar_rm.c
PARENT_SCOPE) PARENT_SCOPE)

@ -0,0 +1,50 @@
/**
*
* section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "srslte/phy/fec/polar/polar_interleaver.h"
#include "srslte/phy/utils/vector.h"
#include <memory.h>
#include <stddef.h>
// Table 5.3.1.1-1: Interleaving pattern
static const uint16_t polar_interleaver_pattern[SRSLTE_POLAR_INTERLEAVER_K_MAX_IL] = {
0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54,
56, 58, 59, 61, 62, 65, 66, 67, 69, 70, 71, 72, 76, 77, 81, 82, 83, 87, 88, 89, 91,
93, 95, 98, 101, 104, 106, 108, 110, 111, 113, 115, 118, 119, 120, 122, 123, 126, 127, 129, 132, 134,
138, 139, 140, 1, 3, 5, 8, 10, 15, 21, 27, 29, 32, 35, 43, 46, 52, 55, 57, 60, 63,
68, 73, 78, 84, 90, 92, 94, 96, 99, 102, 105, 107, 109, 112, 114, 116, 121, 124, 128, 130, 133,
135, 141, 6, 11, 16, 22, 30, 33, 36, 44, 47, 64, 74, 79, 85, 97, 100, 103, 117, 125, 131,
136, 142, 12, 17, 23, 37, 48, 75, 80, 86, 137, 143, 13, 18, 38, 144, 39, 145, 40, 146, 41,
147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163};
void srslte_polar_interleaver_run(const void* in, void* out, uint32_t S, uint32_t K, bool dir)
{
if (in == NULL || out == NULL) {
return;
}
const uint8_t* in_ptr = (const uint8_t*)in;
uint8_t* out_ptr = (uint8_t*)out;
uint32_t k = 0;
for (uint32_t m = 0; m < SRSLTE_POLAR_INTERLEAVER_K_MAX_IL; m++) {
if (polar_interleaver_pattern[m] >= SRSLTE_POLAR_INTERLEAVER_K_MAX_IL - K) {
uint32_t pi_k = polar_interleaver_pattern[m] - (SRSLTE_POLAR_INTERLEAVER_K_MAX_IL - K);
if (dir) {
memcpy(out_ptr + S * k, in_ptr + S * pi_k, S);
} else {
memcpy(out_ptr + S * pi_k, in_ptr + S * k, S);
}
k++;
}
}
}

@ -85,4 +85,9 @@ polar_tests_lite(-3)
# Unit tests full # Unit tests full
set(test_name POLAR-UNIT-TEST) set(test_name POLAR-UNIT-TEST)
set(test_command polar_chain_test) set(test_command polar_chain_test)
polar_tests(101) polar_tests(101)
# Polar inter-leaver test
add_executable(polar_interleaver_test polar_interleaver_test.c)
target_link_libraries(polar_interleaver_test srslte_phy)
add_test(polar_interleaver_test polar_interleaver_test)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,50 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "polar_interleaver_gold.h"
#include "srslte/common/test_common.h"
#include "srslte/phy/fec/polar/polar_interleaver.h"
int main(int argc, char** argv)
{
uint32_t idx = 0;
while (polar_interleaver_gold[idx].K) {
uint32_t K = polar_interleaver_gold[idx].K;
// Create indexes in order
uint16_t indexes_in[SRSLTE_POLAR_INTERLEAVER_K_MAX_IL];
for (uint16_t i = 0; i < (uint16_t)K; i++) {
indexes_in[i] = i;
}
// Run interleaver forward
uint16_t indexes_out[SRSLTE_POLAR_INTERLEAVER_K_MAX_IL];
srslte_polar_interleaver_run_u16(indexes_in, indexes_out, K, true);
// Check indexes
for (uint32_t i = 0; i < K; i++) {
TESTASSERT(polar_interleaver_gold[idx].indexes[i] == indexes_out[i]);
}
// Run interleaver backwards
srslte_polar_interleaver_run_u16(indexes_out, indexes_in, K, false);
// Check indexes
for (uint16_t i = 0; i < (uint16_t)K; i++) {
TESTASSERT(indexes_in[i] == i);
}
idx++;
}
return SRSLTE_SUCCESS;
}
Loading…
Cancel
Save