⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 build_midamble.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/*   This file contains the definitions for the midamble.    Alessandro Nordio 27/02/2001    History  :   Created  27/02/2001                01/03/01 The function Build_Mid_Table has been modified. 		         Now only 1 argument is passed.		02/10/24 The file finds its way in the modularised version		03/05/23 We still have to fix it for gcc-3.2*/#include "midamble.h"#include "debugging.h"#include "estimation.h"#define DBG_LVL 4midamble_t midamble_def[ NUM_MIDAMBLE_DEF ];mmx_t mapping_def[ 2 ][ 4 ];// Get ith bit in unsigned int array#define GET_ith_BIT(in,i) ((in[i >> 5] >> (i & 0x1F))&1)// Pre-Defined Midambles://   1 - 3GPP type 1 (192+64 = 256)#include "Gpp_Mid_Generators192.h"// include twiddles for a 768 points FFT (768=4*192) The format is specified// inside the included file#include "twiddle768.h"// include 1/FFT() of the 0-th midamble generator in mmx_t format// (see the included file for more informations)#include "Gpp_Mid_GeneratorF192.h"unsigned int Gpp_Mid_Table1[8*3];            // 8 = 256/32;   3 possible shiftsunsigned short Reverse_Buffer768[768];       // is a 768 elements FFT//   2 - User Def    (512+32 = 544)#include "User_Def_Mid_Generators512.h"// include twiddles for a 2048 points FFT (2048=4*512) The format is specified// inside the included file#include "twiddle2048.h"// include 1/FFT() of the 0-th midamble generator in mmx_t format// (see the included file for more informations)#include "User_Def_Mid_GeneratorF512.h"// 17 = ceil((512+32)/32); 16 possible shiftsunsigned int User_Def_Mid_Table512[17*16];// is a 512 elements FFTunsigned short Reverse_Buffer2048[2048];//   3 - Midamble defined in Chinese WCDMA 128+16 = 144// include midamble table#include "User_Def_Mid_Generators128.h"// include twiddles for a 512 points FFT (512=4*128) The format is specified// inside the included file#include "twiddle512.h"// include 1/FFT() of the 0-th midamble generator in mmx_t format// (see the included file for more informations)#include "User_Def_Mid_GeneratorF128.h"// 5 = ceil((128+16)/32); 16 possible shiftsunsigned int User_Def_Mid_Table128[5*16];// is a 512 elements FFTunsigned short Reverse_Buffer512[512];unsigned short reverse_bits ( unsigned index, unsigned NumBits ) {  unsigned i, rev;  for ( i=rev=0; i < NumBits; i++ ) {    rev = (rev << 1) | (index & 1);    index >>= 1;  }  return rev;}int build_midamble_table( midamble_t *m );/** * Prepares the defined midambles, filling each structure with the data. * To define a new midamble declare it as global variable in L1_extern.h and L1_vars.c * and add its definition inside this function. */void midamble_prepare(void) {  int i, j;  // counter  // mapping used for 3GPP midamble (when the first bit is real)  mapping_def[0][0].w[0] =   1;  mapping_def[0][0].w[1] =  0;  mapping_def[0][0].w[2] =   0;  mapping_def[0][0].w[3] =  1;  mapping_def[0][1].w[0] =  -1;  mapping_def[0][1].w[1] =  0;  mapping_def[0][1].w[2] =   0;  mapping_def[0][1].w[3] =  1;  mapping_def[0][2].w[0] =   1;  mapping_def[0][2].w[1] =  0;  mapping_def[0][2].w[2] =   0;  mapping_def[0][2].w[3] = -1;  mapping_def[0][3].w[0] =  -1;  mapping_def[0][3].w[1] =  0;  mapping_def[0][3].w[2] =   0;  mapping_def[0][3].w[3] = -1;  // mapping used for 3GPP midamble (when the first bit is imaginary)  mapping_def[1][0].w[0] =   0;  mapping_def[1][0].w[1] =  1;  mapping_def[1][0].w[2] =   1;  mapping_def[1][0].w[3] =  0;  mapping_def[1][1].w[0] =   0;  mapping_def[1][1].w[1] = -1;  mapping_def[1][1].w[2] =   1;  mapping_def[1][1].w[3] =  0;  mapping_def[1][2].w[0] =   0;  mapping_def[1][2].w[1] =  1;  mapping_def[1][2].w[2] =  -1;  mapping_def[1][2].w[3] =  0;  mapping_def[1][3].w[0] =   0;  mapping_def[1][3].w[1] = -1;  mapping_def[1][3].w[2] =  -1;  mapping_def[1][3].w[3] =  0;  // midamble_def[0] the type 0 midamble defined by 3GPP  midamble_def[0].length         = 512;  midamble_def[0].period         = 456;  midamble_def[0].shift          =  57;  midamble_def[0].max_channels   =   8;  // the 1824 elements FFT is not implemented yet  // midamble_def[1] the type 1 midamble defined by 3GPP  midamble_def[1].length         = 256;  midamble_def[1].period         = 192;  midamble_def[1].shift          =  64;  midamble_def[1].max_channels   =   3;  // 6 is given by 192/32 we pointh to the 0-th generator  // there are 128 generatores available  midamble_def[1].generator      = Gpp_Midamble_Generators1;  // points to the pre-defined midamble table  midamble_def[1].midamble_table = Gpp_Mid_Table1;  build_midamble_table(&midamble_def[1]);  // fill channel estimation fields  midamble_def[1].generatorF     = (mmx_t *)Gpp_Mid_GeneratorF192;  midamble_def[1].twiddleFFT     = (mmx_t *)twiddleFFT_768;  midamble_def[1].twiddleIFFT    = (mmx_t *)twiddleIFFT_768;  midamble_def[1].revbuf         = Reverse_Buffer768;  for( i=0; i<256; i++ ) {    j = reverse_bits( i, 8 );    midamble_def[1].revbuf[ 3*i ]   = j;    midamble_def[1].revbuf[ 3*i+1 ] = 256 + j;    midamble_def[1].revbuf[ 3*i+2 ] = 512 + j;  }  midamble_def[1].estimate_channel = channel_estimation_768;  // This is a user defined midamble  // period +extension = 544  midamble_def[2].length         = 512+32;  midamble_def[2].period         = 512;  midamble_def[2].shift          =  32;  midamble_def[2].max_channels   =  16;  midamble_def[2].generator      = User_Def_Midamble_Generators512;  // points to the pre-defined midamble table  midamble_def[2].midamble_table = User_Def_Mid_Table512;  build_midamble_table(&midamble_def[2]);  // fill channel estimation fields  midamble_def[2].generatorF     = (mmx_t *)User_Def_Mid_GeneratorF512;  midamble_def[2].twiddleFFT     = (mmx_t *)twiddleFFT_2048;  midamble_def[2].twiddleIFFT    = (mmx_t *)twiddleIFFT_2048;  midamble_def[2].revbuf         = Reverse_Buffer2048;  // compute the reverse buffer  for( i=0; i<2048; i++ ) {    // 11 = log2(2048)    midamble_def[2].revbuf[i] = reverse_bits( i, 11 );  }  midamble_def[2].estimate_channel = channel_estimation_2048;  // Midamble defined in Chinese WCDMA 128+16 = 144  // period + extension = 144  midamble_def[3].length         = 128+16;  midamble_def[3].period         = 128;  midamble_def[3].shift          =  16;  midamble_def[3].max_channels   =   8;  midamble_def[3].generator      = User_Def_Midamble_Generators128;  // points to the pre-defined midamble table  midamble_def[3].midamble_table = User_Def_Mid_Table128;  build_midamble_table(&midamble_def[3]);  // fill channel estimation fields  midamble_def[3].generatorF     = (mmx_t *)User_Def_Mid_GeneratorF128;  midamble_def[3].twiddleFFT     = (mmx_t *)twiddleFFT_512;  midamble_def[3].twiddleIFFT    = (mmx_t *)twiddleIFFT_512;  midamble_def[3].revbuf         = Reverse_Buffer512;  // compute the reverse buffer  for( i=0; i<512; i++ ) {    // 9 = log2(512)    midamble_def[3].revbuf[i] = reverse_bits(i,9);  }  midamble_def[3].estimate_channel = channel_estimation_512;}/* *  BuildMidTable is given an array "in" of int containing "insize" bits. *  It produces a matrix where is *  is the periodic extension of "in" to a size "outsize", *  starting at 0, with successive shifts "shift". *  The output bits are flipped according to TX_FLIPs[4] in order to get  * j^k modulation  */int build_midamble_table( midamble_t *m ) {  // defines flips for j^k modulation  // if shift is not an integer multiple of 4 then for  // each user we should user different flips !!!!  unsigned int tx_flips[4] = {0x66666666,0x33333333,0x99999999,0xCCCCCCCC};  // This is the flip used for a certain user midamble  unsigned int flip;  // Counts the sequences  unsigned int j;  // Counts the bits in the sequences  unsigned int k;  // Input bit index  unsigned int t;  unsigned int word;  // retrieve some parameters from m  unsigned int *in     = m->generator;  unsigned int *out    = m->midamble_table;  unsigned int insize  = m->period;  unsigned int shift   = m->shift;  unsigned int numseq  = m->max_channels;  unsigned int outsize = m->length;  for (j = 0; j < numseq; j++) {    // choose the FLIP pattern for this shift    flip = tx_flips[(j*shift) & 0x00000003];    // Reset word for each sequence    word = 0;    t = (short unsigned int) j * (short unsigned int) shift;    for ( k = 0; k < outsize; k++ ) {      // Start a new word every 32 bits      if ( ((k & 0x1F) == 0) && (k > 0) ) {        // Record word        *out++ = word ^ flip;        // Reset word        word = 0;      }      word |= GET_ith_BIT(in,t) << (k & 0x1F);      if (++t == insize)        t = 0;    }    // Record last word in sequence    *out++ = word ^ flip;  }  return(1);}/* *  This function writes the midamble of the FIRST user to  * the addess pointed by out. The output amplitude is 'amp' and the  * midamble index (row of the midamble table) is given by 'mid_index' * The midamble characteristics as the midamble table, the length and the  * mapping are contained in the structure pointed by mid. *  The output od the function is directly written in out[], without taking  * care of the existing values of 'out[]' * * @param mid midamble to build * @param out memory address of the output  * @param amp midamble amplitude * @param mid_index midamble index  * @return*/int midamble_write( int mid_type, SYMBOL_COMPLEX *out_mid, unsigned int amp,                    unsigned short mid_index ) {  short bit12;  int bits=0;  int bmask=3;  mmx_t midamp, *map, *out = (mmx_t*)out_mid;  unsigned int i, j;  unsigned int count;  midamble_t *mid = &midamble_def[ mid_type ];  // if the current shift is odd  if((mid_index*(mid->shift)) & 0x00000001) {    // then in the current midamble the first chip is real    map = mapping_def[0];    // Copy the midamble amplitude twice in an mmx variable.    midamp.d[0] = amp;    // midamp = [amp,0,0,amp] (Re and Im; Re first)    midamp.d[1] = amp<<16;  } else {    // Copy the midamble amplitude twice in an mmx variable.    midamp.d[0] = amp<<16;    // midamp = [0,amp,amp,0] (Im and Re; Im first)    midamp.d[1] = amp;    // else in the current midamble the first chip is imaginary    map = mapping_def[1];  }  // in mm3 there is [midamp,0,0,midamp]  movq_m2r(midamp,mm3);  // mid_index now is the index of the current midamble  // in the midamble table (in words)  mid_index = ((mid->length+31)>>5)*mid_index;  // counts the chips in the midamble  count=0;  // for all the words-1 in the current midamble  for (i=0; i<((mid->length)>>5); i++) {    // for each loop it writes 16 mmx_t = 32 cpx samples = 64 real samples    // Read in 32 new bits from the midamble table    bits = mid->midamble_table[mid_index+i];    for ( j=0; j<16; j++ ) {      // extract two chips      bit12 = bits & bmask;      bits = bits >> 2;      // put 64 bit map into register mm0      movq_m2r( map[ bit12 ], mm0 );      // multiply by mm3  (midamp)      pmullw_r2r( mm3, mm0 );      // put the result in out      movq_r2m( mm0, *out );      out++;    }    // adds 32 because we have read 32 chips    count+=32;  }  // if there is still a 32-bit word that contains midamble chips  if( count != mid->length ) {    // Read in the last 32bits from the midamble table    bits = mid->midamble_table[mid_index+(mid->length>>5)];    // for each chip in the last word    for (i=0; i<((mid->length-count)/2); i++) {      bit12 = bits & bmask;      bits = bits >> 2;      movq_m2r( map[bit12], mm0 );      pmullw_r2r( mm3, mm0 );      movq_r2m( mm0, out[i] );    }  }  emms();  return 0;}/** * This function is similar to Build_Midamble. * The only difference is that the output of the function  * DOES NOT REPLACE the existing data contained in 'out[]', instead  * it is summed up with. *  This function writes the midamble of the FIRST user to  * the addess pointed by out. The output amplitude is 'amp' and the  * midamble index (row of the midamble table) is given by 'mid_index' * The midamble characteristics as the midamble table, the length and the  * mapping are contained in the structure pointed by mid. *  The output od the function is directly written in out[], without taking  * care of the existing values of 'out[]' * * @param mid midamble to build * @param out memory address of the output  * @param amp midamble amplitude * @param mid_index midamble index  * @return */int midamble_add( int mid_type, SYMBOL_COMPLEX *out_mid,                  unsigned int amp, unsigned short mid_index ) {  register short bit12;  register int bits=0;  register int bmask=3;  mmx_t midamp, *map, *out = (mmx_t*)out_mid;  unsigned int i, j;  unsigned int count;  midamble_t *mid = &midamble_def[ mid_type ];  // if the current shift is odd  if((mid_index*(mid->shift)) & 0x00000001) {    // then in the current midamble the first chip is real    map = mapping_def[0];    // Copy the midamble amplitude twice in an mmx variable.    midamp.d[0] = amp;    // midamp = [amp,0,0,amp] (Re and Im; Re first)    midamp.d[1] = amp<<16;  } else {    // Copy the midamble amplitude twice in an mmx variable.    midamp.d[0] = amp<<16;    // midamp = [0,amp,amp,0] (Im and Re; Im first)    midamp.d[1] = amp;    // else in the current midamble the first chip is imaginary    map = mapping_def[1];  }  // in mm3 there is [midamp,0,0,midamp]  movq_m2r(midamp,mm3);  // mid_index now is the index of the current midamble  // in the midamble table (in words)  mid_index = ((mid->length+31)>>5)*mid_index;  // counts the chips in the midamble  count=0;  // for all the words-1 in the current midamble  for (i=0; i<((mid->length)>>5); i++) {    // for each loop it writes 16 mmx_t = 32 cpx samples = 64 real samples    // Read in 32 new bits from the midamble table    bits = mid->midamble_table[mid_index+i];    for ( j=0; j<16; j++ ) {      // extract two chips      bit12 = bits & bmask;      bits = bits >> 2;      // put 64 bit map into register mm0      movq_m2r( map[ bit12 ], mm0 );      // multiply by mm3  (midamp)      pmullw_r2r( mm3, mm0 );      // add the result to out      movq_m2r( *out, mm4 );      paddw_r2r( mm0, mm4 );      movq_r2m( mm4, *out );      out++;    }    // adds 32 because we have read 32 more chips    count+=32;  }  // if there is still a 32-bit word that contains midamble chips  if( count != mid->length ) {    // Read in the last 32bits from the midamble table    bits = mid->midamble_table[mid_index+(mid->length>>5)];    // for each chip in the last word    for (i=0; i<((mid->length-count)/2); i++) {      bit12 = bits & bmask;      bits = bits >> 2;      movq_m2r(map[ bit12 ],mm0);      pmullw_r2r(mm3,mm0);      movq_m2r( *out, mm4 );      paddw_r2r( mm0, mm4 );      movq_r2m( mm4, *out );    }  }  return 0;}int midamble_get_nbr_channels( int mid_type ) {  return midamble_def[ mid_type ].max_channels;}int midamble_get_length( int mid_type ) {  return midamble_def[ mid_type ].length;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -