Add PCFICH-PDCCD Error model based on 3GPP R4-081920

This commit is contained in:
Marco Miozzo
2012-07-05 16:42:48 +02:00
parent 5d17c852d4
commit 334bf95352
14 changed files with 171 additions and 25 deletions

View File

@@ -410,7 +410,7 @@ LteHelper::InstallSingleUeDevice (Ptr<Node> n)
Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> ());
Ptr<LteCtrlSinrChunkProcessor> pCtrl = Create<LteCtrlSinrChunkProcessor> (phy->GetObject<LtePhy> (), dlPhy);
dlPhy->AddCtrlSinrChunkProcessor (pCtrl);
Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (dlPhy);

View File

@@ -46,7 +46,28 @@
NS_LOG_COMPONENT_DEFINE ("LteMiErrorModel");
namespace ns3 {
// PCFICH-PDCCH Error model based on 3GPP R4-081920 "LTE PDCCH/PCFICH
// Demodulation Performance Results with Implementation Margin"
double PdcchPcfichBlerCurveXaxis[PDCCH_PCFICH_CURVE_SIZE] = {
-10,-9.8,-9.6, -9.4, -9.2, -9.0, -8.8, -8.6, -8.4, -8.2, -8.0,
-7.8, -7.6, -7.4, -7.2, -7.0, -6.8, -6.6, -6.4, -6.2, -6.0,
-5.8, -5.6, -5.4, -5.2, -5.0, -4.8, -4.6, -4.4, -4.2, -4.0,
-3.8, -3.6, -3.4, -3.2, -3.0, -2.8, -2.6, -2.4, -2.2, -2.0,
-1.8, -1.6, -1.4, -1.2, -1.0
};
double PdcchPcfichBlerCurveYaxis[PDCCH_PCFICH_CURVE_SIZE] = {
0.922602, 0.871559, 0.82334, 0.777789, 0.734758, 0.694107, 0.655706,
0.619429, 0.585159, 0.552785, 0.520927, 0.479229, 0.440869, 0.405579,
0.373114, 0.343104, 0.309947,0.279994, 0.252936, 0.228492, 0.206048,
0.181449, 0.159787, 0.140711, 0.123912, 0.109119, 0.0916184, 0.0769244,
0.0645871, 0.0542285, 0.0454971, 0.037584, 0.0310472, 0.0256473,
0.0211866, 0.0175023, 0.0144636, 0.0119524, 0.00987724, 0.00816236,
0.00673821, 0.00532283, 0.00420476, 0.00332154, 0.00262385, 0.0020727
};
int TbsIndex[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1, -1, -1};
@@ -472,6 +493,78 @@ LteMiErrorModel::GetTbError (const SpectrumValue& sinr, const std::vector<int>&
return errorRate;
}
double
LteMiErrorModel::GetPcfichPdcchError (const SpectrumValue& sinr)
{
NS_LOG_FUNCTION (sinr);
double MI;
double MIsum = 0.0;
SpectrumValue sinrCopy = sinr;
Values::iterator sinrIt = sinrCopy.ValuesBegin ();
uint16_t rb = 0;
NS_ASSERT (sinrIt!=sinrCopy.ValuesEnd ());
while (sinrIt!=sinrCopy.ValuesEnd ())
{
double sinrLin = *sinrIt;
int tr = 0;
while ((tr<MI_MAP_QPSK_SIZE)&&(MI_map_qpsk_axis[tr] < sinrLin))
{
tr++;
}
if (sinrLin > MI_map_qpsk_axis[MI_MAP_QPSK_SIZE-1])
{
MI = 1;
}
else
{
NS_ASSERT_MSG (tr<MI_MAP_QPSK_SIZE, "MI map out of data");
MI = MI_map_qpsk[tr];
}
// NS_LOG_DEBUG (" RB " << rb << " SINR " << 10*log10 (sinrLin) << " MI " << MI);
MIsum += MI;
sinrIt++;
rb++;
}
MI = MIsum / rb;
// return to the effective SINR value
int j = 0;
double esinr = 0.0;
while ((j<MI_MAP_QPSK_SIZE)&&(MI_map_qpsk[j] < MI))
{
j++;
}
if (MI > MI_map_qpsk[MI_MAP_QPSK_SIZE-1])
{
esinr = MI_map_qpsk_axis[MI_MAP_QPSK_SIZE-1];
}
else
{
NS_ASSERT_MSG (j<MI_MAP_QPSK_SIZE, "MI map out of data");
esinr = MI_map_qpsk_axis[j];
}
double esirnDb = 10*log10 (esinr);
// NS_LOG_DEBUG ("Effective SINR " << esirnDb << " max " << 10*log10 (MI_map_qpsk [MI_MAP_QPSK_SIZE-1]));
uint16_t i = 0;
double errorRate = 0.0;
while ((i<PDCCH_PCFICH_CURVE_SIZE)&&(PdcchPcfichBlerCurveXaxis[i] < esirnDb))
{
i++;
}
if (esirnDb > PdcchPcfichBlerCurveXaxis[PDCCH_PCFICH_CURVE_SIZE-1])
{
errorRate = 0.0;
}
else
{
NS_ASSERT_MSG (i<PDCCH_PCFICH_CURVE_SIZE, "PDCCH-PCFICH map out of data");
errorRate = PdcchPcfichBlerCurveYaxis[i];
}
return (errorRate);
}
} // namespace ns3

View File

@@ -44,6 +44,7 @@
namespace ns3 {
const uint16_t PDCCH_PCFICH_CURVE_SIZE = 46;
const uint16_t MI_MAP_QPSK_SIZE = 766;
const uint16_t MI_MAP_16QAM_SIZE = 843;
const uint16_t MI_MAP_64QAM_SIZE = 725;
@@ -62,7 +63,7 @@ public:
* \brief find the mmib (mean mutual information per bit) for different modulations of the specified TB
* \param sinr the perceived sinrs in the whole bandwidth
* \param map the actives RBs for the TB
* \param cms the MCS of the TB
* \param mcs the MCS of the TB
* \return the mmib
*/
static double Mib (const SpectrumValue& sinr, const std::vector<int>& map, uint8_t mcs);
@@ -71,16 +72,26 @@ public:
* \param mmib mean mutual information per bit of a code-block
* \param mcs the MCS
* \param cbSize the size of the CB
* \return the bler
* \return the code block error rate
*/
static double MappingMiBler (double mib, uint8_t mcs, uint16_t cbSize);
/**
* \brief run the error-model algorithm for the specified TB
* \param modulation the modulations (qpsk, 16-qam, 64-qam)
* \param code block-size and code-rate
* \param sinr the perceived sinrs in the whole bandwidth
* \param map the actives RBs for the TB
* \param size the size in bytes of the TB
* \param mcs the MCS of the TB
* \return the TB error rate
*/
static double GetTbError (const SpectrumValue& sinr, const std::vector<int>& map, uint16_t size, uint8_t mcs);
/**
* \brief run the error-model algorithm for the specified PCFICH+PDCCH channels
* \param sinr the perceived sinrs in the whole bandwidth
* \return the decodification error of the PCFICH+PDCCH channels
*/
static double GetPcfichPdcchError (const SpectrumValue& sinr);
//private:

View File

@@ -36,12 +36,22 @@ LteSinrChunkProcessor::~LteSinrChunkProcessor ()
LteCtrlSinrChunkProcessor::LteCtrlSinrChunkProcessor (Ptr<LtePhy> p)
: m_phy (p)
: m_phy (p),
m_spectrumPhy (0)
{
NS_LOG_FUNCTION (this << p);
NS_ASSERT (m_phy);
}
LteCtrlSinrChunkProcessor::LteCtrlSinrChunkProcessor (Ptr<LtePhy> p, Ptr<LteSpectrumPhy> s)
: m_phy (p),
m_spectrumPhy (s)
{
NS_LOG_FUNCTION (this << p);
NS_ASSERT (m_phy);
NS_ASSERT (m_spectrumPhy);
}
LteCtrlSinrChunkProcessor::~LteCtrlSinrChunkProcessor ()
{
@@ -77,6 +87,10 @@ LteCtrlSinrChunkProcessor::End ()
if (m_totDuration.GetSeconds () > 0)
{
m_phy->GenerateCtrlCqiReport ((*m_sumSinr) / m_totDuration.GetSeconds ());
if (m_spectrumPhy)
{
m_spectrumPhy->UpdateSinrPerceived ((*m_sumSinr) / m_totDuration.GetSeconds ());
}
}
else
{

View File

@@ -57,7 +57,8 @@ public:
/**
* The LteCtrlSinrChunkProcessor averages the calculated SINR over time
* for the Ctrl frame and therefore in charge of generating the CQI starting
* from the reference signals.
* from the reference signals and the sinr values used for evaluating the
* decodification error probability of the control channels (PCFICH + PDCCH)
*
*/
class LteCtrlSinrChunkProcessor : public LteSinrChunkProcessor
@@ -65,6 +66,7 @@ class LteCtrlSinrChunkProcessor : public LteSinrChunkProcessor
public:
virtual ~LteCtrlSinrChunkProcessor ();
LteCtrlSinrChunkProcessor (Ptr<LtePhy> p);
LteCtrlSinrChunkProcessor (Ptr<LtePhy> p, Ptr<LteSpectrumPhy> s);
virtual void Start ();
virtual void EvaluateSinrChunk (const SpectrumValue& sinr, Time duration);
virtual void End ();
@@ -72,6 +74,7 @@ private:
Ptr<SpectrumValue> m_sumSinr;
Time m_totDuration;
Ptr<LtePhy> m_phy;
Ptr<LteSpectrumPhy> m_spectrumPhy;
};

View File

@@ -151,10 +151,15 @@ LteSpectrumPhy::GetTypeId (void)
.AddTraceSource ("RxEndError",
"Trace fired when a previosuly started RX terminates with an error",
MakeTraceSourceAccessor (&LteSpectrumPhy::m_phyRxEndErrorTrace))
.AddAttribute ("PemEnabled",
"Activate/Deactivate the error model (by default is active).",
.AddAttribute ("DataErrorModelEnabled",
"Activate/Deactivate the error model of data (TBs of PDSCH and PUSCH) [by default is active].",
BooleanValue (true),
MakeBooleanAccessor (&LteSpectrumPhy::m_pemEnabled),
MakeBooleanAccessor (&LteSpectrumPhy::m_dataErrorModelEnabled),
MakeBooleanChecker ())
.AddAttribute ("CtrlErrorModelEnabled",
"Activate/Deactivate the error model of control (PCFICH-PDCCH decodification) [by default is active].",
BooleanValue (true),
MakeBooleanAccessor (&LteSpectrumPhy::m_ctrlErrorModelEnabled),
MakeBooleanChecker ())
;
return tid;
@@ -801,7 +806,7 @@ LteSpectrumPhy::EndRxData ()
while (itTb!=m_expectedTbs.end ())
{
if (m_pemEnabled)
if (m_dataErrorModelEnabled)
{
double errorRate = LteMiErrorModel::GetTbError (m_sinrPerceived, (*itTb).second.rbBitmap, (*itTb).second.size, (*itTb).second.mcs);
(*itTb).second.corrupt = m_random.GetValue () > errorRate ? false : true;
@@ -875,9 +880,21 @@ LteSpectrumPhy::EndRxDlCtrl ()
// apply transmission mode gain
NS_LOG_DEBUG (this << " txMode " << (uint16_t)m_transmissionMode << " gain " << m_txModeGain.at (m_transmissionMode));
NS_ASSERT (m_transmissionMode < m_txModeGain.size ());
m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
// TODO: Check correctness
if (m_transmissionMode>0)
{
// in case of MIMO, ctrl is always txed as TX diversity
m_sinrPerceived *= m_txModeGain.at (1);
}
// m_sinrPerceived *= m_txModeGain.at (m_transmissionMode);
bool error = false;
if (m_ctrlErrorModelEnabled)
{
double errorRate = LteMiErrorModel::GetPcfichPdcchError (m_sinrPerceived);
errorRate = LteMiErrorModel::GetPcfichPdcchError (m_sinrPerceived);
error = m_random.GetValue () > errorRate ? false : true;
NS_LOG_DEBUG (this << " PCFICH-PDCCH Decodification, errorRate " << errorRate << " error " << error);
}
if (!error)
{
if (!m_ltePhyRxCtrlEndOkCallback.IsNull ())

View File

@@ -372,7 +372,8 @@ private:
SpectrumValue m_sinrPerceived;
UniformVariable m_random;
bool m_pemEnabled; // when true (default) the phy error model is enabled
bool m_dataErrorModelEnabled; // when true (default) the phy error model is enabled
bool m_ctrlErrorModelEnabled; // when true (default) the phy error model is enabled for DL ctrl frame
uint8_t m_transmissionMode; // for UEs: store the transmission mode
std::vector <double> m_txModeGain; // duplicate value of LteUePhy

View File

@@ -25,7 +25,7 @@
#include "ns3/log.h"
#include "ns3/spectrum-test.h"
#include "ns3/boolean.h"
#include "ns3/lte-phy-tag.h"
#include "ns3/lte-test-ue-phy.h"
#include "ns3/lte-test-sinr-chunk-processor.h"
@@ -33,6 +33,7 @@
#include "ns3/lte-test-downlink-sinr.h"
#include <ns3/lte-control-messages.h>
#include "ns3/lte-helper.h"
NS_LOG_COMPONENT_DEFINE ("LteDownlinkSinrTest");
@@ -124,6 +125,7 @@ LteDownlinkDataSinrTestCase::~LteDownlinkDataSinrTestCase ()
void
LteDownlinkDataSinrTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
/**
* Instantiate a single receiving LteSpectrumPhy
*/
@@ -298,6 +300,7 @@ LteDownlinkCtrlSinrTestCase::DoRun (void)
/**
* Instantiate a single receiving LteSpectrumPhy
*/
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
Ptr<LteTestUePhy> uePhy = CreateObject<LteTestUePhy> (dlPhy, ulPhy);

View File

@@ -24,7 +24,7 @@
#include "ns3/string.h"
#include "ns3/double.h"
#include <ns3/enum.h>
#include "ns3/boolean.h"
#include "ns3/mobility-helper.h"
#include "ns3/lte-helper.h"
#include "ns3/ff-mac-scheduler.h"
@@ -114,6 +114,8 @@ LteInterferenceTestCase::~LteInterferenceTestCase ()
void
LteInterferenceTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();

View File

@@ -209,8 +209,8 @@ LenaPfFfMacSchedulerTestCase1::DoRun (void)
{
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false));
LogComponentDisableAll (LOG_LEVEL_ALL);
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);

View File

@@ -109,8 +109,8 @@ LenaPhyErrorModelTestCase::DoRun (void)
double ber = 0.03;
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (ber));
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (true));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (true));
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteUeRrc", LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbMac", LOG_LEVEL_ALL);

View File

@@ -191,8 +191,8 @@ LenaRrFfMacSchedulerTestCase::~LenaRrFfMacSchedulerTestCase ()
void
LenaRrFfMacSchedulerTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
Config::SetDefault ("ns3::LteAmc::Ber", DoubleValue (0.00005));
LogComponentDisableAll (LOG_LEVEL_ALL);
// LogComponentEnable ("LteEnbRrc", LOG_LEVEL_ALL);

View File

@@ -24,6 +24,7 @@
#include "ns3/string.h"
#include "ns3/double.h"
#include "ns3/enum.h"
#include "ns3/boolean.h"
#include "ns3/test.h"
#include "ns3/mobility-helper.h"
#include "ns3/lte-helper.h"
@@ -92,7 +93,8 @@ LteEnbAntennaTestCase::~LteEnbAntennaTestCase ()
void
LteEnbAntennaTestCase::DoRun (void)
{
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
// use 0dB Pathloss, since we are testing only the antenna gain

View File

@@ -109,8 +109,8 @@ LteEpcE2eDataTestCase::~LteEpcE2eDataTestCase ()
void
LteEpcE2eDataTestCase::DoRun ()
{
Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false));
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<EpcHelper> epcHelper = CreateObject<EpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);