5G-LENA nr-v3.3-159-ga6832aa7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-phy.cc
1// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#define NS_LOG_APPEND_CONTEXT \
6 do \
7 { \
8 std::clog << " [ CellId " << GetCellId() << ", bwpId " << GetBwpId() << "] "; \
9 } while (false);
10
11#include "nr-phy.h"
12
13#include "beam-manager.h"
14#include "nr-net-device.h"
15#include "nr-spectrum-phy.h"
16
17#include "ns3/boolean.h"
18#include "ns3/pointer.h"
19#include "ns3/uniform-planar-array.h"
20
21#include <algorithm>
22
23namespace ns3
24{
25
26NS_LOG_COMPONENT_DEFINE("NrPhy");
27
28NS_OBJECT_ENSURE_REGISTERED(NrPhy);
29
30/* SAP */
31class NrMemberPhySapProvider : public NrPhySapProvider
32{
33 public:
34 NrMemberPhySapProvider(NrPhy* phy);
35
36 void SendMacPdu(const Ptr<Packet>& p,
37 const SfnSf& sfn,
38 uint8_t symStart,
39 uint16_t rnti) override;
40
41 void SendControlMessage(Ptr<NrControlMessage> msg) override;
42
43 void SendRachPreamble(uint8_t PreambleId, uint8_t Rnti) override;
44
45 void SetSlotAllocInfo(const SlotAllocInfo& slotAllocInfo) override;
46
47 BeamId GetBeamId(uint8_t rnti) const override;
48
49 Ptr<const SpectrumModel> GetSpectrumModel() override;
50
51 void NotifyConnectionSuccessful() override;
52
53 uint16_t GetBwpId() const override;
54
55 uint16_t GetCellId() const override;
56
57 uint32_t GetSymbolsPerSlot() const override;
58
59 Time GetSlotPeriod() const override;
60
61 uint32_t GetRbNum() const override;
62
63 private:
64 NrPhy* m_phy;
65};
66
67NrMemberPhySapProvider::NrMemberPhySapProvider(NrPhy* phy)
68 : m_phy(phy)
69{
70 // Nothing more to do
71}
72
73void
74NrMemberPhySapProvider::SendMacPdu(const Ptr<Packet>& p,
75 const SfnSf& sfn,
76 uint8_t symStart,
77 uint16_t rnti)
78{
79 m_phy->SetMacPdu(p, sfn, symStart, rnti);
80}
81
82void
83NrMemberPhySapProvider::SendControlMessage(Ptr<NrControlMessage> msg)
84{
85 m_phy->EnqueueCtrlMessage(msg); // May need to change
86}
87
88void
89NrMemberPhySapProvider::SendRachPreamble(uint8_t PreambleId, uint8_t Rnti)
90{
91 m_phy->SendRachPreamble(PreambleId, Rnti);
92}
93
94void
95NrMemberPhySapProvider::SetSlotAllocInfo(const SlotAllocInfo& slotAllocInfo)
96{
97 m_phy->PushBackSlotAllocInfo(slotAllocInfo);
98}
99
100BeamId
101NrMemberPhySapProvider::GetBeamId(uint8_t rnti) const
102{
103 return m_phy->GetBeamId(rnti);
104}
105
106Ptr<const SpectrumModel>
107NrMemberPhySapProvider::GetSpectrumModel()
108{
109 return m_phy->GetSpectrumModel();
110}
111
112void
113NrMemberPhySapProvider::NotifyConnectionSuccessful()
114{
115 m_phy->NotifyConnectionSuccessful();
116}
117
118uint16_t
119NrMemberPhySapProvider::GetBwpId() const
120{
121 return m_phy->GetBwpId();
122}
123
124uint16_t
125NrMemberPhySapProvider::GetCellId() const
126{
127 return m_phy->GetCellId();
128}
129
130uint32_t
131NrMemberPhySapProvider::GetSymbolsPerSlot() const
132{
133 return m_phy->GetSymbolsPerSlot();
134}
135
136Time
137NrMemberPhySapProvider::GetSlotPeriod() const
138{
139 return m_phy->GetSlotPeriod();
140}
141
142uint32_t
143NrMemberPhySapProvider::GetRbNum() const
144{
145 return m_phy->GetRbNum();
146}
147
148/* ======= */
149
150TypeId
151NrPhy::GetTypeId()
152{
153 static TypeId tid = TypeId("ns3::NrPhy")
154 .SetParent<Object>()
155 .AddAttribute("NrSpectrumPhy",
156 "NrSpectrumPhy instance",
157 PointerValue(),
158 MakePointerAccessor(&NrPhy::m_spectrumPhy),
159 MakePointerChecker<NrSpectrumPhy>());
160
161 return tid;
162}
163
164std::vector<int>
165NrPhy::FromRBGBitmaskToRBAssignment(const std::vector<bool> rbgBitmask) const
166{
167 std::vector<int> ret;
168
169 for (uint32_t i = 0; i < rbgBitmask.size(); ++i)
170 {
171 if (rbgBitmask.at(i) == 1)
172 {
173 for (uint32_t k = 0; k < GetNumRbPerRbg(); ++k)
174 {
175 ret.push_back((i * GetNumRbPerRbg()) + k);
176 }
177 }
178 }
179
180 NS_ASSERT(static_cast<uint32_t>(std::count(rbgBitmask.begin(), rbgBitmask.end(), 1) *
181 GetNumRbPerRbg()) == ret.size());
182 return ret;
183}
184
185NrPhy::NrPhy()
186 : m_currSlotAllocInfo(SfnSf(0, 0, 0, 0)),
187 m_tbDecodeLatencyUs(100.0)
188{
189 NS_LOG_FUNCTION(this);
190 m_phySapProvider = new NrMemberPhySapProvider(this);
191}
192
194{
195 NS_LOG_FUNCTION(this);
196}
197
198void
200{
201 NS_LOG_FUNCTION(this);
202 m_slotAllocInfo.clear();
203 m_controlMessageQueue.clear();
204 m_packetBurstMap.clear();
205 m_ctrlMsgs.clear();
206 m_tddPattern.clear();
207 m_netDevice = nullptr;
208 if (m_spectrumPhy)
209 {
210 m_spectrumPhy->Dispose();
211 }
212 m_spectrumPhy = nullptr;
213 delete m_phySapProvider;
214}
215
216void
218{
219 NS_LOG_FUNCTION(this);
220 if (m_spectrumPhy)
221 {
222 m_spectrumPhy->Initialize();
223 }
224}
225
226void
227NrPhy::SetDevice(Ptr<NrNetDevice> d)
228{
229 NS_LOG_FUNCTION(this);
230 m_netDevice = d;
231}
232
233void
235{
236 NS_LOG_FUNCTION(this);
237 NS_ABORT_IF(m_centralFrequency >= 0.0);
238 m_centralFrequency = f;
239}
240
241void
242NrPhy::SetChannelBandwidth(uint16_t channelBandwidth)
243{
244 NS_LOG_FUNCTION(this);
245
246 NS_LOG_DEBUG("SetChannelBandwidth called with channel bandwidth value: "
247 << channelBandwidth * 100 * 1000
248 << "Hz, "
249 "and the previous value of channel bandwidth was: "
250 << GetChannelBandwidth() << " Hz");
251
252 if (m_channelBandwidth != channelBandwidth)
253 {
254 m_channelBandwidth = channelBandwidth;
255 // number of RB and noise PSD must be updated when bandwidth or numerology gets changed
257 }
258}
259
260void
261NrPhy::SetNumerology(uint16_t numerology)
262{
263 NS_LOG_FUNCTION(this);
264 m_numerology = numerology;
265 m_slotsPerSubframe = static_cast<uint16_t>(std::pow(2, numerology));
266 m_slotPeriod = Seconds(0.001 / m_slotsPerSubframe);
267 m_subcarrierSpacing = 15000 * static_cast<uint32_t>(std::pow(2, numerology));
268 m_symbolPeriod = (m_slotPeriod / m_symbolsPerSlot);
269
270 // number of RB and noise PSD must be updated when bandwidth or numerology gets changed
271 if (m_channelBandwidth != 0)
272 {
274
275 NS_LOG_INFO(" Numerology configured:"
276 << GetNumerology() << " slots per subframe: " << m_slotsPerSubframe
277 << " slot period:" << GetSlotPeriod() << " symbol period:" << GetSymbolPeriod()
278 << " subcarrier spacing: " << GetSubcarrierSpacing()
279 << " number of RBs: " << GetRbNum());
280 }
281 else
282 {
283 NS_LOG_DEBUG("Numerology is set, but the channel bandwidth not yet, so the number of RBs "
284 "cannot be updated now.");
285 }
286}
287
288uint16_t
290{
291 return m_numerology;
292}
293
294void
295NrPhy::SetSymbolsPerSlot(uint16_t symbolsPerSlot)
296{
297 NS_LOG_FUNCTION(this);
298 m_symbolsPerSlot = symbolsPerSlot;
299 m_symbolPeriod = (m_slotPeriod / m_symbolsPerSlot);
300}
301
302void
304{
305 m_rbOh = oh;
306}
307
308double
310{
311 return m_rbOh;
312}
313
314uint32_t
316{
317 return m_symbolsPerSlot;
318}
319
320Time
322{
323 NS_ABORT_IF(m_slotPeriod.IsNegative());
324 return m_slotPeriod;
325}
326
327void
328NrPhy::DoSetCellId(uint16_t cellId)
329{
330 NS_LOG_FUNCTION(this);
331 m_cellId = cellId;
332}
333
334void
335NrPhy::SendRachPreamble(uint32_t PreambleId, uint32_t Rnti)
336{
337 NS_LOG_FUNCTION(this); // overridden only in nr-ue-phy
338}
339
340void
341NrPhy::SetMacPdu(const Ptr<Packet>& p, const SfnSf& sfn, uint8_t symStart, uint16_t rnti)
342{
343 NS_LOG_FUNCTION(this);
344 NS_ASSERT(sfn.GetNumerology() == GetNumerology());
345 uint64_t key = sfn.GetEncodingWithSymStartRnti(symStart, rnti);
346 auto it = m_packetBurstMap.find(key);
347
348 if (it == m_packetBurstMap.end())
349 {
350 it = m_packetBurstMap.insert(std::make_pair(key, CreateObject<PacketBurst>())).first;
351 }
352 it->second->AddPacket(p);
353 NS_LOG_INFO("Adding a packet for the Packet Burst of " << sfn << " at sym " << +symStart
354 << std::endl);
355}
356
357void
359{
360 NS_LOG_FUNCTION(this);
361}
362
363Ptr<PacketBurst>
364NrPhy::GetPacketBurst(SfnSf sfn, uint8_t sym, uint16_t rnti)
365{
366 NS_LOG_FUNCTION(this);
367 NS_ASSERT(sfn.GetNumerology() == GetNumerology());
368 Ptr<PacketBurst> pburst;
369 auto it = m_packetBurstMap.find(sfn.GetEncodingWithSymStartRnti(sym, rnti));
370
371 if (it == m_packetBurstMap.end())
372 {
373 // For instance, this can happen with low BW and low MCS: The MAC
374 // ignores the txOpportunity.
375 NS_LOG_WARN("Packet burst not found for " << sfn << " at sym " << +sym);
376 return pburst;
377 }
378 else
379 {
380 pburst = it->second;
381 m_packetBurstMap.erase(it);
382 }
383 return pburst;
384}
385
386Ptr<SpectrumValue>
392
393Ptr<SpectrumValue>
394NrPhy::GetTxPowerSpectralDensity(const std::vector<int>& rbIndexVector)
395{
396 Ptr<const SpectrumModel> sm = GetSpectrumModel();
397
399 rbIndexVector,
400 sm,
401 m_powerAllocationType);
402}
403
404double
406{
407 NS_LOG_FUNCTION(this);
408 NS_ABORT_IF(m_centralFrequency < 0.0);
409 return m_centralFrequency;
410}
411
412std::string
413NrPhy::GetPattern(const std::vector<LteNrTddSlotType>& pattern)
414{
415 static std::unordered_map<LteNrTddSlotType, std::string, std::hash<int>> lookupTable = {
416 {LteNrTddSlotType::DL, "DL"},
417 {LteNrTddSlotType::UL, "UL"},
418 {LteNrTddSlotType::S, "S"},
419 {LteNrTddSlotType::F, "F"}};
420
421 std::stringstream ss;
422
423 for (const auto& v : pattern)
424 {
425 ss << lookupTable[v] << "|";
426 }
427
428 return ss.str();
429}
430
431void
432NrPhy::SetPowerAllocationType(enum NrSpectrumValueHelper::PowerAllocationType powerAllocationType)
433{
434 m_powerAllocationType = powerAllocationType;
435}
436
437enum NrSpectrumValueHelper::PowerAllocationType
439{
440 return m_powerAllocationType;
441}
442
443void
444NrPhy::EnqueueCtrlMessage(const Ptr<NrControlMessage>& m)
445{
446 NS_LOG_FUNCTION(this);
447
448 m_controlMessageQueue.at(m_controlMessageQueue.size() - 1).push_back(m);
449}
450
451void
452NrPhy::EnqueueCtrlMsgNow(const Ptr<NrControlMessage>& msg)
453{
454 NS_LOG_FUNCTION(this);
455
456 m_controlMessageQueue.at(0).push_back(msg);
457}
458
459void
460NrPhy::EnqueueCtrlMsgNow(const std::list<Ptr<NrControlMessage>>& listOfMsgs)
461{
462 for (const auto& msg : listOfMsgs)
463 {
464 m_controlMessageQueue.at(0).push_back(msg);
465 }
466}
467
468void
469NrPhy::EncodeCtrlMsg(const Ptr<NrControlMessage>& msg)
470{
471 NS_LOG_FUNCTION(this);
472 m_ctrlMsgs.push_back(msg);
473}
474
475bool
477{
479}
480
481bool
483{
485}
486
487bool
488NrPhy::HasDlSlot(const std::vector<LteNrTddSlotType>& pattern)
489{
490 for (const auto& v : pattern)
491 {
493 {
494 return true;
495 }
496 }
497 return false;
498}
499
500bool
501NrPhy::HasUlSlot(const std::vector<LteNrTddSlotType>& pattern)
502{
503 for (const auto& v : pattern)
504 {
506 {
507 return true;
508 }
509 }
510 return false;
511}
512
513uint32_t
515{
516 return m_rbNum;
517}
518
519uint32_t
521{
522 // m_channelBandwidth is in kHz * 100
523 return m_channelBandwidth * 1000 * 100;
524}
525
526uint32_t
528{
529 return m_subcarrierSpacing;
530}
531
532void
534{
535 NS_LOG_FUNCTION(this);
536 NS_ABORT_MSG_IF(m_channelBandwidth == 0, "Channel bandwidth not set");
537
538 double realBw = GetChannelBandwidth() * (1 - m_rbOh);
539 uint32_t rbWidth = m_subcarrierSpacing * NrSpectrumValueHelper::SUBCARRIERS_PER_RB;
540
541 NS_ABORT_MSG_IF(
542 rbWidth > realBw,
543 "Bandwidth and numerology not correctly set. Bandwidth after reduction of overhead is :"
544 << realBw << ", while RB width is: " << rbWidth);
545
546 m_rbNum = static_cast<uint32_t>(realBw / rbWidth);
547 NS_ASSERT(GetRbNum() > 0);
548
549 NS_LOG_INFO("Updated RbNum to " << GetRbNum());
550
551 NS_ASSERT(m_spectrumPhy);
552
553 // Update the noisePowerSpectralDensity, as it depends on m_rbNum
554 m_spectrumPhy->SetNoisePowerSpectralDensity(GetNoisePowerSpectralDensity());
555
556 // once we have set noise power spectral density which will
557 // initialize SpectrumModel of our SpectrumPhy, we can
558 // call AddRx function of the SpectrumChannel
559 if (m_spectrumPhy->GetSpectrumChannel())
560 {
561 m_spectrumPhy->GetSpectrumChannel()->AddRx(m_spectrumPhy);
562 }
563 else
564 {
565 NS_LOG_WARN("Working without channel (i.e., under test)");
566 }
567 NS_LOG_DEBUG("Noise Power Spectral Density updated");
568}
569
570bool
571NrPhy::IsTdd(const std::vector<LteNrTddSlotType>& pattern)
572{
573 bool anUl = false;
574 bool aDl = false;
575
576 for (const auto& v : pattern)
577 {
578 // An F slot: we are TDD
579 if (v == LteNrTddSlotType::F)
580 {
581 return true;
582 }
583
584 if (v == LteNrTddSlotType::UL)
585 {
586 anUl = true;
587 }
588 else if (v == LteNrTddSlotType::DL)
589 {
590 aDl = true;
591 }
592 }
593
594 return !(anUl ^ aDl);
595}
596
597void
599{
600 NS_LOG_FUNCTION(this);
601 m_controlMessageQueue.clear();
602
603 for (unsigned i = 0; i <= GetL1L2CtrlLatency(); i++)
604 {
605 m_controlMessageQueue.emplace_back();
606 }
607}
608
609std::list<Ptr<NrControlMessage>>
611{
612 NS_LOG_FUNCTION(this);
613 if (m_controlMessageQueue.empty())
614 {
615 std::list<Ptr<NrControlMessage>> emptylist;
616 return (emptylist);
617 }
618
619 if (!m_controlMessageQueue.at(0).empty())
620 {
621 std::list<Ptr<NrControlMessage>> ret = m_controlMessageQueue.front();
622 m_controlMessageQueue.erase(m_controlMessageQueue.begin());
623 std::list<Ptr<NrControlMessage>> newlist;
624 m_controlMessageQueue.push_back(newlist);
625 return (ret);
626 }
627 else
628 {
629 m_controlMessageQueue.erase(m_controlMessageQueue.begin());
630 std::list<Ptr<NrControlMessage>> newlist;
631 m_controlMessageQueue.push_back(newlist);
632 std::list<Ptr<NrControlMessage>> emptylist;
633 return (emptylist);
634 }
635}
636
637void
638NrPhy::InstallSpectrumPhy(const Ptr<NrSpectrumPhy>& spectrumPhy)
639{
640 NS_LOG_FUNCTION(this);
641 m_spectrumPhy = spectrumPhy;
642}
643
644void
645NrPhy::SetBwpId(uint16_t bwpId)
646{
647 m_bwpId = bwpId;
648}
649
650uint16_t
652{
653 return m_bwpId;
654}
655
656uint16_t
658{
659 return m_cellId;
660}
661
662uint32_t
664{
665 return 2;
666}
667
668Ptr<NrSpectrumPhy>
670{
671 return m_spectrumPhy;
672}
673
676{
677 NS_LOG_FUNCTION(this);
678 return m_phySapProvider;
679}
680
681void
683{
684 NS_LOG_FUNCTION(this);
685
686 NS_LOG_DEBUG("setting info for slot " << slotAllocInfo.m_sfnSf);
687
688 // That's not so complex, as the list would typically be of 2 or 3 elements.
689 bool updated = false;
690 for (auto& alloc : m_slotAllocInfo)
691 {
692 if (alloc.m_sfnSf == slotAllocInfo.m_sfnSf)
693 {
694 NS_LOG_DEBUG("Merging inside existing allocation");
695 alloc.Merge(slotAllocInfo);
696 updated = true;
697 break;
698 }
699 }
700 if (!updated)
701 {
702 m_slotAllocInfo.push_back(slotAllocInfo);
703 m_slotAllocInfo.sort();
704 NS_LOG_DEBUG("Pushing allocation at the end of the list");
705 }
706
707 std::stringstream output;
708
709 for (const auto& alloc : m_slotAllocInfo)
710 {
711 output << alloc;
712 }
713 NS_LOG_DEBUG(output.str());
714}
715
716void
717NrPhy::PushFrontSlotAllocInfo(const SfnSf& newSfnSf, const SlotAllocInfo& slotAllocInfo)
718{
719 NS_LOG_FUNCTION(this);
720
721 m_slotAllocInfo.push_front(slotAllocInfo);
722 SfnSf currentSfn = newSfnSf;
723 std::unordered_map<uint64_t, Ptr<PacketBurst>>
724 newBursts; // map between new sfn and the packet burst
725 std::unordered_map<uint64_t, uint64_t> sfnMap; // map between new and old sfn, for debugging
726
727 // all the slot allocations (and their packet burst) have to be "adjusted":
728 // directly modify the sfn for the allocation, and temporarily store the
729 // burst (along with the new sfn) into newBursts.
730 for (auto it = m_slotAllocInfo.begin(); it != m_slotAllocInfo.end(); ++it)
731 {
732 auto slotSfn = it->m_sfnSf;
733 for (const auto& alloc : it->m_varTtiAllocInfo)
734 {
735 if (alloc.m_dci->m_type == DciInfoElementTdma::DATA)
736 {
737 Ptr<PacketBurst> pburst =
738 GetPacketBurst(slotSfn, alloc.m_dci->m_symStart, alloc.m_dci->m_rnti);
739 if (pburst && pburst->GetNPackets() > 0)
740 {
741 auto newKey = currentSfn.GetEncodingWithSymStartRnti(alloc.m_dci->m_symStart,
742 alloc.m_dci->m_rnti);
743 auto oldKey = it->m_sfnSf.GetEncodingWithSymStartRnti(alloc.m_dci->m_symStart,
744 alloc.m_dci->m_rnti);
745 newBursts.insert({newKey, pburst});
746 sfnMap.insert({newKey, oldKey});
747 }
748 else
749 {
750 NS_LOG_INFO("No packet burst found for " << slotSfn);
751 }
752 }
753 }
754
755 NS_LOG_INFO("Set slot allocation for " << it->m_sfnSf << " to " << currentSfn);
756 it->m_sfnSf = currentSfn;
757 currentSfn.Add(1);
758 }
759
760 for (const auto& burstPair : newBursts)
761 {
762 SfnSf old;
763 SfnSf latest;
764 ns3::SfnSf::Decode(sfnMap.at(burstPair.first));
765 ns3::SfnSf::Decode(burstPair.first);
766 m_packetBurstMap.insert(std::make_pair(burstPair.first, burstPair.second));
767 NS_LOG_INFO("PacketBurst with " << burstPair.second->GetNPackets() << "packets for SFN "
768 << old << " now moved to SFN " << latest);
769 }
770}
771
772bool
774{
775 NS_LOG_FUNCTION(this);
776 NS_ASSERT(retVal.GetNumerology() == GetNumerology());
777 for (const auto& alloc : m_slotAllocInfo)
778 {
779 if (alloc.m_sfnSf == retVal)
780 {
781 return true;
782 }
783 }
784 return false;
785}
786
789{
790 NS_LOG_FUNCTION(this);
791 SlotAllocInfo ret = *m_slotAllocInfo.begin();
792 m_slotAllocInfo.erase(m_slotAllocInfo.begin());
793 return ret;
794}
795
798{
799 NS_LOG_FUNCTION(" slot " << sfnsf);
800 NS_ASSERT(sfnsf.GetNumerology() == GetNumerology());
801
802 for (auto allocIt = m_slotAllocInfo.begin(); allocIt != m_slotAllocInfo.end(); ++allocIt)
803 {
804 if (allocIt->m_sfnSf == sfnsf)
805 {
806 SlotAllocInfo ret = *allocIt;
807 m_slotAllocInfo.erase(allocIt);
808 return ret;
809 }
810 }
811
812 NS_FATAL_ERROR("Didn't found the slot");
813 return SlotAllocInfo(sfnsf);
814}
815
818{
819 NS_LOG_FUNCTION(this);
820 NS_ASSERT(sfnsf.GetNumerology() == GetNumerology());
821 for (auto& alloc : m_slotAllocInfo)
822 {
823 if (alloc.m_sfnSf == sfnsf)
824 {
825 return alloc;
826 }
827 }
828
829 NS_FATAL_ERROR("Didn't found the slot");
830}
831
832size_t
834{
835 NS_LOG_FUNCTION(this);
836 return m_slotAllocInfo.size();
837}
838
839bool
841{
842 NS_LOG_FUNCTION(this);
843 return m_controlMessageQueue.empty() || m_controlMessageQueue.at(0).empty();
844}
845
846Ptr<const SpectrumModel>
848{
849 NS_LOG_FUNCTION(this);
850 NS_ABORT_MSG_IF(GetSubcarrierSpacing() < 0.0, "Set a valid numerology");
851 NS_ABORT_MSG_IF(m_channelBandwidth == 0, "Channel bandwidth not set.");
855}
856
857Time
859{
860 NS_LOG_FUNCTION(this);
861 return m_symbolPeriod;
862}
863
864void
866{
867 m_noiseFigure = d;
868 // as we don't know the order in which will be configured the parameters
869 if (m_spectrumPhy && GetRbNum())
870 {
871 m_spectrumPhy->SetNoisePowerSpectralDensity(GetNoisePowerSpectralDensity());
872 }
873}
874
875double
877{
878 return m_noiseFigure;
879}
880
881void
883{
884 m_tbDecodeLatencyUs = us;
885}
886
887Time
889{
890 return m_tbDecodeLatencyUs;
891}
892
893} // namespace ns3
Time GetSymbolPeriod() const
Get SymbolPeriod.
Definition nr-phy.cc:858
Ptr< NrSpectrumPhy > m_spectrumPhy
Pointer to the (owned) spectrum phy.
Definition nr-phy.h:558
SlotAllocInfo RetrieveSlotAllocInfo()
Get the head for the slot allocation info, and delete it from the internal list.
Definition nr-phy.cc:788
uint16_t GetCellId() const
Definition nr-phy.cc:657
uint16_t GetNumerology() const
Get the configured numerology.
Definition nr-phy.cc:289
Ptr< NrSpectrumPhy > GetSpectrumPhy() const
Retrieve the SpectrumPhy pointer.
Definition nr-phy.cc:669
void EncodeCtrlMsg(const Ptr< NrControlMessage > &msg)
Take the control messages, and put it in a list that will be sent at the first occasion.
Definition nr-phy.cc:469
void SetNumerology(uint16_t numerology)
Set GNB or UE numerology.
Definition nr-phy.cc:261
virtual void SetTbDecodeLatency(const Time &us)
Configures TB decode latency.
Definition nr-phy.cc:882
std::list< Ptr< NrControlMessage > > m_ctrlMsgs
CTRL messages to be sent.
Definition nr-phy.h:571
void DoInitialize() override
DoInitialize method inherited from Object.
Definition nr-phy.cc:217
void SetRbOverhead(double oh)
Set the bandwidth overhead for calculating the usable RB number.
Definition nr-phy.cc:303
void PushBackSlotAllocInfo(const SlotAllocInfo &slotAllocInfo)
Store the slot allocation info.
Definition nr-phy.cc:682
void NotifyConnectionSuccessful()
Notify PHY about the successful RRC connection establishment.
Definition nr-phy.cc:358
void InstallCentralFrequency(double f)
Install the PHY over a particular central frequency.
Definition nr-phy.cc:234
~NrPhy() override
~NrPhy
Definition nr-phy.cc:193
Ptr< PacketBurst > GetPacketBurst(SfnSf sf, uint8_t sym, uint16_t rnti)
Retrieve the PacketBurst at the slot/symbol specified.
Definition nr-phy.cc:364
void SetPowerAllocationType(enum NrSpectrumValueHelper::PowerAllocationType powerAllocationType)
Set power allocation type. There are currently supported two types: one that distributes uniformly en...
Definition nr-phy.cc:432
static std::string GetPattern(const std::vector< LteNrTddSlotType > &pattern)
Get a string representation of a pattern.
Definition nr-phy.cc:413
void InstallSpectrumPhy(const Ptr< NrSpectrumPhy > &spectrumPhy)
Set the SpectrumPhy associated with this PHY.
Definition nr-phy.cc:638
Time GetSlotPeriod() const
Get the slot period.
Definition nr-phy.cc:321
virtual std::list< Ptr< NrControlMessage > > PopCurrentSlotCtrlMsgs()
Extract and return the message list that is at the beginning of the queue.
Definition nr-phy.cc:610
virtual void SendRachPreamble(uint32_t PreambleId, uint32_t Rnti)
Send the RachPreamble.
Definition nr-phy.cc:335
enum NrSpectrumValueHelper::PowerAllocationType GetPowerAllocationType() const
Get the power allocation type.
Definition nr-phy.cc:438
void EnqueueCtrlMsgNow(const Ptr< NrControlMessage > &msg)
Enqueue a CTRL message without considering L1L2CtrlLatency.
Definition nr-phy.cc:452
uint32_t GetChannelBandwidth() const
Retrieve the channel bandwidth, in Hz.
Definition nr-phy.cc:520
virtual Time GetTbDecodeLatency() const
Returns Transport Block decode latency.
Definition nr-phy.cc:888
SlotAllocInfo & PeekSlotAllocInfo(const SfnSf &sfnsf)
Peek the SlotAllocInfo at the SfnSf specified.
Definition nr-phy.cc:817
double GetCentralFrequency() const
Retrieve the frequency (in Hz) of this PHY's channel.
Definition nr-phy.cc:405
void SetMacPdu(const Ptr< Packet > &p, const SfnSf &sfn, uint8_t symStart, uint16_t rnti)
Store a MAC PDU.
Definition nr-phy.cc:341
double m_noiseFigure
Noise figure (attribute)
Definition nr-phy.h:561
void SetSymbolsPerSlot(uint16_t symbolsPerSlot)
Set the number of symbol per slot.
Definition nr-phy.cc:295
void SetDevice(Ptr< NrNetDevice > d)
Set the owner device.
Definition nr-phy.cc:227
Ptr< const SpectrumModel > GetSpectrumModel()
Get the spectrum model of the PHY.
Definition nr-phy.cc:847
size_t SlotAllocInfoSize() const
Retrieve the size of the SlotAllocInfo list.
Definition nr-phy.cc:833
double GetNoiseFigure() const
Get the NoiseFigure value.
Definition nr-phy.cc:876
void SetNoiseFigure(double d)
Set the NoiseFigure value.
Definition nr-phy.cc:865
double m_txPower
Transmission power (attribute)
Definition nr-phy.h:560
void InitializeMessageList()
Initialize the message list.
Definition nr-phy.cc:598
void DoUpdateRbNum()
Update the number of RB. Usually called after bandwidth changes.
Definition nr-phy.cc:533
Ptr< SpectrumValue > GetTxPowerSpectralDensity(const std::vector< int > &rbIndexVector)
Definition nr-phy.cc:394
void SetChannelBandwidth(uint16_t bandwidth)
Function to set the channel bandwidth, used also by child classes, i.e., see functions DoSetDlBanwidt...
Definition nr-phy.cc:242
uint16_t GetBwpId() const
Definition nr-phy.cc:651
void PushFrontSlotAllocInfo(const SfnSf &newSfnSf, const SlotAllocInfo &slotAllocInfo)
Store the slot allocation info at the front.
Definition nr-phy.cc:717
Ptr< NrNetDevice > m_netDevice
Pointer to the owner netDevice.
Definition nr-phy.h:557
uint32_t GetL1L2CtrlLatency() const
Definition nr-phy.cc:663
bool HasDlSlot() const
Go through the current pattern and see if at least one slot is DL, F or S.
Definition nr-phy.cc:476
bool SlotAllocInfoExists(const SfnSf &sfnsf) const
Check if the SlotAllocationInfo for that slot exists.
Definition nr-phy.cc:773
std::unordered_map< uint64_t, Ptr< PacketBurst > > m_packetBurstMap
Map between SfnSf and PacketBurst.
Definition nr-phy.h:564
uint32_t GetSubcarrierSpacing() const
Retrieve the subcarrier spacing in Hz. Subcarrier spacing is updated when the numerology is being upd...
Definition nr-phy.cc:527
uint32_t GetSymbolsPerSlot() const
Get the number of symbols in a slot.
Definition nr-phy.cc:315
std::vector< LteNrTddSlotType > m_tddPattern
Pattern.
Definition nr-phy.h:573
Ptr< SpectrumValue > GetNoisePowerSpectralDensity()
Create Noise Power Spectral density.
Definition nr-phy.cc:387
bool IsCtrlMsgListEmpty() const
Check if there are no control messages queued for this slot.
Definition nr-phy.cc:840
NrPhySapProvider * m_phySapProvider
Pointer to the MAC.
Definition nr-phy.h:568
double GetRbOverhead() const
Get the bandwidth overhead used when calculating the usable RB number.
Definition nr-phy.cc:309
bool HasUlSlot() const
Go through the current pattern and see if at least one slot is UL, F or S.
Definition nr-phy.cc:482
void SetBwpId(uint16_t bwpId)
Set the bwp id. Called by helper.
Definition nr-phy.cc:645
uint32_t GetRbNum() const
Get the number of Resource block configured.
Definition nr-phy.cc:514
void EnqueueCtrlMessage(const Ptr< NrControlMessage > &m)
Enqueue a ctrl message, keeping in consideration L1L2CtrlDelay.
Definition nr-phy.cc:444
static bool IsTdd(const std::vector< LteNrTddSlotType > &pattern)
Check if a pattern is TDD.
Definition nr-phy.cc:571
NrPhySapProvider * GetPhySapProvider()
Retrieve a pointer to an instance of NrPhySapProvider.
Definition nr-phy.cc:675
void DoDispose() override
DoDispose method inherited from Object.
Definition nr-phy.cc:199
void DoSetCellId(uint16_t cellId)
Set the cell ID.
Definition nr-phy.cc:328
SAP interface between the MAC and the PHY.
Definition nr-phy-sap.h:36
static Ptr< const SpectrumModel > GetSpectrumModel(uint32_t numRbs, double centerFrequency, double subcarrierSpacing)
Creates or obtains from a global map a spectrum model with a given number of RBs, center frequency an...
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(double noiseFigure, const Ptr< const SpectrumModel > &spectrumModel)
Create a SpectrumValue that models the power spectral density of AWGN.
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double powerTx, const std::vector< int > &rbIndexVector, const Ptr< const SpectrumModel > &txSm, enum PowerAllocationType allocationType)
Create SpectrumValue that will represent transmit power spectral density, and assuming that all RBs a...
static const uint8_t SUBCARRIERS_PER_RB
subcarriers per resource block
The SfnSf class.
Definition sfnsf.h:32
static SfnSf Decode(uint64_t sfn)
Decode the parameter and return a SfnSf.
Definition sfnsf.cc:91
uint8_t GetNumerology() const
GetNumerology.
Definition sfnsf.cc:182
void Add(uint32_t slotN)
Add to this SfnSf a number of slot indicated by the first parameter.
Definition sfnsf.cc:117
uint64_t GetEncodingWithSymStartRnti(uint8_t symStart, uint16_t rnti) const
Get an encoding of frame & slot number, plus starting OFDM symbol and RNTI.
Definition sfnsf.cc:42
@ F
DL CTRL + DL DATA + UL DATA + UL CTRL.
@ S
DL CTRL + DL DATA + UL CTRL.
@ DL
DL CTRL + DL DATA.
@ UL
UL DATA + UL CTRL.
@ DATA
Used for DL/UL DATA.
The SlotAllocInfo struct.
SfnSf m_sfnSf
SfnSf of this allocation.