Files
openairinterface5g/openair1/PHY/CODING/rate_matching.c
T
Lionel Gauthier 059a0a3fdc astyle --recursive --indent=spaces=2 --style=kr --indent-col1-comments --break-blocks --convert-tabs --max-code-length=200
This is done for better merging branch/LG_PRE_RELEASE_0.3 into trunk (same process is applied on this branch)

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7073 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2015-04-09 09:29:12 +00:00

255 lines
7.0 KiB
C

/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#ifdef DEBUG
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#endif
#include "PHY/defs.h"
//#define DEBUG_PHY 1
unsigned int ps0, ps1, ps2, pb;
//----------------------------------------------
//
/*!\brief Tausworthe Uniform Random Generator. This is based on the hardware implementation described in
Lee et al, "A Hardware Gaussian Noise Generator Usign the Box-Muller Method and its Error Analysis," IEEE Trans. on Computers, 2006.
*/
//
static inline void pset_taus_seed(unsigned int off)
{
ps0 = (unsigned int)0x1e23d852 + (off<<4);
ps1 = (unsigned int)0x81f38a1c + (off<<4);
ps2 = (unsigned int)0xfe1a133e + (off<<4);
}
static inline unsigned int ptaus(void)
{
pb = (((ps0 << 13) ^ ps0) >> 19);
ps0 = (((ps0 & 0xFFFFFFFE) << 12)^ pb);
pb = (((ps1 << 2) ^ ps1) >> 25);
ps1 = (((ps1 & 0xFFFFFFF8) << 4)^ pb);
pb = (((ps2 << 3) ^ ps2) >> 11);
ps2 = (((ps2 & 0xFFFFFFF0) << 17)^ pb);
return ps0 ^ ps1 ^ ps2;
}
int rate_matching(unsigned int N_coded,
unsigned int N_input,
unsigned char *inPtr,
unsigned char N_bps,
unsigned int off)
{
unsigned int i,j,U,Umod,rep_flag=0;
unsigned int N_coded2,N_input2,Mod_input2;
int N_punctured;
if ((9*N_coded<(N_input<<2)) || (N_input<(N_coded>>1))) {
// check validity of parameters
// the first condition represents the case where the rate is greater than 2/3
// the second condition represents the case where the rate is less than 1/4
msg("[PHY][CODING] Rate matching parameter error (N_coded %d, N_input %d, N_bps %d), exiting\n",N_coded,N_input,N_bps);
return(-1);
}
//initialize all bits as transmitted
for (i=0; i<N_input; i++)
inPtr[i] |= 0x80;
// No go puncture the bits that should be removed
i=0;
N_coded2 = N_coded/N_bps;
pset_taus_seed(off);
N_input2 = N_input/N_bps;
N_punctured = N_input2-N_coded2;
if (N_punctured < 0) { // Repeat bits instead of puncturing
N_punctured = -N_punctured;
rep_flag = 1;
}
#ifdef USER_MODE
#ifdef DEBUG_PHY
printf("rate_matching : N_coded %d, N_input %d, N_bps %d\n",N_coded,N_input,N_bps);
printf("rate_matching : N_punctured = %d (%d)\n",N_bps*N_punctured,rep_flag);
printf("rate_matching : code rate = %f\n",(double)N_input/(double)N_coded/2.0);
#endif
#endif
Mod_input2 = (1<<(1+log2_approx(N_input2)))-1;
while (i < N_punctured) {
// generate N_punctured random positions in the input vector
do { // generate a modulo-N_input2 random variable
U = ptaus();
Umod = U&Mod_input2;
// printf("i %d, N_punctured %d U %u Umod %d Iptr[Umod] %x\n",i,N_punctured,U,Umod,inPtr[Umod]);
// check if the bit is already punctured/repeated, if so skip it and generate another RV
if ((Umod < N_input2) && (((inPtr[Umod]&0x80) == 0)||((inPtr[Umod]&0xc0) == 0xc0)))
Umod=N_input2;
} while (Umod>=N_input2);
for (j=0; j<N_bps; j++) { // loop over symbol bits
if (rep_flag == 0)
inPtr[Umod + (j*N_input2)] &= 0x7f; // clear MSB to indicate bit is punctured
else
inPtr[Umod + (j*N_input2)] |= 0xc0; // set MSB-1 to indicate bit is repeated
}
/*
#ifdef USER_MODE
#ifdef DEBUG_PHY
printf("rate_matching : i= %d, U = %d\n",i,Umod);
#endif
#endif
*/
i++;
}
return(0);
}
int rate_matching_lte(unsigned int N_coded,
unsigned int N_input,
unsigned char *inPtr,
unsigned int off)
{
unsigned int i,U,Umod,rep_flag=0;
unsigned int Mod_input;
int N_punctured;
if ((9*N_coded<(N_input<<2)) || (N_input<(N_coded>>1))) {
// check validity of parameters
// the first condition represents the case where the rate is greater than 2/3
// the second condition represents the case where the rate is less than 1/4
msg("[PHY][CODING] Rate matching parameter error (N_coded %d, N_input %d), exiting\n",N_coded,N_input);
return(-1);
}
//initialize all bits as transmitted
for (i=0; i<N_input; i++)
inPtr[i] |= 0x80;
// No go puncture the bits that should be removed
i=0;
pset_taus_seed(off);
N_punctured = N_input-N_coded;
if (N_punctured < 0) { // Repeat bits instead of puncturing
N_punctured = -N_punctured;
rep_flag = 1;
}
#ifdef USER_MODE
#ifdef DEBUG_PHY
printf("rate_matching : N_coded %d, N_input %d\n",N_coded,N_input);
if (rep_flag)
printf("rate_matching : N_repeated = %d\n",N_punctured);
else
printf("rate_matching : N_punctured = %d\n",N_punctured);
printf("rate_matching : code rate = %f\n",(double)N_input/(double)N_coded/3.0);
#endif
#endif
Mod_input = (1<<(1+log2_approx(N_input)))-1;
while (i < N_punctured) {
// generate N_punctured random positions in the input vector
do { // generate a modulo-N_input2 random variable
U = ptaus();
Umod = U&Mod_input;
// printf("i %d, N_punctured %d U %u Umod %d Iptr[Umod] %x\n",i,N_punctured,U,Umod,inPtr[Umod]);
// check if the bit is already punctured/repeated, if so skip it and generate another RV
if ((Umod < N_input) && (((inPtr[Umod]&0x80) == 0)||((inPtr[Umod]&0xc0) == 0xc0)))
Umod=N_input;
} while (Umod>=N_input);
if (rep_flag == 0)
inPtr[Umod] &= 0x7f; // clear MSB to indicate bit is punctured
else
inPtr[Umod] |= 0xc0; // set MSB-1 to indicate bit is repeated
/*
#ifdef USER_MODE
#ifdef DEBUG_PHY
printf("rate_matching : i= %d, U = %d\n",i,Umod);
#endif
#endif
*/
i++;
}
return(0);
}
#ifdef MAIN
void main(int argc,char **argv)
{
unsigned char input[1024];
if (argc == 1) {
printf("Provide an input\n");
exit(-1);
}
memset(input,0,1024);
rate_matching(4*157,4*256,input,atoi(argv[1]),0);
}
#endif