5G-LENA nr-v3.0-32-g83aee33
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-phy-patterns.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
3// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4//
5// SPDX-License-Identifier: GPL-2.0-only
6
7#include <ns3/beam-manager.h>
8#include <ns3/multi-model-spectrum-channel.h>
9#include <ns3/node.h>
10#include <ns3/nr-ch-access-manager.h>
11#include <ns3/nr-gnb-phy.h>
12#include <ns3/nr-mac-scheduler-tdma-rr.h>
13#include <ns3/object-factory.h>
14#include <ns3/test.h>
15#include <ns3/uniform-planar-array.h>
16
25namespace ns3
26{
27
28class TestGnbMac : public NrGnbMac
29{
30 public:
31 static TypeId GetTypeId();
32 TestGnbMac(const std::string& pattern);
33 ~TestGnbMac() override;
34 void DoSlotDlIndication(const SfnSf& sfnSf, LteNrTddSlotType type) override;
35 void DoSlotUlIndication(const SfnSf& sfnSf, LteNrTddSlotType type) override;
36 void SetCurrentSfn(const SfnSf& sfn) override;
37
38 private:
39 std::vector<LteNrTddSlotType> m_pattern;
40 std::set<uint32_t> m_slotCreated;
41 uint32_t m_totalSlotToCreate{0};
42};
43
44NS_OBJECT_ENSURE_REGISTERED(TestGnbMac);
45
46TypeId
47TestGnbMac::GetTypeId()
48{
49 static TypeId tid = TypeId("ns3::TestGnbMac").SetParent<NrGnbMac>()
50 //.AddConstructor<TestGnbMac> ()
51 ;
52 return tid;
53}
54
55TestGnbMac::TestGnbMac(const std::string& pattern)
56{
57 static std::unordered_map<std::string, LteNrTddSlotType> lookupTable = {
62 };
63
64 std::stringstream ss(pattern);
65 std::string token;
66 std::vector<std::string> extracted;
67
68 while (std::getline(ss, token, '|'))
69 {
70 extracted.push_back(token);
71 }
72
73 for (const auto& v : extracted)
74 {
75 if (lookupTable.find(v) == lookupTable.end())
76 {
77 NS_FATAL_ERROR("Pattern type " << v << " not valid. Valid values are: DL UL F S");
78 }
79 m_pattern.push_back(lookupTable[v]);
80 }
81
82 for (const auto& v : m_pattern)
83 {
84 switch (v)
85 {
87 m_totalSlotToCreate += 2; // But since we are using std::set,
88 // duplicated slots will not be counted
89 break;
93 m_totalSlotToCreate += 1;
94 break;
95 }
96 }
97}
98
99TestGnbMac::~TestGnbMac()
100{
101 NS_ASSERT_MSG(m_slotCreated.size() == m_pattern.size(),
102 "The number of created slot ("
103 << m_slotCreated.size() << ") is not equal to the pattern size "
104 << m_pattern.size() << ", we have to create " << m_totalSlotToCreate
105 << " slots");
106}
107
108void
109TestGnbMac::DoSlotDlIndication(const SfnSf& sfnSf, LteNrTddSlotType type)
110{
111 uint32_t pos = sfnSf.Normalize();
112 pos = pos % m_pattern.size();
113
114 NS_ASSERT(type == LteNrTddSlotType::DL || type == LteNrTddSlotType::S ||
115 type == LteNrTddSlotType::F);
116 NS_ASSERT_MSG(m_pattern[pos] == LteNrTddSlotType::DL || m_pattern[pos] == LteNrTddSlotType::S ||
117 m_pattern[pos] == LteNrTddSlotType::F,
118 "MAC called to generate a DL slot, but in the pattern there is "
119 << m_pattern[pos]);
120
121 m_slotCreated.insert(pos);
122
123 NrGnbMac::DoSlotDlIndication(sfnSf, type);
124}
125
126void
127TestGnbMac::DoSlotUlIndication(const SfnSf& sfnSf, LteNrTddSlotType type)
128{
129 uint32_t pos = sfnSf.Normalize();
130 pos = pos % m_pattern.size();
131
132 NS_ASSERT(type == LteNrTddSlotType::UL || type == LteNrTddSlotType::S ||
133 type == LteNrTddSlotType::F);
134 NS_ASSERT_MSG(m_pattern[pos] == LteNrTddSlotType::UL || m_pattern[pos] == LteNrTddSlotType::F,
135 "MAC called to generate a UL slot, but in the pattern there is "
136 << m_pattern[pos]);
137
138 m_slotCreated.insert(pos);
139
140 NrGnbMac::DoSlotUlIndication(sfnSf, type);
141}
142
143void
144TestGnbMac::SetCurrentSfn(const SfnSf& sfnSf)
145{
147}
148
152class LtePhyPatternTestCase : public TestCase
153{
154 public:
159 LtePhyPatternTestCase(const std::string& pattern, const std::string& name)
160 : TestCase(name),
161 m_pattern(pattern)
162 {
163 }
164
165 ~LtePhyPatternTestCase() override;
166
167 private:
168 void DoRun() override;
169 void Print(const std::string& msg1,
170 const std::string& msg2,
171 const std::map<uint32_t, std::vector<uint32_t>>& str);
172 void StartSimu();
173 Ptr<NrGnbMac> CreateMac(const Ptr<NrMacScheduler>& sched) const;
174 Ptr<NrGnbPhy> CreatePhy(const Ptr<NrGnbMac>& mac) const;
175
176 Ptr<NrGnbPhy> m_phy;
177 std::string m_pattern;
178};
179
180LtePhyPatternTestCase::~LtePhyPatternTestCase()
181{
182 if (m_phy)
183 {
184 m_phy->Dispose();
185 m_phy = nullptr;
186 }
187}
188
189void
190LtePhyPatternTestCase::DoRun()
191{
192 ObjectFactory schedFactory;
193 schedFactory.SetTypeId(NrMacSchedulerTdmaRR::GetTypeId());
194 Ptr<NrMacScheduler> sched = DynamicCast<NrMacScheduler>(schedFactory.Create());
195
196 auto mac = CreateMac(sched);
197 m_phy = CreatePhy(mac);
198
199 m_phy->SetPattern(m_pattern);
200
201 // Finishing initialization
202 m_phy->SetPhySapUser(mac->GetPhySapUser());
203 m_phy->Initialize();
204 mac->SetPhySapProvider(m_phy->GetPhySapProvider());
205 mac->Initialize();
206
207 StartSimu();
208}
209
210void
211LtePhyPatternTestCase::StartSimu()
212{
213 Simulator::Stop(MilliSeconds(200));
214 Simulator::Run();
215 Simulator::Destroy();
216}
217
218Ptr<NrGnbPhy>
219LtePhyPatternTestCase::CreatePhy(const Ptr<NrGnbMac>& mac) const
220{
221 Ptr<NrSpectrumPhy> channelPhy = CreateObject<NrSpectrumPhy>();
222 Ptr<NrGnbPhy> phy = CreateObject<NrGnbPhy>();
223 Ptr<UniformPlanarArray> antenna = CreateObject<UniformPlanarArray>();
224
225 phy->InstallCentralFrequency(28e9);
226
227 phy->ScheduleStartEventLoop(0, 0, 0, 0);
228
229 // PHY <--> CAM
230 Ptr<NrChAccessManager> cam =
231 DynamicCast<NrChAccessManager>(CreateObject<NrAlwaysOnAccessManager>());
232 cam->SetNrSpectrumPhy(channelPhy);
233 cam->SetNrGnbMac(mac);
234 phy->SetCam(cam);
235
236 Ptr<NrHarqPhy> harq = Create<NrHarqPhy>();
237 channelPhy->InstallHarqPhyModule(harq);
238
239 Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor>();
240 channelPhy->AddDataSinrChunkProcessor(pData);
241
242 channelPhy->InstallPhy(phy);
243
244 phy->InstallSpectrumPhy(channelPhy);
245 Ptr<BeamManager> beamManager = CreateObject<BeamManager>();
246 beamManager->Configure(antenna);
247 channelPhy->SetBeamManager(beamManager);
248 return phy;
249}
250
251Ptr<NrGnbMac>
252LtePhyPatternTestCase::CreateMac(const Ptr<NrMacScheduler>& sched) const
253{
254 Ptr<NrGnbMac> mac = CreateObject<TestGnbMac>(m_pattern);
255
256 sched->SetMacSchedSapUser(mac->GetNrMacSchedSapUser());
257 sched->SetMacCschedSapUser(mac->GetNrMacCschedSapUser());
258
259 mac->SetNrMacSchedSapProvider(sched->GetMacSchedSapProvider());
260 mac->SetNrMacCschedSapProvider(sched->GetMacCschedSapProvider());
261
262 return mac;
263}
264
265void
266LtePhyPatternTestCase::Print(const std::string& msg1,
267 const std::string& msg2,
268 const std::map<uint32_t, std::vector<uint32_t>>& str)
269{
270 for (const auto& v : str)
271 {
272 for (const auto& i : v.second)
273 {
274 std::cout << msg1 << i << msg2 << v.first << std::endl;
275 }
276 }
277}
278
279class NrLtePatternsTestSuite : public TestSuite
280{
281 public:
282 NrLtePatternsTestSuite()
283 : TestSuite("nr-phy-patterns", Type::UNIT)
284 {
285 AddTestCase(
286 new LtePhyPatternTestCase("DL|S|UL|UL|DL|DL|S|UL|UL|DL|", "LTE TDD Pattern 1 test"),
287 Duration::QUICK);
288
289 AddTestCase(
290 new LtePhyPatternTestCase("DL|S|UL|DL|DL|DL|S|UL|DL|DL|", "LTE TDD Pattern 2 test"),
291 Duration::QUICK);
292
293 AddTestCase(
294 new LtePhyPatternTestCase("DL|S|UL|UL|UL|DL|DL|DL|DL|DL|", "LTE TDD Pattern 3 test"),
295 Duration::QUICK);
296
297 AddTestCase(
298 new LtePhyPatternTestCase("DL|S|UL|UL|DL|DL|DL|DL|DL|DL|", "LTE TDD Pattern 4 test"),
299 Duration::QUICK);
300
301 AddTestCase(
302 new LtePhyPatternTestCase("DL|S|UL|DL|DL|DL|DL|DL|DL|DL|", "LTE TDD Pattern 5 test"),
303 Duration::QUICK);
304
305 AddTestCase(
306 new LtePhyPatternTestCase("DL|S|UL|UL|UL|DL|S|UL|UL|DL|", "LTE TDD Pattern 6 test"),
307 Duration::QUICK);
308
309 AddTestCase(
310 new LtePhyPatternTestCase("DL|S|UL|UL|UL|DL|S|UL|UL|UL|", "LTE TDD Pattern 0 test"),
311 Duration::QUICK);
312
313 AddTestCase(new LtePhyPatternTestCase("F|F|F|F|F|F|F|F|F|F|", "LTE TDD Pattern NR test"),
314 Duration::QUICK);
315 }
316};
317
318static NrLtePatternsTestSuite nrLtePatternsTestSuite;
319
321
322} // namespace ns3
virtual void DoSlotDlIndication(const SfnSf &sfnSf, LteNrTddSlotType type)
Perform DL scheduling decision for the indicated slot.
virtual void SetCurrentSfn(const SfnSf &sfn)
Set the current sfn.
virtual void DoSlotUlIndication(const SfnSf &sfnSf, LteNrTddSlotType type)
Perform UL scheduling decision for the indicated slot.
static TypeId GetTypeId()
GetTypeId.
LteNrTddSlotType
Available TDD slot types. Ordering is important.
@ 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.
static NrLtePatternsTestSuite nrLtePatternsTestSuite
Pattern test suite.