This example demonstrates the scheduling functionality of the medium access control (MAC) layer of the 5G New Radio (NR) stack. The scheduling strategy assigns physical uplink shared channel (PUSCH) and physical downlink shared channel (PDSCH) resources to a set of static user equipments (UEs) connected to a gNB. The example assumes time division duplexing (TDD) mode. Hence uplink (UL) and downlink (DL) transmissions are separated in time. This example also shows the functionality of the radio link control (RLC) layer in unacknowledged mode (UM). Note that this example abstracts the physical layer and adopts a probability-based approach using the assumed channel quality indicator (CQI) values to model packet reception failures. The performance of the scheduling strategy is evaluated in terms of achieved MAC throughput and the fairness in resource sharing.
This example shows how a scheduling strategy (controlled by the gNB) assigns UL and DL resources among the UEs. The example considers the following operations at gNB and UEs that facilitate UL and DL transmissions.
The control packets required are assumed to be sent out of band without the need of frequency resources for transmission. The control packets are UL assignment, DL assignment, buffer status report (BSR), and PDSCH feedback. These control packets follow the TDD DL and UL timings. For example, BSR and PDSCH feedback are sent in UL time while assignments are sent in DL time.
Demodulation reference signal (DM-RS) is not modeled in this example. However, two symbols for slot based scheduling and one symbol for symbol based scheduling is kept unused across the frequency domain of the assignments.
This example models:
Configurable TDD DL-UL pattern.
Slot based and symbol based DL and UL scheduling. UL scheduler ensures that the UEs get the required PUSCH preparation time.
Noncontiguous allocation of frequency domain resources in terms of resource block groups (RBGs).
Configurable subcarrier spacing (15, 30, 60, 120 kHz) resulting in different slot durations.
Asynchronous hybrid automatic repeat request (HARQ) mechanism.
UL reception success/failure detection by UEs using new data indicator (NDI) flag present in UL assignment.
DL reception success/failure detection by gNB using PDSCH feedback sent by UEs.
Periodic DL and UL application traffic pattern.
RLC operating in UM mode.
NR provides a flexible way of configuring the DL and UL resources. The parameters used to define a custom TDD configuration are:
DL-UL transmission periodicity in ms.
Reference subcarrier spacing to calculate the number of slots in the DL-UL pattern. In this example, it is assumed to be same as actual subcarrier spacing used for transmission.
Number of consecutive full DL slots at the beginning of each DL-UL pattern.
Number of consecutive DL symbols in the beginning of the slot following the last full DL slot.
Number of consecutive full UL slots at the end of each DL-UL pattern.
Number of consecutive UL symbols in the end of the slot preceding the first full UL slot.
The example does not model flexible symbols, so the symbols with unspecified symbol type are assumed for guard period. Here is an example of resulting TDD DL-UL pattern based on these parameters. This DL-UL pattern repeats itself in the timeline.
reference_scs
= 15 kHz (i.e. 1 ms slot), DLULPeriodicity
= 5 ms, numDLSlots
= 3, numDLSyms
= 7, numULSlots
= 1, numULSyms
= 5
Number of slots in DL-UL periodicity with respect to reference scs of 15 kHz, NumSlotsDLULPeriodicity
= 5
NumberOfGuardSymbols = TotalSymbolsInPattern - TotalSymbolsWithTypeSpecified
= (14 * NumSlotsDLULPeriodicity
) - (numDLSlots
*14 + numDLSyms
+ numULSyms
+ numULSlots
*14)
= 2 symbols
UL and DL schedulers distribute the UL and DL resources respectively among the UEs. You can choose any one of the implemented scheduling strategies: proportional fair (PF), best CQI, or round robin (RR). The various supported inputs to the schedulers are shown along with the scheduling strategies that consider them.
Both UL and DL schedulers run at the start of a slot when the first symbol is a DL symbol. Schedulers run in DL time so that assignments can be instantly sent to UEs in the DL direction. The run time of the scheduler algorithm as well as the propagation delay is assumed to be zero. The output of scheduling operations is an array of assignments. Each assignment contains the information fields to fully define a PUSCH/PDSCH transmission.
UL Scheduler
The UL scheduling operation follow these two steps.
Select slots to be scheduled: The criteria used in this example selects all the upcoming slots (including the current one) containing unscheduled UL symbols that must be scheduled now. These slots can be scheduled now but cannot be scheduled in the next slot with DL symbols, based on the PUSCH preparation time capability of the UEs. It ensures that the UL resources are scheduled as close as possible to the actual transmission time.
(i) Assuming that the UEs require PUSCH preparation time of 10 symbols, when the UL scheduler runs in Slot-A, it does not select any slot for scheduling. Because scheduling in the next slot with DL symbols (i.e. Slot-B) provides enough PUSCH preparation time (14 symbols) for the UL transmission in Slot-C. Later, when the UL scheduler runs in Slot-B, it selects both Slot-C and Slot-D for scheduling. Slot-D is not scheduled in Slot-C because Slot-C does not have any DL symbols for sending the assignments in the DL direction.
(ii) Assuming that the UEs require PUSCH preparation time of 16 symbols, Slot-C is scheduled in Slot-A itself. Because scheduling in Slot-B would only provide 14 symbols of PUSCH preparation time to start transmission in Slot-C. Slot-D is scheduled in Slot-B.
2. Resource scheduling: If any slots are selected in the first step, assign the UL resources of those slots to the UEs.
DL scheduler
The DL scheduler runs at each slot beginning with a DL symbol and assign resources of the first upcoming slot containing DL symbols. So, when DL scheduler runs at the start of Slot-A, it schedules DL resources of Slot-B.
NR allows the TTI to start at any symbol position in the slot and with TTI granularity in symbols. The figure shows the way UL scheduler operates in this example to schedule UL symbols of a slot with TTI granularity of two symbols. The slot shown contains six UL symbols. Scheduler completes the iteration of the UL symbols in three iterations with each iteration distributing the frequency resources of two symbols. The DL scheduler also follows a similar approach for DL scheduling.
Set the following key configuration parameters for the simulation:
Simulation time
Number of UEs
Scheduling type: slot based or symbol based
TDD DL-UL pattern configuration
Distance of UEs from gNB (affects the CQI values for the UEs)
UL and DL application traffic patterns
Logical channel configuration
Scheduling strategy: PF, Best CQI, RR
Periodicity of BSRs sent by UEs to inform gNB about pending buffer amount
PUSCH preparation time for UEs
Bandwidth in terms of number of resource blocks (RBs)
Subcarrier spacing: 15, 30, 60, 120 (kHz)
Initial channel quality and its update mechanism
Relation of successful reception probability with channel quality
rng('default'); % Reset the random number generator simParameters = []; % Clear simParameters variable simParameters.NumFramesSim = 100; % Simulation time in terms of number of 10 ms frames % Number of UEs in the simulation. UEs are assumed to have sequential radio % network temporary identifiers (RNTIs) from 1 to NumUEs. If you change the % number of UEs, ensure that the following simulation parameters are array % of length equal to NumUEs: simParameters.UEDistance, % simParameters.ULPacketPeriodicityUEs, simParameters.ULPacketSizesUEs, % simParameters.DLPacketPeriodicityUEs, simParameters.DLPacketSizesUEs, % simParameters.RLCConfig.SNFieldLength, % simParameters.RLCConfig.ReassemblyTimer, % simParameters.RLCConfig.MaxTxBufferLength simParameters.NumUEs = 4; % Set the value of scheduling type to 0 (slot based scheduling) or 1 % (symbol based scheduling). If value is not set, the default value is 0 simParameters.SchedulingType = 1; % Set the minimum time-domain assignment in terms of symbol duration. % Applicable only for symbol based scheduling. For slot based scheduling, % it is always full slot (14 symbols) simParameters.TTIGranularity = 4; % Define the TDD DL-UL pattern. The reference subcarrier spacing used for % calculating slot duration for the pattern is assumed to be same as actual % subcarrier spacing used for transmission as defined by simParameters.SCS. % Keep only the symbols intended for guard period during DLULPeriodicity % with type (DL or UL) unspecified simParameters.DLULPeriodicity = 5; % Duration of the DL-UL pattern in ms simParameters.NumDLSlots = 2; % Number of consecutive full DL slots at the beginning of each DL-UL pattern % Define the number of consecutive DL symbols following the full DL slots % and the number of consecutive UL symbols preceding the full UL slots. In % the case of slot based scheduling, only simParameters.NumDLSyms is % applicable and it defines the number of DL symbols at the start of the % slot, while the remaining symbols of the slot are assumed to be allotted % for guard period simParameters.NumDLSyms = 8; % Number of consecutive DL symbols in the beginning of the slot following the last full DL slot simParameters.NumULSyms = 4; % Number of consecutive UL symbols in the end of the slot preceding the first full UL slot simParameters.NumULSlots = 2; % Number of consecutive full UL slots at the end of each DL-UL pattern simParameters.UEDistance = [100; 400; 300; 700]; % Distance of UEs from gNB (in meters) % Mapping between distance from gNB (first column in meters) and maximum % achievable UL CQI value (second column). For example, if a UE is 700 % meters away from the gNB, it can achieve a maximum CQI value of 10 as the % distance falls within the [501, 800] meters range, as per the mapping. % Set the distance in increasing order and the maximum achievable CQI value % in decreasing order simParameters.CQIvsDistance = [ 200 15; 500 12; 800 10; 1000 8; 1200 7]; % Set the periodic UL and DL application traffic pattern for UEs simParameters.ULPacketPeriodicityUEs = [20; 30; 20; 30]; % Periodicity at which the UL packets are generated by UEs simParameters.ULPacketSizesUEs = [2000; 3000; 1500; 3000]; % Size of the UL packets (in bytes) generated by UEs simParameters.DLPacketPeriodicityUEs = [20; 15; 15; 20]; % Periodicity at which the DL packets are generated for UEs at gNB simParameters.DLPacketSizesUEs = [4000; 2500; 2500; 2000]; % Size of the DL packets generated (in bytes) for UEs at gNB % RLC configuration simParameters.RLCConfig.SNFieldLength = [6; 6; 6; 6]; % Sequence number field length (in bits) of the logical channel for each UE simParameters.RLCConfig.ReassemblyTimer = [5; 5; 5; 5]; % Reassembly timer (in ms) of the logical channel for each UE % Max buffer length of the logical channel for each UE (to model Tx buffer overflow) simParameters.RLCConfig.MaxTxBufferLength = [100000; 200000; 200000; 200000]; % MAC configuration simParameters.SchedulerStrategy = 'PF'; % Supported scheduling strategies: 'PF', 'RR' and 'BestCQI' % PUSCH preparation time. gNB ensures that PUSCH assignment is received at % UEs PUSCHPrepTime ahead of the transmission time simParameters.PUSCHPrepTime = 200; % In microseconds % Moving average weight parameter within the range [0, 1] calculates % average data rate for a UE. The value is used in the PF scheduling strategy. % Parameter value closer to 1 implies more weight on the instantaneous % data rate. Parameter value closer to 0 implies more weight on the past % data rate % AverageDataRate = ((1-MovingAvgDataRateWeight)*PastDataRate) + (MovingAvgDataRateWeight*InstantaneousDataRate) simParameters.MovingAvgDataRateWeight = 0.5; simParameters.EnableHARQ = true; % Flag to enable or disable HARQ. If disabled, there are no retransmissions simParameters.NumHARQ = 16; % Number of UL and DL HARQ processes for each UE % Maximum RBs allotted to a UE for PUSCH and PDSCH transmissions (limit is % applicable for new transmission assignments and not for the retransmissions) simParameters.RBAllocationLimitUL = 15; % For PUSCH simParameters.RBAllocationLimitDL = 15; % For PDSCH simParameters.BSRPeriodicity = 1; % Buffer status report transmission periodicity (in ms) % Physical layer and channel configuration % RB count for 5 MHz band with 15 kHz subcarrier spacing (SCS). The complete % bandwidth is assumed to be allotted for PUSCH/PDSCH simParameters.NumRBs = 25; simParameters.SCS = 15; % Configure parameters to update channel conditions for the UEs. Channel % quality is periodically improved or deteriorated by CQIDelta every % channelUpdatePeriodicity seconds for all RBs of a UE. Whether channel % conditions for a particular UE improve or deteriorate is randomly % determined: RB_CQI = RB_CQI +/- CQIDelta simParameters.ChannelUpdatePeriodicity = 0.2; % In sec simParameters.CQIDelta = 1; % Expression to calculate reception success probability of a PUSCH/PDSCH % packet based on the channel quality. 'x' represents the average CQI of % the RBs over which the packet is received simParameters.CQISuccessProb = '.5 + (x/20)'; % Logging and visualization configuration % Flag to enable or disable runtime CQI visualization simParameters.CQIVisualization = true; % Flag to enable or disable run time visualization of RB assignment. If enabled, % then for slot based scheduling it updates every frame (10 ms) to show RB % allocation to the UEs for different slots of the last frame. For % symbol based scheduling, it updates every slot to show RB allocation to % the UEs over different symbols of the last slot simParameters.RBVisualization = false; % The output metrics plots are updated periodically NumMetricsSteps times within the % simulation duration simParameters.NumMetricsSteps = 20; % MAT-files to write the logs into. They are used for post simulation analysis and visualization simParameters.ParametersLogFile = 'simParameters'; % For logging the simulation parameters simParameters.SimulationLogFile = 'simulationLogs'; % For logging the simulation logs hNRSchedulingTDDValidateConfig(simParameters); % Validate the simulation configuration
Based on the primary configuration parameters, compute the derived parameters. Additionally, set some example specific constants.
simParameters.DuplexMode = 1; % TDD (Example specific constant) simParameters.NumLogicalChannels = 1; % Only 1 logical channel is assumed in each UE (Example specific constant) slotDuration = 1/(simParameters.SCS/15); % Slot duration in ms numSlotsFrame = 10/slotDuration; % Number of slots in 10 ms frame numSlotsSim = simParameters.NumFramesSim * numSlotsFrame; % Simulation time in units of slot duration numSymbolsSim = numSlotsSim * 14; % Simulation time in units of symbol duration % Interval at which metrics visualization updates in terms of number of % slots. Make sure that MetricsStepSize is an integer simParameters.MetricsStepSize = ceil(numSlotsSim / simParameters.NumMetricsSteps); if mod(numSlotsSim, simParameters.NumMetricsSteps) ~= 0 % Update the NumMetricsSteps parameter if numSlotsSim is not % completely divisible by it simParameters.NumMetricsSteps = floor(numSlotsSim / simParameters.MetricsStepSize); end % DL and UL packet periodicities for UEs in terms of number of slots appPeriodicityUEsSlotsUL = simParameters.ULPacketPeriodicityUEs ./ slotDuration; appPeriodicityUEsSlotsDL = simParameters.DLPacketPeriodicityUEs ./ slotDuration; % Mapping between logical channel and logical channel group id simParameters.LCHConfig.LCGID = ones(simParameters.NumUEs, simParameters.NumLogicalChannels); % Priority of each logical channel simParameters.LCHConfig.Priority = ones(simParameters.NumUEs, simParameters.NumLogicalChannels); % Prioritized bitrate (in kilo bytes per second) of each logical channel simParameters.LCHConfig.PBR = 8*ones(simParameters.NumUEs, simParameters.NumLogicalChannels); % Bucket size duration (in ms) of each logical channel. However, the priority, % PBR and BSD for logical channel is not relevant with single logical % channel assumed in this example simParameters.LCHConfig.BSD = 10*ones(simParameters.NumUEs, simParameters.NumLogicalChannels); % Logical channel id simParameters.LCHConfig.LCID = ones(simParameters.NumUEs, simParameters.NumLogicalChannels) .* (1:simParameters.NumLogicalChannels); % RLC entity direction. Value 0 represents DL only, 1 % represents UL only and 2 represents both UL and DL % direction. Setting entity direction to have both UL and DL simParameters.RLCConfig.EntityDir = 2*ones(simParameters.NumUEs, simParameters.NumLogicalChannels); % Construct information for RLC logger lchInfo = repmat(struct('LCID',[],'EntityDir',[]), [simParameters.NumUEs 1]); for idx=1:simParameters.NumUEs lchInfo(idx).LCID = simParameters.LCHConfig.LCID(idx, :); lchInfo(idx).EntityDir = simParameters.RLCConfig.EntityDir(idx, :); end % Maximum RLC SDU length (in bytes) simParameters.maxRLCSDULength = 9000; % Calculate maximum achievable CQI value for the UEs based on their distance % from the gNB maxUECQIs = zeros(simParameters.NumUEs, 1); % To store the maximum achievable CQI value for UEs for ueIdx = 1:simParameters.NumUEs % Based on the distance of the UE from gNB, find matching row in CQIvsDistance mapping matchingRowIdx = find(simParameters.CQIvsDistance(:, 1) > simParameters.UEDistance(ueIdx)); if isempty(matchingRowIdx) maxUECQIs(ueIdx) = simParameters.CQIvsDistance(end, 2); else maxUECQIs(ueIdx) = simParameters.CQIvsDistance(matchingRowIdx(1), 2); end end % Periodicity of channel update in terms of number of slots channelUpdatePeriodicitySlots = floor((simParameters.ChannelUpdatePeriodicity * 1000)/... slotDuration); % Update periodicity of RB assignment visualization in terms of number of slots if ~isfield(simParameters, 'SchedulingType') || simParameters.SchedulingType == 0 % If no scheduling type is specified or slot based scheduling is specified rbAssignmentPlotPeriodicity = numSlotsFrame; % Update every frame (10 ms) else % Symbol based scheduling rbAssignmentPlotPeriodicity = 1; % Update every slot end
Create the gNB and UE objects, initialize the channel quality information for UEs and set up the logical channel at gNB and UE. The helper classes hNRGNB.m and hNRUE.m create gNB and UE node respectively, containing the RLC and MAC layer. For MAC layer, hNRGNB.m uses the helper class hNRGNBMAC.m to implement the gNB MAC functionality, and hNRUE.m uses hNRUEMAC.m to implement the UE MAC functionality. Scheduler is implemented in hNRGNBMACScheduler.m. For RLC layer, both hNRGNB.m and hNRUE.m use hNRUMTransmitter.m to implement the functionality of the RLC transmitter, and hNRUMReceiver.m to implement the functionality of the RLC receiver.
gNB = hNRGNB(simParameters); % Create the gNB node scheduler = hNRGNBMACScheduler(simParameters); % Create MAC scheduler addScheduler(gNB, scheduler); % Add scheduler to gNB % Create the set of UE nodes UEs = cell(simParameters.NumUEs, 1); for ueIdx=1:simParameters.NumUEs UEs{ueIdx} = hNRUE(simParameters, ueIdx); end % Define initial UL and DL channel quality as an N-by-P matrix, % where N is the number of UEs and P is the number of RBs in the carrier % bandwidth. The initial value of CQI for each RB, for each UE, is given % randomly and is limited by the maximum achievable CQI value corresponding % to the distance of the UE from gNB for ueIdx = 1:simParameters.NumUEs % Assign random CQI values for the RBs, limited by the maximum achievable CQI value uplinkChannelQuality = randi([1 maxUECQIs(ueIdx)], 1, simParameters.NumRBs); downlinkChannelQuality = uplinkChannelQuality; % For TDD, UL and DL channel quality are same % Update the UL and DL CQI values at gNB with respect to UE. gNB uses % UL CQI values to calculate UL packet reception success probability % and for channel quality based UL assignments. It uses DL channel % quality for channel quality based DL assignments updateChannelQualityStatus(gNB, uplinkChannelQuality, 1, ueIdx); % 1 represents UL direction updateChannelQualityStatus(gNB, downlinkChannelQuality, 0, ueIdx); % 0 represents DL direction % Update the DL CQI values at UE. UE uses DL channel quality to calculate DL packet reception success probability updateChannelQualityStatus(UEs{ueIdx}, downlinkChannelQuality); end % Setup the logical channel lcid = 1; for ueIdx=1:simParameters.NumUEs % Create RLC channel configuration structure rlcChannelConfigStruct.LCID = simParameters.LCHConfig.LCID(ueIdx, lcid); rlcChannelConfigStruct.SnFieldLength = simParameters.RLCConfig.SNFieldLength(ueIdx, lcid); rlcChannelConfigStruct.MaxTxBufferLength = simParameters.RLCConfig.MaxTxBufferLength(ueIdx, lcid); rlcChannelConfigStruct.ReassemblyTime = simParameters.RLCConfig.ReassemblyTimer(ueIdx, lcid); rlcChannelConfigStruct.EntityDir = simParameters.RLCConfig.EntityDir(ueIdx, lcid); rlcChannelConfigStruct.LCGID = simParameters.LCHConfig.LCGID(ueIdx, lcid); rlcChannelConfigStruct.Priority = simParameters.LCHConfig.Priority(ueIdx, lcid); rlcChannelConfigStruct.PBR = simParameters.LCHConfig.PBR(ueIdx, lcid); rlcChannelConfigStruct.BucketSizeDuration = simParameters.LCHConfig.BSD(ueIdx, lcid); % Setup logical channel at gNB for the UE configureLogicalChannel(gNB, ueIdx, rlcChannelConfigStruct); % Setup logical channel at UE configureLogicalChannel(UEs{ueIdx}, ueIdx, rlcChannelConfigStruct); end % Initialize buffers to exchange packets between UEs and gNB hNRPacketExchangeBuffer(simParameters);
Simulation is run symbol by symbol to execute corresponding operations. If slot based scheduling is chosen, the execution jumps from the current slot boundary to the next slot boundary. Processing loop performs slot boundary operations followed by the symbol boundary operations. Based on the current symbol type (DL/UL/Guard), only relevant operations are performed.
Slot boundary operations are:
Update channel conditions: Update CQI values at RBs for each UE based on the channel update periodicity.
Generate application traffic: Generate DL and UL traffic as per the configured periodicity of application traffic pattern.
Run the schedulers: Refer to Scheduler section for the time when DL and UL schedulers run and resources they schedule in a run. For a TTI (whether a slot or a set of contiguous symbols), assignments of RBs for retransmissions are done first, followed by assignments for the new transmissions.
Control Tx (gNB): Construct and send UL and DL assignments based on the assignments done by respective schedulers.
Control Rx (UE): UEs receive their respective UL and DL assignments. UEs process the assignments and store the information to be used for the PUSCH transmission and PDSCH reception.
RLC logging: Log the RLC layer statistics.
Per symbol operations are:
Data Tx (gNB): gNB sends PDSCH packets adhering to the DL assignments sent earlier.
Data Rx (UE): UEs receive PDSCH packet scheduled for this symbol. UEs store the reception success/failure result to send PDSCH feedback as positive acknowledgment (ACK) or negative acknowledgment (NACK). The timing of sending feedback for a PDSCH is based on feedback slot offset (k1) received in the PDSCH assignment.
Data Tx (UE): UEs send PUSCH packet adhering to the UL assignments received earlier.
Control Tx (UE): Based on the configured BSR periodicity, UEs send the BSR to convey the pending buffer amount. Additionally, UEs also send the PDSCH feedback.
Data Rx (gNB): gNB receives PUSCH packets from the UEs scheduled to transmit in this symbol. If a reception fails, create the retransmission context for the particular UE, which is used for assignments for retransmissions when the scheduler runs next.
Control Rx (gNB): Receive BSR and PDSCH feedback.
Scheduler Logging: Log the output of scheduling operations at gNB and UEs.
Visualization: Update the different visualizations as per the set update periodicity.
% To store the following UE metrics for each symbol: throughput % bytes transmitted, goodput bytes transmitted, and pending buffer amount % bytes. The number of goodput bytes is calculated by excluding the retransmissions from the % total transmissions. Metrics are for DL direction if symbol type is DL % (likewise, for UL symbol) UEMetrics = zeros(simParameters.NumUEs, 3); % To store Rx result: 'RxSuccess', 'RxFailure', 'NoRx' for a symbol rxResultUEs = cell(simParameters.NumUEs, 1); % To store the current value of last received NDI flag for HARQ processes % of UEs. NDI values are for DL HARQ processes, if symbol type is DL % (likewise, for UL symbol) HARQProcessStatus = zeros(simParameters.NumUEs, simParameters.NumHARQ); % To store the RLC statistics of a slot ueRLCStats = cell(simParameters.NumUEs, 1); gNBRLCStats = cell(simParameters.NumUEs, 1); % To store current CQI values on the RBs for the UEs channelQuality = zeros(simParameters.NumUEs, simParameters.NumRBs); % Create logging and visualization objects for MAC scheduling and RLC simSchedulingLogger = hNRSchedulingLogger(simParameters); simRLCLogger = hNRRLCLogger(simParameters, lchInfo); if ~isfield(simParameters, 'SchedulingType') || simParameters.SchedulingType == 0 % If no scheduling type is specified or slot based scheduling is specified tickGranularity = 14; % Operations are only at slot boundary. Simulation jumps from one slot boundary to next else % Symbol based scheduling tickGranularity = 1; % Operations can be at symbol boundary. Simulation moves symbol-by-symbol end slotNum = 0; % Execute all the symbols in the simulation for symbolNum = 1 : tickGranularity : numSymbolsSim resourceAssignmentsUL = []; resourceAssignmentsDL = []; UEMetrics(:) = 0; rxResultUEs(:) = {[]}; HARQProcessStatus(:) = 0; symbolType = currentSymbolType(gNB); % Get current symbol type: DL/UL/Guard % Perform the slot boundary operations if mod(symbolNum - 1, 14) == 0 slotNum = slotNum + 1; % Update the channel quality, if channel update periodicity has reached if mod(slotNum, channelUpdatePeriodicitySlots) == 0 for ueIdx = 1:simParameters.NumUEs % Current UL CQI values for the UE (Assuming TDD channel reciprocity, DL CQIs would also be same) currentCQIs = getChannelQualityStatus(gNB, 1, ueIdx); % Update CQI values for RBs by randomly varying current % values by CQIDelta, limited by the minimum and maximum % achievable CQI index value. You can customize the % updating of CQI values as necessary updateType = [1 -1]; % Improvement/deterioration channelQualityChange = updateType(randi(length(updateType))); updatedCQIs = min(max(currentCQIs + simParameters.CQIDelta*channelQualityChange, 1), maxUECQIs(ueIdx)); % Update the DL and UL channel quality information at gNB % and UEs (1 represents UL direction, 0 represents DL % direction) updateChannelQualityStatus(gNB, updatedCQIs, 1, ueIdx); updateChannelQualityStatus(gNB, updatedCQIs, 0, ueIdx); updateChannelQualityStatus(UEs{ueIdx}, updatedCQIs); end end % Generate application traffic for ueIdx = 1:simParameters.NumUEs % Generate UL traffic if mod(slotNum-1, appPeriodicityUEsSlotsUL(ueIdx)) == 0 % Check if UL packet generation periodicity is reached for the UE % Receive UL data for the UE from upper layers based on UL application traffic % pattern % Divide application packet into multiple RLC SDUs if % it is bigger than maximum RLC SDU size numRLCSDU = floor(simParameters.ULPacketSizesUEs(ueIdx, lcid) / simParameters.maxRLCSDULength); rlcSDU = randi([0 255], simParameters.maxRLCSDULength, 1); for i = 1:numRLCSDU % Generate UL packets of max RLC SDU size (if any) receiveRLCSDU(UEs{ueIdx}, ueIdx, lcid , rlcSDU); end if mod(simParameters.ULPacketSizesUEs(ueIdx, lcid),simParameters.maxRLCSDULength) ~= 0 % Generate UL packet which is smaller than maxRLCSDULength rlcSDU = randi([0 255], mod(simParameters.ULPacketSizesUEs(ueIdx, lcid),simParameters.maxRLCSDULength), 1); receiveRLCSDU(UEs{ueIdx}, ueIdx, lcid , rlcSDU); end end % Generate DL traffic if mod(slotNum-1, appPeriodicityUEsSlotsDL(ueIdx)) == 0 % If DL packet generation periodicity reached for UE % Receive DL data for the UE from upper layers based on application traffic % pattern % Divide application packet into multiple RLC SDUs, if it is bigger than maximum RLC SDU size numRLCSDU = floor(simParameters.DLPacketSizesUEs(ueIdx, lcid) / simParameters.maxRLCSDULength); rlcSDU = randi([0 255], simParameters.maxRLCSDULength, 1); for i = 1:numRLCSDU receiveRLCSDU(gNB, ueIdx, lcid, rlcSDU); % Generate DL packets of max RLC SDU size (if any) end if mod(simParameters.DLPacketSizesUEs(ueIdx, lcid),simParameters.maxRLCSDULength) ~= 0 % Generate DL packet which is smaller than maxRLCSDULength rlcSDU = randi([0 255], mod(simParameters.DLPacketSizesUEs(ueIdx, lcid),simParameters.maxRLCSDULength), 1); receiveRLCSDU(gNB, ueIdx, lcid, rlcSDU); end end end % Run the schedulers. Functions internally check if the UL/DL % scheduler is set to run in this slot. If yes, schedule the % resources and send the corresponding UL and DL assignments resourceAssignmentsUL = runULSchedulerTDD(gNB); resourceAssignmentsDL = runDLSchedulerTDD(gNB); if ~isempty(resourceAssignmentsUL) || ~isempty(resourceAssignmentsDL) % Check if UL/DL assignments are done controlTx(gNB, resourceAssignmentsUL, resourceAssignmentsDL); % Construct and send UL and DL assignments end % Run the Rx operation at UEs for simultaneous reception of control packets for ueIdx = 1:simParameters.NumUEs % For all UEs controlRx(UEs{ueIdx}); % Receive UL and DL assignments, if any sent by gNB % Get RLC statistics ueRLCStats{ueIdx} = getRLCStatistics(UEs{ueIdx}, ueIdx); gNBRLCStats{ueIdx} = getRLCStatistics(gNB, ueIdx); end logRLCStats(simRLCLogger, ueRLCStats, gNBRLCStats); % Update RLC statistics logs end % Perform the symbol boundary operations if symbolType == 0 % DL symbol dataTx(gNB); % Send the PDSCH packets, if any scheduled for ueIdx = 1:simParameters.NumUEs % For all UEs % Read current NDI value at UEs for DL HARQ processes (for logging purpose) HARQProcessStatus(ueIdx, :) = getLastNDIFlagHarq(UEs{ueIdx}, 0); % 0 for DL % Receive the PDSCH packets from gNB that are scheduled to be % received in this symbol. Return the information of Rx % success/failure rxResultUEs{ueIdx} = dataRx(UEs{ueIdx}); % Read the UL channel quality at gNB for each of the UEs (for logging purpose) channelQuality(ueIdx,:) = getChannelQualityStatus(gNB, 1, ueIdx); % 1 for UL direction end [UEMetrics(:, 1), UEMetrics(:, 2)] = getCurrTTIBytes(gNB); % Read throughput and goodput bytes sent for each UE (for logging purpose) UEMetrics(:, 3) = getBufferStatus(gNB); % Read pending DL buffer (in bytes) for each UE at gNB (for logging purpose) end if symbolType == 1 % UL Symbol for ueIdx = 1:simParameters.NumUEs % For all UEs % Read current NDI value at UEs for UL HARQ processes (for logging purpose) HARQProcessStatus(ueIdx, :) = getLastNDIFlagHarq(UEs{ueIdx}, 1); % 1 for UL % UE sends the PUSCH packet if it is a Tx start symbol (as conveyed by gNB in % earlier received UL assignments) dataTx(UEs{ueIdx}); % UE sends the BSR packet and ACK/NACK for PDSCHs controlTx(UEs{ueIdx}); % Read throughput and goodput bytes transmitted by this UE in the current TTI (for logging purpose) [UEMetrics(ueIdx, 1), UEMetrics(ueIdx, 2)] = getCurrTTIBytes(UEs{ueIdx}); % Read pending UL buffer (in bytes) on UE (for logging purpose) UEMetrics(ueIdx, 3) = getBufferStatus(UEs{ueIdx}); % Read the DL channel quality at gNB for each of the UEs (for logging purpose) channelQuality(ueIdx,:) = getChannelQualityStatus(gNB, 0, ueIdx); % 0 for DL direction end % Receive PUSCH packets from UEs that are scheduled to be received % in this symbol. Return the information of Rx success/failure rxResultUEs = dataRx(gNB); controlRx(gNB); % Receive BSRs and PDSCH feedback end % Update logs based on the current symbol run of UEs and gNB logScheduling(simSchedulingLogger, symbolNum, [resourceAssignmentsUL resourceAssignmentsDL], UEMetrics, channelQuality, HARQProcessStatus, rxResultUEs, symbolType); % RB assignment visualization (if enabled) if simParameters.RBVisualization if symbolNum > 1 && (simParameters.SchedulingType == 1 && (mod(symbolNum, 14) == 0)) || (simParameters.SchedulingType == 0 && (mod(slotNum, rbAssignmentPlotPeriodicity) == 0)) % Plot at slot boundary, if the update periodicity is % reached plotRBGrids(simSchedulingLogger); end end % CQI grid visualization (if enabled) if simParameters.CQIVisualization if symbolNum > 1 && mod(symbolNum-1, 14) == 0 && mod(slotNum, numSlotsFrame) == 0 % Plot at frame boundary plotCQIRBGrids(simSchedulingLogger); end end % Plot scheduler metrics and RLC metrics visualization at slot % boundary, if the update periodicity is reached if symbolNum > 1 && mod(symbolNum-1, 14) == 0 && mod(slotNum, simParameters.MetricsStepSize) == 0 plotMetrics(simSchedulingLogger); plotMetrics(simRLCLogger); end % Advance timer ticks for gNB and UEs by 'tickGranularity' symbols advanceTimer(gNB, tickGranularity); for ueIdx = 1:simParameters.NumUEs % For all UEs advanceTimer(UEs{ueIdx}, tickGranularity); end end
The five types of runtime visualization shown are:
Display of CQI values for UEs over the PUSCH/PDSCH bandwidth: For details, see the 'Channel Quality Visualization' figure.
Display of resource grid assignment to UEs: The 2-D time-frequency grid shows the resource allocation to the UEs. For slot based scheduling, it updates every 10 ms (frame length), and shows the RB allocation to the UEs in the previous frame. For symbol based scheduling, it updates every slot, and shows the RB allocation of symbols of the previous slot. The HARQ process for the assignments is also shown alongside the RNTI of the UEs. New transmissions are shown in black and retransmissions are shown in blue. Using the HARQ process ID of a UE, a retransmission assignment can be mapped to its previously failed transmission. For details, see the 'Resource Grid Allocation' figure.
Display of uplink metrics plots: The 'Uplink Scheduler Performance Metrics' figure includes plots of the: UL throughput (per UE and cell), UL goodput (per UE and cell), resource share percentage among UEs (out of the total UL resources) to convey the fairness of scheduling, and pending UL buffer status of the UEs to show whether UEs are getting sufficient resources. The performance metrics plots update every metricsStepSize
slots.
Display of downlink metrics plots: Like uplink metrics plots, the 'Downlink Scheduler Performance Metrics' displays corresponding subplots for DL direction. The performance metrics plots update every metricsStepSize
slots
Display of RLC metrics plot: The 'RLC Throughput Visualization' figure shows the throughput of RLC logical channel for the selected UE. The RLC metrics plot updates every metricsStepSize
slots.
The parameters used for simulation and the simulation logs are saved in MAT-files for post simulation analysis and visualization. The simulation parameters are saved in MAT-file with filename as the value of configuration parameter simParameters.ParametersLogFile
. The per time step logs, scheduling assignment logs, and RLC logs are saved in the MAT-file simParameters.SimulationLogFile
. After the simulation, open it to load timeStepLogs
, schedulingAssignmentLogs
, and rlcLogs
in the workspace.
Time step logs: The table shows a sample time step entry. Each row of the table represents a symbol or a slot, based on the chosen scheduling type (symbol based or slot based). The information in a row is for DL, if the type of symbol (or slot) is DL
. Likewise, for UL
symbol (or slot).
Each row contains the following information:
Frame: Frame number.
Slot: Slot number in the frame.
Symbol
: Symbol number in the slot (Only for symbol based scheduling).
Type
: Symbol (or Slot) type as 'DL', 'UL', or 'Guard'. For slot based scheduling, type can only be DL/UL. As the slot containing the guard symbols is assumed to be a DL slot with guard symbols at the end of the slot.
RBG Allocation Bitmap: N-by-P bitmap matrix, where N is the number of UEs and P is the number of RBGs in the bandwidth. If an RBG is assigned to a particular UE, the corresponding bit is set to 1. For example, [ 0 0 1 1 0 1 0 1 0 1 0 0 0; 1 1 0 0 0 0 0 0 0 0 1 0 0; 0 0 0 0 1 0 1 0 1 0 0 1 1; 0 0 0 0 0 0 0 0 0 0 0 0 0] means, that the bandwidth has 13 RBGs and UE-1 is assigned the RBG indices 2, 3, 5, 7, and 9; UE-2 is assigned the RBG indices: 0, 1, and 10; UE-3 is assigned the RBG indices: 4, 6, 8, 11, and 12; and UE-4 is not assigned any RBG.
MCS: Row vector of length N where N is the number of UEs. Each value corresponds to the modulation and coding scheme (MCS) index for the PUSCH/PDSCH transmission. For example, [10 12 8 -1] means that only UE-1, UE-2, and UE-3 are assigned UL resources (symbol type is 'UL') for this symbol and use MCS values 10, 12, and 8, respectively.
HARQ Process: Row vector of length N, where N is the number of UEs. The value is the HARQ process ID used by UE for the PUSCH transmission or used by gNB for PDSCH transmission. For example, [0 3 6 -1] means that only UE-1, UE-2, and UE-3 are assigned UL resources (symbol type is 'UL') for this symbol and use the HARQ process IDs 0, 3, and 6, respectively.
NDI: Row vector of length N, where N is the number of UEs. The value is the NDI flag value in the assignment for PUSCH/PDSCH transmission. For example, [0 0 1 -1] means that only UE-1, UE-2, and UE-3 are assigned UL resources for this symbol and use the NDI flag values (which determine whether a new transmission or a retransmission is done) are 0, 0, and 1, respectively.
Tx Type: Tx Type specifies the transmission type (new transmission or retransmission). Row vector of length N, where N is the number of UEs. Possible values are either 'newTx', 'reTx', or 'noTx'. 'noTx' means that the UE is not allotted PUSCH/PDSCH resources. For example: ['newTx' 'newTx' 'reTx' 'noTx'] means that only UE-1, UE-2, and UE-3 are assigned UL resources for this symbol. UE-1 and UE-2 transmit a new packet from the specified HARQ process, while UE-3 retransmits the packet in the buffer of the specified HARQ process.
CQI for UEs: N-by-P matrix, where N is the number of UEs and P is the number of RBs in the bandwidth. A matrix element at position (i, j) corresponds to the CQI value for UE with RNTI i at RB j.
HARQ NDI Status: N-by-P matrix, where N is the number of UEs and P is the number of HARQ processes. A matrix element at position (i, j) is the last received NDI flag at UE i for DL or UL HARQ process ID j. For new transmissions, this value and the NDI flag in the PUSCH/PDSCH assignment must toggle for the HARQ process in the assignment.
Throughput Bytes: Row vector of length N, where N is the number of UEs. The values represent UL/DL MAC bytes transmitted by/for UEs in this symbol. Note that the total throughput bytes for the complete PUSCH/PDSCH transmission are shown in the row corresponding to the first symbol of the transmission.
Goodput Bytes: Row vector of length N, where N is the number of UEs. The values represent new UL/DL transmission MAC bytes transmitted by/for UEs in this symbol. Like throughput, all the goodput bytes for the complete PUSCH/PDSCH are shown in the row corresponding to first symbol of the transmission.
Buffer Status of UEs: Row vector of length N, where N is the number of UEs. The values represent the amount of UL direction pending buffers at UEs (or DL direction pending buffers for UEs at gNB).
Rx Success/Failure: Row vector of length N, where N is the number of UEs. The possible values are either 'RxSuccess', 'RxFailure', or 'noRx'. 'noRx' means no DL (or UL) transmission is scheduled. For example: ['RxSuccess' 'RxSuccess' 'RxFailure' 'noRx'] means that packets from UE-1 and UE-2 are received successfully, while the packet from UE-3 was either not received or was corrupted. UE-4 was not scheduled for this symbol.
Scheduling assignment logs: Information of all the scheduling assignments and related information is logged in this table. Each row is one UL/DL assignment. The table shows sample log entries.
RLC logs: Refer to NR PUSCH FDD Scheduling example for RLC log format.
You can run the script NRSchedulingTDDPostSimVisualization.m to get a post simulation visualization of logs. In the post simulation script, you get the variable isLogReplay
, which provides these options to visualize 'Resource Grid Allocation' and 'Channel Quality Visualization' figures.
Set isLogReplay
to true
for a replay of the simulation logs.
Set isLogReplay
to false
to analyze the details of a particular frame or a particular slot of a frame. In the 'Resource Grid Allocation' window, input the frame number and slot number to visualize the resource assignment of the particular slot, if scheduling type is symbol based. For slot based scheduling, enter the frame number to visualize the resource assignment for the entire frame. The frame number entered here controls the frame number for 'Channel Quality Visualization' figure too.
% Read the logs and write them to MAT-files timeStepLogs = getSchedulingLogs(simSchedulingLogger); % MAC scheduling logs schedulingGrantLogs = getGrantLogs(simSchedulingLogger); % Scheduling assignments log rlcLogs = getRLCLogs(simRLCLogger); % RLC statistics logs save(simParameters.SimulationLogFile, 'timeStepLogs', 'schedulingGrantLogs', 'rlcLogs'); % Save simulation logs in a MAT-file save(simParameters.ParametersLogFile, 'simParameters'); % Save simulation parameters in a MAT-file
You can modify the existing UL and DL scheduling functionality to schedule resources of a slot. The scheduling of UL resources of a slot is implemented in scheduleULResourcesSlot
function of hNRGNBMACScheduler.m. Populate the output uplinkGrants
of this function with an array of valid UL scheduling assignments. For slot based scheduling, uplinkGrants
can have maximum one assignment per UE. For symbol based scheduling, a slot can have multiple assignments to a UE corresponding to different TTIs. Each element in this array is PUSCH grant for a UE. The PUSCH assignment structure has these fields:
RNTI
: Assignment is for this UE. This field is not part of the actual assignment packet sent to UEs.
Type
: Whether assignment is for new transmission ('newTx'), or retransmission ('reTx') ). This field is not part of actual assignment packet sent to UEs, because the NDI field is sufficient to convey that.
HARQIndex
: Selected UL HARQ process ID.
RBGAllocationBitmap
: Frequency-domain resource assignment. A bitmap of resource-block-groups of the PUSCH bandwidth. Value 1 indicates RBG is assigned to the UE.
StartSymbol
: Start symbol of PUSCH assignment.
NumSymbols
: Number of symbols allotted for PUSCH assignment.
SlotOffset
: Slot offset of PUSCH assignments with respect to the current slot (where scheduling is being done).
MCS
: Selected modulation and coding scheme.
NDI
: New data indicator flag.
RV
: Redundancy version.
The screenshot shows UL resources of a slot being distributed in four PUSCH assignments. It also shows content of the fourth assignment.
Similarly, the scheduleDLResourcesSlot
function of hNRGNBMACScheduler.m implements the corresponding DL functionality. PDSCH assignment has one extra field 'FeedbackSlotOffset' as shown in the figure. The field is the slot offset of ACK/NACK transmission time from the PDSCH reception slot.
Setting output for functions scheduleULResourcesSlot
and scheduleDLResourcesSlot
enables you to control the assignment of all the RBGs of a slot at once. You can also control the assignment of each RBG of a TTI. For reference, you can see the existing scheduling strategies present in the helper functions hNRSchedulingStrategyBestCQI.m, hNRSchedulingStrategyPF.m, and hNRSchedulingStrategyRR.m. Refer to NR PUSCH FDD Scheduling example for the procedure to implement a custom scheduling strategy.
To extend the functionality of this example to support multiple logical channels, refer to NR PUSCH FDD Scheduling example.
Based on the chosen scheduling strategy, this example demonstrates the assignment of UL and DL resources to multiple UEs by the gNB. The physical layer is abstracted in the example. UL and DL scheduling performance is analyzed based on runtime plots of MAC throughput, MAC goodput, resource share fairness, and pending buffer status of the UEs. A more thorough post simulation analysis by using the saved logs gives a detailed picture of the operations happening on a per symbol/slot basis.
The example uses these helper functions and classes:
hNRSchedulingTDDValidateConfig.m: Validates simulation configuration
hNRNodeBase.m: NR node base class
hNRGNB.m: gNB node functionality
hNRUE.m: UE node functionality
hNRMACBase.m: NR MAC base class functionality
hNRGNBMAC.m: gNB MAC functionality
hNRGNBMACScheduler.m: gNB MAC scheduler functionality
hNRUEMAC.m: UE MAC functionality
hNewHARQProcesses.m: Creates new HARQ process
hUpdateHARQProcess.m: Updates HARQ process
hPDSCHTBS.m: PDSCH transport block size
hPUSCHTBS.m: PUSCH transport block size
hNRMACBSR.m: Generates buffer status report
hNRMACBSRParser.m: Parses buffer status report
hNRMACSubPDU.m: Generates MAC subPDU
hNRMACPaddingSubPDU.m: Generates MAC subPDU with padding
hNRMACMultiplex.m: Generates MAC PDU
hNRMACPDUParser.m: Parses MAC PDU
hNRPacketExchangeBuffer.m: Implements packet exchange buffers between UE and gNB
hNRUplinkGrantFormat.m: UL assignment format
hNRDownlinkGrantFormat.m: DL assignment format
hNRSchedulingLogger.m: Implements scheduling information logging and visualization functionality
hNRSchedulingStrategyBestCQI.m: Implements best CQI scheduling strategy
hNRSchedulingStrategyPF.m: Implements proportional fair scheduling strategy
hNRSchedulingStrategyRR.m: Implements round robin scheduling strategy
hNRUMTransmitter.m: RLC UM transmitter functionality
hNRUMReceiver.m: RLC UM receiver functionality
hNRUMDataHeader.m: Generates RLC UM PDU header
hNRUMDataPDUDecode.m: Decodes RLC PDU
hNRUMDataPDUInfo.m: Creates RLC PDU information object
hNRRLCDataReassemblyInfo.m: Create an RLC SDU reassembly information object
hNRRLCBufferStatus.m: Generates RLC buffer status information object
hNRRLCLogger.m: Implements RLC statistics logging and visualization functionality
[1] 3GPP TS 38.214. “NR; Physical layer procedures for data.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
[2] 3GPP TS 38.321. “NR; Medium Access Control (MAC) protocol specification.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
[3] 3GPP TS 38.322. “NR; Radio Link Control (RLC) protocol specification.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
[4] 3GPP TS 38.331. “NR; Radio Resource Control (RRC) protocol specification.” 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.