diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index 435ed8668..ed4799109 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -410,7 +410,7 @@ LteHelper::InstallSingleUeDevice (Ptr n) Ptr phy = CreateObject (dlPhy, ulPhy); - Ptr pCtrl = Create (phy->GetObject ()); + Ptr pCtrl = Create (phy->GetObject (), dlPhy); dlPhy->AddCtrlSinrChunkProcessor (pCtrl); Ptr pData = Create (dlPhy); diff --git a/src/lte/model/lte-mi-error-model.cc b/src/lte/model/lte-mi-error-model.cc index 7c28d7516..e0f6dbaf3 100644 --- a/src/lte/model/lte-mi-error-model.cc +++ b/src/lte/model/lte-mi-error-model.cc @@ -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& 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_axis[MI_MAP_QPSK_SIZE-1]) + { + MI = 1; + } + else + { + NS_ASSERT_MSG (tr MI_map_qpsk[MI_MAP_QPSK_SIZE-1]) + { + esinr = MI_map_qpsk_axis[MI_MAP_QPSK_SIZE-1]; + } + else + { + NS_ASSERT_MSG (j PdcchPcfichBlerCurveXaxis[PDCCH_PCFICH_CURVE_SIZE-1]) + { + errorRate = 0.0; + } + else + { + NS_ASSERT_MSG (i& 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& 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: diff --git a/src/lte/model/lte-sinr-chunk-processor.cc b/src/lte/model/lte-sinr-chunk-processor.cc index 8f6acea10..8dfa1a2fa 100644 --- a/src/lte/model/lte-sinr-chunk-processor.cc +++ b/src/lte/model/lte-sinr-chunk-processor.cc @@ -36,12 +36,22 @@ LteSinrChunkProcessor::~LteSinrChunkProcessor () LteCtrlSinrChunkProcessor::LteCtrlSinrChunkProcessor (Ptr p) - : m_phy (p) + : m_phy (p), + m_spectrumPhy (0) { NS_LOG_FUNCTION (this << p); NS_ASSERT (m_phy); } +LteCtrlSinrChunkProcessor::LteCtrlSinrChunkProcessor (Ptr p, Ptr 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 { diff --git a/src/lte/model/lte-sinr-chunk-processor.h b/src/lte/model/lte-sinr-chunk-processor.h index 4b8f48688..75f723657 100644 --- a/src/lte/model/lte-sinr-chunk-processor.h +++ b/src/lte/model/lte-sinr-chunk-processor.h @@ -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 p); + LteCtrlSinrChunkProcessor (Ptr p, Ptr s); virtual void Start (); virtual void EvaluateSinrChunk (const SpectrumValue& sinr, Time duration); virtual void End (); @@ -72,6 +74,7 @@ private: Ptr m_sumSinr; Time m_totDuration; Ptr m_phy; + Ptr m_spectrumPhy; }; diff --git a/src/lte/model/lte-spectrum-phy.cc b/src/lte/model/lte-spectrum-phy.cc index 311372b3d..5012358f2 100644 --- a/src/lte/model/lte-spectrum-phy.cc +++ b/src/lte/model/lte-spectrum-phy.cc @@ -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 ()) diff --git a/src/lte/model/lte-spectrum-phy.h b/src/lte/model/lte-spectrum-phy.h index d1610dfab..5381b889e 100644 --- a/src/lte/model/lte-spectrum-phy.h +++ b/src/lte/model/lte-spectrum-phy.h @@ -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 m_txModeGain; // duplicate value of LteUePhy diff --git a/src/lte/test/lte-test-downlink-sinr.cc b/src/lte/test/lte-test-downlink-sinr.cc index 75c59786b..fdeda8bfb 100644 --- a/src/lte/test/lte-test-downlink-sinr.cc +++ b/src/lte/test/lte-test-downlink-sinr.cc @@ -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 +#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 dlPhy = CreateObject (); Ptr ulPhy = CreateObject (); Ptr uePhy = CreateObject (dlPhy, ulPhy); diff --git a/src/lte/test/lte-test-interference.cc b/src/lte/test/lte-test-interference.cc index 944d5de0c..b43ce2863 100644 --- a/src/lte/test/lte-test-interference.cc +++ b/src/lte/test/lte-test-interference.cc @@ -24,7 +24,7 @@ #include "ns3/string.h" #include "ns3/double.h" #include - +#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 = CreateObject (); diff --git a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc index 4b368eb10..4525a557d 100644 --- a/src/lte/test/lte-test-pf-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-pf-ff-mac-scheduler.cc @@ -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); diff --git a/src/lte/test/lte-test-phy-error-model.cc b/src/lte/test/lte-test-phy-error-model.cc index f56b1d73f..3d1950892 100644 --- a/src/lte/test/lte-test-phy-error-model.cc +++ b/src/lte/test/lte-test-phy-error-model.cc @@ -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); diff --git a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc index 8f01655e9..eb900ff3a 100644 --- a/src/lte/test/lte-test-rr-ff-mac-scheduler.cc +++ b/src/lte/test/lte-test-rr-ff-mac-scheduler.cc @@ -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); diff --git a/src/lte/test/test-lte-antenna.cc b/src/lte/test/test-lte-antenna.cc index 0c3c8743e..be79aa9dc 100644 --- a/src/lte/test/test-lte-antenna.cc +++ b/src/lte/test/test-lte-antenna.cc @@ -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 = CreateObject (); // use 0dB Pathloss, since we are testing only the antenna gain diff --git a/src/lte/test/test-lte-epc-e2e-data.cc b/src/lte/test/test-lte-epc-e2e-data.cc index 63966c5d2..062df1b47 100644 --- a/src/lte/test/test-lte-epc-e2e-data.cc +++ b/src/lte/test/test-lte-epc-e2e-data.cc @@ -109,8 +109,8 @@ LteEpcE2eDataTestCase::~LteEpcE2eDataTestCase () void LteEpcE2eDataTestCase::DoRun () { - Config::SetDefault ("ns3::LteSpectrumPhy::PemEnabled", BooleanValue (false)); - Ptr lteHelper = CreateObject (); + Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false)); + Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false)); Ptr lteHelper = CreateObject (); Ptr epcHelper = CreateObject (); lteHelper->SetEpcHelper (epcHelper);