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

📄 simulation.cpp

📁 Turbo码性能仿真源程序信道编码方面的
💻 CPP
字号:
#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <math.h>
#include "Global.h"
#include "CoDec.h"
#include "Channel.h"
#include "ST.h"

#define	ASTEP(x)	( (x) > 1 ? 0 : 1 )
#define	STEP(x)		( (x) > 0 ? 0 : 1 )

IO				IO;
SpcCoDec		Spc;	
Random			Rnd;
ComplexChannel	Channel;
ST				MIMO;

void	FileNameGen( );
void	Simulator( double ChipSnr, double Sigma2, int *_BitError, int *_FrameError );
void	TransmitterSide( );
void	ReceiverSide( float Sigma, int *BitError, int *FrameError );
void	Puncture( int *temp );
void	Puncture( float *temp );
void	PreProcess( float Sigma );
void	MIMOtoDecoder( );
void	DePuncture( float *temp );
void	DecodertoMIMO( );
void	DataGen( );



/******************************************************************************************
function : Simulation initialization -- All initialization process of each layer and the
               parameters check should be included here
******************************************************************************************/
void Initialization( )
{
	Rnd.SetState( 443 );

	_Nt						= NT;
	_DataLen				= DATALEN;
	_CodewordLen			= CODEWORDLEN;
	_PuncturedCodewordLen	= PUNCTUREDCODEWORDLEN;
	_SpreadLen				= SPREADLEN;
	_Puncture				= PUNCTURE;
	_StackNum				= STACKNUM;
	_ChipNum				= CHIPNUM;
	_FrameLen				= (int) ceil( (float) _ChipNum / (float) _StackNum / 2 );
	_TranChipNum			= 2 * _FrameLen * _StackNum; 

	_Sb = new Complex [_FrameLen];

	if( PUNCTURE >= NESTDIM ) IO.ErrorMessage( "PUNCTURE >= NESTDIM" );
	Spc.Init( 1, DATALEN, PUNCTURE, EFOLDNUM, FFOLDNUM, NESTDIM, SPCTRELLISLEN, POLYSTATEORDER, NPOLY, DPOLY, _ScrambleNum );
	MIMO.Init( NT, STACKNUM, _FrameLen, SPREADLEN, PUNCTUREDCODEWORDLEN, CHIPNUM, _TranChipNum );
	FileNameGen( );
}

void End( )
{
	delete [] _Sb;
	MIMO.End( );
}


void FileNameGen( )
{
	IO.FnInit( );
	if( strcmp( _ChannelType, "AWGN" ) == 0  ) IO.FnJoin( "AWGN_" );
	else if( strcmp( _ChannelType, "SlowFade" ) == 0 ) IO.FnJoin( "SlowFade" );
	else IO.ErrorMessage( "Unknow channel condition" );

	IO.FnJoin( "_i" );		IO.FnJoin( (float)LTOOLARGE1 );
	IO.FnJoin( "_i" );		IO.FnJoin( (int) log10(RTOOLARGE1) );
	IO.FnJoin( "_n" );		IO.FnJoin( (int) log10(RTOOLARGE2) );
	IO.FnJoin( "_o" );		IO.FnJoin( (int) log10(RTOOLARGE3) );
	
	IO.FnJoin( "_Nt" );		IO.FnJoin( (int) NT );
	IO.FnJoin( "_D" );		IO.FnJoin( (int) DATALEN );
	IO.FnJoin( "e" );		IO.FnJoin( (int) EFOLDNUM );
	IO.FnJoin( "f" );		IO.FnJoin( (int) FFOLDNUM );
	IO.FnJoin( "m" );		IO.FnJoin( (int) NESTDIM );
	IO.FnJoin( "Np" );		IO.FnJoin( (int) NPOLY );
	IO.FnJoin( "Dp" );		IO.FnJoin( (int) DPOLY );
	IO.FnJoin( "_Sp" );		IO.FnJoin( SPREADLEN );
	IO.FnJoin( "_St" );		IO.FnJoin( STACKNUM );
	IO.FnJoin( "Scram" );	IO.FnJoin( _ScrambleNum );
	IO.FnJoin( "Rate" );	IO.FnJoin( Spc.Rate * (float)STACKNUM / (float) SPREADLEN );
	IO.FnJoin( ".txt" );
	IO.FileHeader( );
}

void SimulationProcess( )
{
	int i, j;
	int BlockNum;
	double Snr, ChipSnr, Sigma;

	Rnd.SetState( 443, 17, 53, 113 );

	for( i=0; i<_SimPt; i++ )
	{
		Snr = pow( 10, _SnrStart / 10 );
		//For BPSK system information are normalized to 1
		//For QPSK system information are normalized to 2
		//For BPSK ST system information are normalized to StackNum
		//For QPSK ST system information are normalized to 2*StackNum
		ChipSnr = Snr * Spc.Rate / _SpreadLen;
		Sigma =  sqrt( 0.5 / ChipSnr );
		BlockNum = 0;
		for( j=0; j<_ItNum; j++ ) 
			_BitError[j] = _FrameError[j] = 0;

		while( (_BitError[_ItNum-1] < _BitErrNum || BlockNum < _MinBlockNum ) && BlockNum < _MaxBlockNum )
		{
			BlockNum++;
			Simulator( ChipSnr, Sigma, _BitError, _FrameError );
			if( BlockNum % _ReportGap == 0 ) IO.ScreenOut( _SnrStart, BlockNum, _BitError, _FrameError );
		}
		IO.FileOut( _SnrStart, BlockNum, _BitError, _FrameError );
		_SnrStart += _SnrStep;
	}
}



/******************************************************************************************
function : Data generation for the N users
******************************************************************************************/
void DataGen( )
{
	int i;

	for( i=0; i<_DataLen; i++ )
		_RawData[i] = Rnd.RandomInt( ) % 2;
}


/******************************************************************************************
function : The Major Process of different layers should be included here
input    : ChipSnr is the signal to noise ratio of each chip
******************************************************************************************/
void Simulator( double ChipSnr, double Sigma, int *BitError, int *FrameError )
{
	DataGen( );
	TransmitterSide( );
	Channel.Noise( Sigma, &_Sb[0] );
	ReceiverSide( (float) Sigma, BitError, FrameError );
}

/******************************************************************************************
function : Transmitter
******************************************************************************************/
void TransmitterSide( )
{
	int i, temp[CODEWORDLEN];

	for( i=0; i<_FrameLen; i++ )
		_Sb[i].Re = _Sb[i].Im = 0;

	if( strcmp( _ChannelType, "AWGN" ) == 0  ) 
	{
		for( i=0; i<_Nt; i++ )
		{
			MIMO.FadeFactor[i].Re = 1;
			MIMO.FadeFactor[i].Im = 0;
		}
	}
	else for( i=0; i<_Nt; i++ )
		MIMO.FadeFactor[i] = Rnd.RayleighGenerator( );

	for( i=0; i<_Nt; i++ )
	{
		MIMO.FadeFactor[i].Re /= (float) sqrt( _Nt );
		MIMO.FadeFactor[i].Im /= (float) sqrt( _Nt );
	}

	Spc.Encoder( 0, &temp[0], &_RawData[0] );
	Puncture( &temp[0] );
	MIMO.Encoder( &temp[0], &_Sb[0] );
}

void ReceiverSide( float Sigma, int *BitError, int *FrameError )
{
	int i, it, tmp;

	PreProcess( Sigma );

	for( it=0; it<_ItNum; it++ )
	{
		MIMO.Input( &_Sb[0] );
		MIMOtoDecoder( );
		DePuncture( &MIMO.DeSpreadChipInfo[0] );
		Spc.Decoder( 0, &MIMO.DeSpreadChipInfo[0], "ParityRequire" );
		DecodertoMIMO( );
		Puncture( &MIMO.DeSpreadChipInfo[0] );
		MIMO.Output( Sigma * Sigma );  //===PreProcess( Sigma );

		for( tmp=i=0; i<_DataLen; i++ )	if( _RawData[i] != ASTEP(MIMO.DeSpreadChipInfo[i]) )
		{			_BitError[it] += 1;			tmp = 1;		}
		_FrameError[it] += tmp;
	}
}

void MIMOtoDecoder( )
{
	int i;
	float tmp;

	for( i=0; i<_DataLen; i++ )
	{
		tmp = _ExSb[i];
		_ExSb[i] = ( MIMO.DeSpreadChipInfo[i] );
		MIMO.DeSpreadChipInfo[i] = (MIMO.DeSpreadChipInfo[i] * _UserSb[i] / tmp );
	}
}

void DecodertoMIMO( )
{
	int i;

	for( i=0; i<_DataLen; i++ )
		_UserSb[i] = MIMO.DeSpreadChipInfo[i];
}

void PreProcess( float Sigma )
{
	int i;

	for( i=0; i<_DataLen; i++ )
		_UserSb[i] = _ExSb[i] = 1;
	MIMO.PreProcess( Sigma );
	Spc.PreDecode( );
}

void Puncture( int *temp )
{
	int i, j;
	for( j=i=_DataLen; i<_CodewordLen; i+=(_Puncture+1) )
		temp[j++] = temp[i];
}

void Puncture( float *temp )
{
	int i, j;
	for( j=i=_DataLen; i<_CodewordLen; i+=(_Puncture+1) )
		temp[j++] = temp[i];
}

void DePuncture( float *temp )
{
	int i, j, k;

	j = _PuncturedCodewordLen-1;
	k = _CodewordLen - _DataLen -1;
	for( i=_CodewordLen-1; i>_DataLen; i--, k-- )
	{
		if( k%(_Puncture+1) == 0 ) temp[i] = temp[j--];
		else temp[i] = 1;
	}
}

⌨️ 快捷键说明

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