-
Notifications
You must be signed in to change notification settings - Fork 0
/
hNRScheduler.m
2953 lines (2684 loc) · 159 KB
/
hNRScheduler.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
classdef (Abstract) hNRScheduler < handle
%hNRScheduler Implements physical uplink shared channel (PUSCH) and physical downlink shared channel (PDSCH) resource scheduling
% The class implements uplink (UL) and downlink (DL) scheduling for
% both FDD and TDD modes. It supports both slot based and symbol
% based scheduling. Scheduling is only done at slot boundary when
% start symbol is DL so that output (resource assignments) can be
% immediately conveyed to UEs in DL direction, assuming zero run time
% for scheduler algorithm. Hence, in frequency division duplex (FDD)
% mode the schedulers (DL and UL) run periodically (configurable) as
% every slot is DL while for time division duplex (TDD) mode, DL time
% is checked. In FDD mode, schedulers run to assign the resources
% from the next unscheduled slot onwards and a count of slots equal
% to scheduler periodicity in terms of number of slots are scheduled.
% In TDD mode, the UL scheduler schedules the resources as close to
% the transmission time as possible. The DL scheduler in TDD mode
% runs to assign DL resources of the next slot with unscheduled DL
% resources. Scheduler does the UL resource allocation while
% considering the PUSCH preparation capability of UEs. Scheduling
% decisions are based on selected scheduling strategy, scheduler
% configuration and the context (buffer status, served data rate,
% channel conditions and pending retransmissions) maintained for each
% UE. The information available to scheduler for making scheduling
% decisions is present as various properties of this class. The class
% also implements the MAC portion of the HARQ functionality for
% retransmissions.
% Copyright 2020-2021 The MathWorks, Inc.
properties (SetAccess = protected, GetAccess = public)
%UEs RNTIs of the UEs connected to the gNB
UEs {mustBeInteger, mustBeInRange(UEs, 1, 65519)};
%SCS Subcarrier spacing used. The default value is 15 kHz
SCS (1, 1) {mustBeMember(SCS, [15, 30, 60, 120, 240])} = 15;
%Slot duration in ms
SlotDuration
%NumSlotsFrame Number of slots in a 10 ms frame. Depends on the SCS used
NumSlotsFrame
%ULReservedResource Reserved resources information for UL direction
% Array of three elements: [symNum slotPeriodicity slotOffset].
% These symbols are not available for PUSCH scheduling as per the
% slot offset and periodicity. Currently, it is used for SRS
% resources reservation
ULReservedResource
%SchedulingType Type of scheduling (slot based or symbol based)
% Value 0 means slot based and value 1 means symbol based. The
% default value is 0
SchedulingType (1, 1) {mustBeInteger, mustBeInRange(SchedulingType, 0, 1)} = 0;
%DuplexMode Duplexing mode (FDD or TDD)
% Value 0 means FDD and 1 means TDD. The default value is 0
DuplexMode (1, 1) {mustBeInteger, mustBeInRange(DuplexMode, 0, 1)} = 0;
%NumDLULPatternSlots Number of slots in DL-UL pattern (for TDD mode)
% The default value is 5 slots
NumDLULPatternSlots (1, 1) {mustBeInteger, mustBeGreaterThanOrEqual(NumDLULPatternSlots, 0), mustBeFinite} = 5;
%NumDLSlots Number of full DL slots at the start of DL-UL pattern (for TDD mode)
% The default value is 2 slots
NumDLSlots (1, 1) {mustBeInteger, mustBeGreaterThanOrEqual(NumDLSlots, 0), mustBeFinite} = 2;
%NumDLSyms Number of DL symbols after full DL slots in the DL-UL pattern (for TDD mode)
% The default value is 8 symbols
NumDLSyms (1, 1) {mustBeInteger, mustBeInRange(NumDLSyms, 0, 13)} = 8;
%NumULSyms Number of UL symbols before full UL slots in the DL-UL pattern (for TDD mode)
% The default value is 4 symbols
NumULSyms (1, 1) {mustBeInteger, mustBeInRange(NumULSyms, 0, 13)} = 4;
%NumULSlots Number of full UL slots at the end of DL-UL pattern (for TDD mode)
% The default value is 2 slots
NumULSlots (1, 1) {mustBeInteger, mustBeGreaterThanOrEqual(NumULSlots, 0), mustBeFinite} = 2;
%DLULSlotFormat Format of the slots in DL-UL pattern (for TDD mode)
% N-by-14 matrix where 'N' is number of slots in DL-UL pattern.
% Each row contains the symbol type of the 14 symbols in the slot.
% Value 0, 1 and 2 represent DL symbol, UL symbol, guard symbol,
% respectively
DLULSlotFormat
%NextULSchedulingSlot Slot to be scheduled next by UL scheduler
% Slot number in the 10 ms frame whose resources will be scheduled
% when UL scheduler runs next (for TDD mode)
NextULSchedulingSlot
%NumPUSCHRBs Number of resource blocks (RB) in the uplink bandwidth
% The default value is 52 RBs
NumPUSCHRBs (1, 1){mustBeNonempty, mustBeInteger, mustBeInRange(NumPUSCHRBs, 1, 275)} = 52;
%NumPDSCHRBs Number of RBs in the downlink bandwidth
% The default value is 52 RBs
NumPDSCHRBs (1, 1){mustBeNonempty, mustBeInteger, mustBeInRange(NumPDSCHRBs, 1, 275)} = 52;
%XOverheadPDSCH Additional overheads in PDSCH transmission
XOverheadPDSCH = 6;
%RBGSizeUL Size of an uplink resource block group (RBG) in terms of number of RBs
RBGSizeUL
%RBGSizeDL Size of a downlink RBG in terms of number of RBs
RBGSizeDL
%NumRBGsUL Number of RBGs in uplink bandwidth
NumRBGsUL
%NumRBGsDL Number of RBGs in downlink bandwidth
NumRBGsDL
%RBAllocationLimitUL Maximum limit on number of RBs that can be allotted for a PUSCH
% The limit is applicable for new PUSCH transmissions and not for
% retransmissions
RBAllocationLimitUL {mustBeInteger, mustBeInRange(RBAllocationLimitUL, 1, 275)};
%RBAllocationLimitDL Maximum limit on number of RBs that can be allotted for a PDSCH
% The limit is applicable for new PDSCH transmissions and not for
% retransmissions
RBAllocationLimitDL {mustBeInteger, mustBeInRange(RBAllocationLimitDL, 1, 275)};
%SchedulerPeriodicity Periodicity at which the schedulers (DL and UL) run in terms of number of slots (for FDD mode)
% Default value is 1 slot
SchedulerPeriodicity {mustBeInteger, mustBeInRange(SchedulerPeriodicity, 1, 160)} = 1;
%PUSCHPrepSymDur PUSCH preparation time in terms of number of symbols
% Scheduler ensures that PUSCH grant arrives at UEs at least these
% many symbols before the transmission time
PUSCHPrepSymDur
%BufferStatusDL Stores pending buffer amount in DL direction for logical channels of UEs
% N-by-32 matrix where 'N' is the number of UEs. Each row represents a
% UE and has 32 columns to store the pending DL buffer (in bytes)
% for logical channel IDs 1 to 32
BufferStatusDL
%BufferStatusUL Stores pending buffer amount in UL direction for logical channel groups of UEs
% N-by-8 matrix where 'N' is the number of UEs. Each row represents a
% UE and has 8 columns to store the pending UL buffer amount (in
% bytes) for each logical channel group.
BufferStatusUL
%CQITableUL CQI table used for uplink
% It contains the mapping of CQI indices with Modulation and Coding
% schemes
CQITableUL
%MCSTableUL MCS table used for uplink
% It contains the mapping of MCS indices with Modulation and Coding
% schemes
MCSTableUL
%CQITableDL CQI table used for downlink
% It contains the mapping of CQI indices with Modulation and Coding
% schemes
CQITableDL
%MCSTableDL MCS table used for downlink
% It contains the mapping of MCS indices with Modulation and Coding
% schemes
MCSTableDL
%TTIGranularity Minimum time-domain assignment in terms of number of symbols (for symbol based scheduling).
% The default value is 4 symbols
TTIGranularity {mustBeMember(TTIGranularity, [2, 4, 7])} = 4;
%DMRSTypeAPosition Position of DM-RS in type A transmission
DMRSTypeAPosition (1, 1) {mustBeMember(DMRSTypeAPosition, [2, 3])} = 2;
%PUSCHMappingType PUSCH mapping type
PUSCHMappingType (1,1) {mustBeMember(PUSCHMappingType, ['A', 'B'])} = 'A';
%PUSCHDMRSConfigurationType PUSCH DM-RS configuration type (1 or 2)
PUSCHDMRSConfigurationType (1,1) {mustBeMember(PUSCHDMRSConfigurationType, [1, 2])} = 1;
%PUSCHDMRSLength PUSCH demodulation reference signal (DM-RS) length
PUSCHDMRSLength (1, 1) {mustBeMember(PUSCHDMRSLength, [1, 2])} = 1;
%PUSCHDMRSAdditionalPosTypeA Additional PUSCH DM-RS positions for type A (0..3)
PUSCHDMRSAdditionalPosTypeA (1, 1) {mustBeMember(PUSCHDMRSAdditionalPosTypeA, [0, 1, 2, 3])} = 0;
%PUSCHDMRSAdditionalPosTypeB Additional PUSCH DM-RS positions for type B (0..3)
PUSCHDMRSAdditionalPosTypeB (1, 1) {mustBeMember(PUSCHDMRSAdditionalPosTypeB, [0, 1, 2, 3])} = 0;
%PDSCHMappingType PDSCH mapping type
PDSCHMappingType (1, 1) {mustBeMember(PDSCHMappingType, ['A', 'B'])} = 'A';
%PDSCHDMRSConfigurationType PDSCH DM-RS configuration type (1 or 2)
PDSCHDMRSConfigurationType (1,1) {mustBeMember(PDSCHDMRSConfigurationType, [1, 2])} = 1;
%PDSCHDMRSLength PDSCH demodulation reference signal (DM-RS) length
PDSCHDMRSLength (1, 1) {mustBeMember(PDSCHDMRSLength, [1, 2])} = 1;
%PDSCHDMRSAdditionalPosTypeA Additional PDSCH DM-RS positions for type A (0..3)
PDSCHDMRSAdditionalPosTypeA (1, 1) {mustBeMember(PDSCHDMRSAdditionalPosTypeA, [0, 1, 2, 3])} = 0;
%PDSCHDMRSAdditionalPosTypeB Additional PDSCH DM-RS positions for type B (0 or 1)
PDSCHDMRSAdditionalPosTypeB (1, 1) {mustBeMember(PDSCHDMRSAdditionalPosTypeB, [0, 1])} = 0;
%CSIMeasurementDL Reported DL CSI measurements
% Array of size 'N', where 'N' is the number of UEs. Each element is a structure with the fields: 'RankIndicator', 'PMISet', 'CQI'
% RankIndicator is a scalar value to representing the rank reported by a UE.
% PMISet has the following fields:
% i1 - Indicates wideband PMI (1-based). It a three-element vector in the
% form of [i11 i12 i13].
% i2 - Indicates subband PMI (1-based). It is a vector of length equal to
% the number of subbands or number of PRGs.
% CQI - Array of size equal to number of RBs in the bandwidth. Each index
% contains the CQI value corresponding to the RB index.
CSIMeasurementDL
%CSIMeasurementUL Reported UL CSI measurements
% Array of size 'N', where 'N' is the number of UEs. Each element is a structure with the fields: 'RankIndicator', 'TPMI', 'CQI'
% RankIndicator is a scalar value to representing the rank estimated for a UE.
% TPMI - Transmission precoding matrix indicator
% CQI - Array of size equal to number of RBs in the bandwidth. Each index
% contains the CQI value corresponding to the RB index.
CSIMeasurementUL
%GNBTxAntPanel gNB Tx antenna panel geometry
% It is an array of the form [M, N, P, Mg, Ng] where M and N are
% the number of rows and columns in the antenna array, P is the
% number of polarizations (1 or 2), Mg and Ng are the number of row
% and column array panels, respectively
GNBTxAntPanel
%GNBRxAntPanel gNB Rx antenna panel geometry
% It is an array of the form [M, N, P, Mg, Ng] where M and N are
% the number of rows and columns in the antenna array, P is the
% number of polarizations (1 or 2), Mg and Ng are the number of row
% and column array panels, respectively
GNBRxAntPanel
%UEsTxAntPanel UEs' Tx antenna panel geometry
% It is an array of the form [M, N, P, Mg, Ng] for each UE, where M
% and N are the number of rows and columns in the antenna array, P
% is the number of polarizations (1 or 2), Mg and Ng are the number
% of row and column array panels, respectively
UEsTxAntPanel
%UEsRxAntPanel UEs' Rx antenna panel geometry
% It is an array of the form [M, N, P, Mg, Ng] for each UE where M
% and N are the number of rows and columns in the antenna array, P
% is the number of polarizations (1 or 2), Mg and Ng are the number
% of row and column array panels, respectively
UEsRxAntPanel
%NumCSIRSPorts Number of CSI-RS antenna ports for the UEs
% Vector of length 'N' where 'N' is the number of UEs. Value at
% index 'i' contains the number of CSI-RS ports for UE with RNTI
% 'i'
NumCSIRSPorts
%NumSRSPorts Number of SRS antenna ports for the UEs
% Vector of length 'N' where 'N' is the number of UEs. Value at
% index 'i' contains ths number of SRS ports for UE with RNTI 'i'
NumSRSPorts
%NumHARQ Number of HARQ processes
% The default value is 16 HARQ processes
NumHARQ (1, 1) {mustBeInteger, mustBeInRange(NumHARQ, 1, 16)} = 16;
%HarqProcessesUL Uplink HARQ processes context
% N-by-P structure array where 'N' is the number of UEs and 'P' is
% the number of HARQ processes. Each row in this matrix stores the
% context of all the uplink HARQ processes of a particular UE.
HarqProcessesUL
%HarqProcessesDL Downlink HARQ processes context
% N-by-P structure array where 'N' is the number of UEs and 'P' is
% the number of HARQ processes. Each row in this matrix stores the
% context of all the downlink HARQ processes of a particular UE.
HarqProcessesDL
%HarqStatusUL Status (free or busy) of each uplink HARQ process of the UEs
% N-by-P cell array where 'N' is the number of UEs and 'P' is the number
% of HARQ processes. A non-empty value at index (i,j) indicates
% that HARQ process is busy with value being the uplink grant for
% the UE with RNTI 'i' and HARQ index 'j'. Empty value indicates
% that the HARQ process is free.
HarqStatusUL
%HarqStatusDL Status (free or busy) of each downlink HARQ process of the UEs
% N-by-P cell array where 'N' is the number of UEs and 'P' is the number
% of HARQ processes. A non-empty value at index (i,j) indicates
% that HARQ process is busy with value being the downlink grant for
% the UE with RNTI 'i' and HARQ index 'j'. Empty value indicates
% that the HARQ process is free.
HarqStatusDL
%HarqNDIDL Last sent NDI value for the DL HARQ processes of the UEs
% N-by-P logical array where 'N' is the number of UEs and 'P' is the number
% of HARQ processes. Values at index (i,j) stores the last sent NDI
% for the UE with RNTI 'i' and DL HARQ process index 'j'
HarqNDIDL
%HarqNDIUL Last sent NDI value for the UL HARQ processes of the UEs
% N-by-P logical array where 'N' is the number of UEs and 'P' is the number
% of HARQ processes. Values at index (i,j) stores the last sent NDI
% for the UE with RNTI 'i' and UL HARQ process index 'j'
HarqNDIUL
%RetransmissionContextUL Information about uplink retransmission requirements of the UEs
% N-by-P cell array where 'N' is the number of UEs and 'P' is the
% number of HARQ processes. It stores the information of HARQ
% processes for which the reception failed at gNB. This information
% is used for assigning uplink grants for retransmissions. Each row
% corresponds to a UE and a non-empty value in one of its columns
% indicates that the reception has failed for this particular HARQ
% process governed by the column index. The value in the cell
% element would be uplink grant information used by the UE for the
% previous failed transmission
RetransmissionContextUL
%RetransmissionContextDL Information about downlink retransmission requirements of the UEs
% N-by-P cell array where 'N' is the number of UEs and 'P' is the
% number of HARQ processes. It stores the information of HARQ
% processes for which the reception failed at UE. This information
% is used for assigning downlink grants for retransmissions. Each
% row corresponds to a UE and a non-empty value in one of its
% columns indicates that the reception has failed for this
% particular HARQ process governed by the column index. The value
% in the cell element would be downlink grant information used by
% the gNB for the previous failed transmission
RetransmissionContextDL
%TBSizeDL Stores the size of transport block sent for DL HARQ processes
% N-by-P matrix where 'N' is the number of UEs and P is number of
% HARQ process. Value at index (i,j) stores size of transport block
% sent for UE with RNTI 'i' for HARQ process index 'j'.
% Value is 0 if DL HARQ process is free
TBSizeDL
%TBSizeUL Stores the size of transport block to be received for UL HARQ processes
% N-by-P matrix where 'N' is the number of UEs and P is number of
% HARQ process. Value at index (i,j) stores size of transport block
% to be received from UE with RNTI 'i' for HARQ process index 'j'.
% Value is 0, if no UL packet expected for HARQ process of the UE
TBSizeUL
end
properties (Access = protected)
%CurrSlot Current running slot number in the 10 ms frame at the time of scheduler invocation
CurrSlot = 0;
%CurrSymbol Current running symbol of the current slot at the time of scheduler invocation
CurrSymbol = 0;
%SFN System frame number (0 ... 1023) at the time of scheduler invocation
SFN = 0;
%CurrDLULSlotIndex Slot index of the current running slot in the DL-UL pattern at the time of scheduler invocation (for TDD mode)
CurrDLULSlotIndex = 0;
%SlotsSinceSchedulerRunDL Number of slots elapsed since last DL scheduler run (for FDD mode)
% It is incremented every slot and when it reaches the
% 'SchedulerPeriodicity', it is reset to zero and DL scheduler runs
SlotsSinceSchedulerRunDL
%SlotsSinceSchedulerRunUL Number of slots elapsed since last UL scheduler run (for FDD mode)
% It is incremented every slot and when it reaches the
% 'SchedulerPeriodicity', it is reset to zero and UL scheduler runs
SlotsSinceSchedulerRunUL
%LastSelectedUEUL The RNTI of UE which was assigned the last scheduled uplink RBG
LastSelectedUEUL = 0;
%LastSelectedUEDL The RNTI of UE which was assigned the last scheduled downlink RBG
LastSelectedUEDL = 0;
%GuardDuration Guard period in the DL-UL pattern in terms of number of symbols (for TDD mode)
GuardDuration
%Type1SinglePanelCodebook Type-1 single panel precoding matrix codebook
Type1SinglePanelCodebook = []
%PrecodingGranularity PDSCH precoding granularity in terms of physical resource blocks (PRBs)
PrecodingGranularity = 2
end
properties (Constant)
%NominalRBGSizePerBW Nominal RBG size for the specified bandwidth in accordance with 3GPP TS 38.214, Section 5.1.2.2.1
NominalRBGSizePerBW = [
36 2 4
72 4 8
144 8 16
275 16 16 ];
%DLType Value to specify downlink direction or downlink symbol type
DLType = 0;
%ULType Value to specify uplink direction or uplink symbol type
ULType = 1;
%GuardType Value to specify guard symbol type
GuardType = 2;
%SchedulerInput Format of the context that will be sent to the scheduling strategy
SchedulerInput = struct('LinkDir', 0, 'eligibleUEs', 1, 'slotNum', 0, 'startSym', 0, ...
'numSym', 0, 'RBGIndex', 0, 'RBGSize', 0, 'bufferStatus', 0, 'cqiRBG', 1, ...
'mcsRBG', 1, 'ttiDur', 1, 'UEs', 1, 'selectedRank', 1, 'lastSelectedUE', 1);
end
properties (Access = protected)
%% Transient object maintained for optimization
%PUSCHConfig nrPUSCHConfig object
PUSCHConfig
%PDSCHConfig nrPDSCHConfig object
PDSCHConfig
%CarrierConfigUL nrCarrierConfig object for UL
CarrierConfigUL
%CarrierConfigDL nrCarrierConfig object for DL
CarrierConfigDL
end
methods
function obj = hNRScheduler(param)
%hNRScheduler Construct gNB MAC scheduler object
%
% param is a structure including the following fields:
% NumUEs - Number of UEs in the cell
% DuplexMode - Duplexing mode: FDD (value 0) or TDD (value 1)
% SchedulingType - Slot based scheduling (value 0) or symbol based scheduling (value 1)
% TTIGranularity - Smallest TTI size in terms of number of symbols (for symbol based scheduling)
% NumRBs - Number of resource blocks in PUSCH and PDSCH bandwidth
% SCS - Subcarrier spacing
% SchedulerPeriodicity - Scheduler run periodicity in slots (for FDD mode)
% RBAllocationLimitUL - Maximum limit on the number of RBs allotted to a UE for a PUSCH
% RBAllocationLimitDL - Maximum limit on the number of RBs allotted to a UE for a PDSCH
% NumHARQ - Number of HARQ processes
% EnableHARQ - Flag to enable/disable retransmissions
% DLULPeriodicity - Duration of the DL-UL pattern in ms (for TDD mode)
% NumDLSlots - Number of full DL slots at the start of DL-UL pattern (for TDD mode)
% NumDLSyms - Number of DL symbols after full DL slots of DL-UL pattern (for TDD mode)
% NumULSyms - Number of UL symbols before full UL slots of DL-UL pattern (for TDD mode)
% NumULSlots - Number of full UL slots at the end of DL-UL pattern (for TDD mode)
% PUSCHPrepTime - PUSCH preparation time required by UEs (in microseconds)
% RBGSizeConfig - RBG size configuration as 1 (configuration-1 RBG table) or 2
% (configuration-2 RBG table) as defined in 3GPP TS 38.214 Section 5.1.2.2.1. It
% defines the number of RBs in an RBG. Default value is 1
% DMRSTypeAPosition - DM-RS type A position (2 or 3)
% PUSCHMappingType - PUSCH mapping type ('A' or 'B')
% PUSCHDMRSConfigurationType - PUSCH DM-RS configuration type (1 or 2)
% PUSCHDMRSLength - PUSCH DM-RS length (1 or 2)
% PUSCHDMRSAdditionalPosTypeA - Additional PUSCH DM-RS positions for Type A (0..3)
% PUSCHDMRSAdditionalPosTypeB - Additional PUSCH DM-RS positions for Type B (0..3)
% PDSCHMappingType - PDSCH mapping type ('A' or 'B')
% PDSCHDMRSConfigurationType - PDSCH DM-RS configuration type (1 or 2)
% PDSCHDMRSLength - PDSCH DM-RS length (1 or 2)
% PDSCHDMRSAdditionalPosTypeA - Additional PDSCH DM-RS positions for Type A (0..3)
% PDSCHDMRSAdditionalPosTypeB - Additional PDSCH DM-RS positions for Type B (0 or 1)
% GNBTxAnts - Number of GNB Tx antennas
% GNBRxAnts - Number of GNB Rx antennas
% UETxAnts - Number of Tx antennas on UEs. Vector of length 'N' where N is number of UEs.
% Value at index 'i' contains Tx antennas at UE with RNTI 'i'
% UERxAnts - Number of Rx antennas on UEs. Vector of length 'N' where N is number of UEs.
% Value at index 'i' contains Rx antennas at UE with RNTI 'i'
% SRSConfig - Cell array of size equal to number of UEs. An element at index 'i' is an
% object of type nrSRSConfig and stores the SRS configuration of UE with RNTI 'i'
% CSIRSConfig - Cell array containing the CSI-RS configuration information as an object of
% type nrCSIRSConfig. The element at index 'i' corresponds to the CSI-RS
% configured for a UE with RNTI 'i'. If only one configuration is specified,
% it is assumed to be applicable for all the UEs in the cell.
% CSIReportConfig - Cell array containing the CSI-RS report configuration information as a
% structure. The element at index 'i' corresponds to the CSI-RS report
% configured for a UE with RNTI 'i'. If only one CSI-RS report configuration
% is specified, it is assumed to be applicable for all the UEs in the cell.
% Each element is a structure with the following fields:
% CQIMode - CQI reporting mode. Value as 'Subband' or 'Wideband'
% SubbandSize - Subband size for CQI or PMI reporting as per TS
% 38.214 Table 5.2.1.4-2
% Additional fields for MIMO systems:
% PanelDimensions - Antenna panel configuration as a two-element vector
% in the form of [N1 N2].
% N1 represents the number of antenna elements in
% horizontal direction and N2 represents the number
% of antenna elements in vertical direction.
% Valid combinations of [N1 N2] are defined in 3GPP
% TS 38.214 Table 5.2.2.2.1-2
% PMIMode - PMI reporting mode. Value as 'Subband' or 'Wideband'
% CodebookMode - Codebook mode. Value as 1 or 2
% SRSSubbandSize - SRS subband size (in RBs)
% Initialize the class properties
% Validate the number of UEs
validateattributes(param.NumUEs, {'numeric'}, {'nonempty', ...
'integer', 'scalar', '>', 0, '<=', 65519}, 'param.NumUEs', 'NumUEs');
% UEs are assumed to have sequential radio network temporary
% identifiers (RNTIs) from 1 to NumUEs
obj.UEs = 1:param.NumUEs;
if isfield(param, 'SCS')
obj.SCS = param.SCS;
end
obj.SlotDuration = 1/(obj.SCS/15); % In ms
obj.NumSlotsFrame = 10/obj.SlotDuration; % Number of slots in a 10 ms frame
if isfield(param, 'PUSCHPrepTime')
validateattributes(param.PUSCHPrepTime, {'numeric'}, ...
{'nonempty', 'integer', 'scalar', 'finite', '>=', 0}, ...
'param.PUSCHPrepTime', 'PUSCHPrepTime');
obj.PUSCHPrepSymDur = ceil(param.PUSCHPrepTime/((obj.SlotDuration*1000)/14));
else
% Default value is 200 microseconds
obj.PUSCHPrepSymDur = ceil(200/((obj.SlotDuration*1000)/14));
end
if isfield(param, 'SchedulingType')
obj.SchedulingType = param.SchedulingType;
end
if obj.SchedulingType % Symbol based scheduling
% Set TTI granularity
if isfield(param, 'TTIGranularity')
obj.TTIGranularity = param.TTIGranularity;
end
end
populateDuplexModeProperties(obj, param);
if isfield(param, 'RBAllocationLimitUL')
validateattributes(param.RBAllocationLimitUL, {'numeric'}, ...
{'nonempty', 'integer', 'scalar', '>=', 1, '<=',obj.NumPUSCHRBs},...
'param.RBAllocationLimitUL', 'RBAllocationLimitUL');
obj.RBAllocationLimitUL = param.RBAllocationLimitUL;
else
% Set RB limit to half of the total number of RBs
obj.RBAllocationLimitUL = floor(obj.NumPUSCHRBs * 0.5);
end
if isfield(param, 'RBAllocationLimitDL')
validateattributes(param.RBAllocationLimitDL, {'numeric'}, ...
{'nonempty', 'integer', 'scalar', '>=', 1, '<=',obj.NumPDSCHRBs},...
'param.RBAllocationLimitDL', 'RBAllocationLimitDL');
obj.RBAllocationLimitDL = param.RBAllocationLimitDL;
else
% Set RB limit to half of the total number of RBs
obj.RBAllocationLimitDL = floor(obj.NumPDSCHRBs * 0.5);
end
numUEs = length(obj.UEs);
if ~isfield(param, 'GNBTxAnts')
param.GNBTxAnts = 1;
% Validate the number of transmitter antennas on gNB
elseif ~ismember(param.GNBTxAnts, [1,2,4,8,16,32,64,128,256,512,1024])
error('nr5g:hNRScheduler:InvalidAntennaSize',...
'Number of gNB Tx antennas (%d) must be a member of [1,2,4,8,16,32,64,128,256,512,1024].', param.GNBTxAnts);
end
if ~isfield(param, 'GNBRxAnts')
param.GNBRxAnts = 1;
% Validate the number of receiver antennas on gNB
elseif ~ismember(param.GNBRxAnts, [1,2,4,8,16,32,64,128,256,512,1024])
error('nr5g:hNRScheduler:InvalidAntennaSize',...
'Number of gNB Rx antennas (%d) must be a member of [1,2,4,8,16,32,64,128,256,512,1024].', param.GNBRxAnts);
end
if ~isfield(param, 'UETxAnts')
param.UETxAnts = ones(param.NumUEs, 1);
% Validate the number of transmitter antennas on UEs
else
validateattributes(param.UETxAnts, {'numeric'}, {'nonempty', 'integer', 'nrows', param.NumUEs, 'ncols', 1, 'finite'}, 'param.UETxAnts', 'UETxAnts')
if any(~ismember(param.UETxAnts, [1,2,4,8,16]))
error('nr5g:hNRScheduler:InvalidAntennaSize',...
'Number of UE Tx antennas must be a member of [1,2,4,8,16].');
end
end
if ~isfield(param, 'UERxAnts')
param.UERxAnts = ones(param.NumUEs, 1);
% Validate the number of receiver antennas on UEs
else
validateattributes(param.UERxAnts, {'numeric'}, {'nonempty', 'integer', 'nrows', param.NumUEs, 'ncols', 1, 'finite'}, 'param.UERxAnts', 'UERxAnts')
if any(~ismember(param.UERxAnts, [1,2,4,8,16]))
error('nr5g:hNRScheduler:InvalidAntennaSize',...
'Number of UE Rx antennas must be a member of [1,2,4,8,16].');
end
end
% Turn the overall number of antennas into a specific antenna panel
% array geometry
for i=1:numUEs
% Downlink direction i.e. gNB's Tx antenna panel
% configuration and UE's Rx panel configuration
[obj.GNBTxAntPanel, obj.UEsRxAntPanel(i, :)] = ...
hArrayGeometry(param.GNBTxAnts, param.UERxAnts(i), 'downlink');
% Uplink direction i.e. UE's Tx antenna panel
% configuration and gNB's Rx panel configuration
[obj.UEsTxAntPanel(i, :), obj.GNBRxAntPanel] = ...
hArrayGeometry(param.UETxAnts(i), param.GNBRxAnts, 'uplink');
end
obj.BufferStatusDL = zeros(numUEs, 32); % 32 logical channels
obj.BufferStatusUL = zeros(numUEs, 8); % 8 logical channel groups
% Store the CQI tables as matrices
obj.CQITableUL = getCQITableUL(obj);
obj.CQITableDL = getCQITableDL(obj);
% Context initialization for HARQ processes
if isfield(param, 'NumHARQ')
obj.NumHARQ = param.NumHARQ;
end
harqProcess.RVSequence = [0 3 2 1]; % Set RV sequence
% Validate the flag to enable/disable HARQ
if isfield(param, 'EnableHARQ')
% To support true/false
validateattributes(param.EnableHARQ, {'logical', 'numeric'}, {'nonempty', 'integer', 'scalar'}, 'param.EnableHARQ', 'EnableHARQ');
if isnumeric(param.EnableHARQ)
% To support 0/1
validateattributes(param.EnableHARQ, {'numeric'}, {'>=', 0, '<=', 1}, 'param.EnableHARQ', 'EnableHARQ');
end
if ~param.EnableHARQ
% No retransmissions
harqProcess.RVSequence = 0; % Set RV sequence
end
end
ncw = 1; % Only single codeword
harqProcess.ncw = ncw; % Set number of codewords
harqProcess.blkerr = zeros(1, ncw); % Initialize block errors
harqProcess.RVIdx = ones(1, ncw); % Add RVIdx to process
harqProcess.RV = harqProcess.RVSequence(ones(1,ncw));
% Create HARQ processes context array for each UE
obj.HarqProcessesUL = repmat(harqProcess, numUEs, obj.NumHARQ);
obj.HarqProcessesDL = repmat(harqProcess, numUEs, obj.NumHARQ);
for i=1:numUEs
obj.HarqProcessesUL(i,:) = hNewHARQProcesses(obj.NumHARQ, harqProcess.RVSequence, ncw);
obj.HarqProcessesDL(i,:) = hNewHARQProcesses(obj.NumHARQ, harqProcess.RVSequence, ncw);
end
% Initialize HARQ status and NDI
obj.HarqStatusUL = cell(numUEs, obj.NumHARQ);
obj.HarqStatusDL = cell(numUEs, obj.NumHARQ);
obj.HarqNDIUL = false(numUEs, obj.NumHARQ);
obj.HarqNDIDL = false(numUEs, obj.NumHARQ);
% Create retransmission context
obj.RetransmissionContextUL = cell(numUEs, obj.NumHARQ);
obj.RetransmissionContextDL = cell(numUEs, obj.NumHARQ);
obj.TBSizeDL = zeros(numUEs, obj.NumHARQ);
obj.TBSizeUL = zeros(numUEs, obj.NumHARQ);
if isfield(param, 'DMRSTypeAPosition')
obj.DMRSTypeAPosition = param.DMRSTypeAPosition;
end
% PUSCH DM-RS configuration
if isfield(param, 'PUSCHDMRSConfigurationType')
obj.PUSCHDMRSConfigurationType = param.PUSCHDMRSConfigurationType;
end
if isfield(param, 'PUSCHMappingType')
obj.PUSCHMappingType = param.PUSCHMappingType;
end
if isfield(param, 'PUSCHDMRSLength')
obj.PUSCHDMRSLength = param.PUSCHDMRSLength;
end
if isfield(param, 'PUSCHDMRSAdditionalPosTypeA')
obj.PUSCHDMRSAdditionalPosTypeA = param.PUSCHDMRSAdditionalPosTypeA;
end
if isfield(param, 'PUSCHDMRSAdditionalPosTypeB')
obj.PUSCHDMRSAdditionalPosTypeB = param.PUSCHDMRSAdditionalPosTypeB;
end
% PDSCH DM-RS configuration
if isfield(param, 'PDSCHDMRSConfigurationType')
obj.PDSCHDMRSConfigurationType = param.PDSCHDMRSConfigurationType;
end
if isfield(param, 'PDSCHMappingType')
obj.PDSCHMappingType = param.PDSCHMappingType;
end
if isfield(param, 'PDSCHDMRSLength')
obj.PDSCHDMRSLength = param.PDSCHDMRSLength;
end
if isfield(param, 'PDSCHDMRSAdditionalPosTypeA')
obj.PDSCHDMRSAdditionalPosTypeA = param.PDSCHDMRSAdditionalPosTypeA;
end
if isfield(param, 'PDSCHDMRSAdditionalPosTypeB')
obj.PDSCHDMRSAdditionalPosTypeB = param.PDSCHDMRSAdditionalPosTypeB;
end
obj.NumSRSPorts = ones(numUEs, 1);
if isfield(param, 'SRSConfig')
for srsIdx = 1:length(param.SRSConfig)
if ~isa(param.SRSConfig{srsIdx}, 'nrSRSConfig')
error('nr5g:hNRScheduler:InvalidObjectType', "Each element of 'SRSConfig' must be specified as an object of type nrSRSConfig")
end
if param.SRSConfig{srsIdx}.NumSRSPorts > param.UETxAnts(srsIdx)
error('nr5g:hNRScheduler:InvalidNumSRSPorts', 'Number of SRS antenna ports (%d) must be less than or equal to the number of UE Tx antennas.(%d)',...
param.SRSConfig{srsIdx}.NumSRSPorts, param.UETxAnts(srsIdx))
end
end
% Mark UL reserved resources for SRS
obj.ULReservedResource = [param.SRSConfig{1}.SymbolStart param.SRSConfig{1}.SRSPeriod(1) param.SRSConfig{1}.SRSPeriod(2)];
idx = 1;
obj.NumSRSPorts(1) = param.SRSConfig{1}.NumSRSPorts;
for srsIdx = 2:length(param.SRSConfig)
ulReservedResource = [param.SRSConfig{srsIdx}.SymbolStart param.SRSConfig{srsIdx}.SRSPeriod(1) param.SRSConfig{srsIdx}.SRSPeriod(2)];
% Check if UL resource is already reserved
if ~ismember(ulReservedResource, obj.ULReservedResource, 'rows')
idx = idx + 1;
obj.ULReservedResource(idx, :) = ulReservedResource;
end
obj.NumSRSPorts(srsIdx) = param.SRSConfig{srsIdx}.NumSRSPorts;
end
end
% Pre-calculate type-1 single panel precoding matrix codebook based on the CSI report configuration
if isfield(param, 'CSIRSConfig')
for idx = 1:length(param.CSIRSConfig)
if ~isa(param.CSIRSConfig{idx}, 'nrCSIRSConfig')
error('nr5g:hNRScheduler:InvalidObjectType', "Each element of 'CSIRSConfig' must be specified as an object of type nrCSIRSConfig")
end
end
csirsConfig = param.CSIRSConfig;
obj.NumCSIRSPorts = csirsConfig{1}.NumCSIRSPorts*ones(numUEs,1);
% Validate the number of CSI-RS ports for the given gNB antenna
% configuration
for csirsIdx = 1:length(csirsConfig)
if csirsConfig{csirsIdx}.NumCSIRSPorts > param.GNBTxAnts
error('nr5g:hNRScheduler:InvalidCSIRSRowNumber',...
'Number of CSI-RS ports (%d) corresponding to CSI-RS row number (%d) must be less than or equal to GNBTxAnts (%d)',...
csirsConfig{csirsIdx}.NumCSIRSPorts, csirsConfig{csirsIdx}.RowNumber, param.GNBTxAnts);
else
obj.NumCSIRSPorts(csirsIdx) = csirsConfig{csirsIdx}.NumCSIRSPorts;
end
end
else
csirsConfig = {nrCSIRSConfig};
csirsConfig{1}.RowNumber = 2; % SISO case
obj.NumCSIRSPorts = ones(numUEs,1);
end
if isfield(param, 'CSIReportConfig')
if length(param.CSIReportConfig) == 1
% If 'param.CSIReportConfig' is of length 1 then assume
% that report config is common for all the UEs
param.CSIReportConfig(1:numUEs) = param.CSIReportConfig(1);
end
maxRank = 8;
obj.Type1SinglePanelCodebook = cell(numUEs, maxRank);
for idx=1:length(param.CSIReportConfig)
if isfield(param.CSIReportConfig{idx}, 'PanelDimensions') && obj.NumCSIRSPorts(idx) ~= 2*prod(param.CSIReportConfig{idx}.PanelDimensions)
error('nr5g:hNRScheduler:InvalidPanelDimension',...
'Number of CSI-RS ports (%d) as per the CSI-RS row number must match to the number of CSI-RS ports (%d) as per the panel dimensions.',...
obj.NumCSIRSPorts(idx), 2*prod(param.CSIReportConfig{idx}.PanelDimensions));
end
if ~isfield(param.CSIReportConfig{idx}, 'CodebookSubsetRestriction')
param.CSIReportConfig{idx}.CodebookSubsetRestriction = [];
end
if ~isfield(param.CSIReportConfig{idx}, 'i2Restriction')
param.CSIReportConfig{idx}.i2Restriction = [];
end
param.CSIReportConfig{idx}.NStartBWP = 0;
param.CSIReportConfig{idx}.NSizeBWP = param.NumRBs;
% Set oversampling factors
O1 = 1;
O2 = 1;
if(obj.NumCSIRSPorts(idx) > 2)
% Supported panel configurations and oversampling factors as per
% TS 38.214 Table 5.2.2.2.1-2
panelConfigs = [2 2 4 3 6 4 8 4 6 12 4 8 16 % N1
1 2 1 2 1 2 1 3 2 1 4 2 1 % N2
4 4 4 4 4 4 4 4 4 4 4 4 4 % O1
1 4 1 4 1 4 1 4 4 1 4 4 1]; % O2
configIdx = find(panelConfigs(1,:) == param.CSIReportConfig{idx}.PanelDimensions(1) & panelConfigs(2,:) == param.CSIReportConfig{idx}.PanelDimensions(2),1);
if isempty(configIdx)
error('nr5g:hNRScheduler:InvalidPanelDimension',['The given panel configuration ['...
num2str(param.CSIReportConfig{idx}.PanelDimensions(1)) ' ' num2str(param.CSIReportConfig{idx}.PanelDimensions(2)) '] is not valid. '...
'For a number of CSI-RS ports, the panel configuration should be one of the possibilities from TS 38.214 Table 5.2.2.2.1-2.']);
end
% Extract the oversampling factors
O1 = panelConfigs(3,configIdx);
O2 = panelConfigs(4,configIdx);
end
param.CSIReportConfig{idx}.OverSamplingFactors = [O1 O2];
% Get Type-1 single panel codebook
if obj.NumCSIRSPorts(idx) > 1
% Codebooks for all possible ranks (1-8)
for rank = 1:maxRank % For all ranks limited by the CSI-RS port count
obj.Type1SinglePanelCodebook{idx, rank}= hPMIType1SinglePanelCodebook(param.CSIReportConfig{idx}, rank); % Get precoding codebook
end
end
end
end
% CSI measurements initialization
obj.CSIMeasurementDL = repmat(struct('RankIndicator', [], 'PMISet', [], 'CQI', []), numUEs, 1);
obj.CSIMeasurementUL = repmat(struct('RankIndicator', [], 'TPMI', [], 'CQI', []), numUEs, 1);
initialRank = 1; % Initial ranks for UEs
for i=1:numUEs
obj.CSIMeasurementDL(i).RankIndicator = initialRank;
obj.CSIMeasurementUL(i).RankIndicator = initialRank;
% Initialize the PMI fields (i11, i12, i13, i2). They get
% overwritten with reception of CSI report
if isfield(param, 'CSIReportConfig') && isfield(param.CSIReportConfig{i}, 'SubbandSize')
numSubbands = ceil(obj.NumPDSCHRBs/param.CSIReportConfig{i}.SubbandSize);
% Initialize i11, i12, i13, i2 for each UE
obj.CSIMeasurementDL(i).PMISet = struct('i1', [1 1 1], 'i2', ones(numSubbands,1));
else % Wideband PMI
obj.CSIMeasurementDL(i).PMISet = struct('i1', [1 1 1], 'i2', 1);
end
if ~isfield(param, 'SRSSubbandSize')
param.SRSSubbandSize = 4;
else
validateattributes(param.SRSSubbandSize, {'numeric'},...
{'scalar', 'integer', '>', 0, '<=', param.NumRBs}, 'param.SRSSubbandSize', 'SRSSubbandSize')
end
numSRSSubbands = ceil(obj.NumPUSCHRBs/param.SRSSubbandSize);
obj.CSIMeasurementUL(i).TPMI = zeros(numSRSSubbands,1);
% Initialize DL and UL channel quality as CQI index 7
obj.CSIMeasurementDL(i).CQI = 7*ones(1, obj.NumPDSCHRBs);
obj.CSIMeasurementUL(i).CQI = 7*ones(1, obj.NumPUSCHRBs);
end
% Set the MCS tables as matrices
obj.MCSTableUL = getMCSTableUL(obj);
obj.MCSTableDL = getMCSTableDL(obj);
% Create carrier configuration object for UL
obj.CarrierConfigUL = nrCarrierConfig;
obj.CarrierConfigUL.SubcarrierSpacing = obj.SCS;
obj.CarrierConfigUL.NSizeGrid = obj.NumPUSCHRBs;
% Create carrier configuration object for DL
obj.CarrierConfigDL = obj.CarrierConfigUL;
obj.CarrierConfigDL.NSizeGrid = obj.NumPDSCHRBs;
% Create PUSCH and PDSCH configuration objects and use them to
% optimize performance
obj.PUSCHConfig = nrPUSCHConfig;
obj.PUSCHConfig.DMRS = nrPUSCHDMRSConfig('DMRSConfigurationType', obj.PUSCHDMRSConfigurationType, ...
'DMRSTypeAPosition', obj.DMRSTypeAPosition, 'DMRSLength', obj.PUSCHDMRSLength);
obj.PDSCHConfig = nrPDSCHConfig;
obj.PDSCHConfig.DMRS = nrPDSCHDMRSConfig('DMRSConfigurationType', obj.PDSCHDMRSConfigurationType, ...
'DMRSTypeAPosition', obj.DMRSTypeAPosition, 'DMRSLength', obj.PDSCHDMRSLength);
end
function resourceAssignments = runDLScheduler(obj, currentTimeInfo)
%runDLScheduler Run the DL scheduler
%
% RESOURCEASSIGNMENTS = runDLScheduler(OBJ) runs the DL scheduler
% and returns the resource assignments structure array.
%
% CURRENTTIMEINFO is the information passed to scheduler for
% scheduling. It is a structure with following fields:
% SFN - Current system frame number
% CurrSlot - Current slot number
% CurrSymbol - Current symbol number
%
% RESOURCEASSIGNMENTS is a structure that contains the
% DL resource assignments information.
% Set current time information before doing the scheduling
obj.CurrSlot = currentTimeInfo.CurrSlot;
obj.CurrSymbol = currentTimeInfo.CurrSymbol;
obj.SFN = currentTimeInfo.SFN;
if obj.DuplexMode == 1 % TDD
% Calculate DL-UL slot index in the DL-UL pattern
obj.CurrDLULSlotIndex = mod(obj.SFN*obj.NumSlotsFrame + obj.CurrSlot, obj.NumDLULPatternSlots);
end
% Select the slots to be scheduled and then schedule them
resourceAssignments = {};
numDLGrants = 0;
slotsToBeScheduled = selectDLSlotsToBeScheduled(obj);
for i=1:length(slotsToBeScheduled)
% Schedule each selected slot
slotDLGrants = scheduleDLResourcesSlot(obj, slotsToBeScheduled(i));
resourceAssignments(numDLGrants + 1 : numDLGrants + length(slotDLGrants)) = slotDLGrants(:);
numDLGrants = numDLGrants + length(slotDLGrants);
updateHARQContextDL(obj, slotDLGrants);
end
end
function resourceAssignments = runULScheduler(obj, currentTimeInfo)
%runULScheduler Run the UL scheduler
%
% RESOURCEASSIGNMENTS = runULScheduler(OBJ) runs the UL scheduler
% and returns the resource assignments structure array.
%
% CURRENTTIMEINFO is the information passed to scheduler for
% scheduling. It is a structure with following fields:
% SFN - Current system frame number
% CurrSlot - Current slot number
% CurrSymbol - Current symbol number
%
% RESOURCEASSIGNMENTS is a structure that contains the
% UL resource assignments information.
%Set current time information before doing the scheduling
obj.CurrSlot = currentTimeInfo.CurrSlot;
obj.CurrSymbol = currentTimeInfo.CurrSymbol;
obj.SFN = currentTimeInfo.SFN;
if obj.DuplexMode == 1 % TDD
% Calculate current DL-UL slot index in the DL-UL pattern
obj.CurrDLULSlotIndex = mod(obj.SFN*obj.NumSlotsFrame + obj.CurrSlot, obj.NumDLULPatternSlots);
end
% Select the slots to be scheduled now and schedule them
resourceAssignments = {};
numULGrants = 0;
slotsToBeSched = selectULSlotsToBeScheduled(obj); % Select the set of slots to be scheduled in this UL scheduler run
for i=1:length(slotsToBeSched)
% Schedule each selected slot
slotULGrants = scheduleULResourcesSlot(obj, slotsToBeSched(i));
resourceAssignments(numULGrants + 1 : numULGrants + length(slotULGrants)) = slotULGrants(:);
numULGrants = numULGrants + length(slotULGrants);
updateHARQContextUL(obj, slotULGrants);
end
if obj.DuplexMode == 1 % TDD
% Update the next to-be-scheduled UL slot. Next UL
% scheduler run starts assigning resources this slot
% onwards
if ~isempty(slotsToBeSched)
% If any UL slots are scheduled, set the next
% to-be-scheduled UL slot as the next UL slot after
% last scheduled UL slot
lastSchedULSlot = slotsToBeSched(end);
obj.NextULSchedulingSlot = getToBeSchedULSlotNextRun(obj, lastSchedULSlot);
end
end
end
function updateLCBufferStatusDL(obj, lcBufferStatus)
%updateLCBufferStatusDL Update DL buffer status for a logical channel of the specified UE
%
% updateLCBufferStatusDL(obj, LCBUFFERSTATUS) updates the
% DL buffer status for a logical channel of the specified UE.
%
% LCBUFFERSTATUS is a structure with following three fields.
% RNTI - RNTI of the UE
% LogicalChannelID - Logical channel ID
% BufferStatus - Pending amount in bytes for the specified logical channel of UE
obj.BufferStatusDL(lcBufferStatus.RNTI, lcBufferStatus.LogicalChannelID) = lcBufferStatus.BufferStatus;
end
function processMACControlElement(obj, macCEInfo)
%processMACControlElement Process the received MAC control element
%
% processMACControlElement(OBJ, MACCEINFO) processes the
% received MAC control element (CE). This interface currently
% supports buffer status report (BSR) only. MACCEINFO is a
% structure with following fields.
% RNTI - RNTI of the UE which sent the MAC CE
% LCID - Logical channel ID of the MAC CE
% Packet - MAC CE
% Values 59, 60, 61, 62 represents LCIDs corresponding to
% different BSR formats as per 3GPP TS 38.321
if(macCEInfo.LCID == 59 || macCEInfo.LCID == 60 || macCEInfo.LCID == 61 || macCEInfo.LCID == 62)
[lcgIDList, bufferSizeList] = hNRMACBSRParser(macCEInfo.LCID, macCEInfo.Packet);
obj.BufferStatusUL(macCEInfo.RNTI, lcgIDList+1) = bufferSizeList;
end
end
function updateChannelQualityUL(obj, channelQualityInfo)
%updateChannelQualityUL Update uplink channel quality information for a UE
% UPDATECHANNELQUALITYUL(OBJ, CHANNELQUALITYINFO) updates
% uplink (UL) channel quality information for a UE.
% CHANNELQUALITYINFO is a structure with following fields.
% RNTI - RNTI of the UE
% RankIndicator - Rank indicator for the UE
% TPMI - Measured transmitted precoded matrix indicator (TPMI)
% CQI - CQI corresponding to RANK and TPMI. It is a
% vector of size 'N', where 'N' is number of RBs in UL
% bandwidth. Value at index 'i' represents CQI value at
% RB-index 'i'
obj.CSIMeasurementUL(channelQualityInfo.RNTI).CQI = channelQualityInfo.CQI;
if isfield(channelQualityInfo, 'TPMI')
obj.CSIMeasurementUL(channelQualityInfo.RNTI).TPMI = channelQualityInfo.TPMI;
end
if isfield(channelQualityInfo, 'RankIndicator')
obj.CSIMeasurementUL(channelQualityInfo.RNTI).RankIndicator = channelQualityInfo.RankIndicator;
end
end
function updateChannelQualityDL(obj, channelQualityInfo)
%updateChannelQualityDL Update downlink channel quality information for a UE
% UPDATECHANNELQUALITYDL(OBJ, CHANNELQUALITYINFO) updates
% downlink (DL) channel quality information for a UE.
% CHANNELQUALITYINFO is a structure with following fields.
% RNTI - RNTI of the UE
% RankIndicator - Rank indicator for the UE
% PMISet - Precoding matrix indicator. It is a structure with following fields.
% i1 - Indicates wideband PMI (1-based). It a three-element vector in the
% form of [i11 i12 i13].
% i2 - Indicates subband PMI (1-based). It is a vector of length equal to
% the number of subbands or number of PRGs.
% CQI - CQI corresponding to RANK and TPMI. It is a
% vector of size 'N', where 'N' is number of RBs in UL
% bandwidth. Value at index 'i' represents CQI value at
% RB-index 'i'
obj.CSIMeasurementDL(channelQualityInfo.RNTI).CQI = channelQualityInfo.CQI;
if isfield(channelQualityInfo, 'PMISet')
obj.CSIMeasurementDL(channelQualityInfo.RNTI).PMISet = channelQualityInfo.PMISet;
end
if isfield(channelQualityInfo, 'RankIndicator')
obj.CSIMeasurementDL(channelQualityInfo.RNTI).RankIndicator = channelQualityInfo.RankIndicator;
end