/******************************************************************************* 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 . 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 *******************************************************************************/ /* file: lte_rate_matching.c purpose: Procedures for rate matching/interleaving for LTE (turbo-coded transport channels) (TX/RX) author: raymond.knopp@eurecom.fr date: 21.10.2009 */ #ifdef MAIN #include #include #endif #include "PHY/defs.h" //#define cmin(a,b) ((a)<(b) ? (a) : (b)) static uint32_t bitrev[32] = {0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31}; static uint32_t bitrev_x3[32] = {0,48,24,72,12,60,36,84,6,54,30,78,18,66,42,90,3,51,27,75,15,63,39,87,9,57,33,81,21,69,45,93}; static uint32_t bitrev_cc[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30}; //#define RM_DEBUG_TX 1 //#define RM_DEBUG 1 //#define RM_DEBUG2 1 //#define RM_DEBUG_CC 1 uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w) { uint32_t RTC = (D>>5), ND, ND3; uint32_t row,col,Kpi,index; uint32_t index3,k,k2; #ifdef RM_DEBUG uint32_t nulled=0; #endif uint8_t *d1,*d2,*d3; if ((D&0x1f) > 0) RTC++; Kpi = (RTC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG printf("sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3); printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND); #endif ND3 = ND*3; // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212 d[(3*D)+2] = d[2]; k=0;k2=0; d1 = d-ND3; d2 = d1+1; d3 = d1+5; for (col=0;col<32;col++) { #ifdef RM_DEBUG printf("Col %d\n",col); #endif index = bitrev[col]; index3 = bitrev_x3[col];//3*index; for (row=0;row0) w[(3*Kpi) - 1] = LTE_NULL; #ifdef RM_DEBUG if (ND>0) { printf("RM_TX: Nulled last component in pos %d\n",Kpi-1+k2); nulled++; } printf("RM_TX: Nulled %d\n",nulled); #endif return(RTC); } uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w) { uint32_t RCC = (D>>5), ND, ND3; uint32_t row,col,Kpi,index; uint32_t index3,k; #ifdef RM_DEBUG_CC uint32_t nulled=0; #endif if ((D&0x1f) > 0) RCC++; Kpi = (RCC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG_CC printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w); printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND); #endif ND3 = ND*3; k=0; for (col=0;col<32;col++) { #ifdef RM_DEBUG_CC printf("Col %d\n",col); #endif index = bitrev_cc[col]; index3 = 3*index; for (row=0;row>5), ND, ND3; uint32_t row,col,Kpi,index; uint32_t index3,k,k2; int16_t *d1,*d2,*d3; if ((D&0x1f) > 0) RTC++; Kpi = (RTC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG2 printf("sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3); printf("RTC = %d, Kpi=%d, ND=%d\n",RTC,Kpi,ND); #endif ND3 = ND*3; // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212 k=0;k2=0; d1 = d-ND3; d2 = d1+1; d3 = d1+5; for (col=0;col<32;col++) { #ifdef RM_DEBUG2 printf("Col %d\n",col); #endif index = bitrev[col]; index3 = bitrev_x3[col];//3*index; for (row=0;row0) // d[2] = LTE_NULL;//d[(3*D)+2]; } void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w) { //WANG_Hao uint32_t RCC = (D>>5), ND, ND3; uint32_t RCC = (D>>5); ptrdiff_t ND, ND3; uint32_t row,col,Kpi,index; //WANG_Hao uint32_t index3,k; ptrdiff_t index3; uint32_t k; if ((D&0x1f) > 0) RCC++; Kpi = (RCC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG2 printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w); printf("RCC = %d, Kpi=%d, ND=%d\n",RCC,Kpi,ND); #endif ND3 = ND*3; k=0; for (col=0;col<32;col++) { #ifdef RM_DEBUG2 printf("Col %d\n",col); #endif index = bitrev_cc[col]; index3 = 3*index; for (row=0;row>5), ND; uint32_t col,Kpi,index; int32_t k,k2; #ifdef RM_DEBUG uint32_t nulled=0; #endif uint8_t *wKpi,*wKpi1,*wKpi2,*wKpi4; if ((D&0x1f) > 0) RTC++; Kpi = (RTC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG printf("dummy sub_block_interleaving_turbo : D = %d (%d)\n",D,D*3); printf("RTC = %d, Kpi=%d, ND=%d, F=%d (Nulled %d)\n",RTC,Kpi,ND,F,(2*F + 3*ND)); #endif k=0; k2=0; wKpi = &w[Kpi]; wKpi1 = &w[Kpi+1]; wKpi2 = &w[Kpi+2]; wKpi4 = &w[Kpi+4]; for (col=0;col<32;col++) { #ifdef RM_DEBUG printf("Col %d\n",col); #endif index = bitrev[col]; if (index<(ND+F)) { w[k] = LTE_NULL; wKpi[k2] = LTE_NULL; #ifdef RM_DEBUG nulled+=2; #endif } //bits beyond 32 due to "filler" bits if ((index+32)<(ND+F)) { w[k+1] = LTE_NULL; wKpi2[k2] = LTE_NULL; #ifdef RM_DEBUG nulled+=2; #endif } if ((index+64)<(ND+F)) { w[k+2] = LTE_NULL; wKpi4[k2] = LTE_NULL; #ifdef RM_DEBUG nulled+=2; #endif } if ((index+1)0) w[(3*Kpi)-1] = LTE_NULL; #ifdef RM_DEBUG if (ND>0) { nulled++; printf("dummy_w: Nulled final position %d\n",(3*Kpi)-1); } printf("Nulled = %d\n",nulled); #endif return(RTC); } uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w){ uint32_t RCC = (D>>5), ND; uint32_t col,Kpi,index; int32_t k; #ifdef RM_DEBUG_CC uint32_t nulled=0; #endif if ((D&0x1f) > 0) RCC++; Kpi = (RCC<<5); // Kpi3 = Kpi*3; ND = Kpi - D; #ifdef RM_DEBUG_CC printf("dummy sub_block_interleaving_cc : D = %d (%d)\n",D,D*3); printf("RCC = %d, Kpi=%d, ND=%d, (Nulled %d)\n",RCC,Kpi,ND,3*ND); #endif // ND3 = ND*3; // copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212 k=0; for (col=0;col<32;col++) { #ifdef RM_DEBUG_CC printf("Col %d\n",col); #endif index = bitrev_cc[col]; if (index 32767) { //#ifdef DEBUG_RM printf("OVERFLOW!!!!!, w_tmp = %d\n",w_tmp); //#endif w[ind] = 32767; } else if (w_tmp < -32768) { //#ifdef DEBUG_RM printf("UNDERFLOW!!!!!, w_tmp = %d\n",w_tmp); //#endif w[ind] = -32768; } else */ /* w[ind] += soft_input2[k]; #ifdef RM_DEBUG printf("RM_RX k%d Ind: %d (%d)\n",k,ind,w[ind]); #endif ind++; if (ind==Ncb) ind=0; } */ *E_out = E; return(0); } void lte_rate_matching_cc_rx(uint32_t RCC, uint16_t E, int8_t *w, uint8_t *dummy_w, int8_t *soft_input) { uint32_t ind=0,k; uint16_t Kw = 3*(RCC<<5); uint32_t acc=1; int16_t w16[Kw]; #ifdef RM_DEBUG_CC uint32_t nulled=0; printf("lte_rate_matching_cc_rx: Kw %d, E %d, w %p, soft_input %p\n",3*(RCC<<5),E,w,soft_input); #endif memset(w,0,Kw); memset(w16,0,Kw*sizeof(int16_t)); for (k=0;k7) w[ind]=7; else if (w16[ind]<-8) w[ind]=-8; else w[ind]=(int8_t)w16[ind]; } #ifdef RM_DEBUG_CC printf("Nulled %d\n",nulled); #endif } #ifdef MAIN void main() { uint8_t d[96+3+(3*6144)]; uint8_t w[3*6144],e[12*6144]; uint32_t RTC,G,rvidx; uint32_t nb_rb=6; uint32_t mod_order = 4; uint32_t first_dlsch_symbol = 2; uint32_t i; G = ( nb_rb * (12 * mod_order) * (12-first_dlsch_symbol-3)) ;//( nb_rb * (12 * mod_order) * (14-first_dlsch_symbol-3)) : // initialize 96 first positions to "LTE_NULL" for (i=0;i<96;i++) d[i]=LTE_NULL; RTC = sub_block_interleaving_turbo(4+(192*8), &d[96], w); for (rvidx=0;rvidx<4;rvidx++) { lte_rate_matching_turbo(RTC, G, w, e, 1, //C 1827072, //Nsoft, 8, //Mdlharq, 1, //Kmimo, rvidx, //rvidx, mod_order, //Qm, 1, //Nl, 0 //r ); } } #endif