mirror of https://github.com/pvnis/srsRAN_4G.git
Added Polar RM and removed vectors with malloc from FEC NR
parent
2b59e90304
commit
bde1fa703d
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_chanalloc.h
|
||||||
|
* \brief Declaration of the subchannel allocation block.
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_CHANALLOC_H
|
||||||
|
#define SRSLTE_CHANALLOC_H
|
||||||
|
|
||||||
|
#include "srslte/config.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Allocates message bits (data + CRC) to the encoder input bit vector at the
|
||||||
|
* positions specified in \a K_set\\PC_set, computes and allocates the PC bits and
|
||||||
|
* zeros to the remaining positions.
|
||||||
|
* \param[in] message A pointer to the vector with the message bits (data and CRC).
|
||||||
|
* \param[out] input_encoder A pointer to the encoder input bit vector.
|
||||||
|
* \param[in] N The codeword length.
|
||||||
|
* \param[in] K Number of data + CRC bits.
|
||||||
|
* \param[in] nPC Number of parity check (PC) bits.
|
||||||
|
* \param[in] K_set Pointer to the indices of the encoder input vector containing.
|
||||||
|
* \param[in] PC_set Pointer to the indices of the parity check bits.
|
||||||
|
*/
|
||||||
|
void srslte_polar_chanalloc_tx(const uint8_t* message,
|
||||||
|
uint8_t* input_encoder,
|
||||||
|
const uint16_t N,
|
||||||
|
const uint16_t K,
|
||||||
|
const uint8_t nPC,
|
||||||
|
const uint16_t* K_set,
|
||||||
|
const uint16_t* PC_set);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Extracts message bits (data + CRC) from the decoder output vector
|
||||||
|
* according to the positions specified in \a K_set\\PC_set.
|
||||||
|
* \param[in] output_decoder A pointer to the decoder output bit vector.
|
||||||
|
* \param[out] message A pointer to the vector with the message bits (data and CRC).
|
||||||
|
* \param[in] K Number of data + CRC bits.
|
||||||
|
* \param[in] nPC Number of parity check (PC) bits.
|
||||||
|
* \param[in] K_set Pointer to the indices of the encoder input vector containing.
|
||||||
|
* \param[in] PC_set Pointer to the indices of the parity check bits.
|
||||||
|
*/
|
||||||
|
void srslte_polar_chanalloc_rx(const uint8_t* output_decoder,
|
||||||
|
uint8_t* message,
|
||||||
|
const uint16_t K,
|
||||||
|
const uint8_t nPC,
|
||||||
|
const uint16_t* K_set,
|
||||||
|
const uint16_t* PC_set);
|
||||||
|
|
||||||
|
#endif // SRSLTE_CHANALLOC_H
|
@ -0,0 +1,417 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_code.h
|
||||||
|
* \brief Declaration of the function that obtains
|
||||||
|
* the polar code parameters.
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* The message and parity check sets provided by this functions are needed by
|
||||||
|
* the subchannel allocation block.
|
||||||
|
* The frozen bit set provided by this function is used by the polar decoder.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_POLAR_CODE_H
|
||||||
|
#define SRSLTE_POLAR_CODE_H
|
||||||
|
|
||||||
|
#include "srslte/config.h"
|
||||||
|
#include "srslte/phy/utils/debug.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//#define debug
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Maximum rate-matched codeword length
|
||||||
|
*/
|
||||||
|
static const uint16_t EMAX = 8192;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Maximum codeword length
|
||||||
|
*/
|
||||||
|
static const uint16_t NMAX = 1024;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief \f$log_2(EMAX)\f$
|
||||||
|
*/
|
||||||
|
static const uint16_t eMAX = 13; // log2(EMAX);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 5.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_5[32] = {0, 1, 2, 4, 8, 16, 3, 5, 9, 6, 17, 10, 18, 12, 20, 24,
|
||||||
|
7, 11, 19, 13, 14, 21, 26, 25, 22, 28, 15, 23, 27, 29, 30, 31};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 6.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_6[64] = {0, 1, 2, 4, 8, 16, 32, 3, 5, 9, 6, 17, 10, 18, 12, 33,
|
||||||
|
20, 34, 24, 36, 7, 11, 40, 19, 13, 48, 14, 21, 35, 26, 37, 25,
|
||||||
|
22, 38, 41, 28, 42, 49, 44, 50, 15, 52, 23, 56, 27, 39, 29, 43,
|
||||||
|
30, 45, 51, 46, 53, 54, 57, 58, 60, 31, 47, 55, 59, 61, 62, 63};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 7.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_7[128] = {
|
||||||
|
0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 12, 33, 65, 20, 34, 24, 36,
|
||||||
|
7, 66, 11, 40, 68, 19, 13, 48, 14, 72, 21, 35, 26, 80, 37, 25, 22, 38, 96, 67, 41, 28,
|
||||||
|
69, 42, 49, 74, 70, 44, 81, 50, 73, 15, 52, 23, 76, 82, 56, 27, 97, 39, 84, 29, 43, 98,
|
||||||
|
88, 30, 71, 45, 100, 51, 46, 75, 104, 53, 77, 54, 83, 57, 112, 78, 85, 58, 99, 86, 60, 89,
|
||||||
|
101, 31, 90, 102, 105, 92, 47, 106, 55, 113, 79, 108, 59, 114, 87, 116, 61, 91, 120, 62, 103, 93,
|
||||||
|
107, 94, 109, 115, 110, 117, 118, 121, 122, 63, 124, 95, 111, 119, 123, 125, 126, 127};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 8.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_8[256] = {
|
||||||
|
0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 34, 24,
|
||||||
|
36, 7, 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 21, 132, 35, 26, 80, 37, 25, 22, 136,
|
||||||
|
38, 96, 67, 41, 144, 28, 69, 42, 49, 74, 160, 192, 70, 44, 131, 81, 50, 73, 15, 133, 52, 23,
|
||||||
|
134, 76, 137, 82, 56, 27, 97, 39, 84, 138, 145, 29, 43, 98, 88, 140, 30, 146, 71, 161, 45, 100,
|
||||||
|
51, 148, 46, 75, 104, 162, 53, 193, 152, 77, 164, 54, 83, 57, 112, 135, 78, 194, 85, 58, 168, 139,
|
||||||
|
99, 86, 60, 89, 196, 141, 101, 147, 176, 142, 31, 200, 90, 149, 102, 105, 163, 92, 47, 208, 150, 153,
|
||||||
|
165, 106, 55, 113, 154, 79, 108, 224, 166, 195, 59, 169, 114, 156, 87, 197, 116, 170, 61, 177, 91, 198,
|
||||||
|
172, 120, 201, 62, 143, 103, 178, 93, 202, 107, 180, 151, 209, 94, 204, 155, 210, 109, 184, 115, 167, 225,
|
||||||
|
157, 110, 117, 212, 171, 226, 216, 158, 118, 173, 121, 199, 179, 228, 174, 122, 203, 63, 181, 232, 124, 205,
|
||||||
|
182, 211, 185, 240, 206, 95, 213, 186, 227, 111, 214, 188, 217, 229, 159, 119, 218, 230, 233, 175, 123, 220,
|
||||||
|
183, 234, 125, 241, 207, 187, 236, 126, 242, 244, 189, 215, 219, 231, 248, 190, 221, 235, 222, 237, 243, 238,
|
||||||
|
245, 127, 191, 246, 249, 250, 252, 223, 239, 251, 247, 253, 254, 255};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 9.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_9[512] = {
|
||||||
|
0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20, 256, 34, 24,
|
||||||
|
36, 7, 129, 66, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132, 35, 258, 26, 80, 37, 25, 22,
|
||||||
|
136, 260, 264, 38, 96, 67, 41, 144, 28, 69, 42, 49, 74, 272, 160, 288, 192, 70, 44, 131, 81, 50, 73,
|
||||||
|
15, 320, 133, 52, 23, 134, 384, 76, 137, 82, 56, 27, 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 88,
|
||||||
|
140, 30, 146, 71, 262, 265, 161, 45, 100, 51, 148, 46, 75, 266, 273, 104, 162, 53, 193, 152, 77, 164, 268,
|
||||||
|
274, 54, 83, 57, 112, 135, 78, 289, 194, 85, 276, 58, 168, 139, 99, 86, 60, 280, 89, 290, 196, 141, 101,
|
||||||
|
147, 176, 142, 321, 31, 200, 90, 292, 322, 263, 149, 102, 105, 304, 296, 163, 92, 47, 267, 385, 324, 208, 386,
|
||||||
|
150, 153, 165, 106, 55, 328, 113, 154, 79, 269, 108, 224, 166, 195, 270, 275, 291, 59, 169, 114, 277, 156, 87,
|
||||||
|
197, 116, 170, 61, 281, 278, 177, 293, 388, 91, 198, 172, 120, 201, 336, 62, 282, 143, 103, 178, 294, 93, 202,
|
||||||
|
323, 392, 297, 107, 180, 151, 209, 284, 94, 204, 298, 400, 352, 325, 155, 210, 305, 300, 109, 184, 115, 167, 225,
|
||||||
|
326, 306, 157, 329, 110, 117, 212, 171, 330, 226, 387, 308, 216, 416, 271, 279, 158, 337, 118, 332, 389, 173, 121,
|
||||||
|
199, 179, 228, 338, 312, 390, 174, 393, 283, 122, 448, 353, 203, 63, 340, 394, 181, 295, 285, 232, 124, 205, 182,
|
||||||
|
286, 299, 354, 211, 401, 185, 396, 344, 240, 206, 95, 327, 402, 356, 307, 301, 417, 213, 186, 404, 227, 418, 302,
|
||||||
|
360, 111, 331, 214, 309, 188, 449, 217, 408, 229, 159, 420, 310, 333, 119, 339, 218, 368, 230, 391, 313, 450, 334,
|
||||||
|
233, 175, 123, 341, 220, 314, 424, 395, 355, 287, 183, 234, 125, 342, 316, 241, 345, 452, 397, 403, 207, 432, 357,
|
||||||
|
187, 236, 126, 242, 398, 346, 456, 358, 405, 303, 244, 189, 361, 215, 348, 419, 406, 464, 362, 409, 219, 311, 421,
|
||||||
|
410, 231, 248, 369, 190, 364, 335, 480, 315, 221, 370, 422, 425, 451, 235, 412, 343, 372, 317, 222, 426, 453, 237,
|
||||||
|
433, 347, 243, 454, 318, 376, 428, 238, 359, 457, 399, 434, 349, 245, 458, 363, 127, 191, 407, 436, 465, 246, 350,
|
||||||
|
460, 249, 411, 365, 440, 374, 423, 466, 250, 371, 481, 413, 366, 468, 429, 252, 373, 482, 427, 414, 223, 472, 455,
|
||||||
|
377, 435, 319, 484, 430, 488, 239, 378, 459, 437, 380, 461, 496, 351, 467, 438, 251, 462, 442, 441, 469, 247, 367,
|
||||||
|
253, 375, 444, 470, 483, 415, 485, 473, 474, 254, 379, 431, 489, 486, 476, 439, 490, 463, 381, 497, 492, 443, 382,
|
||||||
|
498, 445, 471, 500, 446, 475, 487, 504, 255, 477, 491, 478, 383, 493, 499, 502, 494, 501, 447, 505, 506, 479, 508,
|
||||||
|
495, 503, 507, 509, 510, 511};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the mother code with code_size_log = 10.
|
||||||
|
*/
|
||||||
|
static const uint16_t mother_code_10[1024] = {
|
||||||
|
0, 1, 2, 4, 8, 16, 32, 3, 5, 64, 9, 6, 17, 10, 18, 128, 12, 33, 65, 20,
|
||||||
|
256, 34, 24, 36, 7, 129, 66, 512, 11, 40, 68, 130, 19, 13, 48, 14, 72, 257, 21, 132,
|
||||||
|
35, 258, 26, 513, 80, 37, 25, 22, 136, 260, 264, 38, 514, 96, 67, 41, 144, 28, 69, 42,
|
||||||
|
516, 49, 74, 272, 160, 520, 288, 528, 192, 544, 70, 44, 131, 81, 50, 73, 15, 320, 133, 52,
|
||||||
|
23, 134, 384, 76, 137, 82, 56, 27, 97, 39, 259, 84, 138, 145, 261, 29, 43, 98, 515, 88,
|
||||||
|
140, 30, 146, 71, 262, 265, 161, 576, 45, 100, 640, 51, 148, 46, 75, 266, 273, 517, 104, 162,
|
||||||
|
53, 193, 152, 77, 164, 768, 268, 274, 518, 54, 83, 57, 521, 112, 135, 78, 289, 194, 85, 276,
|
||||||
|
522, 58, 168, 139, 99, 86, 60, 280, 89, 290, 529, 524, 196, 141, 101, 147, 176, 142, 530, 321,
|
||||||
|
31, 200, 90, 545, 292, 322, 532, 263, 149, 102, 105, 304, 296, 163, 92, 47, 267, 385, 546, 324,
|
||||||
|
208, 386, 150, 153, 165, 106, 55, 328, 536, 577, 548, 113, 154, 79, 269, 108, 578, 224, 166, 519,
|
||||||
|
552, 195, 270, 641, 523, 275, 580, 291, 59, 169, 560, 114, 277, 156, 87, 197, 116, 170, 61, 531,
|
||||||
|
525, 642, 281, 278, 526, 177, 293, 388, 91, 584, 769, 198, 172, 120, 201, 336, 62, 282, 143, 103,
|
||||||
|
178, 294, 93, 644, 202, 592, 323, 392, 297, 770, 107, 180, 151, 209, 284, 648, 94, 204, 298, 400,
|
||||||
|
608, 352, 325, 533, 155, 210, 305, 547, 300, 109, 184, 534, 537, 115, 167, 225, 326, 306, 772, 157,
|
||||||
|
656, 329, 110, 117, 212, 171, 776, 330, 226, 549, 538, 387, 308, 216, 416, 271, 279, 158, 337, 550,
|
||||||
|
672, 118, 332, 579, 540, 389, 173, 121, 553, 199, 784, 179, 228, 338, 312, 704, 390, 174, 554, 581,
|
||||||
|
393, 283, 122, 448, 353, 561, 203, 63, 340, 394, 527, 582, 556, 181, 295, 285, 232, 124, 205, 182,
|
||||||
|
643, 562, 286, 585, 299, 354, 211, 401, 185, 396, 344, 586, 645, 593, 535, 240, 206, 95, 327, 564,
|
||||||
|
800, 402, 356, 307, 301, 417, 213, 568, 832, 588, 186, 646, 404, 227, 896, 594, 418, 302, 649, 771,
|
||||||
|
360, 539, 111, 331, 214, 309, 188, 449, 217, 408, 609, 596, 551, 650, 229, 159, 420, 310, 541, 773,
|
||||||
|
610, 657, 333, 119, 600, 339, 218, 368, 652, 230, 391, 313, 450, 542, 334, 233, 555, 774, 175, 123,
|
||||||
|
658, 612, 341, 777, 220, 314, 424, 395, 673, 583, 355, 287, 183, 234, 125, 557, 660, 616, 342, 316,
|
||||||
|
241, 778, 563, 345, 452, 397, 403, 207, 674, 558, 785, 432, 357, 187, 236, 664, 624, 587, 780, 705,
|
||||||
|
126, 242, 565, 398, 346, 456, 358, 405, 303, 569, 244, 595, 189, 566, 676, 361, 706, 589, 215, 786,
|
||||||
|
647, 348, 419, 406, 464, 680, 801, 362, 590, 409, 570, 788, 597, 572, 219, 311, 708, 598, 601, 651,
|
||||||
|
421, 792, 802, 611, 602, 410, 231, 688, 653, 248, 369, 190, 364, 654, 659, 335, 480, 315, 221, 370,
|
||||||
|
613, 422, 425, 451, 614, 543, 235, 412, 343, 372, 775, 317, 222, 426, 453, 237, 559, 833, 804, 712,
|
||||||
|
834, 661, 808, 779, 617, 604, 433, 720, 816, 836, 347, 897, 243, 662, 454, 318, 675, 618, 898, 781,
|
||||||
|
376, 428, 665, 736, 567, 840, 625, 238, 359, 457, 399, 787, 591, 678, 434, 677, 349, 245, 458, 666,
|
||||||
|
620, 363, 127, 191, 782, 407, 436, 626, 571, 465, 681, 246, 707, 350, 599, 668, 790, 460, 249, 682,
|
||||||
|
573, 411, 803, 789, 709, 365, 440, 628, 689, 374, 423, 466, 793, 250, 371, 481, 574, 413, 603, 366,
|
||||||
|
468, 655, 900, 805, 615, 684, 710, 429, 794, 252, 373, 605, 848, 690, 713, 632, 482, 806, 427, 904,
|
||||||
|
414, 223, 663, 692, 835, 619, 472, 455, 796, 809, 714, 721, 837, 716, 864, 810, 606, 912, 722, 696,
|
||||||
|
377, 435, 817, 319, 621, 812, 484, 430, 838, 667, 488, 239, 378, 459, 622, 627, 437, 380, 818, 461,
|
||||||
|
496, 669, 679, 724, 841, 629, 351, 467, 438, 737, 251, 462, 442, 441, 469, 247, 683, 842, 738, 899,
|
||||||
|
670, 783, 849, 820, 728, 928, 791, 367, 901, 630, 685, 844, 633, 711, 253, 691, 824, 902, 686, 740,
|
||||||
|
850, 375, 444, 470, 483, 415, 485, 905, 795, 473, 634, 744, 852, 960, 865, 693, 797, 906, 715, 807,
|
||||||
|
474, 636, 694, 254, 717, 575, 913, 798, 811, 379, 697, 431, 607, 489, 866, 723, 486, 908, 718, 813,
|
||||||
|
476, 856, 839, 725, 698, 914, 752, 868, 819, 814, 439, 929, 490, 623, 671, 739, 916, 463, 843, 381,
|
||||||
|
497, 930, 821, 726, 961, 872, 492, 631, 729, 700, 443, 741, 845, 920, 382, 822, 851, 730, 498, 880,
|
||||||
|
742, 445, 471, 635, 932, 687, 903, 825, 500, 846, 745, 826, 732, 446, 962, 936, 475, 853, 867, 637,
|
||||||
|
907, 487, 695, 746, 828, 753, 854, 857, 504, 799, 255, 964, 909, 719, 477, 915, 638, 748, 944, 869,
|
||||||
|
491, 699, 754, 858, 478, 968, 383, 910, 815, 976, 870, 917, 727, 493, 873, 701, 931, 756, 860, 499,
|
||||||
|
731, 823, 922, 874, 918, 502, 933, 743, 760, 881, 494, 702, 921, 501, 876, 847, 992, 447, 733, 827,
|
||||||
|
934, 882, 937, 963, 747, 505, 855, 924, 734, 829, 965, 938, 884, 506, 749, 945, 966, 755, 859, 940,
|
||||||
|
830, 911, 871, 639, 888, 479, 946, 750, 969, 508, 861, 757, 970, 919, 875, 862, 758, 948, 977, 923,
|
||||||
|
972, 761, 877, 952, 495, 703, 935, 978, 883, 762, 503, 925, 878, 735, 993, 885, 939, 994, 980, 926,
|
||||||
|
764, 941, 967, 886, 831, 947, 507, 889, 984, 751, 942, 996, 971, 890, 509, 949, 973, 1000, 892, 950,
|
||||||
|
863, 759, 1008, 510, 979, 953, 763, 974, 954, 879, 981, 982, 927, 995, 765, 956, 887, 985, 997, 986,
|
||||||
|
943, 891, 998, 766, 511, 988, 1001, 951, 1002, 893, 975, 894, 1009, 955, 1004, 1010, 957, 983, 958, 987,
|
||||||
|
1012, 999, 1016, 767, 989, 1003, 990, 1005, 959, 1011, 1013, 895, 1006, 1014, 1017, 1018, 991, 1020, 1007, 1015,
|
||||||
|
1019, 1021, 1022, 1023};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 5.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_5[32] = {0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19,
|
||||||
|
12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 6.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_6[64] = {0, 1, 2, 3, 4, 5, 8, 9, 6, 7, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 17, 32, 33, 18, 19, 34, 35, 20, 21, 36, 37, 22, 23, 38, 39,
|
||||||
|
24, 25, 40, 41, 26, 27, 42, 43, 28, 29, 44, 45, 30, 31, 46, 47,
|
||||||
|
48, 49, 50, 51, 52, 53, 56, 57, 54, 55, 58, 59, 60, 61, 62, 63};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 7.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_7[128] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 17, 18, 19, 12, 13, 14, 15, 20, 21,
|
||||||
|
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 64, 65, 66, 67, 36, 37, 38, 39,
|
||||||
|
68, 69, 70, 71, 40, 41, 42, 43, 72, 73, 74, 75, 44, 45, 46, 47, 76, 77, 78, 79, 48, 49,
|
||||||
|
50, 51, 80, 81, 82, 83, 52, 53, 54, 55, 84, 85, 86, 87, 56, 57, 58, 59, 88, 89, 90, 91,
|
||||||
|
60, 61, 62, 63, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 112, 113,
|
||||||
|
114, 115, 108, 109, 110, 111, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 8.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_8[256] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
||||||
|
22, 23, 32, 33, 34, 35, 36, 37, 38, 39, 24, 25, 26, 27, 28, 29, 30, 31, 40, 41, 42, 43,
|
||||||
|
44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
|
||||||
|
66, 67, 68, 69, 70, 71, 128, 129, 130, 131, 132, 133, 134, 135, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||||
|
136, 137, 138, 139, 140, 141, 142, 143, 80, 81, 82, 83, 84, 85, 86, 87, 144, 145, 146, 147, 148, 149,
|
||||||
|
150, 151, 88, 89, 90, 91, 92, 93, 94, 95, 152, 153, 154, 155, 156, 157, 158, 159, 96, 97, 98, 99,
|
||||||
|
100, 101, 102, 103, 160, 161, 162, 163, 164, 165, 166, 167, 104, 105, 106, 107, 108, 109, 110, 111, 168, 169,
|
||||||
|
170, 171, 172, 173, 174, 175, 112, 113, 114, 115, 116, 117, 118, 119, 176, 177, 178, 179, 180, 181, 182, 183,
|
||||||
|
120, 121, 122, 123, 124, 125, 126, 127, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
|
||||||
|
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 224, 225, 226, 227,
|
||||||
|
228, 229, 230, 231, 216, 217, 218, 219, 220, 221, 222, 223, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
|
||||||
|
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 9.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_9[512] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||||
|
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
|
||||||
|
46, 47, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 48, 49, 50, 51, 52,
|
||||||
|
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
|
||||||
|
92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
|
||||||
|
115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
|
||||||
|
138, 139, 140, 141, 142, 143, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 144,
|
||||||
|
145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 272, 273, 274, 275, 276, 277, 278, 279,
|
||||||
|
280, 281, 282, 283, 284, 285, 286, 287, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
|
||||||
|
175, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 176, 177, 178, 179, 180, 181,
|
||||||
|
182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316,
|
||||||
|
317, 318, 319, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 320, 321, 322, 323,
|
||||||
|
324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
|
||||||
|
219, 220, 221, 222, 223, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 224, 225,
|
||||||
|
226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 352, 353, 354, 355, 356, 357, 358, 359, 360,
|
||||||
|
361, 362, 363, 364, 365, 366, 367, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
|
||||||
|
368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390,
|
||||||
|
391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413,
|
||||||
|
414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 448, 449, 450, 451, 452,
|
||||||
|
453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443,
|
||||||
|
444, 445, 446, 447, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482,
|
||||||
|
483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505,
|
||||||
|
506, 507, 508, 509, 510, 511};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Look-up table for the block interleaver for code_size_log = 10.
|
||||||
|
*/
|
||||||
|
static const uint16_t blk_interleaver_10[1024] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||||
|
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
|
||||||
|
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
||||||
|
57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
|
||||||
|
76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
|
||||||
|
95, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
|
||||||
|
146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 96, 97, 98, 99, 100,
|
||||||
|
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
|
||||||
|
120, 121, 122, 123, 124, 125, 126, 127, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
|
||||||
|
171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
||||||
|
190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
|
||||||
|
209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
|
||||||
|
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
|
||||||
|
247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
|
||||||
|
266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
|
||||||
|
285, 286, 287, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527,
|
||||||
|
528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 288, 289, 290,
|
||||||
|
291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309,
|
||||||
|
310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 544, 545, 546, 547, 548, 549, 550, 551, 552,
|
||||||
|
553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571,
|
||||||
|
572, 573, 574, 575, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
|
||||||
|
335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 576, 577,
|
||||||
|
578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596,
|
||||||
|
597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 352, 353, 354, 355, 356, 357, 358, 359,
|
||||||
|
360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
|
||||||
|
379, 380, 381, 382, 383, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621,
|
||||||
|
622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 384,
|
||||||
|
385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403,
|
||||||
|
404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 640, 641, 642, 643, 644, 645, 646,
|
||||||
|
647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665,
|
||||||
|
666, 667, 668, 669, 670, 671, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428,
|
||||||
|
429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447,
|
||||||
|
672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690,
|
||||||
|
691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 448, 449, 450, 451, 452, 453,
|
||||||
|
454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472,
|
||||||
|
473, 474, 475, 476, 477, 478, 479, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715,
|
||||||
|
716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734,
|
||||||
|
735, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497,
|
||||||
|
498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 736, 737, 738, 739, 740,
|
||||||
|
741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759,
|
||||||
|
760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778,
|
||||||
|
779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797,
|
||||||
|
798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816,
|
||||||
|
817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835,
|
||||||
|
836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854,
|
||||||
|
855, 856, 857, 858, 859, 860, 861, 862, 863, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905,
|
||||||
|
906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924,
|
||||||
|
925, 926, 927, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879,
|
||||||
|
880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 928, 929, 930,
|
||||||
|
931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949,
|
||||||
|
950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968,
|
||||||
|
969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987,
|
||||||
|
988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006,
|
||||||
|
1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes a polar set.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint16_t N; /*!< \brief Number of coded bits (N). */
|
||||||
|
uint8_t n; /*!< \brief \f$ log_2(N)\f$.*/
|
||||||
|
uint16_t K; /*!< \brief Number of message bits (data and CRC). */
|
||||||
|
uint16_t nPC; /*!< \brief Number of parity check bits. */
|
||||||
|
uint16_t nWmPC; /*!< \brief Number of parity bits of minimum bandwidth type. */
|
||||||
|
uint16_t F_set_size; /*!< \brief Number of frozen bits. */
|
||||||
|
uint16_t* K_set; /*!< \brief Pointer to the indices of the encoder input vector containing data and CRC bits. */
|
||||||
|
uint16_t* tmp_K_set; /*!< \brief Temporal Pointer. */
|
||||||
|
uint16_t PC_set[4]; /*!< \brief Pointer to the indices of the encoder input vector containing the parity bits.*/
|
||||||
|
uint16_t* F_set; /*!< \brief Pointer to the indices of the encoder input vector containing frozen bits.*/
|
||||||
|
} srslte_polar_code_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns a pointer to the desired mother code.
|
||||||
|
*/
|
||||||
|
static inline const uint16_t* get_mother_code(uint8_t n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 5:
|
||||||
|
return mother_code_5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
return mother_code_6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
return mother_code_7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
return mother_code_8;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
return mother_code_9;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
return mother_code_10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("Wrong code_size_log\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns a pointer to the desired blk_interleaver.
|
||||||
|
*/
|
||||||
|
static inline const uint16_t* get_blk_interleaver(uint8_t n)
|
||||||
|
{
|
||||||
|
switch (n) {
|
||||||
|
case 5:
|
||||||
|
return blk_interleaver_5;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
return blk_interleaver_6;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
return blk_interleaver_7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
return blk_interleaver_8;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
return blk_interleaver_9;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
return blk_interleaver_10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("Wrong code_size_log\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Allocates resources for the message set, frozen set and parity set of any polar code.
|
||||||
|
* \param[out] c A pointer to the initialized polar code.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int srslte_polar_code_init(srslte_polar_code_t* c);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initializes the different index sets as needed by the subchannel allocation block and/or by the polar decoder.
|
||||||
|
* \param[out] c A pointer to the initialized polar code.
|
||||||
|
* \param[in] K Number of data + CRC bits.
|
||||||
|
* \param[in] E Number of bits of the codeword after rate matching.
|
||||||
|
* \param[in] nMax Maximum \f$log_2(N)\f$, where \f$N\f$ is the codeword size, nMax = 9 for downlink and nMax = 10, for
|
||||||
|
* uplink.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
int srslte_polar_code_get(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, const uint8_t nMax);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The polar code "destructor": it frees all the resources.
|
||||||
|
* \param[in] c A pointer to the dismantled polar code.
|
||||||
|
*/
|
||||||
|
void srslte_polar_code_free(srslte_polar_code_t* c);
|
||||||
|
|
||||||
|
#endif // SRSLTE_POLAR_CODE_H
|
@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_rm.h
|
||||||
|
* \brief Declaration of the polar RateMatcher and RateDematcher.
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_POLARRM_H
|
||||||
|
#define SRSLTE_POLARRM_H
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes a polar rate matcher or rate dematcher
|
||||||
|
*/
|
||||||
|
typedef struct SRSLTE_API {
|
||||||
|
void* ptr; /*!< \brief Rate Matcher auxiliary registers. */
|
||||||
|
} srslte_polar_rm_t;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initializes the Rate Matcher for the maximum rate-matched codeword length
|
||||||
|
* \param[out] q A pointer to a srslte_polar_rm_t structure.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_tx_init(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Carries out the actual rate-matching.
|
||||||
|
* \param[in] q A pointer to the Rate-Matcher (a srslte_polar_rm_t structure
|
||||||
|
* instance) that carries out the rate matching.
|
||||||
|
* \param[in] input The codeword obtained from the polar encoder.
|
||||||
|
* \param[out] output The rate-matched codeword resulting from the rate-matching
|
||||||
|
* operation.
|
||||||
|
* \param[in] n \f$log_2\f$ of the codeword length.
|
||||||
|
* \param[in] E Rate-matched codeword length.
|
||||||
|
* \param[in] K Message size (including CRC).
|
||||||
|
* \param[in] ibil Indicator of bit interliaver (set to 0 to disable).
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_tx(srslte_polar_rm_t* q,
|
||||||
|
const uint8_t* input,
|
||||||
|
uint8_t* output,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initializes all the Rate DeMatcher variables.
|
||||||
|
* \param[out] q A pointer to a srslte_polar_rm_t structure.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_init_f(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Carries out the actual rate-dematching.
|
||||||
|
* \param[in] q A pointer to the Rate-DeMatcher (a srslte_polar_rm_t structure
|
||||||
|
* instance) that carries out the rate matching.
|
||||||
|
* \param[in] input The LLRs obtained from the channel samples that correspond to
|
||||||
|
* the codeword to be first, rate-dematched and then decoded.
|
||||||
|
* \param[out] output The rate-dematched codeword resulting from the rate-dematching
|
||||||
|
* operation.
|
||||||
|
* \param[in] E Rate-matched codeword length.
|
||||||
|
* \param[in] n \f$log_2\f$ of the codeword length.
|
||||||
|
* \param[in] K Message size (including CRC).
|
||||||
|
* \param[in] ibil Indicator of bit interliaver (set to 0 to disable).
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_f(srslte_polar_rm_t* q,
|
||||||
|
const float* input,
|
||||||
|
float* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initializes all the Rate DeMatcher variables (int16_t inputs).
|
||||||
|
* \param[out] q A pointer to a srslte_polar_rm_t structure.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_init_s(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Carries out the actual rate-dematching (in16_t inputs)
|
||||||
|
* \param[in] q A pointer to the Rate-DeMatcher (a srslte_polar_rm_t structure
|
||||||
|
* instance) that carries out the rate matching.
|
||||||
|
* \param[in] input The LLRs obtained from the channel samples that correspond to
|
||||||
|
* the codeword to be first, rate-dematched and then decoded.
|
||||||
|
* \param[out] output The rate-dematched codeword resulting from the rate-dematching
|
||||||
|
* operation.
|
||||||
|
* \param[in] E Rate-matched codeword length.
|
||||||
|
* \param[in] n \f$log_2\f$ of the codeword length.
|
||||||
|
* \param[in] K Message size (including CRC).
|
||||||
|
* \param[in] ibil Indicator of bit interliaver (set to 0 to disable).
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_s(srslte_polar_rm_t* q,
|
||||||
|
const int16_t* input,
|
||||||
|
int16_t* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initializes all the Rate DeMatcher variables (int8_t inputs).
|
||||||
|
* \param[out] q A pointer to a srslte_polar_rm_t structure.
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_init_c(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Carries out the actual rate-dematching (int8_t inputs).
|
||||||
|
* \param[in] q A pointer to the Rate-DeMatcher (a srslte_polar_rm_t structure
|
||||||
|
* instance) that carries out the rate matching.
|
||||||
|
* \param[in] input The LLRs obtained from the channel samples that correspond to
|
||||||
|
* the codeword to be first, rate-dematched and then decoded.
|
||||||
|
* \param[out] output The rate-dematched codeword resulting from the rate-dematching
|
||||||
|
* operation.
|
||||||
|
* \param[in] E Rate-matched codeword length.
|
||||||
|
* \param[in] n \f$log_2\f$ of the codeword length.
|
||||||
|
* \param[in] K Message size (including CRC).
|
||||||
|
* \param[in] ibil Indicator of bit interliaver (set to 0 to disable).
|
||||||
|
* \return An integer: 0 if the function executes correctly, -1 otherwise.
|
||||||
|
*/
|
||||||
|
SRSLTE_API int srslte_polar_rm_rx_c(srslte_polar_rm_t* q,
|
||||||
|
const int8_t* input,
|
||||||
|
int8_t* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The Rate Matcher "destructor": it frees all the resources allocated to the rate-matcher.
|
||||||
|
* \param[in] q A pointer to the dismantled rate-matcher.
|
||||||
|
*/
|
||||||
|
SRSLTE_API void srslte_polar_rm_tx_free(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The Rate Matcher "destructor": it frees all the resources allocated to the rate-dematcher.
|
||||||
|
* \param[in] q A pointer to the dismantled rate-dematcher.
|
||||||
|
*/
|
||||||
|
SRSLTE_API void srslte_polar_rm_rx_free_f(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The Rate Matcher "destructor" for short symbols: it frees all the resources allocated to the rate-dematcher.
|
||||||
|
* \param[in] q A pointer to the dismantled rate-dematcher.
|
||||||
|
*/
|
||||||
|
SRSLTE_API void srslte_polar_rm_rx_free_s(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The Rate Matcher "destructor" for int8_t symbols: it frees all the resources allocated to the rate-dematcher.
|
||||||
|
* \param[in] q A pointer to the dismantled rate-dematcher.
|
||||||
|
*/
|
||||||
|
SRSLTE_API void srslte_polar_rm_rx_free_c(srslte_polar_rm_t* q);
|
||||||
|
|
||||||
|
#endif // SRSLTE_POLARRM_H
|
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_chanalloc.c
|
||||||
|
* \brief Definition of the subchannel allocation block.
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/phy/fec/polar/polar_chanalloc.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void srslte_polar_chanalloc_tx(const uint8_t* message,
|
||||||
|
uint8_t* input_encoder,
|
||||||
|
const uint16_t N,
|
||||||
|
const uint16_t K,
|
||||||
|
const uint8_t nPC,
|
||||||
|
const uint16_t* K_set,
|
||||||
|
const uint16_t* PC_set)
|
||||||
|
{
|
||||||
|
bzero(input_encoder, N * sizeof(uint8_t));
|
||||||
|
|
||||||
|
uint16_t i_o = 0;
|
||||||
|
if (nPC == 0) {
|
||||||
|
for (uint16_t i = 0; i < K; i++) {
|
||||||
|
i_o = K_set[i];
|
||||||
|
input_encoder[i_o] = message[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint16_t tmpy0 = 0;
|
||||||
|
uint16_t y0 = 0;
|
||||||
|
uint16_t y1 = 0;
|
||||||
|
uint16_t y2 = 0;
|
||||||
|
uint16_t y3 = 0;
|
||||||
|
uint16_t y4 = 0;
|
||||||
|
uint16_t iKPC = 0;
|
||||||
|
uint16_t iPC = 0;
|
||||||
|
uint16_t iK = 0;
|
||||||
|
for (i_o = 0; i_o < N; i_o++) {
|
||||||
|
// circ. shift register
|
||||||
|
tmpy0 = y0;
|
||||||
|
y0 = y1;
|
||||||
|
y1 = y2;
|
||||||
|
y2 = y3;
|
||||||
|
y3 = y4;
|
||||||
|
y4 = tmpy0;
|
||||||
|
if (i_o == K_set[iKPC]) { // information bit
|
||||||
|
iKPC = iKPC + 1;
|
||||||
|
if (i_o == PC_set[iPC]) { // parity bit
|
||||||
|
iPC++;
|
||||||
|
input_encoder[i_o] = y0;
|
||||||
|
} else {
|
||||||
|
input_encoder[i_o] = message[iK];
|
||||||
|
y0 = y0 ^ message[iK];
|
||||||
|
iK++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_chanalloc_rx(const uint8_t* output_decoder,
|
||||||
|
uint8_t* message,
|
||||||
|
const uint16_t K,
|
||||||
|
const uint8_t nPC,
|
||||||
|
const uint16_t* K_set,
|
||||||
|
const uint16_t* PC_set)
|
||||||
|
{
|
||||||
|
uint16_t i_o = 0;
|
||||||
|
uint16_t iPC = 0;
|
||||||
|
uint16_t iK = 0;
|
||||||
|
for (uint16_t iKPC = 0; iKPC < K + nPC; iKPC++) {
|
||||||
|
i_o = K_set[iKPC]; // includes parity bits
|
||||||
|
if (i_o == PC_set[iPC]) { // skip
|
||||||
|
iPC = iPC + 1;
|
||||||
|
} else {
|
||||||
|
message[iK] = output_decoder[i_o];
|
||||||
|
iK = iK + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_code.c
|
||||||
|
* \brief Definition of the function that computes the polar code parameters including,
|
||||||
|
* message set (K_Set), the frozen set (F_set), and the parity check bits set (PC_Set)..
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* The message and parity check sets provided by this functions are needed by
|
||||||
|
* the subchannel allocation block.
|
||||||
|
* The frozen bit set provided by this function is used by the polar decoder.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/phy/utils/vector.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "srslte/phy/fec/polar/polar_code.h"
|
||||||
|
#include "srslte/phy/utils/debug.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Extracts the elements in x that are smaller than T or are in y.
|
||||||
|
* Returns the length of the output vector z.
|
||||||
|
*/
|
||||||
|
static uint16_t
|
||||||
|
setdiff_stable(const uint16_t* x, const uint16_t* y, uint16_t* z, const int T, const uint16_t len1, const uint16_t len2)
|
||||||
|
{
|
||||||
|
uint16_t o = 0;
|
||||||
|
int flag = 0;
|
||||||
|
for (int i = 0; i < len1; i++) {
|
||||||
|
// is x[i] in y ?
|
||||||
|
flag = 0;
|
||||||
|
if (x[i] <= T) {
|
||||||
|
flag = 1;
|
||||||
|
} else {
|
||||||
|
for (int j = 0; j < len2; j++) {
|
||||||
|
if (x[i] == y[j]) {
|
||||||
|
flag = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag == 0) {
|
||||||
|
z[o] = x[i];
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Compares two uint16_t
|
||||||
|
*/
|
||||||
|
int cmpfunc(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
const uint16_t ai = *(const uint16_t*)a;
|
||||||
|
const uint16_t bi = *(const uint16_t*)b;
|
||||||
|
|
||||||
|
if (ai < bi) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ai > bi) {
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Gets the codeword length N, nPC and nWmPC depending on the code parameters.
|
||||||
|
* Returns -1 if not supported configuration, otherwise returns 0.
|
||||||
|
*/
|
||||||
|
int get_code_params(srslte_polar_code_t* c, const uint16_t K, const uint16_t E, const uint8_t nMax)
|
||||||
|
{
|
||||||
|
|
||||||
|
// include here also npc and nwmPC computatoins
|
||||||
|
if (E > EMAX) {
|
||||||
|
ERROR("Rate-matched codeword size (E) not supported. Chose E<=8192\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (nMax) {
|
||||||
|
case 9: // downlink
|
||||||
|
// iil = true
|
||||||
|
if (K < 36 || K > 164) {
|
||||||
|
ERROR("Codeblock length (K) not supported for downlink transmission, choose 165 > K > 35\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
// iil = false
|
||||||
|
if (K < 18 || (K > 25 && K < 31) || K > 1023) {
|
||||||
|
ERROR("Codeblock length (K) not supported for uplink transmission, choose K > 17 and K < 1024, "
|
||||||
|
"excluding 31 > K > 25\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("nMax not supported choose 9 for downlink and 10 for uplink transmissions\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// number of parity check bits (nPC) and parity check bits of minimum bandwidth nWmPC
|
||||||
|
uint8_t nPC = 0;
|
||||||
|
uint8_t nWmPC = 0;
|
||||||
|
if (K >= 18 && K <= 25) {
|
||||||
|
nPC = 3;
|
||||||
|
if (E > K + 189) {
|
||||||
|
nWmPC = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (K + nPC >= E) {
|
||||||
|
ERROR(" Rate-matched codeword length (E) not supported, choose E > %d\n", K + nPC);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determination of the codeword size (N)
|
||||||
|
// ceil(log2(E))
|
||||||
|
uint16_t tmpE = 0;
|
||||||
|
uint8_t e = 1;
|
||||||
|
for (; e <= eMAX; e++) {
|
||||||
|
tmpE = 1U << e; // 2^e
|
||||||
|
if (tmpE >= E) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t n1 = 0;
|
||||||
|
uint8_t e_1 = e - 1;
|
||||||
|
if ((8 * E <= 9 * (1U << e_1)) && (16 * K < 9 * E)) {
|
||||||
|
n1 = e - 1;
|
||||||
|
} else {
|
||||||
|
n1 = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ceil(log2(K))
|
||||||
|
uint16_t tmpK = 0;
|
||||||
|
uint8_t k = 0;
|
||||||
|
for (; k <= 10; k++) {
|
||||||
|
tmpK = 1U << k; // 2^e
|
||||||
|
if (tmpK >= K) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t n2 = k + 3;
|
||||||
|
|
||||||
|
// min(n1, n2, n3)
|
||||||
|
uint8_t n = n1;
|
||||||
|
if (n2 < n1) {
|
||||||
|
n = n2;
|
||||||
|
}
|
||||||
|
if (nMax < n) {
|
||||||
|
n = nMax;
|
||||||
|
}
|
||||||
|
if (n < 5) {
|
||||||
|
n = 5;
|
||||||
|
}
|
||||||
|
uint16_t N = (1U << n);
|
||||||
|
|
||||||
|
if (K >= N) {
|
||||||
|
ERROR("Codeblock length (K) not supported, choose K < N\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->N = N;
|
||||||
|
c->n = n;
|
||||||
|
c->nPC = nPC;
|
||||||
|
c->nWmPC = nWmPC;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_code_free(srslte_polar_code_t* c)
|
||||||
|
{
|
||||||
|
if (c != NULL) {
|
||||||
|
free(c->F_set);
|
||||||
|
free(c->tmp_K_set); // also removes K_set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate resources to the message set, frozen set and parity set, polar code
|
||||||
|
int srslte_polar_code_init(srslte_polar_code_t* c)
|
||||||
|
{
|
||||||
|
c->tmp_K_set = srslte_vec_u16_malloc(NMAX + 1); // +1 to mark the end with 1024
|
||||||
|
if (!c->tmp_K_set) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->F_set = srslte_vec_u16_malloc(NMAX);
|
||||||
|
if (!c->F_set) {
|
||||||
|
free(c->tmp_K_set);
|
||||||
|
perror("malloc");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_code_get(srslte_polar_code_t* c, uint16_t K, uint16_t E, uint8_t nMax)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (c == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// check polar code parameters
|
||||||
|
if (get_code_params(c, K, E, nMax) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint8_t nPC = c->nPC;
|
||||||
|
uint8_t nWmPC = c->nWmPC;
|
||||||
|
uint8_t n = c->n;
|
||||||
|
uint16_t N = c->N;
|
||||||
|
|
||||||
|
const uint16_t* blk_interleaver = get_blk_interleaver(n);
|
||||||
|
const uint16_t* mother_code = get_mother_code(n);
|
||||||
|
|
||||||
|
c->F_set_size = N - K - nPC;
|
||||||
|
c->K = K;
|
||||||
|
|
||||||
|
// Frozen bits due to Puncturing and Shortening.
|
||||||
|
int T = -1;
|
||||||
|
int tmp_F_set_size = N - E;
|
||||||
|
int N_th = 3 * N / 4;
|
||||||
|
|
||||||
|
if (tmp_F_set_size > 0) {
|
||||||
|
if (16 * K <= 7 * E) { // Puncturing
|
||||||
|
if (E >= N_th) {
|
||||||
|
T = N_th - (E >> 1U) - 1;
|
||||||
|
} else {
|
||||||
|
T = 9 * N / 16 - (E >> 2U);
|
||||||
|
}
|
||||||
|
memcpy(c->F_set,
|
||||||
|
blk_interleaver,
|
||||||
|
tmp_F_set_size * sizeof(uint16_t)); // The first (less reliable) after interleaving
|
||||||
|
|
||||||
|
} else { // Shortening
|
||||||
|
memcpy(c->F_set,
|
||||||
|
blk_interleaver + E,
|
||||||
|
tmp_F_set_size * sizeof(uint16_t)); // The first (less reliable) after interleaving
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tmp_F_set_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp_K = setdiff_stable(mother_code, c->F_set, c->tmp_K_set, T, N, tmp_F_set_size);
|
||||||
|
|
||||||
|
// Select only the most reliable (message and parity)
|
||||||
|
c->K_set = c->tmp_K_set + tmp_K - K - nPC;
|
||||||
|
|
||||||
|
// take the nPC - nWmPC less reliable
|
||||||
|
for (int i = 0; i < nPC - nWmPC; i++) {
|
||||||
|
c->PC_set[i] = c->K_set[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This only happens if K=18:25 and E=E+189+1:8192
|
||||||
|
// In this cases there is no puncturing or shortening
|
||||||
|
if (nWmPC == 1) {
|
||||||
|
if (K <= 21) {
|
||||||
|
c->PC_set[nPC - 1] = 252;
|
||||||
|
} else {
|
||||||
|
c->PC_set[nPC - 1] = 248;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sorted K_set (includes parity bits)
|
||||||
|
qsort(c->K_set, c->K + c->nPC, sizeof(uint16_t), &cmpfunc);
|
||||||
|
// sorted PC_set
|
||||||
|
if (nPC > 0) {
|
||||||
|
qsort(c->PC_set, nPC, sizeof(uint16_t), &cmpfunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the sorted frozen set as the complement of sorted K_set
|
||||||
|
uint16_t i_k = 0;
|
||||||
|
uint16_t fvalue = 0;
|
||||||
|
uint16_t i_f = 0;
|
||||||
|
while (i_f < c->F_set_size) {
|
||||||
|
if (c->K_set[i_k] == fvalue) {
|
||||||
|
i_k++; // skip
|
||||||
|
fvalue++;
|
||||||
|
} else {
|
||||||
|
c->F_set[i_f] = fvalue;
|
||||||
|
fvalue++;
|
||||||
|
i_f++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark the end of the sets (useful at subchannel allocation)
|
||||||
|
c->K_set[c->K + c->nPC] = 1024;
|
||||||
|
c->PC_set[c->nPC] = 1024;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,615 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file polar_rm.c
|
||||||
|
* \brief Definition of the LDPC Rate Matcher and Rate Dematcher (float-valued, int16_t and int8_t)
|
||||||
|
* \author Jesus Gomez (CTTC)
|
||||||
|
* \date 2020
|
||||||
|
*
|
||||||
|
* \copyright Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srslte/phy/utils/vector.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "srslte/phy/fec/polar/polar_code.h"
|
||||||
|
#include "srslte/phy/fec/polar/polar_rm.h"
|
||||||
|
|
||||||
|
#include "srslte/phy/utils/debug.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes an rate matcher.
|
||||||
|
*/
|
||||||
|
struct pRM_tx {
|
||||||
|
uint8_t* y_e; /*!< \brief Pointer to a temporal buffer to store the block interleaved codeword (y), as well as the
|
||||||
|
rate-matched codewords (e). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes an rate dematcher (float version).
|
||||||
|
*/
|
||||||
|
struct pRM_rx_f {
|
||||||
|
float* y_e; /*!< \brief Pointer to a temporal buffer to symbols before and after bit_selection_rx. */
|
||||||
|
float* e; /*!< \brief Pointer to a the position in the y_e buffer where the rate matched llr start.*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes an rate dematcher (int8_t version).
|
||||||
|
*/
|
||||||
|
struct pRM_rx_s {
|
||||||
|
int16_t* y_e; /*!< \brief Pointer to a temporal buffer to symbols before and after bit_selection_rx. */
|
||||||
|
int16_t* e; /*!< \brief Pointer to a the position in the y_e buffer where the rate matched llr start.*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Describes an rate dematcher (int8_t version).
|
||||||
|
*/
|
||||||
|
struct pRM_rx_c {
|
||||||
|
int8_t* y_e; /*!< \brief Pointer to a temporal buffer to symbols before and after bit_selection_rx. */
|
||||||
|
int8_t* e; /*!< \brief Pointer to a the position in the y_e buffer where the rate matched llr start.*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* generic interleaver
|
||||||
|
*/
|
||||||
|
static void interleaver_rm_tx(const uint8_t* input, uint8_t* output, const uint16_t* indices, const uint16_t len)
|
||||||
|
{
|
||||||
|
for (uint32_t j = 0; j < len; j++) {
|
||||||
|
output[j] = input[indices[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* generic deinterleaver.
|
||||||
|
*/
|
||||||
|
static void interleaver_rm_rx(const float* input, float* output, const uint16_t* indices, const uint16_t len)
|
||||||
|
{
|
||||||
|
for (uint32_t j = 0; j < len; j++) {
|
||||||
|
output[indices[j]] = input[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* generic deinterleaver (int16_t).
|
||||||
|
*/
|
||||||
|
static void interleaver_rm_rx_s(const int16_t* input, int16_t* output, const uint16_t* indices, const uint16_t len)
|
||||||
|
{
|
||||||
|
for (uint32_t j = 0; j < len; j++) {
|
||||||
|
output[indices[j]] = input[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* generic deinterleaver (int8_t).
|
||||||
|
*/
|
||||||
|
static void interleaver_rm_rx_c(const int8_t* input, int8_t* output, const uint16_t* indices, const uint16_t len)
|
||||||
|
{
|
||||||
|
for (uint32_t j = 0; j < len; j++) {
|
||||||
|
output[indices[j]] = input[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Bit selection for the polar rate-matching block. ye has length N, but there is EMAX memory allocated to it.
|
||||||
|
*/
|
||||||
|
static uint8_t* bit_selection_rm_tx(uint8_t* y, const uint32_t N, const uint32_t E, const uint32_t K)
|
||||||
|
{
|
||||||
|
uint8_t* e = NULL;
|
||||||
|
uint32_t k_N = 0;
|
||||||
|
|
||||||
|
e = y;
|
||||||
|
if (E >= N) { // repetition
|
||||||
|
for (uint32_t k = N; k < E; k++) {
|
||||||
|
k_N = k % N;
|
||||||
|
e[k] = y[k_N];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (16 * K <= 7 * E) { // puncturing the first N-E bits
|
||||||
|
e = y + (N - E);
|
||||||
|
} // else shortening the last N-E bits
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Undoes bit selection for the rate-dematching block float).
|
||||||
|
* The output has the codeword length N. It inserts 0 to punctured bits (completely unknown bit)
|
||||||
|
* and 127 (to indicate very reliable 0 bit). Repeated symbols are added.
|
||||||
|
*/
|
||||||
|
static float* bit_selection_rm_rx(float* e, const uint32_t E, const uint32_t N, const uint32_t K)
|
||||||
|
{
|
||||||
|
float* y = NULL;
|
||||||
|
uint32_t k_N = 0;
|
||||||
|
|
||||||
|
y = e;
|
||||||
|
if (E >= N) { // add repetitions
|
||||||
|
y = e;
|
||||||
|
for (uint32_t k = N; k < E; k++) {
|
||||||
|
k_N = k % N;
|
||||||
|
y[k_N] = y[k_N] + e[k];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (16 * K <= 7 * E) { // puncturing bits are completely unknown, i.e. llr = 0;
|
||||||
|
y = e - (N - E);
|
||||||
|
for (uint32_t k = 0; k < N - E; k++) {
|
||||||
|
y[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // shortening, bits are know to be 0. i.e., very high llrs
|
||||||
|
for (uint32_t k = E; k < N; k++) {
|
||||||
|
y[k] = 1e+20F; /* max value */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Undoes bit selection for the rate-dematching block (int16_t).
|
||||||
|
* The output has the codeword length N. It inserts 0 to punctured bits (completely unknown bit)
|
||||||
|
* and 127 (to indicate very reliable 0 bit). Repeated symbols are added.
|
||||||
|
*/
|
||||||
|
static int16_t* bit_selection_rm_rx_s(int16_t* e, const uint32_t E, const uint32_t N, const uint32_t K)
|
||||||
|
{
|
||||||
|
int16_t* y = NULL;
|
||||||
|
uint32_t k_N = 0;
|
||||||
|
long tmp = 0;
|
||||||
|
|
||||||
|
y = e;
|
||||||
|
if (E >= N) { // add repetitions
|
||||||
|
y = e;
|
||||||
|
for (uint32_t k = N; k < E; k++) {
|
||||||
|
k_N = k % N;
|
||||||
|
tmp = (long)y[k_N] + e[k];
|
||||||
|
// control saturation
|
||||||
|
if (tmp > 32767) {
|
||||||
|
tmp = 32767;
|
||||||
|
}
|
||||||
|
if (tmp < -32767) {
|
||||||
|
tmp = -32767;
|
||||||
|
}
|
||||||
|
y[k_N] = (int16_t)tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (16 * K <= 7 * E) { // puncturing bits are completely unknown, i.e. llr = 0;
|
||||||
|
y = e - (N - E);
|
||||||
|
for (uint32_t k = 0; k < N - E; k++) {
|
||||||
|
y[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // shortening, bits are know to be 0. i.e., very high llrs
|
||||||
|
for (uint32_t k = E; k < N; k++) {
|
||||||
|
y[k] = 32767; /* max value */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Undoes bit selection for the rate-dematching block (int8_t).
|
||||||
|
* The output has the codeword length N. It inserts 0 to punctured bits (completely unknown bit)
|
||||||
|
* and 127 (to indicate very reliable 0 bit). Repeated symbols are added.
|
||||||
|
*/
|
||||||
|
static int8_t* bit_selection_rm_rx_c(int8_t* e, const uint32_t E, const uint32_t N, const uint32_t K)
|
||||||
|
{
|
||||||
|
int8_t* y = NULL;
|
||||||
|
uint32_t k_N = 0;
|
||||||
|
long tmp = 0;
|
||||||
|
|
||||||
|
y = e;
|
||||||
|
if (E >= N) { // add repetitions
|
||||||
|
y = e;
|
||||||
|
for (uint32_t k = N; k < E; k++) {
|
||||||
|
k_N = k % N;
|
||||||
|
tmp = (long)y[k_N] + e[k];
|
||||||
|
// control saturation
|
||||||
|
if (tmp > 127) {
|
||||||
|
tmp = 127;
|
||||||
|
}
|
||||||
|
if (tmp < -127) {
|
||||||
|
tmp = -127;
|
||||||
|
}
|
||||||
|
y[k_N] = (int8_t)tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (16 * K <= 7 * E) { // puncturing bits are completely unknown, i.e. llr = 0;
|
||||||
|
y = e - (N - E);
|
||||||
|
for (uint32_t k = 0; k < N - E; k++) {
|
||||||
|
y[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // shortening, bits are know to be 0. i.e., very high llrs
|
||||||
|
for (uint32_t k = E; k < N; k++) {
|
||||||
|
y[k] = 127; /* max value */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Channel interleaver.
|
||||||
|
*/
|
||||||
|
static void ch_interleaver_rm_tx(const uint8_t* e, uint8_t* f, const uint32_t E)
|
||||||
|
{
|
||||||
|
// compute T - Smaller integer such that T(T+1)/2 >= E. Use the fact that 1+2+,..,+T = T(T+1)/2
|
||||||
|
uint32_t S = 1;
|
||||||
|
uint32_t T = 1;
|
||||||
|
while (S < E) {
|
||||||
|
T++;
|
||||||
|
S = S + T;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i_out = 0;
|
||||||
|
uint32_t i_in = 0;
|
||||||
|
for (uint32_t r = 0; r < T; r++) {
|
||||||
|
i_in = r;
|
||||||
|
for (uint32_t c = 0; c < T - r; c++) {
|
||||||
|
if (i_in < E) {
|
||||||
|
f[i_out] = e[i_in];
|
||||||
|
i_out++;
|
||||||
|
i_in = i_in + (T - c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Channel deinterleaver.
|
||||||
|
*/
|
||||||
|
static void ch_interleaver_rm_rx(const float* f, float* e, const uint32_t E)
|
||||||
|
{
|
||||||
|
// compute T - Smaller integer such that T(T+1)/2 >= E. Use the fact that 1+2+,..,+T = T(T+1)/2
|
||||||
|
uint32_t S = 1;
|
||||||
|
uint32_t T = 1;
|
||||||
|
while (S < E) {
|
||||||
|
T++;
|
||||||
|
S = S + T;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i_out = 0;
|
||||||
|
uint32_t i_in = 0;
|
||||||
|
for (uint32_t r = 0; r < T; r++) {
|
||||||
|
i_in = r;
|
||||||
|
for (uint32_t c = 0; c < T - r; c++) {
|
||||||
|
if (i_in < E) {
|
||||||
|
e[i_in] = f[i_out];
|
||||||
|
i_out++;
|
||||||
|
i_in = i_in + (T - c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Channel deinterleaver (int16_t).
|
||||||
|
*/
|
||||||
|
static void ch_interleaver_rm_rx_s(const int16_t* f, int16_t* e, const uint32_t E)
|
||||||
|
{
|
||||||
|
// compute T - Smaller integer such that T(T+1)/2 >= E. Use the fact that 1+2+,..,+T = T(T+1)/2
|
||||||
|
uint32_t S = 1;
|
||||||
|
uint32_t T = 1;
|
||||||
|
while (S < E) {
|
||||||
|
T++;
|
||||||
|
S = S + T;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i_out = 0;
|
||||||
|
uint32_t i_in = 0;
|
||||||
|
for (uint32_t r = 0; r < T; r++) {
|
||||||
|
i_in = r;
|
||||||
|
for (uint32_t c = 0; c < T - r; c++) {
|
||||||
|
if (i_in < E) {
|
||||||
|
e[i_in] = f[i_out];
|
||||||
|
i_out++;
|
||||||
|
i_in = i_in + (T - c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Channel deinterleaver (int8_t).
|
||||||
|
*/
|
||||||
|
static void ch_interleaver_rm_rx_c(const int8_t* f, int8_t* e, const uint32_t E)
|
||||||
|
{
|
||||||
|
// compute T - Smaller integer such that T(T+1)/2 >= E. Use the fact that 1+2+,..,+T = T(T+1)/2
|
||||||
|
uint32_t S = 1;
|
||||||
|
uint32_t T = 1;
|
||||||
|
while (S < E) {
|
||||||
|
T++;
|
||||||
|
S = S + T;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t i_out = 0;
|
||||||
|
uint32_t i_in = 0;
|
||||||
|
for (uint32_t r = 0; r < T; r++) {
|
||||||
|
i_in = r;
|
||||||
|
for (uint32_t c = 0; c < T - r; c++) {
|
||||||
|
if (i_in < E) {
|
||||||
|
e[i_in] = f[i_out];
|
||||||
|
i_out++;
|
||||||
|
i_in = i_in + (T - c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_tx_init(srslte_polar_rm_t* p)
|
||||||
|
{
|
||||||
|
if (p == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pRM_tx* pp = NULL; // pointer to the rate matcher instance
|
||||||
|
|
||||||
|
// allocate memory to the rate-matcher instance
|
||||||
|
if ((pp = malloc(sizeof(struct pRM_tx))) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ptr = pp;
|
||||||
|
|
||||||
|
// allocate memory to the blk interleaved codeword
|
||||||
|
if ((pp->y_e = srslte_vec_u8_malloc(EMAX)) == NULL) {
|
||||||
|
free(pp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_init_f(srslte_polar_rm_t* p)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pRM_rx_f* pp = NULL; // pointer to the rate matcher instance
|
||||||
|
|
||||||
|
// allocate memory to ther rate-demacher instance
|
||||||
|
if ((pp = malloc(sizeof(struct pRM_rx_f))) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ptr = pp;
|
||||||
|
|
||||||
|
// allocate memory to the temporal buffer of chDeInterleaved llrs
|
||||||
|
if ((pp->y_e = srslte_vec_f_malloc(EMAX + NMAX)) == NULL) {
|
||||||
|
free(pp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pp->e = pp->y_e + NMAX;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_init_s(srslte_polar_rm_t* p)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pRM_rx_s* pp = NULL; // pointer to the rate matcher instance
|
||||||
|
|
||||||
|
// allocate memory to ther rate-demacher instance
|
||||||
|
if ((pp = malloc(sizeof(struct pRM_rx_s))) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ptr = pp;
|
||||||
|
|
||||||
|
// allocate memory to the temporal buffer of chDeInterleaved llrs
|
||||||
|
if ((pp->y_e = srslte_vec_i16_malloc(EMAX + NMAX)) == NULL) {
|
||||||
|
free(pp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pp->e = pp->y_e + NMAX;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_init_c(srslte_polar_rm_t* p)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pRM_rx_c* pp = NULL; // pointer to the rate matcher instance
|
||||||
|
|
||||||
|
// allocate memory to ther rate-demacher instance
|
||||||
|
if ((pp = malloc(sizeof(struct pRM_rx_c))) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p->ptr = pp;
|
||||||
|
|
||||||
|
// allocate memory to the temporal buffer of chDeInterleaved llrs
|
||||||
|
if ((pp->y_e = srslte_vec_i8_malloc(EMAX + NMAX)) == NULL) {
|
||||||
|
free(pp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pp->e = pp->y_e + NMAX;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_rm_tx_free(srslte_polar_rm_t* q)
|
||||||
|
{
|
||||||
|
if (q != NULL) {
|
||||||
|
struct pRM_tx* qq = q->ptr;
|
||||||
|
free(qq->y_e);
|
||||||
|
free(qq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_rm_rx_free_f(srslte_polar_rm_t* q)
|
||||||
|
{
|
||||||
|
if (q != NULL) {
|
||||||
|
struct pRM_rx_f* qq = q->ptr;
|
||||||
|
free(qq->y_e);
|
||||||
|
// free(qq->indices);
|
||||||
|
free(qq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_rm_rx_free_s(srslte_polar_rm_t* q)
|
||||||
|
{
|
||||||
|
if (q != NULL) {
|
||||||
|
struct pRM_rx_s* qq = q->ptr;
|
||||||
|
free(qq->y_e);
|
||||||
|
// free(qq->indices);
|
||||||
|
free(qq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void srslte_polar_rm_rx_free_c(srslte_polar_rm_t* q)
|
||||||
|
{
|
||||||
|
if (q != NULL) {
|
||||||
|
struct pRM_rx_c* qq = q->ptr;
|
||||||
|
free(qq->y_e);
|
||||||
|
// free(qq->indices);
|
||||||
|
free(qq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_tx(srslte_polar_rm_t* q,
|
||||||
|
const uint8_t* input,
|
||||||
|
uint8_t* output,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil)
|
||||||
|
|
||||||
|
{
|
||||||
|
const uint16_t* blk_interleaver = get_blk_interleaver(n);
|
||||||
|
uint32_t N = (1U << n);
|
||||||
|
|
||||||
|
struct pRM_tx* pp = q->ptr;
|
||||||
|
uint8_t* y = pp->y_e;
|
||||||
|
uint8_t* e = NULL;
|
||||||
|
|
||||||
|
interleaver_rm_tx(input, y, blk_interleaver, N);
|
||||||
|
|
||||||
|
e = bit_selection_rm_tx(y, N, E, K); // moves the pointer if puncturing e = y + (N-E), otherwise e = y;
|
||||||
|
|
||||||
|
if (ibil == 0) {
|
||||||
|
memcpy(output, e, E * sizeof(uint8_t));
|
||||||
|
} else {
|
||||||
|
ch_interleaver_rm_tx(e, output, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_f(srslte_polar_rm_t* q,
|
||||||
|
const float* input,
|
||||||
|
float* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pRM_rx_f* pp = q->ptr;
|
||||||
|
float* y = NULL;
|
||||||
|
float* e = pp->e; // length E
|
||||||
|
uint32_t N = (1U << n);
|
||||||
|
|
||||||
|
const uint16_t* blk_interleaver = get_blk_interleaver(n);
|
||||||
|
|
||||||
|
if (ibil == 0) {
|
||||||
|
memcpy(e, input, E * sizeof(float));
|
||||||
|
} else {
|
||||||
|
ch_interleaver_rm_rx(input, e, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
y = bit_selection_rm_rx(e, E, N, K);
|
||||||
|
interleaver_rm_rx(y, output, blk_interleaver, N);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_s(srslte_polar_rm_t* q,
|
||||||
|
const int16_t* input,
|
||||||
|
int16_t* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pRM_rx_s* pp = q->ptr;
|
||||||
|
int16_t* y = NULL;
|
||||||
|
int16_t* e = pp->e;
|
||||||
|
uint32_t N = (1U << n);
|
||||||
|
|
||||||
|
const uint16_t* blk_interleaver = get_blk_interleaver(n);
|
||||||
|
|
||||||
|
if (ibil == 0) {
|
||||||
|
memcpy(e, input, E * sizeof(int16_t));
|
||||||
|
} else {
|
||||||
|
ch_interleaver_rm_rx_s(input, e, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
y = bit_selection_rm_rx_s(e, E, N, K);
|
||||||
|
interleaver_rm_rx_s(y, output, blk_interleaver, N);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_polar_rm_rx_c(srslte_polar_rm_t* q,
|
||||||
|
const int8_t* input,
|
||||||
|
int8_t* output,
|
||||||
|
const uint32_t E,
|
||||||
|
const uint8_t n,
|
||||||
|
const uint32_t K,
|
||||||
|
const uint8_t ibil)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pRM_rx_c* pp = q->ptr;
|
||||||
|
int8_t* y = NULL;
|
||||||
|
int8_t* e = pp->e;
|
||||||
|
uint32_t N = (1U << n);
|
||||||
|
|
||||||
|
const uint16_t* blk_interleaver = get_blk_interleaver(n);
|
||||||
|
|
||||||
|
if (ibil == 0) {
|
||||||
|
memcpy(e, input, E * sizeof(int8_t));
|
||||||
|
} else {
|
||||||
|
ch_interleaver_rm_rx_c(input, e, E);
|
||||||
|
}
|
||||||
|
|
||||||
|
y = bit_selection_rm_rx_c(e, E, N, K);
|
||||||
|
interleaver_rm_rx_c(y, output, blk_interleaver, N);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue