IT++ Logo

Simulation of a Multicode CDMA system on an AWGN channel

In this example we will introduce the multi-code spreading class Multicode_Spread_2d. This is the most general spreading class availiable in it++. Different spreading codes may be assigned to the I and Q branches. The number of multiple spreading codes and the spreading factor is determined by the number of rows and collumns respectively that is used when calling the member function set_codes. In this example we will use four Hadamard sequenced of length four, and the same spreading sequences will be used for the I and Q brances.

#include <itpp/itcomm.h>

using namespace itpp;

//These lines are needed for use of cout and endl
using std::cout;
using std::endl;

int main()
{
  //Scalars:
  int SF, Ncode, sc, i, j, NumOfBits, MaxIterations, MaxNrOfErrors, MinNrOfErrors;
  double Eb;

  //Vectors and matrixes:
  vec EbN0dB, EbN0, N0, ber;
  smat all_codes, spread_codesI, spread_codesQ;
  bvec transmited_bits, received_bits;
  cvec transmited_symbols, received_symbols, transmited_chips, received_chips;

  //Classes:
  Multicode_Spread_2d mc_spread;
  AWGN_Channel channel;
  QPSK qpsk;
  BERC berc;

  //Initialize the spreading:
  SF = 4;                            //The spreading factor is 4
  Ncode = 4;                         //Use all four codes in the multi-code spreader
  all_codes = to_smat(hadamard(SF)); //Calculate the spreading codes

  //Set the spreading codes:
  spread_codesI.set_size(Ncode, SF, false);
  spread_codesQ.set_size(Ncode, SF, false);
  for (sc = 0; sc < Ncode; sc++) {
    spread_codesI.set_row(sc, all_codes.get_row(sc));
    spread_codesQ.set_row(sc, all_codes.get_row(sc));
  }
  mc_spread.set_codes(to_mat(spread_codesI), to_mat(spread_codesQ));

  //Specify simulation specific variables:
  EbN0dB = linspace(-2, 14, 17);
  EbN0 = pow(10, EbN0dB / 10);
  Eb = 1.0;
  N0 = Eb * pow(EbN0, -1.0);
  NumOfBits = 50000;
  MaxIterations = 10;
  MaxNrOfErrors = 200;
  MinNrOfErrors = 5;
  ber.set_size(EbN0dB.size(), false);
  ber.clear();

  //Randomize the random number generators:
  RNG_randomize();

  for (i = 0; i < EbN0dB.length(); i++) {

    cout << endl << "Simulating point nr " << i + 1 << endl;
    berc.clear();
    channel.set_noise(N0(i) / 2.0);

    for (j = 0; j < MaxIterations; j++) {

      transmited_bits = randb(NumOfBits);
      transmited_symbols  = qpsk.modulate_bits(transmited_bits);

      //This is where we do the multi-code spreading:
      transmited_chips =  mc_spread.spread(transmited_symbols);

      received_chips = channel(transmited_chips);

      //The multi-code despreading:
      //The second argument tells the despreader that the offset is zero chips.
      //This offset is usefull on channels with delay.
      received_symbols = mc_spread.despread(received_chips, 0);

      received_bits = qpsk.demodulate_bits(received_symbols);

      berc.count(transmited_bits, received_bits);
      ber(i) = berc.get_errorrate();

      cout << "   Itteration " << j + 1 << ": ber = " << berc.get_errorrate() << endl;
      if (berc.get_errors() > MaxNrOfErrors) {
        cout << "Breaking on point " << i + 1 << " with " << berc.get_errors() << " errors." << endl;
        break;
      }

    }

    if (berc.get_errors() < MinNrOfErrors) {
      cout << "Exiting Simulation on point " << i + 1 << endl;
      break;
    }

  }

  //Print results:
  cout << endl;
  cout << "EbN0dB = " << EbN0dB << endl;
  cout << "ber = " << ber << endl;

  //Exit program:
  return 0;

}

A typical run of this program will look like this:

Simulating point nr 1
   Itteration 1: ber = 0.13016
Breaking on point 1 with 6508 errors.

Simulating point nr 2
   Itteration 1: ber = 0.103
Breaking on point 2 with 5150 errors.

Simulating point nr 3
   Itteration 1: ber = 0.07886
Breaking on point 3 with 3943 errors.

Simulating point nr 4
   Itteration 1: ber = 0.05534
Breaking on point 4 with 2767 errors.

Simulating point nr 5
   Itteration 1: ber = 0.03822
Breaking on point 5 with 1911 errors.

Simulating point nr 6
   Itteration 1: ber = 0.02388
Breaking on point 6 with 1194 errors.

Simulating point nr 7
   Itteration 1: ber = 0.01316
Breaking on point 7 with 658 errors.

Simulating point nr 8
   Itteration 1: ber = 0.00586
Breaking on point 8 with 293 errors.

Simulating point nr 9
   Itteration 1: ber = 0.0027
   Itteration 2: ber = 0.00247
Breaking on point 9 with 247 errors.

Simulating point nr 10
   Itteration 1: ber = 0.00094
   Itteration 2: ber = 0.00086
   Itteration 3: ber = 0.00076
   Itteration 4: ber = 0.00077
   Itteration 5: ber = 0.0008
   Itteration 6: ber = 0.000796667
Breaking on point 10 with 239 errors.

Simulating point nr 11
   Itteration 1: ber = 0.00016
   Itteration 2: ber = 0.00016
   Itteration 3: ber = 0.000186667
   Itteration 4: ber = 0.000175
   Itteration 5: ber = 0.000172
   Itteration 6: ber = 0.000173333
   Itteration 7: ber = 0.000162857
   Itteration 8: ber = 0.00017
   Itteration 9: ber = 0.000166667
   Itteration 10: ber = 0.000172

Simulating point nr 12
   Itteration 1: ber = 4e-05
   Itteration 2: ber = 2e-05
   Itteration 3: ber = 2.66667e-05
   Itteration 4: ber = 2.5e-05
   Itteration 5: ber = 2e-05
   Itteration 6: ber = 2e-05
   Itteration 7: ber = 3.14286e-05
   Itteration 8: ber = 2.75e-05
   Itteration 9: ber = 2.44444e-05
   Itteration 10: ber = 2.6e-05

Simulating point nr 13
   Itteration 1: ber = 0
   Itteration 2: ber = 0
   Itteration 3: ber = 0
   Itteration 4: ber = 0
   Itteration 5: ber = 0
   Itteration 6: ber = 0
   Itteration 7: ber = 0
   Itteration 8: ber = 2.5e-06
   Itteration 9: ber = 2.22222e-06
   Itteration 10: ber = 2e-06
Exiting Simulation on point 13

EbN0dB = [-2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
ber = [0.13016 0.103 0.07886 0.05534 0.03822 0.02388 0.01316 0.00586 0.00247 0.000796667 0.000172 2.6e-05 2e-06 0 0 0 0]

Use copy-and-paste to insert the variables EbN0dB and ber into Matlab and plot the result.

SourceForge Logo

Generated on Thu Apr 23 20:06:49 2009 for IT++ by Doxygen 1.5.8