📄 simulation.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 + -