wifi: Rework calculations in NistErrorRateModel
This commit is contained in:
committed by
Sébastien Deronne
parent
c2d2c81623
commit
7f0048ef78
@@ -19,9 +19,11 @@
|
||||
* Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <bitset>
|
||||
#include "ns3/log.h"
|
||||
#include "nist-error-rate-model.h"
|
||||
#include "wifi-phy.h"
|
||||
#include "wifi-tx-vector.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -65,50 +67,21 @@ NistErrorRateModel::GetQpskBer (double snr) const
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::Get16QamBer (double snr) const
|
||||
NistErrorRateModel::GetQamBer (uint16_t constellationSize, double snr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr);
|
||||
double z = std::sqrt (snr / (5.0 * 2.0));
|
||||
double ber = 0.75 * 0.5 * erfc (z);
|
||||
NS_LOG_INFO ("16-Qam" << " snr=" << snr << " ber=" << ber);
|
||||
NS_LOG_FUNCTION (this << constellationSize << snr);
|
||||
NS_ASSERT (std::bitset<16> (constellationSize).count () == 1); //constellationSize has to be a power of 2
|
||||
double z = std::sqrt (snr / ((2 * (constellationSize - 1)) / 3));
|
||||
uint8_t bitsPerSymbol = std::sqrt (constellationSize);
|
||||
double ber = ((bitsPerSymbol - 1) / (bitsPerSymbol * std::log2 (bitsPerSymbol))) * erfc (z);
|
||||
NS_LOG_INFO (constellationSize << "-QAM: snr=" << snr << " ber=" << ber);
|
||||
return ber;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::Get64QamBer (double snr) const
|
||||
NistErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits, uint8_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr);
|
||||
double z = std::sqrt (snr / (21.0 * 2.0));
|
||||
double ber = 7.0 / 12.0 * 0.5 * erfc (z);
|
||||
NS_LOG_INFO ("64-Qam" << " snr=" << snr << " ber=" << ber);
|
||||
return ber;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::Get256QamBer (double snr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr);
|
||||
double z = std::sqrt (snr / (85.0 * 2.0));
|
||||
double ber = 15.0 / 32.0 * 0.5 * erfc (z);
|
||||
NS_LOG_INFO ("256-Qam" << " snr=" << snr << " ber=" << ber);
|
||||
return ber;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::Get1024QamBer (double snr) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr);
|
||||
double z = std::sqrt (snr / (341.0 * 2.0));
|
||||
double ber = 31.0 / 80.0 * 0.5 * erfc (z);
|
||||
NS_LOG_INFO ("1024-Qam" << " snr=" << snr << " ber=" << ber);
|
||||
return ber;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
NS_LOG_FUNCTION (this << snr << nbits << +bValue);
|
||||
double ber = GetBpskBer (snr);
|
||||
if (ber == 0.0)
|
||||
{
|
||||
@@ -121,10 +94,9 @@ NistErrorRateModel::GetFecBpskBer (double snr, uint64_t nbits,
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFecQpskBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
NistErrorRateModel::GetFecQpskBer (double snr, uint64_t nbits, uint8_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
NS_LOG_FUNCTION (this << snr << nbits << +bValue);
|
||||
double ber = GetQpskBer (snr);
|
||||
if (ber == 0.0)
|
||||
{
|
||||
@@ -137,9 +109,9 @@ NistErrorRateModel::GetFecQpskBer (double snr, uint64_t nbits,
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const
|
||||
NistErrorRateModel::CalculatePe (double p, uint8_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << bValue);
|
||||
NS_LOG_FUNCTION (this << p << +bValue);
|
||||
double D = std::sqrt (4.0 * p * (1.0 - p));
|
||||
double pe = 1.0;
|
||||
if (bValue == 1)
|
||||
@@ -209,11 +181,10 @@ NistErrorRateModel::CalculatePe (double p, uint32_t bValue) const
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFec16QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
NistErrorRateModel::GetFecQamBer (uint16_t constellationSize, double snr, uint64_t nbits, uint8_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
double ber = Get16QamBer (snr);
|
||||
NS_LOG_FUNCTION (this << constellationSize << snr << nbits << +bValue);
|
||||
double ber = GetQamBer (constellationSize, snr);
|
||||
if (ber == 0.0)
|
||||
{
|
||||
return 1.0;
|
||||
@@ -224,52 +195,25 @@ NistErrorRateModel::GetFec16QamBer (double snr, uint64_t nbits,
|
||||
return pms;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFec64QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
uint8_t
|
||||
NistErrorRateModel::GetBValue (WifiCodeRate codeRate) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
double ber = Get64QamBer (snr);
|
||||
if (ber == 0.0)
|
||||
switch (codeRate)
|
||||
{
|
||||
return 1.0;
|
||||
case WIFI_CODE_RATE_3_4:
|
||||
return 3;
|
||||
case WIFI_CODE_RATE_2_3:
|
||||
return 2;
|
||||
case WIFI_CODE_RATE_1_2:
|
||||
return 1;
|
||||
case WIFI_CODE_RATE_5_6:
|
||||
return 5;
|
||||
case WIFI_CODE_RATE_UNDEFINED:
|
||||
default:
|
||||
NS_FATAL_ERROR ("Unknown code rate");
|
||||
break;
|
||||
}
|
||||
double pe = CalculatePe (ber, bValue);
|
||||
pe = std::min (pe, 1.0);
|
||||
double pms = std::pow (1 - pe, nbits);
|
||||
return pms;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFec256QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
double ber = Get256QamBer (snr);
|
||||
if (ber == 0.0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
double pe = CalculatePe (ber, bValue);
|
||||
pe = std::min (pe, 1.0);
|
||||
double pms = std::pow (1 - pe, nbits);
|
||||
return pms;
|
||||
}
|
||||
|
||||
double
|
||||
NistErrorRateModel::GetFec1024QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << snr << nbits << bValue);
|
||||
double ber = Get1024QamBer (snr);
|
||||
if (ber == 0.0)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
double pe = CalculatePe (ber, bValue);
|
||||
pe = std::min (pe, 1.0);
|
||||
double pms = std::pow (1 - pe, nbits);
|
||||
return pms;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double
|
||||
@@ -284,103 +228,15 @@ NistErrorRateModel::DoGetChunkSuccessRate (WifiMode mode, WifiTxVector txVector,
|
||||
{
|
||||
if (mode.GetConstellationSize () == 2)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
return GetFecBpskBer (snr,
|
||||
nbits,
|
||||
1); //b value
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFecBpskBer (snr,
|
||||
nbits,
|
||||
3); //b value
|
||||
}
|
||||
return GetFecBpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 4)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
return GetFecQpskBer (snr,
|
||||
nbits,
|
||||
1); //b value
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFecQpskBer (snr,
|
||||
nbits,
|
||||
3); //b value
|
||||
}
|
||||
return GetFecQpskBer (snr, nbits, GetBValue (mode.GetCodeRate ()));
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 16)
|
||||
else
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_1_2)
|
||||
{
|
||||
return GetFec16QamBer (snr,
|
||||
nbits,
|
||||
1); //b value
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFec16QamBer (snr,
|
||||
nbits,
|
||||
3); //b value
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 64)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_2_3)
|
||||
{
|
||||
return GetFec64QamBer (snr,
|
||||
nbits,
|
||||
2); //b value
|
||||
}
|
||||
else if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
|
||||
{
|
||||
return GetFec64QamBer (snr,
|
||||
nbits,
|
||||
5); //b value
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFec64QamBer (snr,
|
||||
nbits,
|
||||
3); //b value
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 256)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
|
||||
{
|
||||
return GetFec256QamBer (snr,
|
||||
nbits,
|
||||
5 // b value
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFec256QamBer (snr,
|
||||
nbits,
|
||||
3 // b value
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (mode.GetConstellationSize () == 1024)
|
||||
{
|
||||
if (mode.GetCodeRate () == WIFI_CODE_RATE_5_6)
|
||||
{
|
||||
return GetFec1024QamBer (snr,
|
||||
nbits,
|
||||
5 // b value
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFec1024QamBer (snr,
|
||||
nbits,
|
||||
3 // b value
|
||||
);
|
||||
}
|
||||
return GetFecQamBer (mode.GetConstellationSize (), snr, nbits, GetBValue (mode.GetCodeRate ()));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define NIST_ERROR_RATE_MODEL_H
|
||||
|
||||
#include "error-rate-model.h"
|
||||
#include "wifi-mode.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -48,19 +49,27 @@ public:
|
||||
private:
|
||||
//Inherited from ErrorRateModel
|
||||
double DoGetChunkSuccessRate (WifiMode mode, WifiTxVector txVector, double snr, uint64_t nbits) const;
|
||||
/**
|
||||
* Return the bValue such that coding rate = bValue / (bValue + 1).
|
||||
*
|
||||
* \param codeRate the coding rate
|
||||
*
|
||||
* \return the bValue such that coding rate = bValue / (bValue + 1)
|
||||
*/
|
||||
uint8_t GetBValue (WifiCodeRate codeRate) const;
|
||||
/**
|
||||
* Return the coded BER for the given p and b.
|
||||
*
|
||||
* \param p the SNR ratio (not dB)
|
||||
* \param p the SNR ratio (in linear scale)
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
*
|
||||
* \return the coded BER
|
||||
*/
|
||||
double CalculatePe (double p, uint32_t bValue) const;
|
||||
double CalculatePe (double p, uint8_t bValue) const;
|
||||
/**
|
||||
* Return BER of BPSK at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
*
|
||||
* \return BER of BPSK at the given SNR
|
||||
*/
|
||||
@@ -68,105 +77,50 @@ private:
|
||||
/**
|
||||
* Return BER of QPSK at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
*
|
||||
* \return BER of QPSK at the given SNR
|
||||
*/
|
||||
double GetQpskBer (double snr) const;
|
||||
/**
|
||||
* Return BER of QAM16 at the given SNR.
|
||||
* Return BER of QAM for a given constellation size at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
*
|
||||
* \return BER of QAM16 at the given SNR
|
||||
* \param constellationSize the constellation size (M)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
* \return BER of QAM for a given constellation size at the given SNR
|
||||
*/
|
||||
double Get16QamBer (double snr) const;
|
||||
/**
|
||||
* Return BER of QAM64 at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
*
|
||||
* \return BER of QAM64 at the given SNR
|
||||
*/
|
||||
double Get64QamBer (double snr) const;
|
||||
/**
|
||||
* Return BER of QAM256 at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \return BER of QAM256 at the given SNR
|
||||
*/
|
||||
double Get256QamBer (double snr) const;
|
||||
/**
|
||||
* Return BER of QAM1024 at the given SNR.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \return BER of QAM1024 at the given SNR
|
||||
*/
|
||||
double Get1024QamBer (double snr) const;
|
||||
double GetQamBer (uint16_t constellationSize, double snr) const;
|
||||
/**
|
||||
* Return BER of BPSK at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
* \param bValue the bValue such that coding rate = bValue / (bValue + 1)
|
||||
*
|
||||
* \return BER of BPSK at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFecBpskBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
double GetFecBpskBer (double snr, uint64_t nbits, uint8_t bValue) const;
|
||||
/**
|
||||
* Return BER of QPSK at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
* \param bValue the bValue such that coding rate = bValue / (bValue + 1)
|
||||
*
|
||||
* \return BER of QPSK at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFecQpskBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
double GetFecQpskBer (double snr, uint64_t nbits, uint8_t bValue) const;
|
||||
/**
|
||||
* Return BER of QAM16 at the given SNR after applying FEC.
|
||||
* Return BER of QAM for a given constellation size at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param constellationSize the constellation size (M)
|
||||
* \param snr SNR ratio (in linear scale)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
* \param bValue the bValue such that coding rate = bValue / (bValue + 1)
|
||||
*
|
||||
* \return BER of QAM16 at the given SNR after applying FEC
|
||||
* \return BER of QAM for a given constellation size at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFec16QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
/**
|
||||
* Return BER of QAM64 at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
*
|
||||
* \return BER of QAM64 at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFec64QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
/**
|
||||
* Return BER of QAM256 at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
* \return BER of QAM256 at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFec256QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
/**
|
||||
* Return BER of QAM1024 at the given SNR after applying FEC.
|
||||
*
|
||||
* \param snr SNR ratio (not dB)
|
||||
* \param nbits the number of bits in the chunk
|
||||
* \param bValue such that coding rate = bValue / (bValue + 1)
|
||||
* \return BER of QAM1024 at the given SNR after applying FEC
|
||||
*/
|
||||
double GetFec1024QamBer (double snr, uint64_t nbits,
|
||||
uint32_t bValue) const;
|
||||
double GetFecQamBer (uint16_t constellationSize, double snr, uint64_t nbits, uint8_t bValue) const;
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
Reference in New Issue
Block a user