////////////////////////////////////////////////////////////////////////////////////////// // // // FILE: wimaxTxControl_imp.c // // // // FUNCTION: Tx and Rx chain control // // // // Description: Control mode for Downlink WiMAX IEEE802.16e rel 2005 // // // // // // // // Input: // // // // Output: control_datasource_flow_out // // control_datasink_flow_out // // control_rando_flow_out // // control_derando_flow_out // // control_rsolomon_flow_out // // control_dersolomon_flow_out // // control_puncturing_flow_out // // control_depuncturing_flow_out // // control_interleaver_flow_out // // control_deinterleaver_flow_out // // control_symbolmap_flow_out // // control_symboldemap_flow_out // // // // // // // // // // // //June 2009 // ////////////////////////////////////////////////////////////////////////////////////////// #include /** ALOE headers*/ #include #include #include #include "inputs.h" #include "outputs.h" #include "stats.h" #include "wimaxTxControl.h" //Defines all the WIMAX control parameters #define BITSPERCHAR 8 /*GLOBAL VARIABLES*/ CWimax WIMAXcontrol; int Tslot=0; float EbNo=0.0; /*PREDEFINED FUNCTIONS*/ void generate_control_word(int len); void run_BPSK(); void run_QPSK_1R2(); void run_QPSK_3R4(); void run_16QAM_1R2(); void run_16QAM_3R4(); void run_64QAM_2R3(); void run_64QAM_3R4(); ////////////////////////////////////////////////////////////////////////////////////////// //SQUELETON CALLED FUNCTIONS////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// //CONTROL ////////////////////////////////////////////////////////////////////////CONTROL/ ////////////////////////////////////////////////////////////////////////////////////////// //INPUT/////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// /*Returns the length(in control in type words) of the expected control flow at each time-slot*/ //Funtion activated if control flow has been received*/ /*Check INPUT_MAX_CONTROL*/ int get_controlin_length() { int length=1; length=control_length(); return(length); } /*Process the received control flow according to the length returned by get_controlin_length()*/ /*"len" indicates the number of control words to be processed*/ int process_inputcontrol(int len) { return(1); /*return 1 if OK; return 0 if error*/ } ////////////////////////////////////////////////////////////////////////////////////////// //OUTPUT////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// /*Returns the length (in control out type words) of the generated control flow at each time-slot*/ /*Check OUTPUT_MAX_CONTROL*/ int get_controlout_length_datasource(){ if(Tslot==1)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_rando(){ if(Tslot==2)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_rsolomon(){ if(Tslot==3)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_cconv(){ if(Tslot==4)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_puncturing(){ if(Tslot==5)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_interleaver(){ if(Tslot==6)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_symbolmap(){ if(Tslot==7)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_channel(){ if(Tslot==8)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_symboldemap(){ if(Tslot==9)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_deinterleaver(){ if(Tslot==10)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_depuncturing(){ if(Tslot==11)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_viterbi(){ if(Tslot==12)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_dersolomon(){ if(Tslot==13)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_derando(){ if(Tslot==14)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } int get_controlout_length_datasink(){ if(Tslot==15)return(1); //Return control length: Only sent control word at Tslot 1 else return(0); } /*Generate the control word to be send according the length provided by get_controlout_length()*/ /*"len" indicates the number of control words to be generated*/ int generate_outputcontrol(int len) { generate_control_word(len); /*return 1 if OK; return 0 if error*/ return(1); } ////////////////////////////////////////////////////////////////////////////////////////// //DATA/////////////////////////////////////////////////////////////////////////////DATA/// ////////////////////////////////////////////////////////////////////////////////////////// //INPUT/////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// /*Returns the length(in data in type words) of the expected data flow at each time-slot*/ //Funtion activated only if data flow has been received*/ /*Check INPUT_MAX_DATA*/ int get_datain_length() { int length=1; length=datain_length(); return(length); } /*Process the received data flow according to the length returned by get_datain_length()*/ /** Run function. return 1 if ok, 0 if error*/ /*"len" indicates the number of data words to be processed*/ int process_inputdata(int len) { process_datainflow(len); return 1; } ////////////////////////////////////////////////////////////////////////////////////////// //OUTPUT////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// /*Returns the length (in data out type words) of the generated data flow at each time-slot*/ int get_dataout_length() { int length=1; length=dataout_length(); return(length); } /*Generate the control word to be send according the length provided by get_controlout_length()*/ /** Run function. return 1 if ok, 0 if error*/ /*"len" indicates the number of data words to be generated*/ int generate_outputdata(int len) { return 1; } int InitCustom() { /*DataSource*/ C_datasource[0].CExec.status=NONACTIVE; C_datasource[0].CExec.timeslot=0; /*DataSink*/ C_datasink[0].CExec.status=NONACTIVE; C_datasink[0].CExec.timeslot=0; /*rando*/ control_rando[0].CExec.status=NONACTIVE; control_rando[0].CExec.timeslot=0; /*derando*/ control_derando[0].CExec.status=NONACTIVE; control_derando[0].CExec.timeslot=0; /*rsolomon*/ control_rsolomon[0].CExec.status=NONACTIVE; control_rsolomon[0].CExec.timeslot=0; /*dersolomon*/ control_dersolomon[0].CExec.status=NONACTIVE; control_dersolomon[0].CExec.timeslot=0; /*cconv*/ control_cconv[0].CExec.status=NONACTIVE; control_cconv[0].CExec.timeslot=0; /*viterbi*/ control_viterbi[0].CExec.status=NONACTIVE; control_viterbi[0].CExec.timeslot=0; /*channel*/ control_channel.CExec.status=NONACTIVE; control_channel.CExec.timeslot=0; /*puncturing*/ control_puncturing[0].CExec.status=NONACTIVE; control_puncturing[0].CExec.timeslot=0; /*depuncturing*/ control_depuncturing[0].CExec.status=NONACTIVE; control_depuncturing[0].CExec.timeslot=0; /*interleaver*/ control_inter.CExec.status=NONACTIVE; control_inter.CExec.timeslot=0; /*deinterleaver*/ control_deinter.CExec.status=NONACTIVE; control_deinter.CExec.timeslot=0; /*symbolmap*/ control_symbolmap.CExec.status=NONACTIVE; control_symbolmap.CExec.timeslot=0; /*symboldemap*/ control_symboldemap.CExec.status=NONACTIVE; control_symboldemap.CExec.timeslot=0; return 1; } int RunCustom() { //printf("CONTROL:Tslot=%d status=%d\n", Tslot, output_control[0].CEx.status); Tslot++; return 1; } ////////////////////////////////////////////////////////////////////////////////////////// //END SQUELETON CALLED FUNCTIONS////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// //######################################################################################// ////////////////////////////////////////////////////////////////////////////////////////// //ESPECIFIC MODULE FUNCTIONS////////////////////////////////////////////////////////////// //CONTROL////////////////////////////////////////////////////////////////////////CONTROL// ////////////////////////////////////////////////////////////////////////////////////////// int control_length() { return(INPUT_MAX_CONTROL); } //GENERATE CONTROL WORD()///////////////////////////////////////////////////////////////// //MODULATION PARAMETERS INFO////////////////////////////////////////////////////////////// //MODULATION RS_CODE CC_CODE OVERALL_CODING UncodedBlocks(B) Coded Blocks(B)// //BPSK [12,12,0] 1/2 1/2 12 24 // //QPSK [32,24,4] 2/3 1/2 24 48 // //QPSK [40,36,2] 5/6 3/4 36 48 // //16QAM [64,48,8] 2/3 1/2 48 96 // //16QAM [80,72,4] 5/6 3/4 72 96 // //64QAM [108,96,6] 3/4 2/3 96 144 // //64QAM [120,108,6] 5/6 3/4 108 144 // ////////////////////////////////////////////////////////////////////////////////////////// //CONVOLUTIONAL ENCODER RATE ALWAYS 1/2 // //DIFFERENT CODING RATE ACHIEVED BY PUNCTURING // ////////////////////////////////////////////////////////////////////////////////////////// //INTERLEAVING MODES WIMAX ////////////////////////////////////////////////////////////////////////////////// // subchannels 16 8 4 2 1 // // Ncbps (BPSK: Ncpc=1) 192 96 48 12 12 // // Ncbps (QPSK: Ncpc=2) 384 192 96 24 24 // // Ncbps (16QAM: Ncpc=4) 768 384 192 48 48 // // Ncbps (64QAM: Ncpc=6) 1152 576 288 72 72 // ////////////////////////////////////////////////////////////////////////////////// void generate_control_word(int len) { static int onetime=0; //Control that each branch be executed only one time// int i; if(onetime>50)return; if(onetime==Tslot)return; onetime=Tslot; //CONVOLUTIONAL ENCODER DECODER: Polinomial definition //WIMAX 802.16e int g[2][KMAX] = {{1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, /* 171 */ {1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0}}; /* 133 */ //run_BPSK(); //OK run_QPSK_1R2(); //OK //run_QPSK_3R4(); //OK //run_16QAM_1R2(); //OK //run_16QAM_3R4(); //OK //run_64QAM_2R3(); //OK //run_64QAM_3R4(); //OK //printf("CONTROL: generate_control_word\n"); //printf("CONTROL:Tslot=%d status=%d\n", Tslot, output_control[0].CEx.status); /*DataSource*/ if(Tslot==1){ C_datasource[0].CExec.status=ACTIVE; C_datasource[0].CExec.timeslot=Tslot; C_datasource[0].CData.numdatabytes=WIMAXcontrol.uncodedbytes; /*printf("WIMAX_TXC: DATASOURCE: TSLOT%d, STATUS=%d\n",\ C_datasource[0].CExec.timeslot,\ C_datasource[0].CExec.status); */ } /*rando*/ if(Tslot==2){ control_rando[0].CExec.status=ACTIVE; control_rando[0].CExec.timeslot=Tslot; control_rando[0].CData.ninputbytes=WIMAXcontrol.uncodedbytes; control_rando[0].CData.noutputbytes=WIMAXcontrol.uncodedbytes; /*printf("WIMAX_TXC: RANDO: TSLOT%d, STATUS=%d\n",\ control_rando[0].CExec.timeslot,\ control_rando[0].CExec.status); printf(" NumInputbytes=%d, NumOutputbytes=%d\n",\ control_rando[0].CData.ninputbytes,\ control_rando[0].CData.noutputbytes); */ } /*rsolomon*/ if(Tslot==3){ //control_rsolomon[0].CExec.status=TEST_FLOW; control_rsolomon[0].CExec.status=ACTIVE; control_rsolomon[0].CExec.timeslot=Tslot; control_rsolomon[0].CData.ninputbytes=WIMAXcontrol.uncodedbytes; control_rsolomon[0].CData.noutputbytes=WIMAXcontrol.uncodedbytes\ +WIMAXcontrol.rsolomon; control_rsolomon[0].CData.modulation=WIMAXcontrol.modulation; control_rsolomon[0].CData.rsolomon_Pbytes=WIMAXcontrol.rsolomon; /*printf("WIMAX_TXC: RSOLOMON: TSLOT%d, STATUS=%d\n",\ control_rsolomon[0].CExec.timeslot,\ control_rsolomon[0].CExec.status); printf(" NumInputbytes=%d, NumOutputbytes=%d\n",\ control_rsolomon[0].CData.ninputbytes,\ control_rsolomon[0].CData.noutputbytes); */ } /*cconv*/ if(Tslot==4){ //control_cconv[0].CExec.status=TEST_FLOW; control_cconv[0].CExec.status=ACTIVE; control_cconv[0].CExec.timeslot=Tslot; control_cconv[0].CData.channelcoding=WIMAXcontrol.channelcoding; control_cconv[0].CData.ninputbytes=control_rsolomon[0].CData.noutputbytes; control_cconv[0].CData.CCcoderate=WIMAXcontrol.CCcoderate; control_cconv[0].CData.tail=WIMAXcontrol.tail; if(control_cconv[0].CExec.status==ACTIVE){ control_cconv[0].CData.noutputbytes=\ (int)((float)(control_cconv[0].CData.ninputbytes\ +WIMAXcontrol.tail)\ *(1.0)/WIMAXcontrol.CCcoderate); } if(control_cconv[0].CExec.status==TEST_FLOW){ control_cconv[0].CData.noutputbytes=\ control_cconv[0].CData.ninputbytes; } if(control_cconv[0].CExec.status==TEST_PROCESS){ control_cconv[0].CData.noutputbytes=0; } /*printf("WIMAX_TXC: CCONV: TSLOT%d, STATUS=%d\n",\ control_cconv[0].CExec.timeslot,\ control_cconv[0].CExec.status); printf(" NumInputbytes=%d, NumOutputbytes=%d\n",\ control_cconv[0].CData.ninputbytes,\ control_cconv[0].CData.noutputbytes); */ } /*puncturing*/ if(Tslot==5){ //control_puncturing[0].CExec.status=TEST_FLOW; //control_puncturing[0].CExec.status=TEST_PROCESS; control_puncturing[0].CExec.status=ACTIVE; control_puncturing[0].CExec.timeslot=Tslot; control_puncturing[0].CData.ninputdata=\ control_cconv[0].CData.noutputbytes; control_puncturing[0].CData.punct_rate=WIMAXcontrol.punct_rate; control_puncturing[0].CData.pseqlength=WIMAXcontrol.pseqlength; for(i=0; i