5#define NS_LOG_APPEND_CONTEXT \
8 std::clog << " [ CellId " << GetCellId() << ", bwpId " << GetBwpId() << "] "; \
11#include "nr-gnb-phy.h"
13#include "beam-manager.h"
14#include "nr-ch-access-manager.h"
15#include "nr-gnb-net-device.h"
16#include "nr-net-device.h"
17#include "nr-ue-net-device.h"
20#include <ns3/boolean.h>
21#include <ns3/double.h>
24#include <ns3/node-list.h>
26#include <ns3/object-vector.h>
27#include <ns3/pointer.h>
28#include <ns3/uinteger.h>
33#include <unordered_set>
38NS_LOG_COMPONENT_DEFINE(
"NrGnbPhy");
40NS_OBJECT_ENSURE_REGISTERED(NrGnbPhy);
46 NS_LOG_FUNCTION(
this);
57 NS_LOG_FUNCTION(
this);
58 delete m_gnbCphySapProvider;
66 TypeId(
"ns3::NrGnbPhy")
68 .AddConstructor<NrGnbPhy>()
69 .AddAttribute(
"RbOverhead",
70 "Overhead when calculating the usable RB number",
73 MakeDoubleChecker<double>(0, 0.5))
74 .AddAttribute(
"TxPower",
75 "Transmission power in dBm",
78 MakeDoubleChecker<double>())
81 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
82 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
83 "\"the difference in decibels (dB) between"
84 " the noise output of the actual receiver to the noise output of an "
85 " ideal receiver with the same overall gain and bandwidth when the receivers "
86 " are connected to sources at the standard noise temperature T0.\" "
87 "In this model, we consider T0 = 290K.",
90 MakeDoubleChecker<double>())
92 "PowerAllocationType",
93 "Defines the type of the power allocation. Currently are supported "
94 "two types: \"UniformPowerAllocBw\", which is a uniform power allocation over all "
95 "bandwidth (over all RBs), and \"UniformPowerAllocUsed\", which is a uniform "
96 "power allocation over used (active) RBs. By default is set a uniform power "
97 "allocation over used RBs .",
98 EnumValue(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED),
99 MakeEnumAccessor<NrSpectrumValueHelper::PowerAllocationType>(
102 MakeEnumChecker(NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_BW,
103 "UniformPowerAllocBw",
104 NrSpectrumValueHelper::UNIFORM_POWER_ALLOCATION_USED,
105 "UniformPowerAllocUsed"))
106 .AddAttribute(
"SpectrumPhy",
107 "The downlink NrSpectrumPhy associated to this NrPhy",
111 MakePointerChecker<NrSpectrumPhy>())
112 .AddTraceSource(
"UlSinrTrace",
113 "UL SINR statistics.",
114 MakeTraceSourceAccessor(&NrGnbPhy::m_ulSinrTrace),
115 "ns3::UlSinr::TracedCallback")
116 .AddTraceSource(
"GnbPhyRxedCtrlMsgsTrace",
117 "Gnb PHY Rxed Control Messages Traces.",
118 MakeTraceSourceAccessor(&NrGnbPhy::m_phyRxedCtrlMsgsTrace),
119 "ns3::NrPhyRxTrace::RxedGnbPhyCtrlMsgsTracedCallback")
120 .AddTraceSource(
"GnbPhyTxedCtrlMsgsTrace",
121 "Gnb PHY Txed Control Messages Traces.",
122 MakeTraceSourceAccessor(&NrGnbPhy::m_phyTxedCtrlMsgsTrace),
123 "ns3::NrPhyRxTrace::TxedGnbPhyCtrlMsgsTracedCallback")
124 .AddAttribute(
"N0Delay",
125 "Minimum processing delay needed to decode DL DCI and decode DL data",
128 MakeUintegerChecker<uint32_t>(0, 1))
129 .AddAttribute(
"N1Delay",
130 "Minimum processing delay (UE side) from the end of DL Data reception to "
131 "the earliest possible start of the corresponding ACK/NACK transmission",
134 MakeUintegerChecker<uint32_t>(0, 4))
135 .AddAttribute(
"N2Delay",
136 "Minimum processing delay needed to decode UL DCI and prepare UL data",
139 MakeUintegerChecker<uint32_t>(0, 4))
140 .AddAttribute(
"TbDecodeLatency",
141 "Transport block decode latency",
142 TimeValue(MicroSeconds(100)),
145 .AddAttribute(
"Numerology",
146 "The 3GPP numerology to be used",
149 MakeUintegerChecker<uint16_t>())
152 "Number of symbols in one slot",
155 MakeUintegerChecker<uint16_t>())
156 .AddAttribute(
"Pattern",
158 StringValue(
"F|F|F|F|F|F|F|F|F|F|"),
161 .AddTraceSource(
"SlotDataStats",
162 "Data statistics for the current slot: SfnSf, active UE, used RE, "
163 "used symbols, available RBs, available symbols, bwp ID, cell ID",
164 MakeTraceSourceAccessor(&NrGnbPhy::m_phySlotDataStats),
165 "ns3::NrGnbPhy::SlotStatsTracedCallback")
166 .AddTraceSource(
"SlotCtrlStats",
167 "Ctrl statistics for the current slot: SfnSf, active UE, used RE, "
168 "used symbols, available RBs, available symbols, bwp ID, cell ID",
169 MakeTraceSourceAccessor(&NrGnbPhy::m_phySlotCtrlStats),
170 "ns3::NrGnbPhy::SlotStatsTracedCallback")
173 "Resource Block used for data: SfnSf, symbol, RB PHY map, bwp ID, cell ID",
174 MakeTraceSourceAccessor(&NrGnbPhy::m_rbStatistics),
175 "ns3::NrGnbPhy::RBStatsTracedCallback");
188 return m_currentSlot;
198modulo(
int n, uint32_t m)
202 return static_cast<uint32_t
>(n) % m;
210 return static_cast<uint32_t
>(n);
228ReturnHarqSlot(
const std::vector<LteNrTddSlotType>& pattern, uint32_t pos, uint32_t n1)
230 int32_t k1 =
static_cast<int32_t
>(n1);
232 uint32_t index = modulo(
static_cast<int>(pos) + k1,
static_cast<uint32_t
>(pattern.size()));
237 index = modulo(
static_cast<int>(pos) + k1,
static_cast<uint32_t
>(pattern.size()));
238 NS_ASSERT(index < pattern.size());
246 uint32_t indexDci{0};
259ReturnDciSlot(
const std::vector<LteNrTddSlotType>& pattern, uint32_t pos, uint32_t n)
263 ret.indexDci = modulo(
static_cast<int>(pos) -
static_cast<int>(ret.k),
264 static_cast<uint32_t
>(pattern.size()));
269 ret.indexDci = modulo(
static_cast<int>(pos) -
static_cast<int>(ret.k),
270 static_cast<uint32_t
>(pattern.size()));
271 NS_ASSERT(ret.indexDci < pattern.size());
288GenerateDciMaps(
const std::vector<LteNrTddSlotType>& pattern,
289 std::map<uint32_t, std::vector<uint32_t>>* toSend,
290 std::map<uint32_t, std::vector<uint32_t>>* generate,
293 uint32_t l1l2CtrlLatency)
295 auto dciSlot = ReturnDciSlot(pattern, pos, n);
297 modulo(
static_cast<int>(dciSlot.indexDci) -
static_cast<int>(l1l2CtrlLatency),
298 static_cast<uint32_t
>(pattern.size()));
299 uint32_t kWithCtrlLatency =
static_cast<uint32_t
>(dciSlot.k) + l1l2CtrlLatency;
301 (*toSend)[dciSlot.indexDci].push_back(
static_cast<uint32_t
>(dciSlot.k));
302 (*generate)[indexGen].push_back(kWithCtrlLatency);
306NrGnbPhy::GenerateStructuresFromPattern(
const std::vector<LteNrTddSlotType>& pattern,
307 std::map<uint32_t, std::vector<uint32_t>>* toSendDl,
308 std::map<uint32_t, std::vector<uint32_t>>* toSendUl,
309 std::map<uint32_t, std::vector<uint32_t>>* generateDl,
310 std::map<uint32_t, std::vector<uint32_t>>* generateUl,
311 std::map<uint32_t, uint32_t>* dlHarqfbPosition,
315 uint32_t l1l2CtrlLatency)
317 const uint32_t n =
static_cast<uint32_t
>(pattern.size());
320 std::vector<LteNrTddSlotType> fddGenerationPattern;
330 const std::vector<LteNrTddSlotType>* generationPattern;
334 generationPattern = &pattern;
338 generationPattern = &fddGenerationPattern;
341 for (uint32_t i = 0; i < n; i++)
345 GenerateDciMaps(*generationPattern, toSendUl, generateUl, i, n2, l1l2CtrlLatency);
350 GenerateDciMaps(*generationPattern, toSendDl, generateDl, i, n0, l1l2CtrlLatency);
352 int32_t k1 = ReturnHarqSlot(*generationPattern, i, n1);
353 (*dlHarqfbPosition).insert(std::make_pair(i, k1));
357 GenerateDciMaps(*generationPattern, toSendDl, generateDl, i, n0, l1l2CtrlLatency);
358 GenerateDciMaps(*generationPattern, toSendUl, generateUl, i, n2, l1l2CtrlLatency);
360 int32_t k1 = ReturnHarqSlot(*generationPattern, i, n1);
361 (*dlHarqfbPosition).insert(std::make_pair(i, k1));
386 for (
auto& list : (*generateUl))
388 std::stable_sort(list.second.begin(), list.second.end());
391 for (
auto& list : (*generateDl))
393 std::stable_sort(list.second.begin(), list.second.end());
398NrGnbPhy::PushDlAllocation(
const SfnSf& sfnSf)
const
400 NS_LOG_FUNCTION(
this);
401 NS_ASSERT(m_phySapUser);
404 VarTtiAllocInfo dlCtrlVarTti(dci);
406 SlotAllocInfo slotAllocInfo = SlotAllocInfo(sfnSf);
408 slotAllocInfo.m_numSymAlloc = dlCtrlVarTti.m_dci->m_numSym;
410 slotAllocInfo.m_varTtiAllocInfo.emplace_back(dlCtrlVarTti);
416NrGnbPhy::PushUlAllocation(
const SfnSf& sfnSf)
const
418 NS_LOG_FUNCTION(
this);
419 NS_ASSERT(m_phySapUser);
422 VarTtiAllocInfo ulCtrlVarTti(dci);
424 SlotAllocInfo slotAllocInfo = SlotAllocInfo(sfnSf);
426 slotAllocInfo.m_numSymAlloc = ulCtrlVarTti.m_dci->m_numSym;
428 slotAllocInfo.m_varTtiAllocInfo.emplace_back(ulCtrlVarTti);
434NrGnbPhy::SetTddPattern(
const std::vector<LteNrTddSlotType>& pattern)
436 NS_LOG_FUNCTION(
this);
438 std::stringstream ss;
440 for (
const auto& v : pattern)
444 NS_LOG_INFO(
"Set pattern : " << ss.str());
448 m_generateDl.clear();
449 m_generateUl.clear();
452 m_dlHarqfbPosition.clear();
454 GenerateStructuresFromPattern(pattern,
469 NS_LOG_FUNCTION(
this);
470 Simulator::ScheduleWithContext(nodeId,
472 &NrGnbPhy::StartEventLoop,
480NrGnbPhy::StartEventLoop(uint16_t frame, uint8_t subframe, uint16_t slot)
482 NS_LOG_FUNCTION(
this);
483 NS_LOG_DEBUG(
"PHY starting. Configuration: "
485 <<
"\t TxPower: " <<
m_txPower <<
" dBm" << std::endl
487 <<
"\t N0: " << m_n0Delay << std::endl
488 <<
"\t N1: " << m_n1Delay << std::endl
489 <<
"\t N2: " << m_n2Delay << std::endl
494 <<
"\t Pattern: " <<
GetPattern() << std::endl
495 <<
"Attached to physical channel: " << std::endl
501 StartSlot(startSlot);
507 NS_LOG_FUNCTION(
this);
508 m_gnbCphySapUser = s;
514 NS_LOG_FUNCTION(
this);
515 return m_gnbCphySapProvider;
560 NS_LOG_FUNCTION(
this);
562 for (
const auto& i : m_deviceMap)
564 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(i);
565 uint64_t ueRnti = (DynamicCast<NrUePhy>(ueDev->GetPhy(
GetBwpId())))->GetRnti();
579 NS_LOG_FUNCTION(
this);
580 NS_ASSERT(cam !=
nullptr);
582 m_cam->SetAccessGrantedCallback(
583 std::bind(&NrGnbPhy::ChannelAccessGranted,
this, std::placeholders::_1));
584 m_cam->SetAccessDeniedCallback(std::bind(&NrGnbPhy::ChannelAccessLost,
this));
587Ptr<NrChAccessManager>
590 NS_LOG_FUNCTION(
this);
618 auto scaling = double(rbIndexVector.size()) / double(nTotalAllocRbs);
619 for (
auto it = txPsd->ValuesBegin(); it != txPsd->ValuesEnd(); it++)
635 NS_LOG_FUNCTION(
this);
639 Ptr<NrMibMessage> mibMsg = Create<NrMibMessage>();
648 NS_LOG_FUNCTION(
this);
649 Ptr<NrSib1Message> msg = Create<NrSib1Message>();
650 msg->SetSib1(m_sib1);
656NrGnbPhy::CallMacForSlotIndication(
const SfnSf& currentSlot)
658 NS_LOG_FUNCTION(
this);
659 NS_ASSERT(!m_generateDl.empty() || !m_generateUl.empty());
663 uint64_t currentSlotN = currentSlot.Normalize() %
m_tddPattern.size();
665 NS_LOG_DEBUG(
"Start Slot " << currentSlot <<
". In position " << currentSlotN
666 <<
" there is a slot of type " <<
m_tddPattern[currentSlotN]);
668 for (
const auto& k2WithLatency : m_generateUl[currentSlotN])
670 SfnSf targetSlot = currentSlot;
671 targetSlot.Add(k2WithLatency);
673 uint64_t pos = targetSlot.Normalize() %
m_tddPattern.size();
675 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" generate UL for " << targetSlot
681 for (
const auto& k0WithLatency : m_generateDl[currentSlotN])
683 SfnSf targetSlot = currentSlot;
684 targetSlot.Add(k0WithLatency);
686 uint64_t pos = targetSlot.Normalize() %
m_tddPattern.size();
688 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" generate DL for " << targetSlot
696NrGnbPhy::StartSlot(
const SfnSf& startSlot)
698 NS_LOG_FUNCTION(
this);
699 NS_ASSERT(m_channelStatus != TO_LOSE);
701 m_currentSlot = startSlot;
702 m_lastSlotStart = Simulator::Now();
704 Simulator::Schedule(
GetSlotPeriod(), &NrGnbPhy::EndSlot,
this);
714 NS_LOG_WARN(
"No allocation for the current slot. Using an empty one");
720 if (m_currentSlot.
GetSlot() == 0)
722 bool mibOrSib =
false;
735 VarTtiAllocInfo dlCtrlSlot(m_phySapUser->
GetDlCtrlDci());
742 if (m_channelStatus == GRANTED)
744 NS_LOG_INFO(
"Channel granted");
745 CallMacForSlotIndication(m_currentSlot);
750 bool hasUlDci =
false;
751 SfnSf ulSfn = m_currentSlot;
759 hasUlDci = ulSlot.ContainsDataAllocation() || ulSlot.ContainsUlCtrlAllocation() ||
760 ulSlot.ContainsUlMsg3Allocation();
771 if (m_channelStatus == NONE)
773 NS_LOG_INFO(
"Channel not granted, request the channel");
774 m_channelStatus = REQUESTED;
775 m_cam->RequestAccess();
776 if (m_channelStatus == GRANTED)
780 NS_LOG_INFO(
"Channel granted; asking MAC for SlotIndication for the future and "
781 "then start the slot");
782 CallMacForSlotIndication(m_currentSlot);
790 auto newSfnSf = slotAllocCopy.
m_sfnSf;
792 NS_LOG_INFO(
"Queueing allocation in front for " << newSfnSf);
795 NS_LOG_INFO(
"Reason: Current slot allocation has data");
799 NS_LOG_INFO(
"Reason: CTRL message list is not empty");
808 NS_LOG_INFO(
"Empty slot, but asking MAC for SlotIndication for the future, maybe there "
810 CallMacForSlotIndication(m_currentSlot);
823 NS_LOG_INFO(
"Schedule UL CTRL at " << start);
824 Simulator::Schedule(start, &NrGnbPhy::UlCtrl,
this, alloc.m_dci);
830 NS_LOG_INFO(
"Schedule UL SRS at " << start);
831 Simulator::Schedule(start, &NrGnbPhy::UlSrs,
this, alloc.m_dci);
839NrGnbPhy::DoCheckOrReleaseChannel()
841 NS_LOG_FUNCTION(
this);
843 NS_ASSERT(m_channelStatus == GRANTED);
848 uint8_t lastDlSymbol = 0;
855 std::max(lastDlSymbol,
856 static_cast<uint8_t
>(dci.m_dci->m_symStart + dci.m_dci->m_numSym));
864 NS_LOG_LOGIC(
"Last symbol of data: " << +lastDlSymbol
865 <<
", to the end of slot we still have "
867 <<
" us, so we're going to lose the channel");
868 m_channelStatus = TO_LOSE;
872 NS_LOG_LOGIC(
"Last symbol of data: " << +lastDlSymbol
873 <<
", to the end of slot we still have "
875 <<
" us, so we're NOT going to lose the channel");
880NrGnbPhy::RetrievePrepareEncodeCtrlMsgs()
882 NS_LOG_FUNCTION(
this);
885 ctrlMsgs.merge(RetrieveMsgsFromDCIs(m_currentSlot));
894 for (
const auto& msg : ctrlMsgs)
902NrGnbPhy::GenerateAllocationStatistics(
const SlotAllocInfo& allocInfo)
const
904 NS_LOG_FUNCTION(
this);
905 std::unordered_set<uint16_t> activeUe;
907 uint32_t dataReg = 0;
908 uint32_t ctrlReg = 0;
909 uint32_t dataSym = 0;
910 uint32_t ctrlSym = 0;
912 int lastSymStart = -1;
913 uint32_t symUsed = 0;
915 for (
const auto& allocation : allocInfo.m_varTtiAllocInfo)
917 uint32_t rbg = std::count(allocation.m_dci->m_rbgBitmask.begin(),
918 allocation.m_dci->m_rbgBitmask.end(),
922 if (allocation.m_dci->m_rnti != 0)
924 activeUe.insert(allocation.m_dci->m_rnti);
927 NS_ASSERT(lastSymStart <= allocation.m_dci->m_symStart);
929 auto rbgUsed = (rbg *
GetNumRbPerRbg()) * allocation.m_dci->m_numSym;
940 if (lastSymStart != allocation.m_dci->m_symStart)
942 symUsed += allocation.m_dci->m_numSym;
947 dataSym += allocation.m_dci->m_numSym;
951 ctrlSym += allocation.m_dci->m_numSym;
955 lastSymStart = allocation.m_dci->m_symStart;
958 NS_ASSERT_MSG(symUsed == allocInfo.m_numSymAlloc,
959 "Allocated " << +allocInfo.m_numSymAlloc <<
" but only " << symUsed
960 <<
" written in stats");
962 m_phySlotDataStats(allocInfo.m_sfnSf,
970 m_phySlotCtrlStats(allocInfo.m_sfnSf,
981NrGnbPhy::DoStartSlot()
983 NS_LOG_FUNCTION(
this);
990 NS_LOG_DEBUG(
"Start Slot " << m_currentSlot <<
" of type " <<
m_tddPattern[currentSlotN]);
1001 DoCheckOrReleaseChannel();
1003 RetrievePrepareEncodeCtrlMsgs();
1011NrGnbPhy::PrepareRbgAllocationMap(
const std::deque<VarTtiAllocInfo>& allocations)
1013 NS_LOG_FUNCTION(
this);
1016 m_rbgAllocationPerSym.clear();
1019 for (
const auto& allocation : allocations)
1027 StoreRBGAllocation(&m_rbgAllocationPerSym, allocation.m_dci);
1031 StoreRBGAllocation(&m_rbgAllocationPerSymDataStat, allocation.m_dci);
1035 for (
const auto& s : m_rbgAllocationPerSymDataStat)
1037 auto& rbgAllocation = s.second;
1038 m_rbStatistics(m_currentSlot,
1045 m_rbgAllocationPerSymDataStat.clear();
1049NrGnbPhy::FillTheEvent()
1051 NS_LOG_FUNCTION(
this);
1053 uint8_t lastSymStart = 0;
1056 NS_ASSERT(lastSymStart <= allocation.m_dci->m_symStart);
1059 Simulator::Schedule(varTtiStart, &NrGnbPhy::StartVarTti,
this, allocation.m_dci);
1060 lastSymStart = allocation.m_dci->m_symStart;
1062 NS_LOG_INFO(
"Scheduled allocation " << *(allocation.m_dci) <<
" at " << varTtiStart);
1069NrGnbPhy::StoreRBGAllocation(std::unordered_map<uint8_t, std::vector<uint8_t>>* map,
1070 const std::shared_ptr<DciInfoElementTdma>& dci)
const
1072 NS_LOG_FUNCTION(
this);
1074 auto itAlloc = map->find(dci->m_symStart);
1075 if (itAlloc == map->end())
1077 itAlloc = map->insert(std::make_pair(dci->m_symStart, dci->m_rbgBitmask)).first;
1081 auto& existingRBGBitmask = itAlloc->second;
1082 NS_ASSERT(existingRBGBitmask.size() == dci->m_rbgBitmask.size());
1083 for (uint32_t i = 0; i < existingRBGBitmask.size(); ++i)
1085 existingRBGBitmask.at(i) = existingRBGBitmask.at(i) | dci->m_rbgBitmask.at(i);
1090std::list<Ptr<NrControlMessage>>
1091NrGnbPhy::RetrieveDciFromAllocation(
const SlotAllocInfo& alloc,
1096 NS_LOG_FUNCTION(
this);
1097 std::list<Ptr<NrControlMessage>> ctrlMsgs;
1099 if (!alloc.m_buildRarList.empty())
1101 Ptr<NrRarMessage> ulMsg3DciMsg = Create<NrRarMessage>();
1102 for (
const auto& rarIt : alloc.m_buildRarList)
1104 NrRarMessage::Rar rar{};
1106 NS_ASSERT(rarIt.raPreambleId != 255);
1107 rar.rarPayload = rarIt;
1108 rar.rarPayload.k2Delay = kDelay;
1109 ulMsg3DciMsg->AddRar(rar);
1111 NS_LOG_INFO(
"In slot " << m_currentSlot <<
" PHY retrieves the RAR message for RNTI "
1112 << rar.rarPayload.ulMsg3Dci->m_rnti <<
" RA preamble Id "
1113 << +rar.rarPayload.raPreambleId <<
" at:" << Simulator::Now()
1114 <<
" for slot:" << alloc.m_sfnSf <<
" kDelay:" << kDelay
1115 <<
"k1Delay:" << k1Delay);
1116 ulMsg3DciMsg->SetSourceBwp(
GetBwpId());
1120 ctrlMsgs.push_back(ulMsg3DciMsg);
1124 for (
const auto& dlAlloc : alloc.m_varTtiAllocInfo)
1129 && dlAlloc.m_dci->m_format == format)
1131 auto& dciElem = dlAlloc.m_dci;
1132 NS_ASSERT(dciElem->m_format == format);
1134 "symStart: " <<
static_cast<uint32_t
>(dciElem->m_symStart)
1135 <<
" numSym: " <<
static_cast<uint32_t
>(dciElem->m_numSym)
1139 NS_LOG_INFO(
"Send DCI to RNTI " << dciElem->m_rnti <<
" from sym "
1140 << +dciElem->m_symStart <<
" to "
1141 << +dciElem->m_symStart + dciElem->m_numSym);
1143 Ptr<NrControlMessage> msg;
1147 Ptr<NrDlDciMessage> dciMsg = Create<NrDlDciMessage>(dciElem);
1150 dciMsg->SetKDelay(kDelay);
1151 dciMsg->SetK1Delay(k1Delay);
1156 Ptr<NrUlDciMessage> dciMsg = Create<NrUlDciMessage>(dciElem);
1159 dciMsg->SetKDelay(kDelay);
1163 ctrlMsgs.push_back(msg);
1170std::list<Ptr<NrControlMessage>>
1171NrGnbPhy::RetrieveMsgsFromDCIs(
const SfnSf& currentSlot)
1173 std::list<Ptr<NrControlMessage>> ctrlMsgs;
1174 uint64_t currentSlotN = currentSlot.Normalize() %
m_tddPattern.size();
1176 uint32_t k1delay = m_dlHarqfbPosition[currentSlotN];
1179 for (
const auto& k0delay : m_toSendDl[currentSlotN])
1181 SfnSf targetSlot = currentSlot;
1183 targetSlot.Add(k0delay);
1185 if (targetSlot == currentSlot)
1187 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" send DL DCI for the same slot");
1196 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" send DL DCI for " << targetSlot);
1205 NS_LOG_DEBUG(
"No allocation found for slot " << targetSlot);
1209 for (
const auto& k2delay : m_toSendUl[currentSlotN])
1211 SfnSf targetSlot = currentSlot;
1213 targetSlot.Add(k2delay);
1215 if (targetSlot == currentSlot)
1217 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" send UL DCI for the same slot");
1226 NS_LOG_DEBUG(
" in slot " << currentSlot <<
" send UL DCI for " << targetSlot);
1235 NS_LOG_DEBUG(
"No allocation found for slot " << targetSlot);
1243NrGnbPhy::DlCtrl(
const std::shared_ptr<DciInfoElementTdma>& dci)
1245 NS_LOG_FUNCTION(
this);
1247 NS_LOG_DEBUG(
"Starting DL CTRL TTI at symbol " << +m_currSymStart <<
" to "
1248 << +m_currSymStart + dci->m_numSym);
1256 NS_LOG_DEBUG(
"gNB TXing DL CTRL with "
1257 <<
m_ctrlMsgs.size() <<
" msgs, frame " << m_currentSlot <<
" symbols "
1258 <<
static_cast<uint32_t
>(dci->m_symStart) <<
"-"
1259 <<
static_cast<uint32_t
>(dci->m_symStart + dci->m_numSym - 1) <<
" start "
1260 << Simulator::Now() <<
" end "
1261 << Simulator::Now() + varTtiPeriod - NanoSeconds(1.0));
1265 Ptr<NrControlMessage> msg = m_ctrlMsg;
1266 m_phyTxedCtrlMsgsTrace(m_currentSlot,
GetCellId(), dci->m_rnti,
GetBwpId(), msg);
1269 SendCtrlChannels(varTtiPeriod -
1274 NS_LOG_DEBUG(
"No messages to send, skipping");
1277 return varTtiPeriod;
1281NrGnbPhy::UlCtrl(
const std::shared_ptr<DciInfoElementTdma>& dci)
1283 NS_LOG_FUNCTION(
this);
1285 NS_LOG_DEBUG(
"Starting UL CTRL TTI at symbol " << +m_currSymStart <<
" to "
1286 << +m_currSymStart + dci->m_numSym);
1290 NS_LOG_DEBUG(
"gNB RXng UL CTRL frame "
1291 << m_currentSlot <<
" symbols " <<
static_cast<uint32_t
>(dci->m_symStart) <<
"-"
1292 <<
static_cast<uint32_t
>(dci->m_symStart + dci->m_numSym - 1) <<
" start "
1293 << Simulator::Now() <<
" end " << Simulator::Now() + varTtiPeriod);
1294 return varTtiPeriod;
1298NrGnbPhy::DlData(
const std::shared_ptr<DciInfoElementTdma>& dci)
1300 NS_LOG_FUNCTION(
this);
1301 NS_LOG_DEBUG(
"Starting DL DATA TTI at symbol " << +m_currSymStart <<
" to "
1302 << +m_currSymStart + dci->m_numSym <<
" for "
1307 Ptr<PacketBurst> pktBurst =
GetPacketBurst(m_currentSlot, dci->m_symStart, dci->m_rnti);
1309 if (!pktBurst || pktBurst->GetNPackets() == 0)
1313 return varTtiPeriod;
1316 NS_LOG_INFO(
"gNB TXing DL DATA frame "
1317 << m_currentSlot <<
" symbols " <<
static_cast<uint32_t
>(dci->m_symStart) <<
"-"
1318 <<
static_cast<uint32_t
>(dci->m_symStart + dci->m_numSym - 1) <<
" start "
1319 << Simulator::Now() + NanoSeconds(1) <<
" end "
1320 << Simulator::Now() + varTtiPeriod - NanoSeconds(2.0));
1322 Simulator::Schedule(NanoSeconds(1.0),
1323 &NrGnbPhy::SendDataChannels,
1326 varTtiPeriod - NanoSeconds(2.0),
1329 return varTtiPeriod;
1333NrGnbPhy::UlData(
const std::shared_ptr<DciInfoElementTdma>& dci)
1335 NS_LOG_FUNCTION(
this);
1337 NS_LOG_DEBUG(
"Starting UL DATA TTI at symbol " << +m_currSymStart <<
" to "
1338 << +m_currSymStart + dci->m_numSym);
1356 for (
auto& i : m_deviceMap)
1358 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(i);
1359 uint64_t ueRnti = (DynamicCast<NrUePhy>(ueDev->GetPhy(
GetBwpId())))->GetRnti();
1360 if (dci->m_rnti == ueRnti)
1377 NS_LOG_INFO(
"GNB RXing UL DATA frame "
1378 << m_currentSlot <<
" symbols " <<
static_cast<uint32_t
>(dci->m_symStart) <<
"-"
1379 <<
static_cast<uint32_t
>(dci->m_symStart + dci->m_numSym - 1) <<
" start "
1380 << Simulator::Now() <<
" end " << Simulator::Now() + varTtiPeriod);
1381 return varTtiPeriod;
1387 m_spectrumPhy->GetBeamManager()->ChangeBeamformingVector(dev);
1393 m_spectrumPhy->GetBeamManager()->ChangeToQuasiOmniBeamformingVector();
1397NrGnbPhy::UlSrs(
const std::shared_ptr<DciInfoElementTdma>& dci)
1399 NS_LOG_FUNCTION(
this);
1401 NS_LOG_DEBUG(
"Starting UL SRS TTI at symbol " << +m_currSymStart <<
" to "
1402 << +m_currSymStart + dci->m_numSym);
1412 for (
auto& i : m_deviceMap)
1414 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(i);
1415 uint64_t ueRnti = (DynamicCast<NrUePhy>(ueDev->GetPhy(0)))->GetRnti();
1416 if (dci->m_rnti == ueRnti)
1432 NS_LOG_WARN(
"The UE for which is scheduled this SRS does not have yet initialized RNTI. "
1433 "RAR message was not received yet.");
1436 NS_LOG_INFO(
"GNB RXing UL SRS frame "
1437 << m_currentSlot <<
" symbols " <<
static_cast<uint32_t
>(dci->m_symStart) <<
"-"
1438 <<
static_cast<uint32_t
>(dci->m_symStart + dci->m_numSym - 1) <<
" start "
1439 << Simulator::Now() <<
" end " << Simulator::Now() + varTtiPeriod);
1440 return varTtiPeriod;
1444NrGnbPhy::StartVarTti(
const std::shared_ptr<DciInfoElementTdma>& dci)
1446 NS_LOG_FUNCTION(
this);
1448 m_currSymStart = dci->m_symStart;
1456 varTtiPeriod = DlCtrl(dci);
1460 varTtiPeriod = UlCtrl(dci);
1467 varTtiPeriod = DlData(dci);
1471 varTtiPeriod = UlData(dci);
1477 varTtiPeriod = UlSrs(dci);
1480 Simulator::Schedule(varTtiPeriod, &NrGnbPhy::EndVarTti,
this, dci);
1484NrGnbPhy::EndVarTti(
const std::shared_ptr<DciInfoElementTdma>& lastDci)
1486 NS_LOG_FUNCTION(
this << Simulator::Now().GetSeconds());
1488 NS_LOG_DEBUG(
"DCI started at symbol "
1489 <<
static_cast<uint32_t
>(lastDci->m_symStart) <<
" which lasted for "
1490 <<
static_cast<uint32_t
>(lastDci->m_numSym) <<
" symbols finished");
1496 NS_LOG_FUNCTION(
this);
1498 Time slotStart = m_lastSlotStart +
GetSlotPeriod() - Simulator::Now();
1500 if (m_channelStatus == TO_LOSE)
1502 NS_LOG_INFO(
"Release the channel because we did not have any data to maintain the grant");
1503 m_channelStatus = NONE;
1504 m_channelLostTimer.Cancel();
1507 NS_LOG_DEBUG(
"Slot started at " << m_lastSlotStart <<
" ended");
1508 m_currentSlot.
Add(1);
1509 Simulator::Schedule(slotStart, &NrGnbPhy::StartSlot,
this, m_currentSlot);
1513NrGnbPhy::SendDataChannels(
const Ptr<PacketBurst>& pb,
1514 const Time& varTtiPeriod,
1515 const std::shared_ptr<DciInfoElementTdma>& dci)
1517 NS_LOG_FUNCTION(
this);
1522 if (Simulator::Now() > m_lastBfChange)
1525 "Cannot change analog BF after TX has started");
1526 m_lastBfChange = Simulator::Now();
1528 for (
auto& i : m_deviceMap)
1530 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(i);
1531 uint64_t ueRnti = (DynamicCast<NrUePhy>(ueDev->GetPhy(
GetBwpId())))->GetRnti();
1532 if (dci->m_rnti == ueRnti)
1551 NS_ASSERT(m_rbgAllocationPerSym.find(dci->m_symStart) != m_rbgAllocationPerSym.end());
1552 auto nTotalAllocRbs =
1556 std::list<Ptr<NrControlMessage>> ctrlMsgs;
1557 m_spectrumPhy->StartTxDataFrames(pb, ctrlMsgs, dci, varTtiPeriod);
1561NrGnbPhy::SendCtrlChannels(
const Time& varTtiPeriod)
1563 NS_LOG_FUNCTION(
this <<
"Send Ctrl");
1565 std::vector<int> fullBwRb(
GetRbNum());
1567 for (uint32_t i = 0; i < fullBwRb.size(); ++i)
1569 fullBwRb[i] =
static_cast<int>(i);
1584 NS_LOG_FUNCTION(
this << imsi);
1585 std::set<uint64_t>::iterator it;
1586 it = m_ueAttached.find(imsi);
1588 if (it == m_ueAttached.end())
1590 m_ueAttached.insert(imsi);
1591 m_deviceMap.push_back(ueDevice);
1596 NS_LOG_ERROR(
"Programming error...UE already attached");
1604 Simulator::ScheduleWithContext(
m_netDevice->GetNode()->GetId(),
1614 NS_LOG_FUNCTION(
this << sinr);
1616 Values::const_iterator it;
1618 ulcqi.
m_ulCqi.m_type = UlCqiInfo::PUSCH;
1619 for (it = sinr.ConstValuesBegin(); it != sinr.ConstValuesEnd(); it++)
1625 ulcqi.
m_ulCqi.m_sinr.push_back(
1632 ulcqi.
m_sfnSf = m_currentSlot;
1634 SpectrumValue newSinr = sinr;
1635 m_ulSinrTrace(0, newSinr, newSinr);
1642 NS_LOG_FUNCTION(
this);
1646 Ptr<NrDlCqiMessage> dlcqi = DynamicCast<NrDlCqiMessage>(msg);
1650 NS_LOG_INFO(
"Received DL_CQI for RNTI: " << dlcqiLE.
m_rnti <<
" in slot " << m_currentSlot);
1656 NS_LOG_INFO(
"received RACH_PREAMBLE");
1658 Ptr<NrRachPreambleMessage> rachPreamble = DynamicCast<NrRachPreambleMessage>(msg);
1660 NS_LOG_INFO(
"Received RACH Preamble in slot " << m_currentSlot);
1665 Ptr<NrDlHarqFeedbackMessage> dlharqMsg = DynamicCast<NrDlHarqFeedbackMessage>(msg);
1666 DlHarqInfo dlharq = dlharqMsg->GetDlHarqFeedback();
1667 if (m_ueAttachedRnti.find(dlharq.
m_rnti) != m_ueAttachedRnti.end())
1671 NS_LOG_INFO(
"Received DL_HARQ for RNTI: " << dlharq.
m_rnti <<
" in slot "
1688NrGnbPhy::DoSetBandwidth(uint16_t ulBandwidth, uint16_t dlBandwidth)
1690 NS_LOG_FUNCTION(
this << +ulBandwidth << +dlBandwidth);
1691 NS_ASSERT(ulBandwidth == dlBandwidth);
1696NrGnbPhy::DoSetEarfcn(uint16_t ulEarfcn, uint16_t dlEarfcn)
1698 NS_LOG_FUNCTION(
this << ulEarfcn << dlEarfcn);
1702NrGnbPhy::DoAddUe([[maybe_unused]] uint16_t rnti)
1704 NS_LOG_FUNCTION(
this << rnti);
1705 std::set<uint16_t>::iterator it;
1706 it = m_ueAttachedRnti.find(rnti);
1707 if (it == m_ueAttachedRnti.end())
1709 m_ueAttachedRnti.insert(rnti);
1714NrGnbPhy::DoRemoveUe(uint16_t rnti)
1716 NS_LOG_FUNCTION(
this << rnti);
1718 std::set<uint16_t>::iterator it = m_ueAttachedRnti.find(rnti);
1719 if (it != m_ueAttachedRnti.end())
1721 m_ueAttachedRnti.erase(it);
1725 NS_FATAL_ERROR(
"Impossible to remove UE, not attached!");
1730NrGnbPhy::DoSetPa(uint16_t rnti,
double pa)
1732 NS_LOG_FUNCTION(
this << rnti << pa);
1736NrGnbPhy::DoSetTransmissionMode(uint16_t rnti, uint8_t txMode)
1738 NS_LOG_FUNCTION(
this << rnti << +txMode);
1743NrGnbPhy::DoSetSrsConfigurationIndex(uint16_t rnti, uint16_t srcCi)
1745 NS_LOG_FUNCTION(
this << rnti << srcCi);
1749NrGnbPhy::DoSetMasterInformationBlock([[maybe_unused]] NrRrcSap::MasterInformationBlock mib)
1751 NS_LOG_FUNCTION(
this);
1755NrGnbPhy::DoSetSystemInformationBlockType1(NrRrcSap::SystemInformationBlockType1 sib1)
1757 NS_LOG_FUNCTION(
this);
1764 NS_LOG_FUNCTION(
this);
1777 NS_LOG_FUNCTION(
this);
1779 if (m_ueAttachedRnti.find(mes.
m_rnti) != m_ueAttachedRnti.end())
1781 NS_LOG_INFO(
"Received UL HARQ feedback " << mes.
IsReceivedOk()
1782 <<
" and forwarding to the scheduler");
1790 NS_LOG_FUNCTION(
this);
1792 static std::unordered_map<std::string, LteNrTddSlotType> lookupTable = {
1799 std::vector<LteNrTddSlotType> vector;
1800 std::stringstream ss(pattern);
1802 std::vector<std::string> extracted;
1804 while (std::getline(ss, token,
'|'))
1806 extracted.push_back(token);
1809 for (
const auto& v : extracted)
1811 if (lookupTable.find(v) == lookupTable.end())
1813 NS_FATAL_ERROR(
"Pattern type " << v <<
" not valid. Valid values are: DL UL F S");
1815 vector.push_back(lookupTable[v]);
1818 SetTddPattern(vector);
1830 NS_LOG_FUNCTION(
this);
1835NrGnbPhy::ChannelAccessGranted(
const Time& time)
1837 NS_LOG_FUNCTION(
this);
1841 NS_LOG_INFO(
"Channel granted for less than the slot time. Ignoring the grant.");
1842 m_channelStatus = NONE;
1846 m_channelStatus = GRANTED;
1848 Time toNextSlot = m_lastSlotStart +
GetSlotPeriod() - Simulator::Now();
1849 Time grant = time - toNextSlot;
1850 int64_t slotGranted = grant.GetNanoSeconds() /
GetSlotPeriod().GetNanoSeconds();
1852 NS_LOG_INFO(
"Channel access granted for " << time <<
", which corresponds to " << slotGranted
1854 <<
". We lost " << toNextSlot);
1855 NS_ASSERT(!m_channelLostTimer.IsPending());
1857 if (slotGranted < 1)
1861 m_channelLostTimer = Simulator::Schedule(
GetSlotPeriod() * slotGranted - NanoSeconds(1),
1862 &NrGnbPhy::ChannelAccessLost,
1867NrGnbPhy::ChannelAccessLost()
1869 NS_LOG_FUNCTION(
this);
1870 NS_LOG_INFO(
"Channel access lost");
1871 m_channelStatus = NONE;
Representation of a beam id.
@ DL_HARQ
DL HARQ feedback.
@ RACH_PREAMBLE
Random Access Preamble.
void GenerateDataCqiReport(const SpectrumValue &sinr)
Generate a DL CQI report.
void SetN1Delay(uint32_t delay)
: Set the minimum processing delay (in slots) to decode DL Data and send Harq feedback.
NrGnbCphySapProvider * GetGnbCphySapProvider()
Get the C PHY SAP provider.
void ChangeToQuasiOmniBeamformingVector()
void ReportUlHarqFeedback(const UlHarqInfo &mes)
Get the HARQ feedback from NrSpectrumPhy and forward it to the scheduler.
int8_t DoGetReferenceSignalPower() const
Get the power of the gnb.
Ptr< NrChAccessManager > GetCam() const
Get the channel access manager for the PHY.
void DoDispose() override
DoDispose method inherited from Object.
void SetPrimary()
Set this PHY as primary.
void SetN0Delay(uint32_t delay)
: Set the minimum processing delay (in slots) to decode DL DCI and decode DL data....
void ScheduleStartEventLoop(uint32_t nodeId, uint16_t frame, uint8_t subframe, uint16_t slot) override
Start the ue Event Loop.
~NrGnbPhy() override
~NrGnbPhy
const SfnSf & GetCurrentSfnSf() const override
Get the current SfnSf.
void SetCam(const Ptr< NrChAccessManager > &s)
Set the channel access manager interface for this instance of the PHY.
void SetSubChannels(const std::vector< int > &rbIndexVector, size_t nTotalAllocRbs)
Set the Tx power spectral density based on the RB index vector.
BeamId GetBeamId(uint16_t rnti) const override
Get the BeamId for the selected user.
void SetGnbCphySapUser(NrGnbCphySapUser *s)
Set the C PHY SAP user.
bool RegisterUe(uint64_t imsi, const Ptr< NrUeNetDevice > &ueDevice)
Add the UE to the list of this gnb UEs.
void SetPattern(const std::string &pattern)
Set the pattern that the gnb will utilize.
void SetN2Delay(uint32_t delay)
: Set the minimum processing delay (in slots) to decode UL DCI and prepare UL data.
NrGnbPhy()
NrGnbPhy constructor. Please use the other one.
uint32_t GetN2Delay() const
: Get the minimum processing delay (in slots) to decode UL DCI and prepare UL data
uint32_t GetN1Delay() const
: Get the minimum processing delay (in slots) to decode DL Data and send Harq feedback
void PhyDataPacketReceived(const Ptr< Packet > &p)
Receive a PHY data packet.
void PhyCtrlMessagesReceived(const Ptr< NrControlMessage > &msg)
Receive a list of CTRL messages.
void SetTxPower(double pow)
Set the transmission power for the UE.
double GetTxPower() const override
Retrieve the TX power of the gNB.
void SetPhySapUser(NrGnbPhySapUser *ptr)
Install the PHY SAP user (which is in this case the MAC)
uint32_t GetN0Delay() const
: Get the minimum processing delay (in slots) to decode DL DCI and decode DL Data
uint32_t GetNumRbPerRbg() const override
Retrieve the number of RB per RBG.
std::string GetPattern() const
Retrieve the currently installed pattern.
void ChangeBeamformingVector(Ptr< NrNetDevice > dev)
static TypeId GetTypeId()
Get Type id.
SAP interface between the gNB PHY and the gNB MAC.
virtual void ReceiveControlMessage(Ptr< NrControlMessage > msg)=0
Receive SendNrControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
virtual void SlotUlIndication(const SfnSf &sfn, LteNrTddSlotType slotType)=0
Trigger MAC layer to generate an UL slot for the SfnSf indicated.
virtual void ReceivePhyPdu(Ptr< Packet > p)=0
Notify the MAC of the reception of a new PHY-PDU.
virtual void UlCqiReport(NrMacSchedSapProvider::SchedUlCqiInfoReqParameters ulcqi)=0
Returns to MAC level the UL-CQI evaluated.
virtual void UlHarqFeedback(UlHarqInfo params)=0
Notify the HARQ on the UL transmission status.
virtual void SetCurrentSfn(const SfnSf &sfn)=0
Set the current Sfn. The state machine has advanced by one slot.
virtual uint32_t GetNumRbPerRbg() const =0
PHY requests information from MAC. While MAC normally act as user of PHY services,...
virtual uint8_t GetDlCtrlSymbols() const =0
Retrieve the DL CTRL symbols.
virtual void ReceiveRachPreamble(uint32_t raId)=0
Notify the reception of a RACH preamble on the PRACH.
virtual void SlotDlIndication(const SfnSf &sfn, LteNrTddSlotType slotType)=0
Trigger MAC layer to generate a DL slot for the SfnSf indicated.
virtual std::shared_ptr< DciInfoElementTdma > GetUlCtrlDci() const =0
Retrieve a dci for a UL CTRL allocation.
virtual std::shared_ptr< DciInfoElementTdma > GetDlCtrlDci() const =0
Retrieve a dci for a DL CTRL allocation.
The base class for gNb and UE physical layer.
Time GetSymbolPeriod() const
Get SymbolPeriod.
Ptr< NrSpectrumPhy > m_spectrumPhy
Pointer to the (owned) spectrum phy.
SlotAllocInfo RetrieveSlotAllocInfo()
Get the head for the slot allocation info, and delete it from the internal list.
uint16_t GetCellId() const
uint16_t GetNumerology() const
Get the configured numerology.
Ptr< NrSpectrumPhy > GetSpectrumPhy() const
Retrieve the SpectrumPhy pointer.
void EncodeCtrlMsg(const Ptr< NrControlMessage > &msg)
Take the control messages, and put it in a list that will be sent at the first occasion.
void SetNumerology(uint16_t numerology)
Set GNB or UE numerology.
virtual void SetTbDecodeLatency(const Time &us)
Configures TB decode latency.
std::list< Ptr< NrControlMessage > > m_ctrlMsgs
CTRL messages to be sent.
void SetRbOverhead(double oh)
Set the bandwidth overhead for calculating the usable RB number.
Ptr< PacketBurst > GetPacketBurst(SfnSf sf, uint8_t sym, uint16_t rnti)
Retrieve the PacketBurst at the slot/symbol specified.
void SetPowerAllocationType(enum NrSpectrumValueHelper::PowerAllocationType powerAllocationType)
Set power allocation type. There are currently supported two types: one that distributes uniformly en...
static std::string GetPattern(const std::vector< LteNrTddSlotType > &pattern)
Get a string representation of a pattern.
Time GetSlotPeriod() const
Get the slot period.
virtual std::list< Ptr< NrControlMessage > > PopCurrentSlotCtrlMsgs()
Extract and return the message list that is at the beginning of the queue.
SlotAllocInfo m_currSlotAllocInfo
Current slot allocation.
enum NrSpectrumValueHelper::PowerAllocationType GetPowerAllocationType() const
Get the power allocation type.
void EnqueueCtrlMsgNow(const Ptr< NrControlMessage > &msg)
Enqueue a CTRL message without considering L1L2CtrlLatency.
uint32_t GetChannelBandwidth() const
Retrieve the channel bandwidth, in Hz.
virtual Time GetTbDecodeLatency() const
Returns Transport Block decode latency.
SlotAllocInfo & PeekSlotAllocInfo(const SfnSf &sfnsf)
Peek the SlotAllocInfo at the SfnSf specified.
double GetCentralFrequency() const
Retrieve the frequency (in Hz) of this PHY's channel.
double m_noiseFigure
Noise figure (attribute)
void SetSymbolsPerSlot(uint16_t symbolsPerSlot)
Set the number of symbol per slot.
double GetNoiseFigure() const
Get the NoiseFigure value.
void SetNoiseFigure(double d)
Set the NoiseFigure value.
double m_txPower
Transmission power (attribute)
void InitializeMessageList()
Initialize the message list.
Ptr< SpectrumValue > GetTxPowerSpectralDensity(const std::vector< int > &rbIndexVector)
void SetChannelBandwidth(uint16_t bandwidth)
Function to set the channel bandwidth, used also by child classes, i.e., see functions DoSetDlBanwidt...
uint16_t GetBwpId() const
void PushFrontSlotAllocInfo(const SfnSf &newSfnSf, const SlotAllocInfo &slotAllocInfo)
Store the slot allocation info at the front.
std::vector< int > FromRBGBitmaskToRBAssignment(const std::vector< uint8_t > rbgBitmask) const
Transform a MAC-made vector of RBG to a PHY-ready vector of SINR indices.
Ptr< NrNetDevice > m_netDevice
Pointer to the owner netDevice.
uint32_t GetL1L2CtrlLatency() const
bool SlotAllocInfoExists(const SfnSf &sfnsf) const
Check if the SlotAllocationInfo for that slot exists.
uint32_t GetSymbolsPerSlot() const
Get the number of symbols in a slot.
std::vector< LteNrTddSlotType > m_tddPattern
Pattern.
NrPhySapProvider * m_phySapProvider
Pointer to the MAC.
double GetRbOverhead() const
Get the bandwidth overhead used when calculating the usable RB number.
bool HasUlSlot() const
Go through the current pattern and see if at least one slot is UL, F or S.
uint32_t GetRbNum() const
Get the number of Resource block configured.
static bool IsTdd(const std::vector< LteNrTddSlotType > &pattern)
Check if a pattern is TDD.
void DoDispose() override
DoDispose method inherited from Object.
virtual void SetSlotAllocInfo(const SlotAllocInfo &slotAllocInfo)=0
Set a SlotAllocInfo inside the PHY allocations.
uint8_t GetSubframe() const
GetSubframe.
uint64_t Normalize() const
Normalize the SfnSf in slot number.
void Add(uint32_t slotN)
Add to this SfnSf a number of slot indicated by the first parameter.
uint8_t GetSlot() const
GetSlot.
@ F
DL CTRL + DL DATA + UL DATA + UL CTRL.
@ S
DL CTRL + DL DATA + UL CTRL.
@ CTRL
Used for DL/UL CTRL.
@ DATA
Used for DL/UL DATA.
@ SRS
Used for SRS (it would be like DCI format 2_3)
DciFormat
Format of the DCI.
A struct that contains info for the DL HARQ.
The SchedUlCqiInfoReqParameters struct.
struct UlCqiInfo m_ulCqi
UL CQI.
uint8_t m_symStart
Sym start of the transmission to which this CQI refers to.
SfnSf m_sfnSf
SfnSf of this allocation.
bool ContainsDlCtrlAllocation() const
uint32_t m_numSymAlloc
Number of allocated symbols.
bool ContainsDataAllocation() const
Check if we have data allocations.
bool ContainsUlMsg3Allocation() const
Check if we have UL MSG3 allocations.
std::deque< VarTtiAllocInfo > m_varTtiAllocInfo
queue of allocations
A struct that contains info for the UL HARQ.
bool IsReceivedOk() const override