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

📄 ldpc_decode_ics.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *    ldpc_decode.c  - LDPC decoding *                           ------------------- *   begin                :  01/2003 *   authors              :  Bernhard Bruhn *   emails               :  bernhard.bruhn@epfl.ch ***************************************************************************//*************************************************************************** *                                Changes *                                ------- * date - name - description * 03/04/25 - ineiti - added snr to the stats, so that one can check what *                     snr has been used when decoding * 03/05/09 - ineiti - added a done-stats to know when it's finished * * 03/09/01 - chiurtu - modified for the 2fold decoding (either multiple taps *                      or multiple antennas) * 10 Dec 2003 - chiurtu - modified for 4 by 4 MIMO * 04/03/31 - ineiti - added some debugging messages * 17 June 2004 - chiurtu - compute the true sigma and the true SNR * **************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************//** * LDPC-decoder using the 2fold-techinque to decode a stream coming from a * MIMO environment. */#include "spc.h"#include "graphcreate.h"#include "decodehelpers.h"#include "std.h"#include <complex.h>#define DBG_LVL 0#define MAX_NO_RX 4#define MAX_NO_TX 4typedef struct {  // The total iteration-number. For each iteration, iterations_left  // followed by iterations_right are done.  int iterations;  // How many iterations to the left are done per total iteration  int iterations_left;  // How many iterations to the right are done per total iteration  int iterations_right;  // The ID of the LDPC code  int ldpc_code_id; // 1  // 'a/variance' for AWGN  double channel_param;  // 0.07    // How many input channels  int no_tx; // 4  // How many output channels  int no_rx; // 4  //Block-id of the ChEst  blocks. They will provide H  int chest [MAX_NO_RX]; // [-1 -1 -1 -1]  // How many blocks to drop  int drop_blocks; // 0} config_t;typedef struct{  // The calculated variance of the h_{ij}'s  double h_var;  // The claculated true sigma  double true_sigma;  // The calculated true snr  double true_snr;} stats_t;typedef struct{  graphs *graph;  int *iphi;  int gap;  int ldpc_code_id;  int bits_per_symbol;  int iterations;  int iterations_left;  int iterations_right;  double channel_param; // either 'p' or 'a/variance'  int no_tx;  int no_rx;  int chest[MAX_NO_RX];  int counter;  int drop_blocks;} private_t;/* * The initialisation function, or constructor, * is called the each time this module is instantiated. */int ics_rcv_init( swr_sdb_t *context ) {  int i;  // Begin system-definitions {  config_t *config;  stats_t *stats;  MOD_INC_USE_COUNT;  SET_STATUS( MULTI_IN );    if ( sizeof( private_t ) > 0 ) context->private_data = swr_malloc( sizeof( private_t ) );  swr_sdb_get_config_struct( context->id, (void**)&config );  swr_sdb_get_stats_struct( context->id, (void**)&stats );  // } End of system-definitions      config->ldpc_code_id	= 1;  config->iterations	= 30;  config->channel_param	= 0.07;    config->no_rx = MAX_NO_RX;  config->no_tx = MAX_NO_TX;  for ( i=0; i<MAX_NO_RX; i++){    config->chest[i] = -1;  }  config->drop_blocks = 0;  stats->h_var = -1;  stats->true_sigma = -1;  stats->true_snr = -20;    private->bits_per_symbol= 2;  private->ldpc_code_id = -1;  private->counter=0;    //allocate memory for graph  private->graph=(graphs *)swr_malloc(sizeof(graphs));  private->graph->vnodenum=0;  private->graph->cnodenum=0;  private->graph->f = NULL;      // Begin system-definitions  swr_sdb_free_stats_struct( context->id, (void**)&stats );  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;  // End system-definitions}/* * Every time modules from the outside change the value of a configuration parameter, * this function is called. */int ics_rcv_reconfig( swr_sdb_t *context ) {  int i;  // Definition of variables - don't touch  config_t *config;  stats_t *stats;  int vnodenum=0, cnodenum=0;  swr_sdb_get_config_struct( context->id, (void**)&config );  swr_sdb_get_stats_struct( context->id, (void**)&stats );  // Put you code here  // ADD HERE       private->graph->bits_per_left_checknode = config->no_tx * 2;  if ( private->graph->bits_per_left_checknode ){    PR_DBG( 4, "BPLCN: %i\n", private->graph->bits_per_left_checknode );    // put new code into private->graph if config->ldpc_code_id has changed    if(config->ldpc_code_id!=-1 && private->ldpc_code_id!=config->ldpc_code_id) {      PR_DBG( 2, "loading ldpc code with ID %i\n", config->ldpc_code_id );      if(private->ldpc_code_id!=-1) freeGraph(private->graph, private->iphi);      private->ldpc_code_id = config->ldpc_code_id;      if ( getGraph(private->ldpc_code_id, private->graph, &(private->gap), &(private->iphi)) ){	private->ldpc_code_id = -1;      } else {	vnodenum=private->graph->vnodenum;	cnodenum=private->graph->cnodenum;	size_out(0) = ( vnodenum - cnodenum ) / 8;	PR_DBG( 2, "Put output-size to %i bytes\n", size_out(0) );      }    }  }  private->iterations	=config->iterations;  private->iterations_left	=config->iterations_left;  private->iterations_right	=config->iterations_right;  private->channel_param=config->channel_param;  private->no_rx = config->no_rx;  private->no_tx = config->no_tx;    private->drop_blocks  =config->drop_blocks;  for ( i=0; i<config->no_rx; i++){    private->chest[i] = config->chest[i] ;  }    // Definition - don't touch  swr_sdb_free_stats_struct( context->id, (void**)&stats );  swr_sdb_free_config_struct( context->id, (void**)&config );  return 0;}/* * This is the function that implements the `main method' of the class * Every class has got just ONE method/working-mode. */int ics_rcv_pdata( swr_sdb_t *context ) {    stats_t *stats;  SYMBOL_COMPLEX *in[MAX_NO_RX], *ch[MAX_NO_RX];  SYMBOL_COMPLEX y[MAX_NO_RX], h[MAX_NO_RX][MAX_NO_TX];  U8 *out;  int vnodenum=0, cnodenum=0, dnodenum=0;  int *decisions;  int i, j, n, k, p;  int var_real[MAX_NO_RX], var_imag[MAX_NO_RX];  double x[private->graph->bits_per_left_checknode];  double f;  complex double u, z, w;  double mean_h, var_h;  double mean_sigmanoise;  double true_snr;  double true_sigma;  double code_rate;  PR_DBG( 4, "Entry for %i receivers\n", private->no_rx );    // If we have a matched-filter, then get the correct values  // Return if not all data available yet  j = 0;  for ( i=0; i<private->no_rx; i++ ){    j += !!data_available( i ) * ( 1 << i );  }  if ( j != ( 1 << private->no_rx ) - 1 ){    PR_DBG( 3, "Not all data here yet:%x\n", j );    return -1;  }  PR_DBG( 3, "All %i inputs are filled, processing\n", private->no_rx );    for (i = 0; i < private->no_rx; i++){    in[i] =  buffer_in(i);  }  // To avoid calculating all the time and to give some processing-power  // to the linux-kernel  if ( private->drop_blocks > 0 ){    if ( private->counter++ % private->drop_blocks ){      return -1;    }  }    out=buffer_out(0);    vnodenum=(*private->graph).vnodenum;  cnodenum=(*private->graph).cnodenum;  // d is data nodes  dnodenum=vnodenum - cnodenum;    PR_DBG( 1, "vnodenum=%d, cnodenum=%d, size_in=%d bytes\n", 	  vnodenum, cnodenum, size_in(0));    PR_DBG( 2,"allocating %i decisions, dec_in\n", vnodenum);  decisions=(int*)swr_malloc(sizeof(int)*vnodenum);  //AWGN Channel  //compute LLRs for symbols from 'in' to the decoder input vector 'dec_in'  if( size_in(0) * private->graph->bits_per_left_checknode < vnodenum ) {    PR_DBG( 0, "size_in(0)*bits_per_left_checknode<vnodenum ( %i*2<%i ) => "	    "unable to decode\n", 	    size_in(0) * private->graph->bits_per_left_checknode, vnodenum );    return -1;  } else {    // TODO: implement initialisation of the input    // The respectives f_b's are    // graph->f[node * ( 1 << private->graph->bits_per_left_checknode ) + b ]    // in1 comes from rcv-antenna 1    // in2 comes from rcv-antenna 2    // h11 = ch1[0]    // h12 = ch1[1]    // h21 = ch2[0]    // h22 = ch2[1]    // var1 is the variance of rcv-antenna 1    // var2 is the variance of rcv-antenna 2        for ( i=0; i<private->no_rx; i++ ){      if ( private->chest[i] < 0 ){

⌨️ 快捷键说明

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