并行译码 多线程

 ========================================================================
//  FFILE NAME     :  turbo_parallel_fix_log.c
//  VERSION        :  1.0
//  DESCRIPTION    :  This file is turbo decode BCJR algorithm
//       			  fix slide window log map
//  REVERSION      :
// -------------------------------------------------------------------
//  No.       Date          Author          Description
// -------------------------------------------------------------------
//   1.    2010/9/20       Lu An An        initial
//   2.    2011/4/5        ZhuGuanYa       parallel//no map1 or map2
// =========================================================================
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#include <semaphore.h>

#define window_size 32  // slide window length
#define inf 127.875

#define llr_es_limit 31.875
#define gamma_limit 31.75


#define gate_counter (Len+4*window_size-1) // the first iteration, SISO1 work , SISO2 wait

#define iteriter 12


//inner interleaver ; interleave msg with interleave_table
void inner_interleave(double *msg, int Len, int *interleave_table)
{
	double	*tmp;
	int		i;

	tmp = (double*) malloc(Len*sizeof(double));

	for(i=0; i<Len; i++)
	{
		tmp[i] = msg[interleave_table[i]];
	}

	for(i=0; i<Len; i++)
	{
		msg[i] = tmp[i];
	}

	free(tmp);
}


//inner deinterleaver ; deinterleave msg with interleave_table
void inner_deinterleave(double* msg, int Len, int *interleave_table)
{
	double	*tmp;
	int		i;

	tmp = (double*) malloc(Len*sizeof(double));

	for(i=0; i<Len; i++)
	{
		tmp[interleave_table[i]] = msg[i];
	}

	for(i=0; i<Len; i++)
	{
		msg[i] = tmp[i];
	}

	free(tmp);
}

void get_deinterleave_table(int* deinterleave_table,int Len, int* interleave_table)
{
    int*tmp;
    int i;

    tmp = (int*) malloc(Len*sizeof(int));

    for(i=0;    i<Len;  i++)
    {
        tmp[interleave_table[i]]=i;
    }
    	for(i=0; i<Len; i++)
	{
		deinterleave_table[i] = tmp[i];
	}

	free(tmp);


}
//rate matching; rate match with table inter_index
void	rate_matching(int D, int E, double *input, double *output, int *inter_index)
{
	int i;

	for(i=0; i<E; i++)
	{
		output[i] = input[inter_index[i]];
	}
}


//rate dematching; rate dematch with table inter_index
void	rate_dematching(int D, int E, double *input, double *output, int *inter_index)
{
	int i;
	int j;
	for(i=0; i<3*D; i++)
	{
		output[i] = 0;
	}
	for(i=0; i<E; i++)
	{

		output[inter_index[i]] += input[i];
	}
}

//max algorithm for Log-MAP algorithm of RSC decoder
//int maxo(int t0, int t1)
double maxo(double t0, double t1)
{
	double tmp;  //tmp=log(1+exp(-fabs(t0-t1)));
	if (fabs(t0-t1)<0.25)
		tmp = 0.75;
	else if(fabs(t0-t1)<0.75)
		tmp = 0.5;
	else if(fabs(t0-t1)<2.25)
		tmp = 0.25;
	else
		tmp=0;

	if (t0 >= t1)
	{
		return t0+tmp;//+8*log(1+exp(-abs((t0-t1)/8)));//tmp=4*log(1+exp(-abs((t0-t1)/4)));
	}
	else
	{
		return t1+tmp;//+8*log(1+exp(-abs((t0-t1)/8)));//tmp=4*log(1+exp(-abs((t0-t1)/4)));
	}
}

//gamma buffer: first in first out
void gamma_buffer(double *gs, double *gp, double gs_tmp, double gp_tmp)
{
		int loop;

		for (loop=window_size*4; loop>0; loop--)
		{
			gs[loop]=gs[loop-1];
			gp[loop]=gp[loop-1];
		}

		gs[0]=gs_tmp;
		gp[0]=gp_tmp;
}

//Alpha recursive algorithm
void calc_Alpha(double gs, double gp,double *Alpha,double *Alpha_tmp)
{
		int state;
		int previous_state_1,previous_state_2;

//state 0 and 1 to state 0
		state=0;
		previous_state_1=0;
		previous_state_2=1;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs+gp,Alpha[previous_state_2]);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]-gs-gp,Alpha[previous_state_2]+gs+gp);
		//state 2 and 3 to state 1
		state=1;
		previous_state_1=2;
		previous_state_2=3;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gp,Alpha[previous_state_2]+gs);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs-gp,Alpha[previous_state_2]-gs+gp);
		//state 4 and 5 to state 2
		state=2;
		previous_state_1=4;
		previous_state_2=5;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs,Alpha[previous_state_2]+gp);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]-gs+gp,Alpha[previous_state_2]+gs-gp);
		//state 6 and 7 to state 3
		state=3;
		previous_state_1=6;
		previous_state_2=7;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1],Alpha[previous_state_2]+gs+gp);
		//state 0 and 1 to state 4		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs+gp,Alpha[previous_state_2]-gs-gp);

		state=4;
		previous_state_1=0;
		previous_state_2=1;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1],Alpha[previous_state_2]+gs+gp);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs+gp,Alpha[previous_state_2]-gs-gp);
		//state 2 and 3 to state 5
		state=5;
		previous_state_1=2;
		previous_state_2=3;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs,Alpha[previous_state_2]+gp);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]-gs+gp,Alpha[previous_state_2]+gs-gp);
		//state 4 and 5 to state 6
		state=6;
		previous_state_1=4;
		previous_state_2=5;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gp,Alpha[previous_state_2]+gs);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs-gp,Alpha[previous_state_2]-gs+gp);
		//state 0 and 1 to state 7
		state=7;
		previous_state_1=6;
		previous_state_2=7;
		Alpha_tmp[state]=maxo(Alpha[previous_state_1]+gs+gp,Alpha[previous_state_2]);
		//Alpha_tmp[state]=maxo(Alpha[previous_state_1]-gs-gp,Alpha[previous_state_2]+gs+gp);


        //Alpha overflow processing
		//Alpha overflow processing

}


//Beta recursive algorithm
void calc_Beta(double gs, double gp, double* Beta, double *Beta_tmp)
{

  int state;
  int next_state_1,next_state_2;

		//state 0 to state 0 or 4
		state=0;
		next_state_1=0;
		next_state_2=4;
		//Beta_tmp[state]=maxo(Beta[next_state_1]-gs-gp,Beta[next_state_2]+gs+gp);
        Beta_tmp[state]=maxo(Beta[next_state_1]+gs+gp,Beta[next_state_2]);
		//state 1 to state 0 or 4
		state=1;
		next_state_1=0;
		next_state_2=4;
		//Beta_tmp[state]=maxo(Beta[next_state_1]+gs+gp,Beta[next_state_2]-gs-gp);
        Beta_tmp[state]=maxo(Beta[next_state_1],Beta[next_state_2]+gs+gp);
		//state 2 to state 1 or 5
		state=2;
		next_state_1=1;
		next_state_2=5;
		//Beta_tmp[state]=maxo(Beta[next_state_1]+gs-gp,Beta[next_state_2]-gs+gp);
        Beta_tmp[state]=maxo(Beta[next_state_1]+gp,Beta[next_state_2]+gs);
		//state 3 to state 1 or 5
		state=3;
		next_state_1=1;
		next_state_2=5;
		//Beta_tmp[state]=maxo(Beta[next_state_1]-gs+gp,Beta[next_state_2]+gs-gp);
        Beta_tmp[state]=maxo(Beta[next_state_1]+gs,Beta[next_state_2]+gp);
		//state 4 to state 2 or 6
		state=4;
		next_state_1=2;
		next_state_2=6;
		//Beta_tmp[state]=maxo(Beta[next_state_1]-gs+gp,Beta[next_state_2]+gs-gp);
        Beta_tmp[state]=maxo(Beta[next_state_1]+gs,Beta[next_state_2]+gp);
		//state 5 to state 2 or 6
		state=5;
		next_state_1=2;
		next_state_2=6;
		//Beta_tmp[state]=maxo(Beta[next_state_1]+gs-gp,Beta[next_state_2]-gs+gp);
        Beta_tmp[state]=maxo(Beta[next_state_1]+gp,Beta[next_state_2]+gs);
		//state 6 to state 3 or 7
		state=6;
		next_state_1=3;
		next_state_2=7;
		//Beta_tmp[state]=maxo(Beta[next_state_1]+gs+gp,Beta[next_state_2]-gs-gp);
        Beta_tmp[state]=maxo(Beta[next_state_1],Beta[next_state_2]+gs+gp);
		//state 7 to state 3 or 7
		state=7;
		next_state_1=3;
		next_state_2=7;
		//Beta_tmp[state]=maxo(Beta[next_state_1]-gs-gp,Beta[next_state_2]+gs+gp);
		Beta_tmp[state]=maxo(Beta[next_state_1]+gs+gp,Beta[next_state_2]);
}

//read Beta from Beta buffer for llr calculation
void read_Beta(int Beta_address_order_flag, int llr_calc_counter, double* Beta_buffer, double* Beta_buffer_tmp)
{
    int i;
	for(i=0; i<8; i++)
	{
		if(Beta_address_order_flag==0)  // Beta previous buffer address order: window_size ... 5 4 3 2 1 0
		{
			Beta_buffer_tmp[i]=Beta_buffer[(window_size-1)*8-(llr_calc_counter%window_size)*8+i];
		}
        else  // Beta previous buffer address order 0 1 2 3 ... window_size
		{
        	Beta_buffer_tmp[i]=Beta_buffer[(llr_calc_counter%window_size)*8+i];
		}
	}
}
//Beta update and save
void Beta_update_and_save(int Beta_initial_end, int Beta_address_order_flag, int Beta_initial_flag, int llr_calc_counter, double gs, double gp, double* Beta, double* Beta_acq, double* Beta_buffer)
{
    int i;
    double	*Beta_tmp;
    Beta_tmp = (double*) malloc(8*sizeof(double));

        if (Beta_initial_flag==1)
        {
                for (i=0; i<8; i++)
                {
                    Beta[i]=Beta_acq[i];
                }

            for (i=0; i<8; i++)
            {
                if(Beta_address_order_flag==0) // Beta buffer address order 0 1 2 3 ... window_size
                {
                    Beta_buffer[(window_size-1)*8+i]=Beta[i];
                }
                else // Beta buffer address order window_size ... 5 4 3 2 1 0
                {
                    Beta_buffer[i]=Beta[i];
                }
            }
        }
        else
        {
            calc_Beta(gs,gp,Beta,Beta_tmp);
            for (i=0; i<8; i++)
            {
                if(Beta_address_order_flag==0) // Beta buffer address order 0 1 2 3 ... window_size
                {
                    Beta_buffer[(window_size-1)*8-(llr_calc_counter%window_size)*8+i]=Beta_tmp[i];
                }
                else // Beta buffer address order window_size ... 5 4 3 2 1 0
                {
                    Beta_buffer[(llr_calc_counter%window_size)*8+i]=Beta_tmp[i];
                }

                Beta[i]=Beta_tmp[i];
            }
        }


     free(Beta_tmp);
}

//Beta_acq update for slide window MAP algorithm
void Beta_acq_update(int Beta_acq_initial_end, int Beta_acq_initial_flag, double gs, double gp, double* Beta_acq, int map_type)
{
    double	*Beta_acq_tmp;

    int i;

    Beta_acq_tmp = (double*) malloc(8*sizeof(double));

    if (Beta_acq_initial_end == 1)    //in the end of the code word, initial Beta_acq with the following
    {
           for (i=0; i<8; i++)
           {
               Beta_acq[i]=0;       //turbo code with tail bit, state 0 is the only possible state
           }
           if (1)
           {
               Beta_acq[0]=192/8;
           }



    }
    else                            //not to the end of the code word, initial Beta_acq with the following
    {
           if (Beta_acq_initial_flag==1)      //initial Beta_acq
           {
                for (i=0; i<8; i++)
                {
                    Beta_acq[i]=0;          //eight state has the same probability
                }
            }
            else
           {
                calc_Beta(gs,gp,Beta_acq,Beta_acq_tmp);         //Beta_acq recursive

                for (i=0; i<8; i++)
                {
                    Beta_acq[i]=Beta_acq_tmp[i];
                }

            }
    }


    free(Beta_acq_tmp);
}

//calculate systematic bit extrinstic information(log likelihood ratio) with gp Alpha Beta 	-- type = 0;
//calculate partiy bit extrinstic information(log likelihood ratio) with gs Alpha Beta 	 	-- type = 1;
double calc_ext_llr(double gs, double gp, double *Alpha,double *Beta, int type)
{
	double nom,denom;
	double nom1,nom2,nom3,nom4,denom1,denom2,denom3,denom4;

	if (type==0)
	{
		//nom1=maxo(Alpha[0]+gp+Beta[4],Alpha[1]+gp+Beta[0]);
		nom1=maxo(Alpha[0]+Beta[4],Alpha[1]+Beta[0]);
		//nom2=maxo(Alpha[2]-gp+Beta[1],Alpha[3]-gp+Beta[5]);
		nom2=maxo(Alpha[2]+gp+Beta[1],Alpha[3]+gp+Beta[5]);
		//nom3=maxo(Alpha[4]-gp+Beta[6],Alpha[5]-gp+Beta[2]);
		nom3=maxo(Alpha[4]+gp+Beta[6],Alpha[5]+gp+Beta[2]);
		//nom4=maxo(Alpha[6]+gp+Beta[3],Alpha[7]+gp+Beta[7]);
		nom4=maxo(Alpha[6]+Beta[3],Alpha[7]+Beta[7]);
		nom=maxo(maxo(nom1,nom2),maxo(nom3,nom4));
		//denom1=maxo(Alpha[0]-gp+Beta[0],Alpha[1]-gp+Beta[4]);
        denom1=maxo(Alpha[0]+gp+Beta[0],Alpha[1]+gp+Beta[4]);
		//denom2=maxo(Alpha[2]+gp+Beta[5],Alpha[3]+gp+Beta[1]);
        denom2=maxo(Alpha[2]+Beta[5],Alpha[3]+Beta[1]);
		//denom3=maxo(Alpha[4]+gp+Beta[2],Alpha[5]+gp+Beta[6]);
        denom3=maxo(Alpha[4]+Beta[2],Alpha[5]+Beta[6]);
		//denom4=maxo(Alpha[6]-gp+Beta[7],Alpha[7]-gp+Beta[3]);
        denom4=maxo(Alpha[6]+gp+Beta[7],Alpha[7]+gp+Beta[3]);
		denom=maxo(maxo(denom1,denom2),maxo(denom3,denom4));

		return denom-nom;
	}
	else
	{
		//nom1=maxo(Alpha[0]+gs+Beta[4],Alpha[1]+gs+Beta[0]);
        nom1=maxo(Alpha[0]+Beta[4],Alpha[1]+Beta[0]);
		//nom2=maxo(Alpha[2]-gs+Beta[5],Alpha[3]-gs+Beta[1]);
        nom2=maxo(Alpha[2]+gs+Beta[5],Alpha[3]+gs+Beta[1]);
		//nom3=maxo(Alpha[4]-gs+Beta[2],Alpha[5]-gs+Beta[6]);
        nom3=maxo(Alpha[4]+gs+Beta[2],Alpha[5]+gs+Beta[6]);
		//nom4=maxo(Alpha[6]+gs+Beta[3],Alpha[7]+gs+Beta[7]);
        nom4=maxo(Alpha[6]+Beta[3],Alpha[7]+Beta[7]);
		nom=maxo(maxo(nom1,nom2),maxo(nom3,nom4));
		//denom1=maxo(Alpha[0]-gs+Beta[0],Alpha[1]-gs+Beta[4]);
        denom1=maxo(Alpha[0]+gs+Beta[0],Alpha[1]+gs+Beta[4]);
		//denom2=maxo(Alpha[2]+gs+Beta[3],Alpha[3]+gs+Beta[5]);
        denom2=maxo(Alpha[2]+Beta[1],Alpha[3]+Beta[5]);
		//denom3=maxo(Alpha[4]+gs+Beta[6],Alpha[5]+gs+Beta[2]);
        denom3=maxo(Alpha[4]+Beta[6],Alpha[5]+Beta[2]);
		//denom4=maxo(Alpha[6]-gs+Beta[7],Alpha[7]-gs+Beta[3]);
        denom4=maxo(Alpha[6]+gs+Beta[7],Alpha[7]+gs+Beta[3]);
		denom=maxo(maxo(denom1,denom2),maxo(denom3,denom4));
		return denom-nom;
	}

}


//RSC decoder for turbo decoder
void * turbo_rsc_decoder1(void*   args)
                        //int* Len_p,int* Mem_p,int* llr_es1,int* llr_es2,int* interleave_table,int* deinterleave_table
						//int* llr_s1,int* llr_s2,int* llr_p1,int* llr_p2,int* llr_ep1,int* llr_ep2,int* store_llr1,int* store_llr2
                        //sem1, sem2,  itermax, sem3
{
            int*    Len_p  =   ((void**)args)[0];
            int*    Mem_p   =   ((void**)args)[1];
            double*    llr_es1   =   ((void**)args)[2];
            double*    llr_es2   =   ((void**)args)[3];
            int*    interleave_table    =   ((void**)args)[4];
            int*    deinterleave_table    =   ((void**)args)[5];
            double*    llr_s1  =   ((void**)args)[6];
            double*    llr_s2  =   ((void**)args)[7];
            double*    llr_p1  =   ((void**)args)[8];
            double*    llr_p2  =   ((void**)args)[9];
            double*    llr_ep1  =   ((void**)args)[10];
            double*    llr_ep2  =   ((void**)args)[11];
            double*    store_llr1 = ((void**)args)[12];
            double*    store_llr2 = ((void**)args)[13];
            sem_t*  sem1_p =     ((void**)args)[14];
            sem_t*  sem2_p =     ((void**)args)[15];
            int*    itermax_p = ((void**)args)[16];
            sem_t*  sem3_p = ((void**)args)[17];
            sem_t*  sem4_p = ((void**)args)[18];



		double         *gs;
		double	        *gp;
		double	        gamma_s;
		double	        gamma_p;
		double	        *Beta,*Beta_acq,*Beta_buffer,*Beta_buffer_tmp;
		double         *Alpha;
		double	        *Alpha_tmp;
		int         Beta_initial_flag;
		int  		Beta_acq_initial_flag;
		int 		Beta_address_order_flag;
		int 		i;
        int         Beta_acq_initial_end;
        int         Beta_initial_end;
        int         addr_tmp;
        int         map_type;
        int         Len;
        int         Mem;
        int         itermax;
        int         n_iter;
        int         llr_calc_counter;

        int         window_number;
        int         window_counter;
        int         zero_padding_number;
        int         tmp;
        int         index1;
        int         index2;


		gs = (double*) malloc((window_size*4+1)*sizeof(double));
		gp = (double*) malloc((window_size*4+1)*sizeof(double));
		Alpha = (double*) malloc(8*sizeof(double));
		Alpha_tmp = (double*) malloc(8*sizeof(double));
		Beta = (double*) malloc(8*sizeof(double));
		Beta_acq = (double*) malloc(8*sizeof(double));
		Beta_buffer = (double*) malloc(window_size*8*sizeof(double));
		Beta_buffer_tmp = (double*) malloc(8*sizeof(double));
		//deinterleave_table = (int*) malloc(Len*sizeof(int));

		//llr_calc_counter=0;
		//llr_calc_state=0;
        Beta_acq_initial_end=0;
        Beta_initial_end=0;
        window_counter=0;
        map_type=1;
        Len=*Len_p;
        Mem=*Mem_p;
        itermax=*itermax_p;
        //llr_calc_counter = 0;




		Len=Len+3;   //+3 tail bit;
		//printf("428 interleave %d\n",interleave_table[428]);


            if((Len%window_size)==0)
            {
                window_number=Len/window_size;
                zero_padding_number=0;
            }
            else
            {
                window_number=Len/window_size+1;
                zero_padding_number=window_number*window_size-Len;
            }
        // }
        Len=window_size*window_number;


        //slide window Log-MAP algorithm





             for(n_iter=0;n_iter<itermax;n_iter++)
                {
                    window_counter = 0;
                    Beta_acq_initial_end=0;
                    Beta_initial_end=0;
                    for(i=0;i<window_size*4+1;i++)
                    {
                        gs[i]=0;
                        gp[i]=0;

                    }
                    for(i=0;i<8;i++)
                    {
                        Alpha[i] = 0;
                        Alpha_tmp[i] = 0;
                        Beta[i] = 0;
                        Beta_acq[i] = 0;
                        Beta_buffer_tmp[i] = 0;
                    }
                    for(i=0;i<window_size*8;i++)
                    {
                        Beta_buffer[i]=0;
                    }

                    for(llr_calc_counter = 0;llr_calc_counter<Len+4*window_size;llr_calc_counter++)

                        {
                            //window_counter = 0;
                            //printf("post\n");

                            //if(llr_calc_counter == 0 &&n_iter==1)
                            /*{
                                sem_post(&(*sem3_p));
                                sem_post(&(*sem3_p));

                            }*/

                                if((llr_calc_counter%window_size)==0 && llr_calc_counter!=0)
                                {
                                    window_counter++;
                                }

                                if (llr_calc_counter%(2*window_size)<window_size)
                                {
                                    Beta_address_order_flag=0;  //beta address order 0 1 ... 31
                                }
                                else
                                {
                                    Beta_address_order_flag=1;  //beta address order 31 30 ... 0
                                }

                                 //gamma buffer
                                addr_tmp=llr_calc_counter;
                                //information bits

                                if(addr_tmp<Len-3-zero_padding_number)
                                {
                                    //printf("%d\n",deinterleave_table[addr_tmp]);
                                    tmp=deinterleave_table[addr_tmp];

                                    gamma_s = -llr_s1[addr_tmp]+llr_es2[tmp]+store_llr1[addr_tmp];

                                            gamma_p = -llr_p1[addr_tmp];
                                            //printf("read OK!\n");


                                }
                                //tail bit
                                else if(llr_calc_counter<Len-zero_padding_number)
                                {
                                            gamma_s = -llr_s1[addr_tmp]+store_llr1[addr_tmp];
                                            gamma_p = -llr_p1[addr_tmp];

                                            //handle overflow problem

                                }


                                if(llr_calc_counter<Len-zero_padding_number)
                                {
                                    gamma_buffer(gs,gp,(gamma_s),gamma_p);
                                }
                                else
                                {
                                    if(llr_calc_counter<Len)
                                    {
                                        gamma_buffer(gs,gp,64,64);
                                    }
                                    else
                                    {
                                        gamma_buffer(gs,gp,0,0);
                                    }
                                }
                                //initial Alpha
                                if(llr_calc_counter==0)
                                {
                                    for (i=0; i<8; i++)
                                    {
                                            Alpha[i]= 0;
                                    }
                                    if (1)
                                    {
                                        Alpha[0]=192/4;
                                    }
                                }

                                 //start alpha calculation and llr calculation
                                 //printf("3");
                                if(window_counter>3)
                                {
                                    if(window_counter<window_number+4)
                                    {
                                        read_Beta(Beta_address_order_flag, llr_calc_counter, Beta_buffer, Beta_buffer_tmp);

                                        //llr calculation
                                        addr_tmp=4*window_size;
                                        if(llr_calc_counter>=4*window_size && llr_calc_counter<Len-zero_padding_number+4*window_size)
                                        {

                                            llr_es1[llr_calc_counter-4*window_size] = calc_ext_llr(gs[addr_tmp],gp[addr_tmp],Alpha,Beta_buffer_tmp,0);//>>1;
                                            llr_ep1[llr_calc_counter-4*window_size] = calc_ext_llr(gs[addr_tmp],gp[addr_tmp],Alpha,Beta_buffer_tmp,1);



                                              //Alpha calculation
                                              calc_Alpha(gs[addr_tmp],gp[addr_tmp],Alpha,Alpha_tmp);

                                              for(i=0; i<8; i++)
                                              {
                                                    Alpha[i]=Alpha_tmp[i];   //error Alpha[i]=Alpha_tmp[i]-64;
                                              }
                                           }

                                    }

                              }


                               //start beta calculation
                               //printf("2");
                              if(window_counter>2)
                              {
                                  if(window_counter<window_number+3)
                                  {
                                        if(llr_calc_counter%window_size ==0 )
                                        {
                                            if(window_counter==window_number+2)
                                            {
                                                Beta_initial_end=1;

                                             }
                                             Beta_initial_flag=1;
                                        }
                                        else
                                        {
                                            Beta_initial_flag=0;
                                        }

                                        //Beta update
                                        addr_tmp=2*window_size+(llr_calc_counter%window_size)*2;
                                        Beta_update_and_save(Beta_initial_end,Beta_address_order_flag,Beta_initial_flag, llr_calc_counter, gs[addr_tmp], gp[addr_tmp], Beta, Beta_acq, Beta_buffer);

                                  }

                              }

                              //start beta acq calculation
                              //printf("1");
                              if(window_counter>1)
                              {
                                  if(window_counter<(window_number+2));
                                  {
                                        //Beta flag
                                        if ((llr_calc_counter%window_size) ==0 )
                                        {
                                            if(window_counter==window_number+1)
                                            {
                                                Beta_acq_initial_end=1;
                                            }

                                            Beta_acq_initial_flag=1;
                                        }
                                        else
                                        {
                                            Beta_acq_initial_flag=0;
                                        }

                                        addr_tmp=1+(llr_calc_counter%window_size)*2;
                                        Beta_acq_update(Beta_acq_initial_end,Beta_acq_initial_flag, gs[addr_tmp], gp[addr_tmp], Beta_acq,map_type);
                                    }

                               }
                //printf("0\n");
                /*
                if(n_iter==0&&llr_calc_counter ==0)
                {
                    sem_post(&(*sem3_p));
                }
                sem_getvalue(&(*sem3_p),&index1);
                //sem_getvalue(&(*sem4_p),&index2);*/
                if(llr_calc_counter> gate_counter|| n_iter>0)
                {
                    //
                    sem_post(&(*sem1_p));
                    //printf("0\n");
                    sem_wait(&(*sem2_p));
                    //printf("eeeee\n");
                }


                        }


                }
                //sem_wait(&(*sem3_p));
                //sem_wait(&(*sem4_p));

	    Len=Len-3-zero_padding_number;


		free(Alpha_tmp);
		free(gs);
		free(gp);
		free(Alpha);
		free(Beta);
		free(Beta_buffer);
		free(Beta_buffer_tmp);
		free(Beta_acq);

		return 0;



}

void * turbo_rsc_decoder2(void*   args)
                        //int* Len_p,int* Mem_p,int* llr_es1,int* llr_es2,int* interleave_table,int* deinterleave_table
						//int* llr_s1,int* llr_s2,int* llr_p1,int* llr_p2,int* llr_ep1,int* llr_ep2,int* store_llr1,int* store_llr2
                        //sem1, sem2, llr_calc_counter, n_iter, itermax. sem3


{
            int*    Len_p  =   ((void**)args)[0];
            int*    Mem_p   =   ((void**)args)[1];
            double*    llr_es1   =   ((void**)args)[2];
            double*    llr_es2   =   ((void**)args)[3];
            int*    interleave_table    =   ((void**)args)[4];
            int*    deinterleave_table =   ((void**)args)[5];
            double*    llr_s1  =   ((void**)args)[6];
            double*    llr_s2  =   ((void**)args)[7];
            double*    llr_p1  =   ((void**)args)[8];
            double*    llr_p2  =   ((void**)args)[9];
            double*    llr_ep1  =   ((void**)args)[10];
            double*    llr_ep2  =   ((void**)args)[11];
            double*    store_llr1 = ((void**)args)[12];
            double*    store_llr2 = ((void**)args)[13];
            sem_t*  sem1_p =     ((void**)args)[14];
            sem_t*  sem2_p =     ((void**)args)[15];
            int*    itermax_p = ((void**)args)[16];
            sem_t*  sem3_p = ((void**)args)[17];
            sem_t*  sem4_p = ((void**)args)[18];
            //FILE* fd;



		double         *gs;
		double	        *gp;
		double         gamma_p;
		double         gamma_s;
		double	        *Beta,*Beta_acq,*Beta_buffer,*Beta_buffer_tmp;
		double         *Alpha;
		double	        *Alpha_tmp;
		int         Beta_initial_flag;
		int  		Beta_acq_initial_flag;
		int 		Beta_address_order_flag;
		int 		i;
        int         Beta_acq_initial_end;
        int         Beta_initial_end;
        int         addr_tmp;
        int         map_type;
        int         Len;
        int         Mem;
        int         itermax;
        int         llr_calc_counter;
        int         n_iter;

        int         window_number;
        int         window_counter;
        int         zero_padding_number;
        int         tmp;
        int         index1;
        int         index2;

		//FILE        *fd;

		gs = (double*) malloc((window_size*4+1)*sizeof(double));
		gp = (double*) malloc((window_size*4+1)*sizeof(double));
		Alpha = (double*) malloc(8*sizeof(double));
		Alpha_tmp = (double*) malloc(8*sizeof(double));
		Beta = (double*) malloc(8*sizeof(double));
		Beta_acq = (double*) malloc(8*sizeof(double));
		Beta_buffer = (double*) malloc(window_size*8*sizeof(double));
		Beta_buffer_tmp = (double*) malloc(8*sizeof(double));
		//fd = fopen("step_test.txt","w");

		//llr_calc_counter=0;
		//llr_calc_state=0;
		Len=*Len_p;
		Mem=*Mem_p;
		itermax=*itermax_p;

        Beta_acq_initial_end=0;
        Beta_initial_end=0;
        window_counter=0;
        map_type=1;

		Len=Len+3;   //+3 tail bit;


            if((Len%window_size)==0)
            {
                window_number=Len/window_size;
                zero_padding_number=0;
            }
            else
            {
                window_number=Len/window_size+1;
                zero_padding_number=window_number*window_size-Len;
            }
        // }
        Len=window_size*window_number;


        //slide window Log-MAP algorithm

        //sem_wait(&(*sem3_p));

        //sem_post(&(*sem4_p));



for(n_iter=0;n_iter<itermax;n_iter++)
                {
                    window_counter = 0;
                    Beta_acq_initial_end=0;
                    Beta_initial_end=0;
                    for(i=0;i<window_size*4+1;i++)
                    {
                        gs[i]=0;
                        gp[i]=0;

                    }
                    for(i=0;i<8;i++)
                    {
                        Alpha[i] = 0;
                        Alpha_tmp[i] = 0;
                        Beta[i] = 0;
                        Beta_acq[i] = 0;
                        Beta_buffer_tmp[i] = 0;
                    }
                    for(i=0;i<window_size*8;i++)
                    {
                        Beta_buffer[i]=0;
                    }


                    for(llr_calc_counter=0;llr_calc_counter<Len+4*window_size;llr_calc_counter++)

                        {
                            //printf("calc_2\n");
                            //printf("task2\n");
                //sem_getvalue(&(*sem3_p),&index1);
               //sem_getvalue(&(*sem4_p),&index2);
               if(llr_calc_counter < Len +4*window_size - gate_counter - 1 || n_iter<itermax - 1)
               {
                //sem_post(&(*sem1_p));
                sem_wait(&(*sem1_p));
                //printf("www\n");
               }
               //printf("deBUG!\n");


                        if((llr_calc_counter%window_size)==0 && llr_calc_counter!=0)
                        {
                            window_counter++;
                            //printf("window_counter = %d\n",window_counter);
                        }

                        if (llr_calc_counter%(2*window_size)<window_size)
                        {
                            Beta_address_order_flag=0;  //beta address order 0 1 ... 31
                        }
                        else
                        {
                            Beta_address_order_flag=1;  //beta address order 31 30 ... 0
                        }
                        //printf("deBUG!\n");

                         //gamma buffer
                        addr_tmp=llr_calc_counter;



                        //information bits
                        tmp = interleave_table[addr_tmp];
                        if(addr_tmp<Len-3-zero_padding_number)

                        {

                                    //printf("gamma_s = -llr_s2[addr_tmp]+llr_es1[tmp]+store_llr2[addr_tmp];\n");
                                    gamma_s = -llr_s2[addr_tmp]+llr_es1[tmp]+store_llr2[addr_tmp];
                                    //printf("gamma_s = -llr_s2[addr_tmp]+llr_es1[tmp]+store_llr2[addr_tmp];\n");

                                    gamma_p = -llr_p2[addr_tmp];
                                   // printf("deBUG!\n");
                                    //printf("read2222222!!!\n");

                                    //handle overflow problem

                        }

                        //tail bit
                        else if(llr_calc_counter<Len-zero_padding_number)
                        {
                                    gamma_s = -llr_s2[addr_tmp]+store_llr2[addr_tmp];
                                    gamma_p = -llr_p2[addr_tmp];


                        }



                        if(llr_calc_counter<Len-zero_padding_number)
                        {
                            gamma_buffer(gs,gp,(gamma_s),gamma_p);
                        }
                        else
                        {
                            if(llr_calc_counter<Len)
                            {
                                gamma_buffer(gs,gp,64,64);
                            }
                            else
                            {
                                gamma_buffer(gs,gp,0,0);
                            }
                        }
                        //initial Alpha

                        if(llr_calc_counter==0)
                        {
                            for (i=0; i<8; i++)
                            {
                                    Alpha[i]= 0;
                            }
                            if (1)
                            {
                                Alpha[0]=192/4;
                            }
                        }

                         //start alpha calculation and llr calculation
                        if(window_counter>3)
                        {
                            if(window_counter<window_number+4)
                            {
                                read_Beta(Beta_address_order_flag, llr_calc_counter, Beta_buffer, Beta_buffer_tmp);

                                //llr calculation
                                addr_tmp=4*window_size;
                                if(llr_calc_counter>=4*window_size && llr_calc_counter<Len-zero_padding_number+4*window_size)
                                {

                                    llr_es2[llr_calc_counter-4*window_size] = calc_ext_llr(gs[addr_tmp],gp[addr_tmp],Alpha,Beta_buffer_tmp,0);//>>1;
                                    llr_ep2[llr_calc_counter-4*window_size] = calc_ext_llr(gs[addr_tmp],gp[addr_tmp],Alpha,Beta_buffer_tmp,1);//>>1;


                                      /*
                                      if(llr_calc_counter==4*window_size+100)
                                      {
                                          printf("gs[100]=%d\n",gs[addr_tmp]);
                                      }
                                      */

                                      //Alpha calculation
                                      calc_Alpha(gs[addr_tmp],gp[addr_tmp],Alpha,Alpha_tmp);

                                      for(i=0; i<8; i++)
                                      {
                                            Alpha[i]=Alpha_tmp[i];   //error Alpha[i]=Alpha_tmp[i]-64;
                                      }
                                   }

                            }

                      }


                      //printf("4");
                       //start beta calculation
                      if(window_counter>2)
                      {
                          if(window_counter<window_number+3)
                          {
                                if(llr_calc_counter%window_size ==0 )
                                {
                                    if(window_counter==window_number+2)
                                    {
                                        Beta_initial_end=1;

                                     }
                                     Beta_initial_flag=1;
                                }
                                else
                                {
                                    Beta_initial_flag=0;
                                }

                                //Beta update
                                addr_tmp=2*window_size+(llr_calc_counter%window_size)*2;
                                Beta_update_and_save(Beta_initial_end,Beta_address_order_flag,Beta_initial_flag, llr_calc_counter, gs[addr_tmp], gp[addr_tmp], Beta, Beta_acq, Beta_buffer);

                          }

                      }

                      //start beta acq calculation
                     // printf("5");
                      if(window_counter>1)
                      {
                          if(window_counter<(window_number+2));
                          {
                                //Beta flag
                                if ((llr_calc_counter%window_size) ==0 )
                                {
                                    if(window_counter==window_number+1)
                                    {
                                        Beta_acq_initial_end=1;
                                    }

                                    Beta_acq_initial_flag=1;
                                }
                                else
                                {
                                    Beta_acq_initial_flag=0;
                                }

                                addr_tmp=1+(llr_calc_counter%window_size)*2;
                                Beta_acq_update(Beta_acq_initial_end,Beta_acq_initial_flag, gs[addr_tmp], gp[addr_tmp], Beta_acq,map_type);
                                    }

                               }
                               //if(llr_calc_counter==0&&)
               //sem_getvalue(&(*sem3_p),&index1);
               //sem_getvalue(&(*sem4_p),&index2);
               if(llr_calc_counter < Len +4*window_size - gate_counter - 1 || n_iter<itermax - 1)
               {
                //printf("wwwwww\n");
                sem_post(&(*sem2_p));
                //sem_wait(&(*sem2_p));
               }


                        }


                }


	    Len=Len-3-zero_padding_number;



		free(Alpha_tmp);
		free(gs);
		free(gp);
		free(Alpha);
		free(Beta);
		free(Beta_buffer);
		free(Beta_buffer_tmp);
		free(Beta_acq);
		//fclose(fd);

		return 0;



}
void turbo_decode_rm(	short* dec,
						double* llr_out,
						double* llr_in,
						double* store_llr,
						int Len,
						int E,
						int iterCNum,
						int g0,
						int g1,
						int Mem,
						int* interleave_table,
						int* ratematch_table)
{
	double		*llr_in_tmp, *llr_out_tmp;
	double		*llr_s1, *llr_s2, *llr_p1, *llr_p2, *llr_es1, *llr_es2,*llr_ep1, *llr_ep2, *llr_s_tmp, *llr_p1_tmp, *llr_p2_tmp;
	double	    *gs1, *gp1, *gs2, *gp2;
	int     *deinterleave_table;
	double     *store_llr1, *store_llr2;


	int			i = 0;
	int         itermax = 0;
	itermax=iterCNum;

	pthread_t   thread1,thread2;
	sem_t sem1, sem2, sem3, sem4;


	//FILE        *fd;

	llr_in_tmp = (double *) malloc(3*(Len+4)*sizeof(double));
	llr_out_tmp = (double*) malloc(3*(Len+4)*sizeof(double));
	llr_s1 = (double*) malloc((Len+4)*sizeof(double));
	llr_s2 = (double*) malloc((Len+4)*sizeof(double));
	llr_p1 = (double*) malloc((Len+4)*sizeof(double));
	llr_p2 = (double*) malloc((Len+4)*sizeof(double));
	llr_es1 = (double*) malloc((Len+Mem)*sizeof(double));
    llr_es2 = (double*) malloc((Len+Mem)*sizeof(double));
    llr_ep1 = (double*) malloc((Len+Mem)*sizeof(double));
	llr_ep2 = (double*) malloc((Len+Mem)*sizeof(double));
	deinterleave_table = (int*) malloc((Len)*sizeof(int));

		//store tailbit
	llr_s_tmp = (double*) malloc(4*sizeof(double));
	llr_p1_tmp = (double*) malloc(4*sizeof(double));
	llr_p2_tmp = (double*) malloc(4*sizeof(double));
	store_llr1 = (double*) malloc((Len+Mem)*sizeof(double));
	store_llr2 = (double*) malloc((Len+Mem)*sizeof(double));


	gs1 = (double*) malloc((Len+Mem)*sizeof(double));
	gp1 = (double*) malloc((Len+Mem)*sizeof(double));
	gs2 = (double*) malloc((Len+Mem)*sizeof(double));
	gp2 = (double*) malloc((Len+Mem)*sizeof(double));


    sem_init(&sem1, 0, 0);
    sem_init(&sem2, 0, 0);
    sem_init(&sem3, 0, 0);
    sem_init(&sem4, 0, 0);

    for(i=0;i<Len+4;i++)
    {
    llr_s1[i] = 0;
	llr_s2[i] = 0;
	llr_p1[i] = 0;
	llr_p2[i] = 0;
    }
    for(i=0;i<3*(Len+4);i++)
    {
        llr_in_tmp[i] = 0;
        llr_out_tmp[i]= 0;
    }
    for(i=0;i<Len+Mem;i++)
    {
    llr_es1[i]= 0;
    llr_es2[i]= 0;
    llr_ep1[i]= 0;
	llr_ep2[i]= 0;
	store_llr1[i]= 0;
	store_llr2[i]= 0;
	gs1[i]= 0;
	gp1[i]= 0;
	gs2[i]= 0;
	gp2[i]= 0;
    }
    for(i=0;i<Len;i++)
    {
        deinterleave_table[i] = 0;
    }
    for(i=0;i<4;i++)
    {
    llr_s_tmp[i] = 0;
	llr_p1_tmp[i] = 0;
	llr_p2_tmp[i] = 0;
    }
    void*   arg[19]={&Len, &Mem, llr_es1, llr_es2, interleave_table, deinterleave_table, llr_s1, llr_s2, llr_p1, llr_p2, llr_ep1, llr_ep2, store_llr1, store_llr2, &sem1, &sem2,  &itermax, &sem3, &sem4};


    get_deinterleave_table( deinterleave_table, Len,  interleave_table);


	//rate match....
	rate_dematching(Len+4, E, llr_in, llr_in_tmp, ratematch_table);

	//printf("rate match");

	//*********************************input data**************************************//
	for(i=0 ; i<Len+Mem; i++)
	{
	    llr_es1[i] = 0;
	    llr_es2[i] = 0;
	    llr_ep1[i] = 0;
	    llr_ep2[i] = 0;
	}



	for(i=0; i<Len+4; i++)
	{
		llr_s1[i] = llr_in_tmp[3*i];
		llr_s2[i] = llr_in_tmp[3*i];
		llr_p1[i] = llr_in_tmp[3*i+1];
		llr_p2[i] = llr_in_tmp[3*i+2];


		//check input : |input| > 127 not valid
	}


	//process tail bit
	for(i=0; i<4; i++)
	{
		llr_s_tmp[i] = llr_s1[Len+i];
		llr_p1_tmp[i] = llr_p1[Len+i];
		llr_p2_tmp[i] = llr_p2[Len+i];
	}
	llr_s1[Len]		= llr_s_tmp[0];
	llr_s1[Len+1]	= llr_p2_tmp[0];
	llr_s1[Len+2]	= llr_p1_tmp[1];

	llr_p1[Len]		= llr_p1_tmp[0];
	llr_p1[Len+1]	= llr_s_tmp[1];
	llr_p1[Len+2]	= llr_p2_tmp[1];

	llr_s2[Len]		= llr_s_tmp[2];
	llr_s2[Len+1]	= llr_p2_tmp[2];
	llr_s2[Len+2]	= llr_p1_tmp[3];

	llr_p2[Len]		= llr_p1_tmp[2];
	llr_p2[Len+1]	= llr_s_tmp[3];
	llr_p2[Len+2]	= llr_p2_tmp[3];

	inner_interleave(llr_s2, Len, interleave_table);

		for(i=0; i<Len+Mem; i++)
	{
	    if(store_llr[i]<-127/4)
	    {
	        store_llr[i]=-127/4;
	    }
	    else
	    {
	        if(store_llr[i]>127/4)
	        {
	            store_llr[i]=127/4;
	        }
	    }

	}

	for(i=0; i<Len+Mem; i++)
	{
		store_llr1[i] = store_llr[i];
	}

	inner_interleave(store_llr, Len, interleave_table);
    for(i=0; i<Len; i++)
	{
	    //store_llr2[i] = 0;
	    store_llr2[i] = store_llr[i];
	}
    for(i=Len; i<Len+Mem; i++)
    {
        store_llr2[i] = 0;
    }

	for(i=0; i<Len+Mem; i++)
		{
            if (llr_s1[i] > 127/4)
            {
                llr_s1[i] = 127/4;
            }
            else if (llr_s1[i] < -128/4)
            {
                llr_s1[i] = -128/4;
            }
        }

    for(i=0; i<Len+Mem; i++)
		{
            if (llr_s2[i] > 127/4)
            {
                llr_s2[i] = 127/4;
            }
            else if (llr_s2[i] < -127/4)
            {
                llr_s2[i] = -127/4;
            }
        }
        //printf("MAIN  llr_es2[100] = %d\n",llr_es2[100]);
        //printf("MAIN  llr_es1[100] = %d\n",llr_es1[428]);
        //printf("TURBO_RSC!!!\n");

    pthread_create(&thread1,   NULL,   turbo_rsc_decoder1,   arg);
    pthread_create(&thread2,   NULL,   turbo_rsc_decoder2,   arg);
    //printf("Creat OK!!\n");
	//iterCNum

	//calculating..........

	pthread_join(thread1, NULL);
	pthread_join(thread2, NULL);

	//printf("deinterleave[100] = %d\n",deinterleave_table[100]);
	//printf("MAIN_LATER llr_es1[428] = %d\n",llr_es1[428]);
	//printf("MAIN_LATER llr_es2[100] = %d\n",llr_es2[100]);



	inner_deinterleave(llr_es2, Len, interleave_table);


	for(i=0; i<Len; i++)
	{

		llr_s1[i] = -llr_s1[i] + llr_es1[i] + llr_es2[i] + store_llr1[i];
		llr_p1[i] = -llr_p1[i] + llr_ep1[i];
		llr_p2[i] = -llr_p2[i] + llr_ep2[i];
		store_llr[i] = (store_llr1[i]+llr_es1[i]+llr_es2[i]);
	}

	for(i=Len; i<Len+Mem; i++)
	{
		llr_s1[i] = -llr_s1[i] + llr_es1[i] + store_llr1[i];
        llr_s2[i] = -llr_s2[i] + llr_es2[i];
		llr_p1[i] = -llr_p1[i] + llr_ep1[i];
		llr_p2[i] = -llr_p2[i] + llr_ep2[i];
        store_llr[i] = (store_llr1[i]+llr_es1[i]);
	}

	llr_s_tmp[0]		= llr_s1[Len];
	llr_p1_tmp[0]		= llr_p1[Len];
	llr_p2_tmp[0]		= llr_s1[Len+1];

	llr_s_tmp[1]	= llr_p1[Len+1];
	llr_p1_tmp[1]	= llr_s1[Len+2];
	llr_p2_tmp[1]	= llr_p1[Len+2];

	llr_s_tmp[2]		= llr_s2[Len];
	llr_p1_tmp[2]		= llr_p2[Len];
	llr_p2_tmp[2]		= llr_s2[Len+1];

	llr_s_tmp[3]	= llr_p2[Len+1];
	llr_p1_tmp[3]	= llr_s2[Len+2];
	llr_p2_tmp[3]	= llr_p2[Len+2];

	for(i=0; i<4; i++)
	{
		llr_s1[Len+i] = llr_s_tmp[i];
		llr_p1[Len+i] = llr_p1_tmp[i];
		llr_p2[Len+i] = llr_p2_tmp[i];
	}

	/* decision */
	for(i=0; i<Len; i++)
	{
		dec[i] = (llr_s1[i] < 0)? 1:0;
	}


	for(i=0; i<Len+4; i++)
	{
		llr_out_tmp[3*i] = -llr_s1[i];
		llr_out_tmp[3*i+1] = -llr_p1[i];
		llr_out_tmp[3*i+2] = -llr_p2[i];

	}

    for(i=0; i<3*(Len+4); i++)
	{
		llr_out_tmp[i] = (llr_out_tmp[i]>127/4)? 127/4:llr_out_tmp[i];
		llr_out_tmp[i] = (llr_out_tmp[i]<-128/4)? -128/4:llr_out_tmp[i];
	}

	rate_matching(Len+4, E, llr_out_tmp, llr_out, ratematch_table);

	sem_destroy(&sem1);
    sem_destroy(&sem2);
    sem_destroy(&sem3);
    sem_destroy(&sem4);



	free(gs1);
	free(gp1);
	free(gs2);
	free(gp2);
	free(llr_s1);
	free(llr_s2);
	free(llr_p1);
	free(llr_p2);
	free(llr_es1);
	free(llr_es2);
	free(llr_ep1);
	free(llr_ep2);
	free(store_llr1);
	free(store_llr2);
	free(llr_s_tmp);
	free(llr_p1_tmp);
	free(llr_p2_tmp);
	free(llr_in_tmp);
	free(llr_out_tmp);
	free(deinterleave_table);



}

int main()
{
	int TTINum;
	int TTIloop,rm_loop,block_loop;
	int block_length;
	int rm_length;
	double LLRD[18444];
	int store_llr[18444];
	int QppIntlTable[6144];
	int RmIntlTable[18444];
	short Msg[6144];

	double llr_out[18444];
	short dec[6144];

	double LLRD_f[18444];
	double store_llr_f[18444];

	int err_num;
	int code_num;
	double ber;
	int i;


	FILE        *fd_TTINum;
	FILE        *fd_LLRD;
	FILE        *fd_store_llr;
	FILE        *fd_QppIntlTable;
	FILE        *fd_RmIntlTable;
	FILE        *fd_block_length;
	FILE        *fd_rm_length;
	FILE        *fd_Msg;
	FILE        *fd_result;


	//open test source file
	fd_result = fopen("result.txt","w");


	for(i=iteriter;i<(iteriter+1);i++)
	{
	    printf("\nITERnum = %d\n",i);
	    //open test source file
    fd_TTINum = fopen("../c_test_source/TTINum.txt","r");
	fd_QppIntlTable = fopen("../c_test_source/QppIntlTable.txt","r");
	fd_block_length = fopen("../c_test_source/block_length.txt","r");
	fd_rm_length = fopen("../c_test_source/rm_length.txt","r");
	fd_RmIntlTable = fopen("../c_test_source/RmIntlTable.txt","r");
	fd_LLRD = fopen("../c_test_source/LLRD.txt","r");
	fd_store_llr = fopen("../c_test_source/store_llr.txt","r");
	fd_Msg = fopen("../c_test_source/Msg.txt","r");

    fscanf(fd_TTINum,"%x",&TTINum);
	printf("Test TTINum: %d\n",TTINum);
	//fprintf(fd_result,"Test TTINum: %d\n",TTINum);

	//initial error number and ber
	err_num=0;
	code_num=0;
	ber=0;

	//main loop
	for(TTIloop=0; TTIloop<TTINum; TTIloop++)
	{
		//read block length and rate matching length
		fscanf(fd_block_length,"%x",&block_length);
		fscanf(fd_rm_length,"%x",&rm_length);
		code_num=code_num+block_length;

		printf("     TTINum : %d  \n         <-- block_length : %d -- rm_length:  %d -->\n",TTIloop,block_length,rm_length);
		//fprintf(fd_result,"     TTINum : %d  \n         <-- block_length : %d -- rm_length:  %d -->\n",TTIloop,block_length,rm_length);

		//read Qpp interleave Table
		for (block_loop=0; block_loop<block_length; block_loop++)
		{
			fscanf(fd_QppIntlTable,"%x",&QppIntlTable[block_loop]);
			//printf("     	QppIntlTable input : %d -- location %d\n",QppIntlTable[block_loop],block_loop);
		}


		//read rate matching Table and decoder input
		for (rm_loop=0; rm_loop<rm_length; rm_loop++)
		{
			fscanf(fd_RmIntlTable,"%x",&RmIntlTable[rm_loop]);
			fscanf(fd_LLRD,"%lf",&LLRD[rm_loop]);
			fscanf(fd_store_llr,"%x",&store_llr[rm_loop]);
			LLRD_f[rm_loop] = LLRD[rm_loop];
			store_llr_f[rm_loop] = store_llr[rm_loop];
                }


		//turbo decoder
		turbo_decode_rm(dec, llr_out, LLRD_f, store_llr_f, block_length, rm_length, i, 11, 13, 3, QppIntlTable, RmIntlTable);

		//read msg to count number of error
		for (block_loop=0; block_loop<block_length; block_loop++)
		{
			fscanf(fd_Msg,"%x",&Msg[block_loop]);
			if (dec[block_loop]!=Msg[block_loop])
			{
				err_num = err_num+1;
			}
		}

		//show result
		ber = (err_num*1.0)/code_num;
		printf("	    BER %f   ; error number : %d\n", ber, err_num);

	}
        //fprintf(fd_result,"code_num = %d, errornumber= %d\n",code_num, err_num);
        fprintf(fd_result,"ITERnum = %d  BER %f \n", i,ber);
	}


	//read TTI

	//printf("            finish!!!!!!!!!!!!!!!!");

	fclose(fd_TTINum);
	fclose(fd_block_length);
	fclose(fd_rm_length);
	fclose(fd_QppIntlTable);
	fclose(fd_RmIntlTable);
	fclose(fd_store_llr);
	fclose(fd_LLRD);
	fclose(fd_result);


}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值