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

📄 test_ldpc_mimo_general.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
字号:
/***************************************************************************   test_ldpc_mimo_general.c - a NxN MIMO 2-fold ldpc code                            -------------------    begin                : 01 Sept 2003     authors              : Nicolae Chiurtu    emails               : Nicolae.Chiurtu@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 03/09/01 - Nicou - Begin 03/09/03 - ineiti - added complex channel 10 Dec 2003 - nicu & linus - make it general to work for up to 4 by 4 04/03/03 - ineiti - added a small description  **************************************************************************//*************************************************************************** *                                                                         * *   This program 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 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include <stdlib.h>#include <complex.h>#include <fpu_control.h>#include "spc.h"#include "std.h"#include "math.h"#define DBG_LVL 0char desc[] ="Description:\n""This is a general NxN MIMO LDPC-code simulation, where 1<=N<=4.\n""It shows the result for increasing sigma. The BER for sigmas < 0.7\n""should be 0. Above that, the BER should rise to 0.2 or so.\n""The channel-matrix H is 'a_mn + b_mn * i', where a_mn and b_mn\n""are gaussian variables with variance 1 and mean 0.\n\n";// The number of experiments and variances#define NO_VAR 12#define NO_EXP 1#define NO_TX 2#define NO_RX 2#define BLOCK_LENGTH 4000double getSigma(double);complex double getSigmaComplex(complex double);struct chain_t *test_chain[ NO_TX + NO_RX ];void *start_it( void *arg ) {  swr_sdb_id mid[NO_TX],src,block_complex;  swr_sdb_id split, tsd, rcd, mid_rx[NO_RX],encoder,decoder;  double total_errors;  int a, b, c, d, e;  int errors, total_info_bits;  int MAX_NO_RX;  double ber = 0.0;  double real_sigma;  double sigma_array[NO_VAR] = {3200., 6400., 9600., 12800., 16000., 19200., 22400.,			     25600., 28800., 32000., 35200., 38400.};  complex double h[NO_RX][NO_TX];  // Division by zero and overflow  /* { *//*     fpu_control_t fpu_err = 0x37f - _FPU_MASK_ZM - _FPU_MASK_OM; *//*     _FPU_SETCW( fpu_err ); *//*   } */  PR( "Setting up main-chain\n" );   // This chain simulates a simple 2x2 MIMO with two-folded LDPC  test_chain[0] = swr_chain_create(NEW_SPC_VAR( "random", src ),				   NEW_SPC_VAR( "test_data_send", tsd),				   NEW_SPC_VAR( "ldpc_encode_2fold", encoder),				   NEW_SPC( "mapper"),				   NEW_SPC_VAR( "split", split ),				   NEW_SPC_VAR( "chest_send", mid[ 0 ] ),				   NEW_SPC_VAR( "block_4by4_complex", block_complex),				   NEW_SPC_VAR( "chest_rcv", mid_rx[ 0 ] ),				   NEW_SPC_VAR( "ldpc_decode_2fold_general", decoder),				   NEW_SPC_VAR( "test_data_rcv", rcd ),				   CHAIN_END );  MAX_NO_RX = swr_sdb_get_stats_int( block_complex, "max_no_rx" );  swr_sdb_set_config_int( block_complex, "size", BLOCK_LENGTH / 2 / NO_TX + 256 );        PR( "Setting up secondary chains\n" );  // Doing transmission chains 1..NO_TX  for ( a=1; a<NO_TX; a++ ){    test_chain[ a ] = swr_chain_create( OLD_SPC_OUT( split, a ),					NEW_SPC_VAR( "chest_send", mid[ a ] ),					OLD_SPC_IN( block_complex, a ),					CHAIN_END );  }  // Doing reception chains 1..NO_RX  for ( a=1; a<NO_RX; a++ ){    test_chain[ NO_TX + a - 1 ] =      swr_chain_create( OLD_SPC_OUT( block_complex, a ),			NEW_SPC_VAR( "chest_rcv", mid_rx[ a ] ),			OLD_SPC_IN( decoder, a ),			CHAIN_END );  }  PR( "Chains are set up\n" );   // Precision of the DAD module  swr_sdb_set_config_int( block_complex, "precision", 14 );    // setting the number of antennas for the block_complex  for ( a=0; a<NO_RX; a++ ){    swr_sdb_set_config_int( mid_rx[a], "num_of_antennas", NO_RX );    swr_sdb_set_config_int_array( decoder, "chest", a, mid_rx[a] );    swr_sdb_set_config_int( mid_rx[a], "circ_ext", 0 );  }  for ( a=0; a<NO_TX; a++ ){    swr_sdb_set_config_int( mid[a], "index", a );    swr_sdb_set_config_int( mid[a], "circ_ext", 0 );  }  swr_sdb_set_config_int( rcd, "mode", 1 );  swr_sdb_set_config_int( encoder, "ldpc_code_id", 1 );  swr_sdb_set_config_int( decoder, "ldpc_code_id", 1 );  swr_sdb_set_config_int( decoder, "iterations", 15 );  swr_sdb_set_config_int( decoder, "iterations_left", 1 );  swr_sdb_set_config_int( decoder, "iterations_right", 1 );  swr_sdb_set_config_int( decoder, "no_tx", NO_TX );  swr_sdb_set_config_int( decoder, "no_rx", NO_RX );  swr_sdb_set_config_int( encoder, "bplcn", NO_TX * 2 );  PR( "Connecting the test_data modules\n" );  swr_conn_add(tsd, 1,rcd, 1);    //swr_sdb_set_config_int( snk, "flag", 1 ); //dump    PR( "Sending first message\n" );    for (a = 0; a < NO_VAR; a++ ) {        // setting the noise variance        for (c = 0; c < NO_RX; c++ ) {      swr_sdb_set_config_complex_array( block_complex, "sigma", c, 					sigma_array[a] * ( 1.0 + 1.0*I ) );    }        total_errors = 0.0;    for (b = 0; b < NO_EXP; b++){            // setting the channel            for(d = 0; d < NO_RX; d++){	for(e = 0; e < NO_TX; e++){	  h[d][e] = getSigmaComplex(1.0 + 1.0*I);	  swr_sdb_set_config_complex_array( block_complex, "h", 					    d * MAX_NO_RX + e, h[d][e] ); 	}      }            // print the channel and the variance to compare with the one which we estimate later      // works for a = 0.01            for ( d=0; d<NO_RX; d++ ){	for ( e=0; e<NO_TX; e++ ){	  PR_DBG_CL( 4, "tr-h%i%i(%g:%gi) ", d, e, 		     floor(creal(h[d][e])*327.67),		     floor(cimag(h[d][e])*327.67 ));	}      }            PR_DBG_CL( 4, "tr-var1(%g) tr-var2(%g) \n" ,		 (double) pow(sigma_array[a]*0.01,2), 		 (double) pow(sigma_array[a]*0.01,2) );                  swr_sdb_send_msg( src, SUBS_MSG_USER, NULL, -1 );            //PR( "Total data: %i, Errors: %i\n",      //  swr_sdb_get_stats_int( rcd, "total" ),      //  swr_sdb_get_stats_int( rcd, "error" ) );            total_info_bits = swr_sdb_get_stats_int( rcd, "total" );      errors = swr_sdb_get_stats_int( rcd, "error" );      total_errors += errors;/*       PR("Noise Variance ant 1 = [%i], ant 2  = [%i] \n", *//* 	 swr_sdb_get_stats_int( mid_rx[0], "noise_var_real"),  *//* 	 swr_sdb_get_stats_int( mid_rx[1], "noise_var_real")); */          } // for number experiments        ber = (double) total_errors / (NO_EXP * total_info_bits);    real_sigma = (double) sigma_array[ a ] / 32767;        // PR("Info bits = %i, errors = %i\n", total_info_bits, errors);    PR("Sigma = %g, BER = %g\n", real_sigma, ber);      } // for the number of variances    return 0;}swr_spc_id_t spm_id;struct thread start;/** * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */int um_module_init(void) {  int i;  PR_CL( desc );  for ( i=0; i<NO_TX+NO_RX; i++ ){    test_chain[i] = NULL;  }  if ( swr_thread_init( &start, start_it, NULL ) < 0 )    goto first_no_stack;  return 0;first_no_stack:  PR_DBG( 0, "Couldn't allocate stack\n" );  return -1;}void um_module_exit( void ) {  int i;  swr_thread_free( &start, NULL );  for ( i=NO_TX+NO_RX-1; i>=0; i-- ){    swr_chain_destroy( test_chain[ i ] );  }  PR( "Finished and cleaned up\n" );}double getSigma( double amplitude ) {  unsigned short x[3];  double u, v, w, alpha;  x[0] = (unsigned short)((get_time_usec()>>00)&0xffff);  x[1] = (unsigned short)((get_time_usec()>>16)&0xffff);  x[2] = (unsigned short)((get_time_usec()>>00)&0xffff);  do {    u = 2*erand48(x)-1;    v = 2*erand48(x)-1;    w = u*u + v*v;  } while (w>=1);  alpha = sqrt( -2 * log(w)/w);  return alpha * u * amplitude;}complex double getSigmaComplex( complex double amplitude ){    return getSigma( creal( amplitude ) ) +    getSigma( cimag( amplitude ) ) * I;}module_init( um_module_init );module_exit( um_module_exit );

⌨️ 快捷键说明

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